diff --git a/controllers/albumsController.js b/controllers/albumsController.js
index 5c2fb85..427655d 100644
--- a/controllers/albumsController.js
+++ b/controllers/albumsController.js
@@ -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}`
diff --git a/controllers/uploadController.js b/controllers/uploadController.js
index 8b2f9ab..2184007 100644
--- a/controllers/uploadController.js
+++ b/controllers/uploadController.js
@@ -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)
diff --git a/routes/album.js b/routes/album.js
index dc73da5..0f493b6 100644
--- a/routes/album.js
+++ b/routes/album.js
@@ -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
diff --git a/src/js/dashboard.js b/src/js/dashboard.js
index a25ebcf..32da320 100644
--- a/src/js/dashboard.js
+++ b/src/js/dashboard.js
@@ -949,26 +949,32 @@ page.filtersHelp = element => {
content.innerHTML = `
This supports 3 filter keys, namely user (username), ip and name (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 -user and -ip, 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 user or ip keys.
- Then, it will refine the matches using the supplied name keys.
+ There are 2 special flags, namely -user and -ip, which will match uploads by non-registered users and have no IPs respectively.
- Examples:
+ Matches can also be sorted with orderby:columnName[:direction] 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.
+ Internals:
+ 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 name keys, if any.
+ Third, it will sort the matches using the supplied orderby keys, if any.
+
+ Examples:
Uploads from user with username "demo":
user:demo
-
- Uploads from users with username either "John Doe" OR "demo":
+ Uploads from users with username "John Doe" AND/OR "demo":
user:John\\ Doe user:demo
-
Uploads from IP "127.0.0.1" AND which upload names match "*.rar" OR "*.zip":
ip:127.0.0.1 name:*.rar name:*.zip
-
- Uploads from user with username "test" OR from non-registered users:
+ Uploads from user with username "test" AND/OR from non-registered users:
user:test -user
+ Sort results by "size" column in ascending and descending order respectively:
+ orderby:expirydate
+ user:demo orderby:size
+ -user name:*.mp4 orderby:size:desc
`.trim().replace(/^ {6}/gm, '').replace(/\n/g, '
')
swal({ content })
}