sbeam/src/SuperBeam/RequestHandlers.py

148 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
"""SuperBeam Handlers
SuperBeam Handlers define how to handle certain requests to the
:class:`SuperBeamServer`. Each handler needs to be registered in ThumbHandler
`SuperBeamServer.do_GET()` function within the ``paths`` variable and imported
in the top of the :module:`SuperBeam` module.
The handlers itself are defined in this module.
Each class handler method needs to be a ``staticmethod``. The callee will call
the `handle()` with the ``httpd`` instance of the :class:`SuperBeamServer`.
"""
import os
import json
import uuid
class BaseTextHandler(object):
mimetype = 'text/mime'
@staticmethod
def handle(httpd):
raise Exception(f'Not implemented: Unable to handle {httpd} '
'({BaseTextHandler.mimetype}')
class OctetStreamHandler(object):
mimetype = 'application/octet-stream'
def handle(httpd):
raise Exception(f'Not implemented: Unable to handle {httpd} '
'({StreamHandler.mimetype}')
class ChunkTemplateHandler(BaseTextHandler):
pass
class ThumbHandler(object):
mimetype = 'image/png'
def handle(httpd):
raise Exception(f'Not implemented: Unable to handle {httpd} '
'({ThumbHandler.mimetype}')
class LegacyListHandler(BaseTextHandler):
def handle(httpd):
# files = filess['files']
raise Exception(f'Not implemented: Unable to handle {httpd} '
'({LegacyListHandler.mimetype}')
class JsonListHandler(object):
mimetype = 'application/json'
def _make_jsonlist(files):
filestats = []
totalsize = 0
for file_ in files:
statinfo = os.stat(file_)
filename = os.path.basename(file_)
filepath = os.path.dirname(file_)
filestats.append({
'created': str(int(statinfo.st_ctime) * 1000),
'modified': str(int(statinfo.st_mtime) * 1000),
'name': filename,
'path': filepath,
'size': str(statinfo.st_size),
'type': "Image" # TODO dynamic
})
totalsize += statinfo.st_size
jsonlist = {
'device': 'ANYONMOUS',
'empty_dirs': [],
'files': filestats,
'uuid': str(uuid.uuid4()),
'version': 4130
}
return json.dumps(jsonlist), totalsize
def handle(httpd):
jsonlist, totalsize = JsonListHandler._make_jsonlist(httpd.files)
httpd.send_response(200)
httpd.send_header('Content-Type', 'application/json')
httpd.end_headers()
response = bytes(jsonlist, 'utf-8')
httpd.wfile.write(response)
httpd.total_file_size = totalsize
class SingleFileHandler(OctetStreamHandler):
pass
class ZipFileHandler(object):
mimetype = 'application/zip'
def handle(httpd):
raise Exception('ZipFileHandler not implemeted.')
class SuperStreamHandler(OctetStreamHandler):
@staticmethod
def _get_streamsize(files):
totalsize = 0
for file_ in files:
statinfo = os.stat(file_)
totalsize += statinfo.st_size
return totalsize
@staticmethod
def _stream_file_content(files):
for file_ in files:
with open(file_, 'rb') as f_handle:
yield f_handle.read()
@staticmethod
def handle(httpd):
httpd.send_response(200)
httpd.send_header('ylfrettub', '1')
httpd.send_header('Content-Type', 'application/octet-stream')
httpd.send_header('Content-Length',
str(SuperStreamHandler._get_streamsize(httpd.files)))
httpd.send_header('Content-Disposition', 'attachment; '
'filename="RedHotChillyStream"')
httpd.end_headers()
for chunk in SuperStreamHandler._stream_file_content(httpd.files):
httpd.wfile.write(chunk)
class AssetHandler(OctetStreamHandler):
pass
class ApkRequestHandler(object):
mimetype = 'application/vnd.android.package-archive'
def handle(httpd):
raise Exception(f'Not implemented: Unable to handle {httpd} '
'({ApkRequestHandler.mimetype}')