]>
git.ipfire.org Git - pbs.git/blob - web/ui_modules.py
3 from __future__
import division
15 from backend
.constants
import *
17 class UIModule(tornado
.web
.UIModule
):
20 return self
.handler
.application
.pakfire
24 return self
.pakfire
.settings
27 class TextModule(UIModule
):
30 LINK
= """<a href="%s" target="_blank">%s</a>"""
33 def bugzilla_url(self
):
34 return self
.settings
.get("bugzilla_url", "")
37 def bugzilla_pattern(self
):
38 if not self
.__cache
.has_key("bugzilla_pattern"):
39 self
.__cache
["bugzilla_pattern"] = re
.compile(BUGZILLA_PATTERN
)
41 return self
.__cache
["bugzilla_pattern"]
44 def bugzilla_repl(self
):
45 return self
.LINK
% (self
.bugzilla_url
% { "bugid" : r
"\2" }, r
"\1\2")
49 return self
.settings
.get("cve_url", "")
52 def cve_pattern(self
):
53 if not self
.__cache
.has_key("cve_pattern"):
54 self
.__cache
["cve_pattern"] = re
.compile(CVE_PATTERN
)
56 return self
.__cache
["cve_pattern"]
60 return self
.LINK
% (self
.cve_url
% r
"\3", r
"\1\2\3")
62 def render(self
, text
, pre
=False, remove_linebreaks
=True):
63 link
= """<a href="%s" target="_blank">%s</a>"""
66 text
= text
.replace("\n", " ")
68 # Escape the text and create make urls clickable.
69 text
= tornado
.escape
.xhtml_escape(text
)
70 text
= tornado
.escape
.linkify(text
, shorten
=True,
71 extra_params
='target="_blank"')
73 # Search for bug ids that need to be linked to bugzilla.
75 text
= re
.sub(self
.bugzilla_pattern
, self
.bugzilla_repl
, text
, re
.I|re
.U
)
77 # Search for CVE numbers and create hyperlinks.
79 text
= re
.sub(self
.cve_pattern
, self
.cve_repl
, text
, re
.I|re
.U
)
82 return "<pre>%s</pre>" % text
84 return textile
.textile(text
)
87 class ModalModule(UIModule
):
88 def render(self
, what
, **kwargs
):
89 what
= "modules/modal-%s.html" % what
91 return self
.render_string(what
, **kwargs
)
94 class BuildHeadlineModule(UIModule
):
95 def render(self
, prefix
, build
, short
=False, shorter
=False):
99 return self
.render_string("modules/build-headline.html",
100 prefix
=prefix
, build
=build
, pkg
=build
.pkg
, short
=short
, shorter
=shorter
)
103 class JobsStatusModule(UIModule
):
104 def render(self
, build
):
105 return self
.render_string("modules/jobs/status.html",
106 build
=build
, jobs
=build
.jobs
)
109 class BuildersLoadModule(UIModule
):
111 load
= self
.pakfire
.builders
.get_load()
113 return self
.render_string("modules/builders/load.html", load
=load
)
116 class BugsTableModule(UIModule
):
117 def render(self
, pkg
, bugs
):
118 return self
.render_string("modules/bugs-table.html",
122 class ChangelogModule(UIModule
):
123 def render(self
, name
=None, builds
=None, *args
, **kwargs
):
125 builds
= self
.pakfire
.builds
.get_changelog(name
, *args
, **kwargs
)
127 return self
.render_string("modules/changelog/index.html", builds
=builds
)
130 class ChangelogEntryModule(UIModule
):
131 def render(self
, build
):
132 return self
.render_string("modules/changelog/entry.html", build
=build
)
135 class CommitsTableModule(UIModule
):
136 def render(self
, distro
, source
, commits
, full_format
=True):
137 return self
.render_string("modules/commits-table.html",
138 distro
=distro
, source
=source
, commits
=commits
,
139 full_format
=full_format
)
142 class FooterModule(UIModule
):
144 return self
.render_string("modules/footer.html")
147 class HeadingDateModule(UIModule
):
148 def render(self
, date
):
149 _
= self
.locale
.translate
151 # Check if this is today.
152 today
= datetime
.date
.today()
156 # Check if this was yesterday.
157 yesterday
= today
- datetime
.timedelta(days
=1)
158 if date
== yesterday
:
159 return _("Yesterday")
161 # Convert date to datetime.
162 date
= datetime
.datetime(date
.year
, date
.month
, date
.day
)
164 return self
.locale
.format_date(date
, shorter
=True, relative
=False)
167 class PackagesTableModule(UIModule
):
168 def render(self
, job
, packages
):
169 return self
.render_string("modules/packages-table.html", job
=job
,
173 class PackagesDependencyTableModule(UIModule
):
174 def render(self
, pkg
):
175 if pkg
.type == "source":
177 (None, pkg
.requires
),
181 ("provides", pkg
.provides
),
182 ("requires", pkg
.requires
),
183 ("prerequires", pkg
.prerequires
),
184 ("conflicts", pkg
.conflicts
),
185 ("obsoletes", pkg
.obsoletes
),
186 ("recommends", pkg
.recommends
),
187 ("suggests", pkg
.suggests
),
191 for name
, deps
in all_deps
:
193 has_deps
.append((name
, deps
))
196 span
= math
.floor(12 / len(has_deps
))
203 return self
.render_string("modules/packages/dependency-table.html",
204 pkg
=pkg
, dependencies
=has_deps
, span
=span
)
207 class PackageTable2Module(UIModule
):
208 def render(self
, packages
):
209 return self
.render_string("modules/package-table-detail.html",
213 class FilesTableModule(UIModule
):
214 def render(self
, files
):
215 return self
.render_string("modules/files-table.html", files
=files
)
218 class LogFilesTableModule(UIModule
):
219 def render(self
, job
, files
):
220 return self
.render_string("modules/log-files-table.html", job
=job
,
224 class PackageHeaderModule(UIModule
):
225 def render(self
, pkg
):
226 return self
.render_string("modules/package-header.html", pkg
=pkg
)
229 class PackageFilesTableModule(UIModule
):
230 def render(self
, pkg
, filelist
):
231 return self
.render_string("modules/packages-files-table.html",
232 pkg
=pkg
, filelist
=filelist
)
235 class BuildTableModule(UIModule
):
236 def render(self
, builds
, **kwargs
):
240 show_repo_time
= False,
241 show_can_move_forward
= False,
244 settings
.update(kwargs
)
250 dates
[b
.date
].append(b
)
254 dates
= sorted(dates
.items(), reverse
=True)
256 return self
.render_string("modules/build-table.html", dates
=dates
, **settings
)
259 class BuildStateWarningsModule(UIModule
):
260 def render(self
, build
):
261 return self
.render_string("modules/build-state-warnings.html", build
=build
)
264 class JobsBoxesModule(UIModule
):
265 def render(self
, build
, jobs
=None):
269 return self
.render_string("modules/jobs/boxes.html",
270 build
=build
, jobs
=jobs
)
273 class JobStateModule(UIModule
):
274 def render(self
, job
, cls
=None, show_arch
=False, show_icon
=False, plain
=False):
277 _
= self
.locale
.translate
281 if state
== "aborted":
283 classes
.append("muted")
284 icon
= "icon-warning-sign"
286 elif state
== "dependency_error":
287 text
= _("Dependency problem")
288 classes
.append("text-warning")
291 elif state
== "dispatching":
292 text
= _("Dispatching")
293 classes
.append("text-info")
294 icon
= "icon-download-alt"
296 elif state
== "failed":
298 classes
.append("text-error")
301 elif state
== "finished":
303 classes
.append("text-success")
308 classes
.append("muted")
309 icon
= "icon-asterisk"
311 elif state
== "pending":
313 classes
.append("muted")
316 elif state
== "running":
318 classes
.append("text-info")
321 elif state
== "uploading":
322 text
= _("Uploading")
323 classes
.append("text-info")
324 icon
= "icon-upload-alt"
326 # Return just the string, is state is unknown.
328 text
= _("Unknown: %s") % state
329 classes
.append("muted")
340 if show_icon
and icon
:
341 text
= """<i class="%s"></i> %s""" % (icon
, text
)
343 return """<span class="%s">%s</span>""" % (" ".join(classes
), text
)
346 class JobsTableModule(UIModule
):
347 def render(self
, build
, jobs
=None, type="release"):
351 return self
.render_string("modules/jobs-table.html", build
=build
,
352 jobs
=jobs
, type=type)
355 class JobsListModule(UIModule
):
356 def render(self
, jobs
):
357 return self
.render_string("modules/jobs/list.html", jobs
=jobs
)
360 class RepositoryTableModule(UIModule
):
361 def render(self
, distro
, repos
):
362 return self
.render_string("modules/repository-table.html",
363 distro
=distro
, repos
=repos
)
366 class SourceTableModule(UIModule
):
367 def render(self
, distro
, sources
):
368 return self
.render_string("modules/source-table.html",
369 distro
=distro
, sources
=sources
)
372 class CommentsTableModule(UIModule
):
373 def render(self
, comments
, show_package
=False, show_user
=True):
375 for comment
in comments
:
378 pkg
= pkgs
[comment
.pkg_id
]
380 pkg
= pkgs
[comment
.pkg_id
] = \
381 self
.pakfire
.packages
.get_by_id(comment
.pkg_id
)
387 user
= users
[comment
.user_id
]
389 user
= users
[comment
.user_id
] = \
390 self
.pakfire
.users
.get_by_id(comment
.user_id
)
392 comment
["user"] = user
394 return self
.render_string("modules/comments-table.html",
395 comments
=comments
, show_package
=show_package
, show_user
=show_user
)
398 class LogModule(UIModule
):
399 def render(self
, entries
, **args
):
400 return self
.render_string("modules/log.html",
401 entries
=entries
, args
=args
)
404 class LogEntryModule(UIModule
):
405 def render(self
, entry
, small
=None, **args
):
406 if small
or not entry
.user
:
407 template
= "modules/log-entry-small.html"
409 template
= "modules/log-entry.html"
411 return self
.render_string(template
, entry
=entry
, u
=entry
.user
,
412 show_build
=False, **args
)
415 class LogEntryCommentModule(LogEntryModule
):
416 def render(self
, entry
, show_build
=False, **args
):
417 return self
.render_string("modules/log-entry-comment.html",
418 entry
=entry
, u
=entry
.user
, show_build
=show_build
, **args
)
421 class MaintainerModule(UIModule
):
422 def render(self
, maintainer
):
423 if isinstance(maintainer
, backend
.users
.User
):
428 return self
.render_string("modules/maintainer.html",
429 type=type, maintainer
=maintainer
)
432 class BuildLogModule(UIModule
):
434 def render(self
, messages
):
435 _
= self
.locale
.translate
437 for message
in messages
:
439 msg
= LOG2MSG
[message
.message
]
440 message
["message"] = _(msg
)
444 return self
.render_string("modules/build-log.html", messages
=messages
)
447 class LogTableModule(UIModule
):
448 def render(self
, messages
, links
=["pkg",]):
449 for message
in messages
:
451 message
["message"] = LOG2MSG
[message
.message
]
456 message
["build"] = self
.pakfire
.builds
.get_by_id(message
.build_id
)
459 message
["pkg"] = self
.pakfire
.packages
.get_by_id(message
.pkg_id
)
461 return self
.render_string("modules/log-table.html",
462 messages
=messages
, links
=links
)
465 class UsersTableModule(UIModule
):
466 def render(self
, users
):
467 return self
.render_string("modules/user-table.html", users
=users
)
470 class BuildOffsetModule(UIModule
):
472 return self
.render_string("modules/build-offset.html")
475 class RepoActionsTableModule(UIModule
):
476 def render(self
, repo
):
477 actions
= repo
.get_actions()
479 return self
.render_string("modules/repo-actions-table.html",
480 repo
=repo
, actions
=actions
)
483 class UpdatesTableModule(UIModule
):
484 def render(self
, updates
):
485 return self
.render_string("modules/updates-table.html", updates
=updates
)
488 class WatchersSidebarTableModule(UIModule
):
490 return "css/watchers-sidebar-table.css"
492 def render(self
, build
, watchers
, limit
=5):
493 # Sort the watchers by their realname.
494 watchers
.sort(key
=lambda watcher
: watcher
.realname
)
496 return self
.render_string("modules/watchers-sidebar-table.html",
497 build
=build
, watchers
=watchers
, limit
=limit
)
500 class SelectLocaleModule(UIModule
):
502 # local code, English name, name
503 ("ca_ES", u
"Catalan", "Catal\xc3\xa0"),
504 ("da_DK", u
"Danish", u
"Dansk"),
505 ("de_DE", u
"German", u
"Deutsch"),
506 ("en_GB", u
"English (UK)", u
"English (UK)"),
507 ("en_US", u
"English (US)", u
"English (US)"),
508 ("es_ES", u
"Spanish (Spain)", u
"Espa\xf1ol (Espa\xf1a)"),
509 ("es_LA", u
"Spanish", u
"Espa\xf1ol"),
510 ("fr_CA", u
"French (Canada)", u
"Fran\xe7ais (Canada)"),
511 ("fr_FR", u
"French", u
"Fran\xe7ais"),
512 ("it_IT", u
"Italian", u
"Italiano"),
513 ("km_KH", u
"Khmer", u
"\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a"),
514 ("nl_NL", u
"Dutch", u
"Nederlands"),
515 ("pt_BR", u
"Portuguese (Brazil)", u
"Portugu\xeas (Brasil)"),
516 ("pt_PT", u
"Portuguese (Portugal)", u
"Portugu\xeas (Portugal)"),
517 ("ru_RU", u
"Russian", u
"\u0440\u0443\u0441\u0441\u043a\u0438\u0439"),
518 ("uk_UA", u
"Ukrainian", u
"\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"),
521 # Sort the list of locales by their English name.
522 LOCALE_NAMES
.sort(key
=lambda x
: x
[1])
524 def render(self
, name
=None, id=None, preselect
=None):
525 return self
.render_string("modules/select/locale.html",
526 name
=name
, id=id, preselect
=preselect
, supported_locales
=self
.LOCALE_NAMES
)
529 class SelectTimezoneModule(UIModule
):
530 def render(self
, name
=None, id=None, preselect
=None):
531 return self
.render_string("modules/select/timezone.html",
532 name
=name
, id=id, preselect
=preselect
,
533 supported_timezones
=pytz
.common_timezones
)