From 8dfbf08f173acafe6b1997321d57e00eb5174103 Mon Sep 17 00:00:00 2001 From: Murmele Date: Mon, 18 Sep 2023 12:56:29 +0200 Subject: [PATCH] Add peertube support (#59) --------- Co-authored-by: David A. Ham --- .gitignore | 1 + README.rst | 16 +++++++-- docs/conf.py | 10 ++++-- docs/index.rst | 4 +-- docs/usage.rst | 33 +++++++++++++++-- pyproject.toml | 2 +- sphinxcontrib/youtube/__init__.py | 4 ++- sphinxcontrib/youtube/peertube.py | 56 +++++++++++++++++++++++++++++ sphinxcontrib/youtube/utils.py | 6 ++++ tests/roots/test-video/index.rst | 3 +- tests/roots/test-video/peertube.rst | 7 ++++ tests/test_build.py | 33 +++++++++++++++-- tests/test_build/peertube.html | 4 +++ tests/test_build/peertube.xhtml | 3 ++ 14 files changed, 168 insertions(+), 14 deletions(-) create mode 100644 sphinxcontrib/youtube/peertube.py create mode 100644 tests/roots/test-video/peertube.rst create mode 100644 tests/test_build/peertube.html create mode 100644 tests/test_build/peertube.xhtml diff --git a/.gitignore b/.gitignore index a212576..6902016 100644 --- a/.gitignore +++ b/.gitignore @@ -131,3 +131,4 @@ dmypy.json # Pyre type checker .pyre/ +.idea diff --git a/README.rst b/README.rst index e6f734e..53ac5e6 100644 --- a/README.rst +++ b/README.rst @@ -12,10 +12,10 @@ sphinxcontrib.youtube Overview -------- -This module provides support for including YouTube and Vimeo videos in Sphinx +This module provides support for including YouTube, Vimeo and Peertube videos in Sphinx :code:`rst` documents. -This module defines directives, :code:`youtube` and :code:`vimeo` which insert +This module defines directives, :code:`youtube`, :code:`vimeo` and :code: `peertube` which insert videos from the respective platforms. They take a single, required argument, which is the video ID: @@ -27,5 +27,17 @@ which is the video ID: .. vimeo:: 148751763 +.. code-block:: rst + + .. peertube:: 327a21b3-374e-4373-8b2c-494c9f5e1f19 + +Custom Server for peertube instances: + +.. code-block:: rst + + .. peertube:: 327a21b3-374e-4373-8b2c-494c9f5e1f19 + + :instance: peertube.tv + For full usage information, please see the `web documentation `__. diff --git a/docs/conf.py b/docs/conf.py index 6a0a84f..ba97eab 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,7 +55,7 @@ # -- Option for Latex output --------------------------------------------------- -# create a custom sphinx output for the youtube and vimeo video +# create a custom sphinx output for the youtube, vimeo and peertube video youtube_cmd = ( r"\newcommand{\sphinxcontribyoutube}[3]" r"{\begin{figure}\sphinxincludegraphics{{#2}.jpg}\caption{\url{#1#2#3}}\end{figure}}" @@ -67,4 +67,10 @@ "\n" ) -latex_elements = {"preamble": youtube_cmd + vimeo_cmd} +peertube_cmd = ( + r"\newcommand{\sphinxcontribpeertube}[3]" + r"{\begin{figure}\sphinxincludegraphics{{#2}.jpg}\caption{\url{#1#2#3}}\end{figure}}" + "\n" +) + +latex_elements = {"preamble": youtube_cmd + vimeo_cmd + peertube_cmd} diff --git a/docs/index.rst b/docs/index.rst index b852fb4..398381b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,9 +12,9 @@ sphinxcontrib-youtube Overview -------- -This module provides support for including YouTube and Vimeo videos in Sphinx rst documents. +This module provides support for including YouTube, Vimeo and PeerTube videos in Sphinx rst documents. -This module defines directives, youtube and vimeo which insert videos from the respective platforms. They take a single, required argument, which is the video ID: +This module defines directives, youtube, vimeo and peertube which insert videos from the respective platforms. They take a single, required argument, which is the video ID: .. code-block:: rst diff --git a/docs/usage.rst b/docs/usage.rst index 0dbb5a9..1934f55 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -4,9 +4,9 @@ Getting started Demo ---- -This module provides support for including YouTube and Vimeo videos in Sphinx :code:`rst` documents. +This module provides support for including YouTube, Vimeo and PeerTube videos in Sphinx :code:`rst` documents. -This module defines directives, :code:`youtube` and :code:`vimeo` which insert videos from the respective platforms. They take a single, required argument, wich is the video ID: +This module defines directives, :code:`youtube`, :code:`vimeo` :code:`peertube` which insert videos from the respective platforms. They take a single, required argument, wich is the video ID: .. code-block:: rst @@ -24,6 +24,26 @@ This module defines directives, :code:`youtube` and :code:`vimeo` which insert v :align: center :aspect: 16:9 +.. code-block:: rst + + .. peertube:: 327a21b3-374e-4373-8b2c-494c9f5e1f19 + +.. peertube:: 327a21b3-374e-4373-8b2c-494c9f5e1f19 + :align: center + :aspect: 16:9 + +To link to a different instance than the default :code:`peertube.tv` of the peertube platform, use the :code:`instance` keyword: + +.. code-block:: rst + + .. peertube:: 9732a818-9fed-4bb2-8469-9502a695cb4d + :instance: tube.kockatoo.org + +.. peertube:: 9732a818-9fed-4bb2-8469-9502a695cb4d + :align: center + :aspect: 16:9 + :instance: tube.kockatoo.org + Usage ----- @@ -105,6 +125,11 @@ To start the video at a specific time the parameter "url_parameters" may be used .. vimeo:: 486557682 :url_parameters: "#t=0m43s" +.. code-block:: rst + + .. peertube:: 327a21b3-374e-4373-8b2c-494c9f5e1f19 + :url_parameters: "?start=0s" + When generating the EPUB output, the videos will not be embedded. Instead, a link to the video will be added. LaTeX @@ -120,6 +145,10 @@ In LaTeX output, the following code will be emitted for the videos: \sphinxcontribvimeo{https://player.vimeo.com/video/}{148751763}{"#t=0m43s"} +.. code-block:: latex + + \sphinxcontribpeertube{https://peertube.tv/w/}{327a21b3-374e-4373-8b2c-494c9f5e1f19}{?start=43} + The user may customise the rendering of the URL by defining this command in the preamble. The captions will be downloaded to the latex folder and can thus be used as images in the :code:`.pdf` document. We are using the `Vumbnail `__ (vimeo) and `get-youtube-thumbnail `__ (youtube) web services to retrieve them. Here is an example of custom command for both the vimeo and the yoututbe output. This needs to be added in the :code:`conf.py` file: .. code-block:: python diff --git a/pyproject.toml b/pyproject.toml index 3ed0cae..dc6e0b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ content-type = "text/plain" text = ''' This package contains the youtube Sphinx extension. The extension defines the directives, "youtube" and "vimeo", for embedding -YouTube and Vimeo videos, respectively.''' +YouTube, Vimeo and Peertube videos, respectively.''' [project.urls] Homepage = "https://github.com/sphinx-contrib/youtube" diff --git a/sphinxcontrib/youtube/__init__.py b/sphinxcontrib/youtube/__init__.py index 0875310..cc8ecb5 100644 --- a/sphinxcontrib/youtube/__init__.py +++ b/sphinxcontrib/youtube/__init__.py @@ -1,5 +1,5 @@ """Sphinx "youtube" extension.""" -from . import utils, vimeo, youtube +from . import peertube, utils, vimeo, youtube __version__ = "1.3.0" @@ -10,6 +10,8 @@ def setup(app): app.add_directive("youtube", youtube.YouTube) app.add_node(vimeo.vimeo, **utils._NODE_VISITORS) app.add_directive("vimeo", vimeo.Vimeo) + app.add_node(peertube.peertube, **peertube._NODE_VISITORS) + app.add_directive("peertube", peertube.PeerTube) app.connect("builder-inited", utils.configure_image_download) app.connect("env-merge-info", utils.merge_download_images) app.connect("env-updated", utils.download_images) diff --git a/sphinxcontrib/youtube/peertube.py b/sphinxcontrib/youtube/peertube.py new file mode 100644 index 0000000..7dbfb86 --- /dev/null +++ b/sphinxcontrib/youtube/peertube.py @@ -0,0 +1,56 @@ +"""Directive dedicated to the peertube platform.""" + +from docutils.parsers.rst import directives + +from . import utils + +# https://docs.joinpeertube.org/api/embed-player + + +class peertube(utils.video): + """Empty video node class.""" + + pass + + +class PeerTube(utils.Video): + """Custom version of the Video Directive.""" + + _node = peertube + _thumbnail_url = "{}.jpg" + _platform = "peertube" + _platform_url = "peertube.tv" + + # optional options available + option_spec = { + "width": directives.unchanged, + "height": directives.unchanged, + "aspect": directives.unchanged, + "align": directives.unchanged, + "url_parameters": directives.unchanged, + "instance": directives.unchanged, + } + + +def visit_peertube_node_html(self, node): + """Custom html visit node.""" + node["platform_url"] = f"https://{node['instance']}/videos/embed/" + return utils.visit_video_node_html(self, node) + + +def visit_video_node_epub(self, node): + """Custom epub visit node.""" + node["platform_url"] = f"https://{node['instance']}/w/" + return utils.visit_video_node_epub(self, node) + + +def visit_video_node_latex(self, node): + """Custom epub visit node.""" + node["platform_url"] = f"https://{node['instance']}/w/" + return utils.visit_video_node_latex(self, node) + + +_NODE_VISITORS = utils._NODE_VISITORS.copy() +_NODE_VISITORS.update(html=(visit_peertube_node_html, utils.depart_video_node)) +_NODE_VISITORS.update(epub=(visit_video_node_epub, utils.depart_video_node)) +_NODE_VISITORS.update(latex=(visit_video_node_latex, utils.depart_video_node)) diff --git a/sphinxcontrib/youtube/utils.py b/sphinxcontrib/youtube/utils.py index c73eb2f..f93e535 100644 --- a/sphinxcontrib/youtube/utils.py +++ b/sphinxcontrib/youtube/utils.py @@ -99,6 +99,11 @@ def run(self): else: align = None + # custom platform url for peertube + instance = self._platform_url + if "instance" in self.options: + instance = self.options.get("instance") + return [ self._node( id=self.arguments[0], @@ -111,6 +116,7 @@ def run(self): platform=self._platform, platform_url=self._platform_url, platform_url_privacy=self._platform_url_privacy, + instance=instance, ) ] diff --git a/tests/roots/test-video/index.rst b/tests/roots/test-video/index.rst index 3d3b145..a59acfd 100644 --- a/tests/roots/test-video/index.rst +++ b/tests/roots/test-video/index.rst @@ -4,4 +4,5 @@ index .. toctree:: vimeo - youtube \ No newline at end of file + youtube + peertube \ No newline at end of file diff --git a/tests/roots/test-video/peertube.rst b/tests/roots/test-video/peertube.rst new file mode 100644 index 0000000..a201704 --- /dev/null +++ b/tests/roots/test-video/peertube.rst @@ -0,0 +1,7 @@ +peertube +======== + +.. peertube:: 327a21b3-374e-4373-8b2c-494c9f5e1f19 + +.. peertube:: 327a21b3-374e-4373-8b2c-494c9f5e1f19 + :instance: "peertube.tv" \ No newline at end of file diff --git a/tests/test_build.py b/tests/test_build.py index 7448188..e0ba3ae 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -22,7 +22,7 @@ def test_youtube_html(app, status, warning, file_regression): @pytest.mark.sphinx(testroot="video") def test_vimeo_html(app, status, warning, file_regression): - """Test a youtube video in html build.""" + """Test a vimeo video in html build.""" app.builder.build_all() html = (app.outdir / "vimeo.html").read_text(encoding="utf8") @@ -31,6 +31,17 @@ def test_vimeo_html(app, status, warning, file_regression): file_regression.check(video, basename="vimeo", extension=".html") +@pytest.mark.sphinx(testroot="video") +def test_peertube_html(app, status, warning, file_regression): + """Test a peertube video in html build.""" + app.builder.build_all() + + html = (app.outdir / "peertube.html").read_text(encoding="utf8") + html = BeautifulSoup(html, "html.parser") + video = html.select(".video_wrapper")[0].prettify(formatter=fmt) + file_regression.check(video, basename="peertube", extension=".html") + + # -- Latex related tests ------------------------------------------------------- @@ -42,11 +53,16 @@ def test_latex(app, status, warning): assert r"\newcommand{\sphinxcontribyoutube}" in result assert r"\newcommand{\sphinxcontribvimeo}" in result + assert r"\newcommand{\sphinxcontribpeertube}" in result assert r"\sphinxcontribyoutube{https://youtu.be/}{dQw4w9WgXcQ}{}" in result assert ( r"\sphinxcontribvimeo{https://player.vimeo.com/video/}{148751763}{}" in result ) + assert ( + r"\sphinxcontribpeertube{https://peertube.tv/w/}{327a21b3-374e-4373-8b2c-494c9f5e1f19}{}" + in result + ) # -- Epub related tests -------------------------------------------------------- @@ -65,7 +81,7 @@ def test_youtube_epub(app, status, warning, file_regression): @pytest.mark.sphinx("epub", testroot="video") def test_vimeo_epub(app, status, warning, file_regression): - """Test a youtube video in epub build.""" + """Test a vimeo video in epub build.""" app.builder.build_all() xhtml = (app.outdir / "vimeo.xhtml").read_text(encoding="utf8") @@ -74,12 +90,23 @@ def test_vimeo_epub(app, status, warning, file_regression): file_regression.check(video, basename="vimeo", extension=".xhtml") +@pytest.mark.sphinx("epub", testroot="video") +def test_peertube_epub(app, status, warning, file_regression): + """Test a peertube video in epub build.""" + app.builder.build_all() + + xhtml = (app.outdir / "peertube.xhtml").read_text(encoding="utf8") + xhtml = BeautifulSoup(xhtml, "html.parser") + video = xhtml.select(".video_link_url")[0].prettify(formatter=fmt) + file_regression.check(video, basename="peertube", extension=".xhtml") + + # -- Unsuported builders ------------------------------------------------------- @pytest.mark.sphinx("text", testroot="video") def test_youtube_unsupported(app, status, warning): - """Test a youtube video in unsuprted build.""" + """Test a youtube video in unsupported build.""" app.builder.build_all() assert "unsupported output format (node skipped)" in warning.getvalue() diff --git a/tests/test_build/peertube.html b/tests/test_build/peertube.html new file mode 100644 index 0000000..9820388 --- /dev/null +++ b/tests/test_build/peertube.html @@ -0,0 +1,4 @@ +
+ +
\ No newline at end of file diff --git a/tests/test_build/peertube.xhtml b/tests/test_build/peertube.xhtml new file mode 100644 index 0000000..e684bfa --- /dev/null +++ b/tests/test_build/peertube.xhtml @@ -0,0 +1,3 @@ + + https://peertube.tv/w/327a21b3-374e-4373-8b2c-494c9f5e1f19 + \ No newline at end of file