def _do_remove(self, identifier): # Get downloads API component. api = self.env[DownloadsApi] # Create context. context = Context('downloads-consoleadmin') db = self.env.get_db_cnx() context.cursor = db.cursor() context.req = FakeRequest(self.env, self.consoleadmin_user) # Get download by ID or filename. try: download_id = int(identifier) download = api.get_download(context, download_id) except ValueError: download = api.get_download_by_file(context, identifier) # Check if download exists. if not download: raise AdminCommandError(_('Invalid download identifier: %(value)s', value = identifier)) # Delete download by ID. api.delete_download(context, download_id) # Commit changes in DB. db.commit()
def test_converted_doctest(self): self.repos.get_changeset=lambda x: Mock(date=to_datetime(12345, utc)) BuildConfig(self.env, name='trunk', path='trunk').insert() Build(self.env, rev=123, config='trunk', rev_time=12345, platform=1 ).insert() rpt = Report(self.env, build=1, step='test', category='coverage') rpt.items.append({'file': 'foo.py', 'line_hits': '5 - 0'}) rpt.insert() ann = TestCoverageAnnotator(self.env) req = Mock(href=Href('/'), perm=MockPerm(), chrome={'warnings': []}, args={}) # Version in the branch should not match: context = Context.from_request(req, 'source', '/branches/blah/foo.py', 123) self.assertEquals(ann.get_annotation_data(context), []) # Version in the trunk should match: context = Context.from_request(req, 'source', '/trunk/foo.py', 123) data = ann.get_annotation_data(context) self.assertEquals(data, [u'5', u'-', u'0']) def annotate_row(lineno, line): row = tag.tr() ann.annotate_row(context, row, lineno, line, data) return unicode(row.generate().render('html')) self.assertEquals(annotate_row(1, 'x = 1'), u'<tr><th class="covered">5</th></tr>') self.assertEquals(annotate_row(2, ''), u'<tr><th></th></tr>') self.assertEquals(annotate_row(3, 'y = x'), u'<tr><th class="uncovered">0</th></tr>')
def _do_remove(self, identifier): # Get downloads API component. api = self.env[DownloadsApi] # Create context. context = Context('downloads-consoleadmin') db = self.env.get_db_cnx() context.cursor = db.cursor() context.req = FakeRequest(self.env, self.consoleadmin_user) # Get download by ID or filename. try: download_id = int(identifier) download = api.get_download(context, download_id) except ValueError: download = api.get_download_by_file(context, identifier) # Check if download exists. if not download: raise AdminCommandError( _('Invalid download identifier: %(value)s', value=identifier)) # Delete download by ID. api.delete_download(context, download_id) # Commit changes in DB. db.commit()
def _do_add(self, filename, *arguments): # Get downloads API component. api = self.env[DownloadsApi] # Create context. context = Context('downloads-consoleadmin') db = self.env.get_db_cnx() context.cursor = db.cursor() context.req = FakeRequest(self.env, self.consoleadmin_user) # Convert relative path to absolute. if not os.path.isabs(filename): filename = os.path.join(self.path, filename) # Open file object. file, filename, file_size = self._get_file(filename) # Create download dictionary from arbitrary attributes. download = {'file' : filename, 'size' : file_size, 'time' : to_timestamp(datetime.now(utc)), 'count' : 0} # Read optional attributes from arguments. for argument in arguments: # Check correct format. argument = argument.split("=") if len(argument) != 2: AdminCommandError(_('Invalid format of download attribute:' ' %(value)s', value = argument)) name, value = argument # Check known arguments. if not name in ('description', 'author', 'tags', 'component', 'version', 'architecture', 'platform', 'type'): raise AdminCommandError(_('Invalid download attribute:' ' %(value)s', value = name)) # Transform architecture, platform and type name to ID. if name == 'architecture': value = api.get_architecture_by_name(context, value)['id'] elif name == 'platform': value = api.get_platform_by_name(context, value)['id'] elif name == 'type': value = api.get_type_by_name(context, value)['id'] # Add attribute to download. download[name] = value self.log.debug(download) # Upload file to DB and file storage. api._add_download(context, download, file) # Close input file and commit changes in DB. file.close() db.commit()
def _resolve_ids(self, download): # Create context. context = Context('downloads-core') db = self.env.get_db_cnx() context.cursor = db.cursor() # Resolve platform and type names. api = self.env[DownloadsApi] platform = api.get_platform(context, download['platform']) type = api.get_type(context, download['type']) download['platform'] = platform['name'] download['type'] = type['name']
def _do_list(self): # Get downloads API component. api = self.env[DownloadsApi] # Create context. context = Context('downloads-consoleadmin') db = self.env.get_db_cnx() context.cursor = db.cursor() # Print uploded download downloads = api.get_downloads(context) print_table([(download['id'], download['file'], pretty_size( download['size']), format_datetime(download['time']), download['component'], download['version'], download['platform']['name'], download['type']['name']) for download in downloads], ['ID', 'Filename', 'Size', 'Uploaded', 'Component', 'Version', 'Platform', 'Type'])
def get_resource_description(self, resource, format="default", context=None, **kwargs): # Create context. context = Context("downloads-core") db = self.env.get_db_cnx() context.cursor = db.cursor() # Get download from ID. api = self.env[DownloadsApi] download = api.get_download(context, safe_int(resource.id)) if format == "compact": return download["file"] elif format == "summary": return "(%s) %s" % (pretty_size(download["size"]), download["description"]) return download["file"]
def _check_quickjump(self, req, kwd): """Look for search shortcuts""" noquickjump = int(req.args.get('noquickjump', '0')) # Source quickjump FIXME: delegate to ISearchSource.search_quickjump quickjump_href = None if kwd[0] == '/': quickjump_href = req.href.browser(kwd) name = kwd description = _('Browse repository path %(path)s', path=kwd) else: link = extract_link(self.env, Context.from_request(req, 'search'), kwd) if isinstance(link, Element): quickjump_href = link.attrib.get('href') name = link.children description = link.attrib.get('title', '') if quickjump_href: # Only automatically redirect to local quickjump links if not quickjump_href.startswith(req.base_path or '/'): noquickjump = True if noquickjump: return {'href': quickjump_href, 'name': tag.EM(name), 'description': description} else: req.redirect(quickjump_href)
def process_request(self, req): link = req.args.get("link", "") parts = link.split(":", 1) if len(parts) > 1: resolver, target = parts if target and (target[0] not in "'\"" or target[0] != target[-1]): link = '%s:"%s"' % (resolver, target) link_frag = extract_link(self.env, Context.from_request(req), link) def get_first_href(item): """Depth-first search for the first `href` attribute.""" if isinstance(item, Element): href = item.attrib.get("href") if href is not None: return href if isinstance(item, Fragment): for each in item.children: href = get_first_href(each) if href is not None: return href if isinstance(link_frag, (Element, Fragment)): href = get_first_href(link_frag) if href is None: # most probably no permissions to view raise PermissionError(_("Can't view %(link)s:", link=link)) else: href = req.href(link.rstrip(":")) req.redirect(href)
def render_admin_panel(self, req, category, page, path_info): # Prepare request object. if page == "forum": if not req.args.has_key("group"): req.args["group"] = "-1" if path_info: req.args["forum"] = path_info else: if path_info: req.args["group"] = path_info # Create request context. context = Context.from_request(req) context.realm = "discussion-admin" # Process request. api = self.env[DiscussionApi] template, data = api.process_discussion(context) if context.redirect_url: # Redirect request if needed. href = req.href(context.redirect_url[0]) + context.redirect_url[1] self.log.debug("Redirecting to %s" % (href)) req.redirect(req.href("discussion", "redirect", redirect_url=href)) else: # Return template and data. return template, data
def render_admin_panel(self, req, category, page, path_info): # Prepare request object. if page == 'forum': if not req.args.has_key('group'): req.args['group'] = '-1' if path_info: req.args['forum'] = path_info else: if path_info: req.args['group'] = path_info # Create request context. context = Context.from_request(req) context.realm = 'discussion-admin' # Process request. api = self.env[DiscussionApi] template, data = api.process_discussion(context) if context.redirect_url: # Redirect request if needed. href = req.href(context.redirect_url[0]) + context.redirect_url[1] self.log.debug("Redirecting to %s" % (href)) req.redirect(req.href('discussion', 'redirect', redirect_url=href)) else: # Return template and data. return template, data
def process_request(self, req): # Create request context. context = Context.from_request(req)("downloads-core") # Process request and return content. api = self.env[DownloadsApi] return api.process_downloads(context) + (None,)
def _format_reminder(self, req, ticket, id, time, author, origin, description, delete_button=True): now = to_datetime(None) time = to_datetime(time) if now >= time: when = tag(tag.strong("Right now"), " (pending)") else: when = tag("In ", tag.strong(pretty_timedelta(time)), " (", format_date(time), ")") if description: context = Context.from_request(req, ticket.resource) desc = tag.div(format_to_oneliner(self.env, context, description), class_="description") else: desc = tag() return tag( self._reminder_delete_form(req, id) if delete_button else None, when, " - added by ", tag.em(Chrome(self.env).authorinfo(req, author)), " ", tag.span(pretty_timedelta(origin), title=format_datetime( origin, req.session.get('datefmt', 'iso8601'), req.tz)), " ago.", desc)
def wiki_setup(tc): tc.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) tc.env.path = tempfile.mkdtemp() tc.db_mgr = DatabaseManager(tc.env) tc.db = tc.env.get_db_cnx() TagSetup(tc.env).upgrade_environment(tc.db) now = datetime.now(utc) wiki = WikiPage(tc.env) wiki.name = 'TestPage' wiki.text = '--' wiki.save('joe', 'TagsPluginTestPage', '::1', now) req = Mock(href=Href('/'), abs_href=Href('http://www.example.com/'), authname='anonymous', perm=MockPerm(), tz=utc, args={}, locale=Locale.parse('en_US') if Locale else None) tc.env.href = req.href tc.env.abs_href = req.abs_href tc.context = Context.from_request(req) # Enable big diff output. tc.maxDiff = None
def _render_editor(self, req, db, milestone): data = { 'milestone': milestone, 'ticket': milestone.ticket, 'datefields' : self.date_fields, 'date_hint': get_date_format_hint(), 'datetime_hint': get_datetime_format_hint(), 'milestone_groups': [], 'jump_to' : req.args.get('jump_to') or referer_module(req) } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_VIEW') milestones = [m for m in StructuredMilestone.select(self.env, db=db) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource)] data['milestone_groups'] = group_milestones(milestones, 'TICKET_ADMIN' in req.perm) else: req.perm(milestone.resource).require('MILESTONE_CREATE') TicketModule(self.env)._insert_ticket_data(req, milestone.ticket, data, get_reporter_id(req, 'author'), {}) self._add_tickets_report_data(milestone, req, data) context = Context.from_request(req, milestone.resource) data['attachments']=AttachmentModule(self.env).attachment_data(context) return 'itteco_milestone_edit.html', data, None
def create_trac_ctx(self, website_url, author_name, timezone_str, uri): req = Mock(href=Href(uri), abs_href=Href(website_url), authname=author_name, perm=MockPerm(), tz=timezone_str, args={}) context = Context.from_request(req, 'wiki', 'WikiStart') env = EnvironmentStub(enable=['trac.*']) # + additional components # -- macros support env.path = '' # -- intertrac support env.config.set('intertrac', 'trac.title', 'Trac\'s Trac') env.config.set('intertrac', 'trac.url', website_url) env.config.set('intertrac', 't', 'trac') env.config.set('intertrac', 'th.title', 'Trac Hacks') env.config.set('intertrac', 'th.url', 'http://trac-hacks.org') env.config.set('intertrac', 'th.compat', 'false') # -- safe schemes env.config.set('wiki', 'safe_schemes', 'file,ftp,http,https,svn,svn+ssh,git,' 'rfc-2396.compatible,rfc-2396+under_score') env.href = req.href env.abs_href = req.abs_href return (env, context)
def process_request(self, req): # Create request context. context = Context.from_request(req)('downloads-core') # Process request and return content. api = self.env[DownloadsApi] return api.process_downloads(context) + (None, )
def _render_editor(self, req, db, milestone): data = { 'milestone': milestone, 'ticket': milestone.ticket, 'datefields': self.date_fields, 'date_hint': get_date_format_hint(), 'datetime_hint': get_datetime_format_hint(), 'milestone_groups': [], 'jump_to': req.args.get('jump_to') or referer_module(req) } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_VIEW') milestones = [ m for m in StructuredMilestone.select(self.env, db=db) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource) ] data['milestone_groups'] = group_milestones( milestones, 'TICKET_ADMIN' in req.perm) else: req.perm(milestone.resource).require('MILESTONE_CREATE') TicketModule(self.env)._insert_ticket_data( req, milestone.ticket, data, get_reporter_id(req, 'author'), {}) self._add_tickets_report_data(milestone, req, data) context = Context.from_request(req, milestone.resource) data['attachments'] = AttachmentModule( self.env).attachment_data(context) return 'itteco_milestone_edit.html', data, None
def _format_html(self, event): ticket = event.target short_changes = {} long_changes = {} chrome = Chrome(self.env) for field, old_value in event.changes.items(): new_value = ticket[field] if (new_value and '\n' in new_value) or \ (old_value and '\n' in old_value): long_changes[field.capitalize()] = HTML( "<pre>\n%s\n</pre>" % ('\n'.join( diff_cleanup( difflib.unified_diff( wrap(old_value, cols=60).split('\n'), wrap(new_value, cols=60).split('\n'), lineterm='', n=3))))) else: short_changes[field.capitalize()] = (old_value, new_value) try: req = Mock(href=Href(self.env.abs_href()), abs_href=self.env.abs_href(), authname=event.author, perm=MockPerm(), chrome=dict(warnings=[], notices=[]), args={}) context = Context.from_request(req, event.realm, event.target.id) formatter = HtmlFormatter(self.env, context, event.comment) temp = formatter.generate(True) except Exception, e: self.log.error(exception_to_unicode(e, traceback=True)) temp = 'Comment in plain text: %s' % event.comment
def create_trac_ctx(self, website_url, author_name, timezone_str, uri): req = Mock(href=Href(uri), abs_href=Href(website_url), authname=author_name, perm=MockPerm(), tz=timezone_str, args={}) context = Context.from_request(req, 'wiki', 'WikiStart') env = EnvironmentStub(enable=['trac.*']) # + additional components # -- macros support env.path = '' # -- intertrac support env.config.set('intertrac', 'trac.title', "Trac's Trac") env.config.set('intertrac', 'trac.url', website_url) env.config.set('intertrac', 't', 'trac') env.config.set('intertrac', 'th.title', "Trac Hacks") env.config.set('intertrac', 'th.url', "http://trac-hacks.org") env.config.set('intertrac', 'th.compat', 'false') # -- safe schemes env.config.set('wiki', 'safe_schemes', 'file,ftp,http,https,svn,svn+ssh,git,' 'rfc-2396.compatible,rfc-2396+under_score') env.href = req.href env.abs_href = req.abs_href return (env, context)
def filter_stream(self, req, method, filename, stream, data): """Return a filtered Genshi event stream, or the original unfiltered stream if no match. """ if filename == "ticket.html" and \ ('TICKET_REMINDER_VIEW' in req.perm or 'TICKET_REMINDER_MODIFY' in req.perm or 'TICKET_ADMIN' in req.perm): tags = self._reminder_tags(req, data) if tags: ticket_resource = data['ticket'].resource context = Context.from_request(req, ticket_resource) attachments_data = AttachmentModule( self.env).attachment_data(context) add_stylesheet(req, 'ticketreminder/css/ticketreminder.css') # Will attachments section be displayed? attachments_or_ticket = Transformer( '//div[@id="attachments"]' ) if attachments_data['can_create'] or attachments_data[ 'attachments'] else Transformer('//div[@id="ticket"]') trac_nav = Transformer( '//form[@id="propertyform"]/div[@class="trac-nav"]') return stream | attachments_or_ticket.after( tags) | trac_nav.append(self._reminder_trac_nav(req, data)) return stream
def process_request(self, req): # Create request context. context = Context.from_request(req) context.realm = 'screenshots-core' # Template data dictionary. req.data = {} # Get database access. db = self.env.get_db_cnx() context.cursor = db.cursor() # Prepare data structure. req.data['title'] = self.mainnav_title or self.metanav_title req.data['has_tags'] = self.env.is_component_enabled( 'tracscreenshots.tags.ScreenshotsTags') # Get action from request and perform them. actions = self._get_actions(context) self.log.debug('actions: %s' % (actions,)) template, content_type = self._do_actions(context, actions) # Add CSS style and JavaScript scripts. add_stylesheet(req, 'screenshots/css/screenshots.css') add_script(req, 'screenshots/js/screenshots.js') # Return template and its data. db.commit() return (template + '.html', {'screenshots' : req.data}, content_type)
def _check_quickjump(self, req, kwd): """Look for search shortcuts""" noquickjump = int(req.args.get('noquickjump', '0')) # Source quickjump FIXME: delegate to ISearchSource.search_quickjump quickjump_href = None if kwd[0] == '/': quickjump_href = req.href.browser(kwd) name = kwd description = _('Browse repository path %(path)s', path=kwd) else: link = extract_link(self.env, Context.from_request(req, 'search'), kwd) if isinstance(link, Element): quickjump_href = link.attrib.get('href') name = link.children description = link.attrib.get('title', '') if quickjump_href: # Only automatically redirect to local quickjump links if not quickjump_href.startswith(req.base_path or '/'): noquickjump = True if noquickjump: return { 'href': quickjump_href, 'name': tag.EM(name), 'description': description } else: req.redirect(quickjump_href)
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 get_resource_description(self, resource, format = 'default', context = None, **kwargs): # Create context. context = Context('downloads-core') db = self.env.get_db_cnx() context.cursor = db.cursor() # Get download from ID. api = self.env[DownloadsApi] download = api.get_download(context, resource.id) if format == 'compact': return download['file'] elif format == 'summary': return '(%s) %s' % (pretty_size(download['size']), download['description']) return download['file']
def __init__(self, title, input, correct, file, line, setup=None, teardown=None, context=None): unittest.TestCase.__init__(self, 'test') self.title = title self.input = input self.correct = correct self.file = file self.line = line self._setup = setup self._teardown = teardown req = Mock(href=Href('/'), abs_href=Href('http://www.example.com/'), authname='anonymous', perm=MockPerm(), tz=None, args={}) if context: if isinstance(context, tuple): context = Context.from_request(req, *context) else: context = Context.from_request(req, 'wiki', 'WikiStart') self.context = context all_test_components = [ HelloWorldMacro, DivHelloWorldMacro, TableHelloWorldMacro, DivCodeMacro, DivCodeElementMacro, DivCodeStreamMacro, NoneMacro, WikiProcessorSampleMacro, SampleResolver] self.env = EnvironmentStub(enable=['trac.*'] + all_test_components) # -- macros support self.env.path = '' # -- intertrac support self.env.config.set('intertrac', 'trac.title', "Trac's Trac") self.env.config.set('intertrac', 'trac.url', "http://trac.edgewall.org") self.env.config.set('intertrac', 't', 'trac') self.env.config.set('intertrac', 'th.title', "Trac Hacks") self.env.config.set('intertrac', 'th.url', "http://trac-hacks.org") self.env.config.set('intertrac', 'th.compat', 'false') # -- safe schemes self.env.config.set('wiki', 'safe_schemes', 'file,ftp,http,https,svn,svn+ssh,' 'rfc-2396.compatible,rfc-2396+under_score') # TODO: remove the following lines in order to discover # all the places were we should use the req.href # instead of env.href self.env.href = req.href self.env.abs_href = req.abs_href
def getPageHTML(self, req, pagename, version=None): """ Return latest version of page as rendered HTML, utf8 encoded. """ page = self._fetch_page(req, pagename, version) fields = {"text": page.text} for manipulator in self.manipulators: manipulator.prepare_wiki_page(req, page, fields) context = Context.from_request(req, page.resource, absurls=True) html = format_to_html(self.env, context, fields["text"]) return "<html><body>%s</body></html>" % html.encode("utf-8")
def getPageHTML(self, req, pagename, version=None): """ Return latest version of page as rendered HTML, utf8 encoded. """ page = self._fetch_page(req, pagename, version) fields = {'text': page.text} for manipulator in self.manipulators: manipulator.prepare_wiki_page(req, page, fields) context = Context.from_request(req, page.resource, absurls=True) html = format_to_html(self.env, context, fields['text']) return '<html><body>%s</body></html>' % html.encode('utf-8')
def process_request(self, req): link = req.args.get('link', '') link_elt = extract_link(self.env, Context.from_request(req), link) if isinstance(link_elt, Element): href = link_elt.attrib.get('href') if href is None: # most probably no permissions to view raise PermissionError(_("Can't view %(link)s:", link=link)) else: href = req.href(link.rstrip(':')) req.redirect(href)
def _replaces_formatter(self, formatter, ns, match): replaces = match.group('replaces') if replaces not in self.replace: return match.group(0) title = self.replace[replaces] context = Context.from_request(formatter.req, formatter.resource) return Markup('<span>%s</span>' % (format_to_oneliner(self.env,context,title)))
def process_request(self, req): api = TrackerApi context = Context.from_request(req) db = self.env.get_db_cnx() context.cursor = db.cursor() actions = self._get_actions(context) if req.args.get('fromDMY') and req.args.get('toDMY') and req.args.get('username'): username = req.args.get('username') fromDMY = int(time.mktime(time.strptime(req.args.get('fromDMY'), '%d-%m-%Y'))).__str__() toDMY = int(time.mktime(time.strptime(req.args.get('toDMY'), '%d-%m-%Y'))).__str__() DEFAULT_TIME_VALUE = 10 screenshots = self._get_users_screenshots(username, fromDMY, toDMY) summaryWorkedTimeInMinutes = len(screenshots) * DEFAULT_TIME_VALUE temp_tasks = {} for screenshot in screenshots: if screenshot['ticketId'] in temp_tasks.keys(): temp_tasks[screenshot['ticketId']]['minutes'] += DEFAULT_TIME_VALUE else: temp_tasks[screenshot['ticketId']] = {'minutes': DEFAULT_TIME_VALUE, 'name': screenshot['summary'], 'id': screenshot['ticketId']} tasks = [] for key, temp_task in temp_tasks.iteritems(): href = Href(req.base_path) task = { 'hours': int(temp_task['minutes'] / 60), 'minutes': temp_task['minutes'] % 60, 'name': temp_task['name'], 'id': temp_task['id'], 'href': href.ticket(temp_task['id']) } tasks.append(task) req.data = { 'screenshots': screenshots, 'tasks': tasks, 'summaryWorkedTimeHours': int(summaryWorkedTimeInMinutes / 60), 'summaryWorkedTimeMinutes': summaryWorkedTimeInMinutes % 60, 'fromDMY': req.args.get('fromDMY'), 'toDMY': req.args.get('toDMY'), 'username': req.args.get('username') } add_stylesheet(req, 'trac/css/tracker.css') return "user_report.html", req.data, None else: add_script(req, 'common/js/jquery-ui.js') add_stylesheet(req, 'common/css/jquery-ui/jquery-ui.css') add_script(req, 'common/js/jquery-ui-addons.js') add_stylesheet(req, 'common/css/jquery-ui-addons.css') req.data = { 'users': api.get_users(TrackerApi(), context) } add_stylesheet(req, 'trac/css/tracker.css') return "user_report_date_picker.html", req.data, None
def _do_list(self): # Get downloads API component. api = self.env[DownloadsApi] # Create context. context = Context('downloads-consoleadmin') db = self.env.get_db_cnx() context.cursor = db.cursor() # Print uploded download downloads = api.get_downloads(context) print_table( [(download['id'], download['file'], pretty_size(download['size']), format_datetime(download['time']), download['component'], download['version'], download['architecture']['name'], download['platform']['name'], download['type']['name']) for download in downloads], [ 'ID', 'Filename', 'Size', 'Uploaded', 'Component', 'Version', 'Architecture', 'Platform', 'Type' ])
def _replaces_formatter(self, formatter, ns, match): replaces = match.group('replaces') if replaces not in self.replace: return match.group(0) title = self.replace[replaces] context = Context.from_request(formatter.req, formatter.resource) return Markup('<span>%s</span>' % (format_to_oneliner(self.env, context, title)))
def get_resource_description(self, resource, format='default', context=None, **kwargs): # Create context. context = Context('downloads-core') db = self.env.get_db_cnx() context.cursor = db.cursor() # Get download from ID. api = self.env[DownloadsApi] download = api.get_download(context, safe_int(resource.id)) if format == 'compact': return download['file'] elif format == 'summary': return '(%s) %s' % (pretty_size( download['size']), download['description']) return download['file']
def _get_quickjump(self, req, query): """Find quickjump requests if the search comes from the searchbox in the header. The search is assumed to be from the header searchbox if no page or per_page arguments are found. """ if req.args.get('page') or req.args.get('per_page'): return None link = extract_link(self.env, Context.from_request(req, 'advsearch'), query) if isinstance(link, Element): return link.attrib.get('href')
def wiki2html(self, wiki): """ The easiest way to convert wiki to html """ req = Mock(href=Href(self.env.abs_href.base), abs_href=self.env.abs_href, authname='anonymous', perm=MockPerm(), args={}) context = Context.from_request(req, 'wiki') try: html = format_to_html(self.env, context, wiki).encode('utf8','ignore') except AttributeError: html = wiki return html
def __init__(self, input, correct, file, line, setup=None, teardown=None, context=None): unittest.TestCase.__init__(self, 'test') self.title, self.input = input.split('\n', 1) if self.title: self.title = self.title.strip() self.correct = correct self.file = file self.line = line self._setup = setup self._teardown = teardown req = Mock(href=Href('/'), abs_href=Href('http://www.example.com/'), authname='anonymous', perm=MockPerm(), args={}) if context: if isinstance(context, tuple): context = Context.from_request(req, *context) else: context = Context.from_request(req, 'wiki', 'WikiStart') self.context = context self.env = EnvironmentStub() # -- macros support self.env.path = '' # -- intertrac support self.env.config.set('intertrac', 'trac.title', "Trac's Trac") self.env.config.set('intertrac', 'trac.url', "http://trac.edgewall.org") self.env.config.set('intertrac', 't', 'trac') self.env.config.set('intertrac', 'th.title', "Trac Hacks") self.env.config.set('intertrac', 'th.url', "http://trac-hacks.org") self.env.config.set('intertrac', 'th.compat', 'false') # TODO: remove the following lines in order to discover # all the places were we should use the req.href # instead of env.href self.env.href = req.href self.env.abs_href = req.abs_href
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): context = Context.from_request(req) db = self.env.get_db_cnx() context.cursor = db.cursor() if req.args.get('fromDMY') and req.args.get('toDMY'): fromDMY = int(time.mktime(time.strptime(req.args.get('fromDMY'), '%d-%m-%Y'))).__str__() toDMY = int(time.mktime(time.strptime(req.args.get('toDMY'), '%d-%m-%Y'))).__str__() all_tickets_with_worklogs=[] tickets_id = self._get_tickets_for_period(fromDMY, toDMY) for ticket in tickets_id: worked_time=0 worklogByTicket=WorkLogTable.getByTicketId(self.env, ticket['ticketId']) for worklog in worklogByTicket: worked_time+=worklog['time_spent'] worklog = { 'ticketId': ticket['ticketId'], 'summary':ticket['summary'], 'worked_time':worked_time, 'worked_time_hours':worked_time/60, 'worked_time_minutes':worked_time%60, 'worklogs': worklogByTicket } if worklog['worklogs']!=[]: all_tickets_with_worklogs.append(worklog) total_time=0 for tickets in all_tickets_with_worklogs: total_time+=tickets['worked_time'] req.data = { 'fromDMY': req.args.get('fromDMY'), 'toDMY': req.args.get('toDMY'), 'tickets_with_worklogs':all_tickets_with_worklogs, 'total_time_hours':total_time/60, 'total_time_minutes':total_time%60 } add_stylesheet(req, 'trac/css/tracker.css') add_stylesheet(req, 'trac/css/work-log.css') return "period_report.html", req.data, None else: req.data = {} add_script(req, 'common/js/jquery-ui.js') add_stylesheet(req, 'common/css/jquery-ui/jquery-ui.css') add_script(req, 'common/js/jquery-ui-addons.js') add_stylesheet(req, 'common/css/jquery-ui-addons.css') add_stylesheet(req, 'trac/css/tracker.css') return "report_date_picker.html", req.data, None
def process_request(self, req): context = Context.from_request(req) req.data = {} db = self.env.get_db_cnx() context.cursor = db.cursor() actions = self._get_actions(context) template, content_type = self._do_actions(context, actions) add_stylesheet(req, 'trac/css/tracker.css') return req.data['template'], req.data, None
def wiki_setup(tc): tc.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) tc.env.path = tempfile.mkdtemp() tc.db_mgr = DatabaseManager(tc.env) tc.db = tc.env.get_db_cnx() cursor = tc.db.cursor() cursor.execute("DROP TABLE IF EXISTS tags") cursor.execute("DROP TABLE IF EXISTS tags_change") cursor.execute("DELETE FROM system WHERE name='tags_version'") cursor.execute("DELETE FROM permission WHERE action %s" % tc.db.like(), ('TAGS_%', )) TagSetup(tc.env).upgrade_environment(tc.db) now = datetime.now(utc) wiki = WikiPage(tc.env) wiki.name = 'TestPage' wiki.text = '--' wiki.save('joe', 'TagsPluginTestPage', '::1', now) cursor = tc.db.cursor() # Populate table with initial test data. cursor.executemany( """ INSERT INTO tags (tagspace, name, tag) VALUES (%s,%s,%s) """, [ ('wiki', 'TestPage', '2ndtag'), ('wiki', 'TestPage', 'a.really?_\wild-thing'), ('wiki', 'TestPage', 'heavily-quoted'), ('wiki', 'TestPage', 'onetag'), ('wiki', 'TestPage', 'tagged'), ('wiki', 'TestPage', "single'quote"), ]) req = Mock(href=Href('/'), abs_href=Href('http://www.example.com/'), authname='anonymous', perm=MockPerm(), tz=utc, args={}, locale=locale_en) tc.env.href = req.href tc.env.abs_href = req.abs_href tc.context = Context.from_request(req) # Enable big diff output. tc.maxDiff = None
def _prop_changes(old_node, new_node): old_source = Resource('source', old_node.created_path, version=old_node.created_rev) new_source = Resource('source', new_node.created_path, version=new_node.created_rev) old_props = new_props = [] if 'FILE_VIEW' in req.perm(old_source): old_props = old_node.get_properties() if 'FILE_VIEW' in req.perm(new_source): new_props = new_node.get_properties() old_ctx = Context.from_request(req, old_source) new_ctx = Context.from_request(req, new_source) changed_properties = [] if old_props != new_props: for k, v in sorted(old_props.items()): new = old = diff = None if not k in new_props: old = v # won't be displayed, no need to render it elif v != new_props[k]: diff = self.render_property_diff( k, old_ctx, old_props, new_ctx, new_props, options) if not diff: old = browser.render_property(k, 'changeset', old_ctx, old_props) new = browser.render_property(k, 'changeset', new_ctx, new_props) if new or old or diff: changed_properties.append({'name': k, 'old': old, 'new': new, 'diff': diff}) for k, v in sorted(new_props.items()): if not k in old_props: new = browser.render_property(k, 'changeset', new_ctx, new_props) if new is not None: changed_properties.append({'name': k, 'new': new, 'old': None}) return changed_properties
def get_search_results(self, req, terms, filters): if not 'discussion' in filters: return # Create context. context = Context.from_request(req) context.realm = 'discussion-core' # Get database access. db = self.env.get_db_cnx() cursor = db.cursor() # Search in topics. query, args = search_to_sql(db, ['author', 'subject', 'body'], terms) columns = ('id', 'forum', 'time', 'subject', 'body', 'author') sql = ("SELECT id, forum, time, subject, body, author " "FROM topic " " WHERE %s" % (query, )) self.log.debug(sql) cursor.execute(sql, args) for row in cursor: row = dict(zip(columns, row)) row['time'] = to_datetime(row['time'], utc) yield (req.href.discussion('topic', row['id']) + '#-1', "Topic #%d: %s" % (row['id'], shorten_line(row['subject'])), row['time'], row['author'], shorten_result(row['body'], [query])) # Search in messages query, args = search_to_sql(db, ['m.author', 'm.body', 't.subject'], terms) columns = ('id', 'forum', 'topic', 'time', 'author', 'body', 'subject') sql = ("SELECT m.id, m.forum, m.topic, m.time, m.author, m.body, " "t.subject " "FROM message m " "LEFT JOIN " "(SELECT subject, id " "FROM topic) t " "ON t.id = m.topic " "WHERE %s" % (query)) self.log.debug(sql) cursor.execute(sql, args) for row in cursor: row = dict(zip(columns, row)) row['time'] = to_datetime(row['time'], utc) yield (req.href.discussion('message', row['id']) + '#%s' % (row['id']), "Message #%d: %s" % (row['id'], shorten_line(row['subject'])), row['time'], row['author'], shorten_result(row['body'], [query]))
def get_timeline_events(self, req, start, stop, filters): if ('downloads' in filters) and ('DOWNLOADS_VIEW' in req.perm): # Create context. context = Context.from_request(req)('downloads-timeline') db = self.env.get_db_cnx() context.cursor = db.cursor() try: # Get API component. api = self.env[DownloadsApi] # Get message events for download in api.get_new_downloads(context, to_timestamp(start), to_timestamp(stop)): yield ('newdownload', download['time'], download['author'], download['id']) except: # API maybe disabled or tables are not updated to db pass
def _format_reminder(self, req, ticket, id, time, author, origin, description, delete_button=True): now = to_datetime(None) time = to_datetime(time) if now >= time: when = tag(tag.strong("Right now"), " (pending)") else: when = tag("In ", tag.strong(pretty_timedelta(time)), " (", format_date(time), ")") if description: context = Context.from_request(req, ticket.resource) desc = tag.div(format_to_oneliner(self.env, context, description), class_="description") else: desc = tag() return tag(self._reminder_delete_form(req, id) if delete_button else None, when, " - added by ", tag.em(Chrome(self.env).authorinfo(req, author)), " ", tag.span(pretty_timedelta(origin), title=format_datetime(origin, req.session.get('datefmt', 'iso8601'), req.tz)), " ago.", desc)
def test_converted_doctest(self): self.repos.get_changeset = lambda x: Mock(date=to_datetime(12345, utc)) BuildConfig(self.env, name='trunk', path='trunk').insert() Build(self.env, rev=123, config='trunk', rev_time=12345, platform=1).insert() rpt = Report(self.env, build=1, step='test', category='coverage') rpt.items.append({'file': 'foo.py', 'line_hits': '5 - 0'}) rpt.insert() ann = TestCoverageAnnotator(self.env) req = Mock(href=Href('/'), perm=MockPerm(), chrome={'warnings': []}, args={}) # Version in the branch should not match: context = Context.from_request(req, 'source', '/branches/blah/foo.py', 123) self.assertEquals(ann.get_annotation_data(context), []) # Version in the trunk should match: context = Context.from_request(req, 'source', '/trunk/foo.py', 123) data = ann.get_annotation_data(context) self.assertEquals(data, [u'5', u'-', u'0']) def annotate_row(lineno, line): row = tag.tr() ann.annotate_row(context, row, lineno, line, data) return unicode(row.generate().render('html')) self.assertEquals(annotate_row(1, 'x = 1'), u'<tr><th class="covered">5</th></tr>') self.assertEquals(annotate_row(2, ''), u'<tr><th></th></tr>') self.assertEquals(annotate_row(3, 'y = x'), u'<tr><th class="uncovered">0</th></tr>')
def get_timeline_events(self, req, start, stop, filters): if ("downloads" in filters) and ("DOWNLOADS_VIEW" in req.perm): # Create context. context = Context.from_request(req)("downloads-timeline") db = self.env.get_db_cnx() context.cursor = db.cursor() try: # Get API component. api = self.env[DownloadsApi] # Get message events for download in api.get_new_downloads(context, to_timestamp(start), to_timestamp(stop)): yield ("newdownload", download["time"], download["author"], download["id"]) except: # API maybe disabled or tables are not updated to db pass
def get_search_results(self, req, terms, filters): if not 'discussion' in filters: return # Create context. context = Context.from_request(req) context.realm = 'discussion-core' # Get database access. db = self.env.get_db_cnx() cursor = db.cursor() # Search in topics. query, args = search_to_sql(db, ['author', 'subject', 'body'], terms) columns = ('id', 'forum', 'time', 'subject', 'body', 'author') sql = ("SELECT id, forum, time, subject, body, author " "FROM topic " " WHERE %s" % (query,)) self.log.debug(sql) cursor.execute(sql, args) for row in cursor: row = dict(zip(columns, row)) row['time'] = to_datetime(row['time'], utc) yield (req.href.discussion('topic', row['id']) + '#-1', "Topic #%d: %s" % (row['id'], shorten_line(row['subject'])), row['time'], row['author'], shorten_result(row['body'], [query])) # Search in messages query, args = search_to_sql(db, ['m.author', 'm.body', 't.subject'], terms) columns = ('id', 'forum', 'topic', 'time', 'author', 'body', 'subject') sql = ("SELECT m.id, m.forum, m.topic, m.time, m.author, m.body, " "t.subject " "FROM message m " "LEFT JOIN " "(SELECT subject, id " "FROM topic) t " "ON t.id = m.topic " "WHERE %s" % (query)) self.log.debug(sql) cursor.execute(sql, args) for row in cursor: row = dict(zip(columns, row)) row['time'] = to_datetime(row['time'], utc) yield (req.href.discussion('message', row['id']) + '#%s' % ( row['id']), "Message #%d: %s" % (row['id'], shorten_line( row['subject'])), row['time'], row['author'], shorten_result( row['body'], [query]))
def get_timeline_events(self, req, start, stop, filters): self.log.debug("start: %s, stop: %s, filters: %s" % (start, stop, filters)) if ('discussion' in filters) and 'DISCUSSION_VIEW' in req.perm: # Create request context. context = Context.from_request(req) context.realm = 'discussion-core' # Get database access. db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API component. api = self.env[DiscussionApi] # Add CSS styles and scripts. add_stylesheet(context.req, 'discussion/css/discussion.css') # Get forum events. for forum in api.get_changed_forums(context, start, stop): # Return event. title = 'New forum %s created' % (forum['name'],) description = tag(format_to_oneliner(self.env, context, forum['subject']), ' - ', format_to_oneliner(self.env, context, forum['description'])) ids = ('forum', forum['id']) yield ('discussion unsolved', to_datetime(forum['time'], utc), forum['author'], (title, description, ids)) # Get topic events. for topic in api.get_changed_topics(context, start, stop): title = 'New topic on %s created' % (topic['forum_name'],) description = format_to_oneliner(self.env, context, topic['subject']) ids = ('topic', topic['id']) yield ('discussion solved' if 'solved' in topic['status'] else 'discussion unsolved', to_datetime(topic['time'], utc), topic['author'], (title, description, ids)) # Get message events. for message in api.get_changed_messages(context, start, stop): title = 'New reply on %s created' % (message['forum_name'],) description = format_to_oneliner(self.env, context, message['topic_subject']) ids = (('topic',message['topic']),'message', message['id']) yield ('discussion unsolved', to_datetime(message['time'], utc), message['author'], (title, description, ids))
def render_admin_panel(self, req, category, page, path_info): # Create request context. context = Context.from_request(req)('downloads-admin') # Set page name to request. req.args['page'] = page if page == 'platforms': req.args['platform'] = path_info elif page == 'types': req.args['type'] = path_info elif page == 'downloads': req.args['download'] = path_info # Process request and return content. api = self.env[DownloadsApi] return api.process_downloads(context)
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 get_timeline_events(self, req, start, stop, filters): self.log.debug("start: %s, stop: %s, filters: %s" % (start, stop, filters)) if ('downloads' in filters) and ('DOWNLOADS_VIEW' in req.perm): # Create context. context = Context.from_request(req)('downloads-timeline') db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] # Get message events for download in api.get_new_downloads(context, to_timestamp(start), to_timestamp(stop)): yield ('newticket', download['time'], download['author'], download['id'])
def get_timeline_events(self, req, start, stop, filters): self.log.debug("start: %s, stop: %s, filters: %s" % (start, stop, filters)) if ('screenshots' in filters) and ('SCREENSHOTS_VIEW' in req.perm): # Create context. context = Context.from_request(req)('screenshots-timeline') db = self.env.get_db_cnx() context.cursor = db.cursor() # Get API component. api = self.env[ScreenshotsApi] # Get message events for screenshot in api.get_new_screenshots(context, to_timestamp(start), to_timestamp(stop)): yield ('newticket', screenshot['time'], screenshot['author'], (screenshot['id'], screenshot['name'], screenshot['description']))
def wiki_to_html(event, wikitext): if wikitext is None: return "" try: req = Mock(href=Href(self.env.abs_href()), abs_href=self.env.abs_href, authname=event.author, perm=MockPerm(), chrome=dict(warnings=[], notices=[]), args={}) context = Context.from_request(req, event.realm, event.target.id) formatter = HtmlFormatter(self.env, context, wikitext) return formatter.generate(True) except Exception, e: raise self.log.error("Failed to render %s", repr(wikitext)) self.log.error(exception_to_unicode(e, traceback=True)) return wikitext