Compare commits

...

29 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
0e517d5e2b Fix #81 2020-08-03 20:09:07 -04:00
8223ef3860 Update USAGE.md 2020-08-03 19:48:49 -04:00
995a196690 Log user script task, add async arg 2020-08-03 19:44:43 -04:00
465d017e18 CSS tweaks, fix #87 2020-08-03 19:15:12 -04:00
ca994d3914 Fix bug with media files, don't encode thumbnail when not necessary 2020-07-26 11:52:48 -04:00
db2285973f Configurable column count 2020-07-26 11:50:21 -04:00
61de9e9f14 Set timeout for HTTP get request 2020-07-25 19:55:27 -04:00
3015ef0ff4 Increase file preview file 2020-07-25 17:26:17 -04:00
b55d432841 Fix #65 2020-07-25 09:37:37 -04:00
ed90a140ce Update README.md 2020-07-19 14:53:03 -04:00
28 changed files with 722 additions and 509 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)
@@ -102,7 +104,7 @@ scan is also supported.
### OCR ### OCR
You can enable OCR support for pdf,xps,cbz,cbr,fb2,epub file types with the You can enable OCR support for pdf,xps,fb2,epub file types with the
`--ocr <lang>` option. Download the language data files with your `--ocr <lang>` option. Download the language data files with your
package manager (`apt install tesseract-ocr-eng`) or directly [from Github](https://github.com/tesseract-ocr/tesseract/wiki/Data-Files). package manager (`apt install tesseract-ocr-eng`) or directly [from Github](https://github.com/tesseract-ocr/tesseract/wiki/Data-Files).
@@ -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,19 +49,25 @@ 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.
--batch-size=<int> Index batch size. DEFAULT: 100 --batch-size=<int> Index batch size. DEFAULT: 100
-f, --force-reset Reset Elasticsearch mappings and settings. (You must use this option the first time you use the index command) -f, --force-reset Reset Elasticsearch mappings and settings. (You must use this option the first time you use the index command)
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.
Made by simon987 <me@simon987.net>. Released under GPL-3.0 Made by simon987 <me@simon987.net>. Released under GPL-3.0
``` ```
@@ -239,10 +245,15 @@ 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`
Path to user script. See [Scripting](scripting.md). Path to user script. See [Scripting](scripting.md).
* `--async-script`
Use `wait_for_completion=false` elasticsearch option while executing user script.
(See [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/tasks.html))
* `--batch-size=<int>` * `--batch-size=<int>`
Index batch size. Indexing is generally faster with larger batches, but payloads that Index batch size. Indexing is generally faster with larger batches, but payloads that
are too large will fail and additional overhead for retrying with smaller sizes may slow are too large will fail and additional overhead for retrying with smaller sizes may slow
@@ -273,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
@@ -335,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

@@ -347,7 +347,8 @@ text/javascript, js
text/mcf, mcf text/mcf, mcf
text/pascal, pas text/pascal, pas
text/PGP, text/PGP,
text/plain, com|cmd|conf|def|g|idc|list|lst|mar|sdml|text|txt|md|groovy|license|properties|desktop|ini|rst|cmake|ipynb|readme|less|lo|go|yml|d|cs|hpp|srt|nfo|sfv|m3u|csv|eml text/plain, com|cmd|conf|def|g|idc|list|lst|mar|sdml|text|txt|md|groovy|license|properties|desktop|ini|rst|cmake|ipynb|readme|less|lo|go|yml|d|cs|hpp|srt|nfo|sfv|m3u|csv|eml|make|log|markdown|yaml
application/vnd.coffeescript, coffee
text/richtext, rt|rtf|rtx text/richtext, rt|rtf|rtx
text/rtf, text/rtf,
text/scriplet, wsc text/scriplet, wsc
1 application/arj arj
347 text/mcf mcf
348 text/pascal pas
349 text/PGP
350 text/plain com|cmd|conf|def|g|idc|list|lst|mar|sdml|text|txt|md|groovy|license|properties|desktop|ini|rst|cmake|ipynb|readme|less|lo|go|yml|d|cs|hpp|srt|nfo|sfv|m3u|csv|eml com|cmd|conf|def|g|idc|list|lst|mar|sdml|text|txt|md|groovy|license|properties|desktop|ini|rst|cmake|ipynb|readme|less|lo|go|yml|d|cs|hpp|srt|nfo|sfv|m3u|csv|eml|make|log|markdown|yaml
351 application/vnd.coffeescript coffee
352 text/richtext rt|rtf|rtx
353 text/rtf
354 text/scriplet wsc

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"
@@ -135,6 +136,10 @@ int scan_args_validate(scan_args_t *args, int argc, const char **argv) {
if (args->name == NULL) { if (args->name == NULL) {
args->name = g_path_get_basename(args->output); args->name = g_path_get_basename(args->output);
} else {
char* tmp = malloc(strlen(args->name) + 1);
strcpy(tmp, args->name);
args->name = tmp;
} }
if (args->rewrite_url == NULL) { if (args->rewrite_url == NULL) {
@@ -283,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;
@@ -294,8 +303,10 @@ 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 script=%s", args->script) LOG_DEBUGF("cli.c", "arg script=%s", args->script)
LOG_DEBUGF("cli.c", "arg print=%d", args->print) LOG_DEBUGF("cli.c", "arg print=%d", args->print)
LOG_DEBUGF("cli.c", "arg batch_size=%d", args->batch_size) LOG_DEBUGF("cli.c", "arg batch_size=%d", args->batch_size)
@@ -321,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) {
@@ -378,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)
@@ -421,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,17 +35,20 @@ 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;
int print; int print;
int batch_size; int batch_size;
int async_script;
int force_reset; int force_reset;
int threads; int threads;
} index_args_t; } index_args_t;
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;
@@ -59,8 +62,10 @@ 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;
char *script; char *script;
} exec_args_t; } exec_args_t;

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);
@@ -64,10 +67,10 @@ void index_json(cJSON *document, const char uuid_str[UUID_STR_LEN]) {
tpool_add_work(IndexCtx.pool, index_json_func, bulk_line); tpool_add_work(IndexCtx.pool, index_json_func, bulk_line);
} }
void execute_update_script(const char *script, 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();
@@ -82,9 +85,16 @@ void execute_update_script(const char *script, const char index_id[UUID_STR_LEN]
char *str = cJSON_Print(body); char *str = cJSON_Print(body);
char bulk_url[4096]; char bulk_url[4096];
snprintf(bulk_url, 4096, "%s/sist2/_update_by_query?wait_for_completion=false", Indexer->es_url); if (async) {
snprintf(bulk_url, sizeof(bulk_url), "%s/%s/_update_by_query?wait_for_completion=false", Indexer->es_url,
Indexer->es_index);
} else {
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);
LOG_INFOF("elastic.c", "Executed user script <%d>", r->status_code); if (!async) {
LOG_INFOF("elastic.c", "Executed user script <%d>", r->status_code);
}
cJSON *resp = cJSON_Parse(r->body); cJSON *resp = cJSON_Parse(r->body);
cJSON_free(str); cJSON_free(str);
@@ -99,36 +109,43 @@ void execute_update_script(const char *script, const char index_id[UUID_STR_LEN]
cJSON_free(error_str); cJSON_free(error_str);
} }
if (async) {
cJSON *task = cJSON_GetObjectItem(resp, "task");
LOG_INFOF("elastic.c", "User script queued: %s/_tasks/%s", Indexer->es_url, task->valuestring);
}
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;
size_t buf_size = 0; size_t buf_size = 0;
size_t buf_cur = 0; size_t buf_cur = 0;
char *buf = malloc(8196); char *buf = malloc(8192);
size_t buf_capacity = 8196; size_t buf_capacity = 8192;
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;
@@ -166,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) {
@@ -178,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) {
@@ -248,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);
@@ -257,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) {
@@ -275,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;
@@ -290,31 +326,31 @@ es_indexer_t *create_indexer(const char *url) {
return indexer; return indexer;
} }
void finish_indexer(char *script, char *index_id) { 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);
if (script != NULL) { if (script != NULL) {
execute_update_script(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);
@@ -324,8 +360,8 @@ 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); 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);
@@ -334,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);
@@ -368,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); 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;
@@ -381,21 +427,25 @@ 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); response_t *r = web_get(url, 30);
cJSON *json = NULL; cJSON *json = NULL;
char *status = malloc(128 * sizeof(char)); char *status = malloc(128 * sizeof(char));
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,10 +20,10 @@ 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, char *index_id); void finish_indexer(char *script, int async_script, char *index_id);
void elastic_init(int force_reset); void elastic_init(int force_reset);
@@ -31,6 +31,6 @@ cJSON *elastic_get_document(const char *uuid_str);
char *elastic_get_status(); char *elastic_get_status();
void execute_update_script(const char *script, const char index_id[UUID_STR_LEN]); void execute_update_script(const char *script, int async, const char index_id[UUID_STR_LEN]);
#endif #endif

File diff suppressed because one or more lines are too long

View File

@@ -83,7 +83,7 @@ subreq_ctx_t *http_req(const char *url, const char *extra_headers, const char *p
subreq_ctx_t *ctx = malloc(sizeof(subreq_ctx_t)); subreq_ctx_t *ctx = malloc(sizeof(subreq_ctx_t));
mg_mgr_init(&ctx->mgr, NULL); mg_mgr_init(&ctx->mgr, NULL);
char address[8196]; char address[8192];
snprintf(address, sizeof(address), "tcp://%.*s:%u", (int) host.len, host.p, port); snprintf(address, sizeof(address), "tcp://%.*s:%u", (int) host.len, host.p, port);
struct mg_connection *nc = mg_connect(&ctx->mgr, address, http_req_ev); struct mg_connection *nc = mg_connect(&ctx->mgr, address, http_req_ev);
nc->user_data = &ctx->ev_data; nc->user_data = &ctx->ev_data;
@@ -112,7 +112,7 @@ subreq_ctx_t *web_post_async(const char *url, const char *data) {
return http_req(url, SIST2_HEADERS, data, "POST"); return http_req(url, SIST2_HEADERS, data, "POST");
} }
response_t *web_get(const char *url) { response_t *web_get(const char *url, int timeout) {
response_t *resp = malloc(sizeof(response_t)); response_t *resp = malloc(sizeof(response_t));
CURL *curl; CURL *curl;
@@ -123,8 +123,10 @@ response_t *web_get(const char *url) {
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) (&buffer)); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) (&buffer));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "sist2"); curl_easy_setopt(curl, CURLOPT_USERAGENT, "sist2");
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);
@@ -152,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);
@@ -186,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);
@@ -217,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

@@ -20,7 +20,7 @@ typedef struct {
struct mg_mgr mgr; struct mg_mgr mgr;
} subreq_ctx_t; } subreq_ctx_t;
response_t *web_get(const char *url); response_t *web_get(const char *url, int timeout);
response_t *web_post(const char * url, const char * data); response_t *web_post(const char * url, const char * data);
subreq_ctx_t *web_post_async(const char *url, const char *data); subreq_ctx_t *web_post_async(const char *url, const char *data);
response_t *web_put(const char *url, const char *data); response_t *web_put(const char *url, const char *data);

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.7.3"; 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) {
@@ -317,11 +318,12 @@ void sist2_index(index_args_t *args) {
tpool_wait(IndexCtx.pool); tpool_wait(IndexCtx.pool);
if (!args->print) {
finish_indexer(args->script, desc.uuid);
}
tpool_destroy(IndexCtx.pool); tpool_destroy(IndexCtx.pool);
if (!args->print) {
finish_indexer(args->script, args->async_script, desc.uuid);
}
store_destroy(IndexCtx.tag_store); store_destroy(IndexCtx.tag_store);
g_hash_table_remove_all(IndexCtx.tags); g_hash_table_remove_all(IndexCtx.tags);
g_hash_table_destroy(IndexCtx.tags); g_hash_table_destroy(IndexCtx.tags);
@@ -339,13 +341,14 @@ void sist2_exec_script(exec_args_t *args) {
LOG_DEBUGF("main.c", "descriptor version %s (%s)", desc.version, desc.type) LOG_DEBUGF("main.c", "descriptor version %s (%s)", desc.version, desc.type)
execute_update_script(args->script, desc.uuid); execute_update_script(args->script, args->async_script, desc.uuid);
free(args->script); free(args->script);
} }
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;
@@ -389,7 +392,9 @@ 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_threads = 0; int common_threads = 0;
struct argparse_option options[] = { struct argparse_option options[] = {
@@ -430,20 +435,26 @@ 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_INTEGER(0, "batch-size", &index_args->batch_size, "Index batch size. DEFAULT: 100"), OPT_INTEGER(0, "batch-size", &index_args->batch_size, "Index batch size. DEFAULT: 100"),
OPT_BOOLEAN('f', "force-reset", &index_args->force_reset, "Reset Elasticsearch mappings and settings. " OPT_BOOLEAN('f', "force-reset", &index_args->force_reset, "Reset Elasticsearch mappings and settings. "
"(You must use this option the first time you use the index command)"), "(You must use this option the first time you use the index command)"),
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_END(), OPT_END(),
}; };
@@ -465,10 +476,17 @@ 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;
scan_args->threads = common_threads; scan_args->threads = common_threads;
exec_args->async_script = common_async_script;
index_args->async_script = common_async_script;
if (argc == 0) { if (argc == 0) {
argparse_usage(&argparse); argparse_usage(&argparse);

View File

@@ -54,406 +54,407 @@ enum mime {
application_streamingmedia=655406, application_streamingmedia=655406,
application_vda=655407, application_vda=655407,
application_vnd_amazon_mobi8_ebook=655408 | 0x02000000, application_vnd_amazon_mobi8_ebook=655408 | 0x02000000,
application_vnd_fdf=655409, application_vnd_coffeescript=655409,
application_vnd_font_fontforge_sfd=655410, application_vnd_fdf=655410,
application_vnd_hp_hpgl=655411, application_vnd_font_fontforge_sfd=655411,
application_vnd_iccprofile=655412, application_vnd_hp_hpgl=655412,
application_vnd_lotus_1_2_3=655413, application_vnd_iccprofile=655413,
application_vnd_ms_cab_compressed=655414, application_vnd_lotus_1_2_3=655414,
application_vnd_ms_excel=655415, application_vnd_ms_cab_compressed=655415,
application_vnd_ms_fontobject=655416, application_vnd_ms_excel=655416,
application_vnd_ms_opentype=655417 | 0x20000000, application_vnd_ms_fontobject=655417,
application_vnd_ms_outlook=655418, application_vnd_ms_opentype=655418 | 0x20000000,
application_vnd_ms_pki_certstore=655419, application_vnd_ms_outlook=655419,
application_vnd_ms_pki_pko=655420, application_vnd_ms_pki_certstore=655420,
application_vnd_ms_pki_seccat=655421, application_vnd_ms_pki_pko=655421,
application_vnd_ms_powerpoint=655422, application_vnd_ms_pki_seccat=655422,
application_vnd_ms_project=655423, application_vnd_ms_powerpoint=655423,
application_vnd_oasis_opendocument_base=655424, application_vnd_ms_project=655424,
application_vnd_oasis_opendocument_formula=655425, application_vnd_oasis_opendocument_base=655425,
application_vnd_oasis_opendocument_graphics=655426, application_vnd_oasis_opendocument_formula=655426,
application_vnd_oasis_opendocument_presentation=655427, application_vnd_oasis_opendocument_graphics=655427,
application_vnd_oasis_opendocument_spreadsheet=655428, application_vnd_oasis_opendocument_presentation=655428,
application_vnd_oasis_opendocument_text=655429, application_vnd_oasis_opendocument_spreadsheet=655429,
application_vnd_openxmlformats_officedocument_presentationml_presentation=655430 | 0x04000000, application_vnd_oasis_opendocument_text=655430,
application_vnd_openxmlformats_officedocument_spreadsheetml_sheet=655431 | 0x04000000, application_vnd_openxmlformats_officedocument_presentationml_presentation=655431 | 0x04000000,
application_vnd_openxmlformats_officedocument_wordprocessingml_document=655432 | 0x04000000, application_vnd_openxmlformats_officedocument_spreadsheetml_sheet=655432 | 0x04000000,
application_vnd_symbian_install=655433, application_vnd_openxmlformats_officedocument_wordprocessingml_document=655433 | 0x04000000,
application_vnd_tcpdump_pcap=655434, application_vnd_symbian_install=655434,
application_vnd_wap_wmlc=655435, application_vnd_tcpdump_pcap=655435,
application_vnd_wap_wmlscriptc=655436, application_vnd_wap_wmlc=655436,
application_vnd_xara=655437, application_vnd_wap_wmlscriptc=655437,
application_vocaltec_media_desc=655438, application_vnd_xara=655438,
application_vocaltec_media_file=655439, application_vocaltec_media_desc=655439,
application_warc=655440, application_vocaltec_media_file=655440,
application_winhelp=655441, application_warc=655441,
application_wordperfect=655442, application_winhelp=655442,
application_wordperfect6_0=655443, application_wordperfect=655443,
application_wordperfect6_1=655444, application_wordperfect6_0=655444,
application_x_123=655445, application_wordperfect6_1=655445,
application_x_7z_compressed=655446 | 0x10000000, application_x_123=655446,
application_x_aim=655447, application_x_7z_compressed=655447 | 0x10000000,
application_x_apple_diskimage=655448, application_x_aim=655448,
application_x_arc=655449 | 0x10000000, application_x_apple_diskimage=655449,
application_x_archive=655450, application_x_arc=655450 | 0x10000000,
application_x_atari_7800_rom=655451, application_x_archive=655451,
application_x_authorware_bin=655452, application_x_atari_7800_rom=655452,
application_x_authorware_map=655453, application_x_authorware_bin=655453,
application_x_authorware_seg=655454, application_x_authorware_map=655454,
application_x_avira_qua=655455, application_x_authorware_seg=655455,
application_x_bcpio=655456, application_x_avira_qua=655456,
application_x_bittorrent=655457, application_x_bcpio=655457,
application_x_bsh=655458, application_x_bittorrent=655458,
application_x_bytecode_python=655459, application_x_bsh=655459,
application_x_bzip=655460, application_x_bytecode_python=655460,
application_x_bzip2=655461 | 0x08000000, application_x_bzip=655461,
application_x_cbr=655462, application_x_bzip2=655462 | 0x08000000,
application_x_cbz=655463, application_x_cbr=655463,
application_x_cdlink=655464, application_x_cbz=655464,
application_x_chat=655465, application_x_cdlink=655465,
application_x_chrome_extension=655466, application_x_chat=655466,
application_x_cocoa=655467, application_x_chrome_extension=655467,
application_x_conference=655468, application_x_cocoa=655468,
application_x_coredump=655469, application_x_conference=655469,
application_x_cpio=655470, application_x_coredump=655470,
application_x_dbf=655471, application_x_cpio=655471,
application_x_dbt=655472, application_x_dbf=655472,
application_x_debian_package=655473, application_x_dbt=655473,
application_x_deepv=655474, application_x_debian_package=655474,
application_x_director=655475, application_x_deepv=655475,
application_x_dmp=655476, application_x_director=655476,
application_x_dosdriver=655477, application_x_dmp=655477,
application_x_dosexec=655478, application_x_dosdriver=655478,
application_x_dvi=655479, application_x_dosexec=655479,
application_x_elc=655480, application_x_dvi=655480,
application_x_elc=655481,
application_x_empty=1, application_x_empty=1,
application_x_envoy=655482, application_x_envoy=655483,
application_x_esrehber=655483, application_x_esrehber=655484,
application_x_excel=655484, application_x_excel=655485,
application_x_executable=655485, application_x_executable=655486,
application_x_font_gdos=655486, application_x_font_gdos=655487,
application_x_font_pf2=655487, application_x_font_pf2=655488,
application_x_font_pfm=655488, application_x_font_pfm=655489,
application_x_font_sfn=655489, application_x_font_sfn=655490,
application_x_font_ttf=655490 | 0x20000000, application_x_font_ttf=655491 | 0x20000000,
application_x_fptapplication_x_dbt=655491, application_x_fptapplication_x_dbt=655492,
application_x_freelance=655492, application_x_freelance=655493,
application_x_gamecube_rom=655493, application_x_gamecube_rom=655494,
application_x_gdbm=655494, application_x_gdbm=655495,
application_x_gettext_translation=655495, application_x_gettext_translation=655496,
application_x_git=655496, application_x_git=655497,
application_x_gsp=655497, application_x_gsp=655498,
application_x_gss=655498, application_x_gss=655499,
application_x_gtar=655499, application_x_gtar=655500,
application_x_gzip=655500, application_x_gzip=655501,
application_x_hdf=655501, application_x_hdf=655502,
application_x_helpfile=655502, application_x_helpfile=655503,
application_x_httpd_imap=655503, application_x_httpd_imap=655504,
application_x_ima=655504, application_x_ima=655505,
application_x_innosetup=655505, application_x_innosetup=655506,
application_x_internett_signup=655506, application_x_internett_signup=655507,
application_x_inventor=655507, application_x_inventor=655508,
application_x_ip2=655508, application_x_ip2=655509,
application_x_java_applet=655509, application_x_java_applet=655510,
application_x_java_commerce=655510, application_x_java_commerce=655511,
application_x_java_image=655511, application_x_java_image=655512,
application_x_java_jmod=655512, application_x_java_jmod=655513,
application_x_java_keystore=655513, application_x_java_keystore=655514,
application_x_kdelnk=655514, application_x_kdelnk=655515,
application_x_koan=655515, application_x_koan=655516,
application_x_latex=655516, application_x_latex=655517,
application_x_livescreen=655517, application_x_livescreen=655518,
application_x_lotus=655518, application_x_lotus=655519,
application_x_lz4=655519 | 0x08000000, application_x_lz4=655520 | 0x08000000,
application_x_lz4_json=655520, application_x_lz4_json=655521,
application_x_lzh=655521, application_x_lzh=655522,
application_x_lzh_compressed=655522, application_x_lzh_compressed=655523,
application_x_lzip=655523 | 0x08000000, application_x_lzip=655524 | 0x08000000,
application_x_lzma=655524 | 0x08000000, application_x_lzma=655525 | 0x08000000,
application_x_lzop=655525 | 0x08000000, application_x_lzop=655526 | 0x08000000,
application_x_lzx=655526, application_x_lzx=655527,
application_x_mach_binary=655527, application_x_mach_binary=655528,
application_x_mach_executable=655528, application_x_mach_executable=655529,
application_x_magic_cap_package_1_0=655529, application_x_magic_cap_package_1_0=655530,
application_x_mathcad=655530, application_x_mathcad=655531,
application_x_maxis_dbpf=655531, application_x_maxis_dbpf=655532,
application_x_meme=655532, application_x_meme=655533,
application_x_midi=655533, application_x_midi=655534,
application_x_mif=655534, application_x_mif=655535,
application_x_mix_transfer=655535, application_x_mix_transfer=655536,
application_x_mobipocket_ebook=655536 | 0x02000000, application_x_mobipocket_ebook=655537 | 0x02000000,
application_x_ms_compress_szdd=655537, application_x_ms_compress_szdd=655538,
application_x_ms_pdb=655538, application_x_ms_pdb=655539,
application_x_ms_reader=655539, application_x_ms_reader=655540,
application_x_msaccess=655540, application_x_msaccess=655541,
application_x_n64_rom=655541, application_x_n64_rom=655542,
application_x_navi_animation=655542, application_x_navi_animation=655543,
application_x_navidoc=655543, application_x_navidoc=655544,
application_x_navimap=655544, application_x_navimap=655545,
application_x_navistyle=655545, application_x_navistyle=655546,
application_x_nes_rom=655546, application_x_nes_rom=655547,
application_x_netcdf=655547, application_x_netcdf=655548,
application_x_newton_compatible_pkg=655548, application_x_newton_compatible_pkg=655549,
application_x_nintendo_ds_rom=655549, application_x_nintendo_ds_rom=655550,
application_x_object=655550, application_x_object=655551,
application_x_omc=655551, application_x_omc=655552,
application_x_omcdatamaker=655552, application_x_omcdatamaker=655553,
application_x_omcregerator=655553, application_x_omcregerator=655554,
application_x_pagemaker=655554, application_x_pagemaker=655555,
application_x_pcl=655555, application_x_pcl=655556,
application_x_pgp_keyring=655556, application_x_pgp_keyring=655557,
application_x_pixclscript=655557, application_x_pixclscript=655558,
application_x_pkcs7_certreqresp=655558, application_x_pkcs7_certreqresp=655559,
application_x_pkcs7_signature=655559, application_x_pkcs7_signature=655560,
application_x_project=655560, application_x_project=655561,
application_x_qpro=655561, application_x_qpro=655562,
application_x_rar=655562 | 0x10000000, application_x_rar=655563 | 0x10000000,
application_x_rpm=655563, application_x_rpm=655564,
application_x_sdp=655564, application_x_sdp=655565,
application_x_sea=655565, application_x_sea=655566,
application_x_seelogo=655566, application_x_seelogo=655567,
application_x_setupscript=655567, application_x_setupscript=655568,
application_x_shar=655568, application_x_shar=655569,
application_x_sharedlib=655569, application_x_sharedlib=655570,
application_x_shockwave_flash=655570, application_x_shockwave_flash=655571,
application_x_snappy_framed=655571, application_x_snappy_framed=655572,
application_x_sprite=655572, application_x_sprite=655573,
application_x_sqlite3=655573, application_x_sqlite3=655574,
application_x_stargallery_thm=655574, application_x_stargallery_thm=655575,
application_x_stuffit=655575, application_x_stuffit=655576,
application_x_sv4cpio=655576, application_x_sv4cpio=655577,
application_x_sv4crc=655577, application_x_sv4crc=655578,
application_x_tar=655578 | 0x10000000, application_x_tar=655579 | 0x10000000,
application_x_tbook=655579, application_x_tbook=655580,
application_x_terminfo=655580, application_x_terminfo=655581,
application_x_terminfo2=655581, application_x_terminfo2=655582,
application_x_tex_tfm=655582, application_x_tex_tfm=655583,
application_x_texinfo=655583, application_x_texinfo=655584,
application_x_ustar=655584, application_x_ustar=655585,
application_x_visio=655585, application_x_visio=655586,
application_x_vnd_audioexplosion_mzz=655586, application_x_vnd_audioexplosion_mzz=655587,
application_x_vnd_ls_xpix=655587, application_x_vnd_ls_xpix=655588,
application_x_vrml=655588, application_x_vrml=655589,
application_x_wais_source=655589, application_x_wais_source=655590,
application_x_wine_extension_ini=655590, application_x_wine_extension_ini=655591,
application_x_wintalk=655591, application_x_wintalk=655592,
application_x_world=655592, application_x_world=655593,
application_x_wri=655593, application_x_wri=655594,
application_x_x509_ca_cert=655594, application_x_x509_ca_cert=655595,
application_x_xz=655595 | 0x08000000, application_x_xz=655596 | 0x08000000,
application_x_zip=655596, application_x_zip=655597,
application_x_zstd=655597 | 0x08000000, application_x_zstd=655598 | 0x08000000,
application_x_zstd_dictionary=655598, application_x_zstd_dictionary=655599,
application_xml=655599, application_xml=655600,
application_zip=655600 | 0x10000000, application_zip=655601 | 0x10000000,
application_zlib=655601, application_zlib=655602,
audio_basic=458994 | 0x80000000, audio_basic=458995 | 0x80000000,
audio_it=458995, audio_it=458996,
audio_make=458996, audio_make=458997,
audio_mid=458997, audio_mid=458998,
audio_midi=458998, audio_midi=458999,
audio_mp4=458999, audio_mp4=459000,
audio_mpeg=459000, audio_mpeg=459001,
audio_ogg=459001, audio_ogg=459002,
audio_s3m=459002, audio_s3m=459003,
audio_tsp_audio=459003, audio_tsp_audio=459004,
audio_tsplayer=459004, audio_tsplayer=459005,
audio_vnd_qcelp=459005, audio_vnd_qcelp=459006,
audio_voxware=459006, audio_voxware=459007,
audio_x_aiff=459007, audio_x_aiff=459008,
audio_x_flac=459008, audio_x_flac=459009,
audio_x_gsm=459009, audio_x_gsm=459010,
audio_x_hx_aac_adts=459010, audio_x_hx_aac_adts=459011,
audio_x_jam=459011, audio_x_jam=459012,
audio_x_liveaudio=459012, audio_x_liveaudio=459013,
audio_x_m4a=459013, audio_x_m4a=459014,
audio_x_midi=459014, audio_x_midi=459015,
audio_x_mod=459015, audio_x_mod=459016,
audio_x_mp4a_latm=459016, audio_x_mp4a_latm=459017,
audio_x_mpeg_3=459017, audio_x_mpeg_3=459018,
audio_x_mpequrl=459018, audio_x_mpequrl=459019,
audio_x_nspaudio=459019, audio_x_nspaudio=459020,
audio_x_pn_realaudio=459020, audio_x_pn_realaudio=459021,
audio_x_psid=459021, audio_x_psid=459022,
audio_x_realaudio=459022, audio_x_realaudio=459023,
audio_x_s3m=459023, audio_x_s3m=459024,
audio_x_twinvq=459024, audio_x_twinvq=459025,
audio_x_twinvq_plugin=459025, audio_x_twinvq_plugin=459026,
audio_x_voc=459026, audio_x_voc=459027,
audio_x_wav=459027, audio_x_wav=459028,
audio_x_xbox_executable=459028 | 0x80000000, audio_x_xbox_executable=459029 | 0x80000000,
audio_x_xbox360_executable=459029 | 0x80000000, audio_x_xbox360_executable=459030 | 0x80000000,
audio_xm=459030, audio_xm=459031,
font_otf=327959 | 0x20000000, font_otf=327960 | 0x20000000,
font_sfnt=327960 | 0x20000000, font_sfnt=327961 | 0x20000000,
font_woff=327961 | 0x20000000, font_woff=327962 | 0x20000000,
font_woff2=327962 | 0x20000000, font_woff2=327963 | 0x20000000,
image_bmp=524571, image_bmp=524572,
image_cmu_raster=524572, image_cmu_raster=524573,
image_fif=524573, image_fif=524574,
image_florian=524574, image_florian=524575,
image_g3fax=524575, image_g3fax=524576,
image_gif=524576, image_gif=524577,
image_heic=524577, image_heic=524578,
image_ief=524578, image_ief=524579,
image_jpeg=524579, image_jpeg=524580,
image_jutvision=524580, image_jutvision=524581,
image_naplps=524581, image_naplps=524582,
image_pict=524582, image_pict=524583,
image_png=524583, image_png=524584,
image_svg=524584 | 0x80000000, image_svg=524585 | 0x80000000,
image_svg_xml=524585 | 0x80000000, image_svg_xml=524586 | 0x80000000,
image_tiff=524586, image_tiff=524587,
image_vnd_adobe_photoshop=524587 | 0x80000000, image_vnd_adobe_photoshop=524588 | 0x80000000,
image_vnd_djvu=524588 | 0x80000000, image_vnd_djvu=524589 | 0x80000000,
image_vnd_fpx=524589, image_vnd_fpx=524590,
image_vnd_microsoft_icon=524590, image_vnd_microsoft_icon=524591,
image_vnd_rn_realflash=524591, image_vnd_rn_realflash=524592,
image_vnd_rn_realpix=524592, image_vnd_rn_realpix=524593,
image_vnd_wap_wbmp=524593, image_vnd_wap_wbmp=524594,
image_vnd_xiff=524594, image_vnd_xiff=524595,
image_webp=524595, image_webp=524596,
image_wmf=524596, image_wmf=524597,
image_x_3ds=524597, image_x_3ds=524598,
image_x_adobe_dng=524598 | 0x00800000, image_x_adobe_dng=524599 | 0x00800000,
image_x_award_bioslogo=524599, image_x_award_bioslogo=524600,
image_x_canon_cr2=524600 | 0x00800000, image_x_canon_cr2=524601 | 0x00800000,
image_x_canon_crw=524601 | 0x00800000, image_x_canon_crw=524602 | 0x00800000,
image_x_cmu_raster=524602, image_x_cmu_raster=524603,
image_x_cur=524603, image_x_cur=524604,
image_x_dcraw=524604 | 0x00800000, image_x_dcraw=524605 | 0x00800000,
image_x_dwg=524605, image_x_dwg=524606,
image_x_eps=524606, image_x_eps=524607,
image_x_epson_erf=524607 | 0x00800000, image_x_epson_erf=524608 | 0x00800000,
image_x_exr=524608, image_x_exr=524609,
image_x_fuji_raf=524609 | 0x00800000, image_x_fuji_raf=524610 | 0x00800000,
image_x_gem=524610, image_x_gem=524611,
image_x_icns=524611, image_x_icns=524612,
image_x_icon=524612 | 0x80000000, image_x_icon=524613 | 0x80000000,
image_x_jg=524613, image_x_jg=524614,
image_x_jps=524614, image_x_jps=524615,
image_x_kodak_dcr=524615 | 0x00800000, image_x_kodak_dcr=524616 | 0x00800000,
image_x_kodak_k25=524616 | 0x00800000, image_x_kodak_k25=524617 | 0x00800000,
image_x_kodak_kdc=524617 | 0x00800000, image_x_kodak_kdc=524618 | 0x00800000,
image_x_minolta_mrw=524618 | 0x00800000, image_x_minolta_mrw=524619 | 0x00800000,
image_x_ms_bmp=524619, image_x_ms_bmp=524620,
image_x_niff=524620, image_x_niff=524621,
image_x_nikon_nef=524621 | 0x00800000, image_x_nikon_nef=524622 | 0x00800000,
image_x_olympus_orf=524622 | 0x00800000, image_x_olympus_orf=524623 | 0x00800000,
image_x_panasonic_raw=524623 | 0x00800000, image_x_panasonic_raw=524624 | 0x00800000,
image_x_pcx=524624, image_x_pcx=524625,
image_x_pentax_pef=524625 | 0x00800000, image_x_pentax_pef=524626 | 0x00800000,
image_x_pict=524626, image_x_pict=524627,
image_x_portable_bitmap=524627, image_x_portable_bitmap=524628,
image_x_portable_graymap=524628, image_x_portable_graymap=524629,
image_x_portable_pixmap=524629, image_x_portable_pixmap=524630,
image_x_quicktime=524630, image_x_quicktime=524631,
image_x_rgb=524631, image_x_rgb=524632,
image_x_sigma_x3f=524632 | 0x00800000, image_x_sigma_x3f=524633 | 0x00800000,
image_x_sony_arw=524633 | 0x00800000, image_x_sony_arw=524634 | 0x00800000,
image_x_sony_sr2=524634 | 0x00800000, image_x_sony_sr2=524635 | 0x00800000,
image_x_sony_srf=524635 | 0x00800000, image_x_sony_srf=524636 | 0x00800000,
image_x_tga=524636, image_x_tga=524637,
image_x_tiff=524637, image_x_tiff=524638,
image_x_win_bitmap=524638, image_x_win_bitmap=524639,
image_x_xcf=524639 | 0x80000000, image_x_xcf=524640 | 0x80000000,
image_x_xpixmap=524640 | 0x80000000, image_x_xpixmap=524641 | 0x80000000,
image_x_xwindowdump=524641, image_x_xwindowdump=524642,
message_news=196962, message_news=196963,
message_rfc822=196963, message_rfc822=196964,
model_vnd_dwf=65892, model_vnd_dwf=65893,
model_vnd_gdl=65893, model_vnd_gdl=65894,
model_vnd_gs_gdl=65894, model_vnd_gs_gdl=65895,
model_vrml=65895, model_vrml=65896,
model_x_pov=65896, model_x_pov=65897,
text_PGP=590185, text_PGP=590186,
text_asp=590186, text_asp=590187,
text_css=590187, text_css=590188,
text_html=590188 | 0x01000000, text_html=590189 | 0x01000000,
text_javascript=590189, text_javascript=590190,
text_mcf=590190, text_mcf=590191,
text_pascal=590191, text_pascal=590192,
text_plain=590192, text_plain=590193,
text_richtext=590193, text_richtext=590194,
text_rtf=590194, text_rtf=590195,
text_scriplet=590195, text_scriplet=590196,
text_tab_separated_values=590196, text_tab_separated_values=590197,
text_troff=590197, text_troff=590198,
text_uri_list=590198, text_uri_list=590199,
text_vnd_abc=590199, text_vnd_abc=590200,
text_vnd_fmi_flexstor=590200, text_vnd_fmi_flexstor=590201,
text_vnd_wap_wml=590201, text_vnd_wap_wml=590202,
text_vnd_wap_wmlscript=590202, text_vnd_wap_wmlscript=590203,
text_webviewhtml=590203, text_webviewhtml=590204,
text_x_Algol68=590204, text_x_Algol68=590205,
text_x_asm=590205, text_x_asm=590206,
text_x_audiosoft_intra=590206, text_x_audiosoft_intra=590207,
text_x_awk=590207, text_x_awk=590208,
text_x_bcpl=590208, text_x_bcpl=590209,
text_x_c=590209, text_x_c=590210,
text_x_c__=590210, text_x_c__=590211,
text_x_component=590211, text_x_component=590212,
text_x_diff=590212, text_x_diff=590213,
text_x_fortran=590213, text_x_fortran=590214,
text_x_java=590214, text_x_java=590215,
text_x_la_asf=590215, text_x_la_asf=590216,
text_x_lisp=590216, text_x_lisp=590217,
text_x_m=590217, text_x_m=590218,
text_x_m4=590218, text_x_m4=590219,
text_x_makefile=590219, text_x_makefile=590220,
text_x_ms_regedit=590220, text_x_ms_regedit=590221,
text_x_msdos_batch=590221, text_x_msdos_batch=590222,
text_x_objective_c=590222, text_x_objective_c=590223,
text_x_pascal=590223, text_x_pascal=590224,
text_x_perl=590224, text_x_perl=590225,
text_x_php=590225, text_x_php=590226,
text_x_po=590226, text_x_po=590227,
text_x_python=590227, text_x_python=590228,
text_x_ruby=590228, text_x_ruby=590229,
text_x_sass=590229, text_x_sass=590230,
text_x_scss=590230, text_x_scss=590231,
text_x_server_parsed_html=590231, text_x_server_parsed_html=590232,
text_x_setext=590232, text_x_setext=590233,
text_x_sgml=590233 | 0x01000000, text_x_sgml=590234 | 0x01000000,
text_x_shellscript=590234, text_x_shellscript=590235,
text_x_speech=590235, text_x_speech=590236,
text_x_tcl=590236, text_x_tcl=590237,
text_x_tex=590237, text_x_tex=590238,
text_x_uil=590238, text_x_uil=590239,
text_x_uuencode=590239, text_x_uuencode=590240,
text_x_vcalendar=590240, text_x_vcalendar=590241,
text_x_vcard=590241, text_x_vcard=590242,
text_xml=590242 | 0x01000000, text_xml=590243 | 0x01000000,
video_MP2T=393635, video_MP2T=393636,
video_animaflex=393636, video_animaflex=393637,
video_avi=393637, video_avi=393638,
video_avs_video=393638, video_avs_video=393639,
video_mp4=393639, video_mp4=393640,
video_mpeg=393640, video_mpeg=393641,
video_quicktime=393641, video_quicktime=393642,
video_vdo=393642, video_vdo=393643,
video_vivo=393643, video_vivo=393644,
video_vnd_rn_realvideo=393644, video_vnd_rn_realvideo=393645,
video_vosaic=393645, video_vosaic=393646,
video_webm=393646, video_webm=393647,
video_x_amt_demorun=393647, video_x_amt_demorun=393648,
video_x_amt_showrun=393648, video_x_amt_showrun=393649,
video_x_atomic3d_feature=393649, video_x_atomic3d_feature=393650,
video_x_dl=393650, video_x_dl=393651,
video_x_dv=393651, video_x_dv=393652,
video_x_fli=393652, video_x_fli=393653,
video_x_flv=393653, video_x_flv=393654,
video_x_isvideo=393654, video_x_isvideo=393655,
video_x_jng=393655 | 0x80000000, video_x_jng=393656 | 0x80000000,
video_x_m4v=393656, video_x_m4v=393657,
video_x_matroska=393657, video_x_matroska=393658,
video_x_mng=393658, video_x_mng=393659,
video_x_motion_jpeg=393659, video_x_motion_jpeg=393660,
video_x_ms_asf=393660, video_x_ms_asf=393661,
video_x_msvideo=393661, video_x_msvideo=393662,
video_x_qtc=393662, video_x_qtc=393663,
video_x_sgi_movie=393663, video_x_sgi_movie=393664,
x_epoc_x_sisx_app=721344, x_epoc_x_sisx_app=721345,
}; };
char *mime_get_mime_text(unsigned int mime_id) {switch (mime_id) { char *mime_get_mime_text(unsigned int mime_id) {switch (mime_id) {
case application_arj: return "application/arj"; case application_arj: return "application/arj";
@@ -804,6 +805,7 @@ case text_mcf: return "text/mcf";
case text_pascal: return "text/pascal"; case text_pascal: return "text/pascal";
case text_PGP: return "text/PGP"; case text_PGP: return "text/PGP";
case text_plain: return "text/plain"; case text_plain: return "text/plain";
case application_vnd_coffeescript: return "application/vnd.coffeescript";
case text_richtext: return "text/richtext"; case text_richtext: return "text/richtext";
case text_rtf: return "text/rtf"; case text_rtf: return "text/rtf";
case text_scriplet: return "text/scriplet"; case text_scriplet: return "text/scriplet";
@@ -1315,6 +1317,11 @@ g_hash_table_insert(ext_table, "sfv", (gpointer)text_plain);
g_hash_table_insert(ext_table, "m3u", (gpointer)text_plain); g_hash_table_insert(ext_table, "m3u", (gpointer)text_plain);
g_hash_table_insert(ext_table, "csv", (gpointer)text_plain); g_hash_table_insert(ext_table, "csv", (gpointer)text_plain);
g_hash_table_insert(ext_table, "eml", (gpointer)text_plain); g_hash_table_insert(ext_table, "eml", (gpointer)text_plain);
g_hash_table_insert(ext_table, "make", (gpointer)text_plain);
g_hash_table_insert(ext_table, "log", (gpointer)text_plain);
g_hash_table_insert(ext_table, "markdown", (gpointer)text_plain);
g_hash_table_insert(ext_table, "yaml", (gpointer)text_plain);
g_hash_table_insert(ext_table, "coffee", (gpointer)application_vnd_coffeescript);
g_hash_table_insert(ext_table, "rt", (gpointer)text_richtext); g_hash_table_insert(ext_table, "rt", (gpointer)text_richtext);
g_hash_table_insert(ext_table, "rtf", (gpointer)text_richtext); g_hash_table_insert(ext_table, "rtf", (gpointer)text_richtext);
g_hash_table_insert(ext_table, "rtx", (gpointer)text_richtext); g_hash_table_insert(ext_table, "rtx", (gpointer)text_richtext);
@@ -1792,6 +1799,7 @@ g_hash_table_insert(mime_table, "text/mcf", (gpointer)text_mcf);
g_hash_table_insert(mime_table, "text/pascal", (gpointer)text_pascal); g_hash_table_insert(mime_table, "text/pascal", (gpointer)text_pascal);
g_hash_table_insert(mime_table, "text/PGP", (gpointer)text_PGP); g_hash_table_insert(mime_table, "text/PGP", (gpointer)text_PGP);
g_hash_table_insert(mime_table, "text/plain", (gpointer)text_plain); g_hash_table_insert(mime_table, "text/plain", (gpointer)text_plain);
g_hash_table_insert(mime_table, "application/vnd.coffeescript", (gpointer)application_vnd_coffeescript);
g_hash_table_insert(mime_table, "text/richtext", (gpointer)text_richtext); g_hash_table_insert(mime_table, "text/richtext", (gpointer)text_richtext);
g_hash_table_insert(mime_table, "text/rtf", (gpointer)text_rtf); g_hash_table_insert(mime_table, "text/rtf", (gpointer)text_rtf);
g_hash_table_insert(mime_table, "text/scriplet", (gpointer)text_scriplet); g_hash_table_insert(mime_table, "text/scriplet", (gpointer)text_scriplet);

View File

@@ -38,6 +38,8 @@ void fs_reset(struct vfile *f) {
} }
} }
#define IS_GIT_OBJ (strlen(doc.filepath + doc.base) == 38 && (strstr(doc.filepath, "objects") != NULL))
void parse(void *arg) { void parse(void *arg) {
parse_job_t *job = arg; parse_job_t *job = arg;
@@ -77,6 +79,10 @@ void parse(void *arg) {
int bytes_read = 0; int bytes_read = 0;
if (doc.mime == 0 && !ScanCtx.fast) { if (doc.mime == 0 && !ScanCtx.fast) {
if (IS_GIT_OBJ) {
goto abort;
}
// Get mime type with libmagic // Get mime type with libmagic
if (!job->vfile.is_fs_file) { if (!job->vfile.is_fs_file) {
LOG_WARNING(job->filepath, "Guessing mime type with libmagic inside archive files is not currently supported"); LOG_WARNING(job->filepath, "Guessing mime type with libmagic inside archive files is not currently supported");

View File

@@ -121,7 +121,7 @@ body {
background: #546b7a; background: #546b7a;
} }
a:hover,.btn:hover { a:hover, .btn:hover {
color: #fff; color: #fff;
} }
@@ -130,7 +130,11 @@ a:hover,.btn:hover {
} }
.document { .document {
padding: 0.5rem; padding: 0.3rem;
}
.card-text:last-child {
margin-top: -1px;
} }
.document p { .document p {
@@ -203,7 +207,7 @@ a:hover,.btn:hover {
margin-top: -1px; margin-top: -1px;
font-family: monospace; font-family: monospace;
font-size: 90%; font-size: 90%;
background: rgba(0,0,0,0.2); background: rgba(0, 0, 0, 0.2);
padding: 0.1em 0.4em; padding: 0.1em 0.4em;
color: white; color: white;
cursor: pointer; cursor: pointer;
@@ -214,17 +218,24 @@ a:hover,.btn:hover {
background-color: #e0e0e0; background-color: #e0e0e0;
} }
.card-img-top {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.fit { .fit {
display: block; display: block;
min-width: 64px; min-width: 64px;
max-width: 100%; max-width: 100%;
max-height: 175px; max-height: 400px;
margin: 0 auto 0; margin: 0 auto 0;
padding: 3px 3px 0;
width: auto;
height: auto; height: auto;
} }
.img-padding {
padding: 4px 4px 0 4px;
}
.fit-sm { .fit-sm {
display: block; display: block;
max-width: 64px; max-width: 64px;
@@ -241,20 +252,6 @@ a:hover,.btn:hover {
width: 100%; width: 100%;
} }
@media screen and (min-width: 1500px) {
.container {
max-width: 1440px;
}
.bricklayer-column-sizer {
width: 20% !important;
}
.bricklayer-column {
max-width: 20%;
}
}
@media screen and (min-width: 1800px) { @media screen and (min-width: 1800px) {
.container { .container {
max-width: 1550px; max-width: 1550px;
@@ -451,6 +448,7 @@ option {
.small-btn { .small-btn {
display: none; display: none;
} }
.large-btn { .large-btn {
display: inherit; display: inherit;
} }
@@ -460,6 +458,7 @@ option {
.small-btn { .small-btn {
display: inherit; display: inherit;
} }
.large-btn { .large-btn {
display: none; display: none;
} }

View File

@@ -70,7 +70,11 @@ body {
} }
.document { .document {
padding: 0.5rem; padding: 0.3rem;
}
.card-text:last-child {
margin-top: -1px;
} }
.document p { .document p {
@@ -153,18 +157,25 @@ body {
overflow: hidden; overflow: hidden;
} }
.card-img-top {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.fit { .fit {
display: block; display: block;
min-width: 64px; min-width: 64px;
max-width: 100%; max-width: 100%;
max-height: 175px; max-height: 400px;
margin: 0 auto 0; margin: 0 auto 0;
padding: 3px 3px 0 3px;
width: auto; width: auto;
height: auto; height: auto;
} }
.img-padding {
padding: 4px 4px 0 4px;
}
.fit-sm { .fit-sm {
display: block; display: block;
max-width: 64px; max-width: 64px;
@@ -181,6 +192,10 @@ body {
width: 100%; width: 100%;
} }
.bricklayer {
/*max-width: 100%;*/
}
@media screen and (max-width: 1200px) { @media screen and (max-width: 1200px) {
.bricklayer-column { .bricklayer-column {
max-width: 100%; max-width: 100%;

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",
@@ -392,7 +397,11 @@ function makeThumbnail(mimeCategory, hit, imgWrapper, small) {
if (small) { if (small) {
thumbnail.setAttribute("class", "fit-sm"); thumbnail.setAttribute("class", "fit-sm");
} else { } else {
thumbnail.setAttribute("class", "card-img-top fit"); if (hit["_source"].hasOwnProperty("parent")) {
thumbnail.setAttribute("class", "card-img-top fit img-padding");
} else {
thumbnail.setAttribute("class", "card-img-top fit");
}
} }
thumbnail.setAttribute("src", `t/${hit["_source"]["index"]}/${hit["_id"]}`); thumbnail.setAttribute("src", `t/${hit["_source"]["index"]}/${hit["_id"]}`);

View File

@@ -1,4 +1,4 @@
const SIZE = 40; const SIZE = 60;
let mimeMap = []; let mimeMap = [];
let tagMap = []; let tagMap = [];
let mimeTree; let mimeTree;
@@ -253,7 +253,7 @@ function handleTreeClick(tree) {
if (node.id === "any") { if (node.id === "any") {
if (!node.itree.state.checked) { if (!node.itree.state.checked) {
tree.deselect(); tree.deselectDeep();
} }
} else { } else {
tree.node("any").deselect(); tree.node("any").deselect();

View File

@@ -101,7 +101,8 @@ const _defaults = {
treemapColor: "PuBuGn", treemapColor: "PuBuGn",
treemapSize: "large", treemapSize: "large",
suggestPath: true, suggestPath: true,
fragmentSize: 100 fragmentSize: 100,
columns: 5
}; };
function loadSettings() { function loadSettings() {
@@ -118,6 +119,7 @@ function loadSettings() {
$("#settingTreemapType").val(CONF.options.treemapType); $("#settingTreemapType").val(CONF.options.treemapType);
$("#settingSuggestPath").prop("checked", CONF.options.suggestPath); $("#settingSuggestPath").prop("checked", CONF.options.suggestPath);
$("#settingFragmentSize").val(CONF.options.fragmentSize); $("#settingFragmentSize").val(CONF.options.fragmentSize);
$("#settingColumns").val(CONF.options.columns);
} }
function Settings() { function Settings() {
@@ -125,6 +127,7 @@ function Settings() {
this._onUpdate = function () { this._onUpdate = function () {
$("#fuzzyToggle").prop("checked", this.options.fuzzy); $("#fuzzyToggle").prop("checked", this.options.fuzzy);
updateColumnStyle();
}; };
this.load = function () { this.load = function () {
@@ -161,6 +164,7 @@ function updateSettings() {
CONF.options.treemapType = $("#settingTreemapType").val(); CONF.options.treemapType = $("#settingTreemapType").val();
CONF.options.suggestPath = $("#settingSuggestPath").prop("checked"); CONF.options.suggestPath = $("#settingSuggestPath").prop("checked");
CONF.options.fragmentSize = $("#settingFragmentSize").val(); CONF.options.fragmentSize = $("#settingFragmentSize").val();
CONF.options.columns = $("#settingColumns").val();
CONF.save(); CONF.save();
if (typeof searchDebounced !== "undefined") { if (typeof searchDebounced !== "undefined") {
@@ -203,3 +207,26 @@ function toggleTheme() {
} }
window.location.reload(); window.location.reload();
} }
function updateColumnStyle() {
const style = document.getElementById("style");
if (style) {
style.innerHTML =
`
@media screen and (min-width: 1500px) {
.container {
max-width: 1440px;
}
.bricklayer-column-sizer {
width: ${100 / CONF.options.columns}% !important;
}
.bricklayer-column {
max-width: ${100 / CONF.options.columns}%;
}
}
}
`
}
}

View File

@@ -6,12 +6,13 @@
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'/> <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'/>
<link href="css" rel="stylesheet" type="text/css"> <link href="css" rel="stylesheet" type="text/css">
<style id="style"></style>
</head> </head>
<body> <body>
<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.7.3</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
@@ -216,6 +217,19 @@
<option value="list">List</option> <option value="list">List</option>
</select> </select>
<div class="form-group">
<label for="settingColumns">Maximum column count</label>
<select id="settingColumns" class="form-control form-control-sm">
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
</div>
<hr/> <hr/>
<h4>Stats</h4> <h4>Stats</h4>

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.7.3</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"
@@ -94,6 +94,19 @@
<option value="list">List</option> <option value="list">List</option>
</select> </select>
<div class="form-group">
<label for="settingColumns">Maximum column count</label>
<select id="settingColumns" class="form-control form-control-sm">
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
</div>
<hr/> <hr/>
<h4>Stats</h4> <h4>Stats</h4>

View File

@@ -10,7 +10,7 @@ typedef struct index_descriptor {
char version[64]; char version[64];
long timestamp; long timestamp;
char root[PATH_MAX]; char root[PATH_MAX];
char rewrite_url[8196]; char rewrite_url[8192];
short root_len; short root_len;
char name[1024]; char name[1024];
char type[64]; char type[64];

View File

@@ -111,7 +111,7 @@ void stats_files(struct mg_connection *nc, struct http_message *hm, struct mg_st
return; return;
} }
char disposition[8196]; char disposition[8192];
snprintf(disposition, sizeof(disposition), "Content-Disposition: inline; filename=\"%s\"", file); snprintf(disposition, sizeof(disposition), "Content-Disposition: inline; filename=\"%s\"", file);
char full_path[PATH_MAX]; char full_path[PATH_MAX];
@@ -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;
@@ -256,7 +256,7 @@ int serve_file_from_url(cJSON *json, index_t *idx, struct mg_connection *nc) {
const char *ext = cJSON_GetObjectItem(json, "extension")->valuestring; const char *ext = cJSON_GetObjectItem(json, "extension")->valuestring;
char url[8196]; char url[8192];
snprintf(url, sizeof(url), snprintf(url, sizeof(url),
"%s%s/%s%s%s", "%s%s/%s%s%s",
idx->desc.rewrite_url, path_unescaped, name_unescaped, strlen(ext) == 0 ? "" : ".", ext); idx->desc.rewrite_url, path_unescaped, name_unescaped, strlen(ext) == 0 ? "" : ".", ext);
@@ -291,7 +291,7 @@ void serve_file_from_disk(cJSON *json, index_t *idx, struct mg_connection *nc, s
LOG_DEBUGF("serve.c", "Serving file from disk: %s", full_path) LOG_DEBUGF("serve.c", "Serving file from disk: %s", full_path)
char disposition[8196]; char disposition[8192];
snprintf(disposition, sizeof(disposition), "Content-Disposition: inline; filename=\"%s%s%s\"", snprintf(disposition, sizeof(disposition), "Content-Disposition: inline; filename=\"%s%s%s\"",
name, strlen(ext) == 0 ? "" : ".", ext); name, strlen(ext) == 0 ? "" : ".", ext);
@@ -538,7 +538,7 @@ void tag(struct mg_connection *nc, struct http_message *hm, struct mg_str *path)
} }
} }
char buf[8196]; char buf[8192];
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"{" "{"
" \"script\" : {" " \"script\" : {"
@@ -552,13 +552,13 @@ 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 {
cJSON_AddItemToArray(arr, cJSON_CreateString(arg_req->name)); cJSON_AddItemToArray(arr, cJSON_CreateString(arg_req->name));
char buf[8196]; char buf[8192];
snprintf(buf, sizeof(buf), snprintf(buf, sizeof(buf),
"{" "{"
" \"script\" : {" " \"script\" : {"
@@ -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