Compare commits

...

19 Commits

Author SHA1 Message Date
b2a157e24d Update docs 2020-08-25 10:38:38 -04:00
9aead9389a Fix typo in elastic.c 2020-08-25 10:38:38 -04:00
a32c68cba8 Build fixes 2020-08-25 10:38:38 -04:00
d116cf9d91 Default index for web & exec 2020-08-25 10:38:38 -04:00
Andrew
a020a8b32c Update USAGE.md
Fix link to scripting.
2020-08-25 10:38:38 -04:00
5d5d9c3092 Fix heap buffer overflow warning 2020-08-25 10:38:38 -04:00
3379d5ce71 Fix #97 2020-08-25 10:38:38 -04:00
a0ff4a1f01 Fix heap buffer overflow warning 2020-08-25 10:38:38 -04:00
4589f3bde7 Fix #94 2020-08-25 10:38:38 -04:00
1c898640cf Fix #88 2020-08-25 10:38:38 -04:00
a0739d5177 Fix #92 2020-08-25 10:38:38 -04:00
8f9d29dbc6 Fix #91 2020-08-25 10:38:38 -04:00
3ff4b70223 Update README.md 2020-08-25 10:38:38 -04:00
02ad035b09 Workaround when first ebook page is blank 2020-08-25 10:38:38 -04:00
c11feb213d Gracefully handle archive errors in comic.c 2020-08-25 10:38:38 -04:00
72902947cd Fix for #90 2020-08-25 10:38:38 -04:00
a18bb81222 remove warning 2020-08-25 10:38:38 -04:00
1520288f19 Fix #89 2020-08-25 10:38:38 -04:00
e507de194b Fix log colors 2020-08-25 10:38:38 -04:00
19 changed files with 151 additions and 55 deletions

View File

@@ -2,6 +2,8 @@
[![CodeFactor](https://www.codefactor.io/repository/github/simon987/sist2/badge?s=05daa325188aac4eae32c786f3d9cf4e0593f822)](https://www.codefactor.io/repository/github/simon987/sist2) [![CodeFactor](https://www.codefactor.io/repository/github/simon987/sist2/badge?s=05daa325188aac4eae32c786f3d9cf4e0593f822)](https://www.codefactor.io/repository/github/simon987/sist2)
[![Development snapshots](https://ci.simon987.net/app/rest/builds/buildType(Sist2_Build)/statusIcon)](https://files.simon987.net/artifacts/Sist2/Build/) [![Development snapshots](https://ci.simon987.net/app/rest/builds/buildType(Sist2_Build)/statusIcon)](https://files.simon987.net/artifacts/Sist2/Build/)
**Demo**: [sist2.simon987.net](https://sist2.simon987.net/)
# sist2 # sist2
sist2 (Simple incremental search tool) sist2 (Simple incremental search tool)
@@ -124,7 +126,7 @@ binaries (GCC 7+ required).
1. Install compile-time dependencies 1. Install compile-time dependencies
```bash ```bash
vcpkg install lmdb cjson glib libarchive[core,bzip2,libxml2,lz4,lzma,lzo] pthread tesseract libxml2 ffmpeg zstd gtest mongoose libuuid libmagic libraw vcpkg install lmdb cjson glib libarchive[core,bzip2,libxml2,lz4,lzma,lzo] pthread tesseract libxml2 ffmpeg zstd gtest mongoose libuuid libmagic libraw curl[core,ssl] jbig2dec
``` ```
2. Build 2. Build

View File

@@ -49,6 +49,7 @@ Scan options
Index options Index options
-t, --threads=<int> Number of threads. DEFAULT=1 -t, --threads=<int> Number of threads. DEFAULT=1
--es-url=<str> Elasticsearch url with port. DEFAULT=http://localhost:9200 --es-url=<str> Elasticsearch url with port. DEFAULT=http://localhost:9200
--es-index=<str> Elasticsearch index name. DEFAULT=sist2
-p, --print Just print JSON documents to stdout. -p, --print Just print JSON documents to stdout.
--script-file=<str> Path to user script. --script-file=<str> Path to user script.
--async-script Execute user script asynchronously. --async-script Execute user script asynchronously.
@@ -57,11 +58,14 @@ Index options
Web options Web options
--es-url=<str> Elasticsearch url. DEFAULT=http://localhost:9200 --es-url=<str> Elasticsearch url. DEFAULT=http://localhost:9200
--es-index=<str> Elasticsearch index name. DEFAULT=sist2
--bind=<str> Listen on this address. DEFAULT=localhost:4090 --bind=<str> Listen on this address. DEFAULT=localhost:4090
--auth=<str> Basic auth in user:password format --auth=<str> Basic auth in user:password format
--tag-auth=<str> Basic auth in user:password format for tagging --tag-auth=<str> Basic auth in user:password format for tagging
Exec-script options Exec-script options
--es-url=<str> Elasticsearch url. DEFAULT=http://localhost:9200
--es-index=<str> Elasticsearch index name. DEFAULT=sist2
--script-file=<str> Path to user script. --script-file=<str> Path to user script.
--async-script Execute user script asynchronously. --async-script Execute user script asynchronously.
Made by simon987 <me@simon987.net>. Released under GPL-3.0 Made by simon987 <me@simon987.net>. Released under GPL-3.0
@@ -241,6 +245,8 @@ it is currently unsupported and has no guaranties of back/forward compatibility.
* `--es-url` * `--es-url`
Elasticsearch url and port. If you are using docker, make sure that both containers are on the Elasticsearch url and port. If you are using docker, make sure that both containers are on the
same network. same network.
* `--es-index`
Elasticsearch index name. DEFAULT=sist2
* `-p, --print` * `-p, --print`
Print index in JSON format to stdout. Print index in JSON format to stdout.
* `--script-file` * `--script-file`
@@ -278,6 +284,8 @@ sist2 index --print ./my_index/ | jq | less
### Web options ### Web options
* `--es-url=<str>` Elasticsearch url. * `--es-url=<str>` Elasticsearch url.
* `--es-index`
Elasticsearch index name. DEFAULT=sist2
* `--bind=<str>` Listen on this address. * `--bind=<str>` Listen on this address.
* `--auth=<str>` Basic auth in user:password format * `--auth=<str>` Basic auth in user:password format
* `--tag-auth=<str>` Basic auth in user:password format. Works the same way as the * `--tag-auth=<str>` Basic auth in user:password format. Works the same way as the
@@ -340,4 +348,4 @@ See [Automatic tagging](#automatic-tagging) for information about tag
### Automatic tagging ### Automatic tagging
See [scripting](docs/scripting.md) documentation. See [scripting](scripting.md) documentation.

View File

@@ -54,6 +54,10 @@
"type": "integer", "type": "integer",
"index": false "index": false
}, },
"pages": {
"type": "integer",
"index": false
},
"mtime": { "mtime": {
"type": "integer" "type": "integer"
}, },

View File

@@ -9,6 +9,7 @@
#define DEFAULT_REWRITE_URL "" #define DEFAULT_REWRITE_URL ""
#define DEFAULT_ES_URL "http://localhost:9200" #define DEFAULT_ES_URL "http://localhost:9200"
#define DEFAULT_ES_INDEX "sist2"
#define DEFAULT_BATCH_SIZE 100 #define DEFAULT_BATCH_SIZE 100
#define DEFAULT_LISTEN_ADDRESS "localhost:4090" #define DEFAULT_LISTEN_ADDRESS "localhost:4090"
@@ -287,6 +288,10 @@ int index_args_validate(index_args_t *args, int argc, const char **argv) {
args->es_url = DEFAULT_ES_URL; args->es_url = DEFAULT_ES_URL;
} }
if (args->es_index == NULL) {
args->es_index = DEFAULT_ES_INDEX;
}
if (args->script_path != NULL) { if (args->script_path != NULL) {
if (load_script(args->script_path, &args->script) != 0) { if (load_script(args->script_path, &args->script) != 0) {
return 1; return 1;
@@ -298,6 +303,7 @@ int index_args_validate(index_args_t *args, int argc, const char **argv) {
} }
LOG_DEBUGF("cli.c", "arg es_url=%s", args->es_url) LOG_DEBUGF("cli.c", "arg es_url=%s", args->es_url)
LOG_DEBUGF("cli.c", "arg es_index=%s", args->es_index)
LOG_DEBUGF("cli.c", "arg index_path=%s", args->index_path) LOG_DEBUGF("cli.c", "arg index_path=%s", args->index_path)
LOG_DEBUGF("cli.c", "arg script_path=%s", args->script_path) LOG_DEBUGF("cli.c", "arg script_path=%s", args->script_path)
LOG_DEBUGF("cli.c", "arg async_script=%s", args->async_script) LOG_DEBUGF("cli.c", "arg async_script=%s", args->async_script)
@@ -326,6 +332,10 @@ int web_args_validate(web_args_t *args, int argc, const char **argv) {
args->listen_address = DEFAULT_LISTEN_ADDRESS; args->listen_address = DEFAULT_LISTEN_ADDRESS;
} }
if (args->es_index == NULL) {
args->es_index = DEFAULT_ES_INDEX;
}
if (args->credentials != NULL) { if (args->credentials != NULL) {
char *ptr = strstr(args->credentials, ":"); char *ptr = strstr(args->credentials, ":");
if (ptr == NULL) { if (ptr == NULL) {
@@ -383,6 +393,7 @@ int web_args_validate(web_args_t *args, int argc, const char **argv) {
} }
LOG_DEBUGF("cli.c", "arg es_url=%s", args->es_url) LOG_DEBUGF("cli.c", "arg es_url=%s", args->es_url)
LOG_DEBUGF("cli.c", "arg es_index=%s", args->es_index)
LOG_DEBUGF("cli.c", "arg listen=%s", args->listen_address) LOG_DEBUGF("cli.c", "arg listen=%s", args->listen_address)
LOG_DEBUGF("cli.c", "arg credentials=%s", args->credentials) LOG_DEBUGF("cli.c", "arg credentials=%s", args->credentials)
LOG_DEBUGF("cli.c", "arg tag_credentials=%s", args->tag_credentials) LOG_DEBUGF("cli.c", "arg tag_credentials=%s", args->tag_credentials)
@@ -426,6 +437,10 @@ int exec_args_validate(exec_args_t *args, int argc, const char **argv) {
args->es_url = DEFAULT_ES_URL; args->es_url = DEFAULT_ES_URL;
} }
if (args->es_index == NULL) {
args->es_index = DEFAULT_ES_INDEX;
}
if (args->script_path == NULL) { if (args->script_path == NULL) {
LOG_FATAL("cli.c", "--script-file argument is required"); LOG_FATAL("cli.c", "--script-file argument is required");
} }

View File

@@ -35,6 +35,7 @@ int scan_args_validate(scan_args_t *args, int argc, const char **argv);
typedef struct index_args { typedef struct index_args {
char *es_url; char *es_url;
char *es_index;
const char *index_path; const char *index_path;
const char *script_path; const char *script_path;
char *script; char *script;
@@ -47,6 +48,7 @@ typedef struct index_args {
typedef struct web_args { typedef struct web_args {
char *es_url; char *es_url;
char *es_index;
char *listen_address; char *listen_address;
char *credentials; char *credentials;
char *tag_credentials; char *tag_credentials;
@@ -60,6 +62,7 @@ typedef struct web_args {
typedef struct exec_args { typedef struct exec_args {
char *es_url; char *es_url;
char *es_index;
const char *index_path; const char *index_path;
const char *script_path; const char *script_path;
int async_script; int async_script;

View File

@@ -58,6 +58,7 @@ typedef struct {
typedef struct { typedef struct {
char *es_url; char *es_url;
char *es_index;
int batch_size; int batch_size;
tpool_t *pool; tpool_t *pool;
store_t *tag_store; store_t *tag_store;
@@ -66,6 +67,7 @@ typedef struct {
typedef struct { typedef struct {
char *es_url; char *es_url;
char *es_index;
int index_count; int index_count;
char *auth_user; char *auth_user;
char *auth_pass; char *auth_pass;

View File

@@ -9,6 +9,7 @@
typedef struct es_indexer { typedef struct es_indexer {
int queued; int queued;
char *es_url; char *es_url;
char *es_index;
es_bulk_line_t *line_head; es_bulk_line_t *line_head;
es_bulk_line_t *line_tail; es_bulk_line_t *line_tail;
} es_indexer_t; } es_indexer_t;
@@ -17,11 +18,13 @@ typedef struct es_indexer {
static __thread es_indexer_t *Indexer; static __thread es_indexer_t *Indexer;
void delete_queue(int max); void delete_queue(int max);
void elastic_flush(); void elastic_flush();
void elastic_cleanup() { void elastic_cleanup() {
elastic_flush(); elastic_flush();
if (Indexer != NULL) { if (Indexer != NULL) {
free(Indexer->es_index);
free(Indexer->es_url); free(Indexer->es_url);
free(Indexer); free(Indexer);
} }
@@ -32,7 +35,7 @@ void print_json(cJSON *document, const char uuid_str[UUID_STR_LEN]) {
cJSON *line = cJSON_CreateObject(); cJSON *line = cJSON_CreateObject();
cJSON_AddStringToObject(line, "_id", uuid_str); cJSON_AddStringToObject(line, "_id", uuid_str);
cJSON_AddStringToObject(line, "_index", "sist2"); cJSON_AddStringToObject(line, "_index", IndexCtx.es_index);
cJSON_AddStringToObject(line, "_type", "_doc"); cJSON_AddStringToObject(line, "_type", "_doc");
cJSON_AddItemReferenceToObject(line, "_source", document); cJSON_AddItemReferenceToObject(line, "_source", document);
@@ -67,7 +70,7 @@ void index_json(cJSON *document, const char uuid_str[UUID_STR_LEN]) {
void execute_update_script(const char *script, int async, const char index_id[UUID_STR_LEN]) { void execute_update_script(const char *script, int async, const char index_id[UUID_STR_LEN]) {
if (Indexer == NULL) { if (Indexer == NULL) {
Indexer = create_indexer(IndexCtx.es_url); Indexer = create_indexer(IndexCtx.es_url, IndexCtx.es_index);
} }
cJSON *body = cJSON_CreateObject(); cJSON *body = cJSON_CreateObject();
@@ -83,9 +86,10 @@ void execute_update_script(const char *script, int async, const char index_id[UU
char bulk_url[4096]; char bulk_url[4096];
if (async) { if (async) {
snprintf(bulk_url, sizeof(bulk_url), "%s/sist2/_update_by_query?wait_for_completion=false", Indexer->es_url); snprintf(bulk_url, sizeof(bulk_url), "%s/%s/_update_by_query?wait_for_completion=false", Indexer->es_url,
Indexer->es_index);
} else { } else {
snprintf(bulk_url, sizeof(bulk_url), "%s/sist2/_update_by_query", Indexer->es_url); snprintf(bulk_url, sizeof(bulk_url), "%s/%s/_update_by_query", Indexer->es_url, Indexer->es_index);
} }
response_t *r = web_post(bulk_url, str); response_t *r = web_post(bulk_url, str);
if (!async) { if (!async) {
@@ -113,8 +117,6 @@ void execute_update_script(const char *script, int async, const char index_id[UU
cJSON_Delete(resp); cJSON_Delete(resp);
} }
#define ACTION_STR_LEN 91
void *create_bulk_buffer(int max, int *count, size_t *buf_len) { void *create_bulk_buffer(int max, int *count, size_t *buf_len) {
es_bulk_line_t *line = Indexer->line_head; es_bulk_line_t *line = Indexer->line_head;
*count = 0; *count = 0;
@@ -126,20 +128,24 @@ void *create_bulk_buffer(int max, int *count, size_t *buf_len) {
while (line != NULL && *count < max) { while (line != NULL && *count < max) {
char action_str[256]; char action_str[256];
snprintf(action_str, 256, snprintf(
"{\"index\":{\"_id\":\"%s\", \"_type\":\"_doc\", \"_index\":\"sist2\"}}\n", line->uuid_str); action_str, 256,
"{\"index\":{\"_id\":\"%s\",\"_type\":\"_doc\",\"_index\":\"%s\"}}\n",
line->uuid_str, Indexer->es_index
);
size_t action_str_len = strlen(action_str);
size_t line_len = strlen(line->line); size_t line_len = strlen(line->line);
while (buf_size + line_len + ACTION_STR_LEN > buf_capacity) { while (buf_size + line_len + action_str_len > buf_capacity) {
buf_capacity *= 2; buf_capacity *= 2;
buf = realloc(buf, buf_capacity); buf = realloc(buf, buf_capacity);
} }
buf_size += line_len + ACTION_STR_LEN; buf_size += line_len + action_str_len;
memcpy(buf + buf_cur, action_str, ACTION_STR_LEN); memcpy(buf + buf_cur, action_str, action_str_len);
buf_cur += ACTION_STR_LEN; buf_cur += action_str_len;
memcpy(buf + buf_cur, line->line, line_len); memcpy(buf + buf_cur, line->line, line_len);
buf_cur += line_len; buf_cur += line_len;
@@ -177,6 +183,21 @@ void print_errors(response_t *r) {
free(tmp); free(tmp);
} }
void print_error(response_t *r) {
char *tmp = malloc(r->size + 1);
memcpy(tmp, r->body, r->size);
*(tmp + r->size) = '\0';
cJSON *ret_json = cJSON_Parse(tmp);
if (cJSON_GetObjectItem(ret_json, "error") != NULL) {
char *str = cJSON_Print(cJSON_GetObjectItem(ret_json, "error"));
LOG_ERRORF("elastic.c", "%s\n", str);
cJSON_free(str);
}
cJSON_Delete(ret_json);
free(tmp);
}
void _elastic_flush(int max) { void _elastic_flush(int max) {
if (max == 0) { if (max == 0) {
@@ -189,7 +210,7 @@ void _elastic_flush(int max) {
void *buf = create_bulk_buffer(max, &count, &buf_len); void *buf = create_bulk_buffer(max, &count, &buf_len);
char bulk_url[4096]; char bulk_url[4096];
snprintf(bulk_url, 4096, "%s/sist2/_bulk?pipeline=tie", Indexer->es_url); snprintf(bulk_url, sizeof(bulk_url), "%s/%s/_bulk?pipeline=tie", Indexer->es_url, Indexer->es_index);
response_t *r = web_post(bulk_url, buf); response_t *r = web_post(bulk_url, buf);
if (r->status_code == 0) { if (r->status_code == 0) {
@@ -259,7 +280,7 @@ void delete_queue(int max) {
void elastic_flush() { void elastic_flush() {
if (Indexer == NULL) { if (Indexer == NULL) {
Indexer = create_indexer(IndexCtx.es_url); Indexer = create_indexer(IndexCtx.es_url, IndexCtx.es_index);
} }
_elastic_flush(Indexer->queued); _elastic_flush(Indexer->queued);
@@ -268,7 +289,7 @@ void elastic_flush() {
void elastic_index_line(es_bulk_line_t *line) { void elastic_index_line(es_bulk_line_t *line) {
if (Indexer == NULL) { if (Indexer == NULL) {
Indexer = create_indexer(IndexCtx.es_url); Indexer = create_indexer(IndexCtx.es_url, IndexCtx.es_index);
} }
if (Indexer->line_head == NULL) { if (Indexer->line_head == NULL) {
@@ -286,14 +307,18 @@ void elastic_index_line(es_bulk_line_t *line) {
} }
} }
es_indexer_t *create_indexer(const char *url) { es_indexer_t *create_indexer(const char *url, const char *index) {
char *es_url = malloc(strlen(url) + 1); char *es_url = malloc(strlen(url) + 1);
strcpy(es_url, url); strcpy(es_url, url);
char *es_index = malloc(strlen(index) + 1);
strcpy(es_index, index);
es_indexer_t *indexer = malloc(sizeof(es_indexer_t)); es_indexer_t *indexer = malloc(sizeof(es_indexer_t));
indexer->es_url = es_url; indexer->es_url = es_url;
indexer->es_index = es_index;
indexer->queued = 0; indexer->queued = 0;
indexer->line_head = NULL; indexer->line_head = NULL;
indexer->line_tail = NULL; indexer->line_tail = NULL;
@@ -305,7 +330,7 @@ void finish_indexer(char *script, int async_script, char *index_id) {
char url[4096]; char url[4096];
snprintf(url, sizeof(url), "%s/sist2/_refresh", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s/_refresh", IndexCtx.es_url, IndexCtx.es_index);
response_t *r = web_post(url, ""); response_t *r = web_post(url, "");
LOG_INFOF("elastic.c", "Refresh index <%d>", r->status_code); LOG_INFOF("elastic.c", "Refresh index <%d>", r->status_code);
free_response(r); free_response(r);
@@ -314,18 +339,18 @@ void finish_indexer(char *script, int async_script, char *index_id) {
execute_update_script(script, async_script, index_id); execute_update_script(script, async_script, index_id);
free(script); free(script);
snprintf(url, sizeof(url), "%s/sist2/_refresh", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s/_refresh", IndexCtx.es_url, IndexCtx.es_index);
r = web_post(url, ""); r = web_post(url, "");
LOG_INFOF("elastic.c", "Refresh index <%d>", r->status_code); LOG_INFOF("elastic.c", "Refresh index <%d>", r->status_code);
free_response(r); free_response(r);
} }
snprintf(url, sizeof(url), "%s/sist2/_forcemerge", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s/_forcemerge", IndexCtx.es_url, IndexCtx.es_index);
r = web_post(url, ""); r = web_post(url, "");
LOG_INFOF("elastic.c", "Merge index <%d>", r->status_code); LOG_INFOF("elastic.c", "Merge index <%d>", r->status_code);
free_response(r); free_response(r);
snprintf(url, sizeof(url), "%s/sist2/_settings", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s/_settings", IndexCtx.es_url, IndexCtx.es_index);
r = web_put(url, "{\"index\":{\"refresh_interval\":\"1s\"}}"); r = web_put(url, "{\"index\":{\"refresh_interval\":\"1s\"}}");
LOG_INFOF("elastic.c", "Set refresh interval <%d>", r->status_code); LOG_INFOF("elastic.c", "Set refresh interval <%d>", r->status_code);
free_response(r); free_response(r);
@@ -335,7 +360,7 @@ void elastic_init(int force_reset) {
// Check if index exists // Check if index exists
char url[4096]; char url[4096];
snprintf(url, 4096, "%s/sist2", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s", IndexCtx.es_url, IndexCtx.es_index);
response_t *r = web_get(url, 30); response_t *r = web_get(url, 30);
int index_exists = r->status_code == 200; int index_exists = r->status_code == 200;
free_response(r); free_response(r);
@@ -345,32 +370,38 @@ void elastic_init(int force_reset) {
LOG_INFOF("elastic.c", "Delete index <%d>", r->status_code); LOG_INFOF("elastic.c", "Delete index <%d>", r->status_code);
free_response(r); free_response(r);
snprintf(url, 4096, "%s/sist2", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s", IndexCtx.es_url, IndexCtx.es_index);
r = web_put(url, ""); r = web_put(url, "");
if (r->status_code != 200) {
print_error(r);
LOG_FATAL("elastic.c", "Could not create index")
}
LOG_INFOF("elastic.c", "Create index <%d>", r->status_code); LOG_INFOF("elastic.c", "Create index <%d>", r->status_code);
free_response(r); free_response(r);
snprintf(url, 4096, "%s/sist2/_close", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s/_close", IndexCtx.es_url, IndexCtx.es_index);
r = web_post(url, ""); r = web_post(url, "");
LOG_INFOF("elastic.c", "Close index <%d>", r->status_code); LOG_INFOF("elastic.c", "Close index <%d>", r->status_code);
free_response(r); free_response(r);
snprintf(url, 4096, "%s/_ingest/pipeline/tie", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/_ingest/pipeline/tie", IndexCtx.es_url);
r = web_put(url, pipeline_json); r = web_put(url, pipeline_json);
LOG_INFOF("elastic.c", "Create pipeline <%d>", r->status_code); LOG_INFOF("elastic.c", "Create pipeline <%d>", r->status_code);
free_response(r); free_response(r);
snprintf(url, 4096, "%s/sist2/_settings", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s/_settings", IndexCtx.es_url, IndexCtx.es_index);
r = web_put(url, settings_json); r = web_put(url, settings_json);
LOG_INFOF("elastic.c", "Update settings <%d>", r->status_code); LOG_INFOF("elastic.c", "Update settings <%d>", r->status_code);
free_response(r); free_response(r);
snprintf(url, 4096, "%s/sist2/_mappings/_doc?include_type_name=true", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s/_mappings/_doc?include_type_name=true", IndexCtx.es_url, IndexCtx.es_index);
r = web_put(url, mappings_json); r = web_put(url, mappings_json);
LOG_INFOF("elastic.c", "Update mappings <%d>", r->status_code); LOG_INFOF("elastic.c", "Update mappings <%d>", r->status_code);
free_response(r); free_response(r);
snprintf(url, 4096, "%s/sist2/_open", IndexCtx.es_url); snprintf(url, sizeof(url), "%s/%s/_open", IndexCtx.es_url, IndexCtx.es_index);
r = web_post(url, ""); r = web_post(url, "");
LOG_INFOF("elastic.c", "Open index <%d>", r->status_code); LOG_INFOF("elastic.c", "Open index <%d>", r->status_code);
free_response(r); free_response(r);
@@ -379,12 +410,16 @@ void elastic_init(int force_reset) {
cJSON *elastic_get_document(const char *uuid_str) { cJSON *elastic_get_document(const char *uuid_str) {
char url[4096]; char url[4096];
snprintf(url, 4096, "%s/sist2/_doc/%s", WebCtx.es_url, uuid_str); snprintf(url, sizeof(url), "%s/%s/_doc/%s", WebCtx.es_url, WebCtx.es_index, uuid_str);
response_t *r = web_get(url, 3); response_t *r = web_get(url, 3);
cJSON *json = NULL; cJSON *json = NULL;
if (r->status_code == 200) { if (r->status_code == 200) {
json = cJSON_Parse(r->body); char *tmp = malloc(r->size + 1);
memcpy(tmp, r->body, r->size);
*(tmp + r->size) = '\0';
json = cJSON_Parse(tmp);
free(tmp);
} }
free_response(r); free_response(r);
return json; return json;
@@ -392,8 +427,8 @@ cJSON *elastic_get_document(const char *uuid_str) {
char *elastic_get_status() { char *elastic_get_status() {
char url[4096]; char url[4096];
snprintf(url, 4096, snprintf(url, sizeof(url),
"%s/_cluster/state/metadata/sist2?filter_path=metadata.indices.*.state", WebCtx.es_url); "%s/_cluster/state/metadata/%s?filter_path=metadata.indices.*.state", WebCtx.es_url, WebCtx.es_index);
response_t *r = web_get(url, 30); response_t *r = web_get(url, 30);
cJSON *json = NULL; cJSON *json = NULL;
@@ -401,12 +436,16 @@ char *elastic_get_status() {
status[0] = '\0'; status[0] = '\0';
if (r->status_code == 200) { if (r->status_code == 200) {
json = cJSON_Parse(r->body); char *tmp = malloc(r->size + 1);
memcpy(tmp, r->body, r->size);
*(tmp + r->size) = '\0';
json = cJSON_Parse(tmp);
free(tmp);
const cJSON *metadata = cJSON_GetObjectItem(json, "metadata"); const cJSON *metadata = cJSON_GetObjectItem(json, "metadata");
if (metadata != NULL) { if (metadata != NULL) {
const cJSON *indices = cJSON_GetObjectItem(metadata, "indices"); const cJSON *indices = cJSON_GetObjectItem(metadata, "indices");
const cJSON *sist2 = cJSON_GetObjectItem(indices, "sist2"); const cJSON *index = cJSON_GetObjectItem(indices, WebCtx.es_index);
const cJSON *state = cJSON_GetObjectItem(sist2, "state"); const cJSON *state = cJSON_GetObjectItem(index, "state");
strcpy(status, state->valuestring); strcpy(status, state->valuestring);
} }
} }

View File

@@ -20,7 +20,7 @@ void print_json(cJSON *document, const char uuid_str[UUID_STR_LEN]);
void index_json(cJSON *document, const char uuid_str[UUID_STR_LEN]); void index_json(cJSON *document, const char uuid_str[UUID_STR_LEN]);
es_indexer_t *create_indexer(const char* es_url); es_indexer_t *create_indexer(const char *url, const char *index);
void elastic_cleanup(); void elastic_cleanup();
void finish_indexer(char *script, int async_script, char *index_id); void finish_indexer(char *script, int async_script, char *index_id);

File diff suppressed because one or more lines are too long

View File

@@ -125,7 +125,8 @@ response_t *web_get(const char *url, int timeout) {
curl_easy_setopt(curl, CURLOPT_USERAGENT, "sist2"); curl_easy_setopt(curl, CURLOPT_USERAGENT, "sist2");
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
struct curl_slist *headers = curl_slist_append(headers, "Content-Type: application/json"); struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_perform(curl); curl_easy_perform(curl);
@@ -153,7 +154,8 @@ response_t *web_post(const char *url, const char *data) {
curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "sist2"); curl_easy_setopt(curl, CURLOPT_USERAGENT, "sist2");
struct curl_slist *headers = curl_slist_append(headers, "Content-Type: application/json"); struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
@@ -187,7 +189,8 @@ response_t *web_put(const char *url, const char *data) {
curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0); curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0);
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURLOPT_DNS_LOCAL_IP4 ); curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURLOPT_DNS_LOCAL_IP4 );
struct curl_slist *headers = curl_slist_append(headers, "Content-Type: application/json"); struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
@@ -218,7 +221,8 @@ response_t *web_delete(const char *url) {
curl_easy_setopt(curl, CURLOPT_USERAGENT, "sist2"); curl_easy_setopt(curl, CURLOPT_USERAGENT, "sist2");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, ""); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
struct curl_slist *headers = curl_slist_append(headers, "Content-Type: application/json"); struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_perform(curl); curl_easy_perform(curl);

View File

@@ -150,6 +150,8 @@ char *get_meta_key_text(enum metakey meta_key) {
return "modified_by"; return "modified_by";
case MetaThumbnail: case MetaThumbnail:
return "thumbnail"; return "thumbnail";
case MetaPages:
return "pages";
default: default:
return NULL; return NULL;
} }
@@ -278,6 +280,7 @@ void read_index_bin(const char *path, const char *index_id, index_func func) {
size_t ret = 0; size_t ret = 0;
while (key != '\n') { while (key != '\n') {
switch (key) { switch (key) {
case MetaPages:
case MetaWidth: case MetaWidth:
case MetaHeight: { case MetaHeight: {
int value; int value;

View File

@@ -4,8 +4,7 @@
#include <stdarg.h> #include <stdarg.h>
const char *log_colors[] = { const char *log_colors[] = {
"\033[34m", "\033[01;34m", "\033[0m", "\033[34m", "\033[01;34m", "\033[01;33m", "\033[0m", "\033[31m", "\033[01;31m"
"\033[01;33m", "\033[31m", "\033[01;31m"
}; };
const char *log_levels[] = { const char *log_levels[] = {

View File

@@ -21,7 +21,7 @@
#define EPILOG "Made by simon987 <me@simon987.net>. Released under GPL-3.0" #define EPILOG "Made by simon987 <me@simon987.net>. Released under GPL-3.0"
static const char *const Version = "2.8.0"; static const char *const Version = "2.8.1";
static const char *const usage[] = { static const char *const usage[] = {
"sist2 scan [OPTION]... PATH", "sist2 scan [OPTION]... PATH",
"sist2 index [OPTION]... INDEX", "sist2 index [OPTION]... INDEX",
@@ -259,6 +259,7 @@ void sist2_scan(scan_args_t *args) {
void sist2_index(index_args_t *args) { void sist2_index(index_args_t *args) {
IndexCtx.es_url = args->es_url; IndexCtx.es_url = args->es_url;
IndexCtx.es_index = args->es_index;
IndexCtx.batch_size = args->batch_size; IndexCtx.batch_size = args->batch_size;
if (!args->print) { if (!args->print) {
@@ -347,6 +348,7 @@ void sist2_exec_script(exec_args_t *args) {
void sist2_web(web_args_t *args) { void sist2_web(web_args_t *args) {
WebCtx.es_url = args->es_url; WebCtx.es_url = args->es_url;
WebCtx.es_index = args->es_index;
WebCtx.index_count = args->index_count; WebCtx.index_count = args->index_count;
WebCtx.auth_user = args->auth_user; WebCtx.auth_user = args->auth_user;
WebCtx.auth_pass = args->auth_pass; WebCtx.auth_pass = args->auth_pass;
@@ -390,6 +392,7 @@ int main(int argc, const char *argv[]) {
int arg_version = 0; int arg_version = 0;
char *common_es_url = NULL; char *common_es_url = NULL;
char *common_es_index = NULL;
char *common_script_path = NULL; char *common_script_path = NULL;
int common_async_script = 0; int common_async_script = 0;
int common_threads = 0; int common_threads = 0;
@@ -432,6 +435,7 @@ int main(int argc, const char *argv[]) {
OPT_GROUP("Index options"), OPT_GROUP("Index options"),
OPT_INTEGER('t', "threads", &common_threads, "Number of threads. DEFAULT=1"), OPT_INTEGER('t', "threads", &common_threads, "Number of threads. DEFAULT=1"),
OPT_STRING(0, "es-url", &common_es_url, "Elasticsearch url with port. DEFAULT=http://localhost:9200"), OPT_STRING(0, "es-url", &common_es_url, "Elasticsearch url with port. DEFAULT=http://localhost:9200"),
OPT_STRING(0, "es-index", &common_es_index, "Elasticsearch index name. DEFAULT=sist2"),
OPT_BOOLEAN('p', "print", &index_args->print, "Just print JSON documents to stdout."), OPT_BOOLEAN('p', "print", &index_args->print, "Just print JSON documents to stdout."),
OPT_STRING(0, "script-file", &common_script_path, "Path to user script."), OPT_STRING(0, "script-file", &common_script_path, "Path to user script."),
OPT_BOOLEAN(0, "async-script", &common_async_script, "Execute user script asynchronously."), OPT_BOOLEAN(0, "async-script", &common_async_script, "Execute user script asynchronously."),
@@ -441,11 +445,14 @@ int main(int argc, const char *argv[]) {
OPT_GROUP("Web options"), OPT_GROUP("Web options"),
OPT_STRING(0, "es-url", &common_es_url, "Elasticsearch url. DEFAULT=http://localhost:9200"), OPT_STRING(0, "es-url", &common_es_url, "Elasticsearch url. DEFAULT=http://localhost:9200"),
OPT_STRING(0, "es-index", &common_es_index, "Elasticsearch index name. DEFAULT=sist2"),
OPT_STRING(0, "bind", &web_args->listen_address, "Listen on this address. DEFAULT=localhost:4090"), OPT_STRING(0, "bind", &web_args->listen_address, "Listen on this address. DEFAULT=localhost:4090"),
OPT_STRING(0, "auth", &web_args->credentials, "Basic auth in user:password format"), OPT_STRING(0, "auth", &web_args->credentials, "Basic auth in user:password format"),
OPT_STRING(0, "tag-auth", &web_args->tag_credentials, "Basic auth in user:password format for tagging"), OPT_STRING(0, "tag-auth", &web_args->tag_credentials, "Basic auth in user:password format for tagging"),
OPT_GROUP("Exec-script options"), OPT_GROUP("Exec-script options"),
OPT_STRING(0, "es-url", &common_es_url, "Elasticsearch url. DEFAULT=http://localhost:9200"),
OPT_STRING(0, "es-index", &common_es_index, "Elasticsearch index name. DEFAULT=sist2"),
OPT_STRING(0, "script-file", &common_script_path, "Path to user script."), OPT_STRING(0, "script-file", &common_script_path, "Path to user script."),
OPT_BOOLEAN(0, "async-script", &common_async_script, "Execute user script asynchronously."), OPT_BOOLEAN(0, "async-script", &common_async_script, "Execute user script asynchronously."),
@@ -469,6 +476,11 @@ int main(int argc, const char *argv[]) {
web_args->es_url = common_es_url; web_args->es_url = common_es_url;
index_args->es_url = common_es_url; index_args->es_url = common_es_url;
exec_args->es_url = common_es_url; exec_args->es_url = common_es_url;
web_args->es_index = common_es_index;
index_args->es_index = common_es_index;
exec_args->es_index = common_es_index;
index_args->script_path = common_script_path; index_args->script_path = common_script_path;
exec_args->script_path = common_script_path; exec_args->script_path = common_script_path;
index_args->threads = common_threads; index_args->threads = common_threads;

View File

@@ -75,6 +75,7 @@ function shouldPlayVideo(hit) {
hit["_source"]["extension"] !== "mkv" && hit["_source"]["extension"] !== "mkv" &&
hit["_source"]["extension"] !== "avi" && hit["_source"]["extension"] !== "avi" &&
videoc !== "hevc" && videoc !== "hevc" &&
videoc !== "mpeg1video" &&
videoc !== "mpeg2video" && videoc !== "mpeg2video" &&
videoc !== "wmv3"; videoc !== "wmv3";
} }
@@ -208,6 +209,10 @@ function infoButtonCb(hit) {
.append(tbody) .append(tbody)
); );
tbody.append($("<tr>")
.append($("<td>").text("index"))
.append($("<td>").text(`[${indexMap[doc["index"]]}]`))
);
const displayFields = new Set([ const displayFields = new Set([
"mime", "size", "mtime", "path", "title", "width", "height", "duration", "audioc", "videoc", "mime", "size", "mtime", "path", "title", "width", "height", "duration", "audioc", "videoc",
"bitrate", "artist", "album", "album_artist", "genre", "title", "font_name", "tag", "author", "bitrate", "artist", "album", "album_artist", "genre", "title", "font_name", "tag", "author",

View File

@@ -12,7 +12,7 @@
<nav class="navbar navbar-expand-lg"> <nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="/">sist2</a> <a class="navbar-brand" href="/">sist2</a>
<span class="badge badge-pill version">2.8.0</span> <span class="badge badge-pill version">2.8.1</span>
<span class="tagline">Lightning-fast file system indexer and search tool </span> <span class="tagline">Lightning-fast file system indexer and search tool </span>
<a class="btn ml-auto" href="/stats">Stats</a> <a class="btn ml-auto" href="/stats">Stats</a>
<button class="btn" type="button" data-toggle="modal" data-target="#settings" onclick="loadSettings()">Settings <button class="btn" type="button" data-toggle="modal" data-target="#settings" onclick="loadSettings()">Settings

View File

@@ -10,7 +10,7 @@
<nav class="navbar navbar-expand-lg"> <nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="/">sist2</a> <a class="navbar-brand" href="/">sist2</a>
<span class="badge badge-pill version">2.8.0</span> <span class="badge badge-pill version">2.8.1</span>
<span class="tagline">Lightning-fast file system indexer and search tool </span> <span class="tagline">Lightning-fast file system indexer and search tool </span>
<a style="margin-left: auto" class="btn" href="/">Back</a> <a style="margin-left: auto" class="btn" href="/">Back</a>
<button class="btn" type="button" data-toggle="modal" data-target="#settings" <button class="btn" type="button" data-toggle="modal" data-target="#settings"

View File

@@ -237,13 +237,13 @@ void search(struct mg_connection *nc, struct http_message *hm) {
*(body + hm->body.len) = '\0'; *(body + hm->body.len) = '\0';
char url[4096]; char url[4096];
snprintf(url, 4096, "%s/sist2/_search", WebCtx.es_url); snprintf(url, 4096, "%s/%s/_search", WebCtx.es_url, WebCtx.es_index);
nc->user_data = web_post_async(url, body); nc->user_data = web_post_async(url, body);
free(body); free(body);
} }
int serve_file_from_url(cJSON *json, index_t *idx, struct mg_connection *nc) { void serve_file_from_url(cJSON *json, index_t *idx, struct mg_connection *nc) {
const char *path = cJSON_GetObjectItem(json, "path")->valuestring; const char *path = cJSON_GetObjectItem(json, "path")->valuestring;
const char *name = cJSON_GetObjectItem(json, "name")->valuestring; const char *name = cJSON_GetObjectItem(json, "name")->valuestring;
@@ -552,7 +552,7 @@ void tag(struct mg_connection *nc, struct http_message *hm, struct mg_str *path)
); );
char url[4096]; char url[4096];
snprintf(url, sizeof(url), "%s/sist2/_update/%s", WebCtx.es_url, arg_req->doc_id); snprintf(url, sizeof(url), "%s/%s/_update/%s", WebCtx.es_url, WebCtx.es_index, arg_req->doc_id);
nc->user_data = web_post_async(url, buf); nc->user_data = web_post_async(url, buf);
} else { } else {
@@ -572,7 +572,7 @@ void tag(struct mg_connection *nc, struct http_message *hm, struct mg_str *path)
); );
char url[4096]; char url[4096];
snprintf(url, sizeof(url), "%s/sist2/_update/%s", WebCtx.es_url, arg_req->doc_id); snprintf(url, sizeof(url), "%s/%s/_update/%s", WebCtx.es_url, WebCtx.es_index, arg_req->doc_id);
nc->user_data = web_post_async(url, buf); nc->user_data = web_post_async(url, buf);
} }

File diff suppressed because one or more lines are too long