summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorꦌꦫꦶꦏ꧀ꦦꦿꦧꦮꦑꦩꦭ꧀ <erik@darapsa.co.id>2021-07-10 23:21:25 +0800
committerꦌꦫꦶꦏ꧀ꦦꦿꦧꦮꦑꦩꦭ꧀ <erik@darapsa.co.id>2021-07-10 23:21:25 +0800
commit5d0a833af478b87f4fb815e37da0beb5a09c6067 (patch)
tree00a1e021aea50625d0c57ddeb4321af47a3c0641
parent873f8a55d01ecbd11c957d140eaf2a0bb30ae51f (diff)
Use the response data to initiate client
It's correct now, but the problem is, the client pushes the catalog page faster than the web server can reload to make the newly built sample URL valid.
-rw-r--r--controller.cxx76
-rw-r--r--controller.hxx3
-rw-r--r--handler.c15
-rw-r--r--namatoko.pro3
-rw-r--r--registration.c88
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
diff --git a/handler.c b/handler.c
index 8e118f7..1a0ce01 100644
--- a/handler.c
+++ b/handler.c
@@ -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
}