bbblb 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
bbblb/__init__.py ADDED
@@ -0,0 +1,23 @@
1
+ import logging
2
+ from .settings import config
3
+
4
+ __version__ = "0.0.2"
5
+ VERSION = __version__.split(".", 2)
6
+ VERSION[-1], _, BUILD = VERSION[-1].partition("-")
7
+
8
+ ROOT_LOGGER = logging.getLogger(__name__)
9
+ ROOT_LOGGER.setLevel(logging.INFO)
10
+ ROOT_LOGGER.propagate = False
11
+ ch = logging.StreamHandler()
12
+ ch.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s"))
13
+ ROOT_LOGGER.addHandler(ch)
14
+
15
+ BRANDING = "BBBLB (AGPL-3, https://github.com/defnull/bbblb)"
16
+
17
+
18
+ @config.watch
19
+ def watch_debug_level(name, old, new):
20
+ if name == "DEBUG":
21
+ level = logging.DEBUG if new else logging.INFO
22
+ if level != ROOT_LOGGER.level:
23
+ ROOT_LOGGER.setLevel(logging.DEBUG if new else logging.INFO)
bbblb/__main__.py ADDED
@@ -0,0 +1,3 @@
1
+ from bbblb.cli import main
2
+
3
+ main()
bbblb/api/__init__.py ADDED
@@ -0,0 +1,81 @@
1
+ from contextlib import asynccontextmanager
2
+ from functools import partial
3
+ import pathlib
4
+ from starlette.applications import Starlette
5
+ from starlette.routing import Mount
6
+ from starlette.staticfiles import StaticFiles
7
+ from starlette.responses import RedirectResponse
8
+
9
+ from bbblb.api import bbbapi
10
+ from bbblb.api import bbblbapi
11
+ from bbblb import model
12
+ from bbblb import poller
13
+ from bbblb import recordings
14
+ from bbblb import bbblib
15
+ from bbblb.settings import config
16
+
17
+
18
+ @asynccontextmanager
19
+ async def lifespan(app: Starlette):
20
+ await model.init_engine(config.DB, echo=False)
21
+ poll_worker = poller.Poller()
22
+ importer = recordings.RecordingImporter(
23
+ basedir=pathlib.Path(config.RECORDING_PATH),
24
+ concurrency=config.RECORDING_THREADS,
25
+ )
26
+
27
+ try:
28
+ async with poll_worker, importer:
29
+ app.state.poll_worker = poll_worker
30
+ app.state.importer = importer
31
+ yield
32
+ finally:
33
+ await bbblib.close_pool()
34
+ await model.dispose_engine()
35
+
36
+
37
+ # Playback formats for which we know that they sometimes expect their files
38
+ # in /{format}/* instead of the default /playback/{format}/* path.
39
+ PLAYBACK_FROM_ROOT_FORMATS = ("presentation", "video")
40
+
41
+
42
+ async def format_redirect_app(format, scope, receive, send):
43
+ assert scope["type"] == "http"
44
+ path = scope["path"].lstrip("/")
45
+ response = RedirectResponse(url=f"/playback/{format}/{path}")
46
+ await response(scope, receive, send)
47
+
48
+
49
+ def make_playback_routes():
50
+ return [
51
+ # Serve /playback/* files in case the reverse proxy in front if BBBLB does not.
52
+ Mount(
53
+ "/playback",
54
+ app=StaticFiles(
55
+ directory=config.RECORDING_PATH / "public",
56
+ check_dir=False,
57
+ follow_symlink=True,
58
+ ),
59
+ name="bbb:playback",
60
+ ),
61
+ # Redirect misguided playback file requests to the real path. We send
62
+ # redirects instead of real files in case a reverse proxy in front if BBBLB
63
+ # serves /playback/* for us more efficiently.
64
+ *[
65
+ Mount(f"/{format}", app=partial(format_redirect_app, format))
66
+ for format in PLAYBACK_FROM_ROOT_FORMATS
67
+ ],
68
+ ]
69
+
70
+
71
+ def make_routes():
72
+ return [
73
+ Mount("/bigbluebutton/api", routes=bbbapi.api_routes),
74
+ Mount("/api", routes=bbblbapi.api_routes),
75
+ *make_playback_routes(),
76
+ ]
77
+
78
+
79
+ def make_app():
80
+ config.populate()
81
+ return Starlette(debug=True, routes=make_routes(), lifespan=lifespan)