mirror of
https://github.com/simon987/sist2.git
synced 2025-12-12 15:08:53 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ccccdb3b78 | |||
| 12d17acf4f | |||
| 48b56cdb7b | |||
| 048f707f80 |
@@ -117,7 +117,11 @@ void *create_bulk_buffer(int max, int *count, size_t *buf_len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *print_errors(response_t *r) {
|
void *print_errors(response_t *r) {
|
||||||
cJSON *ret_json = cJSON_Parse(r->body);
|
char * tmp = malloc(r->size + 1);
|
||||||
|
memcpy(tmp, r->body, r->size);
|
||||||
|
*(tmp + r->size) = '\0';
|
||||||
|
|
||||||
|
cJSON *ret_json = cJSON_Parse(tmp);
|
||||||
if (cJSON_GetObjectItem(ret_json, "errors")->valueint != 0) {
|
if (cJSON_GetObjectItem(ret_json, "errors")->valueint != 0) {
|
||||||
cJSON *err;
|
cJSON *err;
|
||||||
cJSON_ArrayForEach(err, cJSON_GetObjectItem(ret_json, "items")) {
|
cJSON_ArrayForEach(err, cJSON_GetObjectItem(ret_json, "items")) {
|
||||||
@@ -129,6 +133,7 @@ void *print_errors(response_t *r) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cJSON_Delete(ret_json);
|
cJSON_Delete(ret_json);
|
||||||
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _elastic_flush(int max) {
|
void _elastic_flush(int max) {
|
||||||
|
|||||||
@@ -6,7 +6,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.3.2";
|
static const char *const Version = "1.3.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",
|
||||||
|
|||||||
45
src/util.h
45
src/util.h
@@ -19,7 +19,7 @@ typedef struct dyn_buffer {
|
|||||||
#include "sist.h"
|
#include "sist.h"
|
||||||
|
|
||||||
typedef struct text_buffer {
|
typedef struct text_buffer {
|
||||||
size_t max_size;
|
long max_size;
|
||||||
int last_char_was_whitespace;
|
int last_char_was_whitespace;
|
||||||
dyn_buffer_t dyn_buffer;
|
dyn_buffer_t dyn_buffer;
|
||||||
} text_buffer_t;
|
} text_buffer_t;
|
||||||
@@ -235,23 +235,42 @@ static void text_buffer_terminate_string(text_buffer_t *buf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__always_inline
|
#define UTF8_END_OF_STRING \
|
||||||
static int text_buffer_append_string(text_buffer_t *buf, char *str, size_t len) {
|
(ptr - str >= len || *ptr == 0 || \
|
||||||
|
(0xc0 == (0xe0 & *ptr) && ptr - str > len - 2) || \
|
||||||
|
(0xe0 == (0xf0 & *ptr) && ptr - str > len - 3) || \
|
||||||
|
(0xf0 == (0xf8 & *ptr) && ptr - str > len - 4))
|
||||||
|
|
||||||
utf8_int32_t c;
|
__always_inline
|
||||||
if (str == NULL || len < 1 ||
|
static int text_buffer_append_string(text_buffer_t *buf, const char *str, size_t len) {
|
||||||
(0xf0 == (0xf8 & str[0]) && len < 4) ||
|
|
||||||
(0xe0 == (0xf0 & str[0]) && len < 3) ||
|
char *ptr = str;
|
||||||
(0xc0 == (0xe0 & str[0]) && len == 1) ||
|
char *oldPtr = ptr;
|
||||||
*(str) == 0) {
|
|
||||||
|
if (str == NULL || UTF8_END_OF_STRING) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (void *v = utf8codepoint(str, &c); c != '\0' && ((char *) v - str + 4) < len; v = utf8codepoint(v, &c)) {
|
utf8_int32_t c;
|
||||||
if (utf8_validchr2(v)) {
|
char tmp[4];
|
||||||
text_buffer_append_char(buf, c);
|
|
||||||
|
do {
|
||||||
|
ptr = utf8codepoint(ptr, &c);
|
||||||
|
*(int *) tmp = 0x00000000;
|
||||||
|
memcpy(tmp, oldPtr, ptr - oldPtr);
|
||||||
|
oldPtr = ptr;
|
||||||
|
|
||||||
|
if (!utf8_validchr2(tmp)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
int ret = text_buffer_append_char(buf, c);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} while (!UTF8_END_OF_STRING);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
2
web/js/1_popper.min.js
vendored
2
web/js/1_popper.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -14,6 +14,12 @@ let searchBusy = true;
|
|||||||
let selectedIndices = [];
|
let selectedIndices = [];
|
||||||
let indexMap = {};
|
let indexMap = {};
|
||||||
|
|
||||||
|
let size_min = 0;
|
||||||
|
let size_max = 10000000000000;
|
||||||
|
|
||||||
|
let date_min = null;
|
||||||
|
let date_max = null;
|
||||||
|
|
||||||
const CONF = new Settings();
|
const CONF = new Settings();
|
||||||
|
|
||||||
const _defaults = {
|
const _defaults = {
|
||||||
@@ -120,9 +126,7 @@ function getDocumentInfo(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleTreeClick(tree) {
|
function handleTreeClick(tree) {
|
||||||
return (event, node, handler) => {
|
return (node) => {
|
||||||
event.preventTreeDefault();
|
|
||||||
|
|
||||||
if (node.id === "any") {
|
if (node.id === "any") {
|
||||||
if (!node.itree.state.checked) {
|
if (!node.itree.state.checked) {
|
||||||
tree.deselect();
|
tree.deselect();
|
||||||
@@ -131,12 +135,10 @@ function handleTreeClick(tree) {
|
|||||||
tree.node("any").deselect();
|
tree.node("any").deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
handler();
|
|
||||||
searchDebounced();
|
searchDebounced();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: filter based on selected indexes, sort mime types
|
|
||||||
$.jsonPost("es", {
|
$.jsonPost("es", {
|
||||||
aggs: {
|
aggs: {
|
||||||
mimeTypes: {
|
mimeTypes: {
|
||||||
@@ -148,7 +150,7 @@ $.jsonPost("es", {
|
|||||||
},
|
},
|
||||||
size: 0,
|
size: 0,
|
||||||
}).then(resp => {
|
}).then(resp => {
|
||||||
resp["aggregations"]["mimeTypes"]["buckets"].forEach(bucket => {
|
resp["aggregations"]["mimeTypes"]["buckets"].sort((a, b) => a.key > b.key).forEach(bucket => {
|
||||||
let tmp = bucket["key"].split("/");
|
let tmp = bucket["key"].split("/");
|
||||||
let category = tmp[0];
|
let category = tmp[0];
|
||||||
let mime = tmp[1];
|
let mime = tmp[1];
|
||||||
@@ -182,7 +184,7 @@ $.jsonPost("es", {
|
|||||||
new InspireTreeDOM(mimeTree, {
|
new InspireTreeDOM(mimeTree, {
|
||||||
target: '#mimeTree'
|
target: '#mimeTree'
|
||||||
});
|
});
|
||||||
mimeTree.on("node.click", handleTreeClick(mimeTree));
|
mimeTree.on("node.state.changed", handleTreeClick(mimeTree));
|
||||||
mimeTree.deselect();
|
mimeTree.deselect();
|
||||||
mimeTree.node("any").select();
|
mimeTree.node("any").select();
|
||||||
});
|
});
|
||||||
@@ -215,7 +217,7 @@ $.jsonPost("es", {
|
|||||||
new InspireTreeDOM(tagTree, {
|
new InspireTreeDOM(tagTree, {
|
||||||
target: '#tagTree'
|
target: '#tagTree'
|
||||||
});
|
});
|
||||||
tagTree.on("node.click", handleTreeClick(tagTree));
|
tagTree.on("node.state.changed", handleTreeClick(tagTree));
|
||||||
tagTree.node("any").select();
|
tagTree.node("any").select();
|
||||||
searchBusy = false;
|
searchBusy = false;
|
||||||
});
|
});
|
||||||
@@ -345,6 +347,14 @@ function search(after = null) {
|
|||||||
filters.push([{terms: {"tag": tags}}]);
|
filters.push([{terms: {"tag": tags}}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (date_min && date_max) {
|
||||||
|
filters.push([{range: {mtime: {gte: date_min, lte: date_max}}}])
|
||||||
|
} else if (date_min) {
|
||||||
|
filters.push([{range: {mtime: {gte: date_min}}}])
|
||||||
|
} else if (date_max) {
|
||||||
|
filters.push([{range: {mtime: {lte: date_max}}}])
|
||||||
|
}
|
||||||
|
|
||||||
let q = {
|
let q = {
|
||||||
"_source": {
|
"_source": {
|
||||||
excludes: ["content", "_tie"]
|
excludes: ["content", "_tie"]
|
||||||
@@ -422,8 +432,6 @@ function search(after = null) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let size_min = 0;
|
|
||||||
let size_max = 10000000000000;
|
|
||||||
|
|
||||||
let searchDebounced = _.debounce(function () {
|
let searchDebounced = _.debounce(function () {
|
||||||
coolingDown = false;
|
coolingDown = false;
|
||||||
@@ -431,6 +439,7 @@ let searchDebounced = _.debounce(function () {
|
|||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
searchBar.addEventListener("keyup", searchDebounced);
|
searchBar.addEventListener("keyup", searchDebounced);
|
||||||
|
pathBar.addEventListener("keyup", searchDebounced);
|
||||||
|
|
||||||
//Size slider
|
//Size slider
|
||||||
$("#sizeSlider").ionRangeSlider({
|
$("#sizeSlider").ionRangeSlider({
|
||||||
@@ -465,6 +474,37 @@ $("#sizeSlider").ionRangeSlider({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Date slider
|
||||||
|
$.jsonPost("es", {
|
||||||
|
aggs: {
|
||||||
|
date_min: {min: {field: "mtime"}},
|
||||||
|
date_max: {max: {field: "mtime"}},
|
||||||
|
},
|
||||||
|
size: 0
|
||||||
|
}).then(resp => {
|
||||||
|
$("#dateSlider").ionRangeSlider({
|
||||||
|
type: "double",
|
||||||
|
grid: false,
|
||||||
|
force_edges: true,
|
||||||
|
min: resp["aggregations"]["date_min"]["value"],
|
||||||
|
max: resp["aggregations"]["date_max"]["value"],
|
||||||
|
from: resp["aggregations"]["date_min"]["value"],
|
||||||
|
to: (Date.now() / 1000),
|
||||||
|
min_interval: 3600 * 24 * 7,
|
||||||
|
step: 3600 * 24,
|
||||||
|
drag_interval: true,
|
||||||
|
prettify: function (num) {
|
||||||
|
let date = (new Date(num * 1000));
|
||||||
|
return date.getUTCFullYear() + "-" + ("0" + (date.getUTCMonth() + 1)).slice(-2) + "-" + ("0" + date.getUTCDate()).slice(-2)
|
||||||
|
},
|
||||||
|
onFinish: function (e) {
|
||||||
|
date_min = e.from === e.min ? null : e.from;
|
||||||
|
date_max = e.to === e.max ? null : e.to;
|
||||||
|
searchDebounced();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
function updateIndices() {
|
function updateIndices() {
|
||||||
let selected = $('#indices').find('option:selected');
|
let selected = $('#indices').find('option:selected');
|
||||||
selectedIndices = [];
|
selectedIndices = [];
|
||||||
@@ -492,7 +532,7 @@ function getNextDepth(node) {
|
|||||||
bool: {
|
bool: {
|
||||||
filter: [
|
filter: [
|
||||||
{term: {index: node.index}},
|
{term: {index: node.index}},
|
||||||
{term: {_depth: node.depth + 1}}
|
{range: {_depth: {gte: node.depth + 1, lte: node.depth + 3}}},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -520,12 +560,21 @@ function getNextDepth(node) {
|
|||||||
if (!buckets) {
|
if (!buckets) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const paths = [];
|
||||||
|
|
||||||
return buckets
|
return buckets
|
||||||
.filter(bucket => bucket.key.length > node.id.length || node.id.startsWith("/"))
|
.filter(bucket => bucket.key.length > node.id.length || node.id.startsWith("/"))
|
||||||
.sort((a, b) => a.key > b.key)
|
.sort((a, b) => a.key > b.key)
|
||||||
.map(bucket => {
|
.map(bucket => {
|
||||||
const i = bucket.key.lastIndexOf("/");
|
|
||||||
const name = (i === -1 || i === 1) ? bucket.key : bucket.key.slice(i + 1);
|
if (paths.some(n => bucket.key.startsWith(n))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = node.id.startsWith("/") ? bucket.key : bucket.key.slice(node.id.length + 1);
|
||||||
|
|
||||||
|
paths.push(bucket.key);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: bucket.key,
|
id: bucket.key,
|
||||||
@@ -534,7 +583,7 @@ function getNextDepth(node) {
|
|||||||
index: node.index,
|
index: node.index,
|
||||||
children: true,
|
children: true,
|
||||||
}
|
}
|
||||||
})
|
}).filter(x => x !== null)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,9 +625,7 @@ function createPathTree(target) {
|
|||||||
|
|
||||||
const button = document.querySelector("#pathBarHelper")
|
const button = document.querySelector("#pathBarHelper")
|
||||||
const tooltip = document.querySelector("#pathTreeTooltip")
|
const tooltip = document.querySelector("#pathTreeTooltip")
|
||||||
console.log(button)
|
Popper.createPopper(button, tooltip, {
|
||||||
console.log(tooltip)
|
|
||||||
Popper.createPopper(button, tooltip ,{
|
|
||||||
trigger: "click",
|
trigger: "click",
|
||||||
placement: "right",
|
placement: "right",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<nav class="navbar navbar-expand-lg">
|
<nav class="navbar navbar-expand-lg">
|
||||||
<a class="navbar-brand" href="/">sist2</a>
|
<a class="navbar-brand" href="/">sist2</a>
|
||||||
<span class="badge badge-pill version">v1.3.2</span>
|
<span class="badge badge-pill version">v1.3.3</span>
|
||||||
<span class="tagline">Lightning-fast file system indexer and search tool </span>
|
<span class="tagline">Lightning-fast file system indexer and search tool </span>
|
||||||
<button style="margin-left: auto" class="btn" type="button" data-toggle="modal" data-target="#settings" onclick="loadSettings()">Settings</button>
|
<button style="margin-left: auto" class="btn" type="button" data-toggle="modal" data-target="#settings" onclick="loadSettings()">Settings</button>
|
||||||
<a id="theme" class="btn" title="Toggle theme" href="/">Theme</a>
|
<a id="theme" class="btn" title="Toggle theme" href="/">Theme</a>
|
||||||
@@ -20,18 +20,6 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<button id="pathBarHelper" class="btn btn-outline-secondary" data-toggle="modal" data-target="#pathTreeModal">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" width="20px"><path d="M288 224h224a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32H400L368 0h-80a32 32 0 0 0-32 32v64H64V8a8 8 0 0 0-8-8H40a8 8 0 0 0-8 8v392a16 16 0 0 0 16 16h208v64a32 32 0 0 0 32 32h224a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32H400l-32-32h-80a32 32 0 0 0-32 32v64H64V128h192v64a32 32 0 0 0 32 32zm0 96h66.74l32 32H512v128H288zm0-288h66.74l32 32H512v128H288z"/></svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<input id="pathBar" type="search" class="form-control" placeholder="Filter path">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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">
|
||||||
@@ -51,7 +39,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input title="File size" id="sizeSlider" name="size">
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<input title="File size" id="sizeSlider" name="size" width="100%">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
<div class="input-group" style="margin-bottom: 0.5em; margin-top: 1em">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<button id="pathBarHelper" class="btn btn-outline-secondary" data-toggle="modal" data-target="#pathTreeModal">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" width="20px"><path d="M288 224h224a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32H400L368 0h-80a32 32 0 0 0-32 32v64H64V8a8 8 0 0 0-8-8H40a8 8 0 0 0-8 8v392a16 16 0 0 0 16 16h208v64a32 32 0 0 0 32 32h224a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32H400l-32-32h-80a32 32 0 0 0-32 32v64H64V128h192v64a32 32 0 0 0 32 32zm0 96h66.74l32 32H512v128H288zm0-288h66.74l32 32H512v128H288z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<input id="pathBar" type="search" class="form-control" placeholder="Filter path">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input title="Date filter" id="dateSlider" name="size" width="100%">
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
|||||||
Reference in New Issue
Block a user