Compare commits

...

13 Commits

Author SHA1 Message Date
e72fa1587b EXIF metadata for images 2019-11-09 15:18:44 -05:00
ea4fb7fa0d Bug fixes 2019-11-09 12:00:07 -05:00
b0a868bb73 remove 'must match' 2019-11-08 21:46:54 -05:00
d761a3b595 update readme 2019-11-08 19:42:36 -05:00
2d7a8a2fdc fuzzy toggle 2019-11-08 16:15:10 -05:00
152d2ddf8a bug fix in deserialize 2019-11-08 09:03:44 -05:00
bc5f22b759 update readme 2019-11-05 18:59:00 -05:00
534b397876 update readme, UI tweak: don't show broken images 2019-11-03 10:39:02 -05:00
7962a994e2 utf8 update + bug fixes 2019-11-03 07:50:31 -05:00
f8f1a27180 video metadata 2019-10-31 11:54:13 -04:00
784c3c9435 Font rendering fixes 2019-10-31 10:15:01 -04:00
f8b081a3f4 UI tweaks, path autocomplete 2019-10-31 08:26:19 -04:00
5661573b06 Dark theme, pdf meta, de-serialize bugfix 2019-10-30 22:20:22 -04:00
41 changed files with 1467 additions and 608 deletions

2
.gitignore vendored
View File

@@ -11,7 +11,7 @@ Makefile
LOG LOG
sist2* sist2*
index.sist2/ index.sist2/
bundle.css bundle*.css
bundle.js bundle.js
*.a *.a
vgcore.* vgcore.*

9
.gitmodules vendored
View File

@@ -16,3 +16,12 @@
[submodule "lmdb"] [submodule "lmdb"]
path = lmdb path = lmdb
url = https://github.com/LMDB/lmdb url = https://github.com/LMDB/lmdb
[submodule "utf8.h"]
path = utf8.h
url = https://github.com/sheredom/utf8.h
[submodule "lib/openjpeg"]
path = lib/openjpeg
url = https://github.com/uclouvain/openjpeg
[submodule "lib/harfbuzz"]
path = lib/harfbuzz
url = https://github.com/harfbuzz/harfbuzz

View File

@@ -37,6 +37,9 @@ if (WITH_SIST2)
lmdb/libraries/liblmdb/lmdb.h lmdb/libraries/liblmdb/mdb.c lmdb/libraries/liblmdb/lmdb.h lmdb/libraries/liblmdb/mdb.c
lmdb/libraries/liblmdb/midl.h lmdb/libraries/liblmdb/midl.c lmdb/libraries/liblmdb/midl.h lmdb/libraries/liblmdb/midl.c
src/cli.c src/cli.h src/cli.c src/cli.h
# utf8.h
utf8.h/utf8.h
) )
endif () endif ()
@@ -67,6 +70,9 @@ if (WITH_SIST2_SCAN)
lmdb/libraries/liblmdb/lmdb.h lmdb/libraries/liblmdb/mdb.c lmdb/libraries/liblmdb/lmdb.h lmdb/libraries/liblmdb/mdb.c
lmdb/libraries/liblmdb/midl.h lmdb/libraries/liblmdb/midl.c lmdb/libraries/liblmdb/midl.h lmdb/libraries/liblmdb/midl.c
src/cli.c src/cli.h src/cli.c src/cli.h
# utf8.h
utf8.h/utf8.h
) )
endif () endif ()
@@ -116,8 +122,8 @@ if (WITH_SIST2)
target_compile_options(sist2 target_compile_options(sist2
PRIVATE PRIVATE
-O3 -Ofast
# -march=native # -march=native
-fno-stack-protector -fno-stack-protector
-fomit-frame-pointer -fomit-frame-pointer
) )
@@ -150,6 +156,9 @@ if (WITH_SIST2)
m m
bz2 bz2
magic magic
harfbuzz
openjp2
freetype
) )
endif () endif ()
@@ -187,7 +196,7 @@ if (WITH_SIST2_SCAN)
) )
target_compile_options(sist2_scan target_compile_options(sist2_scan
PRIVATE PRIVATE
-O3 -Ofast
# -march=native # -march=native
-fno-stack-protector -fno-stack-protector
-fomit-frame-pointer -fomit-frame-pointer
@@ -215,6 +224,9 @@ if (WITH_SIST2_SCAN)
pthread pthread
m m
${PROJECT_SOURCE_DIR}/lib/libharfbuzz.a
${PROJECT_SOURCE_DIR}/lib/libopenjp2.a
freetype
) )
endif () endif ()

View File

@@ -9,7 +9,7 @@ sist2 (Simple incremental search tool)
## Features ## Features
* Fast, low memory usage * Fast, low memory usage, multi-threaded
* Portable (all its features are packaged in a single executable) * Portable (all its features are packaged in a single executable)
* Extracts text from common file types\* * Extracts text from common file types\*
* Generates thumbnails\* * Generates thumbnails\*
@@ -56,10 +56,10 @@ sist2 web --bind 0.0.0.0 --port 4321 ./my_idx1 ./my_idx2 ./my_idx3
File type | Library | Content | Thumbnail | Metadata File type | Library | Content | Thumbnail | Metadata
:---|:---|:---|:---|:--- :---|:---|:---|:---|:---
pdf,xps,cbz,cbr,fb2,epub | MuPDF | yes | yes, `png` | *planned* | pdf,xps,cbz,fb2,epub | MuPDF | yes | yes, `png` | title |
`audio/*` | libav | - | yes, `jpeg` | ID3 tags | `audio/*` | ffmpeg | - | yes, `jpeg` | ID3 tags |
`video/*` | libav | - | yes, `jpeg` | *planned* | `video/*` | ffmpeg | - | yes, `jpeg` | title, comment, artist |
`image/*` | libav | - | yes, `jpeg` | *planned* | `image/*` | ffmpeg | - | yes, `jpeg` | `EXIF:Artist`, `EXIF:ImageDescription` |
ttf,ttc,cff,woff,fnt,otf | Freetype2 | - | yes, `bmp` | Name & style | ttf,ttc,cff,woff,fnt,otf | Freetype2 | - | yes, `bmp` | Name & style |
`text/plain` | *(none)* | yes | no | - | `text/plain` | *(none)* | yes | no | - |
docx, xlsx, pptx | | *planned* | no | *planned* | docx, xlsx, pptx | | *planned* | no | *planned* |
@@ -79,13 +79,14 @@ binaries.
apt install git cmake pkg-config libglib2.0-dev\ apt install git cmake pkg-config libglib2.0-dev\
libssl-dev uuid-dev libavformat-dev libswscale-dev \ libssl-dev uuid-dev libavformat-dev libswscale-dev \
python3 libmagic-dev libfreetype6-dev libcurl-dev \ python3 libmagic-dev libfreetype6-dev libcurl-dev \
libbz2-dev yasm libbz2-dev yasm libharfbuzz-dev ragel
``` ```
*(FreeBSD)* *(FreeBSD)*
```bash ```bash
pkg install cmake gcc yasm gmake bash ffmpeg e2fsprogs-uuid pkg install cmake gcc yasm gmake bash ffmpeg e2fsprogs-uuid\
autotools ragel
``` ```
__
2. Build 2. Build
```bash ```bash
git clone --recurse-submodules https://github.com/simon987/sist2 git clone --recurse-submodules https://github.com/simon987/sist2

2
cJSON

Submodule cJSON updated: 2de7d04aaf...533ff8a783

1
lib/harfbuzz Submodule

Submodule lib/harfbuzz added at 7cde68f10c

1
lib/openjpeg Submodule

Submodule lib/openjpeg added at 5875a6b446

View File

@@ -91,7 +91,7 @@ application/x-esrehber, es
application/x-excel, xla|xld|xlk|xlt|xlv application/x-excel, xla|xld|xlk|xlt|xlv
application/x-executable, exe application/x-executable, exe
application/x-font-sfn, application/x-font-sfn,
application/x-font-ttf, ttf application/x-font-ttf, ttf|ttc
application/x-freelance, pre application/x-freelance, pre
application/x-git, application/x-git,
application/x-gsp, gsp application/x-gsp, gsp
@@ -254,6 +254,7 @@ text/mcf, mcf
text/pascal, pas text/pascal, pas
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 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
text/richtext, rt|rtf|rtx text/richtext, rt|rtf|rtx
text/rtf,
text/scriplet, wsc text/scriplet, wsc
text/x-awk, awk text/x-awk, awk
!video/x-jng, jng !video/x-jng, jng
@@ -263,7 +264,7 @@ image/x-xwindowdump, xwd
!image/vnd.adobe.photoshop, psd !image/vnd.adobe.photoshop, psd
text/tab-separated-values, tsv text/tab-separated-values, tsv
text/troff, man|me|ms|roff|t|tr text/troff, man|me|ms|roff|t|tr
text/uri-list, uni|unis|uri|uris text/uri-list, uji|unis|uri|uris
text/vnd.abc, abc text/vnd.abc, abc
text/vnd.fmi.flexstor, flx text/vnd.fmi.flexstor, flx
text/vnd.wap.wmlscript, wmls text/vnd.wap.wmlscript, wmls
@@ -359,3 +360,54 @@ image/x-tga,
application/x-wine-extension-ini, application/x-wine-extension-ini,
application/x-cbz, cbz application/x-cbz, cbz
application/x-cbr, cbr application/x-cbr, cbr
application/x-ms-compress-szdd, fon
application/x-atari-7800-rom, a78
application/x-nes-rom, nes
application/x-font-pfm, pfm
application/x-gettext-translation,
image/wmf,
application/pgp-keys,
image/x-3ds, 3ds
application/x-lz4, lz4
application/vnd.openxmlformats-officedocument.presentationml.presentation, pptx
application/vnd.oasis.opendocument.presentation, odp
application/x-msaccess, accdb
application/vnd.oasis.opendocument.spreadsheet, ods
audio/x-aiff, aiff|aif
text/x-ms-regedit, reg
application/x-gamecube-rom,
application/x-nintendo-ds-rom,
text/x-objective-c,
application/x-font-gdos,
application/x-apple-diskimage,
application/x-zstd, zst
video/x-m4v, m4v
message/news,
application/vnd.symbian.install,
application/x-lzh-compressed,
application/x-dosdriver,
application/vnd.tcpdump.pcap, pcap
x-epoc/x-sisx-app,
application/x-avira-qua,
video/MP2T,
application/x-snappy-framed,
application/x-lz4+json, jsonlz4
application/x-dmp, dmp
application/zlib, z
application/x-pgp-keyring,
application/x-gdbm,
application/x-font-pf2, pf2
application/x-zip,
application/x-coredump,
application/x-java-jmod, jmod
application/x-terminfo,
application/x-terminfo2,
application/x-arc,
application/vnd.lotus-1-2-3,
image/x-win-bitmap,
application/x-maxis-dbpf,
text/PGP,
audio/x-hx-aac-adts,
application/x-chrome-extension,
image/heic, heic
image/x-gem,
1 application/arj arj
91 application/x-excel xla|xld|xlk|xlt|xlv
92 application/x-executable exe
93 application/x-font-sfn
94 application/x-font-ttf ttf ttf|ttc
95 application/x-freelance pre
96 application/x-git
97 application/x-gsp gsp
254 text/pascal pas
255 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
256 text/richtext rt|rtf|rtx
257 text/rtf
258 text/scriplet wsc
259 text/x-awk awk
260 !video/x-jng jng
264 !image/vnd.adobe.photoshop psd
265 text/tab-separated-values tsv
266 text/troff man|me|ms|roff|t|tr
267 text/uri-list uni|unis|uri|uris uji|unis|uri|uris
268 text/vnd.abc abc
269 text/vnd.fmi.flexstor flx
270 text/vnd.wap.wmlscript wmls
360 application/x-wine-extension-ini
361 application/x-cbz cbz
362 application/x-cbr cbr
363 application/x-ms-compress-szdd fon
364 application/x-atari-7800-rom a78
365 application/x-nes-rom nes
366 application/x-font-pfm pfm
367 application/x-gettext-translation
368 image/wmf
369 application/pgp-keys
370 image/x-3ds 3ds
371 application/x-lz4 lz4
372 application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
373 application/vnd.oasis.opendocument.presentation odp
374 application/x-msaccess accdb
375 application/vnd.oasis.opendocument.spreadsheet ods
376 audio/x-aiff aiff|aif
377 text/x-ms-regedit reg
378 application/x-gamecube-rom
379 application/x-nintendo-ds-rom
380 text/x-objective-c
381 application/x-font-gdos
382 application/x-apple-diskimage
383 application/x-zstd zst
384 video/x-m4v m4v
385 message/news
386 application/vnd.symbian.install
387 application/x-lzh-compressed
388 application/x-dosdriver
389 application/vnd.tcpdump.pcap pcap
390 x-epoc/x-sisx-app
391 application/x-avira-qua
392 video/MP2T
393 application/x-snappy-framed
394 application/x-lz4+json jsonlz4
395 application/x-dmp dmp
396 application/zlib z
397 application/x-pgp-keyring
398 application/x-gdbm
399 application/x-font-pf2 pf2
400 application/x-zip
401 application/x-coredump
402 application/x-java-jmod jmod
403 application/x-terminfo
404 application/x-terminfo2
405 application/x-arc
406 application/vnd.lotus-1-2-3
407 image/x-win-bitmap
408 application/x-maxis-dbpf
409 text/PGP
410 audio/x-hx-aac-adts
411 application/x-chrome-extension
412 image/heic heic
413 image/x-gem

View File

@@ -6,9 +6,11 @@ rm web/js/bundle.js 2> /dev/null
cat `ls web/js/*.min.js` > web/js/bundle.js cat `ls web/js/*.min.js` > web/js/bundle.js
cat web/js/{util,dom,search}.js >> web/js/bundle.js cat web/js/{util,dom,search}.js >> web/js/bundle.js
rm web/css/bundle.css 2> /dev/null rm web/css/bundle*.css 2> /dev/null
cat web/css/*.min.css > web/css/bundle.css cat web/css/*.min.css > web/css/bundle.css
cat web/css/main.css >> web/css/bundle.css cat web/css/light.css >> web/css/bundle.css
cat web/css/*.min.css > web/css/bundle_dark.css
cat web/css/dark.css >> web/css/bundle_dark.css
python3 scripts/mime.py > src/parsing/mime_generated.c python3 scripts/mime.py > src/parsing/mime_generated.c
python3 scripts/serve_static.py > src/web/static_generated.c python3 scripts/serve_static.py > src/web/static_generated.c

View File

@@ -2,12 +2,28 @@
cd lib cd lib
cd mupdf cd mupdf
HAVE_X11=no HAVE_GLUT=no make -j 4 USE_SYSTEM_HARFBUZZ=yes USE_SYSTEM_OPENJPEG=yes HAVE_X11=no HAVE_GLUT=no make -j 4
cd .. cd ..
mv mupdf/build/release/libmupdf.a . mv mupdf/build/release/libmupdf.a .
mv mupdf/build/release/libmupdf-third.a . mv mupdf/build/release/libmupdf-third.a .
# openjp2
cd openjpeg
#cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O3 -march=native -DNDEBUG"
cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O3"
make -j 4
cd ..
mv openjpeg/bin/libopenjp2.a .
# harfbuzz
cd harfbuzz
./autogen.sh
./configure --disable-shared --enable-static
make -j 4
cd ..
mv harfbuzz/src/.libs/libharfbuzz.a .
# ffmpeg # ffmpeg
cd ffmpeg cd ffmpeg
./configure --disable-shared --enable-static --disable-ffmpeg --disable-ffplay \ ./configure --disable-shared --enable-static --disable-ffmpeg --disable-ffplay \

View File

@@ -9,6 +9,22 @@ cd ..
mv mupdf/build/release/libmupdf.a . mv mupdf/build/release/libmupdf.a .
mv mupdf/build/release/libmupdf-third.a . mv mupdf/build/release/libmupdf-third.a .
# openjp2
cd openjpeg
#cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O3 -march=native -DNDEBUG"
cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O3"
gmake -j 4
cd ..
mv openjpeg/bin/libopenjp2.a .
# harfbuzz
cd harfbuzz
./autogen.sh
./configure --disable-shared --enable-static
gmake -j 4
cd ..
mv harfbuzz/src/.libs/libharfbuzz.a .
# ffmpeg # ffmpeg
cd ffmpeg cd ffmpeg
./configure --disable-shared --enable-static --disable-ffmpeg --disable-ffplay \ ./configure --disable-shared --enable-static --disable-ffmpeg --disable-ffplay \

View File

@@ -12,7 +12,8 @@ major_mime = {
"audio": 7, "audio": 7,
"image": 8, "image": 8,
"text": 9, "text": 9,
"application": 10 "application": 10,
"x-epoc": 11,
} }
pdf = ( pdf = (
@@ -24,6 +25,7 @@ pdf = (
font = ( font = (
"application/vnd.ms-opentype", "application/vnd.ms-opentype",
"application/x-ms-compress-szdd"
"application/x-font-sfn", "application/x-font-sfn",
"application/x-font-ttf", "application/x-font-ttf",
"font/otf", "font/otf",

View File

@@ -1,8 +1,9 @@
files = [ files = [
"web/css/bundle.css", "web/css/bundle.css",
"web/css/bundle_dark.css",
"web/js/bundle.js", "web/js/bundle.js",
"web/img/bg-bars.png",
"web/img/sprite-skin-flat.png", "web/img/sprite-skin-flat.png",
"web/img/sprite-skin-flat-dark.png",
"web/search.html", "web/search.html",
] ]

View File

@@ -102,7 +102,14 @@ void elastic_flush() {
cJSON *ret_json = cJSON_Parse(r->body); cJSON *ret_json = cJSON_Parse(r->body);
if (cJSON_GetObjectItem(ret_json, "errors")->valueint != 0) { if (cJSON_GetObjectItem(ret_json, "errors")->valueint != 0) {
fprintf(stderr, "%s\n", r->body); cJSON *err;
cJSON_ArrayForEach(err, cJSON_GetObjectItem(ret_json, "items")) {
if (cJSON_GetObjectItem(cJSON_GetObjectItem(err, "index"), "status")->valueint != 201) {
char* str = cJSON_Print(err);
fprintf(stderr, "%s\n", str);
cJSON_free(str);
}
}
} }
cJSON_Delete(ret_json); cJSON_Delete(ret_json);

View File

@@ -66,7 +66,7 @@ index_descriptor_t read_index_descriptor(char *path) {
strcpy(descriptor.root, cJSON_GetObjectItem(json, "root")->valuestring); strcpy(descriptor.root, cJSON_GetObjectItem(json, "root")->valuestring);
strcpy(descriptor.name, cJSON_GetObjectItem(json, "name")->valuestring); strcpy(descriptor.name, cJSON_GetObjectItem(json, "name")->valuestring);
strcpy(descriptor.rewrite_url, cJSON_GetObjectItem(json, "rewrite_url")->valuestring); strcpy(descriptor.rewrite_url, cJSON_GetObjectItem(json, "rewrite_url")->valuestring);
descriptor.root_len = (short)strlen(descriptor.root); descriptor.root_len = (short) strlen(descriptor.root);
strcpy(descriptor.version, cJSON_GetObjectItem(json, "version")->valuestring); strcpy(descriptor.version, cJSON_GetObjectItem(json, "version")->valuestring);
strcpy(descriptor.uuid, cJSON_GetObjectItem(json, "uuid")->valuestring); strcpy(descriptor.uuid, cJSON_GetObjectItem(json, "uuid")->valuestring);
@@ -181,7 +181,7 @@ void read_index(const char *path, const char index_id[UUID_STR_LEN], index_func
uuid_unparse(line.uuid, uuid_str); uuid_unparse(line.uuid, uuid_str);
cJSON_AddStringToObject(document, "mime", mime_get_mime_text(line.mime)); cJSON_AddStringToObject(document, "mime", mime_get_mime_text(line.mime));
cJSON_AddNumberToObject(document, "size", (double)line.size); cJSON_AddNumberToObject(document, "size", (double) line.size);
cJSON_AddNumberToObject(document, "mtime", line.mtime); cJSON_AddNumberToObject(document, "mtime", line.mtime);
int c; int c;
@@ -197,21 +197,30 @@ void read_index(const char *path, const char index_id[UUID_STR_LEN], index_func
*(buf.buf + line.ext) = '\0'; *(buf.buf + line.ext) = '\0';
} }
cJSON_AddStringToObject(document, "name", buf.buf + line.base); cJSON_AddStringToObject(document, "name", buf.buf + line.base);
*(buf.buf + line.base - 1) = '\0'; if (line.base > 0) {
cJSON_AddStringToObject(document, "path", buf.buf); *(buf.buf + line.base - 1) = '\0';
cJSON_AddStringToObject(document, "path", buf.buf);
} else {
cJSON_AddStringToObject(document, "path", "");
}
enum metakey key = getc(file); enum metakey key = getc(file);
while (key != '\n') { while (key != '\n') {
switch (key) { switch (key) {
case MetaWidth: case MetaWidth:
case MetaHeight: case MetaHeight: {
case MetaMediaDuration:
case MetaMediaBitrate: {
int value; int value;
fread(&value, sizeof(int), 1, file); fread(&value, sizeof(int), 1, file);
cJSON_AddNumberToObject(document, get_meta_key_text(key), value); cJSON_AddNumberToObject(document, get_meta_key_text(key), value);
break; break;
} }
case MetaMediaDuration:
case MetaMediaBitrate: {
long value;
fread(&value, sizeof(long), 1, file);
cJSON_AddNumberToObject(document, get_meta_key_text(key), value);
break;
}
case MetaMediaAudioCodec: case MetaMediaAudioCodec:
case MetaMediaVideoCodec: { case MetaMediaVideoCodec: {
int value; int value;
@@ -232,7 +241,7 @@ void read_index(const char *path, const char index_id[UUID_STR_LEN], index_func
case MetaTitle: { case MetaTitle: {
buf.cur = 0; buf.cur = 0;
while ((c = getc(file)) != 0) { while ((c = getc(file)) != 0) {
if (!(SHOULD_IGNORE_CHAR(c)) || c == ' ') { if (SHOULD_KEEP_CHAR(c) || c == ' ') {
dyn_buffer_write_char(&buf, (char) c); dyn_buffer_write_char(&buf, (char) c);
} }
} }
@@ -240,6 +249,9 @@ void read_index(const char *path, const char index_id[UUID_STR_LEN], index_func
cJSON_AddStringToObject(document, get_meta_key_text(key), buf.buf); cJSON_AddStringToObject(document, get_meta_key_text(key), buf.buf);
break; break;
} }
default:
fprintf(stderr, "Invalid meta key (corrupt index): %x\n", key);
break;
} }
key = getc(file); key = getc(file);

View File

@@ -3,14 +3,13 @@
parse_job_t *create_parse_job(const char *filepath, const struct stat *info, int base) { parse_job_t *create_parse_job(const char *filepath, const struct stat *info, int base) {
int len = (int) strlen(filepath); int len = (int) strlen(filepath);
parse_job_t *job = malloc(sizeof(parse_job_t) + len); parse_job_t *job = malloc(sizeof(parse_job_t) + len);
memcpy(&(job->filepath), filepath, len + 1); strcpy(job->filepath, filepath);
job->base = base; job->base = base;
char *p = strrchr(filepath + base, '.'); char *p = strrchr(filepath + base, '.');
if (p != NULL) { if (p != NULL) {
job->ext = (int)(p - filepath + 1); job->ext = (int) (p - filepath + 1);
} else { } else {
job->ext = len; job->ext = len;
} }

View File

@@ -10,7 +10,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 = "1.0.10"; static const char *const Version = "1.1.3";
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",
@@ -52,11 +52,10 @@ void sist2_scan(scan_args_t *args) {
ScanCtx.tn_qscale = args->quality; ScanCtx.tn_qscale = args->quality;
ScanCtx.tn_size = args->size; ScanCtx.tn_size = args->size;
ScanCtx.content_size = args->content_size; ScanCtx.content_size = args->content_size;
ScanCtx.pool = tpool_create(args->threads, serializer_cleanup);
ScanCtx.threads = args->threads; ScanCtx.threads = args->threads;
strncpy(ScanCtx.index.path, args->output, sizeof(ScanCtx.index.path)); strncpy(ScanCtx.index.path, args->output, sizeof(ScanCtx.index.path));
strncpy(ScanCtx.index.desc.name, args->name, sizeof(ScanCtx.index.desc.name)); strncpy(ScanCtx.index.desc.name, args->name, sizeof(ScanCtx.index.desc.name));
strcpy(ScanCtx.index.desc.root, args->path); strncpy(ScanCtx.index.desc.root, args->path, sizeof(ScanCtx.index.desc.root));
ScanCtx.index.desc.root_len = (short) strlen(ScanCtx.index.desc.root); ScanCtx.index.desc.root_len = (short) strlen(ScanCtx.index.desc.root);
init_dir(ScanCtx.index.path); init_dir(ScanCtx.index.path);
@@ -93,6 +92,8 @@ void sist2_scan(scan_args_t *args) {
printf("Loaded %d items in to mtime table.", g_hash_table_size(ScanCtx.original_table)); printf("Loaded %d items in to mtime table.", g_hash_table_size(ScanCtx.original_table));
} }
ScanCtx.pool = tpool_create(args->threads, serializer_cleanup);
tpool_start(ScanCtx.pool);
walk_directory_tree(ScanCtx.index.desc.root); walk_directory_tree(ScanCtx.index.desc.root);
tpool_wait(ScanCtx.pool); tpool_wait(ScanCtx.pool);
tpool_destroy(ScanCtx.pool); tpool_destroy(ScanCtx.pool);

View File

@@ -15,12 +15,12 @@ typedef struct text_dimensions {
} text_dimensions_t; } text_dimensions_t;
typedef struct glyph { typedef struct glyph {
unsigned int top; int top;
unsigned int height; int height;
unsigned int width; int width;
unsigned int descent; int descent;
unsigned int ascent; int ascent;
unsigned int advance_width; int advance_width;
unsigned char *pixmap; unsigned char *pixmap;
} glyph_t; } glyph_t;
@@ -39,10 +39,10 @@ glyph_t ft_glyph_to_glyph(FT_GlyphSlot slot) {
glyph.pixmap = slot->bitmap.buffer; glyph.pixmap = slot->bitmap.buffer;
glyph.width = slot->bitmap.width; glyph.width = (int) slot->bitmap.width;
glyph.height = slot->bitmap.rows; glyph.height = (int) slot->bitmap.rows;
glyph.top = slot->bitmap_top; glyph.top = slot->bitmap_top;
glyph.advance_width = slot->advance.x / 64; glyph.advance_width = (int) slot->advance.x / 64;
glyph.descent = MAX(0, glyph.height - glyph.top); glyph.descent = MAX(0, glyph.height - glyph.top);
glyph.ascent = MAX(0, MAX(glyph.top, glyph.height) - glyph.descent); glyph.ascent = MAX(0, MAX(glyph.top, glyph.height) - glyph.descent);
@@ -50,10 +50,6 @@ glyph_t ft_glyph_to_glyph(FT_GlyphSlot slot) {
return glyph; return glyph;
} }
__always_inline
glyph_t get_glyph(char character, FT_Face face) {
}
text_dimensions_t text_dimension(char *text, FT_Face face) { text_dimensions_t text_dimension(char *text, FT_Face face) {
text_dimensions_t dimensions; text_dimensions_t dimensions;
@@ -62,7 +58,7 @@ text_dimensions_t text_dimension(char *text, FT_Face face) {
int num_chars = (int) strlen(text); int num_chars = (int) strlen(text);
unsigned int max_ascent = 0; unsigned int max_ascent = 0;
unsigned int max_descent = 0; int max_descent = 0;
char pc = 0; char pc = 0;
for (int i = 0; i < num_chars; i++) { for (int i = 0; i < num_chars; i++) {
@@ -72,7 +68,7 @@ text_dimensions_t text_dimension(char *text, FT_Face face) {
glyph_t glyph = ft_glyph_to_glyph(face->glyph); glyph_t glyph = ft_glyph_to_glyph(face->glyph);
max_descent = MAX(max_descent, glyph.descent); max_descent = MAX(max_descent, glyph.descent);
max_ascent = MAX(max_ascent, glyph.ascent); max_ascent = MAX(max_ascent, MAX(glyph.height, glyph.ascent));
int kerning_x = kerning_offset(c, pc, face); int kerning_x = kerning_offset(c, pc, face);
dimensions.width += MAX(glyph.advance_width, glyph.width) + kerning_x; dimensions.width += MAX(glyph.advance_width, glyph.width) + kerning_x;
@@ -146,6 +142,9 @@ void parse_font(const char *buf, size_t buf_len, document_t *doc) {
if (library == NULL) { if (library == NULL) {
FT_Init_FreeType(&library); FT_Init_FreeType(&library);
} }
if (buf == NULL) {
return;
}
FT_Face face; FT_Face face;
FT_Error err = FT_New_Memory_Face(library, (unsigned char *) buf, buf_len, 0, &face); FT_Error err = FT_New_Memory_Face(library, (unsigned char *) buf, buf_len, 0, &face);
@@ -190,11 +189,18 @@ void parse_font(const char *buf, size_t buf_len, document_t *doc) {
err = FT_Load_Char(face, c, FT_LOAD_NO_HINTING | FT_LOAD_RENDER); err = FT_Load_Char(face, c, FT_LOAD_NO_HINTING | FT_LOAD_RENDER);
if (err != 0) { if (err != 0) {
continue; c = c >= 'a' && c <= 'z' ? c - 32 : c + 32;
err = FT_Load_Char(face, c, FT_LOAD_NO_HINTING | FT_LOAD_RENDER);
if (err != 0) {
continue;
}
} }
glyph_t glyph = ft_glyph_to_glyph(face->glyph); glyph_t glyph = ft_glyph_to_glyph(face->glyph);
pen.x += kerning_offset(c, pc, face); pen.x += kerning_offset(c, pc, face);
if (pen.x <= 0) {
pen.x = ABS(glyph.advance_width - glyph.width);
}
pen.y = dimensions.height - glyph.ascent - dimensions.baseline; pen.y = dimensions.height - glyph.ascent - dimensions.baseline;
draw_glyph(&glyph, pen.x, pen.y, dimensions, bitmap); draw_glyph(&glyph, pen.x, pen.y, dimensions, bitmap);

View File

@@ -1,6 +1,9 @@
#include "src/sist.h" #include "src/sist.h"
#include "src/ctx.h" #include "src/ctx.h"
#define MIN_SIZE 32
__always_inline
AVCodecContext *alloc_jpeg_encoder(int dstW, int dstH, float qscale) { AVCodecContext *alloc_jpeg_encoder(int dstW, int dstH, float qscale) {
AVCodec *jpeg_codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG); AVCodec *jpeg_codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
@@ -22,8 +25,8 @@ AVCodecContext *alloc_jpeg_encoder(int dstW, int dstH, float qscale) {
return jpeg; return jpeg;
} }
__always_inline
AVFrame *scale_frame(const AVCodecContext *decoder, const AVFrame *frame, int size) { AVFrame *scale_frame(const AVCodecContext *decoder, const AVFrame *frame, int size) {
AVFrame *scaled_frame = av_frame_alloc();
int dstW; int dstW;
int dstH; int dstH;
@@ -41,16 +44,22 @@ AVFrame *scale_frame(const AVCodecContext *decoder, const AVFrame *frame, int si
} }
} }
if (dstW <= MIN_SIZE || dstH <= MIN_SIZE) {
return NULL;
}
AVFrame *scaled_frame = av_frame_alloc();
struct SwsContext *ctx = sws_getContext( struct SwsContext *ctx = sws_getContext(
decoder->width, decoder->height, decoder->pix_fmt, decoder->width, decoder->height, decoder->pix_fmt,
dstW, dstH, AV_PIX_FMT_YUVJ420P, dstW, dstH, AV_PIX_FMT_YUVJ420P,
SWS_FAST_BILINEAR, 0, 0, 0 SWS_FAST_BILINEAR, 0, 0, 0
); );
int dst_buf_len = avpicture_get_size(AV_PIX_FMT_YUVJ420P, dstW, dstH); int dst_buf_len = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, dstW, dstH, 1);
uint8_t *dst_buf = (uint8_t *) av_malloc(dst_buf_len); uint8_t *dst_buf = (uint8_t *) av_malloc(dst_buf_len);
avpicture_fill((AVPicture *) scaled_frame, dst_buf, AV_PIX_FMT_YUVJ420P, dstW, dstH); av_image_fill_arrays(scaled_frame->data, scaled_frame->linesize, dst_buf, AV_PIX_FMT_YUV420P, dstW, dstH, 1);
sws_scale(ctx, sws_scale(ctx,
(const uint8_t *const *) frame->data, frame->linesize, (const uint8_t *const *) frame->data, frame->linesize,
@@ -81,7 +90,7 @@ AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder, int st
if (read_frame_ret != 0) { if (read_frame_ret != 0) {
if (read_frame_ret != AVERROR_EOF) { if (read_frame_ret != AVERROR_EOF) {
fprintf(stderr, "Error reading frame: %s\n", av_err2str(read_frame_ret)); fprintf(stderr, "Error reading frame: %d\n", read_frame_ret);
} }
av_frame_free(&frame); av_frame_free(&frame);
av_packet_unref(&avPacket); av_packet_unref(&avPacket);
@@ -107,43 +116,74 @@ AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder, int st
return frame; return frame;
} }
#define APPEND_TAG_META(doc, tag_, keyname) \
text_buffer_t tex = text_buffer_create(-1); \
text_buffer_append_string0(&tex, tag_->value); \
meta_line_t *meta_tag = malloc(sizeof(meta_line_t) + tex.dyn_buffer.cur); \
meta_tag->key = keyname; \
strcpy(meta_tag->strval, tex.dyn_buffer.buf); \
APPEND_META(doc, meta_tag) \
text_buffer_destroy(&tex);
__always_inline
void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) { void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) {
AVDictionaryEntry *tag = NULL; AVDictionaryEntry *tag = NULL;
while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
char *key = tag->key; char key[32];
for (; *key; ++key) *key = (char) tolower(*key); strncpy(key, tag->key, sizeof(key));
if (strcmp(tag->key, "artist") == 0) { char *ptr = key;
size_t len = strlen(tag->value); for (; *ptr; ++ptr) *ptr = (char) tolower(*ptr);
meta_line_t *meta_tag = malloc(sizeof(meta_line_t) + len);
meta_tag->key = MetaArtist; if (strcmp(key, "artist") == 0) {
memcpy(meta_tag->strval, tag->value, len); APPEND_TAG_META(doc, tag, MetaArtist)
APPEND_META(doc, meta_tag) } else if (strcmp(key, "genre") == 0) {
} else if (strcmp(tag->key, "genre") == 0) { APPEND_TAG_META(doc, tag, MetaGenre)
size_t len = strlen(tag->value); } else if (strcmp(key, "title") == 0) {
meta_line_t *meta_tag = malloc(sizeof(meta_line_t) + len); APPEND_TAG_META(doc, tag, MetaTitle)
meta_tag->key = MetaGenre; } else if (strcmp(key, "album_artist") == 0) {
memcpy(meta_tag->strval, tag->value, len); APPEND_TAG_META(doc, tag, MetaAlbumArtist)
APPEND_META(doc, meta_tag) } else if (strcmp(key, "album") == 0) {
} else if (strcmp(tag->key, "title") == 0) { APPEND_TAG_META(doc, tag, MetaAlbum)
size_t len = strlen(tag->value); }
meta_line_t *meta_tag = malloc(sizeof(meta_line_t) + len); }
meta_tag->key = MetaTitle; }
memcpy(meta_tag->strval, tag->value, len);
APPEND_META(doc, meta_tag) __always_inline
} else if (strcmp(tag->key, "album_artist") == 0) { void append_video_meta(AVFormatContext *pFormatCtx, AVFrame *frame, document_t *doc, int include_audio_tags, int is_video) {
size_t len = strlen(tag->value);
meta_line_t *meta_tag = malloc(sizeof(meta_line_t) + len); if (is_video) {
meta_tag->key = MetaAlbumArtist; meta_line_t *meta_duration = malloc(sizeof(meta_line_t));
memcpy(meta_tag->strval, tag->value, len); meta_duration->key = MetaMediaDuration;
APPEND_META(doc, meta_tag) meta_duration->longval = pFormatCtx->duration / AV_TIME_BASE;
} else if (strcmp(tag->key, "album") == 0) { APPEND_META(doc, meta_duration)
size_t len = strlen(tag->value);
meta_line_t *meta_tag = malloc(sizeof(meta_line_t) + len); meta_line_t *meta_bitrate = malloc(sizeof(meta_line_t));
meta_tag->key = MetaAlbum; meta_bitrate->key = MetaMediaBitrate;
memcpy(meta_tag->strval, tag->value, len); meta_bitrate->longval = pFormatCtx->bit_rate;
APPEND_META(doc, meta_tag) APPEND_META(doc, meta_bitrate)
}
AVDictionaryEntry *tag = NULL;
if (is_video) {
while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
if (include_audio_tags && strcmp(tag->key, "title") == 0) {
APPEND_TAG_META(doc, tag, MetaTitle)
} else if (strcmp(tag->key, "comment") == 0) {
APPEND_TAG_META(doc, tag, MetaContent)
} else if (include_audio_tags && strcmp(tag->key, "artist") == 0) {
APPEND_TAG_META(doc, tag, MetaArtist)
}
}
} else {
// EXIF metadata
while ((tag = av_dict_get(frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
if (include_audio_tags && strcmp(tag->key, "Artist") == 0) {
APPEND_TAG_META(doc, tag, MetaArtist)
} else if (strcmp(tag->key, "ImageDescription") == 0) {
APPEND_TAG_META(doc, tag, MetaContent)
}
} }
} }
} }
@@ -160,7 +200,7 @@ void parse_media(const char *filepath, document_t *doc) {
} }
int res = avformat_open_input(&pFormatCtx, filepath, NULL, NULL); int res = avformat_open_input(&pFormatCtx, filepath, NULL, NULL);
if (res < 0) { if (res < 0) {
printf("ERR%s %s\n", filepath, av_err2str(res)); fprintf(stderr, "media error: %s %s\n", filepath, av_err2str(res));
return; return;
} }
@@ -205,20 +245,7 @@ void parse_media(const char *filepath, document_t *doc) {
if (video_stream != -1) { if (video_stream != -1) {
AVStream *stream = pFormatCtx->streams[video_stream]; AVStream *stream = pFormatCtx->streams[video_stream];
if (stream->nb_frames > 1) { if (stream->codecpar->width <= MIN_SIZE || stream->codecpar->height <= MIN_SIZE) {
//This is a video (not a still image)
meta_line_t *meta_duration = malloc(sizeof(meta_line_t));
meta_duration->key = MetaMediaDuration;
meta_duration->longval = pFormatCtx->duration / AV_TIME_BASE;
APPEND_META(doc, meta_duration)
meta_line_t *meta_bitrate = malloc(sizeof(meta_line_t));
meta_bitrate->key = MetaMediaBitrate;
meta_bitrate->intval = pFormatCtx->bit_rate;
APPEND_META(doc, meta_bitrate)
}
if (stream->codecpar->width <= 20 || stream->codecpar->height <= 20) {
avformat_close_input(&pFormatCtx); avformat_close_input(&pFormatCtx);
avformat_free_context(pFormatCtx); avformat_free_context(pFormatCtx);
return; return;
@@ -250,9 +277,19 @@ void parse_media(const char *filepath, document_t *doc) {
return; return;
} }
append_video_meta(pFormatCtx, frame, doc, audio_stream == -1, stream->nb_frames > 1);
// Scale frame // Scale frame
AVFrame *scaled_frame = scale_frame(decoder, frame, ScanCtx.tn_size); AVFrame *scaled_frame = scale_frame(decoder, frame, ScanCtx.tn_size);
if (scaled_frame == NULL) {
av_frame_free(&frame);
avcodec_free_context(&decoder);
avformat_close_input(&pFormatCtx);
avformat_free_context(pFormatCtx);
return;
}
// Encode frame to jpeg // Encode frame to jpeg
AVCodecContext *jpeg_encoder = alloc_jpeg_encoder(scaled_frame->width, scaled_frame->height, ScanCtx.tn_qscale); AVCodecContext *jpeg_encoder = alloc_jpeg_encoder(scaled_frame->width, scaled_frame->height, ScanCtx.tn_qscale);
avcodec_send_frame(jpeg_encoder, scaled_frame); avcodec_send_frame(jpeg_encoder, scaled_frame);
@@ -262,7 +299,8 @@ void parse_media(const char *filepath, document_t *doc) {
avcodec_receive_packet(jpeg_encoder, &jpeg_packet); avcodec_receive_packet(jpeg_encoder, &jpeg_packet);
// Save thumbnail // Save thumbnail
store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) jpeg_packet.data, jpeg_packet.size); store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) jpeg_packet.data,
jpeg_packet.size);
av_packet_unref(&jpeg_packet); av_packet_unref(&jpeg_packet);
av_frame_free(&frame); av_frame_free(&frame);

View File

@@ -5,6 +5,7 @@
#include "src/sist.h" #include "src/sist.h"
#define MIN_VIDEO_SIZE 1024 * 64 #define MIN_VIDEO_SIZE 1024 * 64
#define MIN_IMAGE_SIZE 1024 * 2
void parse_media(const char * filepath, document_t *doc); void parse_media(const char * filepath, document_t *doc);

View File

@@ -1,10 +1,12 @@
#include "mime.h" #include "mime.h"
unsigned int mime_get_mime_by_ext(GHashTable *ext_table, const char * ext) { unsigned int mime_get_mime_by_ext(GHashTable *ext_table, const char * ext) {
char lower[64]; char lower[8];
char *p = lower; char *p = lower;
while ((*ext)) { int cnt = 0;
while ((*ext) != '\0' && cnt + 1 < sizeof(lower)) {
*p++ = (char)tolower(*ext++); *p++ = (char)tolower(*ext++);
cnt++;
} }
*p = '\0'; *p = '\0';
return (size_t) g_hash_table_lookup(ext_table, lower); return (size_t) g_hash_table_lookup(ext_table, lower);

View File

@@ -39,333 +39,385 @@ enum mime {
application_oda=655391, application_oda=655391,
application_ogg=655392, application_ogg=655392,
application_pdf=655393 | 0x40000000, application_pdf=655393 | 0x40000000,
application_pgp_signature=655394, application_pgp_keys=655394,
application_pkcs7_signature=655395, application_pgp_signature=655395,
application_pkix_cert=655396, application_pkcs7_signature=655396,
application_postscript=655397, application_pkix_cert=655397,
application_pro_eng=655398, application_postscript=655398,
application_ringing_tones=655399, application_pro_eng=655399,
application_smil=655400, application_ringing_tones=655400,
application_solids=655401, application_smil=655401,
application_sounder=655402, application_solids=655402,
application_step=655403, application_sounder=655403,
application_streamingmedia=655404, application_step=655404,
application_vda=655405, application_streamingmedia=655405,
application_vnd_fdf=655406, application_vda=655406,
application_vnd_font_fontforge_sfd=655407, application_vnd_fdf=655407,
application_vnd_hp_hpgl=655408, application_vnd_font_fontforge_sfd=655408,
application_vnd_iccprofile=655409, application_vnd_hp_hpgl=655409,
application_vnd_ms_cab_compressed=655410, application_vnd_iccprofile=655410,
application_vnd_ms_excel=655411, application_vnd_lotus_1_2_3=655411,
application_vnd_ms_fontobject=655412, application_vnd_ms_cab_compressed=655412,
application_vnd_ms_opentype=655413 | 0x20000000, application_vnd_ms_excel=655413,
application_vnd_ms_pki_certstore=655414, application_vnd_ms_fontobject=655414,
application_vnd_ms_pki_pko=655415, application_vnd_ms_opentype=655415 | 0x20000000,
application_vnd_ms_pki_seccat=655416, application_vnd_ms_pki_certstore=655416,
application_vnd_ms_powerpoint=655417, application_vnd_ms_pki_pko=655417,
application_vnd_ms_project=655418, application_vnd_ms_pki_seccat=655418,
application_vnd_oasis_opendocument_base=655419, application_vnd_ms_powerpoint=655419,
application_vnd_oasis_opendocument_formula=655420, application_vnd_ms_project=655420,
application_vnd_oasis_opendocument_graphics=655421, application_vnd_oasis_opendocument_base=655421,
application_vnd_oasis_opendocument_text=655422, application_vnd_oasis_opendocument_formula=655422,
application_vnd_openxmlformats_officedocument_spreadsheetml_sheet=655423, application_vnd_oasis_opendocument_graphics=655423,
application_vnd_openxmlformats_officedocument_wordprocessingml_document=655424, application_vnd_oasis_opendocument_presentation=655424,
application_vnd_wap_wmlc=655425, application_vnd_oasis_opendocument_spreadsheet=655425,
application_vnd_wap_wmlscriptc=655426, application_vnd_oasis_opendocument_text=655426,
application_vnd_xara=655427, application_vnd_openxmlformats_officedocument_presentationml_presentation=655427,
application_vocaltec_media_desc=655428, application_vnd_openxmlformats_officedocument_spreadsheetml_sheet=655428,
application_vocaltec_media_file=655429, application_vnd_openxmlformats_officedocument_wordprocessingml_document=655429,
application_winhelp=655430, application_vnd_symbian_install=655430,
application_wordperfect=655431, application_vnd_tcpdump_pcap=655431,
application_wordperfect6_0=655432, application_vnd_wap_wmlc=655432,
application_wordperfect6_1=655433, application_vnd_wap_wmlscriptc=655433,
application_x_123=655434, application_vnd_xara=655434,
application_x_7z_compressed=655435, application_vocaltec_media_desc=655435,
application_x_aim=655436, application_vocaltec_media_file=655436,
application_x_archive=655437, application_winhelp=655437,
application_x_authorware_bin=655438, application_wordperfect=655438,
application_x_authorware_map=655439, application_wordperfect6_0=655439,
application_x_authorware_seg=655440, application_wordperfect6_1=655440,
application_x_bcpio=655441, application_x_123=655441,
application_x_bittorrent=655442, application_x_7z_compressed=655442,
application_x_bsh=655443, application_x_aim=655443,
application_x_bytecode_python=655444, application_x_apple_diskimage=655444,
application_x_bzip=655445, application_x_arc=655445,
application_x_bzip2=655446, application_x_archive=655446,
application_x_cbr=655447, application_x_atari_7800_rom=655447,
application_x_cbz=655448 | 0x40000000, application_x_authorware_bin=655448,
application_x_cdlink=655449, application_x_authorware_map=655449,
application_x_chat=655450, application_x_authorware_seg=655450,
application_x_cocoa=655451, application_x_avira_qua=655451,
application_x_conference=655452, application_x_bcpio=655452,
application_x_cpio=655453, application_x_bittorrent=655453,
application_x_dbf=655454, application_x_bsh=655454,
application_x_dbt=655455, application_x_bytecode_python=655455,
application_x_debian_package=655456, application_x_bzip=655456,
application_x_deepv=655457, application_x_bzip2=655457,
application_x_director=655458, application_x_cbr=655458,
application_x_dosexec=655459, application_x_cbz=655459 | 0x40000000,
application_x_dvi=655460, application_x_cdlink=655460,
application_x_elc=655461, application_x_chat=655461,
application_x_chrome_extension=655462,
application_x_cocoa=655463,
application_x_conference=655464,
application_x_coredump=655465,
application_x_cpio=655466,
application_x_dbf=655467,
application_x_dbt=655468,
application_x_debian_package=655469,
application_x_deepv=655470,
application_x_director=655471,
application_x_dmp=655472,
application_x_dosdriver=655473,
application_x_dosexec=655474,
application_x_dvi=655475,
application_x_elc=655476,
application_x_empty=1, application_x_empty=1,
application_x_envoy=655463, application_x_envoy=655478,
application_x_esrehber=655464, application_x_esrehber=655479,
application_x_excel=655465, application_x_excel=655480,
application_x_executable=655466, application_x_executable=655481,
application_x_font_sfn=655467 | 0x20000000, application_x_font_gdos=655482,
application_x_font_ttf=655468 | 0x20000000, application_x_font_pf2=655483,
application_x_freelance=655469, application_x_font_pfm=655484,
application_x_git=655470, application_x_font_sfn=655485,
application_x_gsp=655471, application_x_font_ttf=655486 | 0x20000000,
application_x_gss=655472, application_x_freelance=655487,
application_x_gtar=655473, application_x_gamecube_rom=655488,
application_x_gzip=655474, application_x_gdbm=655489,
application_x_hdf=655475, application_x_gettext_translation=655490,
application_x_helpfile=655476, application_x_git=655491,
application_x_httpd_imap=655477, application_x_gsp=655492,
application_x_ima=655478, application_x_gss=655493,
application_x_innosetup=655479, application_x_gtar=655494,
application_x_internett_signup=655480, application_x_gzip=655495,
application_x_inventor=655481, application_x_hdf=655496,
application_x_ip2=655482, application_x_helpfile=655497,
application_x_java_applet=655483, application_x_httpd_imap=655498,
application_x_java_commerce=655484, application_x_ima=655499,
application_x_java_image=655485, application_x_innosetup=655500,
application_x_java_keystore=655486, application_x_internett_signup=655501,
application_x_kdelnk=655487, application_x_inventor=655502,
application_x_koan=655488, application_x_ip2=655503,
application_x_latex=655489, application_x_java_applet=655504,
application_x_livescreen=655490, application_x_java_commerce=655505,
application_x_lotus=655491, application_x_java_image=655506,
application_x_lzh=655492, application_x_java_jmod=655507,
application_x_lzx=655493, application_x_java_keystore=655508,
application_x_mach_binary=655494, application_x_kdelnk=655509,
application_x_mach_executable=655495, application_x_koan=655510,
application_x_magic_cap_package_1_0=655496, application_x_latex=655511,
application_x_mathcad=655497, application_x_livescreen=655512,
application_x_meme=655498, application_x_lotus=655513,
application_x_midi=655499, application_x_lz4=655514,
application_x_mif=655500, application_x_lz4_json=655515,
application_x_mix_transfer=655501, application_x_lzh=655516,
application_x_mobipocket_ebook=655502, application_x_lzh_compressed=655517,
application_x_ms_pdb=655503, application_x_lzx=655518,
application_x_ms_reader=655504, application_x_mach_binary=655519,
application_x_navi_animation=655505, application_x_mach_executable=655520,
application_x_navidoc=655506, application_x_magic_cap_package_1_0=655521,
application_x_navimap=655507, application_x_mathcad=655522,
application_x_navistyle=655508, application_x_maxis_dbpf=655523,
application_x_netcdf=655509, application_x_meme=655524,
application_x_newton_compatible_pkg=655510, application_x_midi=655525,
application_x_object=655511, application_x_mif=655526,
application_x_omc=655512, application_x_mix_transfer=655527,
application_x_omcdatamaker=655513, application_x_mobipocket_ebook=655528,
application_x_omcregerator=655514, application_x_ms_compress_szdd=655529,
application_x_pagemaker=655515, application_x_ms_pdb=655530,
application_x_pcl=655516, application_x_ms_reader=655531,
application_x_pixclscript=655517, application_x_msaccess=655532,
application_x_pkcs7_certreqresp=655518, application_x_navi_animation=655533,
application_x_pkcs7_signature=655519, application_x_navidoc=655534,
application_x_project=655520, application_x_navimap=655535,
application_x_qpro=655521, application_x_navistyle=655536,
application_x_rar=655522, application_x_nes_rom=655537,
application_x_rpm=655523, application_x_netcdf=655538,
application_x_sdp=655524, application_x_newton_compatible_pkg=655539,
application_x_sea=655525, application_x_nintendo_ds_rom=655540,
application_x_seelogo=655526, application_x_object=655541,
application_x_setupscript=655527, application_x_omc=655542,
application_x_shar=655528, application_x_omcdatamaker=655543,
application_x_sharedlib=655529, application_x_omcregerator=655544,
application_x_shockwave_flash=655530, application_x_pagemaker=655545,
application_x_sprite=655531, application_x_pcl=655546,
application_x_sqlite3=655532, application_x_pgp_keyring=655547,
application_x_sv4cpio=655533, application_x_pixclscript=655548,
application_x_sv4crc=655534, application_x_pkcs7_certreqresp=655549,
application_x_tar=655535, application_x_pkcs7_signature=655550,
application_x_tbook=655536, application_x_project=655551,
application_x_tex_tfm=655537, application_x_qpro=655552,
application_x_texinfo=655538, application_x_rar=655553,
application_x_ustar=655539, application_x_rpm=655554,
application_x_visio=655540, application_x_sdp=655555,
application_x_vnd_audioexplosion_mzz=655541, application_x_sea=655556,
application_x_vnd_ls_xpix=655542, application_x_seelogo=655557,
application_x_vrml=655543, application_x_setupscript=655558,
application_x_wais_source=655544, application_x_shar=655559,
application_x_wine_extension_ini=655545, application_x_sharedlib=655560,
application_x_wintalk=655546, application_x_shockwave_flash=655561,
application_x_world=655547, application_x_snappy_framed=655562,
application_x_wri=655548, application_x_sprite=655563,
application_x_x509_ca_cert=655549, application_x_sqlite3=655564,
application_x_xz=655550, application_x_sv4cpio=655565,
application_xml=655551, application_x_sv4crc=655566,
application_zip=655552, application_x_tar=655567,
audio_it=458945, application_x_tbook=655568,
audio_make=458946, application_x_terminfo=655569,
audio_mid=458947, application_x_terminfo2=655570,
audio_midi=458948, application_x_tex_tfm=655571,
audio_mp4=458949, application_x_texinfo=655572,
audio_mpeg=458950, application_x_ustar=655573,
audio_ogg=458951, application_x_visio=655574,
audio_s3m=458952, application_x_vnd_audioexplosion_mzz=655575,
audio_tsp_audio=458953, application_x_vnd_ls_xpix=655576,
audio_tsplayer=458954, application_x_vrml=655577,
audio_vnd_qcelp=458955, application_x_wais_source=655578,
audio_voxware=458956, application_x_wine_extension_ini=655579,
audio_x_flac=458957, application_x_wintalk=655580,
audio_x_gsm=458958, application_x_world=655581,
audio_x_jam=458959, application_x_wri=655582,
audio_x_liveaudio=458960, application_x_x509_ca_cert=655583,
audio_x_m4a=458961, application_x_xz=655584,
audio_x_midi=458962, application_x_zip=655585,
audio_x_mod=458963, application_x_zstd=655586,
audio_x_mp4a_latm=458964, application_xml=655587,
audio_x_mpeg_3=458965, application_zip=655588,
audio_x_mpequrl=458966, application_zlib=655589,
audio_x_nspaudio=458967, audio_it=458982,
audio_x_pn_realaudio=458968, audio_make=458983,
audio_x_psid=458969, audio_mid=458984,
audio_x_realaudio=458970, audio_midi=458985,
audio_x_twinvq=458971, audio_mp4=458986,
audio_x_twinvq_plugin=458972, audio_mpeg=458987,
audio_x_voc=458973, audio_ogg=458988,
audio_x_wav=458974, audio_s3m=458989,
audio_xm=458975, audio_tsp_audio=458990,
font_otf=327904 | 0x20000000, audio_tsplayer=458991,
font_sfnt=327905 | 0x20000000, audio_vnd_qcelp=458992,
font_woff=327906 | 0x20000000, audio_voxware=458993,
font_woff2=327907 | 0x20000000, audio_x_aiff=458994,
image_cmu_raster=524516, audio_x_flac=458995,
image_fif=524517, audio_x_gsm=458996,
image_florian=524518, audio_x_hx_aac_adts=458997,
image_g3fax=524519, audio_x_jam=458998,
image_gif=524520, audio_x_liveaudio=458999,
image_ief=524521, audio_x_m4a=459000,
image_jpeg=524522, audio_x_midi=459001,
image_jutvision=524523, audio_x_mod=459002,
image_naplps=524524, audio_x_mp4a_latm=459003,
image_pict=524525, audio_x_mpeg_3=459004,
image_png=524526, audio_x_mpequrl=459005,
image_svg=524527 | 0x80000000, audio_x_nspaudio=459006,
image_svg_xml=524528 | 0x80000000, audio_x_pn_realaudio=459007,
image_tiff=524529, audio_x_psid=459008,
image_vnd_adobe_photoshop=524530 | 0x80000000, audio_x_realaudio=459009,
image_vnd_djvu=524531 | 0x80000000, audio_x_twinvq=459010,
image_vnd_fpx=524532, audio_x_twinvq_plugin=459011,
image_vnd_microsoft_icon=524533, audio_x_voc=459012,
image_vnd_rn_realflash=524534, audio_x_wav=459013,
image_vnd_rn_realpix=524535, audio_xm=459014,
image_vnd_wap_wbmp=524536, font_otf=327943 | 0x20000000,
image_vnd_xiff=524537, font_sfnt=327944 | 0x20000000,
image_webp=524538, font_woff=327945 | 0x20000000,
image_x_cmu_raster=524539, font_woff2=327946 | 0x20000000,
image_x_cur=524540, image_cmu_raster=524555,
image_x_dwg=524541, image_fif=524556,
image_x_eps=524542, image_florian=524557,
image_x_exr=524543, image_g3fax=524558,
image_x_icns=524544, image_gif=524559,
image_x_icon=524545 | 0x80000000, image_heic=524560,
image_x_jg=524546, image_ief=524561,
image_x_jps=524547, image_jpeg=524562,
image_x_ms_bmp=524548, image_jutvision=524563,
image_x_niff=524549, image_naplps=524564,
image_x_pcx=524550, image_pict=524565,
image_x_pict=524551, image_png=524566,
image_x_portable_bitmap=524552, image_svg=524567 | 0x80000000,
image_x_portable_graymap=524553, image_svg_xml=524568 | 0x80000000,
image_x_portable_pixmap=524554, image_tiff=524569,
image_x_quicktime=524555, image_vnd_adobe_photoshop=524570 | 0x80000000,
image_x_rgb=524556, image_vnd_djvu=524571 | 0x80000000,
image_x_tga=524557, image_vnd_fpx=524572,
image_x_tiff=524558, image_vnd_microsoft_icon=524573,
image_x_xcf=524559 | 0x80000000, image_vnd_rn_realflash=524574,
image_x_xpixmap=524560 | 0x80000000, image_vnd_rn_realpix=524575,
image_x_xwindowdump=524561, image_vnd_wap_wbmp=524576,
message_rfc822=196882, image_vnd_xiff=524577,
model_vnd_dwf=65811, image_webp=524578,
model_vnd_gdl=65812, image_wmf=524579,
model_vnd_gs_gdl=65813, image_x_3ds=524580,
model_vrml=65814, image_x_cmu_raster=524581,
model_x_pov=65815, image_x_cur=524582,
text_asp=590104, image_x_dwg=524583,
text_css=590105, image_x_eps=524584,
text_html=590106, image_x_exr=524585,
text_javascript=590107, image_x_gem=524586,
text_mcf=590108, image_x_icns=524587,
text_pascal=590109, image_x_icon=524588 | 0x80000000,
text_plain=590110, image_x_jg=524589,
text_richtext=590111, image_x_jps=524590,
text_scriplet=590112, image_x_ms_bmp=524591,
text_tab_separated_values=590113, image_x_niff=524592,
text_troff=590114, image_x_pcx=524593,
text_uri_list=590115, image_x_pict=524594,
text_vnd_abc=590116, image_x_portable_bitmap=524595,
text_vnd_fmi_flexstor=590117, image_x_portable_graymap=524596,
text_vnd_wap_wml=590118, image_x_portable_pixmap=524597,
text_vnd_wap_wmlscript=590119, image_x_quicktime=524598,
text_webviewhtml=590120, image_x_rgb=524599,
text_x_Algol68=590121, image_x_tga=524600,
text_x_asm=590122, image_x_tiff=524601,
text_x_audiosoft_intra=590123, image_x_win_bitmap=524602,
text_x_awk=590124, image_x_xcf=524603 | 0x80000000,
text_x_bcpl=590125, image_x_xpixmap=524604 | 0x80000000,
text_x_c=590126, image_x_xwindowdump=524605,
text_x_c__=590127, message_news=196926,
text_x_component=590128, message_rfc822=196927,
text_x_diff=590129, model_vnd_dwf=65856,
text_x_fortran=590130, model_vnd_gdl=65857,
text_x_java=590131, model_vnd_gs_gdl=65858,
text_x_la_asf=590132, model_vrml=65859,
text_x_lisp=590133, model_x_pov=65860,
text_x_m=590134, text_PGP=590149,
text_x_m4=590135, text_asp=590150,
text_x_makefile=590136, text_css=590151,
text_x_msdos_batch=590137, text_html=590152,
text_x_pascal=590138, text_javascript=590153,
text_x_perl=590139, text_mcf=590154,
text_x_php=590140, text_pascal=590155,
text_x_po=590141, text_plain=590156,
text_x_python=590142, text_richtext=590157,
text_x_ruby=590143, text_rtf=590158,
text_x_sass=590144, text_scriplet=590159,
text_x_scss=590145, text_tab_separated_values=590160,
text_x_server_parsed_html=590146, text_troff=590161,
text_x_setext=590147, text_uri_list=590162,
text_x_sgml=590148, text_vnd_abc=590163,
text_x_shellscript=590149, text_vnd_fmi_flexstor=590164,
text_x_speech=590150, text_vnd_wap_wml=590165,
text_x_tcl=590151, text_vnd_wap_wmlscript=590166,
text_x_tex=590152, text_webviewhtml=590167,
text_x_uil=590153, text_x_Algol68=590168,
text_x_uuencode=590154, text_x_asm=590169,
text_x_vcalendar=590155, text_x_audiosoft_intra=590170,
text_x_vcard=590156, text_x_awk=590171,
text_xml=590157, text_x_bcpl=590172,
video_animaflex=393550, text_x_c=590173,
video_avi=393551, text_x_c__=590174,
video_avs_video=393552, text_x_component=590175,
video_mp4=393553, text_x_diff=590176,
video_mpeg=393554, text_x_fortran=590177,
video_quicktime=393555, text_x_java=590178,
video_vdo=393556, text_x_la_asf=590179,
video_vivo=393557, text_x_lisp=590180,
video_vnd_rn_realvideo=393558, text_x_m=590181,
video_vosaic=393559, text_x_m4=590182,
video_webm=393560, text_x_makefile=590183,
video_x_amt_demorun=393561, text_x_ms_regedit=590184,
video_x_amt_showrun=393562, text_x_msdos_batch=590185,
video_x_atomic3d_feature=393563, text_x_objective_c=590186,
video_x_dl=393564, text_x_pascal=590187,
video_x_dv=393565, text_x_perl=590188,
video_x_fli=393566, text_x_php=590189,
video_x_flv=393567, text_x_po=590190,
video_x_isvideo=393568, text_x_python=590191,
video_x_jng=393569 | 0x80000000, text_x_ruby=590192,
video_x_matroska=393570, text_x_sass=590193,
video_x_mng=393571, text_x_scss=590194,
video_x_motion_jpeg=393572, text_x_server_parsed_html=590195,
video_x_ms_asf=393573, text_x_setext=590196,
video_x_msvideo=393574, text_x_sgml=590197,
video_x_qtc=393575, text_x_shellscript=590198,
video_x_sgi_movie=393576, text_x_speech=590199,
text_x_tcl=590200,
text_x_tex=590201,
text_x_uil=590202,
text_x_uuencode=590203,
text_x_vcalendar=590204,
text_x_vcard=590205,
text_xml=590206,
video_MP2T=393599,
video_animaflex=393600,
video_avi=393601,
video_avs_video=393602,
video_mp4=393603,
video_mpeg=393604,
video_quicktime=393605,
video_vdo=393606,
video_vivo=393607,
video_vnd_rn_realvideo=393608,
video_vosaic=393609,
video_webm=393610,
video_x_amt_demorun=393611,
video_x_amt_showrun=393612,
video_x_atomic3d_feature=393613,
video_x_dl=393614,
video_x_dv=393615,
video_x_fli=393616,
video_x_flv=393617,
video_x_isvideo=393618,
video_x_jng=393619 | 0x80000000,
video_x_m4v=393620,
video_x_matroska=393621,
video_x_mng=393622,
video_x_motion_jpeg=393623,
video_x_ms_asf=393624,
video_x_msvideo=393625,
video_x_qtc=393626,
video_x_sgi_movie=393627,
x_epoc_x_sisx_app=721308,
}; };
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";
@@ -624,6 +676,7 @@ case text_mcf: return "text/mcf";
case text_pascal: return "text/pascal"; case text_pascal: return "text/pascal";
case text_plain: return "text/plain"; case text_plain: return "text/plain";
case text_richtext: return "text/richtext"; case text_richtext: return "text/richtext";
case text_rtf: return "text/rtf";
case text_scriplet: return "text/scriplet"; case text_scriplet: return "text/scriplet";
case text_x_awk: return "text/x-awk"; case text_x_awk: return "text/x-awk";
case video_x_jng: return "video/x-jng"; case video_x_jng: return "video/x-jng";
@@ -728,6 +781,57 @@ case image_x_tga: return "image/x-tga";
case application_x_wine_extension_ini: return "application/x-wine-extension-ini"; case application_x_wine_extension_ini: return "application/x-wine-extension-ini";
case application_x_cbz: return "application/x-cbz"; case application_x_cbz: return "application/x-cbz";
case application_x_cbr: return "application/x-cbr"; case application_x_cbr: return "application/x-cbr";
case application_x_ms_compress_szdd: return "application/x-ms-compress-szdd";
case application_x_atari_7800_rom: return "application/x-atari-7800-rom";
case application_x_nes_rom: return "application/x-nes-rom";
case application_x_font_pfm: return "application/x-font-pfm";
case application_x_gettext_translation: return "application/x-gettext-translation";
case image_wmf: return "image/wmf";
case application_pgp_keys: return "application/pgp-keys";
case image_x_3ds: return "image/x-3ds";
case application_x_lz4: return "application/x-lz4";
case application_vnd_openxmlformats_officedocument_presentationml_presentation: return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
case application_vnd_oasis_opendocument_presentation: return "application/vnd.oasis.opendocument.presentation";
case application_x_msaccess: return "application/x-msaccess";
case application_vnd_oasis_opendocument_spreadsheet: return "application/vnd.oasis.opendocument.spreadsheet";
case audio_x_aiff: return "audio/x-aiff";
case text_x_ms_regedit: return "text/x-ms-regedit";
case application_x_gamecube_rom: return "application/x-gamecube-rom";
case application_x_nintendo_ds_rom: return "application/x-nintendo-ds-rom";
case text_x_objective_c: return "text/x-objective-c";
case application_x_font_gdos: return "application/x-font-gdos";
case application_x_apple_diskimage: return "application/x-apple-diskimage";
case application_x_zstd: return "application/x-zstd";
case video_x_m4v: return "video/x-m4v";
case message_news: return "message/news";
case application_vnd_symbian_install: return "application/vnd.symbian.install";
case application_x_lzh_compressed: return "application/x-lzh-compressed";
case application_x_dosdriver: return "application/x-dosdriver";
case application_vnd_tcpdump_pcap: return "application/vnd.tcpdump.pcap";
case x_epoc_x_sisx_app: return "x-epoc/x-sisx-app";
case application_x_avira_qua: return "application/x-avira-qua";
case video_MP2T: return "video/MP2T";
case application_x_snappy_framed: return "application/x-snappy-framed";
case application_x_lz4_json: return "application/x-lz4+json";
case application_x_dmp: return "application/x-dmp";
case application_zlib: return "application/zlib";
case application_x_pgp_keyring: return "application/x-pgp-keyring";
case application_x_gdbm: return "application/x-gdbm";
case application_x_font_pf2: return "application/x-font-pf2";
case application_x_zip: return "application/x-zip";
case application_x_coredump: return "application/x-coredump";
case application_x_java_jmod: return "application/x-java-jmod";
case application_x_terminfo: return "application/x-terminfo";
case application_x_terminfo2: return "application/x-terminfo2";
case application_x_arc: return "application/x-arc";
case application_vnd_lotus_1_2_3: return "application/vnd.lotus-1-2-3";
case image_x_win_bitmap: return "image/x-win-bitmap";
case application_x_maxis_dbpf: return "application/x-maxis-dbpf";
case text_PGP: return "text/PGP";
case audio_x_hx_aac_adts: return "audio/x-hx-aac-adts";
case application_x_chrome_extension: return "application/x-chrome-extension";
case image_heic: return "image/heic";
case image_x_gem: return "image/x-gem";
default: return NULL;}} default: return NULL;}}
GHashTable *mime_get_ext_table() {GHashTable *ext_table = g_hash_table_new(g_str_hash, g_str_equal); GHashTable *mime_get_ext_table() {GHashTable *ext_table = g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_insert(ext_table, "arj", (gpointer)application_arj); g_hash_table_insert(ext_table, "arj", (gpointer)application_arj);
@@ -857,6 +961,7 @@ g_hash_table_insert(ext_table, "xlt", (gpointer)application_x_excel);
g_hash_table_insert(ext_table, "xlv", (gpointer)application_x_excel); g_hash_table_insert(ext_table, "xlv", (gpointer)application_x_excel);
g_hash_table_insert(ext_table, "exe", (gpointer)application_x_executable); g_hash_table_insert(ext_table, "exe", (gpointer)application_x_executable);
g_hash_table_insert(ext_table, "ttf", (gpointer)application_x_font_ttf); g_hash_table_insert(ext_table, "ttf", (gpointer)application_x_font_ttf);
g_hash_table_insert(ext_table, "ttc", (gpointer)application_x_font_ttf);
g_hash_table_insert(ext_table, "pre", (gpointer)application_x_freelance); g_hash_table_insert(ext_table, "pre", (gpointer)application_x_freelance);
g_hash_table_insert(ext_table, "gsp", (gpointer)application_x_gsp); g_hash_table_insert(ext_table, "gsp", (gpointer)application_x_gsp);
g_hash_table_insert(ext_table, "gss", (gpointer)application_x_gss); g_hash_table_insert(ext_table, "gss", (gpointer)application_x_gss);
@@ -1094,7 +1199,7 @@ g_hash_table_insert(ext_table, "ms", (gpointer)text_troff);
g_hash_table_insert(ext_table, "roff", (gpointer)text_troff); g_hash_table_insert(ext_table, "roff", (gpointer)text_troff);
g_hash_table_insert(ext_table, "t", (gpointer)text_troff); g_hash_table_insert(ext_table, "t", (gpointer)text_troff);
g_hash_table_insert(ext_table, "tr", (gpointer)text_troff); g_hash_table_insert(ext_table, "tr", (gpointer)text_troff);
g_hash_table_insert(ext_table, "uni", (gpointer)text_uri_list); g_hash_table_insert(ext_table, "uji", (gpointer)text_uri_list);
g_hash_table_insert(ext_table, "unis", (gpointer)text_uri_list); g_hash_table_insert(ext_table, "unis", (gpointer)text_uri_list);
g_hash_table_insert(ext_table, "uri", (gpointer)text_uri_list); g_hash_table_insert(ext_table, "uri", (gpointer)text_uri_list);
g_hash_table_insert(ext_table, "uris", (gpointer)text_uri_list); g_hash_table_insert(ext_table, "uris", (gpointer)text_uri_list);
@@ -1207,6 +1312,28 @@ g_hash_table_insert(ext_table, "vcf", (gpointer)text_x_vcard);
g_hash_table_insert(ext_table, "hlp", (gpointer)application_winhelp); g_hash_table_insert(ext_table, "hlp", (gpointer)application_winhelp);
g_hash_table_insert(ext_table, "cbz", (gpointer)application_x_cbz); g_hash_table_insert(ext_table, "cbz", (gpointer)application_x_cbz);
g_hash_table_insert(ext_table, "cbr", (gpointer)application_x_cbr); g_hash_table_insert(ext_table, "cbr", (gpointer)application_x_cbr);
g_hash_table_insert(ext_table, "fon", (gpointer)application_x_ms_compress_szdd);
g_hash_table_insert(ext_table, "a78", (gpointer)application_x_atari_7800_rom);
g_hash_table_insert(ext_table, "nes", (gpointer)application_x_nes_rom);
g_hash_table_insert(ext_table, "pfm", (gpointer)application_x_font_pfm);
g_hash_table_insert(ext_table, "3ds", (gpointer)image_x_3ds);
g_hash_table_insert(ext_table, "lz4", (gpointer)application_x_lz4);
g_hash_table_insert(ext_table, "pptx", (gpointer)application_vnd_openxmlformats_officedocument_presentationml_presentation);
g_hash_table_insert(ext_table, "odp", (gpointer)application_vnd_oasis_opendocument_presentation);
g_hash_table_insert(ext_table, "accdb", (gpointer)application_x_msaccess);
g_hash_table_insert(ext_table, "ods", (gpointer)application_vnd_oasis_opendocument_spreadsheet);
g_hash_table_insert(ext_table, "aiff", (gpointer)audio_x_aiff);
g_hash_table_insert(ext_table, "aif", (gpointer)audio_x_aiff);
g_hash_table_insert(ext_table, "reg", (gpointer)text_x_ms_regedit);
g_hash_table_insert(ext_table, "zst", (gpointer)application_x_zstd);
g_hash_table_insert(ext_table, "m4v", (gpointer)video_x_m4v);
g_hash_table_insert(ext_table, "pcap", (gpointer)application_vnd_tcpdump_pcap);
g_hash_table_insert(ext_table, "jsonlz4", (gpointer)application_x_lz4_json);
g_hash_table_insert(ext_table, "dmp", (gpointer)application_x_dmp);
g_hash_table_insert(ext_table, "z", (gpointer)application_zlib);
g_hash_table_insert(ext_table, "pf2", (gpointer)application_x_font_pf2);
g_hash_table_insert(ext_table, "jmod", (gpointer)application_x_java_jmod);
g_hash_table_insert(ext_table, "heic", (gpointer)image_heic);
return ext_table;} return ext_table;}
GHashTable *mime_get_mime_table() {GHashTable *mime_table = g_hash_table_new(g_str_hash, g_str_equal); GHashTable *mime_get_mime_table() {GHashTable *mime_table = g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_insert(mime_table, "application/arj", (gpointer)application_arj); g_hash_table_insert(mime_table, "application/arj", (gpointer)application_arj);
@@ -1465,6 +1592,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/plain", (gpointer)text_plain); g_hash_table_insert(mime_table, "text/plain", (gpointer)text_plain);
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/scriplet", (gpointer)text_scriplet); g_hash_table_insert(mime_table, "text/scriplet", (gpointer)text_scriplet);
g_hash_table_insert(mime_table, "text/x-awk", (gpointer)text_x_awk); g_hash_table_insert(mime_table, "text/x-awk", (gpointer)text_x_awk);
g_hash_table_insert(mime_table, "video/x-jng", (gpointer)video_x_jng); g_hash_table_insert(mime_table, "video/x-jng", (gpointer)video_x_jng);
@@ -1569,5 +1697,56 @@ g_hash_table_insert(mime_table, "image/x-tga", (gpointer)image_x_tga);
g_hash_table_insert(mime_table, "application/x-wine-extension-ini", (gpointer)application_x_wine_extension_ini); g_hash_table_insert(mime_table, "application/x-wine-extension-ini", (gpointer)application_x_wine_extension_ini);
g_hash_table_insert(mime_table, "application/x-cbz", (gpointer)application_x_cbz); g_hash_table_insert(mime_table, "application/x-cbz", (gpointer)application_x_cbz);
g_hash_table_insert(mime_table, "application/x-cbr", (gpointer)application_x_cbr); g_hash_table_insert(mime_table, "application/x-cbr", (gpointer)application_x_cbr);
g_hash_table_insert(mime_table, "application/x-ms-compress-szdd", (gpointer)application_x_ms_compress_szdd);
g_hash_table_insert(mime_table, "application/x-atari-7800-rom", (gpointer)application_x_atari_7800_rom);
g_hash_table_insert(mime_table, "application/x-nes-rom", (gpointer)application_x_nes_rom);
g_hash_table_insert(mime_table, "application/x-font-pfm", (gpointer)application_x_font_pfm);
g_hash_table_insert(mime_table, "application/x-gettext-translation", (gpointer)application_x_gettext_translation);
g_hash_table_insert(mime_table, "image/wmf", (gpointer)image_wmf);
g_hash_table_insert(mime_table, "application/pgp-keys", (gpointer)application_pgp_keys);
g_hash_table_insert(mime_table, "image/x-3ds", (gpointer)image_x_3ds);
g_hash_table_insert(mime_table, "application/x-lz4", (gpointer)application_x_lz4);
g_hash_table_insert(mime_table, "application/vnd.openxmlformats-officedocument.presentationml.presentation", (gpointer)application_vnd_openxmlformats_officedocument_presentationml_presentation);
g_hash_table_insert(mime_table, "application/vnd.oasis.opendocument.presentation", (gpointer)application_vnd_oasis_opendocument_presentation);
g_hash_table_insert(mime_table, "application/x-msaccess", (gpointer)application_x_msaccess);
g_hash_table_insert(mime_table, "application/vnd.oasis.opendocument.spreadsheet", (gpointer)application_vnd_oasis_opendocument_spreadsheet);
g_hash_table_insert(mime_table, "audio/x-aiff", (gpointer)audio_x_aiff);
g_hash_table_insert(mime_table, "text/x-ms-regedit", (gpointer)text_x_ms_regedit);
g_hash_table_insert(mime_table, "application/x-gamecube-rom", (gpointer)application_x_gamecube_rom);
g_hash_table_insert(mime_table, "application/x-nintendo-ds-rom", (gpointer)application_x_nintendo_ds_rom);
g_hash_table_insert(mime_table, "text/x-objective-c", (gpointer)text_x_objective_c);
g_hash_table_insert(mime_table, "application/x-font-gdos", (gpointer)application_x_font_gdos);
g_hash_table_insert(mime_table, "application/x-apple-diskimage", (gpointer)application_x_apple_diskimage);
g_hash_table_insert(mime_table, "application/x-zstd", (gpointer)application_x_zstd);
g_hash_table_insert(mime_table, "video/x-m4v", (gpointer)video_x_m4v);
g_hash_table_insert(mime_table, "message/news", (gpointer)message_news);
g_hash_table_insert(mime_table, "application/vnd.symbian.install", (gpointer)application_vnd_symbian_install);
g_hash_table_insert(mime_table, "application/x-lzh-compressed", (gpointer)application_x_lzh_compressed);
g_hash_table_insert(mime_table, "application/x-dosdriver", (gpointer)application_x_dosdriver);
g_hash_table_insert(mime_table, "application/vnd.tcpdump.pcap", (gpointer)application_vnd_tcpdump_pcap);
g_hash_table_insert(mime_table, "x-epoc/x-sisx-app", (gpointer)x_epoc_x_sisx_app);
g_hash_table_insert(mime_table, "application/x-avira-qua", (gpointer)application_x_avira_qua);
g_hash_table_insert(mime_table, "video/MP2T", (gpointer)video_MP2T);
g_hash_table_insert(mime_table, "application/x-snappy-framed", (gpointer)application_x_snappy_framed);
g_hash_table_insert(mime_table, "application/x-lz4+json", (gpointer)application_x_lz4_json);
g_hash_table_insert(mime_table, "application/x-dmp", (gpointer)application_x_dmp);
g_hash_table_insert(mime_table, "application/zlib", (gpointer)application_zlib);
g_hash_table_insert(mime_table, "application/x-pgp-keyring", (gpointer)application_x_pgp_keyring);
g_hash_table_insert(mime_table, "application/x-gdbm", (gpointer)application_x_gdbm);
g_hash_table_insert(mime_table, "application/x-font-pf2", (gpointer)application_x_font_pf2);
g_hash_table_insert(mime_table, "application/x-zip", (gpointer)application_x_zip);
g_hash_table_insert(mime_table, "application/x-coredump", (gpointer)application_x_coredump);
g_hash_table_insert(mime_table, "application/x-java-jmod", (gpointer)application_x_java_jmod);
g_hash_table_insert(mime_table, "application/x-terminfo", (gpointer)application_x_terminfo);
g_hash_table_insert(mime_table, "application/x-terminfo2", (gpointer)application_x_terminfo2);
g_hash_table_insert(mime_table, "application/x-arc", (gpointer)application_x_arc);
g_hash_table_insert(mime_table, "application/vnd.lotus-1-2-3", (gpointer)application_vnd_lotus_1_2_3);
g_hash_table_insert(mime_table, "image/x-win-bitmap", (gpointer)image_x_win_bitmap);
g_hash_table_insert(mime_table, "application/x-maxis-dbpf", (gpointer)application_x_maxis_dbpf);
g_hash_table_insert(mime_table, "text/PGP", (gpointer)text_PGP);
g_hash_table_insert(mime_table, "audio/x-hx-aac-adts", (gpointer)audio_x_hx_aac_adts);
g_hash_table_insert(mime_table, "application/x-chrome-extension", (gpointer)application_x_chrome_extension);
g_hash_table_insert(mime_table, "image/heic", (gpointer)image_heic);
g_hash_table_insert(mime_table, "image/x-gem", (gpointer)image_x_gem);
return mime_table;} return mime_table;}
#endif #endif

View File

@@ -1,7 +1,7 @@
#include "src/sist.h" #include "src/sist.h"
#include "src/ctx.h" #include "src/ctx.h"
__thread magic_t Magic; __thread magic_t Magic = NULL;
void *read_all(parse_job_t *job, const char *buf, int bytes_read, int *fd) { void *read_all(parse_job_t *job, const char *buf, int bytes_read, int *fd) {
@@ -16,7 +16,6 @@ void *read_all(parse_job_t *job, const char *buf, int bytes_read, int *fd) {
if (*fd == -1) { if (*fd == -1) {
perror("open"); perror("open");
printf("%s\n", job->filepath); printf("%s\n", job->filepath);
free(job);
return NULL; return NULL;
} }
} }
@@ -25,6 +24,7 @@ void *read_all(parse_job_t *job, const char *buf, int bytes_read, int *fd) {
int ret = read(*fd, full_buf + bytes_read, job->info.st_size - bytes_read); int ret = read(*fd, full_buf + bytes_read, job->info.st_size - bytes_read);
if (ret == -1) { if (ret == -1) {
perror("read"); perror("read");
return NULL;
} }
} }
@@ -62,7 +62,7 @@ void parse(void *arg) {
if (job->info.st_size == 0) { if (job->info.st_size == 0) {
doc.mime = MIME_EMPTY; doc.mime = MIME_EMPTY;
} else if (*(job->filepath + job->ext) != '\0') { } else if (*(job->filepath + job->ext) != '\0' && (job->ext - job->base != 1)) {
doc.mime = mime_get_mime_by_ext(ScanCtx.ext_table, job->filepath + job->ext); doc.mime = mime_get_mime_by_ext(ScanCtx.ext_table, job->filepath + job->ext);
} }
@@ -80,11 +80,18 @@ void parse(void *arg) {
bytes_read = read(fd, buf, PARSE_BUF_SIZE); bytes_read = read(fd, buf, PARSE_BUF_SIZE);
if (bytes_read == -1) {
perror("read");
close(fd);
free(job);
return;
}
const char *magic_mime_str = magic_buffer(Magic, buf, bytes_read); const char *magic_mime_str = magic_buffer(Magic, buf, bytes_read);
if (magic_mime_str != NULL) { if (magic_mime_str != NULL) {
doc.mime = mime_get_mime_by_string(ScanCtx.mime_table, magic_mime_str); doc.mime = mime_get_mime_by_string(ScanCtx.mime_table, magic_mime_str);
if (doc.mime == 0) { if (doc.mime == 0) {
fprintf(stderr, "Couldn't find mime %s, %s!\n", magic_mime_str, job->filepath + job->base); fprintf(stderr, "Couldn't find mime %s, %s\n", magic_mime_str, job->filepath + job->base);
} }
} }
} }
@@ -93,14 +100,15 @@ void parse(void *arg) {
if (!(SHOULD_PARSE(doc.mime))) { if (!(SHOULD_PARSE(doc.mime))) {
} else if ((mmime == MimeVideo && doc.size >= MIN_VIDEO_SIZE) || mmime == MimeAudio || mmime == MimeImage) { } else if ((mmime == MimeVideo && doc.size >= MIN_VIDEO_SIZE) ||
(mmime == MimeImage && doc.size >= MIN_IMAGE_SIZE) || mmime == MimeAudio) {
parse_media(job->filepath, &doc); parse_media(job->filepath, &doc);
} else if (IS_PDF(doc.mime)) { } else if (IS_PDF(doc.mime)) {
void *pdf_buf = read_all(job, (char *) buf, bytes_read, &fd); void *pdf_buf = read_all(job, (char *) buf, bytes_read, &fd);
parse_pdf(pdf_buf, doc.size, &doc); parse_pdf(pdf_buf, doc.size, &doc);
if (pdf_buf != buf) { if (pdf_buf != buf && pdf_buf != NULL) {
free(pdf_buf); free(pdf_buf);
} }
@@ -111,7 +119,7 @@ void parse(void *arg) {
void *font_buf = read_all(job, (char *) buf, bytes_read, &fd); void *font_buf = read_all(job, (char *) buf, bytes_read, &fd);
parse_font(font_buf, doc.size, &doc); parse_font(font_buf, doc.size, &doc);
if (font_buf != buf) { if (font_buf != buf && font_buf != NULL) {
free(font_buf); free(font_buf);
} }
} }

View File

@@ -1,10 +1,22 @@
#include <src/ctx.h>
#include "pdf.h" #include "pdf.h"
#include "src/ctx.h" #include "src/ctx.h"
fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) { fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
fz_page *cover = fz_load_page(ctx, fzdoc, 0); int err = 0;
fz_page *cover = NULL;
fz_var(cover);
fz_try(ctx)
cover = fz_load_page(ctx, fzdoc, 0);
fz_catch(ctx)
err = 1;
if (err != 0) {
fz_drop_page(ctx, cover);
return NULL;
}
fz_rect bounds = fz_bound_page(ctx, cover); fz_rect bounds = fz_bound_page(ctx, cover);
float scale; float scale;
@@ -24,24 +36,49 @@ fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
fz_clear_pixmap_with_value(ctx, pixmap, 0xFF); fz_clear_pixmap_with_value(ctx, pixmap, 0xFF);
fz_device *dev = fz_new_draw_device(ctx, m, pixmap); fz_device *dev = fz_new_draw_device(ctx, m, pixmap);
pthread_mutex_lock(&ScanCtx.mupdf_mu); fz_var(err);
fz_try(ctx) fz_try(ctx)
{
pthread_mutex_lock(&ScanCtx.mupdf_mu);
fz_run_page(ctx, cover, dev, fz_identity, NULL); fz_run_page(ctx, cover, dev, fz_identity, NULL);
}
fz_always(ctx) fz_always(ctx)
{
fz_close_device(ctx, dev);
fz_drop_device(ctx, dev);
pthread_mutex_unlock(&ScanCtx.mupdf_mu); pthread_mutex_unlock(&ScanCtx.mupdf_mu);
}
fz_catch(ctx) fz_catch(ctx)
fz_rethrow(ctx); err = ctx->error.errcode;
fz_drop_device(ctx, dev); if (err != 0) {
fz_drop_page(ctx, cover);
fz_drop_pixmap(ctx, pixmap);
return NULL;
}
fz_buffer *fzbuf = fz_new_buffer_from_pixmap_as_png(ctx, pixmap, fz_default_color_params); fz_buffer *fzbuf = NULL;
unsigned char *tn_buf; fz_var(fzbuf);
size_t tn_len = fz_buffer_storage(ctx, fzbuf, &tn_buf); fz_var(err);
store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) tn_buf, tn_len); fz_try(ctx)
fzbuf = fz_new_buffer_from_pixmap_as_png(ctx, pixmap, fz_default_color_params);
fz_catch(ctx)
err = ctx->error.errcode;
if (err == 0) {
unsigned char *tn_buf;
size_t tn_len = fz_buffer_storage(ctx, fzbuf, &tn_buf);
store_write(ScanCtx.index.store, (char *) doc->uuid, sizeof(doc->uuid), (char *) tn_buf, tn_len);
}
fz_drop_pixmap(ctx, pixmap);
fz_drop_buffer(ctx, fzbuf); fz_drop_buffer(ctx, fzbuf);
fz_drop_pixmap(ctx, pixmap);
if (err != 0) {
fz_drop_page(ctx, cover);
return NULL;
}
return cover; return cover;
} }
@@ -49,103 +86,178 @@ fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
void fz_noop_callback(__attribute__((unused)) void *user, __attribute__((unused)) const char *message) {} void fz_noop_callback(__attribute__((unused)) void *user, __attribute__((unused)) const char *message) {}
void init_ctx(fz_context *ctx) {
fz_disable_icc(ctx);
fz_register_document_handlers(ctx);
ctx->warn.print = fz_noop_callback;
ctx->error.print = fz_noop_callback;
}
int read_stext_block(fz_stext_block *block, text_buffer_t *tex) {
if (block->type != FZ_STEXT_BLOCK_TEXT) {
return 0;
}
fz_stext_line *line = block->u.t.first_line;
while (line != NULL) {
fz_stext_char *c = line->first_char;
while (c != NULL) {
if (text_buffer_append_char(tex, c->c) == TEXT_BUF_FULL) {
return TEXT_BUF_FULL;
}
c = c->next;
}
line = line->next;
}
return 0;
}
void parse_pdf(void *buf, size_t buf_len, document_t *doc) { void parse_pdf(void *buf, size_t buf_len, document_t *doc) {
if (buf == NULL) {
return;
}
static int mu_is_initialized = 0; static int mu_is_initialized = 0;
if (!mu_is_initialized) { if (!mu_is_initialized) {
pthread_mutex_init(&ScanCtx.mupdf_mu, NULL); pthread_mutex_init(&ScanCtx.mupdf_mu, NULL);
mu_is_initialized = 1; mu_is_initialized = 1;
} }
fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
fz_stream *stream = NULL;
fz_document *fzdoc = NULL;
fz_var(stream); init_ctx(ctx);
int err = 0;
fz_document *fzdoc = NULL;
fz_stream *stream = NULL;
fz_var(fzdoc); fz_var(fzdoc);
fz_var(stream);
fz_var(err);
fz_try(ctx) fz_try(ctx)
{ {
fz_disable_icc(ctx);
fz_register_document_handlers(ctx);
//disable warnings
ctx->warn.print = fz_noop_callback;
ctx->error.print = fz_noop_callback;
stream = fz_open_memory(ctx, buf, buf_len); stream = fz_open_memory(ctx, buf, buf_len);
fzdoc = fz_open_document_with_stream(ctx, mime_get_mime_text(doc->mime), stream); fzdoc = fz_open_document_with_stream(ctx, mime_get_mime_text(doc->mime), stream);
int page_count = fz_count_pages(ctx, fzdoc);
fz_page *cover = render_cover(ctx, doc, fzdoc);
fz_stext_options opts;
text_buffer_t text_buf = text_buffer_create(ScanCtx.content_size);
for (int current_page = 0; current_page < page_count; current_page++) {
fz_page *page;
if (current_page == 0) {
page = cover;
} else {
page = fz_load_page(ctx, fzdoc, current_page);
}
fz_stext_page *stext = fz_new_stext_page(ctx, fz_bound_page(ctx, page));
fz_device *dev = fz_new_stext_device(ctx, stext, &opts);
pthread_mutex_lock(&ScanCtx.mupdf_mu);
fz_try(ctx)
fz_run_page_contents(ctx, page, dev, fz_identity, NULL);
fz_always(ctx)
pthread_mutex_unlock(&ScanCtx.mupdf_mu);
fz_catch(ctx)
fz_rethrow(ctx);
fz_drop_device(ctx, dev);
fz_stext_block *block = stext->first_block;
while (block != NULL) {
if (block->type != FZ_STEXT_BLOCK_TEXT) {
block = block->next;
continue;
}
fz_stext_line *line = block->u.t.first_line;
while (line != NULL) {
fz_stext_char *c = line->first_char;
while (c != NULL) {
if (text_buffer_append_char(&text_buf, c->c) == TEXT_BUF_FULL) {
fz_drop_page(ctx, page);
fz_drop_stext_page(ctx, stext);
goto write_loop_end;
}
c = c->next;
}
line = line->next;
}
block = block->next;
}
fz_drop_page(ctx, page);
fz_drop_stext_page(ctx, stext);
}
write_loop_end:;
text_buffer_terminate_string(&text_buf);
meta_line_t *meta_content = malloc(sizeof(meta_line_t) + text_buf.dyn_buffer.cur);
meta_content->key = MetaContent;
memcpy(meta_content->strval, text_buf.dyn_buffer.buf, text_buf.dyn_buffer.cur);
text_buffer_destroy(&text_buf);
APPEND_META(doc, meta_content)
} }
fz_always(ctx) fz_catch(ctx)
{ err = ctx->error.errcode;
if (err) {
fz_drop_stream(ctx, stream); fz_drop_stream(ctx, stream);
fz_drop_document(ctx, fzdoc); fz_drop_document(ctx, fzdoc);
fz_drop_context(ctx); fz_drop_context(ctx);
} fz_catch(ctx) { return;
fprintf(stderr, "Error %s %s\n", doc->filepath, ctx->error.message);
} }
char title[4096] = {'\0',};
fz_try(ctx)
fz_lookup_metadata(ctx, fzdoc, FZ_META_INFO_TITLE, title, sizeof(title));
fz_catch(ctx)
;
if (strlen(title) > 0) {
meta_line_t *meta_content = malloc(sizeof(meta_line_t) + strlen(title));
meta_content->key = MetaTitle;
strcpy(meta_content->strval, title);
APPEND_META(doc, meta_content)
}
int page_count = -1;
fz_var(err);
fz_try(ctx)
page_count = fz_count_pages(ctx, fzdoc);
fz_catch(ctx)
err = ctx->error.errcode;
if (err) {
fz_drop_stream(ctx, stream);
fz_drop_document(ctx, fzdoc);
fz_drop_context(ctx);
return;
}
fz_page *cover = render_cover(ctx, doc, fzdoc);
if (cover == NULL) {
fz_drop_stream(ctx, stream);
fz_drop_document(ctx, fzdoc);
fz_drop_context(ctx);
return;
}
fz_stext_options opts = {0};
text_buffer_t text_buf = text_buffer_create(ScanCtx.content_size);
for (int current_page = 0; current_page < page_count; current_page++) {
fz_page *page = NULL;
if (current_page == 0) {
page = cover;
} else {
fz_var(err);
fz_try(ctx)
page = fz_load_page(ctx, fzdoc, current_page);
fz_catch(ctx)
err = ctx->error.errcode;
if (err != 0) {
text_buffer_destroy(&text_buf);
fz_drop_page(ctx, page);
fz_drop_stream(ctx, stream);
fz_drop_document(ctx, fzdoc);
fz_drop_context(ctx);
return;
}
}
fz_stext_page *stext = fz_new_stext_page(ctx, fz_bound_page(ctx, page));
fz_device *dev = fz_new_stext_device(ctx, stext, &opts);
fz_var(err);
fz_try(ctx)
fz_run_page(ctx, page, dev, fz_identity, NULL);
fz_always(ctx)
{
fz_close_device(ctx, dev);
fz_drop_device(ctx, dev);
}
fz_catch(ctx)
err = ctx->error.errcode;
if (err != 0) {
text_buffer_destroy(&text_buf);
fz_drop_page(ctx, page);
fz_drop_stext_page(ctx, stext);
fz_drop_stream(ctx, stream);
fz_drop_document(ctx, fzdoc);
fz_drop_context(ctx);
return;
}
fz_stext_block *block = stext->first_block;
while (block != NULL) {
int ret = read_stext_block(block, &text_buf);
if (ret == TEXT_BUF_FULL) {
break;
}
block = block->next;
}
fz_drop_stext_page(ctx, stext);
fz_drop_page(ctx, page);
if (text_buf.dyn_buffer.cur >= text_buf.dyn_buffer.size) {
break;
}
}
text_buffer_terminate_string(&text_buf);
meta_line_t *meta_content = malloc(sizeof(meta_line_t) + text_buf.dyn_buffer.cur);
meta_content->key = MetaContent;
memcpy(meta_content->strval, text_buf.dyn_buffer.buf, text_buf.dyn_buffer.cur);
APPEND_META(doc, meta_content)
fz_drop_stream(ctx, stream);
fz_drop_document(ctx, fzdoc);
fz_drop_context(ctx);
text_buffer_destroy(&text_buf);
} }

View File

@@ -27,17 +27,14 @@ void parse_text(int bytes_read, int *fd, char *buf, document_t *doc) {
read(*fd, intermediate_buf + bytes_read, to_read); read(*fd, intermediate_buf + bytes_read, to_read);
} }
text_buffer_t tex = text_buffer_create(ScanCtx.content_size);
text_buffer_append_string(&tex, intermediate_buf, intermediate_buf_len);
text_buffer_t text_buf = text_buffer_create(ScanCtx.content_size); meta_line_t *meta = malloc(sizeof(meta_line_t) + tex.dyn_buffer.cur);
for (int i = 0; i < intermediate_buf_len; i++) {
text_buffer_append_char(&text_buf, *(intermediate_buf + i));
}
text_buffer_terminate_string(&text_buf);
meta_line_t *meta = malloc(sizeof(meta_line_t) + text_buf.dyn_buffer.cur);
meta->key = MetaContent; meta->key = MetaContent;
strcpy(meta->strval, text_buf.dyn_buffer.buf); strcpy(meta->strval, tex.dyn_buffer.buf);
text_buffer_destroy(&text_buf);
free(intermediate_buf);
APPEND_META(doc, meta) APPEND_META(doc, meta)
free(intermediate_buf);
text_buffer_destroy(&tex);
} }

View File

@@ -16,6 +16,7 @@
#include <libswscale/swscale.h> #include <libswscale/swscale.h>
#include <libswresample/swresample.h> #include <libswresample/swresample.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <ctype.h> #include <ctype.h>
#include <mupdf/fitz.h> #include <mupdf/fitz.h>
#include <mupdf/pdf.h> #include <mupdf/pdf.h>
@@ -49,6 +50,7 @@
#include "parsing/media.h" #include "parsing/media.h"
#include "parsing/font.h" #include "parsing/font.h"
#include "cli.h" #include "cli.h"
#include "utf8.h/utf8.h"
#ifndef SIST_SCAN_ONLY #ifndef SIST_SCAN_ONLY
#include "src/index/elastic.h" #include "src/index/elastic.h"

View File

@@ -25,6 +25,7 @@ typedef struct tpool {
int done_cnt; int done_cnt;
int stop; int stop;
void (*cleanup_func)(); void (*cleanup_func)();
} tpool_t; } tpool_t;
@@ -100,7 +101,7 @@ static void *tpool_worker(void *arg) {
tpool_t *pool = arg; tpool_t *pool = arg;
while (1) { while (1) {
pthread_mutex_lock(&(pool->work_mutex)); pthread_mutex_lock(&pool->work_mutex);
if (pool->stop) { if (pool->stop) {
break; break;
} }
@@ -120,7 +121,7 @@ static void *tpool_worker(void *arg) {
pthread_mutex_lock(&(pool->work_mutex)); pthread_mutex_lock(&(pool->work_mutex));
pool->done_cnt++; pool->done_cnt++;
progress_bar_print((double)pool->done_cnt / pool->work_cnt, ScanCtx.stat_tn_size, ScanCtx.stat_index_size); progress_bar_print((double) pool->done_cnt / pool->work_cnt, ScanCtx.stat_tn_size, ScanCtx.stat_index_size);
if (pool->work_head == NULL) { if (pool->work_head == NULL) {
pthread_cond_signal(&(pool->working_cond)); pthread_cond_signal(&(pool->working_cond));
@@ -188,11 +189,11 @@ tpool_t *tpool_create(size_t thread_cnt, void cleanup_func()) {
tpool_t *pool = malloc(sizeof(tpool_t)); tpool_t *pool = malloc(sizeof(tpool_t));
pool->thread_cnt = thread_cnt; pool->thread_cnt = thread_cnt;
pool->work_cnt =0; pool->work_cnt = 0;
pool->done_cnt =0; pool->done_cnt = 0;
pool->stop = 0; pool->stop = 0;
pool->cleanup_func = cleanup_func; pool->cleanup_func = cleanup_func;
pool->threads = malloc(sizeof(pthread_t) * thread_cnt); pool->threads = calloc(sizeof(pthread_t), thread_cnt);
pthread_mutex_init(&(pool->work_mutex), NULL); pthread_mutex_init(&(pool->work_mutex), NULL);
@@ -202,11 +203,14 @@ tpool_t *tpool_create(size_t thread_cnt, void cleanup_func()) {
pool->work_head = NULL; pool->work_head = NULL;
pool->work_tail = NULL; pool->work_tail = NULL;
for (size_t i = 0; i < thread_cnt; i++) { return pool;
}
void tpool_start(tpool_t *pool) {
for (size_t i = 0; i < pool->thread_cnt; i++) {
pthread_t thread = pool->threads[i]; pthread_t thread = pool->threads[i];
pthread_create(&thread, NULL, tpool_worker, pool); pthread_create(&thread, NULL, tpool_worker, pool);
pthread_detach(thread); pthread_detach(thread);
} }
return pool;
} }

View File

@@ -9,6 +9,7 @@ typedef struct tpool tpool_t;
typedef void (*thread_func_t)(void *arg); typedef void (*thread_func_t)(void *arg);
tpool_t *tpool_create(size_t num, void (*cleanup_func)()); tpool_t *tpool_create(size_t num, void (*cleanup_func)());
void tpool_start(tpool_t *pool);
void tpool_destroy(tpool_t *tm); void tpool_destroy(tpool_t *tm);
int tpool_add_work(tpool_t *pool, thread_func_t func, void *arg); int tpool_add_work(tpool_t *pool, thread_func_t func, void *arg);

View File

@@ -89,6 +89,85 @@ void text_buffer_terminate_string(text_buffer_t *buf) {
dyn_buffer_write_char(&buf->dyn_buffer, '\0'); dyn_buffer_write_char(&buf->dyn_buffer, '\0');
} }
__always_inline
int utf8_validchr(const char *s) {
if (0x00 == (0x80 & *s)) {
return TRUE;
} else if (0xf0 == (0xf8 & *s)) {
if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2])) ||
(0x80 != (0xc0 & s[3]))) {
return FALSE;
}
if (0x80 == (0xc0 & s[4])) {
return FALSE;
}
if ((0 == (0x07 & s[0])) && (0 == (0x30 & s[1]))) {
return FALSE;
}
} else if (0xe0 == (0xf0 & *s)) {
if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2]))) {
return FALSE;
}
if (0x80 == (0xc0 & s[3])) {
return FALSE;
}
if ((0 == (0x0f & s[0])) && (0 == (0x20 & s[1]))) {
return FALSE;
}
} else if (0xc0 == (0xe0 & *s)) {
if (0x80 != (0xc0 & s[1])) {
return FALSE;
}
if (0x80 == (0xc0 & s[2])) {
return FALSE;
}
if (0 == (0x1e & s[0])) {
return FALSE;
}
} else {
return FALSE;
}
return TRUE;
}
int text_buffer_append_string(text_buffer_t *buf, char *str, size_t len) {
utf8_int32_t c;
if (str == NULL || len < 1 ||
(0xf0 == (0xf8 & str[0]) && len < 4) ||
(0xe0 == (0xf0 & str[0]) && len < 3) ||
(0xc0 == (0xe0 & str[0]) && len == 1) ||
*(str) == 0) {
text_buffer_terminate_string(buf);
return 0;
}
for (void *v = utf8codepoint(str, &c); c != '\0' && ((char *) v - str + 4) < len; v = utf8codepoint(v, &c)) {
if (utf8_validchr(v)) {
text_buffer_append_char(buf, c);
}
}
text_buffer_terminate_string(buf);
return 0;
}
int text_buffer_append_string0(text_buffer_t *buf, char *str) {
utf8_int32_t c;
for (void *v = utf8codepoint(str, &c); c != '\0'; v = utf8codepoint(v, &c)) {
if (utf8_validchr(v)) {
text_buffer_append_char(buf, c);
}
}
text_buffer_terminate_string(buf);
}
int text_buffer_append_char(text_buffer_t *buf, int c) { int text_buffer_append_char(text_buffer_t *buf, int c) {
if (SHOULD_IGNORE_CHAR(c)) { if (SHOULD_IGNORE_CHAR(c)) {
@@ -96,15 +175,31 @@ int text_buffer_append_char(text_buffer_t *buf, int c) {
dyn_buffer_write_char(&buf->dyn_buffer, ' '); dyn_buffer_write_char(&buf->dyn_buffer, ' ');
buf->last_char_was_whitespace = TRUE; buf->last_char_was_whitespace = TRUE;
if (buf->dyn_buffer.cur >= buf->max_size) { if (buf->max_size > 0 && buf->dyn_buffer.cur >= buf->max_size) {
return TEXT_BUF_FULL; return TEXT_BUF_FULL;
} }
} }
} else { } else {
buf->last_char_was_whitespace = FALSE; buf->last_char_was_whitespace = FALSE;
dyn_buffer_write_char(&buf->dyn_buffer, (char) c); grow_buffer_small(&buf->dyn_buffer);
if (buf->dyn_buffer.cur >= buf->max_size) { if (0 == ((utf8_int32_t) 0xffffff80 & c)) {
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = (char) c;
} else if (0 == ((utf8_int32_t) 0xfffff800 & c)) {
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xc0 | (char) (c >> 6);
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
} else if (0 == ((utf8_int32_t) 0xffff0000 & c)) {
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xe0 | (char) (c >> 12);
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 6) & 0x3f);
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
} else {
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xf0 | (char) (c >> 18);
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 12) & 0x3f);
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 6) & 0x3f);
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
}
if (buf->max_size > 0 && buf->dyn_buffer.cur >= buf->max_size) {
return TEXT_BUF_FULL; return TEXT_BUF_FULL;
} }
} }
@@ -136,7 +231,7 @@ dyn_buffer_t url_escape(char *str) {
dyn_buffer_t text = dyn_buffer_create(); dyn_buffer_t text = dyn_buffer_create();
char * ptr = str; char *ptr = str;
while (*ptr) { while (*ptr) {
if (*ptr == '#') { if (*ptr == '#') {
dyn_buffer_write(&text, "%23", 3); dyn_buffer_write(&text, "%23", 3);
@@ -169,7 +264,7 @@ char *expandpath(const char *path) {
wordexp_t w; wordexp_t w;
wordexp(path, &w, 0); wordexp(path, &w, 0);
char * expanded = malloc(strlen(w.we_wordv[0]) + 2); char *expanded = malloc(strlen(w.we_wordv[0]) + 2);
strcpy(expanded, w.we_wordv[0]); strcpy(expanded, w.we_wordv[0]);
strcat(expanded, "/"); strcat(expanded, "/");

View File

@@ -5,7 +5,10 @@
#define TEXT_BUF_FULL -1 #define TEXT_BUF_FULL -1
#define INITIAL_BUF_SIZE 1024 * 16 #define INITIAL_BUF_SIZE 1024 * 16
#define SHOULD_IGNORE_CHAR(c) c < '0' || c > 'z'
#define SHOULD_IGNORE_CHAR(c) !(SHOULD_KEEP_CHAR(c))
#define SHOULD_KEEP_CHAR(c) (c >= (int)'!')
typedef struct dyn_buffer { typedef struct dyn_buffer {
char *buf; char *buf;
@@ -21,8 +24,10 @@ typedef struct text_buffer {
dyn_buffer_t dyn_buffer; dyn_buffer_t dyn_buffer;
} text_buffer_t; } text_buffer_t;
char *abspath(const char * path); char *abspath(const char *path);
char *expandpath(const char *path); char *expandpath(const char *path);
dyn_buffer_t url_escape(char *str); dyn_buffer_t url_escape(char *str);
void progress_bar_print(double percentage, size_t tn_size, size_t index_size); void progress_bar_print(double percentage, size_t tn_size, size_t index_size);
@@ -56,13 +61,16 @@ text_buffer_t text_buffer_create(int max_size);
void text_buffer_terminate_string(text_buffer_t *buf); void text_buffer_terminate_string(text_buffer_t *buf);
int text_buffer_append_string(text_buffer_t *buf, char *str, size_t len);
int text_buffer_append_string0(text_buffer_t *buf, char *str);
int text_buffer_append_char(text_buffer_t *buf, int c); int text_buffer_append_char(text_buffer_t *buf, int c);
void incremental_put(GHashTable *table, unsigned long inode_no, int mtime); void incremental_put(GHashTable *table, unsigned long inode_no, int mtime);
int incremental_get(GHashTable *table, unsigned long inode_no); int incremental_get(GHashTable *table, unsigned long inode_no);
int incremental_mark_file_for_copy(GHashTable *table, unsigned long inode_no); int incremental_mark_file_for_copy(GHashTable *table, unsigned long inode_no);
#endif #endif

View File

@@ -43,27 +43,40 @@ int javascript(void *p, onion_request *req, onion_response *res) {
return OCS_PROCESSED; return OCS_PROCESSED;
} }
int style(void *p, onion_request *req, onion_response *res) { int client_requested_dark_theme(onion_request *req) {
set_default_headers(res); const char *cookie = onion_request_get_cookie(req, "sist");
onion_response_set_header(res, "Content-Type", "text/css"); if (cookie == NULL) {
onion_response_set_length(res, sizeof(bundle_css)); return FALSE;
onion_response_write(res, bundle_css, sizeof(bundle_css)); }
return OCS_PROCESSED;
return strcmp(cookie, "dark") == 0;
} }
int bg_bars(void *p, onion_request *req, onion_response *res) { int style(void *p, onion_request *req, onion_response *res) {
set_default_headers(res); set_default_headers(res);
onion_response_set_header(res, "Content-Type", "image/png");
onion_response_set_length(res, sizeof(bg_bars_png)); onion_response_set_header(res, "Content-Type", "text/css");
onion_response_write(res, bg_bars_png, sizeof(bg_bars_png));
if (client_requested_dark_theme(req)) {
onion_response_set_length(res, sizeof(bundle_dark_css));
onion_response_write(res, bundle_dark_css, sizeof(bundle_dark_css));
} else {
onion_response_set_length(res, sizeof(bundle_css));
onion_response_write(res, bundle_css, sizeof(bundle_css));
}
return OCS_PROCESSED; return OCS_PROCESSED;
} }
int img_sprite_skin_flag(void *p, onion_request *req, onion_response *res) { int img_sprite_skin_flag(void *p, onion_request *req, onion_response *res) {
set_default_headers(res); set_default_headers(res);
onion_response_set_header(res, "Content-Type", "image/png"); onion_response_set_header(res, "Content-Type", "image/png");
onion_response_set_length(res, sizeof(sprite_skin_flat_png)); if (client_requested_dark_theme(req)) {
onion_response_write(res, sprite_skin_flat_png, sizeof(sprite_skin_flat_png)); onion_response_set_length(res, sizeof(sprite_skin_flat_dark_png));
onion_response_write(res, sprite_skin_flat_dark_png, sizeof(sprite_skin_flat_dark_png));
} else {
onion_response_set_length(res, sizeof(sprite_skin_flat_png));
onion_response_write(res, sprite_skin_flat_png, sizeof(sprite_skin_flat_png));
}
return OCS_PROCESSED; return OCS_PROCESSED;
} }
@@ -326,7 +339,7 @@ int index_info(void *p, onion_request *req, onion_response *res) {
cJSON_AddStringToObject(idx_json, "name", idx->desc.name); cJSON_AddStringToObject(idx_json, "name", idx->desc.name);
cJSON_AddStringToObject(idx_json, "version", idx->desc.version); cJSON_AddStringToObject(idx_json, "version", idx->desc.version);
cJSON_AddStringToObject(idx_json, "id", idx->desc.uuid); cJSON_AddStringToObject(idx_json, "id", idx->desc.uuid);
cJSON_AddNumberToObject(idx_json, "timestamp", (double)idx->desc.timestamp); cJSON_AddNumberToObject(idx_json, "timestamp", (double) idx->desc.timestamp);
cJSON_AddItemToArray(arr, idx_json); cJSON_AddItemToArray(arr, idx_json);
} }
@@ -362,7 +375,7 @@ int file(void *p, onion_request *req, onion_response *res) {
int ret; int ret;
if (strlen(idx->desc.rewrite_url) == 0) { if (strlen(idx->desc.rewrite_url) == 0) {
ret =serve_file_from_disk(source, idx, req, res); ret = serve_file_from_disk(source, idx, req, res);
} else { } else {
ret = serve_file_from_url(source, idx, req, res); ret = serve_file_from_url(source, idx, req, res);
} }
@@ -384,7 +397,6 @@ void serve(const char *hostname, const char *port) {
onion_url_add(urls, "", search_index); onion_url_add(urls, "", search_index);
onion_url_add(urls, "css", style); onion_url_add(urls, "css", style);
onion_url_add(urls, "js", javascript); onion_url_add(urls, "js", javascript);
onion_url_add(urls, "img/bg-bars.png", bg_bars);
onion_url_add(urls, "img/sprite-skin-flat.png", img_sprite_skin_flag); onion_url_add(urls, "img/sprite-skin-flat.png", img_sprite_skin_flag);
onion_url_add(urls, "es", search); onion_url_add(urls, "es", search);

File diff suppressed because one or more lines are too long

1
utf8.h Submodule

Submodule utf8.h added at 2a7c5bfa95

242
web/css/dark.css Normal file
View File

@@ -0,0 +1,242 @@
a {
color: #00BCD4;
}
body {
overflow-y: scroll;
background: black;
}
.progress {
margin-top: 1em;
}
.card {
margin-top: 1em;
background: #212121;
color: #e0e0e0;
border-radius: 1px;
border: none;
}
.navbar-brand {
font-size: 1.75rem;
padding: 0;
color: #f5f5f5;
}
.navbar {
background: #546b7a;
}
.navbar a:hover {
color: #fff;
}
.navbar span {
color: #eee;
}
.document {
padding: 0.5rem;
}
.document p {
margin-bottom: 0;
}
.document:hover p {
text-decoration: underline;
}
.badge-video {
color: #FFFFFF;
background-color: #F27761;
}
.badge-image {
color: #FFFFFF;
background-color: #AA99C9;
}
.badge-audio {
color: #FFFFFF;
background-color: #00ADEF;
}
.badge-resolution {
color: #212529;
background-color: #B0BEC5;
}
.badge-text {
color: #FFFFFF;
background-color: #FAAB3C;
}
.card-img-overlay {
pointer-events: none;
padding: 0.75rem;
bottom: unset;
top: 0;
left: unset;
right: unset;
}
.file-title {
font-size: 10pt;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.badge {
margin-right: 3px;
}
.fit {
display: block;
min-width: 64px;
max-width: 100%;
max-height: 175px;
margin: 0 auto 0;
padding: 3px 3px 0 3px;
width: auto;
height: auto;
}
.audio-fit {
height: 39px;
vertical-align: bottom;
display: inline;
width: 100%;
}
@media (min-width: 1200px) {
.card-columns {
column-count: 4;
}
}
@media (min-width: 1500px) {
.container {
max-width: 1440px;
}
.card-columns {
column-count: 5;
}
}
@media (min-width: 1800px) {
.container {
max-width: 1550px;
}
}
mark {
background: #fff217;
border-radius: 0;
padding: 1px 0;
}
.content-div {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 13px;
padding: 1em;
background-color: #37474F;
border: 1px solid #616161;
border-radius: 4px;
margin: 3px;
}
.irs-single, .irs-from, .irs-to {
font-size: 13px;
background-color: #00BCD4;
}
.irs-slider {
cursor: col-resize;
}
.irs {
margin-top: 1em;
margin-bottom: 1em;
}
.custom-select {
overflow: auto;
background-color: #37474F;
border: 1px solid #616161;
color: #bdbdbd;
}
.custom-select:focus {
border-color: #757575;
outline: 0;
box-shadow: 0 0 0 .2rem rgba(0, 123, 255, .25);
}
option {
outline: none;
}
.form-control {
background-color: #37474F;
border: 1px solid #616161;
color: #fff;
}
.form-control:focus {
background-color: #546E7A;
color: #fff;
}
.input-group-text {
background: #263238;
border: 1px solid #616161;
color: #dbdbdb;
}
::placeholder {
color: #BDBDBD !important;
opacity: 1;
}
.inspire-tree .selected > .wholerow, .inspire-tree .selected > .title-wrap:hover + .wholerow {
background: none;
}
.inspire-tree .icon-expand::before, .inspire-tree .icon-collapse::before {
background-color: black;
}
.inspire-tree .title {
color: #eee;
}
.inspire-tree {
font-weight: 400;
font-size: 14px;
font-family: Helvetica, Nueue, Verdana, sans-serif;
max-height: 350px;
overflow: auto;
}
.page-indicator {
line-height: 1rem;
padding: 0.5rem;
background: #212121;
color: #eee;
}
.btn-xs {
padding: .1rem .3rem;
font-size: .875rem;
border-radius: .2rem;
}
.btn {
color: #eee;
}

View File

@@ -6,6 +6,7 @@ body {overflow-y:scroll;}
.card { .card {
margin-top: 1em; margin-top: 1em;
box-shadow: 0 .125rem .25rem rgba(0,0,0,.075) !important;
} }
.navbar-brand { .navbar-brand {
font-size: 1.75rem; font-size: 1.75rem;
@@ -87,6 +88,7 @@ body {overflow-y:scroll;}
height: 39px; height: 39px;
vertical-align: bottom; vertical-align: bottom;
display: inline; display: inline;
width: 100%;
} }
@media (min-width: 1200px) { @media (min-width: 1200px) {
@@ -159,6 +161,7 @@ mark {
.page-indicator { .page-indicator {
line-height: 1rem; line-height: 1rem;
padding: 0.5rem; padding: 0.5rem;
background: #f8f9fa;
} }
.btn-xs { .btn-xs {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

View File

@@ -82,7 +82,7 @@ function shouldPlayVideo(hit) {
*/ */
function createDocCard(hit) { function createDocCard(hit) {
let docCard = document.createElement("div"); let docCard = document.createElement("div");
docCard.setAttribute("class", "card shadow-sm"); docCard.setAttribute("class", "card");
let docCardBody = document.createElement("div"); let docCardBody = document.createElement("div");
docCardBody.setAttribute("class", "card-body document"); docCardBody.setAttribute("class", "card-body document");
@@ -136,6 +136,9 @@ function createDocCard(hit) {
thumbnail = document.createElement("img"); thumbnail = document.createElement("img");
thumbnail.setAttribute("class", "card-img-top fit"); 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"]}`);
thumbnail.addEventListener("error", () => {
imgWrapper.remove();
});
} }
//Thumbnail overlay //Thumbnail overlay
@@ -197,7 +200,7 @@ function createDocCard(hit) {
let contentHl = getContentHighlight(hit); let contentHl = getContentHighlight(hit);
if (contentHl !== undefined) { if (contentHl !== undefined) {
let contentDiv = document.createElement("div"); let contentDiv = document.createElement("div");
contentDiv.setAttribute("class", "content-div bg-light"); contentDiv.setAttribute("class", "content-div");
contentDiv.insertAdjacentHTML('afterbegin', contentHl); contentDiv.insertAdjacentHTML('afterbegin', contentHl);
docCard.appendChild(contentDiv); docCard.appendChild(contentDiv);
} }
@@ -257,7 +260,7 @@ function makePreloader() {
function makePageIndicator(searchResult) { function makePageIndicator(searchResult) {
let pageIndicator = document.createElement("div"); let pageIndicator = document.createElement("div");
pageIndicator.setAttribute("class", "page-indicator shadow-sm bg-light font-weight-light"); pageIndicator.setAttribute("class", "page-indicator font-weight-light");
const totalHits = searchResult["hits"]["total"].hasOwnProperty("value") const totalHits = searchResult["hits"]["total"].hasOwnProperty("value")
? searchResult["hits"]["total"]["value"] : searchResult["hits"]["total"]; ? searchResult["hits"]["total"]["value"] : searchResult["hits"]["total"];
pageIndicator.appendChild(document.createTextNode(docCount + " / " + totalHits)); pageIndicator.appendChild(document.createTextNode(docCount + " / " + totalHits));

View File

@@ -21,7 +21,18 @@ jQuery["jsonPost"] = function (url, data) {
}); });
}; };
function toggleSearchBar() { window.onload = () => {
$("#theme").on("click", () => {
if (!document.cookie.includes("sist")) {
document.cookie = "sist=dark";
} else {
document.cookie = "sist=; Max-Age=-99999999;";
}
window.location.reload();
})
};
function toggleFuzzy() {
searchDebounced(); searchDebounced();
} }
@@ -105,7 +116,7 @@ $.jsonPost("es", {
new autoComplete({ new autoComplete({
selector: '#pathBar', selector: '#pathBar',
minChars: 1, minChars: 1,
delay: 75, delay: 400,
renderItem: function (item) { renderItem: function (item) {
return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item + '</div>'; return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item + '</div>';
}, },
@@ -207,11 +218,22 @@ function search() {
let query = searchBar.value; let query = searchBar.value;
let empty = query === ""; let empty = query === "";
let condition = $("#barToggle").prop("checked") && !empty ? "must" : "should"; let condition = empty ? "should" : "must";
let filters = [ let filters = [
{range: {size: {gte: size_min, lte: size_max}}}, {range: {size: {gte: size_min, lte: size_max}}},
{terms: {index: selectedIndices}} {terms: {index: selectedIndices}}
]; ];
let fields = [
"name^8",
"content^3",
"album^8", "artist^8", "title^8", "genre^2", "album_artist^8",
"font_name^6"
];
if ($("#fuzzyToggle").prop("checked")) {
fields.push("content.nGram");
fields.push("name.nGram^3");
}
let path = pathBar.value.replace(/\/$/, "").toLowerCase(); //remove trailing slashes let path = pathBar.value.replace(/\/$/, "").toLowerCase(); //remove trailing slashes
if (path !== "") { if (path !== "") {
@@ -232,12 +254,7 @@ function search() {
multi_match: { multi_match: {
query: query, query: query,
type: "most_fields", type: "most_fields",
fields: [ fields: fields,
"name^8", "name.nGram^3", "content^3",
"content.nGram",
"album^8", "artist^8", "title^8", "genre^2", "album_artist^8",
"font_name^6"
],
operator: "and" operator: "and"
} }
}, },
@@ -254,7 +271,7 @@ function search() {
content: {}, content: {},
name: {}, name: {},
"name.nGram": {}, "name.nGram": {},
// font_name: {}, font_name: {},
} }
}, },
aggs: { aggs: {
@@ -268,14 +285,6 @@ function search() {
//Search stats //Search stats
searchResults.appendChild(makeStatsCard(searchResult)); searchResults.appendChild(makeStatsCard(searchResult));
//Autocomplete
if (searchResult.hasOwnProperty("suggest") && searchResult["suggest"].hasOwnProperty("path")) {
pathAutoComplete = [];
for (let i = 0; i < searchResult["suggest"]["path"][0]["options"].length; i++) {
pathAutoComplete.push(searchResult["suggest"]["path"][0]["options"][i].text)
}
}
//Setup page //Setup page
let resultContainer = makeResultContainer(); let resultContainer = makeResultContainer();
searchResults.appendChild(resultContainer); searchResults.appendChild(resultContainer);
@@ -287,7 +296,6 @@ function search() {
}); });
} }
let pathAutoComplete = [];
let size_min = 0; let size_min = 0;
let size_max = 10000000000000; let size_max = 10000000000000;
@@ -295,8 +303,8 @@ let searchDebounced = _.debounce(function () {
coolingDown = false; coolingDown = false;
search() search()
}, 500); }, 500);
searchBar.addEventListener("keyup", searchDebounced); searchBar.addEventListener("keyup", searchDebounced);
document.getElementById("pathBar").addEventListener("keyup", searchDebounced);
//Size slider //Size slider
$("#sizeSlider").ionRangeSlider({ $("#sizeSlider").ionRangeSlider({
@@ -347,15 +355,18 @@ updateIndices();
//Suggest //Suggest
function getPathChoices() { function getPathChoices() {
return new Promise(getPaths => { return new Promise(getPaths => {
$.jsonPost("es", {
let xhttp = new XMLHttpRequest(); suggest: {
xhttp.onreadystatechange = function () { path: {
if (this.readyState === 4 && this.status === 200) { prefix: pathBar.value,
getPaths(JSON.parse(xhttp.responseText)) completion: {
field: "suggest-path",
skip_duplicates: true,
size: 10000
}
}
} }
}; }).then(resp => getPaths(resp["suggest"]["path"][0]["options"].map(opt => opt["_source"]["path"])));
xhttp.open("GET", "suggest?prefix=" + pathBar.value, true); })
xhttp.send();
});
} }

View File

@@ -9,9 +9,10 @@
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-lg navbar-light"> <nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="/">sist2</a> <a class="navbar-brand" href="/">sist2</a>
<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" id="theme" class="btn" title="Toggle theme" href="/">Theme</a>
</nav> </nav>
<div class="container"> <div class="container">
@@ -23,9 +24,9 @@
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span onclick="document.getElementById('barToggle').click()">Must match&nbsp</span> <span onclick="document.getElementById('fuzzyToggle').click()">Fuzzy&nbsp</span>
<input title="Toggle between 'Should' and 'Must' match mode" type="checkbox" id="barToggle" <input title="Toggle fuzzy searching" type="checkbox" id="fuzzyToggle"
onclick="toggleSearchBar()" checked> onclick="toggleFuzzy()" checked>
</div> </div>
</div> </div>
<input id="searchBar" type="search" class="form-control" placeholder="Search"> <input id="searchBar" type="search" class="form-control" placeholder="Search">