Adding downloading functionality, left TODO's on where to pick up from
This commit is contained in:
@@ -21,11 +21,9 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -std=c++17 -DNDEBUG")
|
||||
set (SOURCES
|
||||
APIRepository.cpp
|
||||
BaseRepository.cpp
|
||||
CoverArtRepository.cpp
|
||||
Demo.cpp
|
||||
RepeatRepository.cpp
|
||||
ShuffleRepository.cpp
|
||||
SongRepository.cpp
|
||||
Tok.cpp
|
||||
TokenRepository.cpp
|
||||
UserRepository.cpp
|
||||
@@ -49,6 +47,7 @@ set (HEADERS
|
||||
Tok.h
|
||||
TokenRepository.h
|
||||
UserRepository.h
|
||||
GeneralUtility.h
|
||||
)
|
||||
|
||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||
|
||||
@@ -21,94 +21,76 @@ namespace repository {
|
||||
template<typename C>
|
||||
class CoverArtRepository {
|
||||
public:
|
||||
std::vector<C> retrieveCoverArtRecords(const model::Token&, const std::string&);
|
||||
std::vector<data> retrieveCoverArtData(const model::Token&, const C&, const std::string&);
|
||||
// TODO: implement this
|
||||
std::vector<C> retrieveCoverArtRecords(const model::Token& token, const std::string& uri) {
|
||||
std::vector<std::string> vals;
|
||||
|
||||
return vals;
|
||||
}
|
||||
|
||||
std::vector<data> retrieveCoverArtData(const model::Token& token, const C& cover,
|
||||
const std::string& uri) {
|
||||
std::string fullUri(uri);
|
||||
if (fullUri.at(fullUri.size() - 1) != '/') {
|
||||
fullUri.append("/");
|
||||
}
|
||||
fullUri.append(downloadEndpoint());
|
||||
fullUri.append(std::to_string(cover.id));
|
||||
|
||||
CURL *curl;
|
||||
struct curl_slist *chunk = nullptr;
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl) {
|
||||
return std::vector<data>();
|
||||
}
|
||||
|
||||
std::string data;
|
||||
std::string authHeader("Authorization: Bearer ");
|
||||
authHeader.append(token.accessToken);
|
||||
constexpr auto keepAliveHeader = "Content-type: Keep-alive";
|
||||
chunk = curl_slist_append(chunk, authHeader.c_str());
|
||||
chunk = curl_slist_append(chunk, keepAliveHeader);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, fullUri.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
|
||||
auto res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
std::vector<char> vals(data.begin(), data.end());
|
||||
|
||||
return vals;
|
||||
}
|
||||
|
||||
// TODO: implement this
|
||||
C retrieveCoverArtRecord(const model::Token& token, const C& cover,
|
||||
const std::string& uri) {
|
||||
C cov;
|
||||
|
||||
return cov;
|
||||
}
|
||||
|
||||
C retrieveCoverArtRecord(const model::Token&, const C&, const std::string&);
|
||||
|
||||
private:
|
||||
constexpr auto downloadEndpoint() noexcept;
|
||||
constexpr auto recordsEndpoint() noexcept;
|
||||
constexpr auto downloadEndpoint() noexcept {
|
||||
return "api/v1/coverart/download/";
|
||||
}
|
||||
|
||||
static size_t respBodyRetriever(void*, size_t, size_t, char*);
|
||||
constexpr auto recordsEndpoint() noexcept {
|
||||
return "api/v1/coverart/";
|
||||
}
|
||||
|
||||
static size_t respBodyRetriever(void *ptr, size_t size,
|
||||
size_t nmemb, char *e) {
|
||||
((std::string*)e)->append((char*)ptr, size * nmemb);
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename C>
|
||||
std::vector<C> CoverArtRepository<C>::retrieveCoverArtRecords(const model::Token& token,
|
||||
const std::string& uri) {
|
||||
std::vector<std::string> vals;
|
||||
|
||||
return vals;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
std::vector<data> CoverArtRepository<C>::retrieveCoverArtData(const model::Token& token,
|
||||
const C& cover,
|
||||
const std::string& uri) {
|
||||
std::string fullUri(uri);
|
||||
if (fullUri.at(fullUri.size() - 1) != '/') {
|
||||
fullUri.append("/");
|
||||
}
|
||||
fullUri.append(downloadEndpoint());
|
||||
fullUri.append(std::to_string(cover.id));
|
||||
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *chunk = nullptr;
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl) {
|
||||
return std::vector<data>();
|
||||
}
|
||||
|
||||
std::string data;
|
||||
std::string authHeader("Authorization: Bearer ");
|
||||
authHeader.append(token.accessToken);
|
||||
constexpr auto keepAliveHeader = "Content-type: Keep-alive";
|
||||
chunk = curl_slist_append(chunk, authHeader.c_str());
|
||||
chunk = curl_slist_append(chunk, keepAliveHeader);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, fullUri.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
std::stringstream buff(data);
|
||||
std::vector<char> vals(data.begin(), data.end());
|
||||
|
||||
return vals;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
C CoverArtRepository<C>::retrieveCoverArtRecord(const model::Token& token,
|
||||
const C& cover,
|
||||
const std::string& uri) {
|
||||
model::CoverArt cov;
|
||||
|
||||
return cov;
|
||||
}
|
||||
|
||||
|
||||
template<typename C>
|
||||
constexpr auto CoverArtRepository<C>::downloadEndpoint() noexcept {
|
||||
return "api/v1/coverart/download/";
|
||||
}
|
||||
template<typename C>
|
||||
constexpr auto CoverArtRepository<C>::recordsEndpoint() noexcept {
|
||||
return "api/v1/coverart/";
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
size_t CoverArtRepository<C>::respBodyRetriever(void *ptr, size_t size, size_t nmemb, char *e) {
|
||||
((std::string*)e)->append((char*)ptr, size * nmemb);
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -388,6 +388,24 @@ Java_com_example_mear_repositories_TrackRepository_retrieveSong(
|
||||
return fetchedSongObj;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jobject
|
||||
JNICALL
|
||||
Java_com_example_mear_repositories_TrackRepositories_downloadSong(
|
||||
JNIEnv *env,
|
||||
jobject thisObj,
|
||||
jobject tokenObj,
|
||||
jobject songObj,
|
||||
jstring uriStr
|
||||
) {
|
||||
// TODO: left off here
|
||||
model::Song downloadedSong;
|
||||
auto downloadedSongObj = songToObj(env, downloadedSong);
|
||||
|
||||
return downloadedSongObj;
|
||||
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jobject
|
||||
JNICALL
|
||||
@@ -478,14 +496,7 @@ Java_com_example_mear_repositories_CoverArtRepository_retrieveCoverArtImage(
|
||||
auto data = coverArtRepo.retrieveCoverArtData(token, cover, env->GetStringUTFChars(apiUri, nullptr));
|
||||
|
||||
jbyteArray image = env->NewByteArray(data.size());
|
||||
//for (auto& b: data) {
|
||||
env->SetByteArrayRegion(image, 0, data.size(), (jbyte*) data.data());
|
||||
//}
|
||||
//constexpr auto testImagePath = "/data/data/com.example.mear/image.png";
|
||||
//std::ofstream out(testImagePath, std::ios::out | std::ios::binary);
|
||||
//out.write(reinterpret_cast<char*>(data.data()), data.size());
|
||||
//out.close();
|
||||
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -8,116 +8,26 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace repository {
|
||||
/**
|
||||
std::vector<model::Song> SongRepository::fetchSongs(const model::Token& token,
|
||||
const std::string& uri)
|
||||
{
|
||||
std::string fullUri(uri);
|
||||
if (fullUri.at(fullUri.size()-1) != '/') {
|
||||
fullUri.append("/");
|
||||
}
|
||||
|
||||
fullUri.append(songRecordEndpoint());
|
||||
std::vector<model::Song> songs;
|
||||
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *chunk = nullptr;
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl) {
|
||||
return songs;
|
||||
}
|
||||
|
||||
std::string resp;
|
||||
|
||||
std::string authInfo("Authorization: Bearer ");
|
||||
authInfo.append(token.accessToken);
|
||||
constexpr auto contentType = "Content-type: Keep-alive";
|
||||
chunk = curl_slist_append(chunk, authInfo.c_str());
|
||||
chunk = curl_slist_append(chunk, contentType);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, fullUri.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res == CURLE_OK) {
|
||||
auto songsJson = nlohmann::json::parse(resp.c_str());
|
||||
for (auto& songJson: songsJson) {
|
||||
model::Song song(songJson["id"].get<int>(), songJson["title"].get<std::string>(),
|
||||
songJson["artist"].get<std::string>(), songJson["album"].get<std::string>(),
|
||||
songJson["genre"].get<std::string>(), songJson["duration"].get<int>(),
|
||||
songJson["year"].get<int>());
|
||||
song.albumArtist = songJson["album_artist"].get<std::string>();
|
||||
song.coverArtId = songJson["coverart_id"].get<int>();
|
||||
|
||||
songs.push_back(song);
|
||||
}
|
||||
}
|
||||
|
||||
return songs;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
model::Song SongRepository::retrieveSong(const model::Token& token, const model::Song& sng,
|
||||
const std::string& baseUri) {
|
||||
std::string uri(baseUri);
|
||||
uri.append(songRecordEndpoint());
|
||||
uri.append(std::to_string(sng.id));
|
||||
model::Song song;
|
||||
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *chunk = nullptr;
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl) {
|
||||
return sng;
|
||||
}
|
||||
|
||||
auto resp = std::make_unique<char[]>(10000);
|
||||
|
||||
std::string authInfo("Authorization: Bearer ");
|
||||
authInfo.append(token.accessToken);
|
||||
constexpr auto contentType = "Content-type: Keep-alive";
|
||||
chunk = curl_slist_append(chunk, authInfo.c_str());
|
||||
chunk = curl_slist_append(chunk, contentType);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, resp.get());
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res == CURLE_OK) {
|
||||
auto s = nlohmann::json::parse(resp.get());
|
||||
song.id = s["id"].get<int>();
|
||||
song.title = s["title"].get<std::string>();
|
||||
song.album = s["album"].get<std::string>();
|
||||
song.albumArtist = s["album_artist"].get<std::string>();
|
||||
song.artist = s["artist"].get<std::string>();
|
||||
song.genre = s["genre"].get<std::string>();
|
||||
song.duration = s["duration"].get<int>();
|
||||
song.year = s["year"].get<int>();
|
||||
song.coverArtId = s["coverart_id"].get<int>();
|
||||
|
||||
return song;
|
||||
}
|
||||
|
||||
return sng;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
size_t SongRepository::respBodyRetriever(void* ptr, size_t size, size_t nmemb, char *e)
|
||||
{
|
||||
((std::string*)e)->append((char*)ptr, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -8,25 +8,170 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "model/Song.h"
|
||||
#include "model/Token.h"
|
||||
#include "GeneralUtility.h"
|
||||
|
||||
namespace repository {
|
||||
|
||||
template<class Song = model::Song>
|
||||
class SongRepository {
|
||||
public:
|
||||
std::vector<model::Song> fetchSongs(const model::Token&, const std::string&);
|
||||
template<typename Token = model::Token>
|
||||
std::vector<Song> fetchSongs(const Token& token, const std::string& uri) {
|
||||
auto fullUri = utility::GeneralUtility::appendForwardSlashToUri<std::string>(uri);
|
||||
fullUri.append(songRecordEndpoint());
|
||||
std::vector<Song> songs;
|
||||
|
||||
model::Song retrieveSong(const model::Token&, const model::Song&, const std::string&);
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *chunk = nullptr;
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl) {
|
||||
return songs;
|
||||
}
|
||||
|
||||
std::string resp;
|
||||
|
||||
std::string authInfo("Authorization: Bearer ");
|
||||
authInfo.append(token.accessToken);
|
||||
constexpr auto contentType = "Content-type: Keep-alive";
|
||||
chunk = curl_slist_append(chunk, authInfo.c_str());
|
||||
chunk = curl_slist_append(chunk, contentType);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, fullUri.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res == CURLE_OK) {
|
||||
auto songsJson = nlohmann::json::parse(resp.c_str());
|
||||
for (auto& songJson: songsJson) {
|
||||
Song song(songJson["id"].get<int>(), songJson["title"].get<std::string>(),
|
||||
songJson["artist"].get<std::string>(),
|
||||
songJson["album"].get<std::string>(),
|
||||
songJson["album_artist"].get<std::string>(),
|
||||
songJson["genre"].get<std::string>(), songJson["duration"].get<int>(),
|
||||
songJson["year"].get<int>(), songJson["coverart_id"].get<int>());
|
||||
/**
|
||||
song.albumArtist = songJson["album_artist"].get<std::string>();
|
||||
song.coverArtId = songJson["coverart_id"].get<int>();
|
||||
*/
|
||||
|
||||
songs.push_back(song);
|
||||
}
|
||||
}
|
||||
|
||||
return songs;
|
||||
}
|
||||
|
||||
template<typename Token = model::Token>
|
||||
Song retrieveSong(const Token& token, const Song& sng,
|
||||
const std::string& baseUri) {
|
||||
auto uri = utility::GeneralUtility::appendForwardSlashToUri(baseUri);
|
||||
uri.append(songRecordEndpoint());
|
||||
uri.append(std::to_string(sng.id));
|
||||
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *chunk = nullptr;
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl) {
|
||||
return sng;
|
||||
}
|
||||
|
||||
std::string resp;
|
||||
|
||||
std::string authInfo("Authorization: Bearer ");
|
||||
authInfo.append(token.accessToken);
|
||||
constexpr auto contentType = "Content-type: Keep-alive";
|
||||
chunk = curl_slist_append(chunk, authInfo.c_str());
|
||||
chunk = curl_slist_append(chunk, contentType);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res == CURLE_OK) {
|
||||
auto s = nlohmann::json::parse(resp.c_str());
|
||||
Song song(s["id"].get<int>(), s["title"].get<std::string>(),
|
||||
s["artist"].get<std::string>(), s["album"].get<std::string>(),
|
||||
s["album_artist"].get<std::string>(), s["genre"].get<std::string>(),
|
||||
s["duration"].get<int>(), s["year"].get<int>(),
|
||||
s["coverart_id"].get<int>());
|
||||
/**
|
||||
song.id = s["id"].get<int>();
|
||||
song.title = s["title"].get<std::string>();
|
||||
song.album = s["album"].get<std::string>();
|
||||
song.albumArtist = s["album_artist"].get<std::string>();
|
||||
song.artist = s["artist"].get<std::string>();
|
||||
song.genre = s["genre"].get<std::string>();
|
||||
song.duration = s["duration"].get<int>();
|
||||
song.year = s["year"].get<int>();
|
||||
song.coverArtId = s["coverart_id"].get<int>();
|
||||
*/
|
||||
|
||||
return song;
|
||||
}
|
||||
|
||||
return sng;
|
||||
}
|
||||
|
||||
template<typename Token = model::Token>
|
||||
Song downloadSong(const Token &token, const Song song, const std::string& uri) {
|
||||
auto fullUri = utility::GeneralUtility::appendForwardSlashToUri(uri);
|
||||
fullUri.append(songDownloadEndpoint());
|
||||
fullUri.append(std::to_string(song.id));
|
||||
Song downloadedSong;
|
||||
|
||||
CURL *curl = curl_easy_init();
|
||||
struct curl_slist *chunk = nullptr;
|
||||
|
||||
std::string data;
|
||||
const auto authHeader = utility::GeneralUtility::authHeader(token);
|
||||
chunk = curl_slist_append(chunk, authHeader.c_str());
|
||||
chunk = curl_slist_append(chunk, "Content-type: Keep-alive");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, fullUri.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
|
||||
auto res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
downloadedSong.data = std::move(std::vector<char>(data.begin(), data.end()));
|
||||
|
||||
return downloadedSong;
|
||||
}
|
||||
private:
|
||||
static size_t respBodyRetriever(void*, size_t, size_t, char*);
|
||||
static size_t respBodyRetriever(void *ptr, size_t size, size_t nmemb, char *e) {
|
||||
((std::string*)e)->append((char*)ptr, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
constexpr auto songRecordEndpoint() noexcept;
|
||||
constexpr auto songRecordEndpoint() noexcept {
|
||||
return "api/v1/song/";
|
||||
}
|
||||
|
||||
constexpr auto songDownloadEndpoint() noexcept {
|
||||
return "api/v1/song/data/";
|
||||
}
|
||||
};
|
||||
|
||||
constexpr auto SongRepository::songRecordEndpoint() noexcept {
|
||||
return "api/v1/song/";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define MEAR_SONG_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace model {
|
||||
@@ -20,22 +21,30 @@ public:
|
||||
const int duration, const int year) :
|
||||
id(id), title(title), artist(artist), album(album),
|
||||
genre(genre), duration(duration), year(year) { }
|
||||
Song(const int id, const std::string&& title, const std::string&& artist,
|
||||
const std::string&& album, const std::string&& genre,
|
||||
const int duration, const int year) :
|
||||
id(id), title(std::move(title)), artist(std::move(artist)),
|
||||
album(std::move(album)), genre(std::move(genre)), duration(duration),
|
||||
year(year) { }
|
||||
Song(const int id, const std::string& title, const std::string& artist,
|
||||
const std::string& album, const std::string& albumArtist, const std::string& genre,
|
||||
const int duration, const int year, const int coverArtId) :
|
||||
id(id), title(title), artist(artist), album(album), albumArtist(albumArtist),
|
||||
genre(genre), duration(duration), year(year), coverArtId(coverArtId) { }
|
||||
/**
|
||||
Song(const int id, const std::string&& title, const std::string&& artist,
|
||||
const std::string&& album, const std::string&& genre,
|
||||
const int duration, const int year) :
|
||||
id(id), title(std::move(title)), artist(std::move(artist)),
|
||||
album(std::move(album)), genre(std::move(genre)), duration(duration),
|
||||
year(year) { }
|
||||
*/
|
||||
|
||||
int id;
|
||||
std::string title;
|
||||
std::string artist;
|
||||
std::string albumArtist;
|
||||
std::string album;
|
||||
std::string albumArtist;
|
||||
std::string genre;
|
||||
int duration;
|
||||
int year;
|
||||
int coverArtId;
|
||||
std::vector<char> data;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -368,6 +368,17 @@ class MainActivity : BaseServiceActivity() {
|
||||
R.id.action_song_view -> {
|
||||
startActivity(Intent(this, IcarusSongActivity::class.java))
|
||||
}
|
||||
R.id.action_song_download -> {
|
||||
// TODO: implement download functionality
|
||||
val appPath = appDirectory()
|
||||
val apiRepo = APIRepository()
|
||||
val tokenRepo = TokenRepository()
|
||||
val trackRepo = TrackRepository()
|
||||
val song = musicService!!.getCurrentSong()
|
||||
|
||||
val token = tokenRepo.retrieveToken(appPath)
|
||||
val apiInfo = apiRepo.retrieveRecord(appPath)
|
||||
}
|
||||
R.id.action_song_play_count-> {
|
||||
val trk = musicService!!.getCurrentSong()
|
||||
val pc = PlayCountRepository(this).getPlayCount(trk.id)
|
||||
|
||||
@@ -21,6 +21,7 @@ class TrackRepository(var context: Context? = null) {
|
||||
private external fun retrieveSongs(token: Token, uri: String): Array<Song>
|
||||
|
||||
private external fun retrieveSong(token: Token, song: Song, uri: String): Song
|
||||
private external fun downloadSong(token: Token, song: Song, uri: String): Song
|
||||
|
||||
|
||||
fun fetchSongs(token: Token, uri: String): Array<Song> {
|
||||
@@ -32,55 +33,12 @@ class TrackRepository(var context: Context? = null) {
|
||||
return retrieveSong(token, song, uri)
|
||||
}
|
||||
|
||||
fun getAll(): List<Track> = context!!.database.use {
|
||||
val tracks = mutableListOf<Track>()
|
||||
fun fetchSongFile(token: Token, song: Song, uri: String): Song {
|
||||
val downloadedSong = downloadSong(token, song, uri)
|
||||
|
||||
select("Track" )
|
||||
.parseList(object : MapRowParser<Track>{
|
||||
override fun parseRow(columns: Map<String, Any?>): Track {
|
||||
val id = columns.getValue("Id")
|
||||
val title = columns.getValue("Title")
|
||||
val artist = columns.getValue("Artist").toString()
|
||||
val album = columns.getValue("Album").toString()
|
||||
val duration = columns.getValue("Duration").toString().toInt()
|
||||
val songPath = columns.getValue("FilePath").toString()
|
||||
|
||||
val track = Track(id.toString().toInt(), title.toString(),artist,album,
|
||||
duration, ByteArray(0),songPath)
|
||||
tracks.add(track)
|
||||
|
||||
return track
|
||||
}
|
||||
})
|
||||
tracks
|
||||
return downloadedSong
|
||||
}
|
||||
fun getTrack(id: Int): Track = context!!.database.use {
|
||||
select("Track").where("Id = $id")
|
||||
.parseSingle(object: MapRowParser<Track>{
|
||||
override fun parseRow(columns: Map<String, Any?>): Track {
|
||||
val id = columns.getValue("Id").toString().toInt()
|
||||
val title = columns.getValue("Title").toString()
|
||||
val artist = columns.getValue("Artist").toString()
|
||||
var album = columns.getValue("Album").toString()
|
||||
val duration = columns.getValue("Duration").toString().toInt()
|
||||
var filePath = columns.getValue("FilePath").toString()
|
||||
|
||||
val track = Track(id, title, artist, album, duration,
|
||||
ByteArray(0), filePath)
|
||||
|
||||
return track
|
||||
}
|
||||
})
|
||||
}
|
||||
fun getSongCount(): Int = context!!.database.use {
|
||||
select("TrackCount").limit(1)
|
||||
.parseSingle(object : MapRowParser<Int>{
|
||||
override fun parseRow(columns: Map<String, Any?>): Int {
|
||||
|
||||
return columns.getValue("TotalSongs").toString().toInt()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun insertTracks(tracks: List<Track>) = context!!.database.use {
|
||||
transaction {
|
||||
@@ -111,30 +69,4 @@ class TrackRepository(var context: Context? = null) {
|
||||
fun delete() = context!!.database.use {
|
||||
delete("Track")
|
||||
}
|
||||
fun deleteTracks(tracks: List<Track>) = context!!.database.use {
|
||||
tracks.iterator().forEach {
|
||||
transaction {
|
||||
delete("Track", "id = {track_id}", "track_id" to it.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
fun deleteTracksByPaths(trackPaths: List<String>) = context!!.database.use {
|
||||
trackPaths.iterator().forEach {
|
||||
transaction {
|
||||
delete("Track", "FilePath = {file_path}", "file_path" to it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getLibraryCount(): Int? {
|
||||
context!!.database.use {
|
||||
select("TrackCount").limit(1)
|
||||
.parseList (object : MapRowParser<Int> {
|
||||
override fun parseRow(columns: Map<String, Any?>): Int {
|
||||
return columns.getValue("TotalSongs").toString().toInt()
|
||||
}
|
||||
})
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,9 @@
|
||||
<item android:id="@+id/action_song_view"
|
||||
android:title="@string/song_view"
|
||||
app:showAsAction="never" />
|
||||
<item android:id="@+id/action_song_download"
|
||||
android:title="@string/song_download"
|
||||
app:showAsAction="never" />
|
||||
<item android:id="@+id/action_song_play_count"
|
||||
android:title="@string/song_play_count"
|
||||
app:showAsAction="never" />
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<string name="settings">Settings</string>
|
||||
<string name="song_view">Songs</string>
|
||||
<string name="song_play_count">Play Count</string>
|
||||
<string name="song_download">Download</string>
|
||||
|
||||
<!-- Popups -->
|
||||
<string name="popup_about_header">About</string>
|
||||
|
||||
Reference in New Issue
Block a user