Able to retrieve an access token. Next implement fetching all songs. I left a TODO.

This commit was merged in pull request #56.
This commit is contained in:
kdeng00
2019-10-03 20:35:59 -04:00
parent 3c8064dfd2
commit 77ecf4ca12
10 changed files with 257 additions and 152 deletions
+1 -1
View File
@@ -64,6 +64,7 @@
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/classes" /> <output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/classes" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
@@ -125,7 +126,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/cpp" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.cxx" /> <excludeFolder url="file://$MODULE_DIR$/.cxx" />
<excludeFolder url="file://$MODULE_DIR$/.externalNativeBuild" /> <excludeFolder url="file://$MODULE_DIR$/.externalNativeBuild" />
<excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/build" />
+19 -23
View File
@@ -15,13 +15,16 @@ cmake_minimum_required(VERSION 3.4.1)
set (SOURCES set (SOURCES
Demo.cpp Demo.cpp
SongRepository.cpp
Tok.cpp Tok.cpp
) )
set (HEADERS set (HEADERS
model/Song.h model/Song.h
model/User.h model/User.h
SongRepository.h
Tok.h Tok.h
) )
set(JSON_BuildTests OFF CACHE INTERNAL "") set(JSON_BuildTests OFF CACHE INTERNAL "")
@@ -29,13 +32,12 @@ set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/json) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/json)
add_library(native-lib add_library(native-lib SHARED
SHARED
# Provides a relative path to your source file(s). # Provides a relative path to your source file(s).
${SOURCES} ${SOURCES}
${HEADERS} ${HEADERS}
) )
# Searches for a specified prebuilt library and stores the path as a # Searches for a specified prebuilt library and stores the path as a
@@ -44,27 +46,26 @@ add_library(native-lib
# you want to add. CMake verifies that the library exists before # you want to add. CMake verifies that the library exists before
# completing its build. # completing its build.
find_library( # Sets the name of the path variable. find_library(log-lib
log-lib
# Specifies the name of the NDK library that # Specifies the name of the NDK library that
# you want CMake to locate. # you want CMake to locate.
log ) log
)
# message(${CMAKE_ANDROID_ARCH_ABI})
set (CURL_LIBRARY set (CURL_LIBRARY
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/${ANDROID_ABI} ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/${ANDROID_ABI}
) )
set (CURL_INCLUDE_DIR set (CURL_INCLUDE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/include/curl ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/include/curl
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/include ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/include
) )
add_library(boo STATIC IMPORTED) add_library(boo STATIC IMPORTED)
set_target_properties(boo PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/${ANDROID_ABI}/libcurl.a") set_target_properties(boo PROPERTIES IMPORTED_LOCATION
#find_package(CURL REQUIRED) "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/${ANDROID_ABI}/libcurl.a"
)
include_directories(${CURL_INCLUDE_DIR}) include_directories(${CURL_INCLUDE_DIR})
@@ -72,15 +73,10 @@ include_directories(${CURL_INCLUDE_DIR})
# can link multiple libraries, such as libraries you define in this # can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries. # build script, prebuilt third-party libraries, or system libraries.
#target_include_directories(native-lib PUBLIC ${CURL_INCLUDE_DIR}) target_link_libraries(native-lib PRIVATE
target_link_libraries( # Specifies the target library.
native-lib
PRIVATE nlohmann_json::nlohmann_json
boo
#${CURL_LIBRARIES}
# Links the target library to the log library nlohmann_json::nlohmann_json
# included in the NDK. boo
${log-lib} ${log-lib}
z z
) )
+21 -115
View File
@@ -20,134 +20,40 @@
#include "model/Song.h" #include "model/Song.h"
#include "model/User.h" #include "model/User.h"
#include "Tok.h"
std::string fetchToken(); std::string fetchToken(const std::string&, const std::string&, const std::string&);
model::Song initSong();
model::User initUser();
size_t funcTest(void*, size_t, size_t, char*);
//size_t funcTest(void*, size_t, size_t, std::string&);
int demoCall();
void printSong(const model::Song&);
std::string fetchToken() std::string fetchToken(const std::string& username, const std::string& password,
const std::string& apiUri)
{ {
auto user = initUser(); model::User user(username, password);
nlohmann::json usr; manager::Tok tokMgr;
usr["username"] = user.username;
usr["password"] = user.password;
CURL *curl; auto token = tokMgr.fetchToken(user, apiUri);
CURLcode res;
curl = curl_easy_init(); return token;
std::string tok;
if (curl) {
const auto url = "";
char resp[2048];
curl_easy_setopt(curl, CURLOPT_URL, url);
const std::string a = usr.dump();
//std::string r;
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, a.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, funcTest);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, resp);
//curl_easy_setopt(curl, CURLOPT_WRITEDATA, r);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
const std::string i = resp;
auto s = nlohmann::json::parse(i);
tok = s["token"].get<std::string>();
return tok;
}
return "";
}
model::Song initSong()
{
model::Song song;
song.title = "hello";
song.artist = "some artist";
return song;
}
model::User initUser()
{
model::User user;
user.username = "";
user.password = "";
return user;
}
size_t funcTest(void* ptr, size_t size, size_t nmemb, char *e)
{
std::memcpy(e, ptr, nmemb);
e[nmemb] = '\0';
return nmemb;
}
size_t funcTest(void* ptr, size_t size, size_t nmemb, std::string& e)
{
e = (char*) ptr;
return nmemb;
}
int demoCall()
{
model::Song song = initSong();
std::cout << "testing" << std::endl;
printSong(song);
return 0;
}
void printSong(const model::Song& song)
{
std::cout << "\nsong information" << std::endl;
std::cout << "title: " << song.title << std::endl;
std::cout << "artist: " << song.artist << std::endl;
std::cout << "album: " << song.album << std::endl;
std::cout << "genre: " << song.genre << std::endl;
std::cout << "year: " << song.year << std::endl;
} }
extern "C" extern "C"
JNIEXPORT void JNIEXPORT jstring
JNICALL
Java_com_example_mear_activities_MainActivity_test(
JNIEnv *env,
jobject /* this */) {
demoCall();
}
extern "C"
JNIEXPORT void
JNICALL JNICALL
Java_com_example_mear_activities_DemoStreamActivity_test( Java_com_example_mear_activities_DemoStreamActivity_logUser(
JNIEnv *env, JNIEnv *env,
jobject /* this */) { jobject thisObj,
jstring username,
jstring password,
jstring apiUri ) {
auto tok = fetchToken(); 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());
} }
+16
View File
@@ -0,0 +1,16 @@
//
// Created by brahmix on 10/3/19.
//
#include "SongRepository.h"
namespace repository {
// TODO: implement this
std::vector<model::Song> SongRepository::fetchSongs(const std::string& token,
const std::string& uri)
{
std::vector<model::Song> songs;
return songs;
}
}
+23
View File
@@ -0,0 +1,23 @@
//
// Created by brahmix on 10/3/19.
//
#ifndef MEAR_SONGREPOSITORY_H
#define MEAR_SONGREPOSITORY_H
#include <string>
#include <vector>
#include "model/Song.h"
namespace repository {
class SongRepository {
public:
std::vector<model::Song> fetchSongs(const std::string&, const std::string&);
private:
};
}
#endif //MEAR_SONGREPOSITORY_H
+66
View File
@@ -3,3 +3,69 @@
// //
#include "Tok.h" #include "Tok.h"
#include <cstring>
#include <curl/curl.h>
#include <nlohmann/json.hpp>
namespace manager {
std::string Tok::fetchToken(const model::User &user, const std::string& uri) {
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (!curl) {
return "none";
}
char resp[2048];
const auto loginUri = fetchLoginUri(uri);
const auto obj = userJsonString(user);
curl_easy_setopt(curl, CURLOPT_URL, loginUri.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, obj.c_str());
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);
return s["token"].get<std::string>();
}
return "failure";
}
std::string Tok::fetchLoginUri(const std::string& baseUri)
{
std::string uri(baseUri);
uri.append("/api/v1/login");
return uri;
}
std::string Tok::userJsonString(const model::User& user)
{
nlohmann::json usr;
usr["username"] = user.username;
usr["password"] = user.password;
return usr.dump();
}
size_t Tok::respBodyRetriever(void* ptr, size_t size, size_t nmemb, char *e)
{
std::memcpy(e, ptr, nmemb);
e[nmemb] = '\0';
return nmemb;
}
}
+13 -2
View File
@@ -7,9 +7,20 @@
#include <string> #include <string>
class Tok { #include "model/User.h"
}; namespace manager {
class Tok {
public:
std::string fetchToken(const model::User&, const std::string&);
private:
std::string fetchLoginUri(const std::string&);
std::string userJsonString(const model::User&);
static size_t respBodyRetriever(void*, size_t, size_t, char*);
};
}
#endif //MEAR_TOK_H #endif //MEAR_TOK_H
+4 -1
View File
@@ -5,11 +5,14 @@
#ifndef MEAR_USER_H #ifndef MEAR_USER_H
#define MEAR_USER_H #define MEAR_USER_H
//#include "../../../../../../../../Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/string"
namespace model { namespace model {
struct User struct User
{ {
User() = default;
User(const std::string& user, const std::string& pass) :
username(user), password(pass) { }
std::string username; std::string username;
std::string password; std::string password;
}; };
@@ -7,6 +7,7 @@ import com.example.mear.R
import kotlinx.android.synthetic.main.activity_demo_stream.* import kotlinx.android.synthetic.main.activity_demo_stream.*
import kotlinx.android.synthetic.main.content_demo_stream.* import kotlinx.android.synthetic.main.content_demo_stream.*
import org.jetbrains.anko.toast
class DemoStreamActivity : AppCompatActivity() { class DemoStreamActivity : AppCompatActivity() {
@@ -17,7 +18,8 @@ class DemoStreamActivity : AppCompatActivity() {
} }
external fun test(); private external fun logUser(usr: String, pass: String, api: String): String
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -25,7 +27,11 @@ class DemoStreamActivity : AppCompatActivity() {
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
demoStream.setOnClickListener { demoStream.setOnClickListener {
test() toast("vacant").show()
}
login.setOnClickListener {
loginButton()
} }
fab.setOnClickListener {view -> fab.setOnClickListener {view ->
@@ -34,4 +40,32 @@ class DemoStreamActivity : AppCompatActivity() {
} }
} }
private fun loginButton() {
if (!validFields()) {
toast("Fields are invalid").show()
return
}
var usernameStr = username.text.toString()
var passwordStr = password.text.toString()
var apiUriStr = apiUri.text.toString()
var token = logUser(usernameStr, passwordStr, apiUriStr)
toast(token).show()
}
private fun validFields(): Boolean {
if (username.text.isEmpty()) {
return false
}
if (password.text.isEmpty()) {
return false
}
if (password.text.isEmpty()) {
return false
}
return true
}
} }
@@ -12,10 +12,60 @@
android:id="@+id/demoStream" android:id="@+id/demoStream"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="140dp" android:layout_marginStart="16dp"
android:text="Stream" android:text="Stream"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.499" /> app:layout_constraintVertical_bias="0.954" />
<EditText
android:id="@+id/username"
android:layout_width="245dp"
android:layout_height="43dp"
android:layout_marginBottom="32dp"
android:ems="10"
android:hint="username"
android:inputType="textPersonName"
android:text="kverse"
app:layout_constraintBottom_toTopOf="@+id/password"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/password"
android:layout_width="245dp"
android:layout_height="43dp"
android:layout_marginBottom="32dp"
android:ems="10"
android:hint="password"
android:inputType="textPassword"
android:text="demolaugh"
app:layout_constraintBottom_toTopOf="@+id/apiUri"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/apiUri"
android:layout_width="245dp"
android:layout_height="43dp"
android:layout_marginBottom="76dp"
android:ems="10"
android:hint="apiUri"
android:inputType="textPersonName"
app:layout_constraintBottom_toTopOf="@+id/login"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="92dp"
android:text="Login"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>