185 lines
4.9 KiB
Python
185 lines
4.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""SuperBeam Handlers
|
|
|
|
The handlers are automatically registered during the creation of the
|
|
:class:`SuperBeamServer` instance.
|
|
|
|
Each class handler method needs to be a ``staticmethod``. The callee will call
|
|
the `handle()` with the ``httpd`` instance of the :class:`SuperBeamServer` as
|
|
required argument.
|
|
"""
|
|
|
|
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'
|
|
|
|
@staticmethod
|
|
def handle(httpd):
|
|
raise Exception(f'Not implemented: Unable to handle {httpd} '
|
|
'({OctetStreamHandler.mimetype}')
|
|
|
|
|
|
class ChunkTemplateHandler(BaseTextHandler):
|
|
"""TODO
|
|
"""
|
|
URI = ('/', '/index.htm', 'index')
|
|
|
|
|
|
class ThumbHandler(object):
|
|
"""TODO
|
|
"""
|
|
mimetype = 'image/png'
|
|
URI = ('/getthumb',)
|
|
|
|
@staticmethod
|
|
def handle(httpd):
|
|
raise Exception(f'Not implemented: Unable to handle {httpd} '
|
|
'({ThumbHandler.mimetype}')
|
|
|
|
|
|
class LegacyListHandler(BaseTextHandler):
|
|
"""Legacy list handler for SuperBeam - plain text with file metadata
|
|
|
|
URI: ``/superlist``
|
|
"""
|
|
URI = ('/superlist',)
|
|
|
|
@staticmethod
|
|
def handle(httpd):
|
|
raise Exception(f'Not implemented: Unable to handle {httpd} '
|
|
'({LegacyListHandler.mimetype}')
|
|
|
|
|
|
class JsonListHandler(object):
|
|
"""Json List Handler - Metadata of served files as json
|
|
|
|
URI: ``/jsonlist``
|
|
"""
|
|
mimetype = 'application/json'
|
|
URI = ('/jsonlist',)
|
|
|
|
@staticmethod
|
|
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
|
|
|
|
@staticmethod
|
|
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):
|
|
"""TODO
|
|
"""
|
|
URI = ('/get/',)
|
|
|
|
|
|
class ZipFileHandler(object):
|
|
"""TODO
|
|
"""
|
|
mimetype = 'application/zip'
|
|
URI = ('/getzip',)
|
|
|
|
@staticmethod
|
|
def handle(httpd):
|
|
raise Exception('ZipFileHandler not implemeted.')
|
|
|
|
|
|
class SuperStreamHandler(OctetStreamHandler):
|
|
"""Serve SuperBeam data stream
|
|
|
|
Writes all files listed in `SuperBeamServer.files` as single stream. The
|
|
client needs to request ``/jsonlist`` or ``/superlist`` prior to the
|
|
download to be able to split the stream into single files.
|
|
|
|
URI: ``/getstream``
|
|
"""
|
|
URI = ('/getstream',)
|
|
|
|
@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):
|
|
"""TODO
|
|
"""
|
|
URI = ('*',)
|
|
|
|
|
|
class ApkRequestHandler(object):
|
|
"""TODO
|
|
"""
|
|
mimetype = 'application/vnd.android.package-archive'
|
|
URI = ('/getapk',)
|
|
|
|
@staticmethod
|
|
def handle(httpd):
|
|
raise Exception(f'Not implemented: Unable to handle {httpd} '
|
|
'({ApkRequestHandler.mimetype}')
|