diff --git a/LICENSE b/LICENSE index 01f2f8f..98285c7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Alejandro Piad, and contributors. +Copyright (c) 2020 Alejandro Piad, and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Readme.md b/Readme.md index 829accf..41a9d62 100644 --- a/Readme.md +++ b/Readme.md @@ -8,7 +8,7 @@ [Gitter](https://gitter.im/auditorium-slides/community) [Demo](https://auditorium-demo.apiad.net) - + > A Python-powered slideshow creator with steroids. @@ -50,6 +50,7 @@ If you want to quickly grok `auditorium`, the best option is to [look at the dem * [Authoring a slideshow with Python](https://apiad.net/auditorium/quickstart/#python-first) * [Authoring a slideshow with Markdown](https://apiad.net/auditorium/quickstart/#markdown-first) * [Rendering a slideshow as purely static HTML](https://apiad.net/auditorium/quickstart/#going-full-static) +* [Hosting a slideshow online for free](https://apiad.net/auditorium/hosting/#hosting-freely-with-auditorium-publish) ## Made with Auditorium diff --git a/auditorium/__main__.py b/auditorium/__main__.py index 4596b8b..6621b70 100644 --- a/auditorium/__main__.py +++ b/auditorium/__main__.py @@ -5,6 +5,7 @@ import webbrowser from auditorium import Show +from auditorium.watcher import Watcher class Auditorium: @@ -14,13 +15,17 @@ def run( *, host: str = "127.0.0.1", port: int = 6789, - debug: bool = False, + reload: bool = False, instance_name: str = "show", ): "Runs a custom Python script as a slideshow." show = Show.load(path, instance_name) - show.run(host=host, port=port, debug=debug) + + if reload: + show = Watcher(path, instance_name) + + show.run(host=host, port=port, debug=reload) @staticmethod def publish( diff --git a/auditorium/watcher.py b/auditorium/watcher.py new file mode 100644 index 0000000..589daab --- /dev/null +++ b/auditorium/watcher.py @@ -0,0 +1,33 @@ +import os, sys, time +import asyncio +import fire + + +class Watcher: + def __init__(self, files, callback=None): + self.files = files + self.callback = callback + + def files_to_timestamp(self): + return dict ([(f, os.path.getmtime(f)) for f in self.files]) + + async def run(self): + before = self.files_to_timestamp() + + while True: + await asyncio.sleep(1) + after = self.files_to_timestamp() + + modified = [] + + for f in before.keys(): + if os.path.getmtime(f) != before.get(f): + modified.append(f) + + if modified: print('Modified: {}'.format(', '.join(modified))) + + before = after + + +if __name__ == "__main__": + fire.Fire(Watcher) diff --git a/docs/api/cli.md b/docs/api/cli.md new file mode 100644 index 0000000..67af257 --- /dev/null +++ b/docs/api/cli.md @@ -0,0 +1,4 @@ +# The `auditorium` CLI + +!!! warning + This section is under construction. More content will be added shortly. diff --git a/docs/api/context.md b/docs/api/context.md new file mode 100644 index 0000000..4df8df9 --- /dev/null +++ b/docs/api/context.md @@ -0,0 +1,4 @@ +# The `Context` class + +!!! warning + This section is under construction. More content will be added shortly. diff --git a/docs/api/show.md b/docs/api/show.md new file mode 100644 index 0000000..e885760 --- /dev/null +++ b/docs/api/show.md @@ -0,0 +1,188 @@ +# The `Show` class + +!!! warning + This section is for advanced usage. Please read the [Quick Start](/quickstart/) guides first. + +!!! note + This section asumes a Python-first approach for simplicity. + You can use all of `auditorium` features in a Markdown-first approach + with [runnable code blocks](/quickstart/#markdown-first). + +The `Show` class is the first class you will need to interact +with when using `auditorium`. All your slideshows begin with something like: + +```python +from auditorium import Show + +show = auditorium.Show("My Show Title") +``` + +## Creating slides + +The most important use of your `show` instance is the `@slide` decorator, which +allows you to create slides. A slide is created by decorating a function (or actually any callable) +with `@show.slide` like this: + +```python +@show.slide +def first_slide(ctx): + # content +``` + +Everything that can be included **inside** a slide is discussed in the [Context](/api/context/) page. + +!!! note + Slides are sorted in the order in which they are declared in your Python script. + +### Customizing slides + +The `@slide` decorator can receive an optional parameter `id` to configure a specific slide. + +```python +@show.slide(id="the-first-slide") +def first_slide(ctx): + # content +``` + +The slide identifier is used in HTML as anchor for that slide. Hence, when running +the slideshow, the previous slide would be located at `http://localhost:6789/#/the-first-slide`. +If no `id` is provided the slide identifier is built from the callable `__name__` parameter, +hence in the previous example it would be located at `http://localhost:6789/#/first_slide` + +!!! warning + Note that when using additional parameters, you have to use the form `@show.slide(...)` + with parenthesis, but when not using parameters, you can use the decorator directly as + `@show.slide` without parenthesis. + +Default slide ids are OK if you don't care about having those ugly underscores in your slide +anchors in HTML. In any case, you can always author your slideshow first and then add +pretty slide identifiers afterwards. + +### Vertical slides + +Vertical slides are an effective way to add "read-more" like content to a slideshow. +You can see them in action at . + +Vertical slides are added *after* a main slide, using a modified form of the `@slide` decorator. +Instead of using `@show.slide` you use `@main_slide.slide` where `main_slide` is the actual +function (or any other callable) that corresponds to the main slide. + +```python +@show.slide +def main_slide(ctx): + # This will be a regular slide + +@main_slide.slide +def vertical_1(ctx): + # This one is vertical to `main_slide` + +@show.slide +def other_slide(ctx): + # This one is another main slide + +@other_slide.slide +def vertical_2(ctx): + # This one is vertical to `other_slide` + +@other_slide.slide +def vertical_3(ctx): + # This one is also vertical to `other_slide`, + # under the previous (`vertical_2`) +``` + +!!! note + Vertical slides can be declared at any moment *after* but not necesarily *under* the main slide. + This allows you to organize all your main slides at the top of a script and then add vertical slides when + you think is convenient. + +## Running the show + +Once all slides are in, you can run a show by calling directly the `show.run` method: + +```python +show.run('localhost', 6789) +``` + +However, this method is actually **not recommended**. Instead it is *preferred* to use: + +```bash +auditorium run /path/to/myshow.py [--host HOST] [--port PORT] +``` + +The second method is preferred because it is more aligned with other usages such as `auditorium publish` +and, in the future, we will add a `--reload` option to allow hot-reload when you save your slideshow. + +!!! error + When calling `run` you can get an error like: + + :::bash + (!) You need `uvicorn` installed in order to call `run`. + + This means you didn't installed `uvicorn` when installing `auditorium`, which is necessary + for actually serving the HTML. You can fix it by installing like this: + + pip install auditorium[server] + + Serverless installations are smaller and useful if you only want to use `render` or `publish`, + or [deploy to a serverless cloud provider](/hosting/#hosting-as-serverless-functions-at-nowsh). + +## Rendering the show + +You can obtain a static HTML with embedded resources ready to be served with: + +```python +static_html = show.render(theme="white") + +with open("/path/to/myshow.html", "w") as fp: + fp.write(static_html) +``` + +The reason why `render` returns a `string` rather than saving to a file is because you could +use this functionality in a serverless cloud provider or any other context where you cannot +interact directly with path-based files. It's up to you how to make use of the rendered HTML. + +That said, if you use the [CLI command](/api/cli) `render` you can achieve this more easily with: + +```python +auditorium render /path/to/myshow.py > /path/to/myshow.html +``` + +## Loading a show + +The static method `Show.load` takes in a path and loads the corresponding show instance. + +```python +show = Show.load("/path/to/show.py") +``` + +It works with both Python (`myshow.py`) and Markdown (`myshow.md`) file extensions. +It is useful in contexts where you can serve multiple slideshows, for example, +in a server context where you want to map URL paths to specific shows. + +After calling `load` you receive a `Show` instance with all it can do. + +## Appending multiple shows + +You can build a slideshow in parts, some in Python, some in Markdown, and then +use `show.append` to connect them. It works with `Show` instances and path names as well. + +```python +show = Show("Main Show") +# ... build show + +# append another instance +other_show = Show("Other show") +# ... build other_show +show.append(other_show) + +# append by path +show.append("/path/to/anothershow.py") # Python +show.append("/path/to/anothershow.md") # Markdown +``` + +This allows you to build a slideshow in parts. Maybe some slides are more +convenient in Markdown-first mode because they are mostly static content, +while a few specific slides are very tricky and it's better to code them in Python. + +!!! warning + This section is under construction. More content will be added shortly. diff --git a/docs/hosting.md b/docs/hosting.md index 5103223..bac9816 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -1,7 +1,7 @@ # Hosting your slideshow If you are presenting on a big screen connected to your own computer, all you need to do is -`auditorium run [file]`, and you can present from [localhost:6789](http://localhost:6789) as usual. +`auditorium run`, and you can present from [localhost:6789](http://localhost:6789) as usual. However, there are many cases where you are either not presenting from your computer, or you want to host your slideshow publicly for others to follow. Here are some ideas. @@ -12,7 +12,7 @@ If the audience can ping your computer, then the easiest solution to simply do: ```bash -auditorium run [file] --host=0.0.0.0 +auditorium run /path/to/file --host=0.0.0.0 ``` Then give them your public IP address. In Linux, run `ip addr` to see it. @@ -30,14 +30,15 @@ with a server that renders the slide and proxies all incoming requests back to y To use it, simple run: ```bash -auditorium publish [file] --name [your-slideshow-name] +auditorium publish /path/to/file --name [your-slideshow-name] ``` Then head over to `http://auditorium.apiad.net/your-slideshow-name/` and enjoy! -> **NOTE:** This service is provided as-is with no guarantees whatsoever. The service runs -> on a development server that is restarted often (at least twice a day), so slideshows are **not** guaranteed to stay -> up for a long time. Don't use this service in mission critical presentations. +!!! warning + This service is provided as-is with no guarantees whatsoever. The service runs + on a development server that is restarted often (at least twice a day), so slideshows are **not** guaranteed to stay + up for a long time. Don't use this service in mission critical presentations. If you need finer control then you can host the server yourself on your own infrastructure and thus ensure that it's online when you need it. Just run: @@ -47,14 +48,29 @@ auditorium server [--host HOST] [--port PORT] ``` Make sure the server is publicly accessible. You'll probably use some kind of web server, -or `--host 0.0.0.0` and `--port 80` which you can totally do since `auditorium` ships +or run it with `--host 0.0.0.0` and `--port 80`, which you can totally do since `auditorium` ships with `uvicorn` which is a fully fledged production web server. Then publish to your own address with: ```bash -auditorium publish [file] --name [name] --server [ws://your-server:port] # or wss:// +auditorium publish /path/to/file --name [name] --server [ws://your-server:port] # or wss:// ``` +!!! error + When calling `server` you can get an error like: + + :::bash + (!) You need `uvicorn` installed in order to call `server`. + + This means you didn't installed `uvicorn` when installing `auditorium`, which is necessary + for actually serving the HTML. You can fix it by installing like this: + + pip install auditorium[server] + + Serverless installations are smaller and useful if you only want to use `render` or `publish`, + or [deploy to a serverless cloud provider](/hosting/#hosting-as-serverless-functions-at-nowsh). + + ## Hosting temporarily through `ngrok` Another option is to use [`ngrok`](https://ngrok.com/). @@ -80,7 +96,7 @@ The do have paid plans for securing a custom domain. If your slideshow is purely static, then you ran run: ```bash -auditorium render [file] > index.html +auditorium render /path/to/file > index.html ``` Then upload the file to a Github repository. diff --git a/docs/index.md b/docs/index.md index 829accf..41a9d62 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,7 +8,7 @@ [Gitter](https://gitter.im/auditorium-slides/community) [Demo](https://auditorium-demo.apiad.net) - + > A Python-powered slideshow creator with steroids. @@ -50,6 +50,7 @@ If you want to quickly grok `auditorium`, the best option is to [look at the dem * [Authoring a slideshow with Python](https://apiad.net/auditorium/quickstart/#python-first) * [Authoring a slideshow with Markdown](https://apiad.net/auditorium/quickstart/#markdown-first) * [Rendering a slideshow as purely static HTML](https://apiad.net/auditorium/quickstart/#going-full-static) +* [Hosting a slideshow online for free](https://apiad.net/auditorium/hosting/#hosting-freely-with-auditorium-publish) ## Made with Auditorium diff --git a/docs/quickstart.md b/docs/quickstart.md index 9889243..905a82b 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -1,5 +1,8 @@ # Quick Start +This section provides quick hints for starting using `auditorium` right now. However, +the best way to grok it is looking at the [demo](https://auditorium-demo.apiad.net). + ## Python First In `auditorium` you create a presentation via the `Show` class: @@ -148,3 +151,7 @@ auditorium render > ``` This will render the slideshow in an HTML file with all CSS and JavaScript embedded. Just copy this single HTML file and open it on any browser. You won't need to have `auditorium` installed. However, do keep in mind that all of the backend code will execute only once for the initial rendering, so your animations will be frozen at the starting frame and none of the interaction will work. + +## Read on + +The [API docs](/api/show/) have a more in-depth explanation about all topics covered here. diff --git a/mkdocs.yml b/mkdocs.yml index 858c746..320af37 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,5 +1,18 @@ site_name: Auditorium -theme: readthedocs +repo_name: 'apiad/auditorium' +repo_url: 'https://github.com/apiad/auditorium' + +theme: + name: material + feature: + tabs: true + +markdown_extensions: + - codehilite + - toc: + permalink: true + - admonition + nav: - Home: index.md - Quick Start: quickstart.md @@ -7,3 +20,8 @@ nav: - Important Considerations: consider.md - Contributing: contributing.md - History: history.md + + - API: + - Show: api/show.md + - Context: api/context.md + - CLI: api/cli.md diff --git a/poetry.lock b/poetry.lock index 15b6635..474c9e0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -132,6 +132,14 @@ optional = true python-versions = "*" version = "0.9.0" +[[package]] +category = "dev" +description = "An HTML Minifier" +name = "htmlmin" +optional = false +python-versions = "*" +version = "0.1.12" + [[package]] category = "main" description = "A collection of framework independent HTTP protocol utils." @@ -185,6 +193,14 @@ MarkupSafe = ">=0.23" [package.extras] i18n = ["Babel (>=0.8)"] +[[package]] +category = "dev" +description = "JavaScript minifier." +name = "jsmin" +optional = false +python-versions = "*" +version = "2.2.2" + [[package]] category = "dev" description = "A fast implementation of the Cassowary constraint solver" @@ -277,6 +293,34 @@ click = ">=3.3" livereload = ">=2.5.1" tornado = ">=5.0" +[[package]] +category = "dev" +description = "A Material Design theme for MkDocs" +name = "mkdocs-material" +optional = false +python-versions = "*" +version = "4.6.0" + +[package.dependencies] +Pygments = ">=2.2" +markdown = "<3.2" +mkdocs = ">=1" +mkdocs-minify-plugin = ">=0.2" +pymdown-extensions = ">=6.2,<6.3" + +[[package]] +category = "dev" +description = "An MkDocs plugin to minify HTML and/or JS files prior to being written to disk" +name = "mkdocs-minify-plugin" +optional = false +python-versions = ">=2.7" +version = "0.2.1" + +[package.dependencies] +htmlmin = ">=0.1.4" +jsmin = ">=2.2.2" +mkdocs = ">=1.0.4" + [[package]] category = "dev" description = "More routines for operating on iterables, beyond itertools" @@ -329,6 +373,14 @@ version = "19.2" pyparsing = ">=2.0.2" six = "*" +[[package]] +category = "dev" +description = "Backport of PEP 562." +name = "pep562" +optional = false +python-versions = "*" +version = "1.0" + [[package]] category = "dev" description = "plugin and hook calling mechanisms for python" @@ -392,6 +444,18 @@ colorama = "*" isort = ">=4.2.5,<5" mccabe = ">=0.6,<0.7" +[[package]] +category = "dev" +description = "Extension pack for Python Markdown." +name = "pymdown-extensions" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +version = "6.2.1" + +[package.dependencies] +Markdown = ">=3.0.1" +pep562 = "*" + [[package]] category = "dev" description = "Python parsing module" @@ -546,9 +610,9 @@ version = "0.1.7" category = "main" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" name = "websockets" -optional = true -python-versions = ">=3.6" -version = "8.0.2" +optional = false +python-versions = ">=3.6.1" +version = "8.1" [[package]] category = "dev" @@ -578,8 +642,8 @@ testing = ["pathlib2", "contextlib2", "unittest2"] server = ["uvicorn"] [metadata] -content-hash = "a14b43d724389766b7cc94cebbca04704bf1aceb4e38d3c37f018694a3496721" -python-versions = "^3.6" +content-hash = "b67155eced3189bf34b4e9e19228bc0f8cc151fef9d3d512ce3850c49b4c4b51" +python-versions = "^3.6.1" [metadata.files] aiofiles = [ @@ -658,6 +722,9 @@ h11 = [ {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, {file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"}, ] +htmlmin = [ + {file = "htmlmin-0.1.12.tar.gz", hash = "sha256:50c1ef4630374a5d723900096a961cff426dff46b48f34d194a81bbe14eca178"}, +] httptools = [ {file = "httptools-0.0.13.tar.gz", hash = "sha256:e00cbd7ba01ff748e494248183abc6e153f49181169d8a3d41bb49132ca01dfc"}, ] @@ -673,6 +740,9 @@ jinja2 = [ {file = "Jinja2-2.10.3-py2.py3-none-any.whl", hash = "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f"}, {file = "Jinja2-2.10.3.tar.gz", hash = "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"}, ] +jsmin = [ + {file = "jsmin-2.2.2.tar.gz", hash = "sha256:b6df99b2cd1c75d9d342e4335b535789b8da9107ec748212706ef7bbe5c2553b"}, +] kiwisolver = [ {file = "kiwisolver-1.1.0-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3"}, {file = "kiwisolver-1.1.0-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:fe51b79da0062f8e9d49ed0182a626a7dc7a0cbca0328f612c6ee5e4711c81e4"}, @@ -771,6 +841,11 @@ markupsafe = [ {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] matplotlib = [ @@ -796,6 +871,14 @@ mkdocs = [ {file = "mkdocs-1.0.4-py2.py3-none-any.whl", hash = "sha256:8cc8b38325456b9e942c981a209eaeb1e9f3f77b493ad755bfef889b9c8d356a"}, {file = "mkdocs-1.0.4.tar.gz", hash = "sha256:17d34329aad75d5de604b9ed4e31df3a4d235afefdc46ce7b1964fddb2e1e939"}, ] +mkdocs-material = [ + {file = "mkdocs-material-4.6.0.tar.gz", hash = "sha256:b21aa2645ccb11442ea381c92d187bbc94127f50702c0d28c3fc0152fa7b29da"}, + {file = "mkdocs_material-4.6.0-py2.py3-none-any.whl", hash = "sha256:89a8e2527ca8426c40f2213ce53513f73f54d0a32b36aef33fde6849d294e9ec"}, +] +mkdocs-minify-plugin = [ + {file = "mkdocs-minify-plugin-0.2.1.tar.gz", hash = "sha256:3000a5069dd0f42f56a8aaf7fd5ea1222c67487949617e39585d6b6434b074b6"}, + {file = "mkdocs_minify_plugin-0.2.1-py2-none-any.whl", hash = "sha256:d54fdd5be6843dd29fd7af2f7fdd20a9eb4db46f1f6bed914e03b2f58d2d488e"}, +] more-itertools = [ {file = "more-itertools-8.0.2.tar.gz", hash = "sha256:b84b238cce0d9adad5ed87e745778d20a3f8487d0f0cb8b8a586816c7496458d"}, {file = "more_itertools-8.0.2-py3-none-any.whl", hash = "sha256:c833ef592a0324bcc6a60e48440da07645063c453880c9477ceb22490aec1564"}, @@ -846,6 +929,10 @@ packaging = [ {file = "packaging-19.2-py2.py3-none-any.whl", hash = "sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108"}, {file = "packaging-19.2.tar.gz", hash = "sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47"}, ] +pep562 = [ + {file = "pep562-1.0-py2.py3-none-any.whl", hash = "sha256:d2a48b178ebf5f8dd31709cc26a19808ef794561fa2fe50ea01ea2bad4d667ef"}, + {file = "pep562-1.0.tar.gz", hash = "sha256:58cb1cc9ee63d93e62b4905a50357618d526d289919814bea1f0da8f53b79395"}, +] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, @@ -878,6 +965,10 @@ pylint = [ {file = "pylint-2.4.4-py3-none-any.whl", hash = "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"}, {file = "pylint-2.4.4.tar.gz", hash = "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd"}, ] +pymdown-extensions = [ + {file = "pymdown-extensions-6.2.1.tar.gz", hash = "sha256:3bbe6048275f8a0d13a0fe44e0ea201e67268aa7bb40c2544eef16abbf168f7b"}, + {file = "pymdown_extensions-6.2.1-py2.py3-none-any.whl", hash = "sha256:dce5e17b93be0572322b7d06c9a13c13a9d98694d6468277911d50ca87d26f29"}, +] pyparsing = [ {file = "pyparsing-2.4.6-py2.py3-none-any.whl", hash = "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec"}, {file = "pyparsing-2.4.6.tar.gz", hash = "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f"}, @@ -973,17 +1064,28 @@ wcwidth = [ {file = "wcwidth-0.1.7.tar.gz", hash = "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e"}, ] websockets = [ - {file = "websockets-8.0.2-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:e906128532a14b9d264a43eb48f9b3080d53a9bda819ab45bf56b8039dc606ac"}, - {file = "websockets-8.0.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:83e63aa73331b9ca21af61df8f115fb5fbcba3f281bee650a4ad16a40cd1ef15"}, - {file = "websockets-8.0.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e9102043a81cdc8b7c8032ff4bce39f6229e4ac39cb2010946c912eeb84e2cb6"}, - {file = "websockets-8.0.2-cp36-cp36m-win32.whl", hash = "sha256:8d7a20a2f97f1e98c765651d9fb9437201a9ccc2c70e94b0270f1c5ef29667a3"}, - {file = "websockets-8.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:c82e286555f839846ef4f0fdd6910769a577952e1e26aa8ee7a6f45f040e3c2b"}, - {file = "websockets-8.0.2-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:73ce69217e4655783ec72ce11c151053fcbd5b837cc39de7999e19605182e28a"}, - {file = "websockets-8.0.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8c77f7d182a6ea2a9d09c2612059f3ad859a90243e899617137ee3f6b7f2b584"}, - {file = "websockets-8.0.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a7affaeffbc5d55681934c16bb6b8fc82bb75b175e7fd4dcca798c938bde8dda"}, - {file = "websockets-8.0.2-cp37-cp37m-win32.whl", hash = "sha256:f5cb2683367e32da6a256b60929a3af9c29c212b5091cf5bace9358d03011bf5"}, - {file = "websockets-8.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:049e694abe33f8a1d99969fee7bfc0ae6761f7fd5f297c58ea933b27dd6805f2"}, - {file = "websockets-8.0.2.tar.gz", hash = "sha256:882a7266fa867a2ebb2c0baaa0f9159cabf131cf18c1b4270d79ad42f9208dc5"}, + {file = "websockets-8.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c"}, + {file = "websockets-8.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170"}, + {file = "websockets-8.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8"}, + {file = "websockets-8.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb"}, + {file = "websockets-8.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5"}, + {file = "websockets-8.1-cp36-cp36m-win32.whl", hash = "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a"}, + {file = "websockets-8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5"}, + {file = "websockets-8.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989"}, + {file = "websockets-8.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d"}, + {file = "websockets-8.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779"}, + {file = "websockets-8.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8"}, + {file = "websockets-8.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422"}, + {file = "websockets-8.1-cp37-cp37m-win32.whl", hash = "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc"}, + {file = "websockets-8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308"}, + {file = "websockets-8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092"}, + {file = "websockets-8.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485"}, + {file = "websockets-8.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1"}, + {file = "websockets-8.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55"}, + {file = "websockets-8.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824"}, + {file = "websockets-8.1-cp38-cp38-win32.whl", hash = "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36"}, + {file = "websockets-8.1-cp38-cp38-win_amd64.whl", hash = "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b"}, + {file = "websockets-8.1.tar.gz", hash = "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f"}, ] wrapt = [ {file = "wrapt-1.11.2.tar.gz", hash = "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"}, diff --git a/pyproject.toml b/pyproject.toml index f3b5a34..46867d9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,19 +1,21 @@ [tool.poetry] name = "auditorium" -version = "19.1.6" +version = "20.2.1" description = "A Python-powered slideshow maker with steroids." authors = ["Alejandro Piad "] license = "MIT" readme = "Readme.md" [tool.poetry.dependencies] -python = "^3.6" +python = "^3.6.1" markdown = "^3.1.1" fire = "^0.2.1" jinja2 = "^2.10.3" pygments = "^2.5.2" fastapi = "^0.45.0" aiofiles = "^0.4.0" +websockets = "^8.1" + # uvicorn is required *only* for calling `auditorium run` uvicorn = { version = "^0.11.1", optional = true } @@ -27,6 +29,7 @@ pylint = "^2.4.4" matplotlib = "^3.1.2" mypy = "^0.760" mkdocs = "^1.0.4" +mkdocs-material = "^4.6.0" [tool.poetry.scripts] auditorium = "auditorium.__main__:main"