Merge branch 'master' of git.goatpr0n.de:jpk/sbeam
* 'master' of git.goatpr0n.de:jpk/sbeam: requirements Remove tui poc code from master Catch connection errors Directory structure refactoring Fixed setup script Updated documentation Request jsonlist instead of superlist Automatic request handler route registration Fixed Instance name Added version to setup and sbeam
This commit is contained in:
commit
ab3325616c
|
@ -1,6 +1,9 @@
|
||||||
*.pyc
|
*.pyc
|
||||||
*.egg-info
|
*.egg-info
|
||||||
|
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
doc/
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
venv/
|
venv/
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -5,8 +5,8 @@
|
||||||
# from the environment for the first two.
|
# from the environment for the first two.
|
||||||
SPHINXOPTS ?=
|
SPHINXOPTS ?=
|
||||||
SPHINXBUILD ?= sphinx-build
|
SPHINXBUILD ?= sphinx-build
|
||||||
SOURCEDIR = source
|
SOURCEDIR = doc/source
|
||||||
BUILDDIR = build
|
BUILDDIR = doc
|
||||||
|
|
||||||
# Put it first so that "make" without argument is like "make help".
|
# Put it first so that "make" without argument is like "make help".
|
||||||
help:
|
help:
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#
|
#
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
sys.path.insert(0, os.path.abspath('../src'))
|
sys.path.insert(0, os.path.abspath('../../src'))
|
||||||
|
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
@ -22,10 +22,10 @@ copyright = '2019, Julian Knauer'
|
||||||
author = 'Julian Knauer'
|
author = 'Julian Knauer'
|
||||||
|
|
||||||
# The short X.Y version
|
# The short X.Y version
|
||||||
version = '0.3'
|
version = '0.5'
|
||||||
|
|
||||||
# The full version, including alpha/beta/rc tags
|
# The full version, including alpha/beta/rc tags
|
||||||
release = '0.3'
|
release = 'alpha'
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
|
@ -6,11 +6,24 @@
|
||||||
Welcome to SuperBeam documentation!
|
Welcome to SuperBeam documentation!
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
|
|
||||||
|
Command line tool
|
||||||
|
-----------------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
|
|
||||||
sbeam
|
sbeam
|
||||||
|
|
||||||
|
|
||||||
|
SuperBeam Development
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Contents:
|
||||||
|
|
||||||
SuperBeam
|
SuperBeam
|
||||||
SuperBeam.RequestHandlers
|
SuperBeam.RequestHandlers
|
||||||
|
|
4
make.bat
4
make.bat
|
@ -7,8 +7,8 @@ REM Command file for Sphinx documentation
|
||||||
if "%SPHINXBUILD%" == "" (
|
if "%SPHINXBUILD%" == "" (
|
||||||
set SPHINXBUILD=sphinx-build
|
set SPHINXBUILD=sphinx-build
|
||||||
)
|
)
|
||||||
set SOURCEDIR=source
|
set SOURCEDIR=doc\source
|
||||||
set BUILDDIR=build
|
set BUILDDIR=doc
|
||||||
|
|
||||||
if "%1" == "" goto help
|
if "%1" == "" goto help
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
certifi==2019.6.16
|
|
||||||
chardet==3.0.4
|
|
||||||
Click==7.0
|
Click==7.0
|
||||||
idna==2.8
|
|
||||||
PyQRCode==1.2.1
|
PyQRCode==1.2.1
|
||||||
requests==2.22.0
|
requests==2.22.0
|
||||||
urllib3==1.25.3
|
|
||||||
|
|
12
setup.py
12
setup.py
|
@ -1,10 +1,18 @@
|
||||||
|
import sys
|
||||||
from setuptools import setup, find_namespace_packages
|
from setuptools import setup, find_namespace_packages
|
||||||
|
from distutils.util import convert_path
|
||||||
|
|
||||||
|
sys.path.insert(0, 'src/')
|
||||||
|
|
||||||
|
main_ns = {}
|
||||||
|
ver_path = convert_path('src/sbeam.py')
|
||||||
|
with open(ver_path) as ver_file:
|
||||||
|
exec(ver_file.read(), main_ns)
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="sbeam",
|
name="sbeam",
|
||||||
description="",
|
description="SuperBeam CLI Client",
|
||||||
version="0.3",
|
version=main_ns['__VERSION__'],
|
||||||
author="JayPiKay",
|
author="JayPiKay",
|
||||||
author_email="jpk+python@goatpr0n.de",
|
author_email="jpk+python@goatpr0n.de",
|
||||||
url='https://git.goatpr0n.de/',
|
url='https://git.goatpr0n.de/',
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""SuperBeam Handlers
|
"""SuperBeam Handlers
|
||||||
|
|
||||||
SuperBeam Handlers define how to handle certain requests to the
|
The handlers are automatically registered during the creation of the
|
||||||
`SuperBeamServer`. Each handler needs to be registered in ThumbHandler
|
:class:`SuperBeamServer` instance.
|
||||||
`SuperBeamServer.do_GET()` function within the ``paths`` variable and imported
|
|
||||||
in the top of the :mod:`SuperBeam` module.
|
|
||||||
|
|
||||||
The handlers itself are defined in this module.
|
|
||||||
|
|
||||||
Each class handler method needs to be a ``staticmethod``. The callee will call
|
Each class handler method needs to be a ``staticmethod``. The callee will call
|
||||||
the `handle()` with the ``httpd`` instance of the :class:`SuperBeamServer`.
|
the `handle()` with the ``httpd`` instance of the :class:`SuperBeamServer` as
|
||||||
|
required argument.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -33,15 +30,20 @@ class OctetStreamHandler(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def handle(httpd):
|
def handle(httpd):
|
||||||
raise Exception(f'Not implemented: Unable to handle {httpd} '
|
raise Exception(f'Not implemented: Unable to handle {httpd} '
|
||||||
'({StreamHandler.mimetype}')
|
'({OctetStreamHandler.mimetype}')
|
||||||
|
|
||||||
|
|
||||||
class ChunkTemplateHandler(BaseTextHandler):
|
class ChunkTemplateHandler(BaseTextHandler):
|
||||||
pass
|
"""TODO
|
||||||
|
"""
|
||||||
|
URI = ('/', '/index.htm', 'index')
|
||||||
|
|
||||||
|
|
||||||
class ThumbHandler(object):
|
class ThumbHandler(object):
|
||||||
|
"""TODO
|
||||||
|
"""
|
||||||
mimetype = 'image/png'
|
mimetype = 'image/png'
|
||||||
|
URI = ('/getthumb',)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def handle(httpd):
|
def handle(httpd):
|
||||||
|
@ -54,7 +56,6 @@ class LegacyListHandler(BaseTextHandler):
|
||||||
|
|
||||||
URI: ``/superlist``
|
URI: ``/superlist``
|
||||||
"""
|
"""
|
||||||
|
|
||||||
URI = ('/superlist',)
|
URI = ('/superlist',)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -110,11 +111,16 @@ class JsonListHandler(object):
|
||||||
|
|
||||||
|
|
||||||
class SingleFileHandler(OctetStreamHandler):
|
class SingleFileHandler(OctetStreamHandler):
|
||||||
pass
|
"""TODO
|
||||||
|
"""
|
||||||
|
URI = ('/get/',)
|
||||||
|
|
||||||
|
|
||||||
class ZipFileHandler(object):
|
class ZipFileHandler(object):
|
||||||
|
"""TODO
|
||||||
|
"""
|
||||||
mimetype = 'application/zip'
|
mimetype = 'application/zip'
|
||||||
|
URI = ('/getzip',)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def handle(httpd):
|
def handle(httpd):
|
||||||
|
@ -130,6 +136,7 @@ class SuperStreamHandler(OctetStreamHandler):
|
||||||
|
|
||||||
URI: ``/getstream``
|
URI: ``/getstream``
|
||||||
"""
|
"""
|
||||||
|
URI = ('/getstream',)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_streamsize(files):
|
def _get_streamsize(files):
|
||||||
|
@ -160,11 +167,16 @@ class SuperStreamHandler(OctetStreamHandler):
|
||||||
|
|
||||||
|
|
||||||
class AssetHandler(OctetStreamHandler):
|
class AssetHandler(OctetStreamHandler):
|
||||||
pass
|
"""TODO
|
||||||
|
"""
|
||||||
|
URI = ('*',)
|
||||||
|
|
||||||
|
|
||||||
class ApkRequestHandler(object):
|
class ApkRequestHandler(object):
|
||||||
|
"""TODO
|
||||||
|
"""
|
||||||
mimetype = 'application/vnd.android.package-archive'
|
mimetype = 'application/vnd.android.package-archive'
|
||||||
|
URI = ('/getapk',)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def handle(httpd):
|
def handle(httpd):
|
||||||
|
|
|
@ -8,12 +8,8 @@ import socket
|
||||||
import struct
|
import struct
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
|
import inspect
|
||||||
from SuperBeam.RequestHandlers import (
|
from SuperBeam import RequestHandlers
|
||||||
ChunkTemplateHandler, ThumbHandler, ApkRequestHandler, LegacyListHandler,
|
|
||||||
SingleFileHandler, ZipFileHandler, SuperStreamHandler, AssetHandler,
|
|
||||||
JsonListHandler
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SuperBeamServer(BaseHTTPRequestHandler):
|
class SuperBeamServer(BaseHTTPRequestHandler):
|
||||||
|
@ -24,6 +20,9 @@ class SuperBeamServer(BaseHTTPRequestHandler):
|
||||||
Class is built on top of :mod:`http.server.BaseHTTPRequestHandler` as
|
Class is built on top of :mod:`http.server.BaseHTTPRequestHandler` as
|
||||||
simple http server.
|
simple http server.
|
||||||
|
|
||||||
|
During initialization, the RequestHandlers are registered as routable
|
||||||
|
paths.
|
||||||
|
|
||||||
Call :func:`serve_forever()` to start the HTTP server. The mainloop will
|
Call :func:`serve_forever()` to start the HTTP server. The mainloop will
|
||||||
serve a list of files given as argument to :func:`serve_forever()`.
|
serve a list of files given as argument to :func:`serve_forever()`.
|
||||||
|
|
||||||
|
@ -37,9 +36,14 @@ class SuperBeamServer(BaseHTTPRequestHandler):
|
||||||
files (list): list of files served by the `SuperBeamServer`.
|
files (list): list of files served by the `SuperBeamServer`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, debug=False, *args, **kwargs):
|
def __init__(self, request, client_address, server, debug=False):
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
super(SuperBeamServer, self).__init__()
|
self.routes = {}
|
||||||
|
for _, cls in inspect.getmembers(RequestHandlers, inspect.isclass):
|
||||||
|
if hasattr(cls, 'URI'):
|
||||||
|
for route in cls.URI:
|
||||||
|
self.routes[route] = cls
|
||||||
|
super(SuperBeamServer, self).__init__(request, client_address, server)
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
"""GET request handler
|
"""GET request handler
|
||||||
|
@ -53,26 +57,12 @@ class SuperBeamServer(BaseHTTPRequestHandler):
|
||||||
exists - forwarded to :func:`respond()`, where the request gets
|
exists - forwarded to :func:`respond()`, where the request gets
|
||||||
answered.
|
answered.
|
||||||
"""
|
"""
|
||||||
# TODO Add globbing
|
|
||||||
if self.debug:
|
if self.debug:
|
||||||
print(threading.current_thread())
|
print(threading.current_thread())
|
||||||
paths = {
|
|
||||||
'index': ChunkTemplateHandler,
|
|
||||||
'/': ChunkTemplateHandler,
|
|
||||||
'/index.htm': ChunkTemplateHandler, # TODO handler2
|
|
||||||
'/getthumb': ThumbHandler,
|
|
||||||
'/light': ChunkTemplateHandler, # TODO handler2
|
|
||||||
'/superlist': LegacyListHandler,
|
|
||||||
'/jsonlist': JsonListHandler,
|
|
||||||
'/get/': SingleFileHandler,
|
|
||||||
'/getapk': ApkRequestHandler,
|
|
||||||
'/getzip': ZipFileHandler,
|
|
||||||
'/getstream': SuperStreamHandler,
|
|
||||||
'*': AssetHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.path in paths: # TODO startswith key check
|
# TODO Add globbing
|
||||||
self.respond(paths[self.path])
|
if self.path in self.routes: # TODO startswith key check
|
||||||
|
self.respond(self.routes[self.path])
|
||||||
|
|
||||||
def respond(self, handler):
|
def respond(self, handler):
|
||||||
"""Respond client with request with registered handler.
|
"""Respond client with request with registered handler.
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
import asyncio
|
|
||||||
|
|
||||||
import urwid
|
|
||||||
|
|
||||||
import weakref
|
|
||||||
|
|
||||||
import struct
|
|
||||||
import base64
|
|
||||||
import pyqrcode
|
|
||||||
import socket
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
|
|
||||||
|
|
||||||
def unhandled(key):
|
|
||||||
if key == 'ctrl c':
|
|
||||||
raise urwid.ExitMainLoop
|
|
||||||
|
|
||||||
|
|
||||||
def get_primary_ip():
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
try:
|
|
||||||
# doesn't even have to be reachable
|
|
||||||
s.connect(('10.255.255.255', 1))
|
|
||||||
IP = s.getsockname()[0]
|
|
||||||
except Exception as exc:
|
|
||||||
print(exc)
|
|
||||||
IP = '127.0.0.1'
|
|
||||||
finally:
|
|
||||||
s.close()
|
|
||||||
return IP
|
|
||||||
|
|
||||||
|
|
||||||
def get_qrcode():
|
|
||||||
primary_ip = get_primary_ip()
|
|
||||||
octets = [1]
|
|
||||||
octets.extend([int(_) for _ in primary_ip.split('.')[::-1]])
|
|
||||||
url = 'http://superbe.am/q?' + base64.b64encode(
|
|
||||||
struct.pack('BBBBB', *octets)
|
|
||||||
).decode('utf-8')
|
|
||||||
return pyqrcode.create(url)
|
|
||||||
|
|
||||||
|
|
||||||
class ClientModel(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.clients = ['127.0.0.1', '192.168.178.34']
|
|
||||||
|
|
||||||
def get_clients(self):
|
|
||||||
return self.clients
|
|
||||||
|
|
||||||
|
|
||||||
class SuperBeamView(urwid.WidgetWrap):
|
|
||||||
|
|
||||||
palette = [
|
|
||||||
('body', 'black', 'light gray', 'standout'),
|
|
||||||
('header', 'white', 'dark red', 'bold'),
|
|
||||||
('screen edge', 'light blue', 'dark cyan'),
|
|
||||||
('main shadow', 'dark gray', 'black'),
|
|
||||||
('line', 'black', 'light gray', 'standout'),
|
|
||||||
('bg background', 'light gray', 'black'),
|
|
||||||
('bg 1', 'black', 'dark blue', 'standout'),
|
|
||||||
('bg 1 smooth', 'dark blue', 'black'),
|
|
||||||
('bg 2', 'black', 'dark cyan', 'standout'),
|
|
||||||
('bg 2 smooth', 'dark cyan', 'black'),
|
|
||||||
('button normal', 'light gray', 'dark blue', 'standout'),
|
|
||||||
('button select', 'white', 'dark green'),
|
|
||||||
('line', 'black', 'light gray', 'standout'),
|
|
||||||
('pg normal', 'white', 'black', 'standout'),
|
|
||||||
('pg complete', 'white', 'dark magenta'),
|
|
||||||
('pg smooth', 'dark magenta', 'black'),
|
|
||||||
('qr code', 'black', 'white'),
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(self, controller):
|
|
||||||
self.controller = controller
|
|
||||||
self.client_model = ClientModel()
|
|
||||||
urwid.WidgetWrap.__init__(self, self.main_window())
|
|
||||||
|
|
||||||
def main_shadow(self, w):
|
|
||||||
bg = urwid.AttrWrap(urwid.SolidFill(u"\u2592"), 'screen edge')
|
|
||||||
shadow = urwid.AttrWrap(urwid.SolidFill(u" "), 'main shadow')
|
|
||||||
|
|
||||||
bg = urwid.Overlay(shadow, bg,
|
|
||||||
('fixed left', 3), ('fixed right', 1),
|
|
||||||
('fixed top', 2), ('fixed bottom', 1))
|
|
||||||
w = urwid.Overlay(w, bg,
|
|
||||||
('fixed left', 2), ('fixed right', 3),
|
|
||||||
('fixed top', 1), ('fixed bottom', 2))
|
|
||||||
return w
|
|
||||||
|
|
||||||
def update_clock(self, widget_ref):
|
|
||||||
widget = widget_ref()
|
|
||||||
if not widget:
|
|
||||||
return
|
|
||||||
widget.set_text(datetime.now().isoformat())
|
|
||||||
loop.call_later(1, self.update_clock, widget_ref)
|
|
||||||
|
|
||||||
def qrcode(self):
|
|
||||||
qrcode = get_qrcode().terminal()
|
|
||||||
qrcode = qrcode.replace('\x1b[0m\x1b[49m ', '██')
|
|
||||||
qrcode = qrcode.replace('\x1b[0m\x1b[7m ', ' ')
|
|
||||||
qrcode = qrcode.replace('\x1b[0m', '')
|
|
||||||
qrcode = qrcode.replace('\x1b[7m', '')
|
|
||||||
widgets = []
|
|
||||||
for row in qrcode.split('\n'):
|
|
||||||
widgets.append(urwid.AttrWrap(urwid.Text(row), 'qr code'))
|
|
||||||
w = urwid.Pile(widgets)
|
|
||||||
return urwid.Filler(urwid.AttrWrap(w, 'body'))
|
|
||||||
|
|
||||||
def client_list(self):
|
|
||||||
clients = []
|
|
||||||
for client in self.client_model.get_clients():
|
|
||||||
clients.append(urwid.Filler(urwid.AttrWrap(urwid.Text(client),
|
|
||||||
'line')))
|
|
||||||
return urwid.Pile([(1, _) for _ in clients])
|
|
||||||
|
|
||||||
def main_window(self):
|
|
||||||
header = urwid.AttrWrap(urwid.Text('SuperBeam Tui'), 'header')
|
|
||||||
clock = urwid.Text('')
|
|
||||||
self.update_clock(weakref.ref(clock))
|
|
||||||
footer = urwid.AttrWrap(clock, 'header')
|
|
||||||
|
|
||||||
body = urwid.Pile([(44, self.qrcode()), self.client_list()])
|
|
||||||
|
|
||||||
window = urwid.Frame(body, header, footer)
|
|
||||||
return self.main_shadow(window)
|
|
||||||
|
|
||||||
|
|
||||||
class SuperBeamController(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.model = ClientModel()
|
|
||||||
self.view = SuperBeamView(self)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
# self.loop = urwid.MainLoop(self.view, self.view.palette)
|
|
||||||
self.loop = urwid.MainLoop(
|
|
||||||
self.view, self.view.palette,
|
|
||||||
event_loop=urwid.AsyncioEventLoop(loop=loop),
|
|
||||||
unhandled_input=unhandled
|
|
||||||
)
|
|
||||||
self.loop.run()
|
|
||||||
|
|
||||||
|
|
||||||
def run():
|
|
||||||
screen = urwid.raw_display.Screen()
|
|
||||||
size = screen.get_cols_rows()
|
|
||||||
if size[0] < 87 or size[1] < 58:
|
|
||||||
raise Exception('Not enough screen space to render QR code.')
|
|
||||||
else:
|
|
||||||
SuperBeamController().run()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
run()
|
|
40
src/sbeam.py
40
src/sbeam.py
|
@ -6,24 +6,6 @@
|
||||||
#
|
#
|
||||||
# Distributed under terms of the MIT license.
|
# Distributed under terms of the MIT license.
|
||||||
|
|
||||||
"""
|
|
||||||
> GET /getstream HTTP/1.1
|
|
||||||
> Host: 192.168.178.50:8080
|
|
||||||
> User-Agent: sbeam
|
|
||||||
> Accept: */*
|
|
||||||
>
|
|
||||||
* Mark bundle as not supporting multiuse
|
|
||||||
< HTTP/1.1 200 OK
|
|
||||||
< ylfrettub: 1
|
|
||||||
< Content-Disposition: attachment; filename="RedHotChillyStream"
|
|
||||||
< Date: Fri, 09 Aug 2019 12:57:20 GMT
|
|
||||||
< Content-Length: 8137967
|
|
||||||
< Content-Type: application/octet-stream
|
|
||||||
|
|
||||||
Server QR Code = http://superbe.am/q?ATKyqMA=
|
|
||||||
Base64 = 01 32 b2 a8 c0 = 01 50 178 168 192
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import click
|
import click
|
||||||
import requests
|
import requests
|
||||||
|
@ -31,7 +13,11 @@ import requests
|
||||||
import SuperBeam
|
import SuperBeam
|
||||||
|
|
||||||
|
|
||||||
|
__VERSION__ = '0.5'
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
|
@click.version_option(version=__VERSION__, prog_name='SuperBeam CLI')
|
||||||
def cli():
|
def cli():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -54,12 +40,12 @@ def serve(recursive, filename):
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@click.argument('host', default='127.0.0.1')
|
@click.argument('host', default='127.0.0.1')
|
||||||
def superlist(host):
|
def jsonlist(host):
|
||||||
"""Fetch superlist from HOST running SupberBeam.
|
"""Fetch jsonlist from HOST running SupberBeam.
|
||||||
|
|
||||||
HOST is the IP of the SuperBeam server.
|
HOST is the IP of the SuperBeam server.
|
||||||
"""
|
"""
|
||||||
with requests.get(f'http://{host}:8080/superlist',
|
with requests.get(f'http://{host}:8080/jsonlist',
|
||||||
headers={'User-Agent': 'sbeam'}) as response:
|
headers={'User-Agent': 'sbeam'}) as response:
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
return response.text.split('\n')
|
return response.text.split('\n')
|
||||||
|
@ -101,8 +87,8 @@ def receive(host, destination):
|
||||||
fullpath = os.path.join(destination, filepath[1:])
|
fullpath = os.path.join(destination, filepath[1:])
|
||||||
os.makedirs(fullpath, exist_ok=True)
|
os.makedirs(fullpath, exist_ok=True)
|
||||||
with open(os.path.join(fullpath, filename), 'wb') as fd:
|
with open(os.path.join(fullpath, filename), 'wb') as fd:
|
||||||
# TODO split filesize in chunks with remainder
|
|
||||||
fd.write(response.raw.read(int(filesize)))
|
fd.write(response.raw.read(int(filesize)))
|
||||||
|
bar.update(len(filelist))
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
|
@ -146,10 +132,8 @@ def split_stream(filename, superlist, directory):
|
||||||
handle.write(blob.read(int(filesize)))
|
handle.write(blob.read(int(filesize)))
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
def tui():
|
|
||||||
SuperBeam.tui.run()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
cli()
|
try:
|
||||||
|
cli()
|
||||||
|
except requests.exceptions.ConnectionError as conerr:
|
||||||
|
print(f'Failed to connect. Target alive?')
|
||||||
|
|
Loading…
Reference in New Issue