diff --git a/tasks.py b/tasks.py index fab7cf1a..ba12765a 100644 --- a/tasks.py +++ b/tasks.py @@ -20,7 +20,10 @@ # Imports # ----------------------------------------------------------------------------- import os - +import glob +import shutil +import urllib +from pathlib import Path from invoke import task, call, Collection from invoke.exceptions import Exit, UnexpectedExit @@ -205,5 +208,21 @@ def __init__(self, *args, **kwargs): server.serve_forever() +# ----------------------------------------------------------------------------- +@task +def web_build(ctx): + # Step 1: build the wheel + build(ctx) + # Step 2: Copy the wheel to the web folder, so the http server can access it + newest_wheel = Path(max(glob.glob('dist/*.whl'), key=lambda f: os.path.getmtime(f))) + shutil.copy(newest_wheel, Path('web/')) + # Step 3: Write wheel's name to web/packageFile + with open(Path('web', 'packageFile'), mode='w') as package_file: + package_file.write(str(Path('/') / newest_wheel.name)) + # Step 4: Success! + print('Include ?packageFile=true in your URL!') + + # ----------------------------------------------------------------------------- web_tasks.add_task(serve) +web_tasks.add_task(web_build, name="build") diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 00000000..1d9b8aae --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,3 @@ +# files created by invoke web.build +*.whl +packageFile diff --git a/web/README.md b/web/README.md index a8cc89c8..27f1c196 100644 --- a/web/README.md +++ b/web/README.md @@ -24,9 +24,14 @@ controller using some other transport (ex: `python apps/hci_bridge.py ws-server: For HTTP, start an HTTP server with the `web` directory as its root. You can use the invoke task `inv web.serve` for convenience. +`inv web.build` will build the local copy of bumble and automatically copy the `.whl` file +to the web directory. To use this build, include the param `?packageFile=true` to the URL. + In a browser, open either `scanner/scanner.html` or `speaker/speaker.html`. You can pass optional query parameters: + * `packageFile=true` will automatically use the bumble package built via the + `inv web.build` command. * `package` may be set to point to a local build of Bumble (`.whl` files). The filename must be URL-encoded of course, and must be located under the `web` directory (the HTTP server won't serve files not under its diff --git a/web/bumble.js b/web/bumble.js index c554bc28..33b62f69 100644 --- a/web/bumble.js +++ b/web/bumble.js @@ -75,7 +75,6 @@ export class Bumble extends EventTarget { } // Load the Bumble module - bumblePackage ||= 'bumble'; console.log('Installing micropip'); this.log(`Installing ${bumblePackage}`) await this.pyodide.loadPackage('micropip'); @@ -166,6 +165,20 @@ export class Bumble extends EventTarget { } } +async function getBumblePackage() { + const params = (new URL(document.location)).searchParams; + // First check the packageFile override param + if (params.has('packageFile')) { + return await (await fetch('/packageFile')).text() + } + // Then check the package override param + if (params.has('package')) { + return params.get('package') + } + // If no override params, default to the main package + return 'bumble' +} + export async function setupSimpleApp(appUrl, bumbleControls, log) { // Load Bumble log('Loading Bumble'); @@ -173,8 +186,7 @@ export async function setupSimpleApp(appUrl, bumbleControls, log) { bumble.addEventListener('log', (event) => { log(event.message); }) - const params = (new URL(document.location)).searchParams; - await bumble.loadRuntime(params.get('package')); + await bumble.loadRuntime(await getBumblePackage()); log('Bumble is ready!') const app = await bumble.loadApp(appUrl);