a79f55a0b81c8b9a2ab86d5404d8ed3d35256902
[markerbeacon.git] / plugins / pelican_youtube / youtube.py
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2013 Kura
4 # Permission is hereby granted, free of charge, to any person obtaining a copy
5 # of this software and associated documentation files (the "Software"), to deal
6 # in the Software without restriction, including without limitation the rights
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 # copies of the Software, and to permit persons to whom the Software is
9 # furnished to do so, subject to the following conditions:
10
11 # The above copyright notice and this permission notice shall be included in
12 # all copies or substantial portions of the Software.
13
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 # SOFTWARE.
21
22 from __future__ import unicode_literals
23
24 from docutils import nodes
25 from docutils.parsers.rst import directives, Directive
26
27
28 class YouTube(Directive):
29     """ Embed YouTube video in posts.
30
31     Based on the YouTube directive by Brian Hsu:
32     https://gist.github.com/1422773
33
34     VIDEO_ID is required, other arguments are optional
35
36     Usage:
37     .. youtube:: VIDEO_ID
38     """
39
40     def boolean(argument):
41         """Conversion function for yes/no True/False."""
42         value = directives.choice(argument, ('yes', 'True', 'no', 'False'))
43         return value in ('yes', 'True')
44
45     required_arguments = 1
46     optional_arguments = 5
47     option_spec = {
48         'class': directives.unchanged,
49         'width': directives.positive_int,
50         'height': directives.positive_int,
51         'allowfullscreen': boolean,
52         'seamless': boolean,
53     }
54
55     final_argument_whitespace = False
56     has_content = False
57
58     def run(self):
59         videoID = self.arguments[0].strip()
60         url = 'https://www.youtube.com/embed/{}'.format(videoID)
61
62         width = self.options['width'] if 'width' in self.options else None
63         height = self.options['height'] if 'height' in self.options else None
64         fullscreen = self.options['allowfullscreen'] \
65             if 'allowfullscreen' in self.options else True
66         seamless = self.options['seamless'] \
67             if 'seamless' in self.options else True
68
69         css_classes = 'youtube'
70         if 'class' in self.options:
71             css_classes += ' {}'.format(self.options['class'])
72         elif height is None:
73             # use responsive design with 16:9 aspect ratio by default
74             css_classes += ' {}'.format('youtube-16x9')
75         # no additional classes if dimensions (height/width) are specified
76
77         iframe_arguments = [
78             (width, 'width="{}"'),
79             (height, 'height="{}"'),
80             (fullscreen, 'allowfullscreen'),
81             (seamless, 'seamless frameBorder="0"'),
82         ]
83
84         div_block = '<div class="{}">'.format(css_classes)
85         embed_block = '<iframe src="{}" '.format(url)
86
87         for value, format in iframe_arguments:
88             embed_block += (format + ' ').format(value) if value else ''
89
90         embed_block = embed_block[:-1] + '></iframe>'
91
92         return [
93             nodes.raw('', div_block, format='html'),
94             nodes.raw('', embed_block, format='html'),
95             nodes.raw('', '</div>', format='html'),
96         ]
97
98
99 def register():
100     directives.register_directive('youtube', YouTube)