def _screenshot_link(self, formatter, ns, params, label): if ns == 'screenshot': # Get screenshot ID and link arguments from macro. match = self.id_re.match(params) if match: screenshot_id = int(match.group(1)) arguments = match.group(2) else: # Bad format of link. return html.a(label, href = formatter.href.screenshots(), title = params, class_ = 'missing') # Create request context. context = Context.from_request(formatter.req)('screenshots-wiki') # Get database access. db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API component. api = self.env[ScreenshotsApi] # Try to get screenshots of that ID. screenshot = api.get_screenshot(context, screenshot_id) # Return macro content if screenshot: return html.a(label, href = formatter.href.screenshots( screenshot['id']) + arguments, title = screenshot['description']) else: return html.a(screenshot_id, href = formatter.href.screenshots(), title = params, class_ = 'missing')
def _download_link(self, formatter, ns, params, label): if ns == 'download': if formatter.req.perm.has_permission('DOWNLOADS_VIEW'): # Create context. context = Context.from_request(formatter.req)('downloads-wiki') db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] # Get download. if re.match(r'\d+', params): download = api.get_download(context, params) else: download = api.get_download_by_file(context, params) if download: # Return link to existing file. return html.a(label, href = formatter.href.downloads(params), title = '%s (%s)' % (download['file'], pretty_size(download['size']))) else: # Return link to non-existing file. return html.a(label, href = '#', title = 'File not found.', class_ = 'missing') else: # Return link to file to which is no permission. return html.a(label, href = '#', title = 'No permission to file.', class_ = 'missing')
def post_process_request(self, req, template, data, content_type): if 'BLOG_VIEW' not in req.perm: return template, data, content_type if '_blog_watch_message_' in req.session: add_notice(req, req.session['_blog_watch_message_']) del req.session['_blog_watch_message_'] if req.authname == 'anonymous': return template, data, content_type # FullBlogPlugin sets the blog_path arg in pre_process_request name = req.args.get('blog_path') if not name: return template, data, content_type klass = self.__class__.__name__ attrs = SubscriptionAttribute.find_by_sid_class_and_target( self.env, req.session.sid, req.session.authenticated, klass, name) if attrs: add_ctxtnav(req, html.a(_("Unwatch This"), href=req.href.blog_watch(name))) else: add_ctxtnav(req, html.a(_("Watch This"), href=req.href.blog_watch(name))) return template, data, content_type
def _download_link(self, formatter, ns, params, label): if ns == 'download': if formatter.req.perm.has_permission('DOWNLOADS_VIEW'): # Get cursor. db = self.env.get_db_cnx() cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] # Get download. download = api.get_download(cursor, params) if download: # Return link to existing file. return html.a(label, href=formatter.href.downloads(params), title=download['file']) else: # Return link to non-existing file. return html.a(label, href='#', title='File not found.', class_='missing') else: # Return link to file to which is no permission. return html.a(label, href='#', title='No permission to file.', class_='missing')
def _link_crash(self, req, uuid, show_uuid=False, sysinfo=False): ret = None try: crash = CrashDump(env=self.env, uuid=uuid) if sysinfo: href = req.href('crash', crash.uuid, 'sysinfo_report') title = 'CrashId#%i (%s)' % (crash.id, crash.uuid) else: if show_uuid: title = str(crash.uuid) else: title = 'CrashId#%i (%s)' % (crash.id, crash.uuid) href = req.href('crash', crash.uuid) if show_uuid: ret = \ tag.a( str(crash.uuid), class_=crash['status'], href=href, title=title, style="white-space: nowrap" ) else: ret = \ tag.a( 'CrashId#%i' % crash.id, class_=crash['status'], href=href, title=crash.uuid ) except ResourceNotFound: pass return ret
def get_navigation_items(self, req): if req.authname and req.authname != 'anonymous': yield 'metanav', 'login', req.authname yield 'metanav', 'logout', html.a('sign out', href=self.logout_url) else: yield 'metanav', 'login', html.a('sign in', href=self.login_url) yield 'metanav', 'logout', html.a('register', href=self.registration_url)
def _download_link(self, formatter, ns, params, label): if ns == 'download': if formatter.req.perm.has_permission('DOWNLOADS_VIEW'): # Get cursor. db = self.env.get_db_cnx() cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] # Get download. download = api.get_download(cursor, params) if download: # Return link to existing file. return html.a(label, href = formatter.href.downloads(params), title = download['file']) else: # Return link to non-existing file. return html.a(label, href = '#', title = 'File not found.', class_ = 'missing') else: # Return link to file to which is no permission. return html.a(label, href = '#', title = 'No permission to file.', class_ = 'missing')
def get_navigation_items(self, req): if req.perm.has_permission('SCREENSHOTS_VIEW'): if self.mainnav_title: yield 'mainnav', 'screenshots', html.a( self.mainnav_title, href=req.href.screenshots()) if self.metanav_title: yield 'metanav', 'screenshots', html.a( self.metanav_title, href=req.href.screenshots())
def get_navigation_items(self, req): if req.perm.has_permission('SCREENSHOTS_VIEW'): if self.mainnav_title: yield 'mainnav', 'screenshots', html.a(self.mainnav_title, href = req.href.screenshots()) if self.metanav_title: yield 'metanav', 'screenshots', html.a(self.metanav_title, href = req.href.screenshots())
def _format_sha_link(self, formatter, ns, sha, label, fullmatch=None): try: changeset = self.env.get_repository().get_changeset(sha) return html.a( label, class_="changeset", title=shorten_line(changeset.message), href=formatter.href.changeset(sha) ) except TracError, e: return html.a( label, class_="missing changeset", href=formatter.href.changeset(sha), title=unicode(e), rel="nofollow" )
def _format_sha_link(self, formatter, ns, sha, label, fullmatch=None): try: changeset = self.env.get_repository().get_changeset(sha) return html.a(label, class_="changeset", title=shorten_line(changeset.message), href=formatter.href.changeset(sha)) except TracError, e: return html.a(label, class_="missing changeset", href=formatter.href.changeset(sha), title=unicode(e), rel="nofollow")
def render_one(page, langs): result = [tag.a(wiki.format_page_name(page), href=formatter.href.wiki(page))] if langs: for lang in sorted(langs): result.append(', ') p = '%s.%s' % (page, lang) result.append(tag.a(lang or 'default', style='color:#833', href=formatter.href.wiki(p))) result[1] = ' (' result.append(')') return result
def _download_link(self, formatter, ns, params, label): if ns == 'download': if formatter.req.perm.has_permission('DOWNLOADS_VIEW'): # Create context. context = Context.from_request(formatter.req)('downloads-wiki') db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] by_id = False # Get download. if params.strip().isdigit(): download = api.get_download(context, params) by_id = True else: download = api.get_download_by_file(context, params) if download: # Get url part to put after "[project]/downloads/" file_part = download['id'] if by_id else download['file'] if formatter.req.perm.has_permission( 'DOWNLOADS_VIEW', Resource('downloads', download['id'])): # Return link to existing file. return html.a( label, href=formatter.href.downloads(file_part), title='%s (%s)' % (download['file'], pretty_size(download['size']))) else: # File exists but no permission to download it. html.a( label, href='#', title='%s (%s)' % (download['file'], pretty_size(download['size'])), class_='missing') else: # Return link to non-existing file. return html.a(label, href='#', title='File not found.', class_='missing') else: # Return link to file to which is no permission. return html.a(label, href='#', title='No permission to file.', class_='missing')
def _pydoc_formatter(self, formatter, ns, object, label): object = urllib.unquote(object) label = urllib.unquote(label) if not object or object == 'index': return html.a(label, class_='wiki', href=formatter.href.pydoc()) else: try: _, target = PyDoc(self.env).load_object(object) doc = pydoc.getdoc(target) if doc: doc = doc.strip().splitlines()[0] return html.a(label, class_='wiki', title=shorten_line(doc), href=formatter.href.pydoc(object)) except ImportError: return html.a(label, class_='missing wiki', href=formatter.href.pydoc(object))
def _get_config_menus(self, req, menu_name): new_menu_option = lambda name: dict( name=name, href='#', enabled=False, parent_name='top') menu, options = {}, {} for option, value in self.config[menu_name].options(): item_parts = option.split('.', 1) name, prop_name = item_parts[ 0], len(item_parts) > 1 and item_parts[1] or 'enabled' if name == 'inherit': options[name] = value continue menu.setdefault(name, new_menu_option(name)) if prop_name == 'parent': menu[name]['parent_name'] = value elif prop_name == 'enabled': menu[name][prop_name] = self.config[menu_name].getbool( option, True) elif prop_name == 'href': value = value.replace('$PATH_INFO', req.path_info) href = value.startswith('/') and (req.href().rstrip('/') + value) or value menu[name]['label'] = menu[name].setdefault( 'label', html.a())(href=href) menu[name][prop_name] = value elif prop_name == 'label': menu[name].setdefault('label', html.a(href='#'))(value) elif prop_name == 'path_info': menu[name]['if_path_info'] = re.match( value, req.path_info) and True or False elif prop_name == 'enabled': menu[name][prop_name] = self.config[menu_name].getbool( option, False) elif prop_name == 'hide_if_no_children': menu[name][prop_name] = self.config[menu_name].getbool( option, False) elif prop_name == 'perm': menu[name][prop_name] = self.config[menu_name].getlist( option, default=[], sep=',') else: menu[name][prop_name] = value # Perform checks for invalid configuration for name in menu: # There won't be an href if there isn't a label if 'label' not in menu[name]: menu[name]['enabled'] = False return menu, options
def filter_stream(self, req, method, filename, stream, data): """ filter hours and estimated hours fields to have them correctly display on the ticket.html """ if filename == 'ticket.html' and 'TICKET_VIEW_HOURS' in req.perm: field = [ field for field in data['fields'] if field['name'] == 'totalhours' ] if field: total_hours = field[0] ticket_id = data['ticket'].id if ticket_id is None: # new ticket field = '0' else: hours = '%.1f' \ % (self.get_total_hours(ticket_id) / 3600.0) field = tag.a(hours, href=req.href('hours', data['ticket'].id), title="hours for ticket %s" % data['ticket'].id) total_hours['rendered'] = field stream |= Transformer( "//input[@id='field-totalhours']").replace(field) return stream
def _link_tickets(self, req, tickets): items = [] for i, word in enumerate(re.split(r'([;,\s]+)', tickets)): if i % 2: items.append(word) elif word: tid = word word = '#%s' % word try: ticket = Ticket(self.env, tid) if 'TICKET_VIEW' in req.perm(ticket.resource): word = \ html.a( '#%s' % ticket.id, href=req.href.ticket(ticket.id), class_=classes(ticket['status'], 'ticket'), title=get_resource_summary(self.env, ticket.resource) ) except ResourceNotFound: pass items.append(word) if items: return html(items) else: return None
def get_navigation_items(self, req): if not req.perm.has_permission('ROADMAP_VIEW'): return yield ('mainnav', 'roadmap', html.a(u'Feuille de route', href=req.href.roadmap(), accesskey=3))
def get_navigation_items(self, req): if self.reset_password_enabled and \ LoginModule(self.env).enabled and \ req.authname == 'anonymous': yield 'metanav', 'reset_password', \ tag.a(_("Forgot your password?"), href=req.href.reset_password())
def _link(resource): if resource.realm == 'tag': # Keep realm selection in tag links. return builder.a(resource.id, href=self.get_href(req, realms, tag=resource)) elif resource.realm == 'ticket': # Return resource link including ticket status dependend # class to allow for common Trac ticket link style. ticket = Ticket(env, resource.id) return builder.a('#%s' % ticket.id, class_=ticket['status'], href=formatter.href.ticket(ticket.id), title=shorten_line(ticket['summary'])) return render_resource_link(env, context, resource, 'compact')
def post_process_request(self, req, template, data, content_type): if template is None or not req.session.authenticated: # Don't start the email verification procedure on anonymous users. return template, data, content_type email = req.session.get('email') # Only send verification if the user entered an email address. if self.verify_email and self.email_enabled is True and email and \ email != req.session.get('email_verification_sent_to') and \ 'ACCTMGR_ADMIN' not in req.perm: req.session['email_verification_token'] = self._gen_token() req.session['email_verification_sent_to'] = email try: AccountManager(self.env)._notify( 'email_verification_requested', req.authname, req.session['email_verification_token'] ) except NotificationError, e: chrome.add_warning(req, _( "Error raised while sending a change notification." ) + _("You should report that issue to a Trac admin.")) self.log.error('Unable to send registration notification: %s', exception_to_unicode(e, traceback=True)) else: # TRANSLATOR: An email has been sent to <%(email)s> # with a token to ... (the link label for following message) link = tag.a(_("verify your new email address"), href=req.href.verify_email()) # TRANSLATOR: ... verify your new email address chrome.add_notice(req, tag_( "An email has been sent to <%(email)s> with a token to " "%(link)s.", email=tag(email), link=link))
def download_link(self, formatter, ns, target, label): if ns == 'download': if 'FILES_DOWNLOADS_VIEW' not in formatter.req.perm: return html.a(label, href='#', title=_('Missing %(permission)s permission', permission='FILES_DOWNLOADS_VIEW'), class_='missing') files_core = FilesCoreComponent(self.env) wiki = ProjectDownloadsWiki(self.env) node_factory, download_config = files_core.files_node_factory_and_config( formatter.req) id_, filename = self._get_id_filename(target) if id_ and filename: primary_path = get_download_path(id_, filename) node = MappedFileNode.from_download_path( primary_path, node_factory, True) if node.exists() and node.is_download(): return wiki.file_link(formatter, 'filesdownload', node.download().download_path, label) node = MappedFileNode.from_download_path( filename, node_factory, True) if node.exists() and node.is_download(): return wiki.file_link(formatter, 'filesdownload', node.download().download_path, label) return wiki.file_link(formatter, 'filesdownload', target, label)
def get_navigation_items(self, req): #self.env.log.debug("FLEX get_navigation_items") node = self._get_node(req) if 'WIKI_CREATE' in req.perm('wiki'): yield('mainnav', 'newpage',\ html.a(_('New page'),\ href=req.href.flexwiki(action='new', page=node.navpath)))
def _link_crashes_by_id(self, req, ids): items = [] for i, word in enumerate(re.split(r'([;,\s]+)', ids)): if i % 2: items.append(word) elif word: crashid = word word = 'CrashId#%s' % word try: crash = CrashDump(env=self.env, id=crashid) word = \ tag.a( 'CrashId#%i' % crash.id, class_=crash['status'], href=req.href('crash', crash.uuid), title=crash.uuid ) except ResourceNotFound: pass items.append(word) if items: return tag(items) else: return None
def _download_link(self, formatter, ns, params, label): if ns == 'download': if formatter.req.perm.has_permission('DOWNLOADS_VIEW'): # Create context. context = Context.from_request(formatter.req)('downloads-wiki') db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] # Get download. if re.match(r'\d+', params): download = api.get_download(context, params) else: download = api.get_download_by_file(context, params) if download: if formatter.req.perm.has_permission( 'DOWNLOADS_VIEW', Resource('downloads', download['id'])): # Return link to existing file. return html.a( label, href=formatter.href.downloads(params), title='%s (%s)' % (download['file'], pretty_size(download['size']))) else: # File exists but no permission to download it. html.a( label, href='#', title='%s (%s)' % (download['file'], pretty_size(download['size'])), class_='missing') else: # Return link to non-existing file. return html.a(label, href='#', title='File not found.', class_='missing') else: # Return link to file to which is no permission. return html.a(label, href='#', title='No permission to file.', class_='missing')
def _format_link(self, formatter, ns, target, label): m = self.date_re.match(target) if not m: return system_message('Invalid IRC Log Link: ' 'Must be of the format channel-UTCYYYY-MM-DDTHH:MM:SS %s') if not m.group('datetime'): return html.a(label, title=label, href=formatter.href.irclogs( m.group('channel'))) else: ch_mgr = IRCChannelManager(self.env) t = strptime(m.group('datetime'), self.date_format) dt = UTC.localize(datetime(*t[:6])) dt = ch_mgr.to_user_tz(formatter.req, dt) timestr = dt.strftime(self.time_format) return html.a(label, title=label, href=formatter.href.irclogs( m.group('channel'), '%02d'%dt.year, '%02d'%dt.month, '%02d'%dt.day,) + '#%s'%timestr)
def _query_link(self, req, name, value, text=None): """Return a link to /query with the appropriate name and value""" default_query = self.crashlink_query.lstrip('?') args = arg_list_to_args(parse_arg_list(default_query)) args[name] = value if name == 'resolution': args['status'] = 'closed' return tag.a(text or value, href=req.href.query(args))
def default_renderer(tag, count, percent): href = self.get_href(req, realms, tag=Resource('tag', tag)) return builder.a(tag, rel='tag', title='%i' % count, href=href, style='font-size: %ipx' % int(min_px + percent * (max_px - min_px)))
def __iter__(self): if self.this_milestone is not None: # for /milestone/xxx milestone = self.this_milestone else: if len(self.buffer.events) >= 4 and len( self.buffer.events[3]) >= 1: milestone = self.buffer.events[3][1] else: self.log.debug( 'see https://trac-hacks.org/ticket/13565 & 13161') milestone = '' if milestone not in self.hours.keys(): return iter([]) hours = self.hours[milestone] estimated_hours = hours['estimatedhours'] total_hours = hours['totalhours'] if not (estimated_hours or total_hours): return iter([]) items = [] if estimated_hours: if parse_version(TRAC_VERSION) < parse_version('1.0'): items.append(tag.dt(_("Estimated Hours:"))) items.append(tag.dd(str(estimated_hours))) else: items.append( tag.span(_("Estimated Hours: "), str(estimated_hours), class_="first interval")) date = hours['date'] link = self.href("hours", milestone=milestone, from_year=date.year, from_month=date.month, from_day=date.day) if parse_version(TRAC_VERSION) < parse_version('1.0'): items.append(tag.dt(tag.a("Total Hours:", href=link))) items.append( tag.dd(tag.a(hours_format % total_hours, href=link))) return iter(tag.dl(*items)) else: items.append( tag.span(tag.a(_("Total Hours: "), hours_format % total_hours, href=link), class_='interval')) return iter(tag.p(*items, class_='legend'))
def exception_code(platform_type, code, name): from trac.util.html import html as tag if platform_type is None: return 'Platform unknown' elif platform_type == 'Linux': return tag.a(str(name) + '(' + hex_format(code) + ')', href='https://en.wikipedia.org/wiki/Unix_signal') elif platform_type == 'Windows NT': return tag.a(str(name) + '(' + hex_format(code) + ')', href='https://en.wikipedia.org/wiki/Windows_NT') elif platform_type == 'Windows': return tag.a(str(name) + '(' + hex_format(code) + ')', href='https://en.wikipedia.org/wiki/Microsoft_Windows') else: return tag.a(str(name) + '(' + hex_format(code) + ')', href='https://en.wikipedia.org/wiki/Special:Search/' + str(platform_type))
def expand_macro(self, formatter, name, content): """ Execute / Render the macro. Return the content to caller. """ if name not in self.macros: return None identifier = self.env.project_identifier project = Project.get(self.env) if project is None: return None if name == 'ProjectName': return project.project_name elif name == 'ProjectIdentifier': return identifier elif name == 'ProjectOwner': return project.author.username elif name == 'ProjectCreateDate': return project.created elif name == 'ProjectUrl': url = project.get_url() txt = content or identifier return html.a(txt, href=url) elif name == 'ProjectVersioncontrolUrl': url = project.get_repository_url() txt = content or url return html.a(txt, href=url) elif name == 'ProjectWebDavUrl': url = project.get_dav_url() txt = content or url return html.a(txt, href=url) elif name == 'WelcomeText': return html.h1("Welcome to " + project.project_name, id="WelcomeToProject")
def format_platform_type(platform_type): from trac.util.html import html as tag from trac.util.translation import _ if platform_type is None: return _('Platform unknown') elif platform_type == 'Linux': return tag.a('Linux', href='https://en.wikipedia.org/wiki/Linux') elif platform_type == 'Windows NT': return tag.a('Windows NT', href='https://en.wikipedia.org/wiki/Windows_NT') elif platform_type == 'Windows': return tag.a('Windows', href='https://en.wikipedia.org/wiki/Microsoft_Windows') else: return tag.a(platform_type, href='https://en.wikipedia.org/wiki/Special:Search/' + str(platform_type))
def expand_macro(self, formatter, name, content): """ Execute / Render the macro. Return the content to caller. """ if name not in self.macros: return None identifier = self.env.project_identifier project = Project.get(self.env) if project is None: return None if name == 'ProjectName': return project.project_name elif name == 'ProjectIdentifier': return identifier elif name == 'ProjectOwner': return project.author.username elif name == 'ProjectCreateDate': return project.created elif name == 'ProjectUrl': url = project.get_url() txt = content or identifier return html.a(txt, href = url) elif name == 'ProjectVersioncontrolUrl': url = project.get_repository_url() txt = content or url return html.a(txt, href = url) elif name == 'ProjectWebDavUrl': url = project.get_dav_url() txt = content or url return html.a(txt, href = url) elif name == 'WelcomeText': return html.h1("Welcome to " + project.project_name, id = "WelcomeToProject")
def filelink(formatter, match, fullmatch): label = None if match[0] == '[': match, label = (fullmatch.group('unc_path'), fullmatch.group('unc_label')) elif match[0] in '"<': match = match[1:-1] return tag.a(label or match, href='file:///%s' % match.replace('\\', '/'))
def _format_link(self, formatter, ns, target, label): kind, module = 'text', 'stuff' try: kind = 'odd' if int(target) % 2 else 'even' module = 'thing' except ValueError: pass return html.a(label, class_='%s resolver' % kind, href=formatter.href(module, target))
def expand_macro(self, formatter, name, content): attachment_type = "" if content: argv = [arg.strip() for arg in content.split(',')] if len(argv) > 0: attachment_type = argv[0] with self.env.db_transaction as db: if attachment_type is None or attachment_type == "": attachments = db(""" SELECT type,id,filename,size,time, description,author,ipnr FROM attachment """) else: attachments = db( """ SELECT type,id,filename,size,time, description,author,ipnr FROM attachment WHERE type=%s """, (attachment_type, )) formatters = { 'wiki': formatter.href.wiki, 'ticket': formatter.href.ticket, 'milestone': formatter.href.milestone, } types = { 'wiki': '', 'ticket': 'ticket ', 'milestone': 'milestone ', } return html.ul([ html.li( html.a(filename, href=formatter.href.attachment(type + '/' + id + '/' + filename)), " (", html.span(pretty_size(size), title=size), ") - added by ", html.em(author), " to ", html.a(types[type] + ' ' + id, href=formatters[type](id)), ' ') for type, id, filename, size, time, description, author, ipnr in attachments if self._has_perm(type, id, filename, formatter.context) ])
def _discussion_link(self, formatter, ns, params, label): id = params # Get database access. db = self.env.get_db_cnx() cursor = db.cursor() if ns == 'forum': columns = ('subject', ) sql = "SELECT f.subject FROM forum f WHERE f.id = %s" self.log.debug(sql % (id, )) cursor.execute(sql, (id, )) for row in cursor: row = dict(zip(columns, row)) return html.a(label, href=formatter.href.discussion(id), title=row['subject']) return html.a(label, href='%s/%s' % (formatter.href.discussion(), id), title=label, class_='missing') elif ns == 'topic': columns = ('forum', 'forum_subject', 'subject') sql = "SELECT t.forum, f.subject, t.subject FROM topic t LEFT" \ " JOIN forum f ON t.forum = f.id WHERE t.id = %s" self.log.debug(sql % (id, )) cursor.execute(sql, (id, )) for row in cursor: row = dict(zip(columns, row)) return html.a(label, href = '%s#-1' % \ (formatter.href.discussion(row['forum'], id),), title = '%s: %s' % (row['forum_subject'], row['subject'])) return html.a(label, href='%s/%s' % (formatter.href.discussion(), id), title=label, class_='missing') elif ns == 'message': columns = ('forum', 'topic', 'forum_subject', 'subject') sql = "SELECT m.forum, m.topic, f.subject, t.subject FROM" \ " message m, (SELECT subject, id FROM forum) f," \ " (SELECT subject, id FROM topic) t WHERE" \ " m.forum = f.id AND m.topic = t.id AND m.id = %s" self.log.debug(sql % (id, )) cursor.execute(sql, (id, )) for row in cursor: row = dict(zip(columns, row)) return html.a(label, href = '%s#%s' % \ (formatter.href.discussion(row['forum'], row['topic'], id), id), title = '%s: %s' % (row['forum_subject'], row['subject'])) return html.a(label, href='%s/%s' % (formatter.href.discussion(), id), title=label, class_='missing') else: return html.a(label, href='%s/%s' % (formatter.href.discussion(), id), title=label, class_='missing')
def get_navigation_items(self, req): ch_mgr = IRCChannelManager(self.env) for channel in ch_mgr.channels(): if req.perm.has_permission(channel.perm()): if channel.name(): href = req.href.irclogs(channel.name()) else: href = req.href.irclogs() l = html.a(channel.navbutton(), href=href) yield "mainnav", channel.menuid(), l
def doxygen_link(formatter, ns, params, label): if '/' not in params: params = self.default_doc+'/'+params segments = params.split('/') if self.html_output: segments[-1:-1] = [self.html_output] action, path, link = self._doxygen_lookup(segments) if action == 'index': return html.a(label, title=self.title, href=formatter.href.doxygen()) if action == 'redirect' and path: return html.a(label, title="Search result for "+params, href=formatter.href.doxygen(link,path=path)) if action == 'search': return html.a(label, title=params, class_='missing', href=formatter.href.doxygen()) else: return html.a(label, title=params, href=formatter.href.doxygen(link, path=path))
def expand_macro(self, formatter, name, content): attachment_type = "" if content: argv = [arg.strip() for arg in content.split(',')] if len(argv) > 0: attachment_type = argv[0] with self.env.db_transaction as db: if attachment_type is None or attachment_type == "": attachments = db(""" SELECT type,id,filename,size,time, description,author,ipnr FROM attachment """) else: attachments = db(""" SELECT type,id,filename,size,time, description,author,ipnr FROM attachment WHERE type=%s """, (attachment_type, )) formatters = { 'wiki': formatter.href.wiki, 'ticket': formatter.href.ticket, 'milestone': formatter.href.milestone, } types = { 'wiki': '', 'ticket': 'ticket ', 'milestone': 'milestone ', } return html.ul( [html.li( html.a(filename, href=formatter.href.attachment(type + '/' + id + '/' + filename)), " (", html.span(pretty_size(size), title=size), ") - added by ", html.em(author), " to ", html.a(types[type] + ' ' + id, href=formatters[type](id)), ' ') for type, id, filename, size, time, description, author, ipnr in attachments if self._has_perm(type, id, filename, formatter.context)])
def get_navigation_items(self, req): if req.authname and req.authname != 'anonymous': # Use the same names as LoginModule to avoid duplicates. yield ('metanav', 'login', _('logged in as %(user)s', user=req.authname)) logout_href = req.href('%s/logout' % self.auth_path_prefix) from pkg_resources import parse_version if parse_version(trac.__version__) < parse_version('1.0.2'): yield ('metanav', 'logout', tag.a(_('Logout'), logout_href)) else: yield ('metanav', 'logout', tag.form(tag.div(tag.button(_('Logout'), name='logout', type='submit')), action=logout_href, method='post', id='logout', class_='trac-logout')) else: yield ('metanav', 'github_login', tag.a(_('GitHub Login'), href=req.href('%s/login' % self.auth_path_prefix)))
def _download_link(self, formatter, ns, params, label): if ns == 'download': if formatter.req.perm.has_permission('DOWNLOADS_VIEW'): # Create context. context = Context.from_request(formatter.req)('downloads-wiki') db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] by_id = False # Get download. if params.strip().isdigit(): download = api.get_download(context, params) by_id = True else: download = api.get_download_by_file(context, params) if download: # Get url part to put after "[project]/downloads/" file_part = download['id'] if by_id else download['file'] if formatter.req.perm.has_permission('DOWNLOADS_VIEW', Resource('downloads', download['id'])): # Return link to existing file. return html.a(label, href = formatter.href.downloads( file_part), title = '%s (%s)' % (download['file'], pretty_size(download['size']))) else: # File exists but no permission to download it. html.a(label, href = '#', title = '%s (%s)' % ( download['file'], pretty_size(download['size'])), class_ = 'missing') else: # Return link to non-existing file. return html.a(label, href = '#', title = 'File not found.', class_ = 'missing') else: # Return link to file to which is no permission. return html.a(label, href = '#', title = 'No permission to file.', class_ = 'missing')
def process_request(self, req): data = dict(_dgettext=dgettext) if req.authname and req.authname != 'anonymous': add_notice(req, tag_( "You're already logged in. If you need to change your " "password please use the %(prefs_href)s page.", prefs_href=tag.a(_("Account Preferences"), href=req.href.prefs('account')))) data['authenticated'] = True if req.method == 'POST': self._do_reset_password(req) return 'reset_password.html', data, None
def expand_macro(self, formatter, name, content): if name == 'ViewTopic': self.log.debug("Rendering ViewTopic macro...") # Determine topic subject page_name = formatter.req.path_info[6:] or 'WikiStart' subject = content or page_name # Create request context. context = Context.from_request(formatter.req) context.realm = 'discussion-wiki' # Get database access. db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API object. api = self.env[DiscussionApi] # Get topic by subject topic = api.get_topic_by_subject(context, subject) self.log.debug('subject: %s' % (subject,)) self.log.debug('topic: %s' % (topic,)) # Prepare request and resource object. if topic: context.req.args['topic'] = topic['id'] context.resource = Resource('discussion', 'topic/%s' % ( topic['id'],)) # Process discussion request. template, data = api.process_discussion(context) # Return rendered template. data['discussion']['mode'] = 'message-list' data['discussion']['page_name'] = page_name if context.redirect_url: # Generate HTML elements for redirection. href = context.req.href(context.redirect_url[0]) + \ context.redirect_url[1] self.log.debug("Redirecting to %s" % (href)) return html.div(html.strong('Redirect: '), ' This page redirects to ', html.a(href, href = href), html.script("window.location = '" + context.req.href( 'discussion', 'redirect', redirect_url = href) + "'", language = "JavaScript"), class_ = "system-message") else: # Render template. return to_unicode(Chrome(self.env).render_template( formatter.req, template, data, 'text/html', True)) else: raise TracError('Not implemented macro %s' % (name))
def _get_config_menus(self, req, menu_name): new_menu_option = lambda name: dict(name=name, href="#", enabled=False, parent_name="top") menu, options = {}, {} for option, value in self.config[menu_name].options(): item_parts = option.split(".", 1) name, prop_name = item_parts[0], len(item_parts) > 1 and item_parts[1] or "enabled" if name == "inherit": options[name] = value continue menu.setdefault(name, new_menu_option(name)) if prop_name == "parent": menu[name]["parent_name"] = value elif prop_name == "enabled": menu[name][prop_name] = self.config[menu_name].getbool(option, True) elif prop_name == "href": value = value.replace("$PATH_INFO", req.path_info) href = value.startswith("/") and (req.href().rstrip("/") + value) or value menu[name]["label"] = menu[name].setdefault("label", html.a())(href=href) menu[name][prop_name] = value elif prop_name == "label": menu[name].setdefault("label", html.a(href="#"))(value) elif prop_name == "path_info": menu[name]["if_path_info"] = re.match(value, req.path_info) and True or False elif prop_name == "enabled": menu[name][prop_name] = self.config[menu_name].getbool(option, False) elif prop_name == "hide_if_no_children": menu[name][prop_name] = self.config[menu_name].getbool(option, False) elif prop_name == "perm": menu[name][prop_name] = self.config[menu_name].getlist(option, default=[], sep=",") else: menu[name][prop_name] = value # Perform checks for invalid configuration for name in menu: # There won't be an href if there isn't a label if "label" not in menu[name]: menu[name]["enabled"] = False return menu, options
def render_watcher(self, req): if not self.ctxtnav_names: return realm, target = self.path_info_to_realm_target(req.path_info) sess = req.session if self.is_watching(sess.sid, sess.authenticated, realm, target): action_name = len(self.ctxtnav_names) >= 2 and \ self.ctxtnav_names[1] or _("Unwatch This") else: action_name = self.ctxtnav_names and \ self.ctxtnav_names[0] or _("Watch This") add_ctxtnav(req, html.a(_(action_name), href=req.href.watch(realm, target)))
def _discussion_link(self, formatter, ns, params, label): id = params # Get database access. db = self.env.get_db_cnx() cursor = db.cursor() if ns == 'forum': columns = ('subject',) sql = "SELECT f.subject FROM forum f WHERE f.id = %s" self.log.debug(sql % (id,)) cursor.execute(sql, (id,)) for row in cursor: row = dict(zip(columns, row)) return html.a(label, href = formatter.href.discussion(id), title = row['subject'].replace('"', '')) return html.a(label, href = '%s/%s' % (formatter.href.discussion(), id), title = label.replace('"', ''), class_ = 'missing') elif ns == 'topic': columns = ('forum', 'forum_subject', 'subject') sql = "SELECT t.forum, f.subject, t.subject FROM topic t LEFT" \ " JOIN forum f ON t.forum = f.id WHERE t.id = %s" self.log.debug(sql % (id,)) cursor.execute(sql, (id,)) for row in cursor: row = dict(zip(columns, row)) return html.a(label, href = '%s#-1' % \ (formatter.href.discussion(row['forum'], id),), title = ('%s: %s' % (row['forum_subject'], row['subject'])) .replace('"', '')) return html.a(label, href = '%s/%s' % (formatter.href.discussion(), id), title = label.replace('"', ''), class_ = 'missing') elif ns == 'message': columns = ('forum', 'topic', 'forum_subject', 'subject') sql = "SELECT m.forum, m.topic, f.subject, t.subject FROM" \ " message m, (SELECT subject, id FROM forum) f," \ " (SELECT subject, id FROM topic) t WHERE" \ " m.forum = f.id AND m.topic = t.id AND m.id = %s" self.log.debug(sql % (id,)) cursor.execute(sql, (id,)) for row in cursor: row = dict(zip(columns, row)) return html.a(label, href = '%s#%s' % \ (formatter.href.discussion(row['forum'], row['topic'], id), id), title = ('%s: %s' % (row['forum_subject'], row['subject'])).replace('"', '')) return html.a(label, href = '%s/%s' % (formatter.href.discussion(), id), title = label.replace('"', ''), class_ = 'missing') else: return html.a(label, href = '%s/%s' % (formatter.href.discussion(), id), title = label.replace('"', ''), class_ = 'missing')
def file_link(self, formatter, ns, target, label): req = formatter.req if ns != 'file' and ns != 'download' and ns != 'filesdownload': return files_core = FilesCoreComponent(self.env) node_factory, download_config = files_core.files_node_factory_and_config(req) try: if ns == 'file': node = MappedFileNode.from_path(target, node_factory, True) else: node = MappedFileNode.from_download_path(target, node_factory, True) missing_perm = None if node.is_download(): if 'FILES_DOWNLOADS_VIEW' not in req.perm: missing_perm = 'FILES_DOWNLOADS_VIEW' elif 'FILES_VIEW' not in req.perm: missing_perm = 'FILES_VIEW' if missing_perm: return html.a(label, href='#', title = _('Missing %(permission)s permission', permission=missing_perm), class_ = 'missing') if node.exists(): if node.is_file(): if node.is_download(): if not node.download().is_available(): return html.a(label, href='#', title = _('Download information not available for %(path)s', path=node.relative_path), class_ = 'missing') else: return html.a(label, href=node.get_url(req), title = _('Download %(name)s (%(size)s)',name=node.filename, size= pretty_size(node.size))) else: return html.a(label, href=node.get_url(req), title = _('File %(name)s',name=node.filename)) elif node.is_dir(): return html.a(label, href=node.get_url(req), title = _('Folder %(name)s',name=node.filename)) else: return html.a(label, href='#', title = _('Not existing file: %(path)s', path=node.relative_path), class_ = 'missing') except TracError: # File doesn't exist return html.a(label, href='#', title=_('Invalid target for %(ns)s: %(path)s',ns=ns, path=target), class_='missing')
def name_details(self, name): # Get cursor. db = self.env.get_db_cnx() cursor = db.cursor() # Get API object. api = self.env[DownloadsApi] # Get tagged download. download = api.get_download(cursor, name) # Return a tuple of (href, wikilink, title) defaults = DefaultTaggingSystem.name_details(self, name) if download: return (defaults[0], html.a(download['file'], href = self.env.href.downloads(download['id']), title = download['description']), download['description']) else: return defaults
def expand_macro(self, formatter, name, content): arguments = content.split(',') error_hash = arguments[0] peer = SymfonyErrorPeer(self.env) msg = peer.retrieve_by_hash(error_hash) if msg: html_msg_h3 = html.h3('Komunikat') html_msg = html.p(html.b(msg[0])) html_uri_h3 = html.h3('Adres strony') html_uri = html.p(msg[1]) html_symfony_action = html.h3(html.span('Modul: ') + html.b(msg[2]) + html.span(' Akcja: ') + html.b(msg[3])) html_delete_link = html.a('Usun podobne bledy', href='/trac/bugs?delete_bug_id=' + arguments[0]) html_error = html.div(html_msg_h3 + html_msg + html_uri_h3 + html_uri + html_symfony_action + html_delete_link, class_='ticket_symfony_box') return html_error else: return 'Brak bledu o podanym identyfikatorze: ' + arguments[0] return html_url
def _discussion_attachment_link(self, formatter, namespace, params, label): id, name = params.split(':') # Create request context. context = Context.from_request(formatter.req) context.realm = 'discussion-wiki' # Get database access. db = self.env.get_db_cnx() context.cursor = db.cursor() if namespace == 'topic-attachment': return format_to_html(self.env, context, '[attachment:discussion:topic/%s:%s %s]' % (id, name, label)) elif namespace == 'raw-topic-attachment': return format_to_html(self.env, context, '[raw-attachment:discussion:topic/%s:%s %s]' % (id, name, label)) else: return html.a(label, href = formatter.href.discussion('topic', id), title = label.replace('"', ''), class_ = 'missing')
def _do_login(self, req): """Log the remote user in. This function expects to be called when the remote user name is available. The user name is inserted into the `auth_cookie` table and a cookie identifying the user on subsequent requests is sent back to the client. If the Authenticator was created with `ignore_case` set to true, then the authentication name passed from the web server in req.remote_user will be converted to lower case before being used. This is to avoid problems on installations authenticating against Windows which is not case sensitive regarding user names and domain names """ if not req.remote_user: raise TracError(html("Authentication information not available. " "Please refer to the ", html.a('installation documentation', title="Configuring Authentication", href=req.href.wiki('TracInstall') + "#ConfiguringAuthentication"), ".")) remote_user = req.remote_user if self.ignore_case: remote_user = remote_user.lower() assert req.authname in ('anonymous', remote_user), \ 'Already logged in as %s.' % req.authname cookie = hex_entropy() db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO auth_cookie (cookie,name,ipnr,time) " "VALUES (%s, %s, %s, %s)", (cookie, remote_user, req.remote_addr, int(time.time()))) db.commit() req.authname = remote_user req.outcookie['trac_auth'] = cookie req.outcookie['trac_auth']['path'] = req.href()