Exemple #1
0
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=['trac.*', 'tractags.*'])
        self.env.path = tempfile.mkdtemp()
        self.perms = PermissionSystem(self.env)

        setup = TagSetup(self.env)
        # Current tractags schema is setup with enabled component anyway.
        #   Revert these changes for getting default permissions inserted.
        self._revert_tractags_schema_init()
        setup.upgrade_environment()

        self.provider = TicketTagProvider(self.env)
        self.realm = 'ticket'
        self.tag_sys = TagSystem(self.env)
        self.tags = ['tag1', 'tag2']

        # Populate tables with initial test data.
        self._create_ticket(self.tags)

        # Mock an anonymous request.
        self.anon_req = Mock()
        self.anon_req.perm = PermissionCache(self.env)

        self.req = Mock(authname='editor')
        self.req.authname = 'editor'
        self.req.perm = PermissionCache(self.env, username='******')
Exemple #2
0
    def screenshot_deleted(self, req, screenshot):
        # Create temporary resource.
        resource = Resource('screenshots', to_unicode(screenshot['id']))

        # Delete tags of screenshot.
        tag_system = TagSystem(self.env)
        tag_system.delete_tags(req, resource)
Exemple #3
0
 def set_resource_tags(self, req, ticket_or_resource, tags, comment=u''):
     try:
         resource = ticket_or_resource.resource
     except AttributeError:
         resource = ticket_or_resource
         assert resource.realm == self.realm
         if not self._check_permission(req, resource, 'modify'):
             raise PermissionError(resource=resource, env=self.env)
         tag_set = set(tags)
         # Processing a call from TracTags, try to alter the ticket.
         tkt = Ticket(self.env, resource.id)
         all = self._ticket_tags(tkt)
         # Avoid unnecessary ticket changes, considering comments below.
         if tag_set != all:
             # Will only alter tags in 'keywords' ticket field.
             split_into_tags = TagSystem(self.env).split_into_tags
             keywords = split_into_tags(tkt['keywords'])
             # Assume, that duplication is depreciated and consolitation
             # wanted to primarily affect 'keywords' ticket field.
             # Consequently updating ticket tags and reducing (tag)
             # 'ticket_fields' afterwards may result in undesired tag loss.
             tag_set.difference_update(all.difference(keywords))
             tkt['keywords'] = u' '.join(sorted(map(to_unicode, tag_set)))
             tkt.save_changes(get_reporter_id(req), comment)
     else:
         # Processing a change listener event.
         tags = self._ticket_tags(ticket_or_resource)
         super(TicketTagProvider,
               self).set_resource_tags(req, resource, tags)
Exemple #4
0
    def render_admin_panel(self, req, cat, page, version):
        req.perm.require('TAGS_ADMIN')
        data = {}
        tag_system = TagSystem(self.env)
        if req.method == 'POST':
            # Replace Tag
            allow_delete = req.args.get('allow_delete')
            new_tag = req.args.get('tag_new_name').strip()
            new_tag = not new_tag == u'' and new_tag or None
            if not (allow_delete or new_tag):
                data['error'] = _("""Selected current tag(s) and either
                                  new tag or delete approval are required""")
            else:
                comment = req.args.get('comment', u'')
                old_tags = req.args.get('tag_name')
                if old_tags:
                    # Provide list regardless of single or multiple selection.
                    old_tags = isinstance(old_tags, list) and old_tags or \
                               [old_tags]
                    tag_system.replace_tag(req, old_tags, new_tag, comment,
                                           allow_delete)
                data['selected'] = new_tag

        all_tags = sorted(tag_system.get_all_tags(req, '-dummy'))
        data['tags'] = all_tags
        try:
            Chrome(self.env).add_textarea_grips(req)
        except AttributeError:
            # Element modifiers unavailable before Trac 0.12, skip gracefully.
            pass
        return 'admin_tag_change.html', data
Exemple #5
0
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=['trac.*', 'tractags.*'])
        self.env.path = tempfile.mkdtemp()
        self.perms = PermissionSystem(self.env)

        self.db = self.env.get_db_cnx()
        setup = TagSetup(self.env)
        # Current tractags schema is setup with enabled component anyway.
        #   Revert these changes for getting default permissions inserted.
        self._revert_tractags_schema_init()
        setup.upgrade_environment(self.db)

        self.provider = TicketTagProvider(self.env)
        self.realm = 'ticket'
        self.tag_sys = TagSystem(self.env)
        self.tags = ['tag1']

        cursor = self.db.cursor()
        # Populate table with initial test data, not synced with tickets yet.
        cursor.execute("""
            INSERT INTO tags
                   (tagspace, name, tag)
            VALUES ('ticket', '1', 'deleted')""")
        self.realm = 'ticket'
        self._create_ticket(self.tags)

        self.req = Mock()
        # Mock an anonymous request.
        self.req.perm = PermissionCache(self.env)
Exemple #6
0
def load_pages_with_tags(env, req, tags):
    tag_system = TagSystem(env)
    pages = []
    blog_resources = [i for i in tag_system.query(req, tags)]
    for resource, ignored in blog_resources:
        pages.append(WikiPage(env, resource))
    return pages
Exemple #7
0
    def expand_macro(self, formatter, name, args):
        req = formatter.req
        add_stylesheet(req, 'hacks/css/trachacks.css')

        tag_system = TagSystem(self.env)

        categories = natural_sort([r.id for r, _ in
                                 tag_system.query(req, 'realm:wiki type')])

        def link(resource):
            return render_resource_link(self.env, formatter.context,
                                        resource, 'compact')

        dl = builder.dl(class_='hacktypesmacro')
        for category in categories:
            page = WikiPage(self.env, category)
            match = self.title_extract.search(page.text)
            if match:
                cat_title = '%s' % match.group(1).strip()
                cat_body = self.title_extract.sub('', page.text, 1)
            else:
                cat_title = '%s' % category
                cat_body = page.text
            cat_body = self.self_extract.sub('', cat_body).strip()
            dl(builder.dt(link(Resource('wiki', category))))
            dl(builder.dd(wiki_to_html(cat_body, self.env, req)))

        return dl
Exemple #8
0
    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.
        """
        query = req.args.get('q', '').lower()
        tagsystem = TagSystem(self.env)
        alltags = tagsystem.query(req)
        tags = {}
        for resource, _tags in alltags:
            for tag in _tags:
                if query in tag.lower():
                    tags[tag] = tags.setdefault(tag, 0) + 1

        tags = sorted(tags.items(), key=lambda x: x[1], reverse=True)
        writeOut = str('\n'.join(
            ['%s|%d' % (name, number) for name, number in tags]))
        req.send_header('Content-length', str(len(writeOut)))
        req.end_headers()
        req.write(writeOut)
Exemple #9
0
    def check_permission(self, action, username, resource, perm):
        if resource is None or action.split('_')[0] != resource.realm.upper():
            return None

        from tractags.api import TagSystem

        class FakeRequest(object):
            def __init__(self, perm):
                self.perm = perm

        permission = action.lower().split('_')[1]
        req = FakeRequest(perm)
        tags = TagSystem(self.env).get_tags(None, resource)

        # Explicitly denied?
        if ':-'.join((username, permission)) in tags:
            return False

        # Find all granted permissions for the requesting user from
        # tagged permissions by expanding any meta action as well.
        if action in set(
                PermissionSystem(self.env).expand_actions([
                    '_'.join([resource.realm, t.split(':')[1]]).upper()
                    for t in tags if t.split(':')[0] == username
                ])):
            return True
Exemple #10
0
 def _get_keywords(self, req):
     keywords = set(self.sticky_tags_opt)  # prevent duplicates
     if self.tags_enabled:
         # Use TagsPlugin >= 0.7 performance-enhanced API.
         tags = TagSystem(self.env).get_all_tags(req)
         keywords.update(tags.keys())
     return sorted(keywords) if keywords else []
Exemple #11
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
Exemple #12
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)
Exemple #13
0
    def setUp(self):
        self.env = EnvironmentStub(
                enable=['trac.*', 'tractags.*'])
        self.env.path = tempfile.mkdtemp()
        self.db = self.env.get_db_cnx()
        setup = TagSetup(self.env)
        # Current tractags schema is setup with enabled component anyway.
        #   Revert these changes for getting a clean setup.
        self._revert_tractags_schema_init()
        setup.upgrade_environment(self.db)

        self.tag_s = TagSystem(self.env)
        self.tag_rh = TagRequestHandler(self.env)

        perms = PermissionSystem(self.env)
        # Revoke default permissions, because more diversity is required here.
        perms.revoke_permission('anonymous', 'TAGS_VIEW')
        perms.revoke_permission('authenticated', 'TAGS_MODIFY')
        perms.grant_permission('reader', 'TAGS_VIEW')
        perms.grant_permission('writer', 'TAGS_MODIFY')
        perms.grant_permission('admin', 'TAGS_ADMIN')
        self.anonymous = PermissionCache(self.env)
        self.reader = PermissionCache(self.env, 'reader')
        self.writer = PermissionCache(self.env, 'writer')
        self.admin = PermissionCache(self.env, 'admin')

        self.href = Href('/trac')
        self.abs_href = Href('http://example.org/trac')
Exemple #14
0
    def _format_tagged(self, formatter, ns, target, label, fullmatch=None):
        """Tag and tag query expression link formatter."""

        def unquote(text):
            """Strip all matching pairs of outer quotes from string."""
            while re.match(WikiParser.QUOTED_STRING, text):
                # Remove outer whitespace after stripped quotation too.
                text = text[1:-1].strip()
            return text
 
        label = label and unquote(label.strip()) or ''
        target = unquote(target.strip())
        tag_res = Resource('tag', target)
        if 'TAGS_VIEW' in formatter.perm(tag_res):
            context = formatter.context
            href = get_resource_url(self.env, tag_res, context.href)
            tag_sys = TagSystem(self.env)
            # Tag exists or tags query yields at least one match.
            if target in tag_sys.get_all_tags(formatter.req) or \
                    [(res, tags) for res, tags in
                     tag_sys.query(formatter.req, target)]:
                if label:
                    return tag.a(label, href=href)
                return render_resource_link(self.env, context, tag_res)
            else:
                return tag.a(label+'?', href=href, class_='missing tags',
                             rel='nofollow')
        else:
            return tag.span(label, class_='forbidden tags',
                            title=_("no permission to view tags"))
Exemple #15
0
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=['trac.*', 'tractags.*'])
        self.env.path = tempfile.mkdtemp()
        self.perms = PermissionSystem(self.env)

        self.tag_s = TagSystem(self.env)
        self.tag_wp = WikiTagProvider(self.env)

        self.db = self.env.get_db_cnx()
        setup = TagSetup(self.env)
        # Current tractags schema is partially setup with enabled component.
        #   Revert these changes for getting a clean setup.
        self._revert_tractags_schema_init()
        setup.upgrade_environment(self.db)

        cursor = self.db.cursor()
        # Populate table with initial test data.
        cursor.execute("""
            INSERT INTO tags
                   (tagspace, name, tag)
            VALUES ('wiki', 'WikiStart', 'tag1')
        """)

        self.req = Mock()
        # Mock an anonymous request.
        self.req.perm = PermissionCache(self.env)
        self.realm = 'wiki'
        self.tags = ['tag1']
Exemple #16
0
    def expand_macro(self, formatter, name, args):
        req = formatter.req
        add_stylesheet(req, 'hacks/css/trachacks.css')

        tag_system = TagSystem(self.env)
        releases = natural_sort([r.id for r, _ in
                                 tag_system.query(req, 'realm:wiki release')])

        def link(resource):
            return render_resource_link(self.env, formatter.context,
                                        resource, 'compact')

        dl = builder.dl(class_='tracreleasesmacro')
        for release in releases:
            page = WikiPage(self.env, release)
            match = self.title_extract.search(page.text)
            if match:
                rel_title = '%s' % match.group(1).strip()
            else:
                rel_title = '%s' % release

            dl(builder.dt(link(Resource('wiki', release))))
            dl(builder.dd(wiki_to_html(rel_title, self.env, req)))

        return dl
Exemple #17
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
Exemple #18
0
 def set_resource_tags(self, req, resource, tags):
     req.perm.require('TICKET_MODIFY', resource)
     split_into_tags = TagSystem(self.env).split_into_tags
     ticket = Ticket(self.env, resource.id)
     all = self._ticket_tags(ticket)
     keywords = split_into_tags(ticket['keywords'])
     tags.difference_update(all.difference(keywords))
     ticket['keywords'] = u' '.join(sorted(map(to_unicode, tags)))
     ticket.save_changes(req.username, u'')
Exemple #19
0
 def _do_save(self, req, versioned_page):
     title = req.args.get('blogtitle')
     content = '= %s =\n\n%s' % (title, req.args.get('text', ''))
     req.args['text'] = content
     tags = ['blog'] + self._get_tags(req)
     tag_system = TagSystem(self.env)
     tag_system.add_tags(req, versioned_page.resource, tags)
     result = super(NewPostModule, self)._do_save(req, versioned_page)
     return result
Exemple #20
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
Exemple #21
0
 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)
     tag_sys = TagSystem(self.env)
     # XXX Ugh. Hopefully this will be sufficient to fool any endpoints.
     from trac.test import Mock, MockPerm
     req = Mock(authname='anonymous', perm=MockPerm())
     tag_sys.reparent_tags(req, Resource('wiki', page.name), old_name)
Exemple #22
0
    def __call__(self, context, type_):
        if not (type_ and isinstance(type_, basestring) and len(type_)):
            raise ValidationError('No type selected?!')

        tags = TagSystem(self.env)
        req = FakeRequest(self.env)
        types = [r.id for r, _ in tags.query(req, 'realm:wiki type')]
        if type_ not in types:
            raise ValidationError('Selected type "%s" invalid?!' % str(type_))
        return type_
Exemple #23
0
def Main(opts):
    """ Cross your fingers and pray """
    env = Environment(opts.envpath)
    from tractags.api import TagSystem

    tlist = opts.tags or split_tags(
        env.config.get('blog', 'default_tag', 'blog'))
    tags = TagSystem(env)
    req = Mock(perm=MockPerm())
    blog = tags.query(req, ' '.join(tlist + ['realm:wiki']))

    cnx = env.get_db_cnx()
    for resource, page_tags in list(blog):
        try:
            page = WikiPage(env, version=1, name=resource.id)
            _, publish_time, author, _, _ = page.get_history().next()
            if opts.deleteonly:
                page.delete()
                continue
            categories = ' '.join([t for t in page_tags if t not in tlist])
            page = WikiPage(env, name=resource.id)
            for version, version_time, version_author, version_comment, \
                _ in page.get_history():
                # Currently the basename of the post url is used due to
                # http://trac-hacks.org/ticket/2956
                #name = resource.id.replace('/', '_')
                name = resource.id
                # extract title from text:
                fulltext = page.text
                match = _title_split_match(fulltext)
                if match:
                    title = match.group(1)
                    fulltext = match.group(2)
                else:
                    title = name
                body = fulltext
                print "Adding post %s, v%s: %s" % (name, version, title)
                insert_blog_post(cnx, name, version, title, body, publish_time,
                                 version_time, version_comment, version_author,
                                 author, categories)
                reparent_blog_attachments(env, resource.id, name)
                continue
            cnx.commit()
            if opts.delete:
                page.delete()
                continue
        except:
            env.log.debug("Error loading wiki page %s" % resource.id,
                          exc_info=True)
            print "Failed to add post %s, v%s: %s" % (name, version, title)
            cnx.rollback()
            cnx.close()
            return 1
    cnx.close()
    return 0
Exemple #24
0
    def download_deleted(self, context, download):
        # Check proper permissions to modify tags.
        if 'TAGS_MODIFY' not in context.req.perm:
            return

        # Create temporary resource.
        resource = Resource(self.realm, download['id'])

        # Delete tags of download.
        tag_system = TagSystem(self.env)
        tag_system.delete_tags(context.req, resource)
Exemple #25
0
    def screenshot_created(self, req, screenshot):
        # Create temporary resource.
        resource = Resource('screenshots', to_unicode(screenshot['id']))

        # Delete tags of screenshot with same ID for sure.
        tag_system = TagSystem(self.env)
        tag_system.delete_tags(req, resource)

        # Add tags of new screenshot.
        new_tags = self._get_tags(screenshot)
        tag_system.add_tags(req, resource, new_tags)
Exemple #26
0
    def download_deleted(self, req, download):
        # Check proper permissions to modify tags.
        if not req.perm.has_permission('TAGS_MODIFY'):
           return

        # Create temporary resource.
        resource = Resource('downloads', download['id'])

        # Delete tags of download.
        tag_system = TagSystem(self.env)
        tag_system.delete_tags(req, resource)
Exemple #27
0
    def user_created(self, user, password):
        req = FakeRequest(self.env, user)
        resource = Resource('wiki', user)
        tag_system = TagSystem(self.env)
        tag_system.add_tags(req, resource, ['user',])

        page = WikiPage(self.env, user)
        page.text = '''= %(user)s =\n\n[[ListTagged(%(user)s)]]\n''' % {'user' : user}
        page.save(user, 'New user %s registered' % user, None)

        self.env.log.debug("New user %s registered" % user)
Exemple #28
0
    def _update_tags(self, req, resource, new_tags):
        # Get old tags of the resource.
        tag_system = TagSystem(self.env)
        old_tags = self._get_stored_tags(req, resource)

        self.log.debug("setting tags: %s" % (new_tags,))

        # Replace with new tags if different.
        if old_tags != new_tags:
            tag_system.set_tags(req, resource, new_tags)
            return True
        return False
Exemple #29
0
 def expand_macro(self, formatter, name, content):
     req = formatter.req
     query_result = TagSystem(self.env).query(req, content)
     all_tags = {}
     # Find tag counts
     for resource, tags in query_result:
         for tag in tags:
             try:
                 all_tags[tag] += 1
             except KeyError:
                 all_tags[tag] = 1
     return render_cloud(self.env, req, all_tags)
Exemple #30
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