/
web.py
executable file
·159 lines (130 loc) · 5.8 KB
/
web.py
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
from bbcode import *
import re
import urllib
class Url(TagNode):
"""
Creates a hyperlink.
Usage:
[code lang=bbdocs linenos=0][url=<http://www.domain.com>]Text[/url]
[url]http://www.domain.com[/url][/code]
"""
verbose_name = 'Link'
open_pattern = re.compile(r'(\[url\]|\[url="?(?P<href>[^\]]+)"?\]|\[url (?P<arg1>\w+)="?(?P<val1>[^ ]+)"?( (?P<arg2>\w+)="?(?P<val2>[^ ]+)"?)?\])')
close_pattern = re.compile(patterns.closing % 'url')
def parse(self):
gd = self.match.groupdict()
gd.update({'css':''})
if gd['arg1']:
gd[gd['arg1']] = gd['val1']
if gd['arg2']:
gd[gd['arg2']] = gd['val2']
if gd['href']:
href = self.variables.resolve(gd['href'])
inner = self.parse_inner()
else:
inner = ''
for node in self.nodes:
if node.is_text_node or isinstance(node, AutoDetectURL):
inner += node.raw_content
else:
soft_raise("Url tag cannot have nested tags without an argument.")
return self.raw_content
href = self.variables.resolve(inner)
inner = href
if gd['css']:
css = ' class="%s"' % gd['css'].replace(',',' ')
else:
css = ''
raw_href = self.variables.resolve(href)
if raw_href.startswith('http://'):
href = raw_href[:7] + urllib.quote(raw_href[7:])
else:
href = urllib.quote(raw_href)
css = self.variables.resolve(css)
return '<a href="%s"%s>%s</a>' % (href, css, inner)
class Email(ArgumentTagNode):
"""
Creates an email link.
Usage:
[code lang=bbdocs linenos=0][email]name@domain.com[/email]
[email=<name@domain.com>]Text[/email][/code]
"""
verbose_name = 'E-Mail'
open_pattern = re.compile(patterns.single_argument % 'email')
close_pattern = re.compile(patterns.closing % 'email')
def parse(self):
if self.argument:
inner = ''
for node in self.nodes:
if isinstance(node, AutoDetectURL):
inner += node.raw_content
else:
inner += node.parse()
return '<a href="mailto:%s">%s</a>' % (self.argument, inner)
else:
inner = ''
for node in self.nodes:
inner += node.raw_content
return '<a href="mailto:%s">%s</a>' % (inner, inner)
class Img(ArgumentTagNode):
"""
Displays an image.
Usage:
[code lang=bbdocs linenos=0][img]http://www.domain.com/image.jpg[/img]
[img=<align>]http://www.domain.com/image.jpg[/img][/code]
Arguments:
Allowed values for [i]align[/i]: left, center, right. Default: None.
"""
verbose_name = 'Image'
open_pattern = re.compile(patterns.single_argument % 'img')
close_pattern = re.compile(patterns.closing % 'img')
def parse(self):
inner = ''
for node in self.nodes:
if node.is_text_node or isinstance(node, AutoDetectURL):
inner += node.raw_content
else:
soft_raise("Img tag cannot have nested tags without an argument.")
return self.raw_content
inner = self.variables.resolve(inner)
if self.argument:
return '<img src="%s" alt="image" class="img-%s" />' % (inner, self.argument)
else:
return '<img src="%s" alt="image" />' % inner
class Youtube(TagNode):
"""
Includes a youtube video. Post the URL to the youtube video inside the tag.
Usage:
[code lang=bbdocs linenos=0][youtube]http://www.youtube.com/watch?v=FjPf6B8EVJI[/youtube][/code]
"""
_video_id_pattern = re.compile('v=(\w+)')
open_pattern = re.compile(patterns.no_argument % 'youtube')
close_pattern = re.compile(patterns.closing % 'youtube')
def parse(self):
url = ''
for node in self.nodes:
if node.is_text_node or isinstance(node, AutoDetectURL):
inner += node.raw_content
else:
soft_raise("Youtube tag cannot have nested tags")
return self.raw_content
match = self._video_id_pattern.search(url)
if not match:
soft_raise("'%s' does not seem like a youtube link" % url)
return self.raw_content
videoid = match.groups()
if not videoid:
soft_raise("'%s' does not seem like a youtube link" % url)
return self.raw_content
videoid = videoid[0]
return """<object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/%s&hl=en&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/%s&hl=en&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>""" % (videoid, videoid)
class AutoDetectURL(SelfClosingTagNode):
open_pattern = re.compile('[^[\]](?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~/|/)?(?#Username:Password)(?:\w+:\w+@)?(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?[^[\]]')
def parse(self):
url = self.match.group()
return '<a href="%s">%s</a>' % (url, url)
register(Url)
register(Img)
register(Email)
register(Youtube)
register(AutoDetectURL)