def render_widget(self, name, context, options): """Gather timeline events and render data in compact view """ data = None req = context.req try: timemdl = self.env[TimelineModule] if timemdl is None : raise TracError('Timeline module not available (disabled?)') params = ('from', 'daysback', 'doneby', 'precision', 'filters', \ 'max', 'realm', 'id') start, days, user, precision, filters, count, realm, rid = \ self.bind_params(name, options, *params) if count is None: count = self.default_count fakereq = dummy_request(self.env, req.authname) fakereq.args = { 'author' : user or '', 'daysback' : days or '', 'max' : count, 'precision' : precision, 'user' : user } if filters: fakereq.args.update(dict((k, True) for k in filters)) if start is not None: fakereq.args['from'] = start.strftime('%x %X') wcontext = context.child() if (realm, rid) != (None, None): # Override rendering context resource = Resource(realm, rid) if resource_exists(self.env, resource) or \ realm == rid == '': wcontext = context.child(resource) wcontext.req = req else: self.log.warning("TimelineWidget: Resource %s not found", resource) # FIXME: Filter also if existence check is not conclusive ? if resource_exists(self.env, wcontext.resource): module = FilteredTimeline(self.env, wcontext) self.log.debug('Filtering timeline events for %s', \ wcontext.resource) else: module = timemdl data = module.process_request(fakereq)[1] except TracError, exc: if data is not None: exc.title = data.get('title', 'Activity') raise
def _context_to_resource(env, context): """Find parent realm and resource_id and optional TracForms subcontext. Some guesswork is knowingly involved here to finally overcome previous potentially ambiguous contexts by distinct resource parameters. """ realm, resource_path = resource_from_page(env, context) subcontext = None if resource_path is not None: # ambiguous: ':' could be part of resource_id or subcontext or # the start of subcontext segments = re.split(':', resource_path) id = '' resource_id = None while len(segments) > 0: id += segments.pop(0) # guess: shortest valid resource_id is parent, # the rest is a TracForms subcontext if resource_exists(env, Resource(realm, id)): resource_id = id subcontext = ':'.join(segments) break id += ':' # valid resource_id in context NOT FOUND if resource_id is None: resource_id = resource_path else: # realm in context NOT FOUND resource_id = context realm = '' return realm, resource_id, subcontext
def _get_tags(self, req, resource): if not resource_exists(self.env, resource): raise ResourceNotFound('Resource "%r" does not exists' % resource) # Workaround for ServiceException when calling TagSystem.get_tags(). provider = [p for p in self.tag_system.tag_providers if p.get_taggable_realm() == resource.realm][0] # Type conversion needed for content transfer of Python set objects. return list(provider.get_resource_tags(req, resource))
def test_resource_exists(self): repos = Resource('repository', REPOS_NAME) self.assertEqual(True, resource_exists(self.env, repos)) self.assertEqual(False, resource_exists(self.env, repos(id='xxx'))) node = repos.child('source', u'tête') self.assertEqual(True, resource_exists(self.env, node)) self.assertEqual(False, resource_exists(self.env, node(id='xxx'))) cset = repos.child('changeset', HEAD) self.assertEqual(True, resource_exists(self.env, cset)) self.assertEqual(False, resource_exists(self.env, cset(id=123456)))
def render_widget(self, name, context, options): """Render widget considering given options. """ if name == 'WidgetDoc': add_stylesheet(context.req, 'dashboard/css/docs.css') widget_name, = self.bind_params(options, self.get_widget_params(name), 'urn') if widget_name is not None: try: providers = [([widget_name], self.resolve_widget(widget_name))] except LookupError: return 'widget_alert.html', { 'title': _('Widget documentation'), 'data': { 'msglabel': 'Alert', 'msgbody': 'Unknown identifier', 'msgdetails': [('Widget name', widget_name)] } }, context else: providers = [(provider.get_widgets(), provider) \ for provider in self.widget_providers] metadata = [self._prepare_doc_metadata(self.widget_metadata(wnm, p)) \ for widgets, p in providers for wnm in widgets] docs_resource = Resource('wiki', 'BloodhoundWidgets') insert_docs = resource_exists(self.env, docs_resource) and \ not (context.resource and \ docs_resource == context.resource) return 'widget_doc.html', { 'title': _('Widget documentation'), 'data': { 'items': metadata }, 'ctxtnav': [ tag.a(tag.i(class_='icon-info-sign'), ' ', _('Help'), href=get_resource_url(self.env, docs_resource, context.href)) ] if insert_docs else [], }, context else: raise InvalidIdentifier('Widget name MUST match any of ' + ', '.join(self.get_widgets()), title='Invalid widget identifier')
def render_widget(self, name, context, options): """Render widget considering given options. """ if name == 'WidgetDoc': add_stylesheet(context.req, 'dashboard/css/docs.css') widget_name, = self.bind_params(options, self.get_widget_params(name), 'urn') if widget_name is not None: try: providers = [([widget_name], self.resolve_widget(widget_name))] except LookupError: return 'widget_alert.html', { 'title': _('Widget documentation'), 'data': { 'msglabel': 'Alert', 'msgbody': 'Unknown identifier', 'msgdetails': [ ('Widget name', widget_name) ] } }, context else: providers = [(provider.get_widgets(), provider) \ for provider in self.widget_providers] metadata = [self._prepare_doc_metadata(self.widget_metadata(wnm, p)) \ for widgets, p in providers for wnm in widgets] docs_resource = Resource('wiki', 'BloodhoundWidgets') insert_docs = resource_exists(self.env, docs_resource) and \ not (context.resource and \ docs_resource == context.resource) return 'widget_doc.html', { 'title': _('Widget documentation'), 'data': { 'items': metadata }, 'ctxtnav': [tag.a(tag.i(class_='icon-info-sign'), ' ', _('Help'), href=get_resource_url( self.env, docs_resource, context.href) )] if insert_docs else [], }, context else: raise InvalidIdentifier('Widget name MUST match any of ' + ', '.join(self.get_widgets()), title='Invalid widget identifier')
def filter_stream(self, req, method, filename, stream, data): crumbs = self._get_crumbs(req.session) if not crumbs: return stream add_stylesheet(req, 'breadcrumbs/css/breadcrumbs.css') ul = [] path = req.path_info if path.count('/') >= 2: realm, resource_id = path.split('/', 2)[1:] if '&' in resource_id: resource_id = resource_id[0:resource_id.index('&')] current = '/'.join((realm, resource_id)) else: current = None offset = 0 if crumbs and crumbs[0] == current: offset = 1 for crumb in crumbs[offset: self.max_crumbs + offset]: realm, resource_id = crumb.split('/', 1) resource = Resource(realm, resource_id) name = get_resource_shortname(self.env, resource) if not resource_exists(self.env, resource): continue title = get_resource_summary(self.env, resource) link = req.href(realm, resource_id) first = ul == [] li = tag.li(tag.a(title=title, href=link)(name)) if first: li(class_="first") ul.append(li) if ul: last = ul.pop() ul.append(last(class_="last")) label = self.label if self.label else "Breadcrumbs:" insert = tag.ul(class_="nav", id="breadcrumbs")(tag.li(label), ul) else: insert = '' return stream | Transformer('//div[@id="metanav"]/ul').after(insert)
def resource_from_path(env, path): """Find realm and resource ID from resource URL. Assuming simple resource paths to convert to Trac resource identifiers. """ if isinstance(path, basestring): path = path.strip('/') # Special-case: Default TracWiki start page. if path == 'wiki': path += '/WikiStart' for realm in ResourceSystem(env).get_known_realms(): if path.startswith(realm): resource_id = re.sub(realm, '', path, 1).lstrip('/') resource = Resource(realm, resource_id) if not resource_check: return resource elif resource_exists(env, resource) in (None, True): return get_versioned_resource(env, resource)
def post_process_request(self, req, template, data, metadata): if data and 'page' in data and 'text' in data: name = data['page'].name notice = "" release = desc = alt_rel_path = alt_id = alt_desc = None if name in self.default_pages: release = self.stable_release desc = 'latest stable' alt_id = self.lts_release + '/' + name alt_rel_path = alt_id alt_desc = 'previous' elif name.startswith(self.lts_release) and \ name[len(self.lts_release)+1:] in self.default_pages: release = self.lts_release desc = 'maintenance' alt_id = name[len(self.lts_release) + 1:] alt_rel_path = '../../' + alt_id alt_desc = 'latest stable' elif name.startswith(self.dev_release) and \ name[len(self.dev_release)+1:] in self.default_pages: release = self.dev_release desc = 'development' alt_id = name[len(self.dev_release) + 1:] alt_rel_path = '../../' + alt_id alt_desc = 'latest stable' if alt_id: resource = Resource('wiki', alt_id) alt_notice = ALT_NOTICE_TEMPLATE % {'alt_page': alt_rel_path, 'alt_desc': alt_desc} \ if resource_exists(self.env, resource) \ else "" notice = NOTICE_TEMPLATE % { 'release': release, 'desc': desc, 'alt_notice': alt_notice } data['text'] = notice + data['text'] return template, data, metadata
def post_process_request(self, req, template, data, content_type): if data and 'page' in data and 'text' in data: name = data['page'].name notice = "" release = desc = alt_rel_path = alt_id = alt_desc = None if name in self.default_pages: release = self.stable_release desc = 'latest stable' alt_id = self.lts_release + '/' + name alt_rel_path = alt_id alt_desc = 'previous' elif name.startswith(self.lts_release) and \ name[len(self.lts_release)+1:] in self.default_pages: release = self.lts_release desc = 'maintenance' alt_id = name[len(self.lts_release)+1:] alt_rel_path = '../../' + alt_id alt_desc = 'latest stable' elif name.startswith(self.dev_release) and \ name[len(self.dev_release)+1:] in self.default_pages: release = self.dev_release desc = 'development' alt_id = name[len(self.dev_release)+1:] alt_rel_path = '../../' + alt_id alt_desc = 'latest stable' if alt_id: resource = Resource('wiki', alt_id) alt_notice = ALT_NOTICE_TEMPLATE % {'alt_page': alt_rel_path, 'alt_desc': alt_desc} \ if resource_exists(self.env, resource) \ else "" notice = NOTICE_TEMPLATE % {'release': release, 'desc': desc, 'alt_notice': alt_notice} data['text'] = notice + data['text'] return template, data, content_type
def _format_name(self, req, url): linkname = url name = "" missing = False path_info = url query_string = '' idx = path_info.find('?') if idx >= 0: path_info, query_string = path_info[:idx], path_info[idx:] href = req.href(path_info) + query_string args = arg_list_to_args(parse_arg_list(query_string.lstrip('?'))) version = args.get('version', False) path = path_info.strip('/').split('/') realm = path[0] class_ = realm if len(path) > 1: resource = Resource(realm, path[1]) if resource: if realm == 'ticket': linkname = get_resource_shortname(self.env, resource) try: name = get_resource_summary(self.env, resource) except ResourceNotFound: missing = True else: from trac.ticket.model import Ticket class_ = Ticket(self.env, resource.id)['status'] + \ ' ' + class_ elif realm == 'milestone': linkname = get_resource_name(self.env, resource) elif realm == 'wiki': resource = Resource(realm, '/'.join(path[1:]), version) linkname = get_resource_shortname(self.env, resource) if version: linkname += '@' + version elif realm == 'report': linkname = "{%s}" % path[1] name = self._format_report_name(path[1]) elif realm == 'changeset': rev = path[1] parent = Resource('source', '/'.join(path[2:])) resource = Resource(realm, rev, False, parent) linkname = "[%s]" % rev name = get_resource_description(self.env, resource) elif realm == 'browser': parent = Resource('source', path[1]) resource = Resource('source', '/'.join(path[2:]), False, parent) linkname = get_resource_description(self.env, resource) name = get_resource_summary(self.env, resource) elif realm == 'attachment': # Assume a file and check existence parent = Resource(path[1], '/'.join(path[2:-1])) resource = Resource(realm, path[-1], parent=parent) linkname = get_resource_name(self.env, resource) if not resource_exists(self.env, resource): # Assume an attachment list page and check existence parent = Resource(path[1], '/'.join(path[2:])) if resource_exists(self.env, parent): resource = Resource(realm, parent=parent) linkname = get_resource_name(self.env, resource) if not query_string: # Trailing slash needed for Trac < 1.0, t:#10280 href += '/' else: # Assume it's a missing attachment missing = True else: linkname = get_resource_shortname(self.env, resource) name = get_resource_summary(self.env, resource) elif len(path) == 1 and path[0] and path[0] != 'wiki': linkname = path[0].capitalize() else: class_ = 'wiki' linkname = 'WikiStart' if missing: href = None class_ = 'missing ' + realm return { 'class_': class_, 'href': href, 'linkname': linkname, 'name': name, 'delete': req.href.bookmark('delete_in_page', url), }
def _attachment_exists(self, type, id, filename): att = Attachment(self.env, type, id, filename) return resource_exists(self.env, att.resource)
def test_resource_exists(self): att = Attachment(self.env, 'wiki', 'WikiStart') att.insert('file.txt', StringIO(''), 1) self.assertTrue(resource_exists(self.env, att.resource))
def _format_name(self, req, url): linkname = url name = "" missing = False path_info = url query_string = '' idx = path_info.find('?') if idx >= 0: path_info, query_string = path_info[:idx], path_info[idx:] href = req.href(path_info) + query_string args = arg_list_to_args(parse_arg_list(query_string.lstrip('?'))) version = args.get('version', False) path = path_info.strip('/').split('/') realm = path[0] class_ = realm if len(path) > 1: resource = Resource(realm, path[1]) if resource: if realm == 'ticket': linkname = get_resource_shortname(self.env, resource) try: name = get_resource_summary(self.env, resource) except ResourceNotFound: missing = True else: from trac.ticket.model import Ticket class_ = Ticket(self.env, resource.id)['status'] + \ ' ' + class_ elif realm == 'milestone': linkname = get_resource_name(self.env, resource) elif realm == 'wiki': resource = Resource(realm, '/'.join(path[1:]), version) linkname = get_resource_shortname(self.env, resource) if version: linkname += '@' + version elif realm == 'report': linkname = "{%s}" % path[1] name = self._format_report_name(path[1]) elif realm == 'changeset': rev = path[1] parent = Resource('source', '/'.join(path[2:])) resource = Resource(realm, rev, False, parent) linkname = "[%s]" % rev name = get_resource_description(self.env, resource) elif realm == 'browser': rm = RepositoryManager(self.env) reponame, repos, path = rm.get_repository_by_path('/'.join( path[1:])) parent = Resource('source', reponame) resource = Resource('source', path, False, parent) linkname = get_resource_description(self.env, resource) name = get_resource_summary(self.env, resource) elif realm == 'attachment': # Assume a file and check existence parent = Resource(path[1], '/'.join(path[2:-1])) resource = Resource(realm, path[-1], parent=parent) linkname = get_resource_name(self.env, resource) if not resource_exists(self.env, resource): # Assume an attachment list page and check existence parent = Resource(path[1], '/'.join(path[2:])) if resource_exists(self.env, parent): resource = Resource(realm, parent=parent) linkname = get_resource_name(self.env, resource) if not query_string: # Trailing slash needed for Trac < 1.0, t:#10280 href += '/' else: # Assume it's a missing attachment missing = True else: linkname = get_resource_shortname(self.env, resource) name = get_resource_summary(self.env, resource) elif len(path) == 1 and path[0] and path[0] != 'wiki': linkname = path[0].capitalize() else: class_ = 'wiki' linkname = 'WikiStart' if missing: href = None class_ = 'missing ' + realm return { 'class_': class_, 'href': href, 'linkname': linkname, 'name': name, 'delete': req.href.bookmark('delete_in_page', url), }
def test_resource_doesnt_exist(self): """Non-existent resource returns False from resource_exists.""" parent = Resource('parent_realm', 'parent_id') self.assertTrue(resource_exists(self.env, parent)) r = parent.child('attachment', 'file.txt') self.assertFalse(resource_exists(self.env, r))
def render_widget(self, name, context, options): """Gather timeline events and render data in compact view """ data = None req = context.req try: timemdl = self.env[TimelineModule] admin_page = tag.a(_("administration page."), title=_("Plugin Administration Page"), href=req.href.admin('general/plugin')) if timemdl is None: return 'widget_alert.html', { 'title': _("Activity"), 'data': { 'msglabel': _("Warning"), 'msgbody': tag_("The TimelineWidget is disabled because the " "Timeline component is not available. " "Is the component disabled? " "You can enable from the %(page)s", page=admin_page), 'dismiss': False, } }, context params = ('from', 'daysback', 'doneby', 'precision', 'filters', 'max', 'realm', 'id') start, days, user, precision, filters, count, realm, rid = \ self.bind_params(name, options, *params) if context.resource.realm == 'ticket': if days is None: # calculate a long enough time daysback ticket = Ticket(self.env, context.resource.id) ticket_age = datetime.now(utc) - ticket.time_created days = ticket_age.days + 1 if count is None: # ignore short count for ticket feeds count = 0 if count is None: count = self.default_count fakereq = dummy_request(self.env, req.authname) fakereq.args = { 'author': user or '', 'daysback': days or '', 'max': count, 'precision': precision, 'user': user } if filters: fakereq.args.update(dict((k, True) for k in filters)) if start is not None: fakereq.args['from'] = start.strftime('%x %X') wcontext = context.child() if (realm, rid) != (None, None): # Override rendering context resource = Resource(realm, rid) if resource_exists(self.env, resource) or \ realm == rid == '': wcontext = context.child(resource) wcontext.req = req else: self.log.warning("TimelineWidget: Resource %s not found", resource) # FIXME: Filter also if existence check is not conclusive ? if resource_exists(self.env, wcontext.resource): module = FilteredTimeline(self.env, wcontext) self.log.debug('Filtering timeline events for %s', wcontext.resource) else: module = timemdl data = module.process_request(fakereq)[1] except TracError, exc: if data is not None: exc.title = data.get('title', _('Activity')) raise
def render_widget(self, name, context, options): """Gather timeline events and render data in compact view """ data = None req = context.req try: timemdl = self.env[TimelineModule] admin_page = tag.a(_("administration page."), title=_("Plugin Administration Page"), href=req.href.admin('general/plugin')) if timemdl is None: return 'widget_alert.html', { 'title': _("Activity"), 'data': { 'msglabel': _("Warning"), 'msgbody': tag_( "The TimelineWidget is disabled because the " "Timeline component is not available. " "Is the component disabled? " "You can enable from the %(page)s", page=admin_page), 'dismiss': False, } }, context params = ('from', 'daysback', 'doneby', 'precision', 'filters', 'max', 'realm', 'id') start, days, user, precision, filters, count, realm, rid = \ self.bind_params(name, options, *params) if context.resource.realm == 'ticket': if days is None: # calculate a long enough time daysback ticket = Ticket(self.env, context.resource.id) ticket_age = datetime.now(utc) - ticket.time_created days = ticket_age.days + 1 if count is None: # ignore short count for ticket feeds count = 0 if count is None: count = self.default_count fakereq = dummy_request(self.env, req.authname) fakereq.args = { 'author': user or '', 'daysback': days or '', 'max': count, 'precision': precision, 'user': user } if filters: fakereq.args.update(dict((k, True) for k in filters)) if start is not None: fakereq.args['from'] = start.strftime('%x %X') wcontext = context.child() if (realm, rid) != (None, None): # Override rendering context resource = Resource(realm, rid) if resource_exists(self.env, resource) or \ realm == rid == '': wcontext = context.child(resource) wcontext.req = req else: self.log.warning("TimelineWidget: Resource %s not found", resource) # FIXME: Filter also if existence check is not conclusive ? if resource_exists(self.env, wcontext.resource): module = FilteredTimeline(self.env, wcontext) self.log.debug('Filtering timeline events for %s', wcontext.resource) else: module = timemdl data = module.process_request(fakereq)[1] except TracError, exc: if data is not None: exc.title = data.get('title', _('Activity')) raise
def test_resource_exists(self): att = Attachment(self.env, "wiki", "WikiStart") att.insert("file.txt", StringIO(""), 1) self.assertTrue(resource_exists(self.env, att.resource))