fix: download-counter: different cases and encodings with urls weren't properly counted #240

Massimo Melina committed May 7, 2023 at 16:54 UTC 6f42381a4025a3c0e46f3005ef647d50b82f19b0
1 file changed +13 -6
plugins/download-counter/plugin.js
+13 -6
@@ -1,5 +1,5 @@
1 exports.description = "Counts downloads for each file, and displays the total in the list or file menu"
2 -exports.version = 4 // config.where
2 +exports.version = 4.1 // fix: different cases and encodings with urls weren't properly counted
3 exports.apiRequired = 8
4
5 exports.config = {
@@ -15,7 +15,7 @@ exports.init = async api => {
15 const _ = api.require('lodash')
16 const yaml = api.require('yaml')
17 const { writeFile, readFile } = api.require('fs/promises')
18 - const { debounceAsync } = api.require('./misc')
18 + const { debounceAsync, newObj } = api.require('./misc')
19
20 const countersFile = 'counters.yaml'
21
@@ -29,6 +29,7 @@ exports.init = async api => {
29 try {
30 const data = await readFile(countersFile, 'utf8')
31 counters = yaml.parse(data) || {}
32 + counters = newObj(counters, (v,k,setKey) => setKey(uri2key(k)) && v)
33 console.debug('counters loaded')
34 }
35 catch(err) {
@@ -43,15 +44,21 @@ exports.init = async api => {
44 middleware: (ctx) =>
45 () => { // execute after other middlewares are done
46 if (ctx.status >= 300 || !ctx.vfsNode) return
46 - const { path } = ctx
47 - counters[path] = counters[path] + 1 || 1
47 + const k = uri2key(ctx.path)
48 + counters[k] = counters[k] + 1 || 1
49 save()
50 },
51 onDirEntry: ({ entry, listUri }) => {
51 - const path = listUri + entry.n
52 - const n = counters[path]
52 + const k = uri2key(listUri + entry.n)
53 + const n = counters[k]
54 if (n)
55 entry.hits = n
56 }
57 }
58 }
59 +
60 +function uri2key(uri) { // normalize uri to avoid having different keys for same file
61 + try { uri = decodeURIComponent(uri) } // decodeURI doesn't support #=%23
62 + catch {}
63 + return uri.toLowerCase()
64 +}