root/platform/trac/plugins/wlwriter/trunk/wlwriter/atompub.py @ 17263

Revision 17263, 33.3 kB (checked in by hirobe, 5 years ago)

atompub版。完成形じゃないけど中断。

Line 
1# -*- coding: utf-8 -*-
2
3import re
4import pkg_resources
5
6# TODO: ページを取得後に画像を追加するとエラーになる。
7# TODO: 新規の投稿と、開いてからの投稿で、メソッドがちがう?レスポンスが違う?
8# TODO: 添付ファイルに対する HEAD メソッドは何を意味する?
9# TODO: ページ取得時のレスポンスに鍵がありそう。
10
11try:
12    from cStringIO import StringIO
13except ImportError:
14    from StringIO import StringIO
15   
16from trac.core import *
17from trac.wiki.model import WikiPage
18from trac.attachment import Attachment
19from trac.web.main import IRequestHandler
20from trac.web.api import RequestDone
21from trac.web.chrome import add_link, add_stylesheet,  ITemplateProvider
22
23from blogwiki import BlogWikiCore
24from trac.util.datefmt import to_datetime,format_datetime
25
26from genshi import Markup, escape, unescape
27from trac.mimeview.api import Context
28from trac.resource import *
29from wikitohtml import wiki_to_html,WikiToEditHtmlFormatter
30
31from genshi.input import XML
32from trac.util.text import unicode_quote,unicode_unquote,to_unicode
33from trac.web.api import IAuthenticator
34from trac.perm import IPermissionRequestor
35
36
37class IAtomPubHandler(Interface):
38    def atompub_title():
39        """aaa
40        """   
41       
42    def atompub_collection(req):
43        """aaa
44        """   
45
46    def atompub_get_feed(self,req,id):
47        """
48        return data,location
49        """
50    def atompub_get_feedlist(req):
51        """
52        return data
53        """
54
55    def atompub_do_create(req,pagename,content_type,content):
56        """
57        return pageid
58        """
59
60    def atompub_do_update(req,pagename,content_type,content):
61        """
62        return pageid
63        """
64
65    def atompub_do_delete(req):
66        """aaa
67        """
68
69
70    def atompub_do_create_attachment(self,req):
71        """aaa
72        """
73
74    def atompub_do_update_attachment(self,req,id):
75        """aaa
76        """
77
78
79from xhtmltowiki import XhtmlToWikiFormatter
80from wikitohtml import wiki_to_html,WikiToEditHtmlFormatter
81
82class CommonHandler(BlogWikiCore):
83
84   
85    def _attachment(self, req, pagename=None,username=None,filename=None,realm='wiki',put_flag=True):
86        username = req.authname
87        status_code=200
88        if pagename == None or pagename == '':
89            pagename = self._getTempPage(username,realm)
90       
91        page = WikiPage(self.env, pagename, version=None)
92        if put_flag == True:
93            status_code=201
94            if filename == None:
95                filename = req.get_header('Slug')
96                ex = req.get_header('Content-Type').split('/').pop()
97                filename = filename + '.' + ex
98
99            #filename = reqfile['name'].split('/')[-1]
100            rawdata =req.read(int(req.get_header('Content-Length')))
101            #data = file['bits']
102            if not page.exists:
103                pagename=self._getTempPage(username)
104                page = WikiPage(self.env, pagename)
105                if not page.exists:
106                    page.text = 'dumy'
107                    page.save(username,
108                              None,
109                              req.remote_addr)
110            try:
111                attachment = Attachment(self.env, realm, pagename, filename)
112                attachment.delete()
113            except TracError:
114                pass
115            attachment = Attachment(self.env, realm, pagename)
116            attachment.author = req.authname or 'anonymous'
117            attachment.description = None
118            attachment.insert(filename, StringIO(rawdata), len(rawdata))
119            filename = attachment.filename
120            #req.send_header('Location', req.abs_href.atompub('login/%s/attachment/%s/%s'%(realm,page.name,filename)))
121            location = req.abs_href.atompub('login/%s/attachment/%s/%s'%(realm,page.name,filename))
122
123        else:
124            attachment = Attachment(self.env, realm, pagename)
125            location = None
126
127        href = req.abs_href('raw-attachment',realm, pagename, filename)
128        #self.log.debug (href)
129       
130        entry= {  'id':attachment.filename,
131                 'title':attachment.filename,
132                 'author':attachment.author,
133                 'updated':format_datetime(attachment.date,'iso8601'),
134                 #'src':req.abs_href('raw-attachment','wiki', page.name, filename), #req.href.attachment('%s/%s/%s'%(realm,page.name,filename)),
135                 'content_src':req.abs_href('raw-attachment',realm, pagename, filename), #req.href.attachment('%s/%s/%s'%(realm,page.name,filename)),
136                 'content_type':'image/png',
137                 'content':None,
138                 'edit_media_href':req.abs_href.atompub('login/%s/edit_attachment/%s/%s'%(realm,page.name,filename)),
139                 'edit_href':req.abs_href.atompub('login/%s/attachment/%s/%s'%(realm,page.name,filename)),
140                 'href':req.abs_href.atompub('login/%s/attachment/%s/%s'%(realm,page.name,filename))
141                 #'href':req.abs_href.atompub('%s/edit/%s'%(realm,page.name)),
142                 
143                 #'content':Markup(html),
144                 }
145                 
146        data = {'entry':entry}
147       
148        self._response_entry(req,data,status_code,location)
149        #req.send_header('Location', entry['edit_href'])
150        #return 'atom_media_entry.xml',data,'application/atom+xml'
151        #return data
152
153
154    def _response_entry(self,req,data,status_code=200,location=None):
155        req.send_response(status_code)
156        req.send_header('Content-Type', 'application/atom+xml')
157        if location:
158            req.send_header('location', location)
159        req.end_headers()
160        if req.method != 'HEAD':
161           
162            id = data['entry']['id']
163            title = data['entry']['title']
164            author = data['entry']['author']
165            updated = data['entry']['updated']
166            href = data['entry']['href']
167            content = data['entry']['content']
168            content_src = data['entry']['content_src']
169            content_type = data['entry']['content_type']
170            req.write('''<?xml version="1.0" encoding="utf-8"?>''')
171            req.write('''
172<entry xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app">
173    <id>%s</id>
174    <title type="text">%s</title>
175    <author>
176        <name>%s</name>
177    </author>
178    <updated>%s</updated>
179    <app:edited>%s</app:edited>
180    <summary type="xhtml">
181        <div xmlns="http://www.w3.org/1999/xhtml"/>
182    </summary>
183    <link rel="self" type='application/atom+xml' href="%s" />
184    <link rel="edit" type='application/atom+xml' href="%s" />
185    <link rel="edit-media" type='application/atom+xml' href="%s" />
186'''%(id,title,author,updated,updated,href,href,href,href))
187            if content_src:
188                req.write('''
189<content type="%s" src="%s"/>
190</entry>
191'''%(content_type,content_src))           
192            else:
193                req.write('''
194    <content type="%s" >
195        <div xmlns="http://www.w3.org/1999/xhtml">%s</div>
196    </content>
197</entry>
198'''%(content_type,content))           
199
200    def _responsez(self, req, type_code=200, doc=None):
201        req.send_response(type_code)
202        req.send_header('Content-Type', 'application/atom+xml')
203        req.end_headers()
204       
205        if req.method != 'HEAD' and doc != None:
206            req.write(doc.toprettyxml(indent = '    '))
207        raise RequestDone
208   
209
210    def _response_errorz(self, req, error_type,error_code=500,error_mes=''):
211       
212        if error_type == 'BadRequest':
213             error_code = 400
214             error_mes = 'XML parse failed.'
215        elif error_type == 'Unauthorized WSSE':
216             error_code = 401
217             error_mes = 'X-WSSE authentication required'
218             req.send_header('WWW-Authenticate','WSSE profile="UsernameToken"')
219        elif error_type == 'Unauthorized Basic':
220             error_code = 401
221             error_mes = 'Basic authentication required'
222             req.send_header('WWW-Authenticate','Basic realm="SECRET AREA"')
223        elif error_type == 'Unauthorized Digest':
224             error_code = 401
225             error_mes = 'Basic authentication required'
226             req.send_header('WWW-Authenticate','Basic realm="SECRET AREA"')
227        elif error_type == 'Forbidden':
228             error_code = 403
229             error_mes = 'Forbidden'
230        elif error_type == 'MethodNotAllowed':
231             error_code = 405
232             error_mes = 'Method Not Allowed'
233       
234        req.send_response(error_code)
235        req.send_header('Content-Type', 'text/html;charset=UTF-8')
236        req.end_headers()
237       
238        if req.method != 'HEAD':
239            req.write('''
240<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY></BODY></HTML>
241'''%(error_mes))
242           
243            #req.write('<?xml version="1.0" encoding="UTF-8"?>\n')
244            #req.write('<error>%s</error>'%error_mes)
245        raise RequestDone
246
247
248
249     
250
251
252class Wiki(CommonHandler):
253    implements(IAtomPubHandler)
254
255    def _getTempPage(self,username,realm='wiki'):
256        return  'tempolaryOf' + username
257
258    ""
259    ""
260
261    # IAtomPubHandler methods
262    def atompub_title(self):
263        return 'wiki'
264   
265    def atompub_collection(self,req):
266        return """
267      <atom:title>Wiki</atom:title>
268      <accept>*/*</accept>
269      <categories fixed="no"/>
270        """
271#      <accept>image/*</accept>
272#      <accept>application/atom+xml;type=entry</accept>
273
274    def atompub_do_create(self,req,pagename,content_type,content):
275        #TODO:should return page name and status_code
276        username = req.authname
277        status_code = 201
278        try:
279            self._do_save(req, pagename,content,username)
280        except TracError:
281            if TracError.title == "Page not modified":
282                status_code = 304
283            else:
284                status_code = 500
285        return pagename,status_code
286
287    def atompub_do_update(self,req,pagename,content_type,content):
288        return self.atompub_do_create(req,pagename,content_type,content)
289
290
291    def atompub_do_delete(self,req):
292        version = None
293        page = WikiPage(self.env, id, version)
294        page.delete(version)
295
296
297    def atompub_do_create_attachment(self,req):
298        return self._attachment(req,put_flag=True)
299
300    def atompub_do_update_attachment(self,req,id):
301        words = id.split('/')
302        filename = words.pop()
303        pagename = '/'.join(words)
304        return self._attachment(req,filename=filename,pagename=pagename,realm='wiki',put_flag=False)
305
306
307
308    def atompub_get_feedlist(self,req):
309        # feed list request
310        orderby = ''
311        numberOfPosts = -1
312        #entries = []
313
314        db = self.env.get_db_cnx()
315        cursor = db.cursor()
316        limit=''
317        if orderby != '':
318            orderby = " ORDER BY %s "%orderby
319            self.log.debug('orderby:%s'%orderby)
320        if numberOfPosts != -1:
321            limit = " Limit %s "%numberOfPosts
322           
323        cursor.execute('SELECT name, max(time), author, version, comment FROM wiki'
324                       '  GROUP BY name ' + orderby + limit )
325        result = []
326        rowid = 0
327        cate = []
328        #cate.append(dict(discription='hoge',title='wiki'))
329        entries = []
330
331        for name, time, author, version, comment in cursor:
332            entry = {'title':name,
333                     'alternate_url':req.abs_href.atompub('login/wiki/edit/%s'%(name)),
334                     'service_edit_url':req.abs_href.atompub('login/wiki/edit/%s'%(name)),
335                     'service_feed_url':req.abs_href.atompub('login/wiki/feed/%s'%(name)),
336                     'modified':format_datetime(to_datetime(time),'iso8601'),
337                     'realm':'wiki:%s'%(name),
338                     'content':''
339                     }
340            entries.append(entry)
341        data = {'alternate_url':req.abs_href(), #ツᄆツᄆツᆰwlwツᆰハᅦランツᄋツ←URLツ￉ツ￈ツ←,
342                'service_post_url':req.abs_href.atompub('post'),
343                'service_feed_url':req.abs_href.atompub('feed'),
344                'service_upload_url':req.abs_href.atompub('login/wiki/feed'),
345                'title':'title:hoge',
346                'author':'',
347                'entries':entries     
348                }
349            #entries.append(entry)
350        #self.log.debug(entries)
351        #data['entriess'] = entries
352        #data['alternate'] = req.abs_href.wiki()
353#        return 'wlwmanifest.xml',data
354        return data
355        #return 'atom_feed.xml', data, 'text/xml' #'application/atom+xml'
356
357
358           
359 
360    def _do_save(self, req, pagename, content, username):
361        self.username = username
362        """ writes the content of the page. """
363        page = WikiPage(self.env, pagename)
364        if page.readonly:
365            req.perm.assert_permission('WIKI_ADMIN')
366        elif not page.exists:
367            req.perm.assert_permission('WIKI_CREATE')
368        else:
369            req.perm.assert_permission('WIKI_MODIFY')
370
371        ctx = Context.from_request(req,'wiki', pagename,absurls=True)
372
373        self.log.debug(content['description'])
374        hoge = XhtmlToWikiFormatter(self.env,ctx)
375        hoge.setReq(req)
376        hoge.setCaller(self)
377
378        hoge.setTempPage(self._getTempPage(username))
379        text = hoge.xhtmltowiki(content['description'])
380        self.log.debug(text)
381        page.text = text
382        #try:
383        page.save(username,
384                  None,
385                  req.remote_addr)
386        #except TracError:
387            #TODO: DELETE temp attachment,temp page
388            #self._delete_temp_page(username)
389            #raise TracError
390           
391        self._move_temp_attachment(pagename,username)
392        #delete temp page
393        self._delete_temp_page(username)
394        return True
395
396    def _move_temp_attachment(self,pagename,username):
397        db = self.env.get_db_cnx()
398        temp_attachments = Attachment.select(self.env, 'wiki', self._getTempPage(self.username),db=db)
399        for temp_att in temp_attachments:
400            filename = temp_att.filename
401            try:
402                data = temp_att.open().read()
403                new_att = Attachment(self.env, 'wiki', pagename)
404                new_att.author = username or 'anonymous'
405                new_att.description = temp_att.description
406                new_att.insert(filename, StringIO(data), len(data),db=db)
407            except ResourceNotFound:
408                self.log.error('ResourceNotFound: Attachment %s not found'%filename)
409                pass
410        Attachment.delete_all(self.env, 'wiki', self._getTempPage(self.username),db=db)
411        db.commit()
412
413    def _delete_temp_page(self,username):
414        db = self.env.get_db_cnx()
415        page = WikiPage(self.env, self._getTempPage(username))
416        if page.exists:
417            page.delete(db=db)
418
419        db.commit()
420
421    def atompub_get_feed(self,req,pagename,need_location=False):
422        self.log.debug(pagename)
423        #self._response_wiki(req,pagename=id)
424        page = WikiPage(self.env, pagename, version=None)
425        if page.exists:
426            resource = Resource('wiki',pagename)
427            context = Context(Resource('wiki',pagename))
428            context.req = req
429            html = wiki_to_html(page.text, self.env, req, absurls=1,resource=resource)
430        else:
431            msg = 'Wiki page "%s" does not exist' % pagename
432            #if version is not None:
433            #    msg += ' at version %s' % version
434            raise TracError( msg)
435
436        entry = {'id':page.name,
437                 'title':page.name,
438                 'author':page.author,
439                 'updated':format_datetime(page.time,'iso8601'),
440                 'content':Markup(html),
441                 'content_src':None,
442                 'content_type':'xhtml',
443                 'href':req.abs_href.atompub('login/wiki/edit/%s'%(unicode_quote(to_unicode(page.name))))
444                 }
445        data = {'entry':entry}
446       
447        eo = Entry()
448        eo.id = page.name
449        eo.title = page.name
450        eo.author = page.author
451        eo.updated = format_datetime(page.time,'iso8601')
452        eo.content = Markup(html)
453        eo.href = req.abs_href.atompub('login/wiki/edit/%s'%(unicode_quote(to_unicode(page.name))))
454       
455        self.log.debug(data)
456       
457        # LocationをつけないとPostできないがつけると、Broken Pipeになる
458        #location_header = None
459        #if need_location==True:
460        location_header= req.abs_href.atompub('login/wiki/edit/%s'%(unicode_quote(to_unicode(page.name))))
461       
462        return data,location_header
463
464
465class Entry(object):
466
467    def __init__(self):
468
469        self.id = None
470        self.title = None
471        self.author = None
472        self.updated = None
473        self.content = None
474        self.href = None
475   
476
477   
478class Ticket(Wiki):
479    implements(IAtomPubHandler)
480
481
482    # IAtomPubHandler methods
483    def atompub_title(self):
484        return 'ticket'
485   
486    def atompub_collection(self,req):
487        return """
488      <atom:title>Ticket</atom:title>
489      <accept>application/atom+xml;type=entry</accept>
490      <accept>image/png</accept>
491      <accept>image/jpeg</accept>
492      <accept>image/gif</accept>
493      <categories fixed="no"/>
494        """
495
496    def atompub_do_create(self,req,pagename,content_type,content):
497        username = req.authname
498       
499        return self._do_save(req, pagename,content,username)
500
501    def atompub_do_update(self,req,pagename,content_type,content):
502        return self.atompub_do_create(req,pagename,content_type,content)
503
504
505    def atompub_do_delete(self,req):
506        pass
507
508
509    def atompub_do_create_attachment(self,req):
510        return self._attachment(req,put_flag=True)
511
512    def atompub_do_update_attachment(self,req,id):
513        words = id.split('/')
514        filename = words.pop()
515        pagename = '/'.join(words)
516        return self._attachment(req,filename=filename,pagename=pagename,realm='ticket',put_flag=False)
517
518
519    def atompub_get_feedlist(self,req):
520        orderby = 'id desc'
521        numberOfPosts = -1
522
523        db = self.env.get_db_cnx()
524        cursor = db.cursor()
525        limit=''
526        if orderby != '':
527            orderby = " ORDER BY %s "%orderby
528            self.log.debug('orderby:%s'%orderby)
529        if numberOfPosts != -1:
530            limit = " Limit %s "%numberOfPosts
531           
532        cursor.execute('SELECT id, summary ,changetime FROM ticket '+ orderby + limit )
533        result = []
534        rowid = 0
535        cate = []
536        #cate.append(dict(discription='hoge',title='wiki'))
537        entries = []
538
539        for id, summary ,changetime in cursor:
540            entry = {'title':'#%s: %s'%(str(id),summary),
541                     'alternate_url':req.abs_href.atompub('login/ticket/edit/%s'%(id)),
542                     'service_edit_url':req.abs_href.atompub('login/ticket/edit/%s'%(id)),
543                     'service_feed_url':req.abs_href.atompub('login/ticket/feed/%s'%(id)),
544                     'modified':format_datetime(to_datetime(changetime),'iso8601'),
545                     'realm':'ticket:%s'%(str(id)),
546                     'content':''
547                     }
548            entries.append(entry)
549        data = {'alternate_url':req.abs_href(),
550                'service_post_url':req.abs_href.atompub('post'),
551                'service_feed_url':req.abs_href.atompub('feed'),
552                'service_upload_url':req.abs_href.atompub('upload'),
553                'title':'title:hoge',
554                'author':'',
555                'entries':entries     
556                }
557            #entries.append(entry)
558        #self.log.debug(entries)
559        #data['entriess'] = entries
560        #data['alternate'] = req.abs_href.wiki()
561#        return 'wlwmanifest.xml',data
562        return data
563
564    def atompub_get_feed(self,req,pagename,need_location=False):
565        self.log.debug(pagename)
566        #self._response_wiki(req,pagename=id)
567        page = WikiPage(self.env, pagename, version=None)
568        if page.exists:
569            resource = Resource('wiki',pagename)
570            context = Context(Resource('wiki',pagename))
571            context.req = req
572            html = wiki_to_html(page.text, self.env, req, absurls=1,resource=resource)
573        else:
574            msg = 'Wiki page "%s" does not exist' % pagename
575            #if version is not None:
576            #    msg += ' at version %s' % version
577            raise TracError( msg)
578
579        entry = {'id':page.name,
580                 'title':page.name,
581                 'author':page.author,
582                 'updated':format_datetime(page.time,'iso8601'),
583                 'content':Markup(html),
584                 'href':req.abs_href.atompub('login/wiki/edit/%s'%(unicode_quote(to_unicode(page.name))))
585                 }
586        data = {'entry':entry}
587        self.log.debug(data)
588       
589        # LocationをつけないとPostできないがつけると、Broken Pipeになる
590        #location_header = None
591        #if need_location==True:
592        location_header= req.abs_href.atompub('login/wiki/edit/%s'%(unicode_quote(to_unicode(page.name))))
593       
594        return data,location_header
595       
596class AtomPub(Component):
597    implements(IRequestHandler,ITemplateProvider,IPermissionRequestor)   
598
599    service_providers = ExtensionPoint(IAtomPubHandler)
600
601   
602    # ITemplateProvider methods
603    def get_htdocs_dirs(self):
604        return []
605
606    def get_templates_dirs(self):
607        return [pkg_resources.resource_filename(__name__, 'templates')]
608   
609    # IRequestHandler methods
610    def match_request(self, req):
611        match = re.match(r'^/atompub(?:/(.*))?', req.path_info)
612        if match:
613            if match.group(1):
614                req.args['action'] = match.group(1)
615            return 1
616
617    def process_request(self, req):
618        #self._authorization(req)
619        self.log.debug('@@authname:%s'%req.authname)
620        pathsplit = req.args.get('action','').split('/')
621        service = pathsplit.pop(0)
622        if service == 'login':
623            #header = req.environ.get('HTTP_AUTHORIZATION')
624            #if header ==None:
625            #    self.log.debug(req.environ)
626            #    return self._response_error(req, 'Unauthorized Basic')
627            service = pathsplit.pop(0)
628       
629        action = ''
630        if len(pathsplit) > 0 :
631            action = pathsplit.pop(0)
632        id = '/'.join(pathsplit)
633
634        try:
635            for provider in self.service_providers:
636                if service == provider.atompub_title():
637                   
638                    #return provider.atompub_handler(req,action,id)
639
640                    req.perm.assert_permission('ATOM_PUB')
641                    self.log.debug(action)
642                    self.log.debug(req.method)
643                    username = req.authname
644                   
645                    if action == 'edit':
646                        if req.method == 'POST' or req.method == 'PUT':
647                            # update page
648                            (pagename,content_type,content) = self._parse_postdata(req)
649                            pageid,status_code = provider.atompub_do_update(req, pagename,content_type,content)
650                            data,loch = provider.atompub_get_feed(req,pageid)   
651                            #return self._response_feed(req,  data,loch)
652                            return self._response_entry(req,data,status_code,loch)
653                        elif req.method == 'DELETE':
654                            # delete page
655                            provider.atompub_do_delete(req, id)
656                            return self._response(req, 200,None)
657                        else:
658                            # get page
659                            data,loch = provider.atompub_get_feed(req,id)   
660                            return self._response_entry(req,  data,200,None)
661                    elif action == 'feed':
662                        if req.method == 'POST' or req.method == 'PUT':
663                            if req.get_header('Content-Type').startswith('application/atom+xml'):
664                                # create page
665                                (pagename,content_type,content) = self._parse_postdata(req)
666                                pageid,status_code = provider.atompub_do_create(req, pagename,content_type,content)
667                                data,loch = provider.atompub_get_feed(req,pageid)   
668                                #return self._response_feed(req,  data,loch)
669                                return self._response_entry(req,data,status_code,location=loch)
670                            else:
671                                # create attachment
672                                return provider.atompub_do_create_attachment(req)
673                        else:
674                            # get feedlist
675                            return 'atom_feed.xml', provider.atompub_get_feedlist(req), 'application/atom+xml' #'application/atom+xml'
676
677                    elif action == 'attachment' or action == 'edit_attachment':
678                        return provider.atompub_do_update_attachment(req,id)
679
680            if service == 'wlwmanifest.xml':
681                if action == '':
682                    data = {}
683                    return "wlwmanifest.xml",data,'application/xml'
684                elif action == 'WebLayout':
685                    data = {}
686                    add_stylesheet(req, 'common/css/wiki.css')
687                    add_stylesheet(req, 'wlwriter/css/wiki_temp_view.css')
688                    return "WebLayout.html",data,None
689                elif action == 'WebPreview':
690                    pagename = 'WikiStart'     
691                    context = Context.from_request(req,'wiki',pagename)
692                    add_stylesheet(req, 'common/css/wiki.css')
693                    add_stylesheet(req, 'wlwriter/css/wiki_temp_view.css')
694                    data = {'page': context.resource,
695                            'context': context,
696                            'action': 'view',
697                            'page_name': '{post-title}',
698                            #'attachments': AttachmentModule(self.env).attachment_list(context),
699                            'title': 'WebPreview'}
700                    return "WebPreview.html",data,None
701            elif service == 'attachment':
702                req.perm.assert_permission('ATOM_PUB')
703                # atompub/attachment/edit/wiki/pagename/../filename
704                realm = pathsplit.pop(0)
705                filename = pathsplit.pop()
706                id = '/'.join(pathsplit)
707                return self._process_attachement(req,action,realm,id,filename)
708            else:
709                return self._response_service(req)
710        except Exception, e:
711            self.log.error(e)
712            import traceback
713            from StringIO import StringIO
714            out = StringIO()
715            traceback.print_exc(file = out)
716            self.log.error(out.getvalue())
717            self._response_error(req, '',error_code=500,error_mes=str(e))
718            #self._send_response(req, xmlrpclib.dumps(xmlrpclib.Fault(2, "'%s' while executing '%s()'" % (str(e), method))))
719           
720    def _response_feed(self,req,data,location_header=False):
721        if location_header:
722            req.send_header('Location', location_header)
723        return 'atom_entry.xml',data,'application/atom+xml'
724
725
726    def _response_entry(self,req,data,status_code=200,location=None):
727        req.send_response(status_code)
728        req.send_header('Content-Type', 'application/atom+xml')
729        if location:
730            req.send_header('location', location)
731        req.end_headers()
732        if req.method != 'HEAD':
733           
734            id = data['entry']['id']
735            title = data['entry']['title']
736            author = data['entry']['author']
737            updated = data['entry']['updated']
738            href = data['entry']['href']
739            content = data['entry']['content']
740            content_src = data['entry']['content_src']
741            content_type = data['entry']['content_type']
742            req.write('''<?xml version="1.0" encoding="utf-8"?>''')
743            req.write('''
744<entry xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app">
745    <id>%s</id>
746    <title type="text">%s</title>
747    <author>
748        <name>%s</name>
749    </author>
750    <updated>%s</updated>
751    <app:edited>%s</app:edited>
752    <summary type="xhtml">
753        <div xmlns="http://www.w3.org/1999/xhtml"/>
754    </summary>
755    <link rel="self" type='application/atom+xml' href="%s" />
756    <link rel="edit" type='application/atom+xml' href="%s" />
757    <link rel="edit-media" href="%s" />
758'''%(id,title,author,updated,updated,href,href,href))
759            if content_src:
760                req.write('''
761<content type="%s" src="%s"/>
762</entry>
763'''%(content_type,content_src))           
764            else:
765                req.write('''
766    <content type="%s" >
767        <div xmlns="http://www.w3.org/1999/xhtml">%s</div>
768    </content>
769</entry>
770'''%(content_type,content))           
771        #raise RequestDone
772        #TODO : ここでExceptionがおきると、エラーを送信できない
773                   
774       
775    # IPermissionRequestor methods
776    def get_permission_actions(self):
777        yield 'ATOM_PUB'       
778       
779
780    def _parse_postdata(self,req):
781        rawreq=req.read(int(req.get_header('Content-Length')))
782        self.log.debug(rawreq)
783        doc = XML(rawreq)
784        description = Markup(doc.select('//content/.'))
785        ## if content type="html" : need unescape
786        content_type = str(doc.select('//content/@type'))
787        if content_type == "html":
788            description = unescape(Markup(doc.select('//content/.')))
789            description = unescape(Markup(description))
790        else :
791            description = Markup(doc.select('//content/.'))
792       
793        #doc = self._loads(rawreq)
794        #description = doc.getElementsByTagName('content')[0]
795        self.log.debug(description)
796        content = {'description':description}
797        #pagename = self._get_text_tag(doc,'id')
798        pagename = str(doc.select('//title/.'))
799        #self.log.debug('@@id'+id)
800        #self.log.debug(self._get_text_tag(doc,'content'))
801        return (pagename,content_type,content)
802 
803
804
805    def _link(self,doc,rel=None,href=None,type=None,title=None):
806        link = doc.createElement('link')
807        if rel !=None:
808            link.setAttribute('rel',rel)
809        if href !=None:
810            link.setAttribute('href',href)
811        if type !=None:
812            link.setAttribute('type',type)
813        if title !=None:
814            link.setAttribute('title',title)
815        return link   
816   
817
818
819    def _process_ticket(self,req,action,id):
820        pass
821
822
823    def _response_service(self, req, type_code=200, doc=None):
824        collections = []
825        for provider in self.service_providers:
826            collection = {'href':req.abs_href.atompub('login/%s/feed'%provider.atompub_title()),
827                          'data':Markup(provider.atompub_collection(req))}
828            collections.append(collection)
829       
830
831        #return 'atom_service.xml',{'collections':collections},'text/xml'#'application/atomsvc+xml'
832        return 'atom_service.xml',{'collections':collections},'application/atomsvc+xml'
833
834
835
836    def _responsez(self, req, type_code=200, doc=None):
837        req.send_response(type_code)
838        req.send_header('Content-Type', 'application/atom+xml')
839        req.end_headers()
840       
841        if req.method != 'HEAD' and doc != None:
842            req.write(doc.toprettyxml(indent = '    '))
843        raise RequestDone
844   
845
846    def _response_error(self, req, error_type,error_code=500,error_mes=''):
847       
848        if error_type == 'BadRequest':
849             error_code = 400
850             error_mes = 'XML parse failed.'
851        elif error_type == 'Unauthorized WSSE':
852             error_code = 401
853             error_mes = 'X-WSSE authentication required'
854             req.send_header('WWW-Authenticate','WSSE profile="UsernameToken"')
855        elif error_type == 'Unauthorized Basic':
856             error_code = 401
857             error_mes = 'Basic authentication required'
858             req.send_header('WWW-Authenticate','Basic realm="SECRET AREA"')
859        elif error_type == 'Unauthorized Digest':
860             error_code = 401
861             error_mes = 'Basic authentication required'
862             req.send_header('WWW-Authenticate','Basic realm="SECRET AREA"')
863        elif error_type == 'Forbidden':
864             error_code = 403
865             error_mes = 'Forbidden'
866        elif error_type == 'MethodNotAllowed':
867             error_code = 405
868             error_mes = 'Method Not Allowed'
869       
870        req.send_response(error_code)
871        req.send_header('Content-Type', 'text/html;charset=UTF-8')
872        req.end_headers()
873       
874        if req.method != 'HEAD':
875            req.write('''
876<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY></BODY></HTML>
877'''%(error_mes))
878           
879            #req.write('<?xml version="1.0" encoding="UTF-8"?>\n')
880            #req.write('<error>%s</error>'%error_mes)
881        raise RequestDone
882
883   
Note: See TracBrowser for help on using the browser.