def get_tiddlers(environ, start_response): """ Get a list representation of the tiddlers in a bag. The information sent is dependent on the serialization chosen. """ store = environ['tiddlyweb.store'] filters = environ['tiddlyweb.filters'] bag_name = web.get_route_value(environ, 'bag_name') bag = _get_bag(environ, bag_name) title = 'Tiddlers From Bag %s' % bag.name title = environ['tiddlyweb.query'].get('title', [title])[0] usersign = environ['tiddlyweb.usersign'] # will raise exception if there are problems bag.policy.allows(usersign, 'read') if filters: tiddlers = Tiddlers(title=title) else: tiddlers = Tiddlers(title=title, store=store) for tiddler in store.list_bag_tiddlers(bag): tiddlers.add(tiddler) tiddlers.link = '%s/tiddlers' % web.bag_url(environ, bag, full=False) return send_tiddlers(environ, start_response, tiddlers=tiddlers)
def post_createbag(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] bag_name = environ['tiddlyweb.query'].get('bag', [''])[0] publicity = environ['tiddlyweb.query'].get('publicity', [''])[0] description = environ['tiddlyweb.query'].get('description', [''])[0] if not bag_name: raise HTTP400('missing data') bag = Bag(bag_name) try: bag = store.get(bag) raise HTTP400('bag exists') except NoBagError: pass if publicity == 'public': bag = ensure_public_bag( store, user['name'], desc=description, name=bag_name) elif publicity == 'protected': bag = ensure_protected_bag( store, user['name'], desc=description, name=bag_name) else: bag = ensure_private_bag( store, user['name'], desc=description, name=bag_name) # the bag has already been stored raise HTTP303('%s/tiddlers' % bag_url(environ, bag))
def get_tiddlers(environ, start_response): """ Get a list representation of the tiddlers in a bag. The information sent is dependent on the serialization chosen. """ store = environ['tiddlyweb.store'] filters = environ['tiddlyweb.filters'] bag_name = web.get_route_value(environ, 'bag_name') bag = _get_bag(environ, bag_name) title = 'Tiddlers From Bag %s' % bag.name title = environ['tiddlyweb.query'].get('title', [title])[0] usersign = environ['tiddlyweb.usersign'] # will raise exception if there are problems bag.policy.allows(usersign, 'read') tiddlers = Tiddlers(title=title) if not filters: tiddlers.store = store tiddlers.bag = bag_name for tiddler in store.list_bag_tiddlers(bag): tiddlers.add(tiddler) tiddlers.link = '%s/tiddlers' % web.bag_url(environ, bag, full=False) return send_tiddlers(environ, start_response, tiddlers=tiddlers)
def _process_choices(environ, start_response, form): store = environ['tiddlyweb.store'] user = environ['tiddlyweb.usersign'] tmp_bag = form['tmp_bag'][0] bag = form['target_bag'][0] if bag: bag = Bag(bag) try: bag.skinny = True bag = store.get(bag) except NoBagError: return _send_wimport(environ, start_response, 'chosen bag does not exist') else: bag = form['new_bag'][0] bag = _make_bag(environ, bag) try: bag.policy.allows(user, 'write') except (ForbiddenError, UserRequiredError): return _send_wimport(environ, start_response, 'you may not write to that bag') tiddler_titles = form['tiddler'] for title in tiddler_titles: tiddler = Tiddler(title.decode('utf-8', 'ignore'), tmp_bag) tiddler = store.get(tiddler) tiddler.bag = bag.name store.put(tiddler) tmp_bag = Bag(tmp_bag) store.delete(tmp_bag) bagurl = bag_url(environ, bag) + '/tiddlers' raise HTTP302(bagurl)
def post_createbag(environ, start_response): user = get_user_object(environ) store = environ["tiddlyweb.store"] bag_name = environ["tiddlyweb.query"].get("bag", [""])[0] publicity = environ["tiddlyweb.query"].get("publicity", [""])[0] description = environ["tiddlyweb.query"].get("description", [""])[0] if not bag_name: raise HTTP400("missing data") bag = Bag(bag_name) try: bag = store.get(bag) raise HTTP400("bag exists") except NoBagError: pass if publicity == "public": bag = ensure_public_bag(store, user["name"], desc=description, name=bag_name) elif publicity == "protected": bag = ensure_protected_bag(store, user["name"], desc=description, name=bag_name) else: bag = ensure_private_bag(store, user["name"], desc=description, name=bag_name) # the bag has already been stored raise HTTP303("%s/tiddlers" % bag_url(environ, bag))
def bag_as(self, bag): """ A single bag as HAL """ bag_uri = bag_url(self.environ, bag, full=True) entity_structure = dict(policy=self._get_policy(bag.policy), desc=bag.desc, name=bag.name) return self._entity_as(entity_structure, bag_uri, 'bags')
def _bag_policy(environ, bag_name, publicity): user = get_user_object(environ) store = environ["tiddlyweb.store"] bag = Bag(bag_name) bag = store.get(bag) bag.policy.allows(user, "manage") if publicity == "custom": raise HTTP303(bag_url(environ, bag) + "/tiddlers") if publicity == "public": bag.policy = public_policy(user["name"]) elif publicity == "protected": bag.policy = protected_policy(user["name"]) else: bag.policy = private_policy(user["name"]) store.put(bag) raise HTTP303(bag_url(environ, bag) + "/tiddlers")
def _bag_policy(environ, bag_name, publicity): user = get_user_object(environ) store = environ['tiddlyweb.store'] bag = Bag(bag_name) bag = store.get(bag) bag.policy.allows(user, 'manage') if publicity == 'custom': raise HTTP303(bag_url(environ, bag) + '/tiddlers') if publicity == 'public': bag.policy = public_policy(user['name']) elif publicity == 'protected': bag.policy = protected_policy(user['name']) else: bag.policy = private_policy(user['name']) store.put(bag) raise HTTP303(bag_url(environ, bag) + '/tiddlers')
def bag_policy(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] publicity = environ['tiddlyweb.query'].get('publicity', [''])[0] bag_name = environ['tiddlyweb.query'].get('bag', [''])[0] bag = Bag(bag_name) bag.skinny = True bag = store.get(bag) bag.policy.allows(user, 'manage') if publicity == 'custom': raise HTTP303(bag_url(environ, bag) + '/tiddlers') if publicity == 'public': bag.policy = public_policy(user['name']) elif publicity == 'protected': bag.policy = protected_policy(user['name']) else: bag.policy = private_policy(user['name']) store.put(bag) raise HTTP303(bag_url(environ, bag) + '/tiddlers')
def _tiddlers_self(self, tiddler): """ Given a single tiddler from a collection determine the self URI of that collection. """ links = {} if tiddler.recipe: tiddlers_container = recipe_url(self.environ, Recipe(tiddler.recipe), full=True) links['tiddlyweb:recipe'] = tiddlers_container else: tiddlers_container = bag_url(self.environ, Bag(tiddler.bag), full=True) links['tiddlyweb:bag'] = tiddlers_container return links
def _tiddler_links(self, tiddler): """ The links to provide with a single tiddler. """ links = [] tiddler_link = tiddler_url(self.environ, tiddler, full=True) collection_link = self._tiddlers_links(Tiddlers(), tiddler)['self'] links.append(Link('tiddlyweb:tiddlers', collection_link)) links.append(Link('collection', collection_link)) links.append(Link('tiddlyweb:bag', bag_url(self.environ, Bag(tiddler.bag), full=True))) if tiddler.recipe: links.append(Link('tiddlyweb:recipe', recipe_url(self.environ, Recipe(tiddler.recipe), full=True))) links.append(Link('self', tiddler_link)) return links
def render(tiddler, environ, seen_titles=None): """ Return tiddler.text as rendered HTML by passing it down a socket to the nodejs based server.js process. Transclusions are identified in the returned text and processed recursively. If there is a current user, that user is passed along the pipe so that private content can be retrieved by nodejs (over HTTP). """ if seen_titles is None: seen_titles = [] parser = html5lib.HTMLParser( tree = html5lib.treebuilders.getTreeBuilder("dom")) if tiddler.recipe: collection = recipe_url(environ, Recipe(tiddler.recipe)) + '/tiddlers' else: collection = bag_url(environ, Bag(tiddler.bag)) + '/tiddlers' try: user_cookie = environ['HTTP_COOKIE'] cookie = Cookie.SimpleCookie() cookie.load(user_cookie) tiddlyweb_cookie = 'tiddlyweb_user='******'tiddlyweb_user'].value except KeyError: tiddlyweb_cookie = '' socket_path = environ['tiddlyweb.config'].get('twikified.socket', '/tmp/wst.sock') twik_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: twik_socket.connect(socket_path) except (socket.error, IOError), exc: output = """ <div class='error'>There was a problem rendering this tiddler. The raw text is given below.</div> <pre class='wikitext'>%s</pre> """ % (escape_attribute_value(tiddler.text)) logging.warn('twikifier socket connect failed: %s', exc) twik_socket.shutdown(socket.SHUT_RDWR) twik_socket.close() return output
def put(environ, start_response): """ Handle ``PUT`` on a single bag URI. Put a :py:class:`bag <tiddlyweb.model.bag.Bag>` to the server, meaning the description and policy of the bag, if :py:class:`policy <tiddlyweb.model.policy.Policy>` allows. """ bag_name = web.get_route_value(environ, 'bag_name') bag_name = web.handle_extension(environ, bag_name) bag = Bag(bag_name) store = environ['tiddlyweb.store'] length, _ = web.content_length_and_type(environ) usersign = environ['tiddlyweb.usersign'] try: bag = store.get(bag) bag.policy.allows(usersign, 'manage') except NoBagError: create_policy_check(environ, 'bag', usersign) try: serialize_type = web.get_serialize_type(environ)[0] serializer = Serializer(serialize_type, environ) serializer.object = bag content = web.read_request_body(environ, length) serializer.from_string(content.decode('utf-8')) bag.policy.owner = usersign['name'] _validate_bag(environ, bag) store.put(bag) except BagFormatError as exc: raise HTTP400('unable to put bag: %s' % exc) except TypeError: raise HTTP400('Content-type header required') except NoSerializationError: raise HTTP415('Content type not supported: %s' % serialize_type) start_response("204 No Content", [('Location', web.bag_url(environ, bag))]) return []
def put(environ, start_response): """ Put a bag to the server, meaning the description and policy of the bag, if policy allows. """ bag_name = _determine_bag_name(environ) bag_name = web.handle_extension(environ, bag_name) bag = Bag(bag_name) store = environ['tiddlyweb.store'] length = environ['CONTENT_LENGTH'] usersign = environ['tiddlyweb.usersign'] try: bag.skinny = True bag = store.get(bag) bag.policy.allows(usersign, 'manage') try: delattr(bag, 'skinny') except AttributeError: pass except NoBagError: create_policy_check(environ, 'bag', usersign) try: serialize_type = web.get_serialize_type(environ)[0] serializer = Serializer(serialize_type, environ) serializer.object = bag content = environ['wsgi.input'].read(int(length)) serializer.from_string(content.decode('utf-8')) bag.policy.owner = usersign['name'] _validate_bag(environ, bag) store.put(bag) except TypeError: raise HTTP400('Content-type header required') except NoSerializationError: raise HTTP415('Content type not supported: %s' % serialize_type) start_response("204 No Content", [('Location', web.bag_url(environ, bag))]) return []
def render(tiddler, environ, seen_titles=None): """ Return tiddler.text as rendered HTML by passing it down a socket to the nodejs based server.js process. Transclusions are identified in the returned text and processed recursively. If there is a current user, that user is passed along the pipe so that private content can be retrieved by nodejs (over HTTP). """ if seen_titles is None: seen_titles = [] parser = html5lib.HTMLParser( tree=html5lib.treebuilders.getTreeBuilder("dom")) if tiddler.recipe: collection = recipe_url(environ, Recipe(tiddler.recipe)) + '/tiddlers' else: collection = bag_url(environ, Bag(tiddler.bag)) + '/tiddlers' try: user_cookie = environ['HTTP_COOKIE'] cookie = Cookie.SimpleCookie() cookie.load(user_cookie) tiddlyweb_cookie = 'tiddlyweb_user='******'tiddlyweb_user'].value except KeyError: tiddlyweb_cookie = '' socket_path = environ['tiddlyweb.config'].get('twikified.socket', '/tmp/wst.sock') twik_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: twik_socket.connect(socket_path) except (socket.error, IOError), exc: output = """ <div class='error'>There was a problem rendering this tiddler. The raw text is given below.</div> <pre class='wikitext'>%s</pre> """ % (escape_attribute_value(tiddler.text)) logging.warn('twikifier socket connect failed: %s', exc) twik_socket.shutdown(socket.SHUT_RDWR) twik_socket.close() return output
def _tiddlers_collection_uri(self): """ Calculate the uri of the current tiddler collection. This ought to use tiddlyweb.model.collection but the code is not there yet. """ recipe_name = bag_name = None try: recipe_name = get_route_value(self.environ, 'recipe_name') except KeyError: try: bag_name = get_route_value(self.environ, 'bag_name') except KeyError: return None if recipe_name: base = recipe_url(self.environ, Recipe(recipe_name), full=True) else: base = bag_url(self.environ, Bag(bag_name), full=True) return base + '/tiddlers'
def render(tiddler, environ): if tiddler.recipe: collection = recipe_url(environ, Recipe(tiddler.recipe)) + '/tiddlers' else: collection = bag_url(environ, Bag(tiddler.bag)) + '/tiddlers' socket_path = environ['tiddlyweb.config'].get('twikified.socket', '/tmp/wst.sock') twik_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) twik_socket.connect('/tmp/wst.sock') twik_socket.sendall('%s\x00%s\n' % (collection, tiddler.title)) output = '' try: while True: data = twik_socket.recv(1024) if data: output += data else: break finally: twik_socket.close() return output.decode('UTF-8')
def test_content_type(): bag = Bag('holder') bag = store.get(bag) tiddlers = Tiddlers(store=store) # duplicate what the handler would do tiddlers.link = bag_url({'tiddlyweb.config': config}, bag, full=False) + '/tiddlers' for tiddler in store.list_bag_tiddlers(bag): tiddlers.add(tiddler) serializer = Serializer('tiddlywebwiki.serialization', {'tiddlyweb.config': config}) output = ''.join(serializer.list_tiddlers(tiddlers)) # we are expecting an img link to the image tiddler assert 'server.content-type="image/png"' in output # but we want just an html anchor link to the zero assert 'server.content-type="application/octet-stream"' in output assert 'server.content-type="text/html"' in output assert ('you may still <a href="/bags/holder/tiddlers">browse' in output)
def render(tiddler, environ): if tiddler.recipe: collection = recipe_url(environ, Recipe(tiddler.recipe)) + '/tiddlers' else: collection = bag_url(environ, Bag(tiddler.bag)) + '/tiddlers' try: user_cookie = environ['HTTP_COOKIE'] cookie = Cookie.SimpleCookie() cookie.load(user_cookie) tiddlyweb_cookie = 'tiddlyweb_user='******'tiddlyweb_user'].value except KeyError: tiddlyweb_cookie = '' socket_path = environ['tiddlyweb.config'].get('twikified.socket', '/tmp/wst.sock') twik_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: twik_socket.connect('/tmp/wst.sock') except IOError: output = """ <div class='error'>There was a problem rendering this tiddler. The raw text is given instead below.</div> <pre class='wikitext'>%s</pre> """%(escape_attribute_value(tiddler.text)) return output twik_socket.sendall('%s\x00%s\x00%s\n' % (collection, tiddler.title, tiddlyweb_cookie)) output = '' try: while True: data = twik_socket.recv(1024) if data: output += data else: break finally: twik_socket.close() return output.decode('UTF-8')
def put(environ, start_response): """ Put a bag to the server, meaning the description and policy of the bag, if policy allows. """ bag_name = _determine_bag_name(environ) bag_name = web.handle_extension(environ, bag_name) bag = Bag(bag_name) store = environ["tiddlyweb.store"] length = environ["CONTENT_LENGTH"] usersign = environ["tiddlyweb.usersign"] try: bag.skinny = True bag = store.get(bag) bag.policy.allows(usersign, "manage") delattr(bag, "skinny") except NoBagError: create_policy_check(environ, "bag", usersign) try: serialize_type = web.get_serialize_type(environ)[0] serializer = Serializer(serialize_type, environ) serializer.object = bag content = environ["wsgi.input"].read(int(length)) serializer.from_string(content.decode("utf-8")) bag.policy.owner = usersign["name"] store.put(bag) except NoSerializationError: raise HTTP415("Content type not supported: %s" % serialize_type) start_response("204 No Content", [("Location", web.bag_url(environ, bag))]) return []
def get_tiddlers(environ, start_response): """ Handle ``GET`` on a tiddlers-within-a-bag URI. Get a list representation of the :py:class:`tiddlers <tiddlyweb.model.tiddler.Tiddler>` in a :py:class:`bag <tiddlyweb.model.bag.Bag>`. The information sent is dependent on the serialization chosen via :py:mod:`tiddlyweb.web.negotiate`. """ store = environ['tiddlyweb.store'] filters = environ['tiddlyweb.filters'] bag_name = web.get_route_value(environ, 'bag_name') bag = _get_bag(environ, bag_name) title = 'Tiddlers From Bag %s' % bag.name title = environ['tiddlyweb.query'].get('title', [title])[0] usersign = environ['tiddlyweb.usersign'] # will raise exception if there are problems bag.policy.allows(usersign, 'read') tiddlers = Tiddlers(title=title) if not filters: tiddlers.store = store tiddlers.bag = bag_name # A special bag can raise NoBagError here. try: for tiddler in store.list_bag_tiddlers(bag): tiddlers.add(tiddler) except NoBagError as exc: raise HTTP404('%s not found, %s' % (bag.name, exc)) tiddlers.link = '%s/tiddlers' % web.bag_url(environ, bag, full=False) return send_tiddlers(environ, start_response, tiddlers=tiddlers)
def post_createbag(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] bag_name = environ['tiddlyweb.query'].get('bag', [''])[0] publicity = environ['tiddlyweb.query'].get('publicity', [''])[0] description = environ['tiddlyweb.query'].get('description', [''])[0] if not bag_name: raise HTTP400('missing data') bag = Bag(bag_name) try: bag = store.get(bag) raise HTTP400('bag exists') except NoBagError: pass if publicity == 'public': bag = ensure_public_bag(store, user['name'], desc=description, name=bag_name) elif publicity == 'protected': bag = ensure_protected_bag(store, user['name'], desc=description, name=bag_name) else: bag = ensure_private_bag(store, user['name'], desc=description, name=bag_name) # the bag has already been stored raise HTTP303('%s/tiddlers' % bag_url(environ, bag))
content = environ['wsgi.input'].read(int(length)) serializer.from_string(content.decode('utf-8')) bag.policy.owner = usersign['name'] _validate_bag(environ, bag) store.put(bag) except BagFormatError, exc: raise HTTP400('unable to put bag: %s' % exc) except TypeError: raise HTTP400('Content-type header required') except NoSerializationError: raise HTTP415('Content type not supported: %s' % serialize_type) start_response("204 No Content", [('Location', web.bag_url(environ, bag))]) return [] def _validate_bag(environ, bag): """ Unless bag is valid raise a 409 with the reason why. """ try: validate_bag(bag, environ) except InvalidBagError, exc: raise HTTP409('Bag content is invalid: %s' % exc) def _get_bag(environ, bag_name):
# will raise exception if there are problems bag.policy.allows(usersign, "read") tiddlers = Tiddlers(title=title) if not filters: tiddlers.store = store tiddlers.bag = bag_name # A special bag can raise NoBagError here. try: for tiddler in store.list_bag_tiddlers(bag): tiddlers.add(tiddler) except NoBagError, exc: raise HTTP404("%s not found, %s" % (bag.name, exc)) tiddlers.link = "%s/tiddlers" % web.bag_url(environ, bag, full=False) return send_tiddlers(environ, start_response, tiddlers=tiddlers) def list_bags(environ, start_response): """ List all the bags that the current user can read. """ return list_entities(environ, start_response, "list_bags") def put(environ, start_response): """ Put a bag to the server, meaning the description and policy of the bag, if policy allows.
def render(tiddler, environ): """ Return tiddler.text as rendered HTML by passing it down a socket to the nodejs based server.js process. Transclusions are identified in the returned text and processed recursively. If there is a current user, that user is passed along the pipe so that private content can be retrieved by nodejs (over HTTP). """ if tiddler.recipe: collection = recipe_url(environ, Recipe(tiddler.recipe)) + '/tiddlers' else: collection = bag_url(environ, Bag(tiddler.bag)) + '/tiddlers' try: user_cookie = environ['HTTP_COOKIE'] cookie = Cookie.SimpleCookie() cookie.load(user_cookie) tiddlyweb_cookie = 'tiddlyweb_user='******'tiddlyweb_user'].value except KeyError: tiddlyweb_cookie = '' socket_path = environ['tiddlyweb.config'].get( 'twikified.socket', '/var/run/twikifier/wst.sock') twik_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) twik_socket.settimeout(15.0) try: try: twik_socket.connect(socket_path) except (socket.error, IOError), exc: output = """ <div class='error'>There was a problem rendering this tiddler. The raw text is given below.</div> <pre class='wikitext'>%s</pre> """ % (escape_attribute_value(tiddler.text)) LOGGER.warn('twikifier socket connect failed: %s', exc) twik_socket.shutdown(socket.SHUT_RDWR) twik_socket.close() return output try: twik_socket.sendall( '%s\x00%s\x00%s\n' % (collection, tiddler.text.encode('utf-8', 'replace'), tiddlyweb_cookie)) twik_socket.shutdown(socket.SHUT_WR) output = '' try: while True: data = twik_socket.recv(1024) if data: output += data else: break finally: twik_socket.shutdown(socket.SHUT_RDWR) twik_socket.close() except (socket.error, IOError), exc: if hasattr(exc, 'errno') and exc.errno == 57: twik_socket.close() else: LOGGER.warn('twikifier error during data processing: %s', exc) output = """ <div class='error'>There was a problem rendering this tiddler. The raw text is given below.</div> <pre class='wikitext'>%s</pre> """ % (escape_attribute_value(tiddler.text)) try: twik_socket.shutdown(socket.SHUT_RDWR) twik_socket.close() except (socket.error), exc: LOGGER.warn('twikifier bad socket shutdown: %s', exc) return output
content = environ["wsgi.input"].read(int(length)) bag.policy.allows(environ["tiddlyweb.usersign"], "create") try: serialize_type, mime_type = web.get_serialize_type(environ) serializer = Serializer(serialize_type, environ) serializer.object = bag serializer.from_string(content) except NoSerializationError: raise HTTP415("Content type not supported: %s" % mime_type) except AttributeError, exc: raise HTTP400("Content malformed: %s" % exc) start_response("204 No Content", [("Location", "%s/tiddlers" % web.bag_url(environ, bag))]) return [""] def list(environ, start_response): """ List all the bags that the current user can read. """ store = environ["tiddlyweb.store"] bags = store.list_bags() kept_bags = [] for bag in bags: try: bag.skinny = True bag = store.get(bag) bag.policy.allows(environ["tiddlyweb.usersign"], "read")
serializer.object = bag content = environ['wsgi.input'].read(int(length)) serializer.from_string(content.decode('utf-8')) bag.policy.owner = usersign['name'] _validate_bag(environ, bag) store.put(bag) except BagFormatError, exc: raise HTTP400('unable to put bag: %s' % exc) except TypeError: raise HTTP400('Content-type header required') except NoSerializationError: raise HTTP415('Content type not supported: %s' % serialize_type) start_response("204 No Content", [('Location', web.bag_url(environ, bag))]) return [] def _validate_bag(environ, bag): """ Unless bag is valid raise a 409 with the reason why. """ try: validate_bag(bag, environ) except InvalidBagError, exc: raise HTTP409('Bag content is invalid: %s' % exc) def _determine_bag_name(environ):
content = web.read_request_body(environ, length) serializer.from_string(content.decode('utf-8')) bag.policy.owner = usersign['name'] _validate_bag(environ, bag) store.put(bag) except BagFormatError, exc: raise HTTP400('unable to put bag: %s' % exc) except TypeError: raise HTTP400('Content-type header required') except NoSerializationError: raise HTTP415('Content type not supported: %s' % serialize_type) start_response("204 No Content", [('Location', web.bag_url(environ, bag))]) return [] def _validate_bag(environ, bag): """ Unless bag is valid raise a 409 with the reason why. """ try: validate_bag(bag, environ) except InvalidBagError, exc: raise HTTP409('Bag content is invalid: %s' % exc) def _get_bag(environ, bag_name):
def render(tiddler, environ): """ Return tiddler.text as rendered HTML by passing it down a socket to the nodejs based server.js process. Transclusions are identified in the returned text and processed recursively. If there is a current user, that user is passed along the pipe so that private content can be retrieved by nodejs (over HTTP). """ if tiddler.recipe: collection = recipe_url(environ, Recipe(tiddler.recipe)) + '/tiddlers' else: collection = bag_url(environ, Bag(tiddler.bag)) + '/tiddlers' try: user_cookie = environ['HTTP_COOKIE'] cookie = Cookie.SimpleCookie() cookie.load(user_cookie) tiddlyweb_cookie = 'tiddlyweb_user='******'tiddlyweb_user'].value except KeyError: tiddlyweb_cookie = '' socket_path = environ['tiddlyweb.config'].get('twikified.socket', '/var/run/twikifier/wst.sock') twik_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) twik_socket.settimeout(15.0) try: try: twik_socket.connect(socket_path) except (socket.error, IOError), exc: output = """ <div class='error'>There was a problem rendering this tiddler. The raw text is given below.</div> <pre class='wikitext'>%s</pre> """ % (escape_attribute_value(tiddler.text)) LOGGER.warn('twikifier socket connect failed: %s', exc) twik_socket.shutdown(socket.SHUT_RDWR) twik_socket.close() return output try: twik_socket.sendall('%s\x00%s\x00%s\n' % (collection, tiddler.text.encode('utf-8', 'replace'), tiddlyweb_cookie)) twik_socket.shutdown(socket.SHUT_WR) output = '' try: while True: data = twik_socket.recv(1024) if data: output += data else: break finally: twik_socket.shutdown(socket.SHUT_RDWR) twik_socket.close() except (socket.error, IOError), exc: if hasattr(exc, 'errno') and exc.errno == 57: twik_socket.close() else: LOGGER.warn('twikifier error during data processing: %s', exc) output = """ <div class='error'>There was a problem rendering this tiddler. The raw text is given below.</div> <pre class='wikitext'>%s</pre> """ % (escape_attribute_value(tiddler.text)) try: twik_socket.shutdown(socket.SHUT_RDWR) twik_socket.close() except (socket.error), exc: LOGGER.warn('twikifier bad socket shutdown: %s', exc) return output
serializer.object = bag content = environ["wsgi.input"].read(int(length)) serializer.from_string(content.decode("utf-8")) bag.policy.owner = usersign["name"] _validate_bag(environ, bag) store.put(bag) except BagFormatError, exc: raise HTTP400("unable to put bag: %s" % exc) except TypeError: raise HTTP400("Content-type header required") except NoSerializationError: raise HTTP415("Content type not supported: %s" % serialize_type) start_response("204 No Content", [("Location", web.bag_url(environ, bag))]) return [] def _validate_bag(environ, bag): """ Unless bag is valid raise a 409 with the reason why. """ try: validate_bag(bag, environ) except InvalidBagError, exc: raise HTTP409("Bag content is invalid: %s" % exc) def _determine_bag_name(environ):