| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
import os.path |
|---|
| 4 |
import threading |
|---|
| 5 |
import cherrypy |
|---|
| 6 |
import sha |
|---|
| 7 |
from sets import Set |
|---|
| 8 |
from urllib import unquote |
|---|
| 9 |
from amplee.comparer import app_updated_comparer |
|---|
| 10 |
from amplee.utils import get_isodate, \ |
|---|
| 11 |
compute_etag_from_feed, compute_etag_from_entry |
|---|
| 12 |
|
|---|
| 13 |
from bridge import Element as E |
|---|
| 14 |
from bridge import Document, PI |
|---|
| 15 |
from bridge.common import ATOM10_NS, ATOM10_PREFIX |
|---|
| 16 |
|
|---|
| 17 |
from core.utils import transform_member_resource |
|---|
| 18 |
|
|---|
| 19 |
__all__ = ['Browser', 'Menu', 'Null'] |
|---|
| 20 |
|
|---|
| 21 |
class Null(object): |
|---|
| 22 |
pass |
|---|
| 23 |
|
|---|
| 24 |
class Browser(object): |
|---|
| 25 |
def __init__(self, service, indexer): |
|---|
| 26 |
self.service = service |
|---|
| 27 |
self.indexer = indexer |
|---|
| 28 |
|
|---|
| 29 |
@cherrypy.expose |
|---|
| 30 |
def index(self): |
|---|
| 31 |
cherrypy.response.headers['content-type'] = 'application/xml' |
|---|
| 32 |
return self.service.service.xml() |
|---|
| 33 |
|
|---|
| 34 |
@cherrypy.expose |
|---|
| 35 |
def search(self, query): |
|---|
| 36 |
tokens = query.split(' ') |
|---|
| 37 |
s = Set() |
|---|
| 38 |
for token in tokens: |
|---|
| 39 |
t = self.indexer.indexes['category_index'].lookup(term=token) |
|---|
| 40 |
s |= t |
|---|
| 41 |
|
|---|
| 42 |
items = self.indexer.to_dict(s) |
|---|
| 43 |
|
|---|
| 44 |
cherrypy.response.headers['content-type'] = 'application/xml' |
|---|
| 45 |
return self.service.make_feed(items, entry_processor=transform_member_resource, |
|---|
| 46 |
title=u"Search Result", xslt_path=u"/static/search.xsl", |
|---|
| 47 |
member_comparer=app_updated_comparer).xml() |
|---|
| 48 |
|
|---|
| 49 |
class Menu(object): |
|---|
| 50 |
def __init__(self, collection): |
|---|
| 51 |
self.collection = collection |
|---|
| 52 |
self.lock = threading.Lock() |
|---|
| 53 |
|
|---|
| 54 |
@cherrypy.expose |
|---|
| 55 |
def index(self): |
|---|
| 56 |
|
|---|
| 57 |
|
|---|
| 58 |
cherrypy.response.headers['content-type'] = 'application/xml' |
|---|
| 59 |
feed = self.collection.feed_handler.public_feed.xml_root |
|---|
| 60 |
cherrypy.response.headers['ETag'] = compute_etag_from_feed(feed) |
|---|
| 61 |
return self.collection.feed_handler.public_xml() |
|---|
| 62 |
|
|---|
| 63 |
@cherrypy.expose |
|---|
| 64 |
def default(self, recipe, comments=None, **kwargs): |
|---|
| 65 |
recipe = unquote(recipe).decode('utf-8') |
|---|
| 66 |
member_id, media_id = self.collection.convert_id(recipe) |
|---|
| 67 |
member = self.collection.get_member(member_id) |
|---|
| 68 |
if not member: |
|---|
| 69 |
raise cherrypy.NotFound() |
|---|
| 70 |
|
|---|
| 71 |
if not comments: |
|---|
| 72 |
entry = transform_member_resource(member, xslt_path="/static/entry.xsl") |
|---|
| 73 |
cherrypy.response.headers['ETag'] = compute_etag_from_entry(entry.xml_root) |
|---|
| 74 |
if recipe.endswith('.atom'): |
|---|
| 75 |
cherrypy.response.headers['content-type'] = 'application/atom+xml;type=entry' |
|---|
| 76 |
else: |
|---|
| 77 |
cherrypy.response.headers['content-type'] = 'application/xml' |
|---|
| 78 |
return entry.xml() |
|---|
| 79 |
elif cherrypy.request.method == 'GET': |
|---|
| 80 |
path = os.path.join('static', 'replies', member.media_id) |
|---|
| 81 |
if os.path.exists(path): |
|---|
| 82 |
cherrypy.response.headers['content-type'] = 'application/xml' |
|---|
| 83 |
return file(path, 'r') |
|---|
| 84 |
elif cherrypy.request.method == 'POST': |
|---|
| 85 |
author = kwargs.get('author', '') |
|---|
| 86 |
content = kwargs.get('content', '') |
|---|
| 87 |
path = os.path.join('static', 'replies', member.media_id) |
|---|
| 88 |
try: |
|---|
| 89 |
self.lock.acquire() |
|---|
| 90 |
feed = E.load(file(path, 'r').read()) |
|---|
| 91 |
root = feed.xml_root |
|---|
| 92 |
e = E(u'entry', namespace=ATOM10_NS, prefix=ATOM10_PREFIX, parent=root) |
|---|
| 93 |
isodate = get_isodate() |
|---|
| 94 |
E(u'id', content=u'tags:comment:%s' % sha.new(str(isodate)).hexdigest(), |
|---|
| 95 |
namespace=ATOM10_NS, prefix=ATOM10_PREFIX, parent=e) |
|---|
| 96 |
E(u'updated', content=isodate, |
|---|
| 97 |
namespace=ATOM10_NS, prefix=ATOM10_PREFIX, parent=e) |
|---|
| 98 |
E(u'title', attributes={u'type': u'text'}, |
|---|
| 99 |
namespace=ATOM10_NS, prefix=ATOM10_PREFIX, parent=e) |
|---|
| 100 |
a = E(u'author', namespace=ATOM10_NS, prefix=ATOM10_PREFIX, parent=e) |
|---|
| 101 |
E(u'name', content=author.decode('utf-8'), |
|---|
| 102 |
namespace=ATOM10_NS, prefix=ATOM10_PREFIX, parent=a) |
|---|
| 103 |
|
|---|
| 104 |
E(u'content', content=content.decode('utf-8'), |
|---|
| 105 |
attributes={u'type': u'text'}, namespace=ATOM10_NS, prefix=ATOM10_PREFIX, parent=e) |
|---|
| 106 |
|
|---|
| 107 |
updated = root.get_child('updated', ATOM10_NS) |
|---|
| 108 |
updated.xml_text = isodate |
|---|
| 109 |
|
|---|
| 110 |
file(path, 'w').write(feed.xml()) |
|---|
| 111 |
finally: |
|---|
| 112 |
self.lock.release() |
|---|
| 113 |
|
|---|
| 114 |
raise cherrypy.HTTPRedirect(cherrypy.url()) |
|---|
| 115 |
|
|---|
| 116 |
raise cherrypy.NotFound() |
|---|
| 117 |
|
|---|
| 118 |
@cherrypy.expose |
|---|
| 119 |
def feed(self): |
|---|
| 120 |
cherrypy.response.headers['content-type'] = 'application/atom+xml;type=feed' |
|---|
| 121 |
feed = self.collection.feed_handler.public_feed.xml_root |
|---|
| 122 |
cherrypy.response.headers['ETag'] = compute_etag_from_feed(feed) |
|---|
| 123 |
return self.collection.feed_handler.public_xml() |
|---|
| 124 |
|
|---|