diff options
author | Trumeet <yuuta@yuuta.moe> | 2022-11-18 17:26:25 -0800 |
---|---|---|
committer | Trumeet <yuuta@yuuta.moe> | 2022-11-18 17:26:25 -0800 |
commit | 3ebff2e47ab77a74fd9905896046ef66531b2b14 (patch) | |
tree | 97061a3f2a9f9de1022f3c63c9c7068a3dd1e7ff | |
download | hitokoto-3ebff2e47ab77a74fd9905896046ef66531b2b14.tar hitokoto-3ebff2e47ab77a74fd9905896046ef66531b2b14.tar.gz hitokoto-3ebff2e47ab77a74fd9905896046ef66531b2b14.tar.bz2 hitokoto-3ebff2e47ab77a74fd9905896046ef66531b2b14.zip |
First Commit
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | PKGBUILD | 29 | ||||
-rw-r--r-- | README.md | 23 | ||||
-rw-r--r-- | init.sql | 28 | ||||
-rw-r--r-- | m2.c | 79 | ||||
-rw-r--r-- | types | 5 |
6 files changed, 170 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2bbb1ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +pkg/ +src/ +*.log +*.zst +*.db +hitokoto diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..9f9338d --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,29 @@ +# Maintainer: Yuuta Liang <yuuta@yuuta.moe> +pkgname=hitokoto +pkgver=2.0 +pkgrel=1 +epoch= +pkgdesc="Yuuta's Hitokoto" +arch=(x86_64) +url="https://www.youtube.com/watch?v=dQw4w9WgXcQ" +license=('custom') +groups=() +depends=(sqlite3 fcgi) +source=("m2.c" +"init.sql") +sha256sums=('80aa15bca8361fd4430c114be633e024ee10df84e9a2d6b8939c5ab5407eeb38' + 'e71a00dfb9a2744f482de80e33c02341d6cae19a1f54e53a5346d972bfeff054') + +build() { + cd "$srcdir" + cc -Wall -O3 -lsqlite3 -lfcgi -o hitokoto m2.c +} + +package() { + cd "$srcdir" + mkdir -p $pkgdir/usr/bin/ + cp hitokoto $pkgdir/usr/bin/ + chmod 755 $pkgdir/usr/bin/hitokoto + mkdir -p $pkgdir/usr/share/$pkgdir/doc/ + cp init.sql $pkgdir/usr/share/$pkgdir/doc/ +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..7c5f29f --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Hitokoto + +Yuuta's hitokoto + +## Installation + +```shell +makepkg +pacman -U ./hitokoto-*.zst +``` + +## Usage + +```shell +sqlite3 /path/to/data.db '.read /usr/share/hitokoto/doc/init.sql' +spawn-fcgi -n -p 8080 /usr/bin/hitokoto /path/to/data.db +``` + +Use your favourite SQLite editor to add sources and quotes. + +## License + +WTFPL diff --git a/init.sql b/init.sql new file mode 100644 index 0000000..ff62b67 --- /dev/null +++ b/init.sql @@ -0,0 +1,28 @@ +BEGIN TRANSACTION; +CREATE TABLE "quotes" ( + "id" INTEGER, + "source" INTEGER NOT NULL, + "time" INTEGER NOT NULL, + "text" TEXT NOT NULL, + "text_zh" INTEGER, + FOREIGN KEY("source") REFERENCES "sources"("id") ON DELETE CASCADE ON UPDATE CASCADE, + PRIMARY KEY("id" AUTOINCREMENT) +); +CREATE TABLE "sources" ( + "id" INTEGER, + "type" INTEGER NOT NULL, + "title" TEXT NOT NULL, + "title_zh" TEXT, + PRIMARY KEY("id" AUTOINCREMENT) +); +CREATE VIEW "v_random_quote" AS +SELECT + sources.title, + sources.title_zh, + text, + text_zh +FROM quotes +INNER JOIN sources ON sources.id = quotes.source +ORDER BY RANDOM() +LIMIT 1; +COMMIT; @@ -0,0 +1,79 @@ +#define _POSIX_C_SOURCE 200809L + +#include <fcgiapp.h> +#include <sqlite3.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include <assert.h> + +struct fcgi_env { + FCGX_Stream *in; + FCGX_Stream *out; + FCGX_Stream *err; + FCGX_ParamArray *envp; +}; + +static sqlite3 *db = NULL; + +static void cleanup(void) { + if (db) { + sqlite3_close(db); + } +} + +static int cb(void *dat, int count, char **data, char **columns) { + struct fcgi_env *env = dat; + if (count != 3) { + FCGX_FPrintF(env->out, + "Status: 500 Internal Server Error\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "The database returned %d columns.\n", + count); + } + FCGX_FPrintF(env->out, + "Content-type: application/json\r\n" + "\r\n" + "{\"title\":\"%s\",\"title_zh\":\"%s\",\"text\":\"%s\",\"text_zh\":\"%s\"\"}\n", + data[0], + data[1] == NULL ? "" : data[1], + data[2], + data[3]); + + return 0; +} + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s /path/to/data.db\n", argv[0]); + return 64; + } + atexit(cleanup); + int r; + if ((r = sqlite3_open_v2(argv[1], &db, SQLITE_OPEN_READONLY, NULL)) != SQLITE_OK) { + fprintf(stderr, "Cannot open database: %s\n", sqlite3_errstr(r)); + return r; + } + FCGX_Stream *in, *out, *err; + FCGX_ParamArray envp; + struct fcgi_env env; + char *errmsg; + while(FCGX_Accept(&in, &out, &err, &envp) >= 0) { + env.in = in; + env.out = out; + env.err = err; + env.envp = &envp; + if ((r = sqlite3_exec(db, "SELECT title,title_zh,text,text_zh FROM v_random_quote", + cb, &env, &errmsg))) { + FCGX_FPrintF(out, + "Status: 500 Internal Server Error\r\n" + "Content-type: text/plain\r\n" + "\r\n" + "%s\n", + errmsg); + sqlite3_free(errmsg); + } + } +} @@ -0,0 +1,5 @@ +0 Anime +1 Song +2 Novel +3 Game +4 Friends |