diff options
-rw-r--r-- | controller.cxx | 76 | ||||
-rw-r--r-- | controller.hxx | 3 | ||||
-rw-r--r-- | handler.c | 15 | ||||
-rw-r--r-- | namatoko.pro | 3 | ||||
-rw-r--r-- | registration.c | 88 |
5 files changed, 128 insertions, 57 deletions
diff --git a/controller.cxx b/controller.cxx index e70a66d..6f7759f 100644 --- a/controller.cxx +++ b/controller.cxx @@ -1,55 +1,67 @@ +#include <icclient.h> #include <QtQml> #include <qicclient/admin.hxx> #include "controller.hxx" extern "C" { - void sign_up(char const*, char const*); - struct icclient_catalog* catalog_data(char const*); + void sign_up(char const*, char const*, void (*)(icclient_response *)); + struct icclient_catalog* catalog_data(char const*, char const*); } -Controller::Controller(QObject* parent) : - QObject{parent}, - catalog{nullptr} +static Controller* controller; +static QQmlApplicationEngine* engine; +static QICClient::Client* interchange = nullptr; +static QString* path = nullptr; +static QString* imageDir = nullptr; +static Catalog* catalog = nullptr; + +Controller::Controller(QObject* parent) : QObject{parent} { + controller = this; #ifdef __ANDROID__ QString cert{CA_BUNDLE}; - QString path{QDir{QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)}.absolutePath() - % cert.remove(0, cert.lastIndexOf("/"))}; - QFile{"assets:" % cert}.copy(path); -#endif - interchange = new Client{SAMPLEURL, IMAGE_DIR -#ifdef __ANDROID__ - , path.toLatin1().constData() + path = new QString{QDir{ + QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)}.absolutePath() + % cert.remove(0, cert.lastIndexOf("/"))}; + QFile{"assets:" % cert}.copy(*path); #endif - }; - auto engine = static_cast<QQmlApplicationEngine*>(parent); + engine = static_cast<QQmlApplicationEngine*>(parent); engine->load(QUrl{QStringLiteral("qrc:/main.qml")}); auto window = engine->rootObjects()[0]; - window->setProperty("imageDir", SAMPLEURL"/images/"); connect(window, SIGNAL(signUp(QString)), this, SIGNAL(signUp(QString))); - connect(this, &Controller::signUp, [/*this,*/ + connect(this, &Controller::signUp, [](QString const& brand) { + sign_up(brand.toLatin1().constData(), path ? path->toLatin1().constData() : nullptr, + [](icclient_response* response) { + QString brand{response->data}; + icclient_free_response(response); + QString sampleUrl{QString{SECURE_SERVER} % "/" % brand}; + imageDir = new QString{"/" % brand % "/images"}; + interchange = new Client{sampleUrl.toLatin1().constData(), + imageDir->toLatin1().constData() #ifdef __ANDROID__ - path + , path->toLatin1().constData() #endif - ](QString const& brand) { - sign_up(brand.toLatin1().constData(), -#ifdef __ANDROID__ - path.toLatin1().constData() -#else - nullptr -#endif - ); -// interchange->catalog(brand); - }); - connect(interchange, &Client::gotCatalog, [this,engine,window](QString const& response) { - catalog = new Catalog{catalog_data(response.toLatin1().constData())}; - engine->rootContext()->setContextProperty("catalog", catalog); - QMetaObject::invokeMethod(window, "pushCatalog"); + }; + delete path; + auto window = engine->rootObjects()[0]; + window->setProperty("imageDir", QString{sampleUrl % "/images/"}); + controller->connect(interchange, &Client::gotCatalog, + [window](QString const& response) { + catalog = new Catalog{ + catalog_data(response.toLatin1().constData(), + imageDir->toLatin1().constData())}; + engine->rootContext()->setContextProperty("catalog", + catalog); + QMetaObject::invokeMethod(window, "pushCatalog"); + }); + interchange->allProducts(); + }); }); } Controller::~Controller() { if (catalog) delete catalog; - delete interchange; + if (imageDir) delete imageDir; + if (interchange) delete interchange; } diff --git a/controller.hxx b/controller.hxx index b073a67..845179b 100644 --- a/controller.hxx +++ b/controller.hxx @@ -13,9 +13,6 @@ class Controller : public QObject ~Controller(); signals: void signUp(QString const& name); - private: - Client* interchange; - Catalog* catalog; }; #endif @@ -3,21 +3,24 @@ #include <tidybuffio.h> #include <icclient.h> -static void recurse_catalog(TidyDoc doc, TidyNode tnod, struct icclient_catalog **catalog) +static void recurse_catalog(TidyDoc doc, TidyNode tnod, const char *image_dir, + struct icclient_catalog **catalog) { for (TidyNode child = tidyGetChild(tnod); child; child = tidyGetNext(child)) { ctmbstr name = tidyNodeGetName(child); if (!name) continue; if (strcmp(name, "img")) { - recurse_catalog(doc, child, catalog); + recurse_catalog(doc, child, image_dir, catalog); continue; } - static const char *prefix = IMAGE_DIR"/thumb/"; + static const char *subdir = "/thumb/"; + char prefix[strlen(image_dir) + strlen(subdir) + 1]; size_t prefix_len = strlen(prefix); bool bail = false; for (TidyAttr attr = tidyAttrFirst(child); attr; attr = tidyAttrNext(attr)) - if (!strcmp(tidyAttrName(attr), "src") && strncmp(tidyAttrValue(attr), prefix, prefix_len)) { + if (!strcmp(tidyAttrName(attr), "src") + && strncmp(tidyAttrValue(attr), prefix, prefix_len)) { bail = true; break; } @@ -47,7 +50,7 @@ static void recurse_catalog(TidyDoc doc, TidyNode tnod, struct icclient_catalog } } -struct icclient_catalog *catalog_data(const char *response) +struct icclient_catalog *catalog_data(const char *response, const char *image_dir) { TidyDoc tdoc = tidyCreate(); TidyBuffer output = {0}; @@ -55,7 +58,7 @@ struct icclient_catalog *catalog_data(const char *response) tidySaveBuffer(tdoc, &output); struct icclient_catalog *catalog = malloc(sizeof(struct icclient_catalog)); catalog->length = 0; - recurse_catalog(tdoc, tidyGetRoot(tdoc), &catalog); + recurse_catalog(tdoc, tidyGetRoot(tdoc), image_dir, &catalog); tidyBufFree(&output); tidyRelease(tdoc); return catalog; diff --git a/namatoko.pro b/namatoko.pro index b2830b8..c01e708 100644 --- a/namatoko.pro +++ b/namatoko.pro @@ -1,8 +1,7 @@ QT += quickcontrols2 DEFINES += \ CA_BUNDLE=\\\"$$CA_BUNDLE\\\" \ - SAMPLEURL=\\\"$$SAMPLEURL\\\" \ - IMAGE_DIR=\\\"$$IMAGE_DIR\\\" + SECURE_SERVER=\\\"$$SECURE_SERVER\\\" debug: DEFINES += DEBUG HEADERS += controller.hxx SOURCES += \ diff --git a/registration.c b/registration.c index f3a6a0a..5e0fe00 100644 --- a/registration.c +++ b/registration.c @@ -1,35 +1,86 @@ +#ifdef DEBUG +#ifdef __ANDROID__ +#include <android/log.h> +#else +#include <stdio.h> +#endif #ifdef __EMSCRIPTEN__ -#include <stdlib.h> -#include <string.h> #include <emscripten/fetch.h> #else +#include <threads.h> #include <curl/curl.h> #endif +#include <stdlib.h> +#include <string.h> +#include <icclient/typedefs.h> #ifdef __EMSCRIPTEN__ -static void cleanup(struct emscripten_fetch_t *fetch) +static void clean_up(struct emscripten_fetch_t *fetch) { free(fetch->userData); emscripten_fetch_close(fetch); } +#else + +struct container { + CURL *curl; + void (*handler)(icclient_response *); + icclient_response *response; +}; + +static size_t append(char *data, size_t size, size_t nmemb, icclient_response *response) +{ + size_t realsize = size * nmemb; + response->data = realloc(response->data, response->numBytes + realsize + 1); + memcpy(&(response->data[response->numBytes]), data, realsize); + response->numBytes += realsize; + response->data[response->numBytes] = '\0'; + return realsize; +} + +static int async(void *arg) +{ + int ret = thrd_success; + struct container *container = (struct container *)arg; + CURLcode res = curl_easy_perform(container->curl); + if (res == CURLE_OK) + container->handler(container->response); + else { + ret = thrd_error; +#ifdef DEBUG + const char *error = curl_easy_strerror(res); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_ERROR, "namatoko.so", "%s", error); +#else + fprintf(stderr, "%s\n", error); +#endif +#endif + } + curl_easy_cleanup(container->curl); + free(container); + curl_global_cleanup(); + return ret; +} #endif -void sign_up(const char *brand, const char *certificate) +#endif + +void sign_up(const char *brand, const char *certificate, void (*handler)(icclient_response *)) { + char *data = malloc(strlen(brand) + 1); + strcpy(data, brand); #ifdef __EMSCRIPTEN__ emscripten_fetch_attr_t attr; emscripten_fetch_attr_init(&attr); attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; strcpy(attr.requestMethod, "POST"); - char *data = malloc(strlen(brand) + 1); - strcpy(data, brand); attr.requestData = data; - attr.requestDataSize = strlen(data) + 1; + attr.requestDataSize = strlen(data); attr.userData = data; - attr.onsuccess = cleanup; - attr.onerror = cleanup; + attr.onsuccess = handler; + attr.onerror = clean_up; emscripten_fetch(&attr, "registration"); (void)certificate; #else @@ -41,10 +92,19 @@ void sign_up(const char *brand, const char *certificate) #ifdef DEBUG curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); #endif - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, brand); - curl_easy_setopt(curl, CURLOPT_URL, SAMPLEURL"/registration"); - curl_easy_perform(curl); - curl_easy_cleanup(curl); - curl_global_cleanup(); + curl_easy_setopt(curl, CURLOPT_URL, SECURE_SERVER"/registration"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, append); + icclient_response *response = malloc(sizeof(icclient_response)); + response->data = malloc(1); + response->numBytes = 0; + response->userData = data; + curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + struct container *container = malloc(sizeof(struct container)); + container->curl = curl; + container->handler = handler; + container->response = response; + thrd_t thread; + thrd_create(&thread, async, container); #endif } |