small fixes
This commit is contained in:
@@ -54,8 +54,16 @@ UPLOAD_FOLDER = settings["upload_folder"]
|
|||||||
MAX_FILE_AGE_DAYS = settings["max_file_age_days"]
|
MAX_FILE_AGE_DAYS = settings["max_file_age_days"]
|
||||||
MAX_FILE_SIZE_BYTES = settings["max_file_size_bytes"]
|
MAX_FILE_SIZE_BYTES = settings["max_file_size_bytes"]
|
||||||
|
|
||||||
|
# Ensure upload folder exists and has proper permissions
|
||||||
if not os.path.exists(UPLOAD_FOLDER):
|
if not os.path.exists(UPLOAD_FOLDER):
|
||||||
os.makedirs(UPLOAD_FOLDER)
|
try:
|
||||||
|
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
||||||
|
# Set permissions to 755 (rwxr-xr-x)
|
||||||
|
os.chmod(UPLOAD_FOLDER, 0o755)
|
||||||
|
print(f"[INFO] Created upload directory: {UPLOAD_FOLDER}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ERROR] Failed to create upload directory: {str(e)}")
|
||||||
|
raise
|
||||||
|
|
||||||
# ===== Cryptographic Functions =====
|
# ===== Cryptographic Functions =====
|
||||||
def derive_key(password: str, salt: bytes) -> bytes:
|
def derive_key(password: str, salt: bytes) -> bytes:
|
||||||
@@ -140,6 +148,7 @@ def log_admin_event(message: str):
|
|||||||
# ===== File Management =====
|
# ===== File Management =====
|
||||||
def cleanup_expired_files():
|
def cleanup_expired_files():
|
||||||
"""Remove files older than MAX_FILE_AGE_DAYS."""
|
"""Remove files older than MAX_FILE_AGE_DAYS."""
|
||||||
|
try:
|
||||||
now = datetime.datetime.now(UTC)
|
now = datetime.datetime.now(UTC)
|
||||||
for fname in os.listdir(UPLOAD_FOLDER):
|
for fname in os.listdir(UPLOAD_FOLDER):
|
||||||
if fname.endswith(".enc") or fname.endswith(".json"):
|
if fname.endswith(".enc") or fname.endswith(".json"):
|
||||||
@@ -152,6 +161,8 @@ def cleanup_expired_files():
|
|||||||
print(f"[INFO] Deleted expired file: {fname}")
|
print(f"[INFO] Deleted expired file: {fname}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[ERROR] Could not check/delete file {fname}: {e}")
|
print(f"[ERROR] Could not check/delete file {fname}: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ERROR] Failed to cleanup expired files: {str(e)}")
|
||||||
|
|
||||||
# ===== Route Handlers =====
|
# ===== Route Handlers =====
|
||||||
@app.route("/", methods=["GET", "POST"])
|
@app.route("/", methods=["GET", "POST"])
|
||||||
@@ -415,7 +426,16 @@ def admin_page():
|
|||||||
uptime_str = "Unavailable"
|
uptime_str = "Unavailable"
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
# Linux uptime using uptime command
|
# Try reading from /proc/uptime first
|
||||||
|
with open('/proc/uptime', 'r') as f:
|
||||||
|
uptime_seconds = float(f.readline().split()[0])
|
||||||
|
days = int(uptime_seconds // 86400)
|
||||||
|
hours = int((uptime_seconds % 86400) // 3600)
|
||||||
|
minutes = int((uptime_seconds % 3600) // 60)
|
||||||
|
uptime_str = f"{days} days, {hours} hours, {minutes} minutes"
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
# Fallback to uptime command if /proc/uptime fails
|
||||||
uptime_str = subprocess.check_output("uptime -p", shell=True).decode().strip()
|
uptime_str = subprocess.check_output("uptime -p", shell=True).decode().strip()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[ERROR] Failed to get Linux uptime: {str(e)}")
|
print(f"[ERROR] Failed to get Linux uptime: {str(e)}")
|
||||||
@@ -553,24 +573,80 @@ def admin_update_server():
|
|||||||
return jsonify({"error": "Unauthorized"}), 401
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
try:
|
try:
|
||||||
repo_dir = os.path.abspath(os.path.dirname(__file__))
|
# Get the absolute path of the current directory
|
||||||
|
current_dir = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
# Check if we're in a git repository
|
# Try to find git executable
|
||||||
if not os.path.exists(os.path.join(repo_dir, ".git")):
|
git_paths = [
|
||||||
return jsonify({"error": "Not a git repository"}), 400
|
"/usr/bin/git", # Standard Debian path
|
||||||
|
"/usr/local/bin/git",
|
||||||
|
"/bin/git",
|
||||||
|
"git" # Fallback to PATH
|
||||||
|
]
|
||||||
|
|
||||||
# Execute git commands
|
git_cmd = None
|
||||||
subprocess.run(["git", "fetch"], cwd=repo_dir, check=True)
|
for path in git_paths:
|
||||||
subprocess.run(["git", "reset", "--hard", "origin/main"], cwd=repo_dir, check=True)
|
if os.path.exists(path) or path == "git":
|
||||||
subprocess.run(["git", "pull"], cwd=repo_dir, check=True)
|
try:
|
||||||
|
# Test if git is executable
|
||||||
|
subprocess.run([path, "--version"], check=True, capture_output=True)
|
||||||
|
git_cmd = path
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
return jsonify({"message": "Server updated successfully from GitHub!"}), 200
|
if not git_cmd:
|
||||||
|
return jsonify({"error": "Git executable not found. Please ensure git is installed and accessible."}), 500
|
||||||
|
|
||||||
|
# Try to find the git repository by checking parent directories
|
||||||
|
repo_dir = current_dir
|
||||||
|
max_depth = 5 # Limit how far up we'll look
|
||||||
|
found_git = False
|
||||||
|
|
||||||
|
for _ in range(max_depth):
|
||||||
|
git_dir = os.path.join(repo_dir, ".git")
|
||||||
|
if os.path.exists(git_dir):
|
||||||
|
found_git = True
|
||||||
|
break
|
||||||
|
parent_dir = os.path.dirname(repo_dir)
|
||||||
|
if parent_dir == repo_dir: # We've reached the root directory
|
||||||
|
break
|
||||||
|
repo_dir = parent_dir
|
||||||
|
|
||||||
|
if not found_git:
|
||||||
|
return jsonify({
|
||||||
|
"error": "Git repository not found. Current directory: " + current_dir,
|
||||||
|
"details": "Please ensure the application is running from within the git repository directory."
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Execute git commands with proper error handling
|
||||||
|
try:
|
||||||
|
# Fetch latest changes
|
||||||
|
fetch_result = subprocess.run([git_cmd, "fetch"], cwd=repo_dir, check=True, capture_output=True, text=True)
|
||||||
|
|
||||||
|
# Reset to origin/main
|
||||||
|
reset_result = subprocess.run([git_cmd, "reset", "--hard", "origin/main"], cwd=repo_dir, check=True, capture_output=True, text=True)
|
||||||
|
|
||||||
|
# Pull latest changes
|
||||||
|
pull_result = subprocess.run([git_cmd, "pull"], cwd=repo_dir, check=True, capture_output=True, text=True)
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"message": "Server updated successfully from GitHub!",
|
||||||
|
"details": {
|
||||||
|
"fetch": fetch_result.stdout,
|
||||||
|
"reset": reset_result.stdout,
|
||||||
|
"pull": pull_result.stdout
|
||||||
|
}
|
||||||
|
}), 200
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
print(f"[ERROR] Git operation failed: {str(e)}")
|
error_msg = f"Git operation failed: {e.stderr if e.stderr else e.stdout}"
|
||||||
return jsonify({"error": f"Git operation failed: {str(e)}"}), 500
|
print(f"[ERROR] {error_msg}")
|
||||||
|
return jsonify({"error": error_msg}), 500
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[ERROR] Update failed: {str(e)}")
|
error_msg = f"Update failed: {str(e)}"
|
||||||
return jsonify({"error": f"Update failed: {str(e)}"}), 500
|
print(f"[ERROR] {error_msg}")
|
||||||
|
return jsonify({"error": error_msg}), 500
|
||||||
|
|
||||||
# ===== Sitemap and Robots =====
|
# ===== Sitemap and Robots =====
|
||||||
@app.route("/sitemap", methods=["GET"])
|
@app.route("/sitemap", methods=["GET"])
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ footer {
|
|||||||
display: none;
|
display: none;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
max-width: 300px;
|
max-width: 500px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
|
|||||||
Reference in New Issue
Block a user