1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
from docutils import nodes
from docutils.parsers.rst import directives, Directive
from sphinx.environment import BuildEnvironment
from sphinx.locale import __
from sphinx.util import logging
logger = logging.getLogger(__name__)
def get_size(d, key):
if key not in d:
return None
m = re.match(r"(\d+)(|%|px)$", d[key])
if not m:
raise ValueError("invalid size %r" % d[key])
return int(m.group(1)), m.group(2) or "px"
def css(d):
return "; ".join(sorted("%s: %s" % kv for kv in d.items()))
class peertube(nodes.General, nodes.Element):
pass
def visit_peertube_node(self, node):
instance = node["instance"]
if not (self.config.peertube_instance or instance):
logger.warning(__("No peertube instance defined"))
return
if instance is None:
instance = self.config.peertube_instance
# Modified to be an external link for Debian, instead of an embedded video
style = {
"margin-bottom": "24px"
}
a_attrs = {
"class": "reference external",
"href": instance + "videos/watch/%s" % node["id"],
"style": css(style),
"target": "_blank"
}
div_attrs = {
"class": "toctree-wrapper compound"
}
anchor = self.starttag(node, "a", **a_attrs) + f"View PeerTube video on {instance}</a>"
self.body.append(self.starttag(node, "div", **div_attrs))
self.body.append(self.starttag(node, "ul"))
self.body.append(self.starttag(node, "li"))
self.body.append(anchor)
self.body.append("</li></ul></div>")
def depart_peertube_node(self, node):
pass
def visit_peertube_node_latex(self, node):
instance = node["instance"]
if not (self.config.peertube_instance or instance):
logger.warning(__("No peertube instance defined"))
return
if instance is None:
instance = self.config.peertube_instance
self.body.append(
r'\begin{quote}\begin{center}\fbox{\url{' +
instance +
r'videos/watch/%s}}\end{center}\end{quote}' %
node['id'])
class PeerTube(Directive):
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {
"instance": directives.unchanged,
"width": directives.unchanged,
"height": directives.unchanged,
"aspect": directives.unchanged,
}
def run(self):
instance = self.options.get("instance")
if "aspect" in self.options:
aspect = self.options.get("aspect")
m = re.match(r"(\d+):(\d+)", aspect)
if m is None:
raise ValueError("invalid aspect ratio %r" % aspect)
aspect = tuple(int(x) for x in m.groups())
else:
aspect = None
width = get_size(self.options, "width")
height = get_size(self.options, "height")
return [peertube(id=self.arguments[0], instance=instance, aspect=aspect, width=width, height=height)]
def unsupported_visit_peertube(self, node):
self.builder.warn('PeerTube: unsupported output format (node skipped)')
raise nodes.SkipNode
_NODE_VISITORS = {
'html': (visit_peertube_node, depart_peertube_node),
'latex': (visit_peertube_node_latex, depart_peertube_node),
'man': (unsupported_visit_peertube, None),
'texinfo': (unsupported_visit_peertube, None),
'text': (unsupported_visit_peertube, None)
}
def setup(app):
app.add_node(peertube, **_NODE_VISITORS)
app.add_directive("peertube", PeerTube)
app.add_config_value('peertube_instance', "", True, [str])
return {
'parallel_read_safe': True,
'parallel_write_safe': True,
}
|