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.
@@ -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
+ ![NPM Version](https://img.shields.io/npm/v/thelounge-plugin-janitor?style=for-the-badge)
4
+ ![NPM Downloads](https://img.shields.io/npm/dy/thelounge-plugin-janitor?style=for-the-badge)
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
+ }