Ejemplo n.º 1
0
 def post_process_request(self, req, template, data, content_type):
     if req.method == 'GET' and req.path_info.startswith('/wiki/') and \
             req.args.get('action') == 'edit' and \
             req.args.get('template') and 'tags' not in req.args:
         # Retrieve template resource to be queried for tags.
         template_page = WikiPage(
             self.env, ''.join([
                 WikiModule.PAGE_TEMPLATES_PREFIX,
                 req.args.get('template')
             ]))
         if template_page and template_page.exists and \
                 'TAGS_VIEW' in req.perm(template_page.resource):
             ts = TagSystem(self.env)
             tags = sorted(ts.get_tags(req, template_page.resource))
             # Prepare tags as content for the editor field.
             tags_str = ' '.join(tags)
             self.env.log.debug("Tags retrieved from template: '%s'" \
                                % unicode(tags_str).encode('utf-8'))
             # DEVEL: More arguments need to be propagated here?
             req.redirect(
                 req.href(req.path_info,
                          action='edit',
                          tags=tags_str,
                          template=req.args.get('template')))
     return (template, data, content_type)
Ejemplo n.º 2
0
    def _page_tags(self, req):
        pagename = req.args.get('page', 'WikiStart')

        tag_system = TagSystem(self.env)
        resource = Resource('wiki', pagename)
        tags = sorted(tag_system.get_tags(req, resource))
        return tags
Ejemplo n.º 3
0
    def _page_tags(self, req):
        pagename = req.args.get('page', 'WikiStart')

        tag_system = TagSystem(self.env)
        resource = Resource('wiki', pagename)
        tags = sorted(tag_system.get_tags(req, resource))
        return tags
Ejemplo n.º 4
0
    def post_process_request(self, req, template, data, content_type):
        if data and req.path_info == '/timeline' and \
                'TAGS_VIEW' in req.perm(Resource('tags')):

            def realm_handler(_, node, context):
                return query.match(node, [context.realm])

            query_str = req.args.getfirst(self.key)
            if query_str is None and req.args.get('format') != 'rss':
                query_str = req.session.get('timeline.%s' % self.key)
            else:
                query_str = (query_str or '').strip()
                # Record tag query expression between visits.
                req.session['timeline.%s' % self.key] = query_str

            if data.get('events') and query_str:
                tag_system = TagSystem(self.env)
                try:
                    query = Query(query_str,
                                  attribute_handlers={'realm': realm_handler})
                except InvalidQuery as e:
                    add_warning(req, _("Tag query syntax error: %s" % e))
                else:
                    all_realms = tag_system.get_taggable_realms(req.perm)
                    query_realms = set()
                    for m in REALM_RE.finditer(query.as_string()):
                        query_realms.add(m.group(1))
                    # Don't care about resources from non-taggable realms.
                    realms = not query_realms and all_realms or \
                             query_realms.intersection(all_realms)
                    events = []
                    self.log.info("Filtering timeline events by tags '%s'",
                                   query_str)
                    for event in data['events']:
                        resource = resource_from_event(event)
                        if resource and resource.realm in realms:
                            # Shortcut view permission checks here.
                            tags = tag_system.get_tags(None, resource)
                            if query(tags, context=resource):
                                events.append(event)
                    # Overwrite with filtered list.
                    data['events'] = events
            if query_str:
                # Add current value for next form rendering.
                data[self.key] = query_str
            elif self.key in req.session:
                del req.session[self.key]

            filter_lst = []
            # xpath = '//form[@id="prefs"]/div[1]'
            xform = JTransformer('form#prefs > div:nth-of-type(1)')
            insert = builder(Markup('<br />'), tag_("matching tags "),
                             builder.input(type='text', name=self.key,
                                           value=data.get(self.key)))
            filter_lst.append(xform.append(Markup(insert)))
            add_script_data(req, {'tags_filter': filter_lst})
            add_script(req, 'tags/js/tags_jtransform.js')

        return template, data, content_type
Ejemplo n.º 5
0
    def _update_tags(self, req, page):
        tag_system = TagSystem(self.env)
        newtags = tag_system.split_into_tags(req.args.get('tags', ''))
        oldtags = tag_system.get_tags(req, page.resource)

        if oldtags != newtags:
            tag_system.set_tags(req, page.resource, newtags)
            return True
        return False
Ejemplo n.º 6
0
    def _update_tags(self, req, page):
        tag_system = TagSystem(self.env)
        newtags = tag_system.split_into_tags(req.args.get('tags', ''))
        oldtags = tag_system.get_tags(req, page.resource)

        if oldtags != newtags:
            tag_system.set_tags(req, page.resource, newtags)
            return True
        return False
Ejemplo n.º 7
0
    def _page_tags(self, req):
        pagename = req.args.get('page', 'WikiStart')
        version = req.args.get('version')
        tags_version = req.args.get('tags_version')

        page = WikiPage(self.env, pagename, version=version)
        resource = page.resource
        if version and not tags_version:
            tags_version = page.time
        tag_sys = TagSystem(self.env)
        tags = sorted(tag_sys.get_tags(req, resource, when=tags_version))
        return tags
Ejemplo n.º 8
0
    def post_process_request(self, req, template, data, content_type):
        if data and req.path_info == '/timeline' and \
                'TAGS_VIEW' in req.perm(Resource('tags')):

            def realm_handler(_, node, context):
                return query.match(node, [context.realm])

            query_str = req.args.get(self.key)
            if query_str is None and req.args.get('format') != 'rss':
                query_str = req.session.get('timeline.%s' % self.key)
            else:
                query_str = (query_str or '').strip()
                # Record tag query expression between visits.
                req.session['timeline.%s' % self.key] = query_str

            if data.get('events') and query_str:
                tag_system = TagSystem(self.env)
                try:
                    query = Query(query_str,
                                  attribute_handlers=dict(realm=realm_handler)
                            )
                except InvalidQuery, e:
                    add_warning(req, _("Tag query syntax error: %s"
                                       % to_unicode(e)))
                else:
                    all_realms = tag_system.get_taggable_realms(req.perm)
                    query_realms = set()
                    for m in REALM_RE.finditer(query.as_string()):
                        query_realms.add(m.group(1))
                    # Don't care about resources from non-taggable realms.
                    realms = not query_realms and all_realms or \
                             query_realms.intersection(all_realms)
                    events = []
                    self.log.debug("Filtering timeline events by tags '%s'",
                                   query_str)
                    for event in data['events']:
                        resource = event['data'][0]
                        if resource.realm in realms:
                            # Shortcut view permission checks here.
                            tags = tag_system.get_tags(None, resource)
                            if query(tags, context=resource):
                                events.append(event)
                    # Overwrite with filtered list.
                    data['events'] = events
            if query_str:
                # Add current value for next form rendering.
                data[self.key] = query_str
            elif self.key in req.session:
                del req.session[self.key]
Ejemplo n.º 9
0
    def post_process_request(self, req, template, data, content_type):
        if data and req.path_info == '/timeline' and \
                'TAGS_VIEW' in req.perm(Resource('tags')):

            def realm_handler(_, node, context):
                return query.match(node, [context.realm])

            query_str = req.args.get(self.key)
            if query_str is None and req.args.get('format') != 'rss':
                query_str = req.session.get('timeline.%s' % self.key)
            else:
                query_str = (query_str or '').strip()
                # Record tag query expression between visits.
                req.session['timeline.%s' % self.key] = query_str

            if data.get('events') and query_str:
                tag_system = TagSystem(self.env)
                try:
                    query = Query(query_str,
                                  attribute_handlers=dict(realm=realm_handler))
                except InvalidQuery, e:
                    add_warning(
                        req, _("Tag query syntax error: %s" % to_unicode(e)))
                else:
                    all_realms = tag_system.get_taggable_realms(req.perm)
                    query_realms = set()
                    for m in REALM_RE.finditer(query.as_string()):
                        query_realms.add(m.group(1))
                    # Don't care about resources from non-taggable realms.
                    realms = not query_realms and all_realms or \
                             query_realms.intersection(all_realms)
                    events = []
                    self.log.debug("Filtering timeline events by tags '%s'" %
                                   query_str)
                    for event in data['events']:
                        resource = event['data'][0]
                        if resource.realm in realms:
                            # Shortcut view permission checks here.
                            tags = tag_system.get_tags(None, resource)
                            if query(tags, context=resource):
                                events.append(event)
                    # Overwrite with filtered list.
                    data['events'] = events
            if query_str:
                # Add current value for next form rendering.
                data[self.key] = query_str
            elif self.key in req.session:
                del req.session[self.key]
Ejemplo n.º 10
0
 def _post_process_request_edit(self, req):
     # Retrieve template resource to be queried for tags.
     template_pagename = ''.join([WikiModule.PAGE_TEMPLATES_PREFIX,
                                  req.args.get('template')])
     template_page = WikiPage(self.env, template_pagename)
     if template_page.exists and \
             'TAGS_VIEW' in req.perm(template_page.resource):
         tag_sys = TagSystem(self.env)
         tags = sorted(tag_sys.get_tags(req, template_page.resource))
         # Prepare tags as content for the editor field.
         tags_str = ' '.join(tags)
         self.env.log.debug("Tags retrieved from template: '%s'" \
                            % unicode(tags_str).encode('utf-8'))
         # DEVEL: More arguments need to be propagated here?
         req.redirect(req.href(req.path_info,
                               action='edit', tags=tags_str,
                               template=req.args.get('template')))
Ejemplo n.º 11
0
 def post_process_request(self, req, template, data, content_type):
     if req.method == 'GET' and req.path_info.startswith('/wiki/') and \
             req.args.get('action') == 'edit' and \
             req.args.get('template') and 'tags' not in req.args:
         # Retrieve template resource to be queried for tags.
         template_page = WikiPage(self.env,''.join(
                                  [WikiModule.PAGE_TEMPLATES_PREFIX,
                                   req.args.get('template')]))
         if template_page and template_page.exists and \
                 'TAGS_VIEW' in req.perm(template_page.resource):
             ts = TagSystem(self.env)
             tags = sorted(ts.get_tags(req, template_page.resource))
             # Prepare tags as content for the editor field.
             tags_str = ' '.join(tags)
             self.env.log.debug("Tags retrieved from template: '%s'" \
                                % unicode(tags_str).encode('utf-8'))
             # DEVEL: More arguments need to be propagated here?
             req.redirect(req.href(req.path_info,
                                   action='edit', tags=tags_str,
                                   template=req.args.get('template')))
     return (template, data, content_type)
Ejemplo n.º 12
0
 def _get_stored_tags(self, req, resource):
     # Return tags associated to resource.
     tag_system = TagSystem(self.env)
     tags = tag_system.get_tags(req, resource)
     return sorted(tags)
Ejemplo n.º 13
0
class WikiTagInterface(TagTemplateProvider):
    """[main] Implements the user interface for tagging Wiki pages."""

    implements(IRequestFilter, ITemplateStreamFilter, IWikiChangeListener,
               IWikiPageManipulator)

    def __init__(self):
        self.tag_system = TagSystem(self.env)

    # IRequestFilter methods

    def pre_process_request(self, req, handler):
        return handler

    def post_process_request(self, req, template, data, content_type):
        if template is not None:
            if req.method == 'GET' and req.path_info.startswith('/wiki/'):
                if req.args.get('action') == 'edit' and \
                        req.args.get('template') and 'tags' not in req.args:
                    self._post_process_request_edit(req)
                if req.args.get('action') == 'history' and \
                        data and 'history' in data:
                    self._post_process_request_history(req, data)
            elif req.method == 'POST' and \
                    req.path_info.startswith('/wiki/') and \
                    'save' in req.args:
                requests.reset()
        return template, data, content_type

    # ITemplateStreamFilter methods
    def filter_stream(self, req, method, filename, stream, data):
        page_name = req.args.get('page', 'WikiStart')
        resource = Resource('wiki', page_name)
        if filename == 'wiki_view.html' and 'TAGS_VIEW' in req.perm(resource):
            return self._wiki_view(req, stream)
        elif filename == 'wiki_edit.html' and \
                         'TAGS_MODIFY' in req.perm(resource):
            return self._wiki_edit(req, stream)
        elif filename == 'history_view.html' and \
                         'TAGS_VIEW' in req.perm(resource):
            return self._wiki_history(req, stream)
        return stream

    # IWikiPageManipulator methods
    def prepare_wiki_page(self, req, page, fields):
        pass

    def validate_wiki_page(self, req, page):
        # If we're saving the wiki page, and can modify tags, do so.
        if req and 'TAGS_MODIFY' in req.perm(page.resource) \
                and req.path_info.startswith('/wiki') and 'save' in req.args:
            page_modified = req.args.get('text') != page.old_text or \
                    page.readonly != int('readonly' in req.args)
            if page_modified:
                requests.set(req)
                req.add_redirect_listener(self._redirect_listener)
            elif page.version > 0:
                # If the page hasn't been otherwise modified, save tags and
                # redirect to avoid the "page has not been modified" warning.
                if self._update_tags(req, page):
                    req.redirect(
                        get_resource_url(self.env,
                                         page.resource,
                                         req.href,
                                         version=None))
        return []

    # IWikiChangeListener methods
    def wiki_page_added(self, page):
        req = requests.get()
        if req:
            self._update_tags(req, page, page.time)

    def wiki_page_changed(self, page, version, t, comment, author, ipnr):
        req = requests.get()
        if req:
            self._update_tags(req, page, page.time)

    def wiki_page_renamed(self, page, old_name):
        """Called when a page has been renamed (since Trac 0.12)."""
        self.log.debug("Moving wiki page tags from %s to %s", old_name,
                       page.name)
        req = MockReq()
        self.tag_system.reparent_tags(req, Resource('wiki', page.name),
                                      old_name)

    def wiki_page_deleted(self, page):
        # Page gone, so remove all records on it.
        delete_tags(self.env, page.resource, purge=True)

    def wiki_page_version_deleted(self, page):
        pass

    # Internal methods
    def _page_tags(self, req):
        pagename = req.args.get('page', 'WikiStart')
        version = req.args.get('version')
        tags_version = req.args.get('tags_version')

        page = WikiPage(self.env, pagename, version=version)
        resource = page.resource
        if version and not tags_version:
            tags_version = page.time
        tags = sorted(
            self.tag_system.get_tags(req, resource, when=tags_version))
        return tags

    def _redirect_listener(self, req, url, permanent):
        requests.reset()

    def _post_process_request_edit(self, req):
        # Retrieve template resource to be queried for tags.
        template_pagename = ''.join(
            [WikiModule.PAGE_TEMPLATES_PREFIX,
             req.args.get('template')])
        template_page = WikiPage(self.env, template_pagename)
        if template_page.exists and \
                'TAGS_VIEW' in req.perm(template_page.resource):
            tags = sorted(self.tag_system.get_tags(req,
                                                   template_page.resource))
            # Prepare tags as content for the editor field.
            tags_str = ' '.join(tags)
            self.env.log.debug("Tags retrieved from template: '%s'",
                               unicode(tags_str).encode('utf-8'))
            # DEVEL: More arguments need to be propagated here?
            req.redirect(
                req.href(req.path_info,
                         action='edit',
                         tags=tags_str,
                         template=req.args.get('template')))

    def _post_process_request_history(self, req, data):
        history = []
        page_histories = data.get('history', [])
        resource = data['resource']
        tags_histories = tag_changes(self.env, resource)

        for page_history in page_histories:
            while tags_histories and \
                    tags_histories[0][0] >= page_history['date']:
                tags_history = tags_histories.pop(0)
                date = tags_history[0]
                author = tags_history[1]
                comment = render_tag_changes(tags_history[2], tags_history[3])
                url = req.href(resource.realm,
                               resource.id,
                               version=page_history['version'],
                               tags_version=to_utimestamp(date))
                history.append({
                    'version': '*',
                    'url': url,
                    'date': date,
                    'author': author,
                    'comment': comment,
                    'ipnr': ''
                })
            history.append(page_history)

        data.update(
            dict(history=history, wiki_to_oneliner=self._wiki_to_oneliner))

    def _wiki_view(self, req, stream):
        add_stylesheet(req, 'tags/css/tractags.css')
        tags = self._page_tags(req)
        if not tags:
            return stream
        li = []
        for tag_ in tags:
            resource = Resource('tag', tag_)
            anchor = render_resource_link(self.env, web_context(req, resource),
                                          resource)
            anchor = anchor(rel='tag')
            li.append(tag.li(anchor, ' '))

        # TRANSLATOR: Header label text for tag list at wiki page bottom.
        insert = tag.ul(class_='tags')(tag.li(_("Tags"), class_='header'), li)
        return stream | (
            Transformer('//div[contains(@class,"wikipage")]').after(insert))

    def _update_tags(self, req, page, when=None):
        newtags = split_into_tags(req.args.get('tags', ''))
        oldtags = self.tag_system.get_tags(req, page.resource)

        if oldtags != newtags:
            self.tag_system.set_tags(req, page.resource, newtags, when=when)
            return True
        return False

    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 _wiki_history(self, req, stream):
        xpath = '//input[@type="radio" and @value="*"]'
        stream = stream | Transformer(xpath).remove()
        # Remove invalid links to wiki page revisions (fix for Trac < 0.12).
        xpath = '//a[contains(@href,"%2A")]'
        return stream | Transformer(xpath).remove()

    def _wiki_to_oneliner(self, context, wiki, shorten=None):
        if isinstance(wiki, Fragment):
            return wiki
        return format_to_oneliner(self.env, context, wiki, shorten=shorten)
Ejemplo n.º 14
0
class HacksCache(Borg):
    _lock = threading.RLock()
    _initialized = False

    _hacks = dict()
    _types = dict()
    _releases = dict()

    def __init__(self, env):
        if self._initialized:
            self._log('already initialized')
            return
        else:
            env.log.debug('HacksCache %x: initializing' % id(self.__dict__))

        self._lock.acquire()

        self._env = env
        self._tag_system = TagSystem(env)
        self._req = FakeRequest(env)
        self.id = id(self.__dict__)

        self._rebuild_cache()

        self._initialized = True
        self._lock.release()
        self._log('initialization finished')

    def __del__(self):
        self._log('Aiiieeeee')

    def _rebuild_cache(self):
        """ Rebuild the cache. Caller MUST hold the lock! """
        self._log('rebuilding cache (initialized=%s)' % self._initialized)
        self._hacks = dict()
        self._types = dict()
        self._releases = dict()

        self._update_types()
        self._update_releases()

        query  = 'realm:wiki (%s) (%s)' % \
            (' or '.join(self._types), ' or '.join(self._releases))
        for h in self._query_tags(query):
            self._update_hack(h, False, False)

    def _log(self, message):
        self._env.log.debug('HacksCache %x: %s' % (self.id, message))

    def _query_tags(self, query):
        """ Helper to perform queries on cached tags system """
        return [r.id for r, _ in self._tag_system.query(self._req, query)]

    def _update_types(self):
        """ Get/update list of hack types """
        types = self._query_tags('realm:wiki type')
        keys = self._types.keys()

        # add types that have been added since last update
        for t in types:
            if t not in keys:
                self._types[t] = Tag(t, self._env, self._req, self._tag_system)

        # remove types that no longer exist
        for k in keys:
            if k not in types:
                del self._types[k]

    def _update_releases(self):
        """ Get/update list of Trac releases """
        releases = self._query_tags('realm:wiki release')
        keys = self._releases.keys()

        # add releases that have been added since last update
        for r in releases:
            if r not in keys:
                self._releases[r] = Tag(r, self._env, self._req,
                                        self._tag_system)

        # remove releases that no longer exist
        for k in keys:
            if k not in releases:
                del self._releases[k]

    def _update_hack(self, name, full_update=True, check_delete=True):
        """ Get/update/delete hack properties """
        if full_update:
            self._update_types()
            self._update_releases()

        delete = False
        if check_delete:
            page = WikiPage(self._env, name)
            if page.exists:
                tags = set(self._tag_system.get_tags(self._req, page.resource))
                if not (tags.intersection(self._types)
                        and tags.intersection(self._releases)):
                    delete = True
            else:
                delete = True

        if delete:
            try:
                del self._hacks[name]
                self._log('deleted hack %s' % name)
            except:
                self._log('%s is no hack, skipped' % name)
        else:
            try:
                self._hacks[name].update()
                self._log('updated hack %s' % name)
            except:
                self._hacks[name] = Hack(name, self._env, self._req,
                                         self._tag_system)
                self._log('learned hack %s' % name)

    def _get(self, where, what):
        try:
            return where[what]
        except:
            return None

    def _get_all(self, where, sorted=False):
        v = where.values()
        if sorted:
            return natural_sort(v)
        else:
            return v

    # Public API
    def update(self, hack=None):
        """ Update cache for all or just the given hack """
        if hack:
            self._update_hack(hack, True, True)
        else:
            self._lock.acquire()
            self._rebuild_cache()
            self._lock.release()

    def get_type(self, name):
        return self._get(self._types, name)

    def get_all_types(self, sorted=False):
        return self._get_all(self._types, sorted)

    def get_release(self, name):
        return self._get(self._releases, name)

    def get_all_releases(self, sorted=False):
        return self._get_all(self._releases, sorted)

    def get_hack(self, name):
        return self._get(self._hacks, name)

    def get_all_hacks(self, sorted=False):
        return self._get_all(self._hacks, sorted)
Ejemplo n.º 15
0
 def _get_stored_tags(self, req, download_id):
     tag_system = TagSystem(self.env)
     resource = Resource('downloads', download_id)
     tags = tag_system.get_tags(req, resource)
     return sorted(tags)
Ejemplo n.º 16
0
class WikiTagInterface(TagTemplateProvider):
    """[main] Implements the user interface for tagging Wiki pages."""

    implements(IRequestFilter, ITemplateStreamFilter,
               IWikiChangeListener, IWikiPageManipulator)

    def __init__(self):
        self.tag_system = TagSystem(self.env)

    # IRequestFilter methods

    def pre_process_request(self, req, handler):
        return handler

    def post_process_request(self, req, template, data, content_type):
        if template is not None:
            if req.method == 'GET' and req.path_info.startswith('/wiki/'):
                if req.args.get('action') == 'edit' and \
                        req.args.get('template') and 'tags' not in req.args:
                    self._post_process_request_edit(req)
                if req.args.get('action') == 'history' and \
                        data and 'history' in data:
                    self._post_process_request_history(req, data)
            elif req.method == 'POST' and \
                    req.path_info.startswith('/wiki/') and \
                    'save' in req.args:
                requests.reset()
        return template, data, content_type

    # ITemplateStreamFilter methods
    def filter_stream(self, req, method, filename, stream, data):
        page_name = req.args.get('page', 'WikiStart')
        resource = Resource('wiki', page_name)
        if filename == 'wiki_view.html' and 'TAGS_VIEW' in req.perm(resource):
            return self._wiki_view(req, stream)
        elif filename == 'wiki_edit.html' and \
                         'TAGS_MODIFY' in req.perm(resource):
            return self._wiki_edit(req, stream)
        elif filename == 'history_view.html' and \
                         'TAGS_VIEW' in req.perm(resource):
            return self._wiki_history(req, stream)
        return stream

    # IWikiPageManipulator methods
    def prepare_wiki_page(self, req, page, fields):
        pass

    def validate_wiki_page(self, req, page):
        # If we're saving the wiki page, and can modify tags, do so.
        if req and 'TAGS_MODIFY' in req.perm(page.resource) \
                and req.path_info.startswith('/wiki') and 'save' in req.args:
            page_modified = req.args.get('text') != page.old_text or \
                    page.readonly != int('readonly' in req.args)
            if page_modified:
                requests.set(req)
                req.add_redirect_listener(self._redirect_listener)
            elif page.version > 0:
                # If the page hasn't been otherwise modified, save tags and
                # redirect to avoid the "page has not been modified" warning.
                if self._update_tags(req, page):
                    req.redirect(get_resource_url(self.env, page.resource,
                                                  req.href, version=None))
        return []

    # IWikiChangeListener methods
    def wiki_page_added(self, page):
        req = requests.get()
        if req:
            self._update_tags(req, page, page.time)

    def wiki_page_changed(self, page, version, t, comment, author, ipnr):
        req = requests.get()
        if req:
            self._update_tags(req, page, page.time)

    def wiki_page_renamed(self, page, old_name):
        """Called when a page has been renamed (since Trac 0.12)."""
        self.log.debug("Moving wiki page tags from %s to %s",
                       old_name, page.name)
        req = MockReq()
        self.tag_system.reparent_tags(req, Resource('wiki', page.name),
                                      old_name)

    def wiki_page_deleted(self, page):
        # Page gone, so remove all records on it.
        delete_tags(self.env, page.resource, purge=True)

    def wiki_page_version_deleted(self, page):
        pass

    # Internal methods
    def _page_tags(self, req):
        pagename = req.args.get('page', 'WikiStart')
        version = req.args.get('version')
        tags_version = req.args.get('tags_version')

        page = WikiPage(self.env, pagename, version=version)
        resource = page.resource
        if version and not tags_version:
            tags_version = page.time
        tags = sorted(self.tag_system.get_tags(req, resource,
                                               when=tags_version))
        return tags

    def _redirect_listener(self, req, url, permanent):
        requests.reset()

    def _post_process_request_edit(self, req):
        # Retrieve template resource to be queried for tags.
        template_pagename = ''.join([WikiModule.PAGE_TEMPLATES_PREFIX,
                                     req.args.get('template')])
        template_page = WikiPage(self.env, template_pagename)
        if template_page.exists and \
                'TAGS_VIEW' in req.perm(template_page.resource):
            tags = sorted(self.tag_system.get_tags(req,
                                                   template_page.resource))
            # Prepare tags as content for the editor field.
            tags_str = ' '.join(tags)
            self.env.log.debug("Tags retrieved from template: '%s'",
                               unicode(tags_str).encode('utf-8'))
            # DEVEL: More arguments need to be propagated here?
            req.redirect(req.href(req.path_info,
                                  action='edit', tags=tags_str,
                                  template=req.args.get('template')))

    def _post_process_request_history(self, req, data):
        history = []
        page_histories = data.get('history', [])
        resource = data['resource']
        tags_histories = tag_changes(self.env, resource)

        for page_history in page_histories:
            while tags_histories and \
                    tags_histories[0][0] >= page_history['date']:
                tags_history = tags_histories.pop(0)
                date = tags_history[0]
                author = tags_history[1]
                comment = render_tag_changes(tags_history[2], tags_history[3])
                url = req.href(resource.realm, resource.id,
                               version=page_history['version'],
                               tags_version=to_utimestamp(date))
                history.append({'version': '*', 'url': url, 'date': date,
                                'author': author, 'comment': comment,
                                'ipnr': ''})
            history.append(page_history)

        data.update(dict(history=history,
                         wiki_to_oneliner=self._wiki_to_oneliner))

    def _wiki_view(self, req, stream):
        add_stylesheet(req, 'tags/css/tractags.css')
        tags = self._page_tags(req)
        if not tags:
            return stream
        li = []
        for tag_ in tags:
            resource = Resource('tag', tag_)
            anchor = render_resource_link(self.env,
                                          web_context(req, resource),
                                          resource)
            anchor = anchor(rel='tag')
            li.append(tag.li(anchor, ' '))

        # TRANSLATOR: Header label text for tag list at wiki page bottom.
        insert = tag.ul(class_='tags')(tag.li(_("Tags"), class_='header'), li)
        return stream | (Transformer('//div[contains(@class,"wikipage")]')
                         .after(insert))

    def _update_tags(self, req, page, when=None):
        newtags = split_into_tags(req.args.get('tags', ''))
        oldtags = self.tag_system.get_tags(req, page.resource)

        if oldtags != newtags:
            self.tag_system.set_tags(req, page.resource, newtags, when=when)
            return True
        return False

    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 _wiki_history(self, req, stream):
        xpath = '//input[@type="radio" and @value="*"]'
        stream = stream | Transformer(xpath).remove()
        # Remove invalid links to wiki page revisions (fix for Trac < 0.12).
        xpath = '//a[contains(@href,"%2A")]'
        return stream | Transformer(xpath).remove()

    def _wiki_to_oneliner(self, context, wiki, shorten=None):
        if isinstance(wiki, Fragment):
            return wiki
        return format_to_oneliner(self.env, context, wiki, shorten=shorten)
Ejemplo n.º 17
0
 def _get_stored_tags(self, context, download_id):
     tag_system = TagSystem(self.env)
     resource = Resource(self.realm, download_id)
     tags = tag_system.get_tags(context.req, resource)
     return sorted(tags)
Ejemplo n.º 18
0
 def _get_stored_tags(self, req, download_id):
     tag_system = TagSystem(self.env)
     resource = Resource('downloads', download_id)
     tags = tag_system.get_tags(req, resource)
     return sorted(tags)
Ejemplo n.º 19
0
class HacksCache(Borg):
    _lock = threading.RLock()
    _initialized = False

    _hacks = dict()
    _types = dict()
    _releases = dict()

    def __init__(self, env):
        if self._initialized:
            self._log('already initialized')
            return
        else:
            env.log.debug('HacksCache %x: initializing' % id(self.__dict__))

        self._lock.acquire()

        self._env = env
        self._tag_system = TagSystem(env)
        self._req = FakeRequest(env)
        self.id = id(self.__dict__)

        self._rebuild_cache()

        self._initialized = True
        self._lock.release()
        self._log('initialization finished')

    def __del__(self):
        self._log('Aiiieeeee')

    def _rebuild_cache(self):
        """ Rebuild the cache. Caller MUST hold the lock! """
        self._log('rebuilding cache (initialized=%s)' % self._initialized)
        self._hacks = dict()
        self._types = dict()
        self._releases = dict()

        self._update_types()
        self._update_releases()

        query  = 'realm:wiki (%s) (%s)' % \
            (' or '.join(self._types), ' or '.join(self._releases))
        for h in self._query_tags(query):
            self._update_hack(h, False, False)

    def _log(self, message):
        self._env.log.debug('HacksCache %x: %s' % (self.id, message))

    def _query_tags(self, query):
        """ Helper to perform queries on cached tags system """
        return [ r.id for r, _ in self._tag_system.query(self._req, query) ]

    def _update_types(self):
        """ Get/update list of hack types """
        types = self._query_tags('realm:wiki type')
        keys = self._types.keys()

        # add types that have been added since last update
        for t in types:
            if t not in keys:
                self._types[t] = Tag(t, self._env, self._req, self._tag_system)

        # remove types that no longer exist
        for k in keys:
            if k not in types:
                del self._types[k]

    def _update_releases(self):
        """ Get/update list of Trac releases """
        releases = self._query_tags('realm:wiki release')
        keys = self._releases.keys()

        # add releases that have been added since last update
        for r in releases:
            if r not in keys:
                self._releases[r] = Tag(r, self._env, self._req, self._tag_system)

        # remove releases that no longer exist
        for k in keys:
            if k not in releases:
                del self._releases[k]

    def _update_hack(self, name, full_update = True, check_delete = True):
        """ Get/update/delete hack properties """
        if full_update:
            self._update_types()
            self._update_releases()

        delete = False
        if check_delete:
            page = WikiPage(self._env, name)
            if page.exists:
                tags = set(self._tag_system.get_tags(self._req, page.resource))
                if not (tags.intersection(self._types) and tags.intersection(self._releases)):
                    delete = True
            else:
                delete = True

        if delete:
            try:
                del self._hacks[name]
                self._log('deleted hack %s' % name)
            except:
                self._log('%s is no hack, skipped' % name)
        else:
            try:
                self._hacks[name].update()
                self._log('updated hack %s' % name)
            except:
                self._hacks[name] = Hack(name, self._env, self._req, self._tag_system)
                self._log('learned hack %s' % name)

    def _get(self, where, what):
        try:
            return where[what]
        except:
            return None

    def _get_all(self, where, sorted = False):
        v = where.values()
        if sorted:
            return natural_sort(v)
        else:
            return v


    # Public API
    def update(self, hack = None):
        """ Update cache for all or just the given hack """
        if hack:
            self._update_hack(hack, True, True)
        else:
            self._lock.acquire()
            self._rebuild_cache()
            self._lock.release()

    def get_type(self, name):
        return self._get(self._types, name)

    def get_all_types(self, sorted = False):
        return self._get_all(self._types, sorted)

    def get_release(self, name):
        return self._get(self._releases, name)

    def get_all_releases(self, sorted = False):
        return self._get_all(self._releases, sorted)

    def get_hack(self, name):
        return self._get(self._hacks, name)

    def get_all_hacks(self, sorted = False):
        return self._get_all(self._hacks, sorted)
Ejemplo n.º 20
0
 def _get_stored_tags(self, req, screenshot_id):
     tag_system = TagSystem(self.env)
     resource = Resource('screenshots', to_unicode(screenshot_id))
     tags = tag_system.get_tags(req, resource)
     return sorted(tags)
Ejemplo n.º 21
0
 def _get_stored_tags(self, context, download_id):
     tag_system = TagSystem(self.env)
     resource = Resource(self.realm, download_id)
     tags = tag_system.get_tags(context.req, resource)
     return sorted(tags)
Ejemplo n.º 22
0
 def _get_stored_tags(self, req, screenshot_id):
     tag_system = TagSystem(self.env)
     resource = Resource('screenshots', to_unicode(screenshot_id))
     tags = tag_system.get_tags(req, resource)
     return sorted(tags)