def get_resource_description(self, resource, format=None, **kwargs): env = self.env href = kwargs.get('href') if resource.parent is None: return _("Unparented form %(id)s", id=resource.id) parent_name = get_resource_name(env, resource.parent) parent_url = href and \ get_resource_url(env, resource.parent, href) or None parent = parent_url is not None and \ tag.a(parent_name, href=parent_url) or parent_name # DEVEL: resource description not implemented yet #if format == 'summary': # return Form(self.env, resource).description if resource.id: if format == 'compact': return _("Form %(form_id)s (%(parent)s)", form_id=resource.id, parent=get_resource_shortname(env, resource.parent)) # TRANSLATOR: Most verbose title, i.e. for form history page return tag(Markup(_("Form %(form_id)s (in %(parent)s)", form_id=resource.id, parent=parent))) else: # TRANSLATOR: Title printed i.e. in form select page if format == 'compact': return tag(Markup(_("Forms (%(parent)s)", parent=parent))) return tag(Markup(_("Forms in %(parent)s", parent=parent)))
def _render_change(old, new): rendered = None if old and not new: rendered = tag( Markup(_("%(value)s reset to default value", value=tag.em(old)))) elif new and not old: rendered = tag( Markup(_("from default value set to %(value)s", value=tag.em(new)))) elif old and new: if len(old) < 20 and len(new) < 20: rendered = tag( Markup( _("changed from %(old)s to %(new)s", old=tag.em(old), new=tag.em(new)))) else: nbsp = tag.br() # TRANSLATOR: same as before, but with additional line breaks rendered = tag( Markup( _("changed from %(old)s to %(new)s", old=tag.em(nbsp, old), new=tag.em(nbsp, new)))) return rendered
def post_process_request(self, req, template, data, content_type): """Do any post-processing the request might need; typically adding values to the template `data` dictionary, or changing template or mime type. `data` may be update in place. Always returns a tuple of (template, data, content_type), even if unchanged. Note that `template`, `data`, `content_type` will be `None` if: - called when processing an error page - the default request handler did not return any result (Since 0.11) """ if template == 'ticket.html': geoticket = GeoTicket(self.env) ticket = data['ticket'] message = req.session.pop('geolocation_error', None) if message: add_warning(req, Markup(message)) return (template, data, content_type)
def filter_stream(self, req, method, filename, stream, data): """Return a filtered Genshi event stream, or the original unfiltered stream if no match. `req` is the current request object, `method` is the Genshi render method (xml, xhtml or text), `filename` is the filename of the template to be rendered, `stream` is the event stream and `data` is the data for the current template. See the Genshi documentation for more information. """ # move these someplace sensible? form_id = "acctmgr_registerform" # id of the registration form msg = "Please enter the text below to prove you're not a machine." if filename == "register.html": word = random_word(self.dict_file) req.session['captcha'] = word req.session.save() if self.captcha_type == 'png': captcha = '<img src="%s"/>' % req.href('captcha.png') else: captcha = skimpyAPI.Pre(word).data() content = "<p>%s</p><p>%s</p>" % (msg, captcha) content += '<label>Confirm: <input type="text" name="captcha" class="textwidget" size="20"/></label>' stream |= Transformer('//form[@id="%s"]/fieldset[1]' % form_id).append(tag.div(Markup(content))) return stream
def post_process_request(self, req, template, data, content_type): """Do any post-processing the request might need; typically adding values to the template `data` dictionary, or changing template or mime type. `data` may be update in place. Always returns a tuple of (template, data, content_type), even if unchanged. Note that `template`, `data`, `content_type` will be `None` if: - called when processing an error page - the default request handler did not return any result (Since 0.11) """ if template != 'query.html': return (template, data, content_type) geoticket = self.geoticket() location = req.args.get('center_location', '').strip() lat = lon = None if location: try: location, (lat, lon) = geoticket.geolocate(location) except GeolocationException, e: add_script(req, 'geoticket/js/query_location_filler.js') add_warning(req, Markup(e.html()))
def load_map(self, locations, kml=None): """JS map for issues""" options = '{kml: %s}' % (kml and '"%s"' % kml or 'null') script = """$(document).ready(function() { var locations = %s; map_locations(locations, %s); })""" % (simplejson.dumps(locations), options) return tag.script(Markup(script), **{'type': 'text/javascript'})
def moreless(text, length): """Turns `text` into HTML code where everything behind `length` can be uncovered using a ''show more'' link and later covered again with a ''show less'' link.""" try: if len(text) <= length: return tag(text) except: return tag(text) return tag(tag.span(text[:length]), tag.a(' [', tag.strong(Markup('…')), ']', class_="more"), tag.span(text[length:], class_="moretext"), tag.a(' [', tag.strong('-'), ']', class_="less"))
def _wiki_edit(self, req, stream): # TRANSLATOR: Label text for link to '/tags'. link = tag.a(_("view all tags"), href=req.href.tags()) # TRANSLATOR: ... (view all tags) insert = tag(Markup(_("Tag under: (%(tags_link)s)", tags_link=link))) insert( tag.br(), tag.input(id='tags', type='text', name='tags', size='50', value=req.args.get('tags', ' '.join(self._page_tags(req)))) ) insert = tag.div(tag.label(insert), class_='field') return stream | Transformer('//div[@id="changeinfo1"]').append(insert)
def filter_stream(self, req, method, filename, stream, data): """Return a filtered Genshi event stream, or the original unfiltered stream if no match. `req` is the current request object, `method` is the Genshi render method (xml, xhtml or text), `filename` is the filename of the template to be rendered, `stream` is the event stream and `data` is the data for the current template. See the Genshi documentation for more information. """ # only show CAPTCHAs for anonymous users if req.authname != 'anonymous': return stream # only put CAPTCHAs in the realms specified realm = self.realm(req) if realm not in self.realms: return stream # add the CAPTCHA to the stream if filename in self.xpath: # store CAPTCHA in DB and session word = random_word(self.dict_file) insert_update(self.env, 'captcha', 'id', req.session.sid, dict(word=word)) req.session['captcha'] = word req.session.save() # render the template chrome = Chrome(self.env) template = chrome.load_template('captcha.html') _data = {} # CAPTCHA type if self.captcha_type == 'png': captcha = tag.img(None, src=req.href('captcha.png')) else: captcha = Markup(skimpyAPI.Pre(word).data()) _data['captcha'] = captcha _data['email'] = req.session.get('email', '') _data['name'] = req.session.get('name', '') _data['captchaid'] = req.session.sid xpath = self.xpath[filename] stream |= Transformer(xpath).before(template.generate(**_data)) if filename in self.delete: stream |= Transformer(self.delete[filename]).remove() return stream
def _blogpost_title_html(self, req, page): title_html = self._wiki_to_html(req, page.resource, self._wikitext_title(page)) title_groups = self._extract_root_tag('h1', title_html) link_html = self._wiki_to_html(req, page.resource, '[wiki:"%s"]' % page.resource.id) link_groups = self._extract_root_tag('a', link_html) opening_tags = title_groups[0] + link_groups[0] core_title_html = title_groups[1] closing_tags = link_groups[2] + title_groups[2] final_html = opening_tags + core_title_html + closing_tags return Markup(final_html)
def filter_stream(self, req, method, filename, stream, data): """Return a filtered Genshi event stream, or the original unfiltered stream if no match. `req` is the current request object, `method` is the Genshi render method (xml, xhtml or text), `filename` is the filename of the template to be rendered, `stream` is the event stream and `data` is the data for the current template. See the Genshi documentation for more information. """ # move these someplace sensible? form_id = "acctmgr_loginform" # id of the login form msg = "Please enter the text below to prove you're not a machine." if filename == "login.html": #Check whether to display capcha. db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("""SELECT * FROM login_attempts WHERE ip= '%s' """ % req.remote_addr) row1 = cursor.fetchone() db.close() self.should_display_capcha[req.remote_addr] = False if row1: if row1[1] > 2: self.should_display_capcha[req.remote_addr] = True if self.should_display_capcha[req.remote_addr] == True: word = random_word(self.dict_file) req.session['captcha'] = word req.session.save() self.last_capcha[req.remote_addr] = word if self.captcha_type == 'png': captcha = '<img src="%s"/>' % req.href('captcha.png') else: captcha = skimpyAPI.Pre(word).data() content = "<p>%s</p><p>%s</p>" % (msg, captcha) content += '<label>Confirm: <input type="text" name="captcha" class="textwidget" size="20"/></label>' stream |= Transformer('//form[@id="%s"]' % form_id).append( tag.div(Markup(content))) #DEBUG #stream |= Transformer('//form[@id="%s"]' % form_id).append(tag.div(Markup(word))) return stream
def expand_macro(self, formatter, name, content): req = formatter.req query_string = '' argv, kwargs = parse_args(content, strict=False) if 'order' not in kwargs: kwargs['order'] = 'id' if 'max' not in kwargs: kwargs['max'] = '0' # unlimited by default query_string = '&'.join( ['%s=%s' % item for item in kwargs.iteritems()]) query = Query.from_string(self.env, query_string) tickets = query.execute(req) tickets = [ t for t in tickets if 'TICKET_VIEW' in req.perm('ticket', t['id']) ] ticket_ids = [t['id'] for t in tickets] # locate the tickets geoticket = GeoTicket(self.env) locations = geoticket.locate_tickets(ticket_ids, req) if not locations: return tag.div(tag.b('MapTickets: '), "No locations found for ", tag.i(content)) data = dict(locations=Markup(simplejson.dumps(locations)), query_href=query.get_href(req), query_string=content) # set an id for the map map_id = req.environ.setdefault('MapTicketsId', 0) + 1 req.environ['MapTicketsId'] = map_id data['map_id'] = 'tickets-map-%d' % map_id return Chrome(self.env).render_template(req, 'map_tickets.html', data, None, fragment=True)
def process_request(self, req): """Process the request. For ClearSilver, return a (template_name, content_type) tuple, where `template` is the ClearSilver template to use (either a `neo_cs.CS` object, or the file name of the template), and `content_type` is the MIME type of the content. For Genshi, return a (template_name, data, content_type) tuple, where `data` is a dictionary of substitutions for the template. For both templating systems, "text/html" is assumed if `content_type` is `None`. Note that if template processing should not occur, this method can simply send the response itself and not return anything. """ gids = get_column(self.env, 'georegions', 'gid') regions = {} georegions_columns = columns(self.env, 'georegions') for gid in gids: regions[gid] = {} regions[gid]['data'] = {} _columns = [ column for column in georegions_columns if column not in set(['gid', 'the_geom']) ] for column in _columns: regions[gid]['data'][column] = get_scalar(self.env, "SELECT %s FROM georegions WHERE gid=%s" % (column, gid)) regions[gid]['region'] = Markup(get_scalar(self.env, "SELECT ST_AsKML(the_geom) FROM georegions WHERE gid=%s" % gid)) # filter out non-matching results # XXX this is hacky, but I'm not sure how to do this in SQL filter = {} for key, value in req.args.items(): if key in georegions_columns: filter[key] = value for key in regions.keys(): for _key, _value in filter.items(): if str(regions[key]['data'][_key]) != _value: del regions[key] break return 'region.kml', dict(regions=regions), 'application/vnd.google-earth.kml+xml'
def _do_switch(self, env, req, form): data = {'_dgettext': dgettext} data['page_title'] = get_resource_description(env, form.resource, href=req.href) data['title'] = get_resource_shortname(env, form.resource) data['siblings'] = [] for sibling in form.siblings: form_id = tag.strong( tag.a(_("Form %(form_id)s", form_id=sibling[0]), href=req.href.form(sibling[0]))) if sibling[1] == '': data['siblings'].append(form_id) else: # TRANSLATOR: Form list entry for form select page data['siblings'].append( tag( Markup( _("%(form_id)s (subcontext = '%(subcontext)s')", form_id=form_id, subcontext=sibling[1])))) add_stylesheet(req, 'tracforms/tracforms.css') return 'switch.html', data, None
def expand_macro(self, formatter, name, content): env = formatter.env req = formatter.req if not content: args = [] kw = {} else: args, kw = parse_args(content) if name == 'ProjectStats': if 'wiki' in kw.keys(): prefix = 'prefix' in kw.keys() and kw['prefix'] or None wiki = WikiSystem(env) if kw['wiki'] == 'count' or 'count' in args: return tag(sum(1 for page in wiki.get_pages(prefix))) elif name == 'UserQuery': msg_no_perm = tag.p(Markup( _("(required %(perm)s missing)", perm=tag.strong('USER_VIEW'))), class_='hint') users = [] if 'perm' in kw.keys(): perm_sys = PermissionSystem(self.env) users = perm_sys.get_users_with_permission(kw['perm'].upper()) else: acct_mgr = AccountManager(env) users = list(set(acct_mgr.get_users())) if 'locked' in kw.keys() or 'locked' in args: guard = AccountGuard(env) locked = [] for user in users: if guard.user_locked(user): locked.append(user) if kw.get('locked', 'True').lower() in ('true', 'yes', '1'): users = locked else: users = list(set(users) - set(locked)) elif 'visit' in kw.keys() or 'visit' in args: if not 'USER_VIEW' in req.perm: return msg_no_perm cols = [] data = {} data['accounts'] = fetch_user_data(env, req) data['cls'] = 'wiki' for col in ('email', 'name'): if col in args: cols.append(col) data['cols'] = cols data['pretty_date'] = get_pretty_dateinfo(env, req) return Chrome(env).render_template(req, 'user_table.html', data, 'text/html', True) if kw.get('format') == 'count' or 'count' in args: return tag(len(users)) if not 'USER_VIEW' in req.perm: return msg_no_perm if 'email' in args or 'name' in args: # Replace username with full name, add email if available. for username, name, email in self.env.get_known_users(): if username in users: if not 'name' in args or name is None: name = username if 'email' in args and email is not None: email = ''.join(['<', email, '>']) name = ' '.join([name, email]) if not username == name: users.pop(users.index(username)) users.append(name) if not users and 'nomatch' in kw.keys(): return format_to_oneliner(env, formatter.context, kw['nomatch']) users = sorted(users) if kw.get('format') == 'list': return tag.ul([ tag.li(Chrome(env).format_author(req, user)) for user in users ]) else: # Default output format: comma-separated list. return tag(', '.join( [Chrome(env).format_author(req, user) for user in users]))
def process_request(self, req): """Process the request. For ClearSilver, return a (template_name, content_type) tuple, where `template` is the ClearSilver template to use (either a `neo_cs.CS` object, or the file name of the template), and `content_type` is the MIME type of the content. For Genshi, return a (template_name, data, content_type) tuple, where `data` is a dictionary of substitutions for the template. For both templating systems, "text/html" is assumed if `content_type` is `None`. Note that if template processing should not occur, this method can simply send the response itself and not return anything. """ # get the GeoTicket component assert self.env.is_component_enabled(GeoTicket) geoticket = GeoTicket(self.env) # add the query script add_script(req, 'common/js/query.js') # get the panel configuration config = self.panels() # build the panels panels = [] located_tickets = geoticket.tickets_with_location() for panel in config: # query the tickets query_string = panel['query'] query = Query.from_string(self.env, query_string) # decide the date to sort by if query.order == 'time': date_to_display = 'time_created' else: date_to_display = 'time_changed' results = query.execute(req) n_tickets = len(results) results = [ result for result in results if result['id'] in located_tickets ] locations = [] tickets = [] results = results[:self.dashboard_tickets] for result in results: ticket = Ticket(self.env, result['id']) try: address, (lat, lon) = geoticket.locate_ticket(ticket) content = geoticket.feature_content(req, ticket) # style for the markers style = {} for extension in self.marker_style: style.update(extension.style(ticket, req, **style)) style = style or None locations.append({ 'latitude': lat, 'longitude': lon, 'style': style, 'content': Markup(content) }) tickets.append(ticket) except GeolocationException: continue title = panel['label'] panels.append({ 'title': title, 'id': panel['id'], 'locations': Markup(simplejson.dumps(locations)), 'tickets': tickets, 'n_tickets': n_tickets, 'date_to_display': date_to_display, 'query_href': query.get_href(req.href) }) # add the tag cloud, if enabled cloud = None if self.display_cloud: if TagCloudMacro is None: self.log.warn( "[geo] display_cloud is set but the TagsPlugin is not installed" ) else: formatter = Formatter(self.env, Context.from_request(req)) macro = TagCloudMacro(self.env) cloud = macro.expand_macro(formatter, 'TagCloud', '') add_stylesheet(req, 'tags/css/tractags.css') add_stylesheet(req, 'tags/css/tagcloud.css') # compile data for the genshi template data = dict(panels=panels, cloud=cloud, openlayers_url=self.openlayers_url) return ('mapdashboard.html', data, 'text/html')