]> git.ipfire.org Git - pbs.git/blame - web/ui_modules.py
Break line between build headline and summary.
[pbs.git] / web / ui_modules.py
CommitLineData
f6e6ff79 1#!/usr/bin/python
9137135a 2
cd870d0a 3import pytz
f6e6ff79
MT
4import re
5import string
e434b018 6import textile
f6e6ff79 7import tornado.escape
9137135a
MT
8import tornado.web
9
f6e6ff79 10import backend.users
9137135a
MT
11from backend.constants import *
12
13class UIModule(tornado.web.UIModule):
14 @property
15 def pakfire(self):
16 return self.handler.application.pakfire
17
f6e6ff79
MT
18 @property
19 def settings(self):
20 return self.pakfire.settings
21
22
23class TextModule(UIModule):
c764ce43 24 __cache = {}
f6e6ff79 25
c764ce43 26 LINK = """<a href="%s" target="_blank">%s</a>"""
f6e6ff79 27
c764ce43
MT
28 @property
29 def bugzilla_url(self):
30 return self.settings.get("bugzilla_url", "")
f6e6ff79 31
c764ce43
MT
32 @property
33 def bugzilla_pattern(self):
34 if not self.__cache.has_key("bugzilla_pattern"):
35 self.__cache["bugzilla_pattern"] = re.compile(BUGZILLA_PATTERN)
36
37 return self.__cache["bugzilla_pattern"]
38
39 @property
40 def bugzilla_repl(self):
41 return self.LINK % (self.bugzilla_url % { "bugid" : r"\2" }, r"\1\2")
42
43 @property
44 def cve_url(self):
45 return self.settings.get("cve_url", "")
46
47 @property
48 def cve_pattern(self):
49 if not self.__cache.has_key("cve_pattern"):
50 self.__cache["cve_pattern"] = re.compile(CVE_PATTERN)
51
52 return self.__cache["cve_pattern"]
53
54 @property
55 def cve_repl(self):
56 return self.LINK % (self.cve_url % r"\3", r"\1\2\3")
c21cb4ec 57
c764ce43
MT
58 def render(self, text, pre=False, remove_linebreaks=True):
59 link = """<a href="%s" target="_blank">%s</a>"""
f6e6ff79 60
c764ce43
MT
61 if remove_linebreaks:
62 text = text.replace("\n", " ")
f6e6ff79 63
c764ce43
MT
64 # Escape the text and create make urls clickable.
65 text = tornado.escape.xhtml_escape(text)
66 text = tornado.escape.linkify(text, shorten=True,
67 extra_params='target="_blank"')
f6e6ff79 68
c764ce43
MT
69 # Search for bug ids that need to be linked to bugzilla.
70 if self.bugzilla_url:
71 text = re.sub(self.bugzilla_pattern, self.bugzilla_repl, text, re.I|re.U)
f6e6ff79 72
c764ce43
MT
73 # Search for CVE numbers and create hyperlinks.
74 if self.cve_url:
75 text = re.sub(self.cve_pattern, self.cve_repl, text, re.I|re.U)
f6e6ff79
MT
76
77 if pre:
c764ce43 78 return "<pre>%s</pre>" % text
f6e6ff79 79
c764ce43 80 return textile.textile(text)
f6e6ff79
MT
81
82
83class ModalModule(UIModule):
84 def render(self, what, **kwargs):
85 what = "modules/modal-%s.html" % what
9137135a 86
f6e6ff79
MT
87 return self.render_string(what, **kwargs)
88
89
90class BuildHeadlineModule(UIModule):
91 def render(self, prefix, build, short=False, shorter=False):
92 if shorter:
93 short = True
94
95 return self.render_string("modules/build-headline.html",
96 prefix=prefix, build=build, pkg=build.pkg, short=short, shorter=shorter)
97
98
99class BugsTableModule(UIModule):
100 def render(self, pkg, bugs):
101 return self.render_string("modules/bugs-table.html",
102 pkg=pkg, bugs=bugs)
103
104
4b1e87c4
MT
105class ChangelogModule(UIModule):
106 def render(self, name=None, builds=None, *args, **kwargs):
107 if not builds:
108 builds = self.pakfire.builds.get_changelog(name, *args, **kwargs)
109
110 return self.render_string("modules/changelog/index.html", builds=builds)
111
112
113class ChangelogEntryModule(UIModule):
114 def render(self, build):
115 return self.render_string("modules/changelog/entry.html", build=build)
116
117
f6e6ff79
MT
118class CommitsTableModule(UIModule):
119 def render(self, distro, source, commits, full_format=True):
120 return self.render_string("modules/commits-table.html",
121 distro=distro, source=source, commits=commits,
122 full_format=full_format)
123
124
125class FooterModule(UIModule):
126 def render(self):
127 return self.render_string("modules/footer.html")
128
129
130class PackagesTableModule(UIModule):
131 def render(self, job, packages):
132 return self.render_string("modules/packages-table.html", job=job,
133 packages=packages)
9137135a
MT
134
135
136class PackageTable2Module(UIModule):
137 def render(self, packages):
138 return self.render_string("modules/package-table-detail.html",
139 packages=packages)
140
141
142class FilesTableModule(UIModule):
143 def render(self, files):
144 return self.render_string("modules/files-table.html", files=files)
145
146
f6e6ff79
MT
147class LogFilesTableModule(UIModule):
148 def render(self, job, files):
149 return self.render_string("modules/log-files-table.html", job=job,
150 files=files)
151
152
153class PackageHeaderModule(UIModule):
154 def render(self, pkg):
155 return self.render_string("modules/package-header.html", pkg=pkg)
156
157
9137135a 158class PackageFilesTableModule(UIModule):
f6e6ff79
MT
159 def render(self, pkg, filelist):
160 return self.render_string("modules/packages-files-table.html",
161 pkg=pkg, filelist=filelist)
9137135a
MT
162
163
164class BuildTableModule(UIModule):
f6e6ff79
MT
165 def render(self, builds, **kwargs):
166 settings = dict(
167 show_user = False,
168 show_repo = False,
169 show_repo_time = False,
170 show_can_move_forward = False,
171 show_when = True,
172 )
173 settings.update(kwargs)
174
175 return self.render_string("modules/build-table.html",
176 builds=builds, **settings)
177
178
179class BuildStateWarningsModule(UIModule):
180 def render(self, build):
181 return self.render_string("modules/build-state-warnings.html", build=build)
182
183
184class JobsTableModule(UIModule):
185 def render(self, build, jobs=None, type="release"):
186 if jobs is None:
187 jobs = build.jobs
188
189 return self.render_string("modules/jobs-table.html", build=build,
190 jobs=jobs, type=type)
191
192
193class JobsListModule(UIModule):
194 def render(self, jobs, show_builder=False):
195 return self.render_string("modules/jobs-list.html", jobs=jobs,
196 show_builder=show_builder)
9137135a
MT
197
198
199class RepositoryTableModule(UIModule):
200 def render(self, distro, repos):
201 return self.render_string("modules/repository-table.html",
202 distro=distro, repos=repos)
203
204
205class SourceTableModule(UIModule):
206 def render(self, distro, sources):
207 return self.render_string("modules/source-table.html",
208 distro=distro, sources=sources)
209
210
211class CommentsTableModule(UIModule):
212 def render(self, comments, show_package=False, show_user=True):
213 pkgs, users = {}, {}
214 for comment in comments:
215 if show_package:
216 try:
217 pkg = pkgs[comment.pkg_id]
218 except KeyError:
219 pkg = pkgs[comment.pkg_id] = \
220 self.pakfire.packages.get_by_id(comment.pkg_id)
221
222 comment["pkg"] = pkg
223
224 if show_user:
225 try:
226 user = users[comment.user_id]
227 except KeyError:
228 user = users[comment.user_id] = \
229 self.pakfire.users.get_by_id(comment.user_id)
230
231 comment["user"] = user
232
233 return self.render_string("modules/comments-table.html",
234 comments=comments, show_package=show_package, show_user=show_user)
235
236
f6e6ff79
MT
237class LogModule(UIModule):
238 def render(self, entries, **args):
239 return self.render_string("modules/log.html",
240 entries=entries, args=args)
241
242
243class LogEntryModule(UIModule):
e434b018
MT
244 def render(self, entry, small=None, **args):
245 if small or entry.system_msg:
246 template = "modules/log-entry-small.html"
247 else:
248 template = "modules/log-entry.html"
249
250 return self.render_string(template, entry=entry, u=entry.user, **args)
f6e6ff79
MT
251
252
253class LogEntryCommentModule(LogEntryModule):
254 def render(self, entry, **args):
255 return self.render_string("modules/log-entry-comment.html",
e434b018 256 entry=entry, u=entry.user, **args)
f6e6ff79
MT
257
258
259class MaintainerModule(UIModule):
260 def render(self, maintainer):
261 if isinstance(maintainer, backend.users.User):
262 type = "user"
263 else:
264 type = "string"
265
266 return self.render_string("modules/maintainer.html",
267 type=type, maintainer=maintainer)
268
269
9137135a
MT
270class BuildLogModule(UIModule):
271 # XXX deprecated
272 def render(self, messages):
273 _ = self.locale.translate
274
275 for message in messages:
276 try:
277 msg = LOG2MSG[message.message]
278 message["message"] = _(msg)
279 except KeyError:
280 pass
281
282 return self.render_string("modules/build-log.html", messages=messages)
283
284
285class LogTableModule(UIModule):
286 def render(self, messages, links=["pkg",]):
287 for message in messages:
288 try:
289 message["message"] = LOG2MSG[message.message]
290 except KeyError:
291 pass
292
293 if message.build_id:
294 message["build"] = self.pakfire.builds.get_by_id(message.build_id)
295
296 elif message.pkg_id:
297 message["pkg"] = self.pakfire.packages.get_by_id(message.pkg_id)
298
299 return self.render_string("modules/log-table.html",
300 messages=messages, links=links)
301
302
303class UsersTableModule(UIModule):
304 def render(self, users):
305 return self.render_string("modules/user-table.html", users=users)
306
307
308class BuildOffsetModule(UIModule):
309 def render(self):
310 return self.render_string("modules/build-offset.html")
311
312
313class RepoActionsTableModule(UIModule):
314 def render(self, repo):
315 actions = repo.get_actions()
316
317 return self.render_string("modules/repo-actions-table.html",
318 repo=repo, actions=actions)
f6e6ff79
MT
319
320
321class UpdatesTableModule(UIModule):
322 def render(self, updates):
323 return self.render_string("modules/updates-table.html", updates=updates)
324
325
326class WatchersSidebarTableModule(UIModule):
327 def css_files(self):
328 return "css/watchers-sidebar-table.css"
329
330 def render(self, build, watchers, limit=5):
331 # Sort the watchers by their realname.
332 watchers.sort(key=lambda watcher: watcher.realname)
333
334 return self.render_string("modules/watchers-sidebar-table.html",
335 build=build, watchers=watchers, limit=limit)
cd870d0a
MT
336
337
338class SelectLocaleModule(UIModule):
339 LOCALE_NAMES = (
340 # local code, English name, name
341 ("ca_ES", u"Catalan", "Catal\xc3\xa0"),
342 ("da_DK", u"Danish", u"Dansk"),
343 ("de_DE", u"German", u"Deutsch"),
344 ("en_GB", u"English (UK)", u"English (UK)"),
345 ("en_US", u"English (US)", u"English (US)"),
346 ("es_ES", u"Spanish (Spain)", u"Espa\xf1ol (Espa\xf1a)"),
347 ("es_LA", u"Spanish", u"Espa\xf1ol"),
348 ("fr_CA", u"French (Canada)", u"Fran\xe7ais (Canada)"),
349 ("fr_FR", u"French", u"Fran\xe7ais"),
350 ("it_IT", u"Italian", u"Italiano"),
351 ("km_KH", u"Khmer", u"\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a"),
352 ("pt_BR", u"Portuguese (Brazil)", u"Portugu\xeas (Brasil)"),
353 ("pt_PT", u"Portuguese (Portugal)", u"Portugu\xeas (Portugal)"),
354 ("ru_RU", u"Russian", u"\u0440\u0443\u0441\u0441\u043a\u0438\u0439"),
355 )
356
357 def render(self, name=None, id=None, preselect=None):
358 return self.render_string("modules/select/locale.html",
359 name=name, id=id, preselect=preselect, supported_locales=self.LOCALE_NAMES)
360
361
362class SelectTimezoneModule(UIModule):
363 def render(self, name=None, id=None, preselect=None):
364 return self.render_string("modules/select/timezone.html",
365 name=name, id=id, preselect=preselect,
366 supported_timezones=pytz.common_timezones)