Initial
This commit is contained in:
37
LICENSE
37
LICENSE
@@ -1,26 +1,25 @@
|
|||||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
MIT License
|
||||||
Version 3, 19 November 2007
|
|
||||||
|
|
||||||
---
|
Copyright (c) Patrick Asmus (scriptos)
|
||||||
|
|
||||||
Copyright ©
|
|
||||||
|
|
||||||
Name: Patrick Asmus (scriptos)
|
|
||||||
Email: support@techniverse.net
|
|
||||||
Website: https://www.patrick-asmus.de
|
Website: https://www.patrick-asmus.de
|
||||||
Blog: https://www.cleveradmin.de
|
Blog: https://www.cleveradmin.de
|
||||||
|
Email: support@techniverse.net
|
||||||
|
|
||||||
---
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
The above copyright notice and this permission notice shall be included in all
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
copies or substantial portions of the Software.
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
GNU Affero General Public License for more details.
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
You should have received a copy of the GNU Affero General Public License
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
SOFTWARE.
|
||||||
|
|||||||
83
README.md
83
README.md
@@ -4,10 +4,10 @@
|
|||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h1 align="center">Name des Projekts</h1>
|
<h1 align="center">Kutt Links Cleanup</h1>
|
||||||
|
|
||||||
<h4 align="center">
|
<h4 align="center">
|
||||||
Kurzbeschreibung des Projekts/Anwendung, um die es geht
|
Bash-Script zum automatischen Aufräumen anonymer Links in einer selbst gehosteten Kutt-Instanz.
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
<h6 align="center">
|
<h6 align="center">
|
||||||
@@ -22,7 +22,84 @@
|
|||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
|
|
||||||
CONTENT BEREICH
|
## Was macht das Script?
|
||||||
|
|
||||||
|
Anonyme Links (ohne Account erstellt) werden gelöscht, wenn sie beispielhaft seit **365 Tagen nicht mehr aufgerufen** wurden. Als Referenzdatum gilt:
|
||||||
|
|
||||||
|
- Der **letzte Aufruf** (letzter Eintrag in der `visits`-Tabelle)
|
||||||
|
- Falls der Link **nie aufgerufen** wurde: das **Erstelldatum**
|
||||||
|
|
||||||
|
Links von eingeloggten Usern werden **nie** angefasst.
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
- Kutt läuft als Docker-Setup mit einem PostgreSQL-Container namens `kutt-db`
|
||||||
|
- Der ausführende User hat Zugriff auf `docker exec`
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Script ablegen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /home/docker-projekte/kutt/scripts
|
||||||
|
cp kutt-links-cleanup.sh /home/docker-projekte/kutt/scripts/
|
||||||
|
chmod +x /home/docker-projekte/kutt/scripts/kutt-links-cleanup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Cronjob einrichten
|
||||||
|
|
||||||
|
Täglich um 03:00 Uhr ausführen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
Folgende Zeile hinzufügen:
|
||||||
|
|
||||||
|
```
|
||||||
|
0 3 * * * /home/docker-projekte/kutt/scripts/kutt-links-cleanup.sh >> /home/docker-projekte/kutt/scripts/cleanup.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verwendung
|
||||||
|
|
||||||
|
### Dry Run (nur anzeigen, nichts löschen)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./kutt-links-cleanup.sh --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
Zeigt alle Links an, die gelöscht werden würden — ohne etwas zu verändern.
|
||||||
|
|
||||||
|
### Ausführen (Links löschen)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./kutt-links-cleanup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Log prüfen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat /home/docker-projekte/kutt/scripts/cleanup.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Konfiguration
|
||||||
|
|
||||||
|
Die Variablen stehen am Anfang des Scripts:
|
||||||
|
|
||||||
|
| Variable | Standard | Beschreibung |
|
||||||
|
|---|---|---|
|
||||||
|
| `CONTAINER` | `kutt-db` | Name des PostgreSQL-Containers |
|
||||||
|
| `DB_USER` | `kutt` | Datenbank-Benutzer |
|
||||||
|
| `DB_NAME` | `kutt` | Datenbank-Name |
|
||||||
|
| `MAX_AGE_DAYS` | `365` | Tage ohne Zugriff bis zur Löschung |
|
||||||
|
|
||||||
|
## Technische Details
|
||||||
|
|
||||||
|
- Gelöschte Links sind sofort aus der Kutt-Oberfläche verschwunden
|
||||||
|
- Zugehörige Visit-Statistiken werden automatisch mitgelöscht (`ON DELETE CASCADE`)
|
||||||
|
- Kutt nutzt Redis nur für Rate-Limiting, nicht als Link-Cache — es gibt kein Cache-Problem nach dem Löschen
|
||||||
|
- Die freigewordenen Short-Link-Adressen können danach wieder vergeben werden
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|||||||
63
kutt-links-cleanup.sh
Normal file
63
kutt-links-cleanup.sh
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Löscht anonyme Kutt-Links die seit %MAX_AGE_DAYS% Tagen nicht mehr aufgerufen wurden.
|
||||||
|
# Als Referenzdatum gilt der letzte Visit oder — falls nie aufgerufen — das Erstelldatum.
|
||||||
|
#
|
||||||
|
# Nutzung: Per Cron z.B. täglich ausführen.
|
||||||
|
# 0 3 * * * /home/docker-projekte/kutt/scripts/kutt-links-cleanup.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER="kutt-db"
|
||||||
|
DB_USER="kutt"
|
||||||
|
DB_NAME="kutt"
|
||||||
|
MAX_AGE_DAYS=365
|
||||||
|
DRY_RUN="${1:-}"
|
||||||
|
|
||||||
|
SQL_SELECT="
|
||||||
|
SELECT l.id, l.address, l.target,
|
||||||
|
COALESCE(MAX(v.created_at), l.created_at) AS last_activity
|
||||||
|
FROM links l
|
||||||
|
LEFT JOIN visits v ON v.link_id = l.id
|
||||||
|
WHERE l.user_id IS NULL
|
||||||
|
GROUP BY l.id
|
||||||
|
HAVING COALESCE(MAX(v.created_at), l.created_at) < NOW() - INTERVAL '${MAX_AGE_DAYS} days'
|
||||||
|
ORDER BY last_activity;
|
||||||
|
"
|
||||||
|
|
||||||
|
SQL_DELETE="
|
||||||
|
DELETE FROM links
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT l.id
|
||||||
|
FROM links l
|
||||||
|
LEFT JOIN visits v ON v.link_id = l.id
|
||||||
|
WHERE l.user_id IS NULL
|
||||||
|
GROUP BY l.id
|
||||||
|
HAVING COALESCE(MAX(v.created_at), l.created_at) < NOW() - INTERVAL '${MAX_AGE_DAYS} days'
|
||||||
|
);
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "$(date '+%Y-%m-%d %H:%M:%S') — Cleanup anonymer Links (älter als ${MAX_AGE_DAYS} Tage ohne Zugriff)"
|
||||||
|
|
||||||
|
if [ "$DRY_RUN" = "--dry-run" ]; then
|
||||||
|
echo "DRY RUN — es wird nichts gelöscht."
|
||||||
|
docker exec "$CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -c "$SQL_SELECT"
|
||||||
|
else
|
||||||
|
CANDIDATES=$(docker exec "$CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -t -A -c "
|
||||||
|
SELECT COUNT(*) FROM links l
|
||||||
|
LEFT JOIN visits v ON v.link_id = l.id
|
||||||
|
WHERE l.user_id IS NULL
|
||||||
|
GROUP BY l.id
|
||||||
|
HAVING COALESCE(MAX(v.created_at), l.created_at) < NOW() - INTERVAL '${MAX_AGE_DAYS} days';
|
||||||
|
" | wc -l)
|
||||||
|
|
||||||
|
if [ "$CANDIDATES" -eq 0 ]; then
|
||||||
|
echo "Keine abgelaufenen anonymen Links gefunden."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${CANDIDATES} Link(s) werden gelöscht..."
|
||||||
|
docker exec "$CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -c "$SQL_DELETE"
|
||||||
|
echo "Fertig."
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user