mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-01-19 01:31:34 +00:00
Added type-is filter keys (is:image and is:video)
Fixed text queries threshold being applied to moderators Bumped v1 version string and rebuilt client assets
This commit is contained in:
parent
d201b03f59
commit
126cfe0e15
@ -770,6 +770,7 @@ self.list = async (req, res) => {
|
||||
const MAX_WILDCARDS_IN_KEY = 2
|
||||
const MAX_TEXT_QUERIES = 3 // non-keyed keywords
|
||||
const MAX_SORT_KEYS = 1
|
||||
const MAX_IS_KEYS = 1
|
||||
|
||||
const filterObj = {
|
||||
uploaders: [],
|
||||
@ -777,6 +778,10 @@ self.list = async (req, res) => {
|
||||
queries: {
|
||||
exclude: {}
|
||||
},
|
||||
typeIs: [
|
||||
'image',
|
||||
'video'
|
||||
],
|
||||
flags: {}
|
||||
}
|
||||
|
||||
@ -843,6 +848,7 @@ self.list = async (req, res) => {
|
||||
|
||||
filterObj.queries = searchQuery.parse(filters, {
|
||||
keywords: keywords.concat([
|
||||
'is',
|
||||
'sort'
|
||||
]),
|
||||
ranges,
|
||||
@ -855,6 +861,7 @@ self.list = async (req, res) => {
|
||||
if (typeof filterObj.queries.exclude.text === 'string')
|
||||
filterObj.queries.exclude.text = [filterObj.queries.exclude.text]
|
||||
|
||||
// Text (non-keyed keywords) queries
|
||||
let textQueries = 0
|
||||
if (filterObj.queries.text) textQueries += filterObj.queries.text.length
|
||||
if (filterObj.queries.exclude.text) textQueries += filterObj.queries.exclude.text.length
|
||||
@ -869,7 +876,7 @@ self.list = async (req, res) => {
|
||||
if (filterObj.queries.text)
|
||||
for (let i = 0; i < filterObj.queries.text.length; i++) {
|
||||
const result = sqlLikeParser(filterObj.queries.text[i])
|
||||
if (result.count > MAX_WILDCARDS_IN_KEY)
|
||||
if (!ismoderator && result.count > MAX_WILDCARDS_IN_KEY)
|
||||
return res.json({
|
||||
success: false,
|
||||
description: `Users are only allowed to use ${MAX_WILDCARDS_IN_KEY} wildcard${MAX_WILDCARDS_IN_KEY === 1 ? '' : 's'} per key.`
|
||||
@ -877,18 +884,16 @@ self.list = async (req, res) => {
|
||||
filterObj.queries.text[i] = result.escaped
|
||||
}
|
||||
|
||||
if (filterObj.queries.exclude.text) {
|
||||
textQueries += filterObj.queries.exclude.text.length
|
||||
if (filterObj.queries.exclude.text)
|
||||
for (let i = 0; i < filterObj.queries.exclude.text.length; i++) {
|
||||
const result = sqlLikeParser(filterObj.queries.exclude.text[i])
|
||||
if (result.count > MAX_WILDCARDS_IN_KEY)
|
||||
if (!ismoderator && result.count > MAX_WILDCARDS_IN_KEY)
|
||||
return res.json({
|
||||
success: false,
|
||||
description: `Users are only allowed to use ${MAX_WILDCARDS_IN_KEY} wildcard${MAX_WILDCARDS_IN_KEY === 1 ? '' : 's'} per key.`
|
||||
})
|
||||
filterObj.queries.exclude.text[i] = result.escaped
|
||||
}
|
||||
}
|
||||
|
||||
for (const key of keywords) {
|
||||
let queryIndex = -1
|
||||
@ -1050,6 +1055,39 @@ self.list = async (req, res) => {
|
||||
// Delete key to avoid unexpected behavior
|
||||
delete filterObj.queries.sort
|
||||
}
|
||||
|
||||
// Parse is keys
|
||||
let isKeys = 0
|
||||
let isLast
|
||||
if (filterObj.queries.is || filterObj.queries.exclude.is) {
|
||||
for (const type of filterObj.typeIs) {
|
||||
const inQuery = filterObj.queries.is && filterObj.queries.is.includes(type)
|
||||
const inExclude = filterObj.queries.exclude.is && filterObj.queries.exclude.is.includes(type)
|
||||
|
||||
// Prioritize exclude keys when both types found
|
||||
if (inQuery || inExclude) {
|
||||
filterObj.flags[`is${type}`] = inExclude ? false : inQuery
|
||||
if (isLast !== undefined && isLast !== filterObj.flags[`is${type}`])
|
||||
return res.json({
|
||||
success: false,
|
||||
description: 'Cannot mix inclusion and exclusion type-is keys.'
|
||||
})
|
||||
isKeys++
|
||||
isLast = filterObj.flags[`is${type}`]
|
||||
}
|
||||
}
|
||||
|
||||
// Delete keys to avoid unexpected behavior
|
||||
delete filterObj.queries.is
|
||||
delete filterObj.queries.exclude.is
|
||||
}
|
||||
|
||||
// Regular user threshold check
|
||||
if (!ismoderator && isKeys > MAX_IS_KEYS)
|
||||
return res.json({
|
||||
success: false,
|
||||
description: `Users are only allowed to use ${MAX_IS_KEYS} type-is key${MAX_IS_KEYS === 1 ? '' : 's'} at a time.`
|
||||
})
|
||||
}
|
||||
|
||||
function filter () {
|
||||
@ -1136,6 +1174,23 @@ self.list = async (req, res) => {
|
||||
this.andWhere('expirydate', '<=', filterObj.queries.date.to)
|
||||
})
|
||||
|
||||
// Then, refine using type-is flags
|
||||
this.andWhere(function () {
|
||||
for (const type of filterObj.typeIs) {
|
||||
const patterns = utils[`${type}Exts`].map(ext => `%${ext}`)
|
||||
|
||||
let operator
|
||||
if (filterObj.flags[`is${type}`] === true)
|
||||
operator = 'like'
|
||||
else if (filterObj.flags[`is${type}`] === false)
|
||||
operator = 'not like'
|
||||
|
||||
if (operator)
|
||||
for (const pattern of patterns)
|
||||
this.orWhere('name', operator, pattern)
|
||||
}
|
||||
})
|
||||
|
||||
// Then, refine using the supplied keywords against their file names
|
||||
this.andWhere(function () {
|
||||
if (!filterObj.queries.text) return
|
||||
|
2
dist/js/dashboard.js
vendored
2
dist/js/dashboard.js
vendored
File diff suppressed because one or more lines are too long
2
dist/js/dashboard.js.map
vendored
2
dist/js/dashboard.js.map
vendored
File diff suppressed because one or more lines are too long
@ -1049,13 +1049,19 @@ page.uploadFiltersHelp = element => {
|
||||
API requests to the filter endpoint will attach your browser's timezone offset, so the server will automatically calculate timezone differences.
|
||||
|
||||
Matches can also be sorted with <b>sort</b> keys.
|
||||
Its format is: <code>sort:columnName[:d[escending]]</code>, where <code>:d[escending]</code> is an optional tag to set the direction to descending.
|
||||
Their formats are: <code>sort:columnName[:d[escending]]</code>, where <code>:d[escending]</code> is an optional tag to set the direction to descending.
|
||||
This key must be used with internal column names used in the database (<code>id</code>, <code>${all ? 'userid' : 'albumid'}</code>, and so on),
|
||||
but there are 2 shortcuts available: <b>date</b> for <code>timestamp</code> column and <b>expiry</b> for <code>expirydate</code> column.
|
||||
This key can also be specified more than once, where their order will decide the sorting steps.
|
||||
|
||||
Finally, there are type-<b>is</b> keys to refine by types.
|
||||
You can use <code>is:image</code> and <code>is:video</code> to list images and videos respectively.
|
||||
This will only use image/video extensions whose thumbnails can be generated by the safe.
|
||||
Negation sign works for this key as well.
|
||||
Mixing inclusion and exclusion is not allowed (i.e. <code>is:image -is:video</code>, since the second key is redundant).
|
||||
|
||||
Any leftover keywords which do not use keys (non-keyed keywords) will be matched against the matches' file names.
|
||||
Excluding certain keywords is also supported by adding negation sign (<b>-</b>) before the keywords.
|
||||
Excluding certain keywords is also supported by adding negation sign before the keywords.
|
||||
|
||||
<b>Internal steps:</b>
|
||||
${all ? `- Query uploads passing ALL exclusion filter keys OR matching ANY filter keys, if any.
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"1": "1588451242",
|
||||
"1": "1588455082",
|
||||
"2": "1581416390",
|
||||
"3": "1581416390",
|
||||
"4": "1581416390",
|
||||
|
Loading…
Reference in New Issue
Block a user