~ubuntu-branches/ubuntu/precise/trac-xmlrpc/precise

« back to all changes in this revision

Viewing changes to sandbox/tracrpc/wiki.py

  • Committer: Package Import Robot
  • Author(s): W. Martin Borgert, Jakub Wilk
  • Date: 2011-12-31 18:27:57 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20111231182757-oe70jynzu0lk5hny
Tags: 1.1.2+r10706-1
* New upstream version (Closes: #653726). Works with Trac 0.12.
* Fixed lintians.
  [Jakub Wilk <jwilk@debian.org>]
* Replace deprecated > operator with >=.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
try:
2
 
    from cStringIO import StringIO
3
 
except ImportError:
4
 
    from StringIO import StringIO
5
 
import xmlrpclib
6
 
import posixpath
7
 
 
8
 
from trac.core import *
9
 
from trac.perm import IPermissionRequestor
10
 
from trac.wiki.api import WikiSystem
11
 
from trac.wiki.model import WikiPage
12
 
from trac.wiki.formatter import wiki_to_html
13
 
from trac.attachment import Attachment
14
 
from tracrpc.api import IXMLRPCHandler, expose_rpc
15
 
from tracrpc.util import to_timestamp
16
 
 
17
 
class WikiRPC(Component):
18
 
    """ Implementation of the [http://www.jspwiki.org/Wiki.jsp?page=WikiRPCInterface2 WikiRPC API]. """
19
 
 
20
 
    implements(IXMLRPCHandler)
21
 
 
22
 
    def __init__(self):
23
 
        self.wiki = WikiSystem(self.env)
24
 
 
25
 
    def xmlrpc_namespace(self):
26
 
        return 'wiki'
27
 
 
28
 
    def xmlrpc_methods(self):
29
 
        yield ('WIKI_VIEW', ((dict, xmlrpclib.DateTime),), self.getRecentChanges)
30
 
        yield ('WIKI_VIEW', ((int,),), self.getRPCVersionSupported)
31
 
        yield ('WIKI_VIEW', ((str, str), (str, str, int),), self.getPage)
32
 
        yield ('WIKI_VIEW', ((str, str, int),), self.getPage, 'getPageVersion')
33
 
        yield ('WIKI_VIEW', ((str, str), (str, str, int)), self.getPageHTML)
34
 
        yield ('WIKI_VIEW', ((str, str), (str, str, int)), self.getPageHTML, 'getPageHTMLVersion')
35
 
        yield ('WIKI_VIEW', ((list,),), self.getAllPages)
36
 
        yield ('WIKI_VIEW', ((dict, str), (dict, str, int)), self.getPageInfo)
37
 
        yield ('WIKI_VIEW', ((dict, str, int),), self.getPageInfo, 'getPageInfoVersion')
38
 
        yield ('WIKI_CREATE', ((bool, str, str, dict),), self.putPage)
39
 
        yield ('WIKI_VIEW', ((list, str),), self.listAttachments)
40
 
        yield ('WIKI_VIEW', ((xmlrpclib.Binary, str),), self.getAttachment)
41
 
        yield ('WIKI_MODIFY', ((bool, str, xmlrpclib.Binary),), self.putAttachment)
42
 
        yield ('WIKI_MODIFY', ((bool, str, str, str, xmlrpclib.Binary),
43
 
                               (bool, str, str, str, xmlrpclib.Binary, bool)),
44
 
                               self.putAttachmentEx)
45
 
        yield ('WIKI_DELETE', ((bool, str),), self.deleteAttachment)
46
 
        yield ('WIKI_VIEW', ((list, str),), self.listLinks)
47
 
        yield ('WIKI_VIEW', ((str, str),), self.wikiToHtml)
48
 
 
49
 
    def _page_info(self, name, time, author, version):
50
 
        return dict(name=name, lastModified=xmlrpclib.DateTime(int(time)),
51
 
                    author=author, version=int(version))
52
 
 
53
 
    def getRecentChanges(self, req, since):
54
 
        """ Get list of changed pages since timestamp """
55
 
        since = to_timestamp(since)
56
 
        db = self.env.get_db_cnx()
57
 
        cursor = db.cursor()
58
 
        cursor.execute('SELECT name, max(time), author, version FROM wiki'
59
 
                       ' WHERE time >= %s GROUP BY name ORDER BY max(time) DESC', (since,))
60
 
        result = []
61
 
        for name, time, author, version in cursor:
62
 
            result.append(self._page_info(name, time, author, version))
63
 
        return result
64
 
 
65
 
    def getRPCVersionSupported(self, req):
66
 
        """ Returns 2 with this version of the Trac API. """
67
 
        return 2
68
 
 
69
 
    def getPage(self, req, pagename, version=None):
70
 
        """ Get the raw Wiki text of page, latest version. """
71
 
        page = WikiPage(self.env, pagename, version)
72
 
        if page.exists:
73
 
            return page.text
74
 
        else:
75
 
            msg = 'Wiki page "%s" does not exist' % pagename
76
 
            if version is not None:
77
 
                msg += ' at version %s' % version
78
 
            raise xmlrpclib.Fault(0, msg)
79
 
 
80
 
    def getPageHTML(self, req, pagename, version=None):
81
 
        """ Return page in rendered HTML, latest version. """
82
 
        text = self.getPage(req, pagename, version)
83
 
        html = wiki_to_html(text, self.env, req, absurls=1)
84
 
        return '<html><body>%s</body></html>' % html
85
 
 
86
 
    def getAllPages(self, req):
87
 
        """ Returns a list of all pages. The result is an array of utf8 pagenames. """
88
 
        return list(self.wiki.get_pages())
89
 
 
90
 
    def getPageInfo(self, req, pagename, version=None):
91
 
        """ Returns information about the given page. """
92
 
        page = WikiPage(self.env, pagename, version)
93
 
        if page.exists:
94
 
            last_update = page.get_history().next()
95
 
            return self._page_info(page.name, last_update[1], last_update[2],
96
 
                                   page.version)
97
 
 
98
 
    def putPage(self, req, pagename, content, attributes):
99
 
        """ writes the content of the page. """
100
 
        page = WikiPage(self.env, pagename)
101
 
        if page.readonly:
102
 
            req.perm.assert_permission('WIKI_ADMIN')
103
 
        elif not page.exists:
104
 
            req.perm.assert_permission('WIKI_CREATE')
105
 
        else:
106
 
            req.perm.assert_permission('WIKI_MODIFY')
107
 
 
108
 
        page.text = content
109
 
        if req.perm.has_permission('WIKI_ADMIN'):
110
 
            page.readonly = attributes.get('readonly') and 1 or 0
111
 
 
112
 
        page.save(attributes.get('author', req.authname),
113
 
                  attributes.get('comment'),
114
 
                  req.remote_addr)
115
 
        return True
116
 
 
117
 
    def listAttachments(self, req, pagename):
118
 
        """ Lists attachments on a given page. """
119
 
        return [pagename + '/' + a.filename for a in Attachment.select(self.env, 'wiki', pagename)]
120
 
 
121
 
    def getAttachment(self, req, path):
122
 
        """ returns the content of an attachment. """
123
 
        pagename, filename = posixpath.split(path)
124
 
        attachment = Attachment(self.env, 'wiki', pagename, filename)
125
 
        return xmlrpclib.Binary(attachment.open().read())
126
 
 
127
 
    def putAttachment(self, req, path, data):
128
 
        """ (over)writes an attachment. Returns True if successful.
129
 
        
130
 
        This method is compatible with WikiRPC.  `putAttachmentEx` has a more
131
 
        extensive set of (Trac-specific) features. """
132
 
        pagename, filename = posixpath.split(path)
133
 
        self.putAttachmentEx(req, pagename, filename, None, data)
134
 
        return True
135
 
 
136
 
    def putAttachmentEx(self, req, pagename, filename, description, data, replace=True):
137
 
        """ Attach a file to a Wiki page. Returns the (possibly transformed)
138
 
        filename of the attachment.
139
 
        
140
 
        Use this method if you don't care about WikiRPC compatibility. """
141
 
        if not WikiPage(self.env, pagename).exists:
142
 
            raise TracError, 'Wiki page "%s" does not exist' % pagename
143
 
        if replace:
144
 
            try:
145
 
                attachment = Attachment(self.env, 'wiki', pagename, filename)
146
 
                attachment.delete()
147
 
            except TracError:
148
 
                pass
149
 
        attachment = Attachment(self.env, 'wiki', pagename)
150
 
        attachment.author = req.authname or 'anonymous'
151
 
        attachment.description = description
152
 
        attachment.insert(filename, StringIO(data.data), len(data.data))
153
 
        return attachment.filename
154
 
 
155
 
    def deleteAttachment(self, req, path):
156
 
        """ Delete an attachment. """
157
 
        pagename, filename = posixpath.split(path)
158
 
        if not WikiPage(self.env, pagename).exists:
159
 
            raise TracError, 'Wiki page "%s" does not exist' % pagename
160
 
        attachment = Attachment(self.env, 'wiki', pagename, filename)
161
 
        attachment.delete()
162
 
        return True
163
 
 
164
 
    def listLinks(self, req, pagename):
165
 
        """ ''Not implemented'' """
166
 
        return []
167
 
 
168
 
    def wikiToHtml(self, req, text):
169
 
        """ Render arbitrary Wiki text as HTML. """
170
 
        return unicode(wiki_to_html(text, self.env, req, absurls=1))