1
2 import datetime
3 import logging
4 import uuid
5
6 from urllib import quote
7
8
9 from cherrypy import request, NotFound
10 from turbogears import (config, controllers, expose, error_handler, flash,
11 identity, redirect, url, validate, validators, visit)
12 from turbogears.view import variable_providers
13
14
15 from spammcan.model import Format, Paste, Style, session
16
17 from spammcan.forms import (paste_form, Range, style_select, ValidPasteGuid,
18 ValidStyle)
19 from spammcan.release import version as sc_version
20 from spammcan.util import (absolute_url, add_global_tmpl_vars, code2html,
21 get_user_id, get_server_name, get_static_content, txt2html, wrap_text)
22
23
24 log = logging.getLogger("spammcan.controllers")
25 variable_providers.append(add_global_tmpl_vars)
26
27
28 -class Root(controllers.RootController):
29 """The root controller of the application."""
30
31 @expose(template="spammcan.templates.paste")
32 @validate(validators=dict(
33 paste=ValidPasteGuid(),
34 hl=Range(if_invalid=None),
35 ln=validators.StringBoolean(if_invalid=True),
36 st=ValidStyle(if_invalid=None, convert_value=False),
37 wrap=validators.Int(if_invalid=None)))
38 - def index(self, paste=None, hl=None, ln=True, st=None, wrap=80,
39 tg_errors=None):
40 """"Show the paste given by GUID."""
41 if tg_errors:
42 flash(_(u'Paste not found.'))
43 paste = None
44
45 if paste is None:
46 redirect('/new')
47
48 try:
49 if wrap:
50 wrapped_lines, code = wrap_text(paste.code, wrap)
51 if wrapped_lines:
52 hl = set(hl or [])
53 hl.update(wrapped_lines)
54 hl = list(hl)
55 flash(_(u"Some long lines have been wrapped at %i chars "
56 "and highlighted. Add '?wrap=no' to the paste URL to "
57 "disable line wrapping.") % wrap)
58 else:
59 code = paste.code
60 html, css = code2html(code, paste.format.name, style=st,
61 hl_lines=hl, linenos=ln)
62 except:
63 log.exception('Syntax highlighting error.')
64 flash(_(u'Internal error. Syntax highlighting disabled.'))
65 html = '<pre class="source">%s</pre>' % paste.code
66 css = None
67
68
69
70 subject = _(u"Link for paste '%s' on %s") % (paste.title or
71 _(u"untitled"), get_server_name())
72 paste_url = absolute_url(['/paste', paste.guid], st=st)
73 mailto_url = 'mailto:?subject=%s&body=%s' % (quote(subject, ''),
74 quote(paste_url, ''))
75
76 styles = list(Style.options())
77 pagetitle = _(u"Serving paste '%s' fresh from the SpammCan") % (
78 paste.title or 'untitled',)
79 paste.last_access = datetime.datetime.now()
80 session.flush()
81 return dict(
82 paste = paste,
83 pretty_code = html,
84 css = css,
85 pagetitle = pagetitle,
86 mailto_url = mailto_url,
87 lineno = not ln,
88 style_select = style_select,
89 form_values = dict(st=st or 'default'),
90 form_params = dict(
91 action=url(['/paste', paste.guid]),
92 child_args=dict(st={'options': styles})))
93 paste = index
94
95 @expose(content_type="text/plain")
96 @validate(validators=dict(paste=ValidPasteGuid()))
97 - def download(self, paste, tg_errors=None, *args, **kw):
98 """Serve the paste given by GUID as plain text."""
99 if tg_errors:
100 raise NotFound
101 paste.last_access = datetime.datetime.now()
102 session.flush()
103 return paste.code
104
105 @expose(template="spammcan.templates.new")
106 @validate(validators=dict(paste=ValidPasteGuid(if_invalid=None)))
107 - def new(self, paste=None, tg_errors=None):
131
132 @expose(template="spammcan.templates.paste")
133 @validate(form=paste_form)
134 @error_handler(new)
135 - def create(self, code, format=None, title=None):
146
147 @expose(template='spammcan.templates.list')
154
155 @expose(template="spammcan.templates.static")
156 - def about(self, package=None):
157 """Display information page about the software."""
158 content = get_static_content('about.rst')
159 return dict(
160 pagetitle = _(u'About'),
161 heading = _(u'About this site'),
162 content = content,
163 message = _(u'This site is powered by SpammCan version %s.'
164 ) % sc_version
165 )
166
167 @expose(template="spammcan.templates.static")
168 - def help(self, package=None):
169 """Display usage information for the software."""
170 content = get_static_content('help.rst')
171 return dict(
172 pagetitle = _(u'Help'),
173 heading = _(u'How to use the SpammCan'),
174 content = content
175 )
176
177 @expose(template="spammcan.templates.login")
178 - def login(self, forward_url=None, *args, **kw):
179 """Show the login form or forward user to previously requested page."""
180
181 if forward_url:
182 if isinstance(forward_url, list):
183 forward_url = forward_url.pop(0)
184 else:
185 del request.params['forward_url']
186
187 new_visit = visit.current()
188 if new_visit:
189 new_visit = new_visit.is_new
190
191 if (not new_visit and not identity.current.anonymous
192 and identity.was_login_attempted()
193 and not identity.get_identity_errors()):
194 redirect(forward_url or '/', kw)
195
196 if identity.was_login_attempted():
197 if new_visit:
198 msg = _(u"Cannot log in because your browser "
199 "does not support session cookies.")
200 else:
201 msg = _(u"The credentials you supplied were not correct or "
202 "did not grant access to this resource.")
203 elif identity.get_identity_errors():
204 msg = _(u"You must provide your credentials before accessing "
205 "this resource.")
206 else:
207 msg = _(u"Please log in.")
208 if not forward_url:
209 forward_url = request.headers.get("Referer", "/")
210
211
212
213 return dict(logging_in=True, message=msg,
214 forward_url=forward_url, previous_url=request.path_info,
215 original_parameters=request.params)
216
217 @expose()
219 """Log out the current identity and redirect to start page."""
220 identity.current.logout()
221 redirect("/")
222