132 lines
4.2 KiB
Python
Executable File
132 lines
4.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Cleanup daemon for expired files and pastes in Sharey
|
|
Runs continuously and checks for expired files at regular intervals
|
|
Supports both local storage and Backblaze B2 storage backends
|
|
"""
|
|
import os
|
|
import sys
|
|
import json
|
|
import sqlite3
|
|
import time
|
|
import signal
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
# Add the project root to Python path
|
|
project_root = Path(__file__).parent
|
|
sys.path.append(str(project_root))
|
|
|
|
from src.config import config
|
|
from src.storage import StorageManager
|
|
from expiry_db import ExpiryDatabase
|
|
|
|
# Configuration
|
|
CLEANUP_INTERVAL = 60 # seconds (1 minute)
|
|
CHECK_INTERVAL = 5 # seconds between startup checks
|
|
|
|
# Global flag for graceful shutdown
|
|
running = True
|
|
|
|
def signal_handler(signum, frame):
|
|
"""Handle shutdown signals gracefully"""
|
|
global running
|
|
print(f"\n🛑 Received signal {signum}, shutting down gracefully...")
|
|
running = False
|
|
|
|
def cleanup_expired_files():
|
|
"""Perform cleanup of expired files (same logic as cleanup script)"""
|
|
try:
|
|
# Initialize storage manager
|
|
storage_manager = StorageManager(config)
|
|
backend_info = storage_manager.get_backend_info()
|
|
|
|
# Initialize expiry database
|
|
expiry_db = ExpiryDatabase()
|
|
|
|
# Get expired files from database
|
|
expired_files = expiry_db.get_expired_files()
|
|
|
|
if not expired_files:
|
|
print(f"⏰ {datetime.now().strftime('%H:%M:%S')} - No expired files found")
|
|
return 0
|
|
|
|
print(f"🗑️ {datetime.now().strftime('%H:%M:%S')} - Found {len(expired_files)} expired files to delete")
|
|
|
|
deleted_count = 0
|
|
for file_info in expired_files:
|
|
file_path = file_info['file_path']
|
|
expires_at = file_info['expires_at']
|
|
|
|
try:
|
|
print(f"🗑️ Deleting: {file_path} (expired: {expires_at})")
|
|
|
|
# Delete from storage backend
|
|
if storage_manager.delete_file(file_path):
|
|
# Remove from expiry database
|
|
expiry_db.remove_file(file_path)
|
|
deleted_count += 1
|
|
print(f"✅ Deleted: {file_path}")
|
|
else:
|
|
print(f"❌ Failed to delete: {file_path}")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error deleting {file_path}: {e}")
|
|
|
|
if deleted_count > 0:
|
|
print(f"✅ Cleanup completed! Deleted {deleted_count} expired files")
|
|
|
|
return deleted_count
|
|
|
|
except Exception as e:
|
|
print(f"❌ Cleanup error: {e}")
|
|
return -1
|
|
|
|
def main():
|
|
"""Main daemon function"""
|
|
# Set up signal handlers for graceful shutdown
|
|
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
|
|
signal.signal(signal.SIGTERM, signal_handler) # systemctl stop
|
|
|
|
print("🧹 Sharey Cleanup Daemon")
|
|
print("=" * 40)
|
|
print(f"🚀 Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print(f"⏰ Cleanup interval: {CLEANUP_INTERVAL} seconds")
|
|
print(f"📁 Storage backend: {config.get('storage', {}).get('backend', 'b2')}")
|
|
print(f"🗄️ Database: expiry.db")
|
|
print("=" * 40)
|
|
print("Press Ctrl+C to stop")
|
|
print()
|
|
|
|
last_cleanup = 0
|
|
|
|
try:
|
|
while running:
|
|
current_time = time.time()
|
|
|
|
# Check if it's time for cleanup
|
|
if current_time - last_cleanup >= CLEANUP_INTERVAL:
|
|
try:
|
|
cleanup_expired_files()
|
|
last_cleanup = current_time
|
|
except Exception as e:
|
|
print(f"❌ Cleanup cycle failed: {e}")
|
|
|
|
# Sleep for a short interval to avoid busy waiting
|
|
time.sleep(CHECK_INTERVAL)
|
|
|
|
except KeyboardInterrupt:
|
|
pass # Handle Ctrl+C gracefully
|
|
|
|
print(f"\n🛑 Cleanup daemon stopped at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print("👋 Goodbye!")
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
main()
|
|
except Exception as e:
|
|
print(f"❌ Daemon failed to start: {e}")
|
|
sys.exit(1)
|
|
|
|
sys.exit(0)
|