Commit c6e76146 authored by Titouan Soulard's avatar Titouan Soulard

First working version: allows downloading binaries

parents
__pycache__
*.key
.env
# Gakeshadeba – Simple ShaCache and ShaDir implementation in plain Python
import hashlib
import json
import os
from base64 import b64encode, b64decode
from OpenSSL import crypto
class Gakeshadeba():
def __init__(self, content_dir, sr_file):
self.content_dir = content_dir
self.sr_file = sr_file
self.sr_md5_dir = {}
self.file_sha512_dir = {}
self.key = None
def set_signing_key(self, key_file_name):
with open(key_file_name) as key_file:
self.key = crypto.load_privatekey(crypto.FILETYPE_PEM, key_file.read())
def build_sr_dir(self):
r_file_sha512_dir = dict([reversed(i) for i in self.file_sha512_dir.items()])
sr_file_handle = open(self.sr_file, "r")
sr_file_json = sr_file_handle.read()
sr_file_content = json.loads(sr_file_json)
for sr_el in sr_file_content:
sr = sr_el["software_release"]
file = sr_el["cache_file"]
sr_md5 = hashlib.md5(sr.encode("utf8"))
file_sha512 = r_file_sha512_dir.get(file)
if file_sha512:
entry = {
"sha512": file_sha512,
"software_url": sr,
# Should be flexible
"software_root": sr_el["software_root"],
"multiarch": sr_el["multiarch"],
"os": sr_el["os"],
# Useless fields, don't ask.
"file": "file",
"urlmd5": "urlmd5",
}
entry_json = json.dumps(entry)
entry_signature = b64encode(crypto.sign(self.key, entry_json, "sha1")).decode()
self.sr_md5_dir[sr_md5.hexdigest()] = [entry_json, entry_signature]
def build_file_cache(self):
for file_name in os.listdir(self.content_dir):
fullpath = os.path.join(self.content_dir, file_name)
sha512 = hashlib.sha512()
with open(fullpath, "rb") as handle:
for chunk in iter(lambda: handle.read(4096), b""):
sha512.update(chunk)
self.file_sha512_dir[sha512.hexdigest()] = file_name
def serve_sr_dir_entry(self, md5):
dir_content = self.sr_md5_dir.get(md5)
if dir_content:
return json.dumps([self.sr_md5_dir[md5]])
else:
return None
def find_file_cache_entry(self, sha512):
file_name = self.file_sha512_dir.get(sha512)
if file_name:
return file_name
else:
return None
from flask import Flask, send_from_directory
from gakeshadeba import Gakeshadeba
content_dir = "./files"
gsha = Gakeshadeba("./files", "./sr_list.json")
gsha.set_signing_key("tmp.key")
gsha.build_file_cache()
gsha.build_sr_dir()
app = Flask(__name__)
@app.route("/bdir/<md5>")
def binary_dir(md5):
return gsha.serve_sr_dir_entry(md5)
@app.route("/bcache/<sha512>")
def binary_cache(sha512):
file_name = gsha.find_file_cache_entry(sha512)
if file_name is None:
return "Not found\n", 404
return send_from_directory(content_dir, file_name, as_attachment=True)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment