source: tagsplugin/tags/0.6/tractags/wiki.py

Last change on this file was 7383, checked in by Michael Renzmann, 14 years ago

Revert r7372 up to and including r7377. These should have been applied to
trunk rather than to a tagged version. Sorry for any confusion this may
have caused.

File size: 5.6 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2006 Alec Thomas <alec@swapoff.org>
4#
5# This software is licensed as described in the file COPYING, which
6# you should have received as part of this distribution.
7#
8
9from trac.core import *
10from tractags.api import DefaultTagProvider, TagSystem
11from trac.web.chrome import add_stylesheet
12from trac.wiki.api import IWikiSyntaxProvider
13from trac.resource import Resource, render_resource_link, get_resource_url
14from trac.mimeview.api import Context
15from trac.web.api import ITemplateStreamFilter
16from trac.wiki.api import IWikiPageManipulator, IWikiChangeListener
17from trac.util.compat import sorted
18from genshi.builder import tag
19from genshi.filters.transform import Transformer
20
21
22class WikiTagProvider(DefaultTagProvider):
23    """Tag provider for the Wiki."""
24    realm = 'wiki'
25
26    def check_permission(self, perm, operation):
27        map = {'view': 'WIKI_VIEW', 'modify': 'WIKI_MODIFY'}
28        return super(WikiTagProvider, self).check_permission(perm, operation) \
29            and map[operation] in perm
30
31
32class WikiTagInterface(Component):
33    """Implement the user interface for tagging Wiki pages."""
34    implements(ITemplateStreamFilter, IWikiPageManipulator,
35               IWikiChangeListener)
36
37    # ITemplateStreamFilter methods
38    def filter_stream(self, req, method, filename, stream, data):
39        page_name = req.args.get('page', 'WikiStart')
40        resource = Resource('wiki', page_name)
41        if filename == 'wiki_view.html' and 'TAGS_VIEW' in req.perm(resource):
42            return self._wiki_view(req, stream)
43        elif filename == 'wiki_edit.html' and 'TAGS_MODIFY' in req.perm(resource):
44            return self._wiki_edit(req, stream)
45        return stream
46
47    # IWikiPageManipulator methods
48    def prepare_wiki_page(self, req, page, fields):
49        pass
50
51    def validate_wiki_page(self, req, page):
52        if req and 'TAGS_MODIFY' in req.perm(page.resource) \
53                and req.path_info.startswith('/wiki') and 'save' in req.args:
54            if self._update_tags(req, page) and \
55                    page.text == page.old_text and \
56                    page.readonly == int('readonly' in req.args):
57                req.redirect(get_resource_url(self.env, page.resource, req.href, version=None))
58        return []
59
60    # IWikiChangeListener methods
61    def wiki_page_added(self, page):
62        pass
63
64    def wiki_page_changed(self, page, version, t, comment, author, ipnr):
65        pass
66
67    def wiki_page_deleted(self, page):
68        tag_system = TagSystem(self.env)
69        # XXX Ugh. Hopefully this will be sufficient to full any endpoints.
70        from trac.test import Mock, MockPerm
71        req = Mock(authname='anonymous', perm=MockPerm())
72        tag_system.delete_tags(req, page.resource)
73
74    def wiki_page_version_deleted(self, page):
75        pass
76
77    # Internal methods
78    def _page_tags(self, req):
79        pagename = req.args.get('page', 'WikiStart')
80
81        tag_system = TagSystem(self.env)
82        resource = Resource('wiki', pagename)
83        tags = sorted(tag_system.get_tags(req, resource))
84        return tags
85
86    def _wiki_view(self, req, stream):
87        tags = self._page_tags(req)
88        if not tags:
89            return stream
90        tag_system = TagSystem(self.env)
91        add_stylesheet(req, 'tags/css/tractags.css')
92        li = []
93        for tag_ in tags:
94            resource = Resource('tag', tag_)
95            anchor = render_resource_link(self.env,
96                Context.from_request(req, resource), resource)
97            li.append(tag.li(anchor, ' '))
98
99        insert = tag.ul(class_='tags')(tag.li('Tags', class_='header'), li)
100        return stream | Transformer('//div[@class="buttons"]').before(insert)
101
102    def _update_tags(self, req, page):
103        tag_system = TagSystem(self.env)
104        newtags = tag_system.split_into_tags(req.args.get('tags', ''))
105        oldtags = tag_system.get_tags(req, page.resource)
106
107        if oldtags != newtags:
108            tag_system.set_tags(req, page.resource, newtags)
109            return True
110        return False
111
112    def _wiki_edit(self, req, stream):
113        insert = tag.div(class_='field')(
114            tag.label(
115                'Tag under: (', tag.a('view all tags', href=req.href.tags()), ')',
116                tag.br(),
117                tag.input(id='tags', type='text', name='tags', size='30',
118                          value=req.args.get('tags', ' '.join(self._page_tags(req)))),
119                )
120            )
121        return stream | Transformer('//div[@id="changeinfo1"]').append(insert)
122
123
124class TagWikiSyntaxProvider(Component):
125    """Provide tag:<expr> links."""
126
127    implements(IWikiSyntaxProvider)
128
129    # IWikiSyntaxProvider methods
130    def get_wiki_syntax(self):
131        yield (r'''\[tag(?:ged)?:(?P<tlpexpr>(?:'.*?'|".*?"|\S)+)\s+(?P<tlptitle>.*?]*)\]''',
132               lambda f, n, m: self._format_tagged(f,
133                                    m.group('tlpexpr'),
134                                    m.group('tlptitle')))
135        yield (r'''(?P<tagsyn>tag(?:ged)?):(?P<texpr>(?:'.*?'|".*?"|\S)+)''',
136               lambda f, n, m: self._format_tagged(f,
137                                    m.group('texpr'),
138                                    '%s:%s' % (m.group('tagsyn'), m.group('texpr'))))
139
140    def get_link_resolvers(self):
141        return []
142
143    def _format_tagged(self, formatter, target, label):
144        if label:
145            href = formatter.context.href
146            url = get_resource_url(self.env, Resource('tag', target), href)
147            return tag.a(label, href=url)
148        return render_resource_link(self.env, formatter.context,
149                                    Resource('tag', target))
150
Note: See TracBrowser for help on using the repository browser.