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'' + content += "" + + print(file_metadata) + + for filename in file_metadata.keys(): + content += "" + content += f'' + content += f'' + content += f'' + content += f'' + content += "" + + content += '
{heading}
{filename}{file_metadata[filename]["size"]}B{file_metadata[filename]["modified"]}{file_metadata[filename]["sha256"]}
' + + 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)