User credentials are saved and retrieved from the SQLite database. Next I want to retrieve all songs from icarus and return it to java/kotlin. Some code cleanup

This commit is contained in:
kdeng00
2019-10-07 21:44:20 -04:00
parent bb6b08cf1a
commit 9483c6b834
26 changed files with 601 additions and 637 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+392 -548
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -10,7 +10,7 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity <activity
android:name=".activities.DemoStreamActivity" android:name=".activities.LoginActivity"
android:label="@string/title_activity_demo_stream" android:label="@string/title_activity_demo_stream"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
+1 -5
View File
@@ -15,7 +15,6 @@ namespace repository { namespace local {
const auto dbPath = pathOfDatabase(appPath); const auto dbPath = pathOfDatabase(appPath);
SQLite::Database db(dbPath, SQLite::OPEN_READONLY); SQLite::Database db(dbPath, SQLite::OPEN_READONLY);
//SQLite::Database db(m_tableName, SQLite::OPEN_READONLY);
return true; return true;
} catch (std::exception& ex) { } catch (std::exception& ex) {
auto msg = ex.what(); auto msg = ex.what();
@@ -39,7 +38,7 @@ namespace repository { namespace local {
auto msg = ex.what(); auto msg = ex.what();
} }
return false; return true;
} }
@@ -47,11 +46,8 @@ namespace repository { namespace local {
{ {
try { try {
const auto dbPath = pathOfDatabase(appPath); const auto dbPath = pathOfDatabase(appPath);
//std::fstream cret(dbPath, std::ios::out);
//cret.close();
SQLite::Database db(dbPath, SQLite::OPEN_CREATE | SQLite::OPEN_READWRITE); SQLite::Database db(dbPath, SQLite::OPEN_CREATE | SQLite::OPEN_READWRITE);
//SQLite::Database db(m_tableName, SQLite::OPEN_CREATE);
} catch (std::exception& ex) { } catch (std::exception& ex) {
auto msg = ex.what(); auto msg = ex.what();
} }
+125 -49
View File
@@ -30,24 +30,23 @@
#include "UserRepository.h" #include "UserRepository.h"
model::Song retrieveSong(const std::string&, const std::string&); model::Song retrieveSong(const std::string&, const std::string&, const int);
model::User retrieveCredentials(const std::string&);
std::string fetchToken(const std::string&, const std::string&, const std::string&); std::string fetchToken(const std::string&, const std::string&, const std::string&);
bool doesDatabaseExist(const std::string&);
bool userCredentialExist(const std::string&);
void saveCredentials(const model::User&, const std::string&); void saveCredentials(const model::User&, const std::string&);
model::Song retrieveSong(const std::string& token, const std::string& baseUri) model::Song retrieveSong(const std::string& token, const std::string& baseUri, const int songId)
{ {
repository::SongRepository songRepo; repository::SongRepository songRepo;
model::Song song; model::Song song(songId, "Smooth", "Amaze", "The Herb", "Blazing",
song.id = 1; 420, 420);
song.title = "Smooth";
song.album = "Amaze";
song.artist = "The Herb";
song.genre = "Blazing";
song.duration = 420;
song.year = 420;
song = songRepo.retrieveSong(token, baseUri, song); song = songRepo.retrieveSong(token, baseUri, song);
@@ -55,6 +54,15 @@ model::Song retrieveSong(const std::string& token, const std::string& baseUri)
} }
model::User retrieveCredentials(const std::string& dataPath)
{
repository::local::UserRepository userRepo;
auto user = userRepo.retrieveUserCredentials(dataPath);
return user;
}
std::string fetchToken(const std::string& username, const std::string& password, std::string fetchToken(const std::string& username, const std::string& password,
const std::string& apiUri) const std::string& apiUri)
{ {
@@ -68,6 +76,22 @@ std::string fetchToken(const std::string& username, const std::string& password,
} }
bool doesDatabaseExist(const std::string& dataPath)
{
repository::local::UserRepository userRepo;
const auto result = userRepo.databaseExist(dataPath);
return result;
}
bool userCredentialExist(const std::string& dataPath)
{
repository::local::UserRepository userRepo;
return userRepo.isTableEmpty(dataPath);
}
void iterateDirectory(const std::string& path) void iterateDirectory(const std::string& path)
{ {
/** /**
@@ -85,58 +109,37 @@ void iterateDirectory(const std::string& path)
void saveCredentials(const model::User& user, const std::string& appDirectory) void saveCredentials(const model::User& user, const std::string& appDirectory)
{ {
std::string filePath(appDirectory);
filePath.append("/");
repository::local::UserRepository userRepo; repository::local::UserRepository userRepo;
if (!userRepo.databaseExist(filePath)) { if (!userRepo.databaseExist(appDirectory)) {
userRepo.initializedDatabase(filePath); userRepo.initializedDatabase(appDirectory);
} }
if (!userRepo.doesUserTableExist(filePath)) { if (!userRepo.doesUserTableExist(appDirectory)) {
userRepo.createUserTable(filePath); userRepo.createUserTable(appDirectory);
} }
if (userRepo.isTableEmpty(filePath)) { if (userRepo.isTableEmpty(appDirectory)) {
userRepo.deleteUserTable(filePath); userRepo.deleteUserTable(appDirectory);
} }
userRepo.saveUserCred(user, filePath); userRepo.saveUserCred(user, appDirectory);
}
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_example_mear_activities_DemoStreamActivity_logUser(
JNIEnv *env,
jobject thisObj,
jstring username,
jstring password,
jstring apiUri ) {
const std::string usr = env->GetStringUTFChars(username, NULL);
const std::string pass = env->GetStringUTFChars(password, NULL);
const std::string api = env->GetStringUTFChars(apiUri, NULL);
auto token = fetchToken(usr, pass, api);
return env->NewStringUTF(token.c_str());
} }
extern "C" extern "C"
JNIEXPORT jobject JNIEXPORT jobject
JNICALL JNICALL
Java_com_example_mear_activities_DemoStreamActivity_retrieveSong( Java_com_example_mear_activities_LoginActivity_retrieveSong(
JNIEnv *env, JNIEnv *env,
jobject thisObj, jobject thisObj,
jstring token, jstring token,
jstring apiUri jstring apiUri,
) jint idOfSong
)
{ {
const std::string tok = env->GetStringUTFChars(token, NULL); const std::string tok = env->GetStringUTFChars(token, NULL);
const std::string baseUri = env->GetStringUTFChars(apiUri, NULL); const std::string baseUri = env->GetStringUTFChars(apiUri, NULL);
auto song = retrieveSong(tok, baseUri); auto song = retrieveSong(tok, baseUri, idOfSong);
jclass songClass = env->FindClass( "com/example/mear/models/Song"); jclass songClass = env->FindClass( "com/example/mear/models/Song");
jmethodID jconstructor = env->GetMethodID( songClass, "<init>", "()V" ); jmethodID jconstructor = env->GetMethodID( songClass, "<init>", "()V" );
@@ -169,11 +172,87 @@ Java_com_example_mear_activities_DemoStreamActivity_retrieveSong(
return songObj; return songObj;
} }
extern "C"
JNIEXPORT jobject
JNICALL
Java_com_example_mear_activities_LoginActivity_retrieveUserCredentials(
JNIEnv *env,
jobject thisObj,
jstring dataPath
) {
jclass userClass = env->FindClass("com/example/mear/models/User");
jmethodID userContructor = env->GetMethodID(userClass, "<init>", "()V");
jobject userObj = env->NewObject(userClass, userContructor);
const std::string dataPathStr = env->GetStringUTFChars(dataPath, nullptr);
auto user = retrieveCredentials(dataPathStr);
jmethodID usernameId = env->GetMethodID(userClass, "setUsername", "(Ljava/lang/String;)V");
jmethodID passwordId = env->GetMethodID(userClass, "setPassword", "(Ljava/lang/String;)V");
jstring username = env->NewStringUTF(user.username.c_str());
jstring password = env->NewStringUTF(user.password.c_str());
env->CallVoidMethod(userObj, usernameId, username);
env->CallVoidMethod(userObj, passwordId, password);
return userObj;
}
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_example_mear_activities_LoginActivity_logUser(
JNIEnv *env,
jobject thisObj,
jstring username,
jstring password,
jstring apiUri ) {
const std::string usr = env->GetStringUTFChars(username, NULL);
const std::string pass = env->GetStringUTFChars(password, NULL);
const std::string api = env->GetStringUTFChars(apiUri, NULL);
auto token = fetchToken(usr, pass, api);
return env->NewStringUTF(token.c_str());
}
extern "C"
JNIEXPORT jboolean
JNICALL
Java_com_example_mear_activities_LoginActivity_isUserTableEmpty(
JNIEnv *env,
jobject thisObj,
jstring dataPath
) {
const std::string dataPathStr = env->GetStringUTFChars(dataPath, NULL);
jboolean result = userCredentialExist(dataPathStr);
return result;
}
extern "C"
JNIEXPORT jboolean
JNICALL
Java_com_example_mear_activities_LoginActivity_doesDatabaseExist(
JNIEnv *env,
jobject thidObj,
jstring dataPath
) {
const std::string dataPathStr = env->GetStringUTFChars(dataPath, NULL);
jboolean result = doesDatabaseExist(dataPathStr);
return result;
}
extern "C" extern "C"
JNIEXPORT void JNIEXPORT void
JNICALL JNICALL
Java_com_example_mear_activities_DemoStreamActivity_pathIteratorDemo( Java_com_example_mear_activities_LoginActivity_pathIteratorDemo(
JNIEnv *env, JNIEnv *env,
jobject thisObj, jobject thisObj,
jstring path jstring path
@@ -187,21 +266,18 @@ Java_com_example_mear_activities_DemoStreamActivity_pathIteratorDemo(
extern "C" extern "C"
JNIEXPORT void JNIEXPORT void
JNICALL JNICALL
Java_com_example_mear_activities_DemoStreamActivity_saveUserCredentials( Java_com_example_mear_activities_LoginActivity_saveUserCredentials(
JNIEnv *env, JNIEnv *env,
jobject thisObj, jobject thisObj,
jstring username, jstring username,
jstring password, jstring password,
jstring appDirectory jstring appDirectory
) { ) {
const std::string usernameStr = env->GetStringUTFChars(username, NULL); const std::string usernameStr = env->GetStringUTFChars(username, NULL);
const std::string passwordStr = env->GetStringUTFChars(password, NULL); const std::string passwordStr = env->GetStringUTFChars(password, NULL);
const std::string appDirectoryStr = env->GetStringUTFChars(appDirectory, NULL); const std::string appDirectoryStr = env->GetStringUTFChars(appDirectory, NULL);
model::User user; model::User user(usernameStr, passwordStr);
user.username = usernameStr;
user.password = passwordStr;
saveCredentials(user, appDirectoryStr); saveCredentials(user, appDirectoryStr);
} }
-4
View File
@@ -19,7 +19,6 @@ namespace repository { namespace local {
try { try {
const auto dbPath = pathOfDatabase(appPath); const auto dbPath = pathOfDatabase(appPath);
SQLite::Database db(dbPath, SQLite::OPEN_READONLY); SQLite::Database db(dbPath, SQLite::OPEN_READONLY);
//SQLite::Database db(m_tableName, SQLite::OPEN_READONLY);
std::string queryString("SELECT * FROM "); std::string queryString("SELECT * FROM ");
queryString.append(m_tableName); queryString.append(m_tableName);
@@ -50,7 +49,6 @@ namespace repository { namespace local {
try { try {
const auto dbPath = pathOfDatabase(appPath); const auto dbPath = pathOfDatabase(appPath);
SQLite::Database db(dbPath, SQLite::OPEN_READONLY); SQLite::Database db(dbPath, SQLite::OPEN_READONLY);
//SQLite::Database db(m_tableName, SQLite::OPEN_READONLY);
return db.tableExists(m_tableName); return db.tableExists(m_tableName);
} catch (std::exception& ex) { } catch (std::exception& ex) {
@@ -66,7 +64,6 @@ namespace repository { namespace local {
try { try {
const auto dbPath = pathOfDatabase(appPath); const auto dbPath = pathOfDatabase(appPath);
SQLite::Database db(dbPath, SQLite::OPEN_READWRITE); SQLite::Database db(dbPath, SQLite::OPEN_READWRITE);
//SQLite::Database db(m_tableName, SQLite::OPEN_READWRITE);
std::string queryString("CREATE TABLE "); std::string queryString("CREATE TABLE ");
queryString.append(m_tableName); queryString.append(m_tableName);
@@ -97,7 +94,6 @@ namespace repository { namespace local {
try { try {
const auto dbPath = pathOfDatabase(appPath); const auto dbPath = pathOfDatabase(appPath);
SQLite::Database db(dbPath, SQLite::OPEN_READWRITE); SQLite::Database db(dbPath, SQLite::OPEN_READWRITE);
//SQLite::Database db(m_tableName, SQLite::OPEN_READWRITE);
std::string queryString("INSERT INTO "); std::string queryString("INSERT INTO ");
queryString.append(m_tableName); queryString.append(m_tableName);
queryString.append(" (Username, Password) VALUES (?, ?)"); queryString.append(" (Username, Password) VALUES (?, ?)");
+1
View File
@@ -19,6 +19,7 @@ namespace repository { namespace local {
model::User retrieveUserCredentials(const std::string&); model::User retrieveUserCredentials(const std::string&);
bool isEmpty(const std::string&);
bool doesUserTableExist(const std::string&); bool doesUserTableExist(const std::string&);
void createUserTable(const std::string&); void createUserTable(const std::string&);
+15 -1
View File
@@ -10,8 +10,22 @@
namespace model { namespace model {
struct Song class Song
{ {
public:
Song() = default;
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(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) { }
int id; int id;
std::string title; std::string title;
std::string artist; std::string artist;
+5 -2
View File
@@ -6,14 +6,17 @@
#define MEAR_TOKEN_H #define MEAR_TOKEN_H
#include <string> #include <string>
#include <utility>
namespace model { namespace model {
class Token class Token
{ {
public: public:
Token(const std::string& token) : token(token) { } Token(const std::string& accessToken) : accessToken(accessToken) { }
Token(const std::string&& accessToken) :
accessToken(std::move(accessToken)) { }
std::string token; std::string accessToken;
}; };
} }
+6 -1
View File
@@ -5,13 +5,18 @@
#ifndef MEAR_USER_H #ifndef MEAR_USER_H
#define MEAR_USER_H #define MEAR_USER_H
#include <string>
#include <utility>
namespace model { namespace model {
struct User class User
{ {
public:
User() = default; User() = default;
User(const std::string& user, const std::string& pass) : User(const std::string& user, const std::string& pass) :
username(user), password(pass) { } username(user), password(pass) { }
User(const std::string&& user, const std::string&& pass) :
username(std::move(user)), password(std::move(pass)) {}
std::string username; std::string username;
std::string password; std::string password;
@@ -3,16 +3,16 @@ package com.example.mear.activities
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.support.design.widget.Snackbar import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import com.example.mear.R import com.example.mear.R
import kotlinx.android.synthetic.main.activity_demo_stream.* import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.android.synthetic.main.content_demo_stream.* import kotlinx.android.synthetic.main.content_login.*
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
import com.example.mear.models.Song import com.example.mear.models.Song
import com.example.mear.models.User
class DemoStreamActivity : BaseServiceActivity() { class LoginActivity : BaseServiceActivity() {
companion object { companion object {
init { init {
@@ -21,22 +21,31 @@ class DemoStreamActivity : BaseServiceActivity() {
} }
private var token: String? = null private external fun retrieveSong(tok: String, api: String, songId: Int): Song
private external fun retrieveUserCredentials(path: String): User
// TODO: add external call to retrieve User credentials
private external fun logUser(usr: String, pass: String, api: String): String private external fun logUser(usr: String, pass: String, api: String): String
private external fun retrieveSong(tok: String, api: String): Song
//private external fun testSongStream(tok: String, id: Int) private external fun doesDatabaseExist(path: String): Boolean
private external fun isUserTableEmpty(path: String): Boolean
private external fun pathIteratorDemo(path: String) private external fun pathIteratorDemo(path: String)
private external fun saveUserCredentials(username: String, password: String, appDir: String) private external fun saveUserCredentials(username: String, password: String, appDir: String)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_demo_stream) setContentView(R.layout.activity_login)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
val pa = appDirectory()
if (doesDatabaseExist(pa) && !isUserTableEmpty(pa)) {
val usr = retrieveUserCredentials(pa)
username.setText(usr.username)
password.setText(usr.password)
}
doBindService() doBindService()
demoStream.setOnClickListener { demoStream.setOnClickListener {
@@ -69,19 +78,14 @@ class DemoStreamActivity : BaseServiceActivity() {
apiUriStr = "" apiUriStr = ""
} }
token = logUser(usernameStr, passwordStr, apiUriStr) val token = logUser(usernameStr, passwordStr, apiUriStr)
try { try {
val songId = 4
val s = retrieveSong(token!!, apiUriStr) val song = retrieveSong(token, apiUriStr, songId)
musicService!!.icarusPlaySong(this.applicationContext, token!!, apiUriStr, s) val pa = appDirectory()
val dir = Environment.getExternalStorageDirectory().absolutePath + "/music" if (saveCred && isUserTableEmpty(pa)) {
val appRelPath: String = resources.getString(R.string.app_relative_path) saveUserCredentials(usernameStr, passwordStr, pa)
var inStoragePath = Environment.getDataDirectory().toString()
inStoragePath += "/data/$appRelPath"
if (saveCred) {
saveUserCredentials(usernameStr, passwordStr, inStoragePath)
} }
} }
catch (ex: Exception) { catch (ex: Exception) {
@@ -89,6 +93,13 @@ class DemoStreamActivity : BaseServiceActivity() {
} }
} }
private fun appDirectory(): String {
return Environment.getDataDirectory().toString() + "/data/" +
resources.getString(R.string.app_relative_path)
}
private fun validFields(): Boolean { private fun validFields(): Boolean {
if (username.text.isEmpty()) { if (username.text.isEmpty()) {
return false return false
@@ -0,0 +1,13 @@
package com.example.mear.constants
import android.os.Bundle
import android.content.res.Resources
import android.os.Environment
import com.example.mear.R
import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.android.synthetic.main.content_login.*
object AppDataPath {
val APP_DATA_PATH: String = Environment.getDataDirectory().toString()
}
@@ -0,0 +1,3 @@
package com.example.mear.models
class Token (var accessToken: String = "")
@@ -0,0 +1,3 @@
package com.example.mear.models
class User (var username: String = "", var password: String = "")
@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".activities.DemoStreamActivity"> tools:context=".activities.LoginActivity">
<android.support.design.widget.AppBarLayout <android.support.design.widget.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -28,6 +28,6 @@
android:layout_margin="@dimen/fab_margin" android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" /> app:srcCompat="@android:drawable/ic_dialog_email" />
<include layout="@layout/content_demo_stream" /> <include layout="@layout/content_login" />
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>
@@ -5,8 +5,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activities.DemoStreamActivity" tools:context=".activities.LoginActivity"
tools:showIn="@layout/activity_demo_stream"> tools:showIn="@layout/activity_login">
<Button <Button
android:id="@+id/demoStream" android:id="@+id/demoStream"
@@ -27,7 +27,6 @@
android:ems="10" android:ems="10"
android:hint="username" android:hint="username"
android:inputType="textPersonName" android:inputType="textPersonName"
android:text="kverse"
app:layout_constraintBottom_toTopOf="@+id/password" app:layout_constraintBottom_toTopOf="@+id/password"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
@@ -40,7 +39,6 @@
android:ems="10" android:ems="10"
android:hint="password" android:hint="password"
android:inputType="textPassword" android:inputType="textPassword"
android:text="demolaugh"
app:layout_constraintBottom_toTopOf="@+id/apiUri" app:layout_constraintBottom_toTopOf="@+id/apiUri"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
@@ -53,6 +51,7 @@
android:ems="10" android:ems="10"
android:hint="apiUri" android:hint="apiUri"
android:inputType="textPersonName" android:inputType="textPersonName"
android:text="https://www.soaricarus.com"
app:layout_constraintBottom_toTopOf="@+id/saveUserCred" app:layout_constraintBottom_toTopOf="@+id/saveUserCred"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />