def expand_macro(self, formatter, name, text, args): proxy_support = urllib2.ProxyHandler({"https" : proxy_url}) opener = urllib2.build_opener(proxy_support) urllib2.install_opener(opener) url = 'https://inventaris.onroerenderfgoed.be/erfgoed/node/%s' % (Markup.escape(text)) req = urllib2.Request(url) req.add_header('Accept', 'application/json') r = urllib2.urlopen(req) data = json.load(r) link = tag.a(data['omschrijving'] + ' (' + data['id'] + ')',href=url) return link
def expand_macro(self, formatter, name, text, args): proxy_support = urllib2.ProxyHandler({"https" : proxy_url}) opener = urllib2.build_opener(proxy_support) urllib2.install_opener(opener) url = 'https://inventaris.onroerenderfgoed.be/erfgoed/node?query=%s' % (urllib2.quote(text)) req = urllib2.Request(url) req.add_header('Accept', 'application/json') r = urllib2.urlopen(req) data = json.load(r) titel = tag.div(tag.b("Uw zoekopdracht: " + Markup.escape(text))) res = tag.em("Resultaten %d - %d van %d" % \ (data['startIndex'], data['startIndex'] -1 + data['itemsPerPage'], data['totalResults'])) def make_listitem(item): def filter_html_link(link): return link['type'] == 'text/html' url = filter(filter_html_link,item['links'])[0]['href'] link = tag.a(item['omschrijving'] + ' (' + item['id'] + ')',href=url) return tag.li(link) lijst = tag.ul(map(make_listitem,data['items'])) return titel + res + lijst
def test_unescape_markup(self): string = '<b>"&"</b>' markup = Markup.escape(string) assert type(markup) is Markup self.assertEquals(string, unescape(markup))
def test_Markup_escape_None_noquotes(self): markup = Markup.escape(None, False) assert type(markup) is Markup self.assertEquals('', markup)
def render_def(s): rendered = s and render_item(s) or None if isinstance(s, str): s = Markup(s.replace('&', '&')) return [tag.td(rendered, nbsp, style='border:none'), tag.td(tag.kbd(s), style=value_style)]
def render_js_player(self): vars = simplejson.dumps(self.player_vars()) flash_playlist = simplejson.dumps(self.flash_override_playlist()) return Markup("new mcore.JWPlayer(%s, %s)" % (vars, flash_playlist))
def format_multiline_value(value): if value: return Markup(html.escape(value).replace('\n', '<text:line-break/>'). replace('\t', '<text:s/><text:s/><text:s/><text:s/>')) return ""
def render_js_player(self): return Markup('new mcore.SublimePlayer()')
def render_js_player(self): return Markup("new mcore.Html5Player()")
def _add_user(self, req, group_store, membership, username=None): """ :param req: Request :param group_store: CQDEUserGroupStore :param membership: Membership API :param username: Override username from the request """ req.perm.require('PERMISSION_GRANT') if username is None: username = req.args.get('member') group = req.args.get('group') if not username or not group: raise TracError('Invalid arguments while adding user') # Get/check if user exists auth = Authentication() username = auth.get_trac_username(username) # check if already exists if username in [ e[0] for e in group_store.get_all_user_groups() if e[1] == group ]: add_warning( req, _('User %(user)s already exists in the group %(group)s', group=group, user=username)) return # User does not yet exists in multiproject database => retrieve and create user from authentication backend(s) if not username: username = req.args.get('member') # Create user using authentication backends and sync functionality if not auth.sync_user(username): # Show warning with possibility to create a local user - if user has enough permissions. # Otherwise give traditional user cannot be found error home_perm = PermissionCache(env=self.conf.home_env, username=req.authname) if 'USER_CREATE' in home_perm: link = Href(self.conf.url_home_path)( 'admin/users/create_local', { 'goto': req.abs_href(req.path_info) }) create_link = Markup('<a href="%s">%s</a>' % (link, _('create a local user?'))) add_warning( req, _('User "%(username)s" can not be found. Check name or ', username=username) + create_link) else: add_warning( req, _('User "%(username)s" can not be found. Please check the name.', username=username)) return add_notice(req, _('Added user %s to service' % username)) # Now, retrieve the username again username = auth.get_trac_username(username) # when adding to normal project, accept possible membership requests if membership is not None: # If adding user in group it means that membership is accepted if username in membership.get_membership_requests(): membership.accept_membership(username) add_notice( req, _('Membership request has been accepted for %(who)s.', who=username)) try: group_store.add_user_to_group(username, group) add_notice( req, _('User %(who)s has been added to group %(where)s.', who=username, where=group)) except InvalidPermissionsState, e: add_warning( req, _('User %(who)s cannot be added to group %(where)s. %(reason)s', who=username, where=group, reason=e.message))
def _build(self, mo, element_store, environ): content = mo.group(1) return creoleparser.core.bldr.tag.__getattr__('span')( Markup('&' + content + ';'))
def expand_macro(self, formatter_or_context, name, content): """Return the HTML output of the macro. :param formatter_or_context: a Formatter when called as a macro, a Context when called by `GraphvizPlugin.render` :param name: Wiki macro command that resulted in this method being called. In this case, it should be 'graphviz', followed (or not) by the processor name, then by an output format, as following: graphviz.<processor>/<format> Valid processor names are: dot, neato, twopi, circo, and fdp. The default is dot. Valid output formats are: jpg, png, gif, svg and svgz. The default is the value specified in the out_format configuration parameter. If out_format is not specified in the configuration, then the default is png. examples: graphviz.dot/png -> dot png graphviz.neato/jpg -> neato jpg graphviz.circo -> circo png graphviz/svg -> dot svg :param content: The text the user entered for the macro to process. """ # check and load the configuration errmsg = self._load_config() if errmsg: return self._error_div(errmsg) ## Extract processor and format from name processor = out_format = None # first try with the RegExp engine try: m = re.match('graphviz\.?([a-z]*)\/?([a-z]*)', name) (processor, out_format) = m.group(1, 2) # or use the string.split method except: (d_sp, s_sp) = (name.split('.'), name.split('/')) if len(d_sp) > 1: s_sp = d_sp[1].split('/') if len(s_sp) > 1: out_format = s_sp[1] processor = s_sp[0] elif len(s_sp) > 1: out_format = s_sp[1] # assign default values, if instance ones are empty if not out_format: out_format = self.out_format if not processor: processor = self.processor if processor in Graphviz.Processors: proc_cmd = self.cmds[processor] else: self.log.error('render_macro: requested processor (%s) not found.' % processor) return self._error_div('requested processor (%s) not found.' % processor) if out_format not in Graphviz.Formats: self.log.error('render_macro: requested format (%s) not found.' % out_format) return self._error_div( tag.p(_("Graphviz macro processor error: " "requested format (%(fmt)s) not valid.", fmt=out_format))) encoded_cmd = (processor + unicode(self.processor_options)) \ .encode(self.encoding) encoded_content = content.encode(self.encoding) sha_key = sha.new(encoded_cmd + encoded_content).hexdigest() img_name = '%s.%s.%s' % (sha_key, processor, out_format) # cache: hash.<dot>.<png> img_path = os.path.join(self.cache_dir, img_name) map_name = '%s.%s.map' % (sha_key, processor) # cache: hash.<dot>.map map_path = os.path.join(self.cache_dir, map_name) # Check for URL="" presence in graph code URL_in_graph = 'URL=' in content # Create image if not in cache if not os.path.exists(img_path): self._clean_cache() if URL_in_graph: # translate wiki TracLinks in URL if isinstance(formatter_or_context, Context): context = formatter_or_context else: context = formatter_or_context.context content = self._expand_wiki_links(context, out_format, content) encoded_content = content.encode(self.encoding) # Antialias PNGs with rsvg, if requested if out_format == 'png' and self.png_anti_alias == True: # 1. SVG output failure, errmsg = self._launch( encoded_content, proc_cmd, '-Tsvg', '-o%s.svg' % img_path, *self.processor_options) if failure: return self._error_div(errmsg) # 2. SVG to PNG rasterization failure, errmsg = self._launch( None, self.rsvg_path, '--dpi-x=%d' % self.dpi, '--dpi-y=%d' % self.dpi, '%s.svg' % img_path, img_path) if failure: return self._error_div(errmsg) else: # Render other image formats failure, errmsg = self._launch( encoded_content, proc_cmd, '-T%s' % out_format, '-o%s' % img_path, *self.processor_options) if failure: return self._error_div(errmsg) # Generate a map file for binary formats if URL_in_graph and out_format in Graphviz.Bitmap_Formats: # Create the map if not in cache if not os.path.exists(map_path): failure, errmsg = self._launch( encoded_content, proc_cmd, '-Tcmap', '-o%s' % map_path, *self.processor_options) if failure: return self._error_div(errmsg) if errmsg: # there was a warning. Ideally we should be able to use # `add_warning` here, but that's not possible as the warnings # are already emitted at this point in the template processing return self._error_div(errmsg) # Generate HTML output img_url = formatter_or_context.href.graphviz(img_name) # for SVG(z) if out_format in Graphviz.Vector_Formats: try: # try to get SVG dimensions f = open(img_path, 'r') svg = f.readlines(1024) # don't read all f.close() svg = "".join(svg).replace('\n', '') w = re.search('width="([0-9]+)(.*?)" ', svg) h = re.search('height="([0-9]+)(.*?)"', svg) (w_val, w_unit) = w.group(1,2) (h_val, h_unit) = h.group(1,2) # Graphviz seems to underestimate height/width for SVG images, # so we have to adjust them. # The correction factor seems to be constant. w_val, h_val = [1.35 * float(x) for x in (w_val, h_val)] width = unicode(w_val) + w_unit height = unicode(h_val) + h_unit except ValueError: width = height = '100%' # insert SVG, IE compatibility return tag.object( tag.embed(src=img_url, type="image/svg+xml", width=width, height=height), data=img_url, type="image/svg+xml", width=width, height=height) # for binary formats, add map elif URL_in_graph and os.path.exists(map_path): f = open(map_path, 'r') map = f.readlines() f.close() map = "".join(map).replace('\n', '') return tag(tag.map(Markup(map), id='G'+sha_key, name='G'+sha_key), tag.img(src=img_url, usemap="#G"+sha_key, alt=_("GraphViz image"))) else: return tag.img(src=img_url, alt=_("GraphViz image"))
def render_widget(self, name, context, options): """Count ocurrences of values assigned to given ticket field. """ req = context.req params = ('field', 'query', 'verbose', 'threshold', 'max', 'title', 'view') fieldnm, query, verbose, threshold, maxitems, title, view = \ self.bind_params(name, options, *params) if query is None: if fieldnm is None: raise InvalidWidgetArgument('field', 'Missing ticket field') tsys = self.env[TicketSystem] if tsys is None: raise TracError(_('Error loading ticket system (disabled?)')) for field in tsys.get_ticket_fields(): if field['name'] == fieldnm: break else: field_maps = { 'type': { 'admin_url': 'type', 'title': 'Types', }, 'status': { 'admin_url': None, 'title': 'Statuses', }, 'priority': { 'admin_url': 'priority', 'title': 'Priorities', }, 'milestone': { 'admin_url': 'milestones', 'title': 'Milestones', }, 'component': { 'admin_url': 'components', 'title': 'Components', }, 'version': { 'admin_url': 'versions', 'title': 'Versions', }, 'severity': { 'admin_url': 'severity', 'title': 'Severities', }, 'resolution': { 'admin_url': 'resolution', 'title': 'Resolutions', }, } if fieldnm in field_maps: admin_suffix = field_maps.get(fieldnm)['admin_url'] if 'TICKET_ADMIN' in req.perm and admin_suffix is not None: hint = _( 'You can add one or more ' '<a href="%(url)s">here</a>', url=req.href.admin('ticket', admin_suffix)) else: hint = _( 'Contact your administrator for further details') return 'widget_alert.html', \ { 'title' : Markup(_('%(field)s', field=field_maps[fieldnm]['title'])), 'data' : dict(msgtype='info', msglabel="Note", msgbody=Markup(_('''There is no value defined for ticket field <em>%(field)s</em>. %(hint)s''', field=fieldnm, hint=hint) ) ) }, context else: raise InvalidWidgetArgument( 'field', 'Unknown ticket field %s' % (fieldnm, )) if field.get('custom'): sql = "SELECT COALESCE(value, ''), count(COALESCE(value, ''))" \ " FROM ticket_custom " \ " WHERE name='%(name)s' GROUP BY COALESCE(value, '')" else: sql = "SELECT COALESCE(%(name)s, ''), " \ "count(COALESCE(%(name)s, '')) FROM ticket " \ "GROUP BY COALESCE(%(name)s, '')" sql = sql % field # TODO : Implement threshold and max db = self.env.get_db_cnx() try: cursor = db.cursor() cursor.execute(sql) items = cursor.fetchall() finally: cursor.close() QUERY_COLS = [ 'id', 'summary', 'owner', 'type', 'status', 'priority' ] item_link = lambda item: req.href.query(col=QUERY_COLS + [fieldnm], **{fieldnm: item[0]}) else: query = Query.from_string(self.env, query, group=fieldnm) if query.group is None: raise InvalidWidgetArgument( 'field', 'Invalid ticket field for ticket groups') fieldnm = query.group sql, v = query.get_sql() sql = "SELECT COALESCE(%(name)s, '') , count(COALESCE(%(name)s, ''))"\ "FROM (%(sql)s) AS foo GROUP BY COALESCE(%(name)s, '')" % \ { 'name' : fieldnm, 'sql' : sql } db = self.env.get_db_cnx() try: cursor = db.cursor() cursor.execute(sql, v) items = cursor.fetchall() finally: cursor.close() query_href = query.get_href(req.href) item_link= lambda item: query_href + \ '&' + urlencode([(fieldnm, item[0])]) if fieldnm in self.DASH_ITEM_HREF_MAP: def dash_item_link(item): if item[0]: args = self.DASH_ITEM_HREF_MAP[fieldnm] + (item[0], ) return req.href(*args) else: return item_link(item) else: dash_item_link = item_link if title is None: heading = _(fieldnm.capitalize()) else: heading = None return 'widget_cloud.html', \ { 'title' : title, 'data' : dict( bounds=minmax(items, lambda x: x[1]), item_link=dash_item_link, heading=heading, items=items, verbose=verbose, view=view, ), }, \ context
def filter_stream(self, req, method, filename, stream, data): self.log.debug('IN BlackMagic') if not filename == "ticket.html": self.log.debug('Not a ticket returning') return stream fields = self.config.getlist(csection, 'fields', []) self.log.debug('read enchants = %r' % fields) for field in fields: self.log.debug('starting : %s' % field) disabled = False hidden = False hide_summary = False remove = False perms = self.config.getlist(csection, '%s.permission' % field, []) self.log.debug('read permission config: %s has %s' % (field, perms)) for (perm, denial) in [s.split(":") for s in perms]: perm = perm.upper() self.log.debug( 'testing permission: %s:%s should act= %s' % (field, perm, (not req.perm.has_permission(perm) or perm == "ALWAYS"))) if (not req.perm.has_permission(perm) or perm == "ALWAYS"): if denial: denial = denial.lower() if denial == "disable": disabled = True elif denial == "hide": hidden = True elif denial == "remove": remove = True else: disabled = True else: disabled = True if disabled or istrue( self.config.get(csection, '%s.disable' % field, False)): self.log.debug('disabling: %s' % field) stream = disable_field(stream, field) if self.config.get(csection, '%s.label' % field, None): self.log.debug('labeling: %s' % field) stream = stream | Transformer( '//label[@for="field-%s"]' % field).replace( self.config.get(csection, '%s.label' % field)) if self.config.get(csection, '%s.notice' % field, None): self.log.debug('noticing: %s' % field) stream = stream | Transformer( '//*[@id="field-%s"]' % field).after(tag.br() + tag.small()(tag.em()(Markup( self.config.get(csection, '%s.notice' % field))))) tip = self.config.get(csection, '%s.tip' % field, None) if tip: self.log.debug('tipping: %s' % field) stream = stream | Transformer( '//div[@id="banner"]').before( tag.script(type="text/javascript", src=req.href.chrome( "blackmagic", "js", "wz_tooltip.js"))()) stream = stream | Transformer( '//*[@id="field-%s"]' % field).attr( "onmouseover", "Tip('%s')" % tip.replace(r"'", r"\'")) if remove or istrue( self.config.get(csection, '%s.remove' % field, None)): self.log.debug('removing: %s' % field) stream = remove_field(stream, field) if hidden or istrue( self.config.get(csection, '%s.hide' % field, None)): self.log.debug('hiding: %s' % field) stream = hide_field(stream, field) return stream
def filter_stream(self, req, method, template, stream, data): if not (template == 'browser.html' and data.get('dir')): if ((not data.get('dir')) and (data.get('path')) and (data.get('path').endswith('.md'))): # Rendering single markdown file preview stream = stream | Transformer("//head[1]").after( tag.script( Markup( "jQuery(document).ready(function($) {" " $('#preview').each(function() {" " $(this).html(marked( $(this).children('pre').first().text() ));" " });" "});" ), type = "text/javascript" ) ) return stream add_stylesheet(req, 'common/css/code.css') repos = data.get('repos') or self.env.get_repository() rev = req.args.get('rev', None) for entry in data['dir']['entries']: # Rendering all READMEs in a directory preview try: if not entry.isdir and entry.name.lower().startswith('readme'): node = repos.get_node(entry.path, rev) req.perm(data['context'].resource).require('FILE_VIEW') mimeview = Mimeview(self.env) content = node.get_content() mimetype = node.content_type divclass = 'searchable' if entry.name.lower().endswith('.wiki'): mimetype = 'text/x-trac-wiki' divclass = 'searchable wiki' elif entry.name.lower().endswith('.md'): mimetype = 'text/x-markdown' divclass = 'searchable markdown' if not mimetype or mimetype == 'application/octet-stream': mimetype = mimeview.get_mimetype(node.name, content.read(4096)) or mimetype or 'text/plain' del content self.log.debug("ReadmeRenderer: rendering node %s@%s as %s" % (node.name, str(rev), mimetype)) output = mimeview.preview_data( data['context'], node.get_content(), node.get_content_length(), mimetype, node.created_path, '', annotations = [], force_source = False ) if output: if isinstance(output['rendered'], Stream): #content = output['rendered'].select('./pre/node()') #content = output['rendered'].select('./pre') content = output['rendered'].select('.') else: self.log.debug("GOT THERE") content = output['rendered'] insert = tag.div( tag.h1(entry.name, tag.a(Markup(' ¶'), class_ = "anchor", href = '#' + entry.name, title = 'Link to file' ), id_ = entry.name ), tag.div( content, #xml:space = "preserve", class_ = divclass, title = entry.name ), class_ = "readme", style = "padding-top: 1em;" ) stream = stream | Transformer("//div[@id='content']/div[@id='help']").before(insert) except Exception, e: self.log.debug(to_unicode(e))
class ReadmeRendererPlugin(Component): implements(ITemplateStreamFilter, ITemplateProvider, IHTMLPreviewRenderer) # http://tools.ietf.org/html/draft-ietf-appsawg-text-markdown-01 # http://tools.ietf.org/html/draft-seantek-text-markdown-media-type-00 #returns_source = True def get_quality_ratio(self, mimetype): if mimetype in ('text/markdown', 'text/x-markdown', 'text/x-web-markdown', 'text/vnd.daringfireball.markdown'): return 8 return 0 def render(self, context, mimetype, content, filename=None, url=None): self.log.debug("Using Markdown Mimeviewer") req = context.req add_stylesheet(req, 'readme/readme.css') add_script(req, 'readme/marked.js') content = content_to_unicode(self.env, content, mimetype) # for some insane reason genshi will only preserve whitespace of <pre> elements, trac calls Stream.render() inappropriately. #return tag.pre(content.encode('utf-8')) return tag.pre(content) def filter_stream(self, req, method, template, stream, data): if not (template == 'browser.html' and data.get('dir')): if ((not data.get('dir')) and (data.get('path')) and (data.get('path').endswith('.md'))): # Rendering single markdown file preview stream = stream | Transformer("//head[1]").after( tag.script( Markup( "jQuery(document).ready(function($) {" " $('#preview').each(function() {" " $(this).html(marked( $(this).children('pre').first().text() ));" " });" "});" ), type = "text/javascript" ) ) return stream add_stylesheet(req, 'common/css/code.css') repos = data.get('repos') or self.env.get_repository() rev = req.args.get('rev', None) for entry in data['dir']['entries']: # Rendering all READMEs in a directory preview try: if not entry.isdir and entry.name.lower().startswith('readme'): node = repos.get_node(entry.path, rev) req.perm(data['context'].resource).require('FILE_VIEW') mimeview = Mimeview(self.env) content = node.get_content() mimetype = node.content_type divclass = 'searchable' if entry.name.lower().endswith('.wiki'): mimetype = 'text/x-trac-wiki' divclass = 'searchable wiki' elif entry.name.lower().endswith('.md'): mimetype = 'text/x-markdown' divclass = 'searchable markdown' if not mimetype or mimetype == 'application/octet-stream': mimetype = mimeview.get_mimetype(node.name, content.read(4096)) or mimetype or 'text/plain' del content self.log.debug("ReadmeRenderer: rendering node %s@%s as %s" % (node.name, str(rev), mimetype)) output = mimeview.preview_data( data['context'], node.get_content(), node.get_content_length(), mimetype, node.created_path, '', annotations = [], force_source = False ) if output: if isinstance(output['rendered'], Stream): #content = output['rendered'].select('./pre/node()') #content = output['rendered'].select('./pre') content = output['rendered'].select('.') else: self.log.debug("GOT THERE") content = output['rendered'] insert = tag.div( tag.h1(entry.name, tag.a(Markup(' ¶'), class_ = "anchor", href = '#' + entry.name, title = 'Link to file' ), id_ = entry.name ), tag.div( content, #xml:space = "preserve", class_ = divclass, title = entry.name ), class_ = "readme", style = "padding-top: 1em;" ) stream = stream | Transformer("//div[@id='content']/div[@id='help']").before(insert) except Exception, e: self.log.debug(to_unicode(e)) stream = stream | Transformer("//head[1]").after( tag.script( Markup( "jQuery(document).ready(function($) {" " $('.markdown').each(function() {" " $(this).html(marked( $(this).children('pre').first().html() ));" " });" "});" ), type = "text/javascript" ) ) return stream