From 5d727cf35972e8fbadbd498bb73a8e22466c4ba1 Mon Sep 17 00:00:00 2001
From: Michael Mikovsky <77305074+Astatin3@users.noreply.github.com>
Date: Sun, 25 May 2025 13:38:50 -0600
Subject: [PATCH] Add upload and download to python server
---
server/main.py | 105 ++++++++++++++++++++++++++++++++++++----
server/requirements.txt | 1 +
server/utils.py | 20 ++++++--
3 files changed, 111 insertions(+), 15 deletions(-)
diff --git a/server/main.py b/server/main.py
index 1f2f24b..457abd5 100644
--- a/server/main.py
+++ b/server/main.py
@@ -1,6 +1,10 @@
+from ast import mod
import os
import json
-from bottle import Bottle, run, get, static_file, response
+import hashlib
+from datetime import datetime
+from bottle import Bottle, run, get, put, static_file, response, request,HTTPResponse
+from random import SystemRandom
from utils import *
@@ -10,18 +14,52 @@ file_metadata = {}
def save_metadata():
global file_metadata
- write(METADATA_FILE, json.dumps(file_metadata))
+ write(METADATA_PATH4, json.dumps(file_metadata))
def load_metadata():
global file_metadata
- data = read(METADATA_FILE)
+ data = read(METADATA_PATH4)
if data is not None:
file_metadata = json.loads(data)
-# @app.route('/')
-# def list():
-# response.content_type = 'application/json'
-# return json.dumps(ls(DATA_ROOT))
+api_key = None
+cryptogen = SystemRandom()
+
+def aquire_key():
+ global api_key
+ global cryptogen
+
+ if api_key is None:
+ try:
+ api_key = read(API_KEY_PATH).decode("utf-8").strip()
+ except:
+ ran = cryptogen.randrange(10**80)
+ api_key = "%064x" % ran
+ write(API_KEY_PATH, api_key)
+
+@app.route('/')
+def list_html():
+ global file_metadata
+ load_metadata()
+
+ content = '
'
+ for heading in ['File', 'Size', 'Modified', 'Sha256']:
+ content += f'| {heading} | '
+ content += "
"
+
+ print(file_metadata)
+
+ for filename in file_metadata.keys():
+ content += ""
+ content += f'| {filename} | '
+ content += f'{file_metadata[filename]["size"]}B | '
+ content += f'{file_metadata[filename]["modified"]} | '
+ content += f'{file_metadata[filename]["sha256"]} | '
+ content += "
"
+
+ content += '
'
+
+ return content
@app.route('/api/metadata')
@@ -32,11 +70,58 @@ def metadata():
return json.dumps(file_metadata)
+@app.route('/api/', method='PUT')
+def upload(filename):
+ global api_key
+ try:
+ sentkey = request.headers[API_KEY_HEADER]
+ if sentkey != api_key:
+ return HTTPResponse(status=403, body=f"Invalid Key {sentkey}, {api_key}")
+ except:
+ return HTTPResponse(status=403, body="You must specify an 'api_key' header")
-# @app.route('/')
-# def hello(filename):
-# return static_file(DATA_ROOT, filename)
+
+ global file_metadata
+ load_metadata()
+
+ data = request.body.read()
+
+ try:
+ modified = request.headers[MODIFIED_HEADER]
+ except:
+ modified = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
+
+ sha256_hash = hashlib.sha256()
+ sha256_hash.update(data)
+
+ file_metadata[filename] = {
+ 'size': len(data),
+ 'modified': modified,
+ 'sha256': sha256_hash.hexdigest()
+ }
+
+ save_metadata()
+
+
+
+ write(os.path.join(DATA_ROOT, filename), data)
+ # save_metadata()
+ # response.content_type = 'application/json'
+ # return json.dumps(file_metadata)
+
+
+@app.route('/api/')
+def download(filename):
+
+ data = read(os.path.join(DATA_ROOT, filename))
+
+ if data is not None:
+ response.content_type = 'application/octet-stream'
+ return data
+ else:
+ HTTPResponse(status=404, body="File not found")
if __name__ == '__main__':
mkdir(DATA_ROOT)
+ aquire_key()
app.run(host='localhost', port=8080)
diff --git a/server/requirements.txt b/server/requirements.txt
index 310dc0b..7851c1b 100644
--- a/server/requirements.txt
+++ b/server/requirements.txt
@@ -1 +1,2 @@
bottle
+random
diff --git a/server/utils.py b/server/utils.py
index 44c1b5a..48114b7 100644
--- a/server/utils.py
+++ b/server/utils.py
@@ -1,9 +1,14 @@
import os
ROOT = os.path.dirname(__file__)
-METADATA_FILE = os.path.join(ROOT, 'metadata.json')
DATA_ROOT = os.path.join(os.path.dirname(__file__), 'data')
+METADATA_PATH4 = os.path.join(ROOT, 'metadata.json')
+API_KEY_PATH = os.path.join(ROOT, 'api_key.txt')
+
+MODIFIED_HEADER = 'modified'
+API_KEY_HEADER = 'api_key'
+
def mkdir(path):
if not os.path.exists(path):
os.makedirs(path)
@@ -18,13 +23,18 @@ def read(path):
if not os.path.exists(path):
return None
try:
- with open(path) as f:
+ with open(path, 'rb') as f:
return f.read()
- except:
+ except Exception as e:
+ print(f"Error reading file {path}: {e}")
return None
def write(path, data):
if not os.path.exists(path):
- with open(path, mode='a'): pass
- with open(path, 'w') as f:
+ with open(path, mode='ab'): pass
+
+ if isinstance(data, str):
+ data = str.encode(data)
+
+ with open(path, 'wb') as f:
f.write(data)