root/trunk/vertical/rest/preprocessors.py

Revision 226, 8.4 kB (checked in by mksoft, 10 months ago)

Small fix for auto buffering

Line 
1 # Copyright 2006, Meir Kriheli <meir@mksoft.co.il>
2 #
3 # This file is part of Lahak
4 #
5 # Lahak is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # any later version.
9 #
10 # Lahak is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Lahak; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 #
19 # vim: set ts=4 sw=4 et:
20
21 from lahak.vertical.core.protocols import supported_protocols, get_protocol_display
22 from lahak.vertical.uploads.models import Image, Audio
23 from lahak.vertical.core.templatetags.lahak_general import resize
24 from django.db.models.base import ObjectDoesNotExist
25 import urllib, re
26 from django.utils.translation import ugettext as _
27
28 class ProtocolsPreProcessor(object):
29     "Converts lahak supported protocols in the content to links"
30
31     def __call__(self, content):
32        
33         autolinks = supported_protocols.get_regexp().findall(content)
34
35         for match in autolinks:
36             the_model = supported_protocols.get_protocols()[match[1]]
37             try:
38                 # we're looking for a 'lookup' key in the model's
39                 # LahakMeta.protocol, if not, fallback to id
40                 lookup = { the_model.LahakMeta.protocol.get('lookup','id'): match[2] }
41
42                 data = the_model.objects.get(**lookup)
43                 label = get_protocol_display(data)
44
45                 content = content.replace( match[0], r"`%s <%s>`_" % (label, data.get_absolute_url() ) )
46             except ObjectDoesNotExist:
47                 # hmm, object not found, let's try to deal with it.
48                 # Does the manager has 'protocol_new_path' property ?
49                 # If so, use it. Otherwise fail silently, and keep
50                 # the text as is
51                 new_path = the_model.LahakMeta.protocol.get('new_path', None)
52                 if new_path:
53                     content = content.replace(match[0], r"`%s <%s%s>`_" % ( match[2], new_path, urllib.quote_plus( match[2].encode('utf-8') )) )
54                 else:
55                     # we don't want to get stuck with the vertical bars, as
56                     # they defint reST references, so we'll replace them
57                     content = content.replace(match[0], r"`%s </error_404>`_" % match[2])
58
59         return content
60        
61 class UploadedImagePreProcessor(object):
62     """Converts lahak image directive pointing to an image id to proper reST
63     directives.
64     
65     If width or height is smaller than original image, creates thumbnails
66     on the fly"""
67
68     regexp = re.compile( '\.\. (%s|image):: (\d+)((\s+:.+:\s+.*?\s*\n)*)' % _('image'), re.MULTILINE )
69     width_regexp = re.compile(r'([ |\t]*):(%s|width):\s+(\d+)' % _('width'))
70     height_regexp= re.compile(r'([ |\t]*):(%s|height):\s+(\d+)' % _('height'))
71
72     def _replace_image_url( self, matchobj ):
73        
74         params = matchobj.group(3)
75         url = '.. %s:: %s%s'
76         try:
77             img = Image.objects.get(pk=int(matchobj.group(2)))
78
79             width_match = self.width_regexp.findall(params)
80             height_match = self.height_regexp.findall(params)
81
82             # width is specified, to we need to generate the thumbnail
83             if width_match:
84                 width = int(width_match[0][2])
85                 image_url = resize(img.get_image_url() ,'width=%d' % width)
86                 params = "\n%s:target: %s%s" % (width_match[0][0], img.get_image_url(), params)
87             elif height_match:
88                 height = int(height_match[0][2])
89                 image_url = resize(img.get_image_url() ,'height=%d' % height)
90                 params = "\n%s:target: %s%s" % (height_match[0][0], img.get_image_url(), params)
91             else:
92                 image_url = img.get_image_url()
93                
94             return url % ( matchobj.group(1), image_url , params )
95         except ObjectDoesNotExist:
96             return url % ( matchobj.group(1), matchobj.group(2) )
97
98     def __call__(self, content):
99         content = self.regexp.sub(self._replace_image_url, content)
100         return content
101
102
103 class ParameterTranslationPreProcessor(object):
104     """Replaces translated reST paramaters to original ones
105     (reST doesn't support param translations)"""
106
107     translations = (
108         ( _('width'), 'width' ),
109         ( _('height'), 'height' ),
110         ( _('alt'), 'alt' ),
111     )
112
113     def __call__(self, content):
114         # since image params are not translatable by reST, will subst them here
115
116         for tr in self.translations:
117             content = content.replace( ':%s:' % tr[0], ':%s:' % tr[1])
118         return content
119
120
121 class AdmonitionsPreProcessor(object):
122     """Translate block admonitions to general admonition.
123     
124     Since we want the special style name generated by admonitions, but can't
125     support unicode (hence Hebrew in style names, a post precessor is also
126     required"""
127
128     translations = (
129         ( _('exercise'), 'exercise' ),
130         ( _('quote'), 'quote' ),
131     )
132    
133     def __call__(self, content):
134         for tr in self.translations:
135             content = content.replace( '.. %s::' % tr[0], '.. admonition:: %s' % tr[1])
136         return content
137
138 class SanitizePreProcessor(object):
139     """Sanitize unwanted javascript (and other) in links"""
140
141     regexp_hyperlink = re.compile(r'(\.\.\s*\_.*?:\s*)(.*script:)(.*)', re.MULTILINE)
142     regexp_hyperlink_embedded = re.compile(r'(\`.*?\<)(.*?script:)(.*?\>\`_)', re.MULTILINE)
143
144
145     def __call__(self, content):
146         content = self.regexp_hyperlink.sub(r'\1script_not_allowed\3', content)
147         content = self.regexp_hyperlink_embedded.sub(r'\1script_not_allowed\3', content)
148         return content
149
150 class UploadedAudioPreProcessor(object):
151
152     # replaces all |audio|fileid| to some prevalue, later will be replaced in the
153     # post processor to the flash applet
154
155     def __call__(self, content):
156        
157         def repl_func(match):
158             return "lahakaudio__%s__lahakaudio" % match.group(1)
159
160         re_str = u"\|%s\|(\d+)\|" % _("audio")
161          
162         content = re.sub(re_str, repl_func,content)
163
164         return content
165
166 # builtin special protocols dict, key is protocol name, value is a tuple of 2 element:
167 # regex_find, regex replace
168
169 YOUTUBE_STR = r"""
170 <object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/\1"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/\1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>
171
172 """
173
174 YOUTUBE_HELP = "youtube.com/watch?v=xxx "+ _("will be") +" xxx"
175
176 GOOGLE_VIDEO_STR = r"""
177 <embed style="width:400px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=\1&amp;hl=en" flashvars=""> </embed>
178 """
179
180 GOOGLE_VIDEO_HELP = "video.google.com/videoplay?docid=-xyz " + _("will be") + " -xyz"
181
182 FLICKR_STR = r"""
183 <iframe align="center" src="http://www.flickr.com/photos/\1/show/" frameborder="0" width="100%" height="500" scrolling="yes"></iframe>
184 """
185
186 FLICKR_HELP = "flickr.com/photos/user_name/ "+ _("will be") +"  user_name, flickr.com/photos/user_name/tags/airplane/ " + _("will be") +" usrename/tags/airplane "
187
188 VIDEO_STR = r"""<embed height="268" width="320" flashvars='config={"videoFile":"\1","autoPlay":false,"autoBuffering":false}' pluginspage="http://www.adobe.com/go/getflashplayer" type="application/x-shockwave-flash" bgcolor="#ffffff" quality="high" allowscriptaccess="always" allowfullscreen="true" src="/media/swf/FlowPlayerDark.swf"/>"""
189
190 VIDEO_HELP = _("Link to any flash supported video")
191
192 BUILTIN_PROTOCOLOS={
193     _('youtube'): (r'(.*)', YOUTUBE_STR, YOUTUBE_HELP),
194     _('google_video'): (r'(.*)', GOOGLE_VIDEO_STR, GOOGLE_VIDEO_HELP),
195     _('flickr'): (r'(.*)', FLICKR_STR, FLICKR_HELP),
196     _('video'): (r'(.*)', VIDEO_STR, VIDEO_HELP),
197 }
198
199 class SpecialProtocolsPreProcessor(object):
200     "Handles special protocols"
201
202     def __init__(self):
203         "Build a preprocessing regex"
204         re_str = r"\|(%s)\|(.*?)\|" % '|'.join(BUILTIN_PROTOCOLOS.keys())
205
206         self.protocols_re = re.compile(re_str, re.UNICODE)
207
208     def __call__(self, content):
209
210         return self.protocols_re.sub( r'lahakprotocol__\1__\2__lahakprotocol', content )
211
Note: See TracBrowser for help on using the browser.