summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2022-04-03 11:12:53 -0700
committerTrumeet <yuuta@yuuta.moe>2022-04-03 11:12:53 -0700
commit08b49f458c6adf2ac040a980cfde8ac0fdaf773f (patch)
treeec2f839345b72d3dbf7c4d11bd7f7db0d4c429de
parente2d4d73ee5519e32f43735f7c82609914434233e (diff)
downloadksyxbot-08b49f458c6adf2ac040a980cfde8ac0fdaf773f.tar
ksyxbot-08b49f458c6adf2ac040a980cfde8ac0fdaf773f.tar.gz
ksyxbot-08b49f458c6adf2ac040a980cfde8ac0fdaf773f.tar.bz2
ksyxbot-08b49f458c6adf2ac040a980cfde8ac0fdaf773f.zip
Add stats
-rw-r--r--query.c130
-rw-r--r--sql/1_2.sql9
-rw-r--r--tdutils.c2
-rw-r--r--tdutils.h2
4 files changed, 110 insertions, 33 deletions
diff --git a/query.c b/query.c
index b7c5058..6ec7a1f 100644
--- a/query.c
+++ b/query.c
@@ -14,7 +14,7 @@
#include <assert.h>
struct result {
- char id[10];
+ char id[32];
/* Title in selection */
char *title;
/* Description in selection */
@@ -32,31 +32,64 @@ static void cb_answer(bool successful, struct TdObject *result, struct TdError *
}
int handle_inline(struct TdUpdateNewInlineQuery *update) {
- struct result results[10];
+ struct result results[11];
memset(results, 0, sizeof(results));
sqlite3_stmt *stmt;
int r;
const bool query = update->query_;
- bool sys = false;
- if ((r = sqlite3_prepare_v2(db,
- query ? "SELECT id, t, url FROM says WHERE t LIKE ? LIMIT 10;"
- :"SELECT id, t, url FROM says ORDER BY RANDOM() LIMIT 10;",
- -1,
- &stmt,
- NULL))) {
+
+ if ((r = sqlite3_prepare_v2(db, "SELECT i FROM stats WHERE user = ?", -1, &stmt, NULL))) {
goto sql_err;
sql_err:
- snprintf(results[0].id, 10, "e%d", r);
+ snprintf(results[0].id, 32, "e%d", r);
char *msg = (char *) sqlite3_errstr(r);
LOGEV("Cannot query: %s.", msg);
results[0].title = "Error!";
results[0].text = msg;
results[0].description = msg;
- sys = true;
- sqlite3_finalize(stmt);
+ if (stmt) sqlite3_finalize(stmt);
goto answer;
}
+ if ((r = sqlite3_bind_int64(stmt, 1, update->sender_user_id_))) {
+ goto sql_err;
+ }
+
+ char msg_stat[32];
+ int st;
+ switch (r = sqlite3_step(stmt)) {
+ case SQLITE_ROW: {
+ st = sqlite3_column_int(stmt, 0);
+ goto st_answer;
+ st_answer:
+ snprintf(msg_stat, 32, "我已经卖了 %d 句菜", st);
+ results[0].title = "卖菜统计";
+ results[0].text = msg_stat;
+ results[0].description = "点击发送卖菜统计";
+ snprintf(results[0].id, 32, "s%lld", update->sender_user_id_);
+ break;
+ }
+ case SQLITE_DONE: {
+ st = 0;
+ goto st_answer;
+ }
+ default: {
+ goto sql_err;
+ }
+ }
+
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+
+ if ((r = sqlite3_prepare_v2(db,
+ query ? "SELECT id, t, url FROM says WHERE t LIKE ? LIMIT 10;"
+ : "SELECT id, t, url FROM says ORDER BY RANDOM() LIMIT 10;",
+ -1,
+ &stmt,
+ NULL))) {
+ goto sql_err;
+ }
+
char *query_str = NULL;
if (query) {
const size_t raw_query_len = strlen(update->query_);
@@ -73,7 +106,7 @@ int handle_inline(struct TdUpdateNewInlineQuery *update) {
}
}
- int j = 0;
+ int j = 1;
goto step;
step:
switch (r = sqlite3_step(stmt)) {
@@ -98,11 +131,11 @@ int handle_inline(struct TdUpdateNewInlineQuery *update) {
break;
}
results[j].title = title;
- snprintf(results[j].id, 10, "%d", sqlite3_column_int(stmt, 0));
+ snprintf(results[j].id, 32, "x_%d", sqlite3_column_int(stmt, 0));
results[j].text = t1;
results[j].url = url1;
results[j].description = url1;
- if ((++j) > 9) break;
+ if ((++j) > 10) break;
goto step;
}
case SQLITE_DONE: {
@@ -116,19 +149,12 @@ int handle_inline(struct TdUpdateNewInlineQuery *update) {
if (query_str) free(query_str);
sqlite3_finalize(stmt);
- if (!j) {
- results[0].title = "No data";
- results[0].description = "No data is available.";
- sprintf(results[0].id, "e_nodat");
- results[0].text = "No data is available. Adjust your search terms or check it out later.\n\n"
- "https://www.youtube.com/watch?v=dQw4w9WgXcQ";
- sys = true;
- }
+ /* There must be a stat option. */
assert(results[0].title);
goto answer;
answer:
{
- struct TdInputInlineQueryResultArticle *results_inline[10]; /* No need to memset(). Var 'i' will assure that. */
+ struct TdInputInlineQueryResultArticle *results_inline[11]; /* No need to memset(). Var 'i' will assure that. */
int i;
for (i = 0; i < sizeof(results) / sizeof(struct result); i++) {
struct result res = results[i];
@@ -164,17 +190,55 @@ int handle_inline(struct TdUpdateNewInlineQuery *update) {
NULL),
&cb_answer,
NULL);
- if (!sys) {
- for (i = 0; i < sizeof(results) / sizeof(struct result); i++) {
- struct result res = results[i];
- if (!res.title) {
- break;
- }
- free(res.title);
- if (res.url) free(res.url);
- free(res.text);
+ for (i = 1 /* 0 is error message or stats */;
+ i < sizeof(results) / sizeof(struct result); i++) {
+ struct result res = results[i];
+ if (!res.title) {
+ break;
}
+ free(res.title);
+ if (res.url) free(res.url);
+ free(res.text);
}
return r;
}
}
+
+int handle_inline_chosen(struct TdUpdateNewChosenInlineResult *update) {
+ if (!update->result_id_ || update->result_id_[0] != 'x' ||
+ update->result_id_[1] != '_') return 0;
+ int r;
+ sqlite3_stmt *stmt = NULL;
+ if ((r = sqlite3_prepare_v2(db, "UPDATE stats SET i = i + 1 WHERE user = ?;", -1, &stmt, NULL))) {
+ goto sql_err;
+ sql_err:
+ LOGEV("Cannot change stat: %s.", sqlite3_errstr(r));
+ if (stmt) sqlite3_finalize(stmt);
+ return r;
+ }
+ if ((r = sqlite3_bind_int64(stmt, 1, update->sender_user_id_))) {
+ goto sql_err;
+ }
+ if ((r = sqlite3_step(stmt)) != SQLITE_DONE) {
+ goto sql_err;
+ }
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+ if (sqlite3_changes(db)) {
+ return 0;
+ }
+ if ((r = sqlite3_prepare_v2(db, "INSERT INTO stats(user, i) VALUES(?, 1);",
+ -1,
+ &stmt,
+ NULL))) {
+ goto sql_err;
+ }
+ if ((r = sqlite3_bind_int64(stmt, 1, update->sender_user_id_))) {
+ goto sql_err;
+ }
+ if ((r = sqlite3_step(stmt)) != SQLITE_DONE) {
+ goto sql_err;
+ }
+ sqlite3_finalize(stmt);
+ return 0;
+}
diff --git a/sql/1_2.sql b/sql/1_2.sql
new file mode 100644
index 0000000..37d2168
--- /dev/null
+++ b/sql/1_2.sql
@@ -0,0 +1,9 @@
+-- Add stats
+CREATE TABLE "stats"
+(
+ "user" INTEGER UNIQUE,
+ "i" INTEGER NOT NULL,
+ PRIMARY KEY("user")
+);
+
+PRAGMA user_version = 2; \ No newline at end of file
diff --git a/tdutils.c b/tdutils.c
index 89fb3b2..0df00c3 100644
--- a/tdutils.c
+++ b/tdutils.c
@@ -323,6 +323,8 @@ static int handle_update(const struct TdUpdate *update) {
return handle_inline((struct TdUpdateNewInlineQuery *) update);
case CODE_UpdateOption:
return handle_option((struct TdUpdateOption *) update);
+ case CODE_UpdateNewChosenInlineResult:
+ return handle_inline_chosen((struct TdUpdateNewChosenInlineResult *) update);
default:
return 0;
}
diff --git a/tdutils.h b/tdutils.h
index c0653d5..db2f6de 100644
--- a/tdutils.h
+++ b/tdutils.h
@@ -25,4 +25,6 @@ int handle_message(struct TdUpdateNewMessage *update);
int handle_inline(struct TdUpdateNewInlineQuery * update);
+int handle_inline_chosen(struct TdUpdateNewChosenInlineResult *);
+
#endif /* _TDUTILS_H */ \ No newline at end of file