Added sorting feature for Manage Uploads

This adds support for a new key named 'orderby'.
The key needs to be used with internal column names used in the db.
The key can be used more than once.
Help message in Dashboard's Manage Uploads have been updated to include
examples using the said key.
This commit is contained in:
Bobby Wibowo 2020-04-04 23:36:43 +07:00
parent f534ac2e4d
commit 8f50ba49c0
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
4 changed files with 52 additions and 19 deletions

View File

@ -328,7 +328,7 @@ self.get = async (req, res, next) => {
const files = await db.table('files')
.select('name')
.where('albumid', album.id)
.orderBy('id', 'DESC')
.orderBy('id', 'desc')
for (const file of files) {
file.file = `${config.domain}/${file.name}`

View File

@ -775,6 +775,18 @@ self.list = async (req, res) => {
}
}
// Cast column(s) to specific type if they're stored differently
const _orderByCasts = {
size: 'integer'
}
// Columns with which to use SQLite's NULLS LAST option
const _orderByNullsLast = [
'userid',
'expirydate',
'ip'
]
const _orderBy = []
// Perhaps this can be simplified even further?
if (filters) {
const usernames = []
@ -797,11 +809,26 @@ self.list = async (req, res) => {
})
.forEach(v => {
if (!v) return
if (v[0] === 'user') usernames.push(v[1])
else if (v[0] === 'name') _filters.names.push(v[1])
else if (v[0] === 'ip') _filters.ips.push(v[1])
else if (v[0] === '-user') _filters.flags.nouser = true
else if (v[0] === '-ip') _filters.flags.noip = true
if (v[0] === 'user') {
usernames.push(v[1])
} else if (v[0] === 'name') {
_filters.names.push(v[1])
} else if (v[0] === 'ip') {
_filters.ips.push(v[1])
} else if (v[0] === '-user') {
_filters.flags.nouser = true
} else if (v[0] === '-ip') {
_filters.flags.noip = true
} else if (v[0] === 'orderby') {
const tmp = v[1].split(':')
let col = tmp[0]
let dir = 'asc'
if (_orderByCasts[col])
col = `cast (\`${col}\` as ${_orderByCasts[col]})`
if (tmp[1] && /^d/i.test(tmp[1]))
dir = 'desc'
_orderBy.push(`${col} ${dir}${_orderByNullsLast.includes(col) ? ' nulls last' : ''}`)
}
})
_filters.uploaders = await db.table('users')
.whereIn('username', usernames)
@ -855,7 +882,7 @@ self.list = async (req, res) => {
const files = await db.table('files')
.where(filter)
.orderBy('id', 'DESC')
.orderByRaw(_orderBy.length ? _orderBy.join(', ') : '`id` desc')
.limit(25)
.offset(25 * offset)
.select(columns)

View File

@ -59,7 +59,7 @@ routes.get('/a/:identifier', async (req, res, next) => {
const files = await db.table('files')
.select('name', 'size')
.where('albumid', album.id)
.orderBy('id', 'DESC')
.orderBy('id', 'desc')
album.thumb = ''
album.totalSize = 0

View File

@ -949,26 +949,32 @@ page.filtersHelp = element => {
content.innerHTML = `
This supports 3 filter keys, namely <b>user</b> (username), <b>ip</b> and <b>name</b> (upload name).
Each key can be specified more than once.
Backlashes should be used if the usernames have spaces.
There are also 2 additional flags, namely <b>-user</b> and <b>-ip</b>, which will match uploads by non-registered users and have no IPs respectively.
Backslashes should be used if the username contain whitespaces.
How does it work?
First, it will filter uploads matching ANY of the supplied <b>user</b> or <b>ip</b> keys.
Then, it will refine the matches using the supplied <b>name</b> keys.
There are 2 special flags, namely <b>-user</b> and <b>-ip</b>, which will match uploads by non-registered users and have no IPs respectively.
Examples:
Matches can also be sorted with <b>orderby:columnName[:direction]</b> key.
This key requires using the internal column names used in the database (size, timestamp, expirydate, and so on).
This key can also be specified more than once, where their order will decide the sorting steps.
<b>Internals:</b>
First, it will filter uploads matching ANY of the supplied filter keys AND/OR special flags, if any.
Second, it will refine the matches using the supplied <b>name</b> keys, if any.
Third, it will sort the matches using the supplied <b>orderby</b> keys, if any.
<b>Examples:</b>
Uploads from user with username "demo":
<code>user:demo</code>
Uploads from users with username either "John Doe" OR "demo":
Uploads from users with username "John Doe" AND/OR "demo":
<code>user:John\\ Doe user:demo</code>
Uploads from IP "127.0.0.1" AND which upload names match "*.rar" OR "*.zip":
<code>ip:127.0.0.1 name:*.rar name:*.zip</code>
Uploads from user with username "test" OR from non-registered users:
Uploads from user with username "test" AND/OR from non-registered users:
<code>user:test -user</code>
Sort results by "size" column in ascending and descending order respectively:
<code>orderby:expirydate</code>
<code>user:demo orderby:size</code>
<code>-user name:*.mp4 orderby:size:desc</code>
`.trim().replace(/^ {6}/gm, '').replace(/\n/g, '<br>')
swal({ content })
}