thelounge-plugin-janitor 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/build.yml.disabled +28 -0
- package/.github/workflows/publish.yml +36 -0
- package/README.md +33 -0
- package/index.js +91 -0
- package/package.json +29 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Build package
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
|
|
9
|
+
steps:
|
|
10
|
+
- name: Checkout code
|
|
11
|
+
uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- name: Setup Node.js
|
|
14
|
+
uses: actions/setup-node@v4
|
|
15
|
+
with:
|
|
16
|
+
node-version: 18.20.8
|
|
17
|
+
|
|
18
|
+
- name: Install dependencies
|
|
19
|
+
run: npm ci
|
|
20
|
+
|
|
21
|
+
# - name: Lint
|
|
22
|
+
# run: npm run lint --if-present
|
|
23
|
+
|
|
24
|
+
# - name: Test
|
|
25
|
+
# run: npm test --if-present
|
|
26
|
+
|
|
27
|
+
# - name: Build
|
|
28
|
+
# run: npm run build --if-present
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout code
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Setup Node.js
|
|
19
|
+
uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: 18.20.8
|
|
22
|
+
registry-url: https://registry.npmjs.org
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: npm ci
|
|
26
|
+
|
|
27
|
+
- name: Build
|
|
28
|
+
run: npm run build --if-present
|
|
29
|
+
|
|
30
|
+
- name: Test
|
|
31
|
+
run: npm test --if-present
|
|
32
|
+
|
|
33
|
+
- name: Publish to npm
|
|
34
|
+
run: npm publish --provenance --access public
|
|
35
|
+
env:
|
|
36
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# The Lounge Janitor Plugin
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
A plugin for [The Lounge](https://thelounge.chat/) that cleans up old uploads
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Via the `thelounge` command line:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
thelounge install thelounge-plugin-janitor
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Add a `deleteUploadsAfter` entry in the `config.js` of your instance representing how long uploads stay on the server before getting deleted in minutes:
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
"use strict";
|
|
20
|
+
module.exports = {
|
|
21
|
+
deleteUploadsAfter: 1440, // 1 day in minutes
|
|
22
|
+
// rest of config...
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Restart The Lounge after installation
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
The plugin runs every minute in the background, users do not need to do anything.
|
|
30
|
+
|
|
31
|
+
## License
|
|
32
|
+
|
|
33
|
+
This plugin is licensed under [MIT](https://opensource.org/license/mit)
|
package/index.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
|
|
6
|
+
let logger;
|
|
7
|
+
|
|
8
|
+
function deleteOldUploads(dir, maxAgeMinutes) {
|
|
9
|
+
if (!fs.existsSync(dir)) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const now = Date.now();
|
|
14
|
+
const maxAgeMs = maxAgeMinutes * 60 * 1000;
|
|
15
|
+
let count = 0;
|
|
16
|
+
|
|
17
|
+
// Uploads are stored in subdirectories named by the upload ID, so we need to read those first
|
|
18
|
+
const uploadDirs = fs
|
|
19
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
20
|
+
.filter((d) => d.isDirectory());
|
|
21
|
+
|
|
22
|
+
for (const uploadDir of uploadDirs) {
|
|
23
|
+
const uploadPath = path.join(dir, uploadDir.name);
|
|
24
|
+
const files = fs.readdirSync(uploadPath);
|
|
25
|
+
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
const filePath = path.join(uploadPath, file);
|
|
28
|
+
const stats = fs.statSync(filePath);
|
|
29
|
+
const ageMs = now - stats.mtimeMs;
|
|
30
|
+
|
|
31
|
+
if (ageMs > maxAgeMs) {
|
|
32
|
+
try {
|
|
33
|
+
fs.unlinkSync(filePath);
|
|
34
|
+
count++;
|
|
35
|
+
logger.debug(`Deleted ${filePath} (age: ${ageMs} ms)`);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
logger.error(`Failed to delete ${filePath}: ${err.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// If the upload directory is empty after deleting old files, remove it
|
|
43
|
+
if (fs.readdirSync(uploadPath).length === 0) {
|
|
44
|
+
try {
|
|
45
|
+
fs.rmdirSync(uploadPath);
|
|
46
|
+
logger.debug(`Deleted empty upload directory: ${uploadPath}`);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
logger.error(
|
|
49
|
+
`Failed to delete directory ${uploadPath}: ${err.message}`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (count > 0) {
|
|
56
|
+
logger.info(`Deleted ${count} upload${count > 1 ? "s" : ""}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
onServerStart(tl) {
|
|
62
|
+
logger = tl.Logger;
|
|
63
|
+
const config = tl.Config.getConfig();
|
|
64
|
+
|
|
65
|
+
if (config.deleteUploadsAfter && config.deleteUploadsAfter > 0) {
|
|
66
|
+
const tlDir = process.env.THELOUNGE_HOME;
|
|
67
|
+
|
|
68
|
+
if (!tlDir) {
|
|
69
|
+
logger.error(
|
|
70
|
+
"THELOUNGE_HOME environment variable is not set, cannot determine uploads directory",
|
|
71
|
+
);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const uploadsDir = path.join(tlDir, "uploads");
|
|
76
|
+
|
|
77
|
+
logger.info(
|
|
78
|
+
`Watching ${uploadsDir} to delete uploads older than ${config.deleteUploadsAfter} minutes`,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Run the janitor every 1 minute
|
|
82
|
+
setInterval(() => {
|
|
83
|
+
deleteOldUploads(uploadsDir, config.deleteUploadsAfter);
|
|
84
|
+
}, 60 * 1000);
|
|
85
|
+
} else {
|
|
86
|
+
logger.warn(
|
|
87
|
+
"deleteUploadsAfter is not set or is not greater than 0, janitor will not run",
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "thelounge-plugin-janitor",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A plugin for The Lounge that cleans up old uploads",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"thelounge",
|
|
7
|
+
"thelounge-plugin"
|
|
8
|
+
],
|
|
9
|
+
"thelounge": {
|
|
10
|
+
"name": "janitor",
|
|
11
|
+
"type": "plugin",
|
|
12
|
+
"supports": ">=4.0.0"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/cy1der/thelounge-plugin-janitor#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/cy1der/thelounge-plugin-janitor/issues"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/cy1der/thelounge-plugin-janitor.git"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "cy1der",
|
|
24
|
+
"type": "commonjs",
|
|
25
|
+
"main": "index.js",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"thelounge": "^4.4.3"
|
|
28
|
+
}
|
|
29
|
+
}
|