def send_entity(environ, start_response, entity): """ Send a bag or recipe out HTTP, first serializing to the correct type. """ username = environ['tiddlyweb.usersign']['name'] try: serialize_type, mime_type = get_serialize_type(environ) serializer = Serializer(serialize_type, environ) serializer.object = entity content = serializer.to_string() except NoSerializationError: raise HTTP415('Content type %s not supported' % mime_type) etag_string = '"%s"' % (sha(_entity_etag(entity) + encode_name(username) + encode_name(mime_type)).hexdigest()) start_response("200 OK", [('Content-Type', mime_type), ('ETag', etag_string), ('Vary', 'Accept')]) if isinstance(content, basestring): return [content] else: return content
def test_generated_string(): serializer = Serializer('text') string = ''.join(serializer.list_tiddlers(tiddler_collection)) assert 'TiddlerOne' in string assert 'TiddlerTwo' in string assert 'TiddlerThree' in string
def test_html_attribute_escape_with_bag(): tiddler = Tiddler('escape "double" quotes in tiddler field values') tiddler.bag = 'foo "bar" baz' tiddler.modifier = 'Chris "sensei" Dent' tiddler.tags = ["foo", 'xxx "yyy" zzz'] tiddler.fields["custom"] = u"""lorem 'ipsum' dolor "sit" amet""" tiddler.text = '' serializer = Serializer('tiddlywebwiki.serialization', environ) serializer.object = tiddler string = serializer.to_string() assert ('title="escape "double" quotes in tiddler field values"' in string) assert ('server.title="escape "double" quotes in tiddler ' 'field values"' in string) assert 'bag="foo "bar" baz"' in string assert 'server.workspace="bags/foo "bar" baz"' in string assert 'modifier="Chris "sensei" Dent"' in string assert 'creator="Chris "sensei" Dent"' in string assert 'tags="foo [[xxx "yyy" zzz]]"' in string assert '''custom="lorem 'ipsum' dolor "sit" amet"''' in string # single tiddler's browse link is that tiddler in its bag assert ('you may still <a href="/bags/foo%20%22bar%22%20baz/tiddlers/' 'escape%20%22double%22%20quotes%20in%20tiddler%20field%20' 'values">browse' in string)
def send_entity(environ, start_response, entity): """ Send a bag or recipe out HTTP, first serializing to the correct type. """ username = environ['tiddlyweb.usersign']['name'] try: serialize_type, mime_type = get_serialize_type(environ) serializer = Serializer(serialize_type, environ) serializer.object = entity content = serializer.to_string() except NoSerializationError: raise HTTP415('Content type %s not supported' % mime_type) etag_string = '"%s"' % (sha( _entity_etag(entity) + encode_name(username) + encode_name(mime_type)).hexdigest()) start_response("200 OK", [('Content-Type', mime_type), ('ETag', etag_string), ('Vary', 'Accept')]) if isinstance(content, basestring): return [content] else: return content
def _get_tiddler_content(environ, tiddler): """ Extract the content of the tiddler, either straight up if the content is not considered text, or serialized if it is. """ config = environ['tiddlyweb.config'] default_serializer = config['default_serializer'] default_serialize_type = config['serializers'][default_serializer][0] serialize_type, mime_type, accept = get_serialize_type(environ, accept_type=True) extension = environ.get('tiddlyweb.extension') serialized = False # If this is a tiddler with a CANONICAL_URI_FIELD redirect # there unless we are requesting a json form if (CANONICAL_URI_FIELD in tiddler.fields and CANONICAL_URI_PASS_TYPE not in mime_type): raise HTTP302(tiddler.fields[CANONICAL_URI_FIELD]) if not renderable(tiddler, environ): if (serialize_type == default_serialize_type or accept.startswith(tiddler.type) or extension == 'html'): mime_type = tiddler.type content = tiddler.text return content, mime_type, serialized serializer = Serializer(serialize_type, environ) serializer.object = tiddler try: content = serializer.to_string() serialized = True except (TiddlerFormatError, NoSerializationError) as exc: raise HTTP415(exc) return content, mime_type, serialized
def test_bad_string_raises(): serializer = Serializer('text') foobar = Tiddler('foobar') serializer.object = foobar with pytest.raises(TiddlerFormatError): serializer.from_string(bad_string)
def send_entity(environ, start_response, entity): """ Send a :py:class:`bag <tiddlyweb.model.bag.Bag>` or :py:class:`recipe <tiddlyweb.model.recipe.Recipe>` out over HTTP, first :py:class:`serializing <tiddlyweb.serializer.Serializer>` to the correct type. If an incoming ``Etag`` validates, raise a ``304`` response. """ etag_string = entity_etag(environ, entity) check_incoming_etag(environ, etag_string) try: serialize_type, mime_type = get_serialize_type(environ) serializer = Serializer(serialize_type, environ) serializer.object = entity content = serializer.to_string() except NoSerializationError: raise HTTP415('Content type %s not supported' % mime_type) start_response("200 OK", [('Content-Type', mime_type), ('Cache-Control', 'no-cache'), ('ETag', etag_string), ('Vary', 'Accept')]) if isinstance(content, basestring): return [content] else: return content
def post_request(environ, start_response): length = int(environ["CONTENT_LENGTH"]) post_content = environ["wsgi.input"].read(length) serializer = Serializer("json") # TODO: use content-type to determine serialization rev = Tiddler("untitled") # N.B.: Serializations need not contain title. serializer.object = rev serializer.from_string(post_content.decode("utf-8")) query = environ["tiddlyweb.query"] store = environ["tiddlyweb.store"] rev1_id = query.get("rev1", [None])[0] rev2_id = query.get("rev2", [None])[0] try: if not rev1_id: rev1 = rev rev2 = _get_tiddler(rev2_id, store) elif not rev2_id: rev1 = _get_tiddler(rev1_id, store) rev2 = rev else: raise HTTP400("ambiguous request") except AttributeError: raise HTTP400("missing revision parameter") format = query.get("format", [None])[0] content = compare_tiddlers(rev1, rev2, format) return _generate_response(content, environ, start_response)
def test_html_list(): serializer = Serializer('html') recipes = [Recipe('recipe' + str(name)) for name in xrange(2)] string = ''.join(serializer.list_recipes(recipes)) assert 'href="recipes/recipe0' in string assert 'href="recipes/recipe1' in string
def test_bag_to_html(): serializer = Serializer("html") serializer.object = bagfour html = serializer.to_string() assert html == expected_bag_html
def list_tiddlers(self, bag): try: qs = self.environ["tiddlyweb.query"]["j"][0] js = True except KeyError: js = False if not js: try: host = "http://"+self.environ['HTTP_HOST'] refer = self.environ["HTTP_REFERER"] if refer == host or refer == "%s%s"%(host,self.environ['REQUEST_URI']): js = True else: js = False except KeyError: js = False if js: s = Serializer("tiddlywebwiki.serialization",self.environ) return s.list_tiddlers(bag) else: if bag.tiddlers[0] and bag.tiddlers[0].recipe: try: beefcaked_recipe ="beefcaked_"+bag.tiddlers[0].recipe store = self.environ['tiddlyweb.store'] recipe = store.get(Recipe(beefcaked_recipe)) return generate_index(self.environ,self.get_tiddlers_bag_for_recipe(beefcaked_recipe)) except NoRecipeError: return generate_index(self.environ,bag) else: return generate_index(self.environ,bag)
def test_generated_html_with_revbag(): html_serializer = Serializer("html") bagfour.revbag = True string = html_serializer.list_tiddlers(bagfour) assert expected_html_revbag_string in string bagfour.revbag = False
def test_generated_text(): serializer = Serializer("text") serializer.object = recipe string = serializer.to_string() assert string == expected_string assert "%s" % serializer == expected_string
def test_html_list(): serializer = Serializer("html") recipes = [Recipe("recipe" + str(name)) for name in range(2)] string = "".join(serializer.list_recipes(recipes)) assert 'href="recipes/recipe0' in string assert 'href="recipes/recipe1' in string
def test_float_field(): tiddler = Tiddler('foo', 'bar') tiddler.fields['float'] = 100.5 serializer = Serializer('text') serializer.object = tiddler assert '100.5' in '%s' % serializer
def test_text_list(): serializer = Serializer("text") bags = [Bag("bag" + str(name)) for name in xrange(2)] string = serializer.list_bags(bags) assert "bag0" in string assert "bag1" in string
def test_generated_txt_string(): serializer = Serializer('text') serializer.object = tiddler string = serializer.to_string() assert string == expected_string assert '%s' % serializer == expected_string
def test_html_list(): serializer = Serializer('html') bags = [Bag('bag' + str(name)) for name in xrange(2)] string = ''.join(serializer.list_bags(bags)) assert 'href="bags/bag0' in string assert 'href="bags/bag1' in string
def test_generated_html_with_revbag(): html_serializer = Serializer("html") bagfour.revbag = True string = html_serializer.list_tiddlers(bagfour) assert '<li><a href="/bags/bagfour/tiddlers/TiddlerTwo/revisions/0">TiddlerTwo:0</a></li>' in string bagfour.revbag = False
def test_text_list(): serializer = Serializer('text') bags = [Bag('bag' + str(name)) for name in xrange(2)] string = ''.join(serializer.list_bags(bags)) assert 'bag0' in string assert 'bag1' in string
def test_html_list(): serializer = Serializer('html') bags = [Bag('bag' + str(name)) for name in range(2)] string = ''.join(serializer.list_bags(bags)) assert 'href="bags/bag0' in string assert 'href="bags/bag1' in string
def test_text_list(): serializer = Serializer('text') bags = [Bag('bag' + str(name)) for name in range(2)] string = ''.join(serializer.list_bags(bags)) assert 'bag0' in string assert 'bag1' in string
def send_tiddlers(environ, start_response, bag): """ Output the tiddlers contained in the provided bag in a Negotiated representation. Often, but not always, a wiki. """ last_modified = None etag = None bags_tiddlers = bag.list_tiddlers() download = environ['tiddlyweb.query'].get('download', [None])[0] if bags_tiddlers: last_modified, etag = _validate_tiddler_list(environ, bags_tiddlers) else: raise HTTP404('No tiddlers in container') serialize_type, mime_type = get_serialize_type(environ) serializer = Serializer(serialize_type, environ) content_header = ('Content-Type', mime_type) cache_header = ('Cache-Control', 'no-cache') response = [content_header, cache_header] if serialize_type == 'wiki': if download: response.append(('Content-Disposition', 'attachment; filename="%s"' % download)) if last_modified: response.append(last_modified) if etag: response.append(etag) output = serializer.list_tiddlers(bag) start_response("200 OK", response) return [output]
def test_html_list(): serializer = Serializer("html") bags = [Bag("bag" + str(name)) for name in xrange(2)] string = serializer.list_bags(bags) assert 'href="bags/bag0' in string assert 'href="bags/bag1' in string
def send_entity(environ, start_response, entity): """ Send a bag or recipe out HTTP, first serializing to the correct type. If the incoming etag matches, raise 304. """ etag_string = entity_etag(environ, entity) incoming_etag = environ.get('HTTP_IF_NONE_MATCH', None) if incoming_etag: if incoming_etag == etag_string: raise HTTP304(incoming_etag) try: serialize_type, mime_type = get_serialize_type(environ) serializer = Serializer(serialize_type, environ) serializer.object = entity content = serializer.to_string() except NoSerializationError: raise HTTP415('Content type %s not supported' % mime_type) start_response("200 OK", [('Content-Type', mime_type), ('Cache-Control', 'no-cache'), ('ETag', etag_string), ('Vary', 'Accept')]) if isinstance(content, basestring): return [content] else: return content
def _get_tiddler_content(environ, tiddler): """ Extract the content of the tiddler, either straight up if the content is not considered text, or serialized if it is """ config = environ['tiddlyweb.config'] default_serializer = config['default_serializer'] default_serialize_type = config['serializers'][default_serializer][0] serialize_type, mime_type = web.get_serialize_type(environ) extension = environ.get('tiddlyweb.extension') if not renderable(tiddler, environ): if (serialize_type == default_serialize_type or mime_type.startswith(tiddler.type) or extension == 'html'): mime_type = tiddler.type content = tiddler.text return content, mime_type serializer = Serializer(serialize_type, environ) serializer.object = tiddler try: content = serializer.to_string() except (TiddlerFormatError, NoSerializationError), exc: raise HTTP415(exc)
def _process_request_body(environ, tiddler): """ Read request body to set tiddler content. If a serializer exists for the content type, use it, otherwise treat the content as binary or pseudo-binary tiddler. """ length, content_type = content_length_and_type(environ) content = read_request_body(environ, length) try: try: serialize_type = get_serialize_type(environ)[0] serializer = Serializer(serialize_type, environ) # Short circuit de-serialization attempt to avoid # decoding content multiple times. if hasattr(serializer.serialization, 'as_tiddler'): serializer.object = tiddler try: serializer.from_string(content.decode('utf-8')) except TiddlerFormatError as exc: raise HTTP400('unable to put tiddler: %s' % exc) else: raise NoSerializationError() except NoSerializationError: tiddler.type = content_type if pseudo_binary(tiddler.type): tiddler.text = content.decode('utf-8') else: tiddler.text = content except UnicodeDecodeError as exc: raise HTTP400('unable to decode tiddler, utf-8 expected: %s' % exc)
def get(environ, start_response): """ Get a representation in some serialization of a bag (the bag itself not the tiddlers within). """ bag_name = _determine_bag_name(environ) bag_name = web.handle_extension(environ, bag_name) bag = _get_bag(environ, bag_name, True) bag.policy.allows(environ['tiddlyweb.usersign'], 'manage') try: serialize_type, mime_type = web.get_serialize_type(environ) serializer = Serializer(serialize_type, environ) serializer.object = bag content = serializer.to_string() except NoSerializationError: raise HTTP415('Content type not supported: %s' % mime_type) start_response("200 Ok", [('Content-Type', mime_type), ('Vary', 'Accept')]) return [content]
def test_generated_text(): serializer = Serializer('text') serializer.object = recipe string = serializer.to_string() assert string == expected_string assert '%s' % serializer == expected_string
def _get_tiddler_content(environ, tiddler): """ Extract the content of the tiddler, either straight up if the content is not considered text, or serialized if it is. """ config = environ['tiddlyweb.config'] default_serializer = config['default_serializer'] default_serialize_type = config['serializers'][default_serializer][0] serialize_type, mime_type = get_serialize_type(environ) extension = environ.get('tiddlyweb.extension') serialized = False # If this is a tiddler with a CANONICAL_URI_FIELD redirect # there unless we are requesting a json form if (CANONICAL_URI_FIELD in tiddler.fields and not CANONICAL_URI_PASS_TYPE in mime_type): raise HTTP302(tiddler.fields[CANONICAL_URI_FIELD]) if not renderable(tiddler, environ): if (serialize_type == default_serialize_type or mime_type.startswith(tiddler.type) or extension == 'html'): mime_type = tiddler.type content = tiddler.text return content, mime_type, serialized serializer = Serializer(serialize_type, environ) serializer.object = tiddler try: content = serializer.to_string() serialized = True except (TiddlerFormatError, NoSerializationError) as exc: raise HTTP415(exc) return content, mime_type, serialized
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") kept_bags.append(bag) except (UserRequiredError, ForbiddenError): pass try: serialize_type, mime_type = web.get_serialize_type(environ) serializer = Serializer(serialize_type, environ) content = serializer.list_bags(kept_bags) except NoSerializationError: raise HTTP415("Content type not supported: %s" % mime_type) start_response("200 OK", [("Content-Type", mime_type)]) return [content]
def put(environ, start_response): """ Put a bag to the server, meaning the description and policy of the bag, if 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 = environ['CONTENT_LENGTH'] 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 = 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)
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 = 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 = 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)
def put(environ, start_response): """ Put a bag to the server, meaning the description and policy of the bag, if 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, exc: raise HTTP400('unable to put bag: %s' % exc)
def import_plugin(bag, url): """ Import one plugin, at svn url, into bag, retrieving both the .js and .js.meta files. If there is no meta file, then set title and tags to something appropriate before de-serializing. """ meta_url = "%s.meta" % url plugin_content = get_url(url) try: meta_content = _get_url(meta_url) except HTTPError: meta_content = "title: %s\ntags: systemConfig\n" % _strip_extension(url, ".js").split("/")[-1] title = [line for line in meta_content.split("\n") if line.startswith("title:")][0] title = title.split(":", 1)[1].lstrip().rstrip() tiddler_meta = "\n".join([line for line in meta_content.split("\n") if not line.startswith("title:")]) tiddler_meta.rstrip() tiddler_text = "%s\n\n%s" % (tiddler_meta, plugin_content) tiddler = Tiddler(title, bag) serializer = Serializer("text") serializer.object = tiddler serializer.from_string(tiddler_text) _store().put(tiddler)
def test_tiddler_from_json(): serializer = Serializer('json') tiddler = Tiddler('test tiddler') serializer.object = tiddler serializer.from_string(expected_json_string) assert tiddler.title == 'test tiddler' assert tiddler.text == "Hello, I'm the content."
def test_generated_html_with_prefix(): new_config = config.copy() new_config['server_prefix'] = '/salacious' environ = {'tiddlyweb.config': new_config} html_serializer = Serializer('html', environ) string = html_serializer.list_tiddlers(tiddler_collection) assert '<li><a href="/salacious/bags/bagfour/tiddlers/TiddlerOne">TiddlerOne</a></li>' in string
def test_server_etag(): tiddler = Tiddler('Foo', 'Alpha') serializer = Serializer('tiddlywebwiki.serialization', environ) serializer.object = tiddler string = serializer.to_string() tiddler = _extract_tiddler('Foo', string) assert r'''server.etag=""Alpha/Foo/''' in tiddler
def test_tiddler_fields_as_text(): tiddler = Tiddler('feebles', bag='bag0') tiddler = store.get(tiddler) serializer = Serializer('text') serializer.object = tiddler text_of_tiddler = serializer.to_string() assert 'field1: value1\n' in text_of_tiddler assert 'field2: value2\n' in text_of_tiddler
def test_generated_html(): serializer = Serializer('html') recipe.desc = 'Courage of Bags' serializer.object = recipe string = serializer.to_string() assert expected_html_string in string assert expected_html_string in '%s' % serializer
def test_generated_json_string(): serializer = Serializer('json') serializer.object = tiddler string = serializer.to_string() info = simplejson.loads(string) assert info['title'] == 'test tiddler' assert info['text'] == "Hello, I'm the content."
def test_tiddler_html_encode(): serializer = Serializer('html') tiddler = Tiddler('jeremy found a bug') tiddler.bag = u'foo' tiddler.text = u'"Hello." I\'m > than 5 & < you.' serializer.object = tiddler string = serializer.to_string() assert '"Hello." I\'m > than 5 & < you.' in string
def _put(entity, content, serialization): """ Put entity to store, by serializing content using the named serialization. """ serializer = Serializer(serialization) serializer.object = entity serializer.from_string(content) _store().put(entity)
def save_tiddler(store, tiddler): title = tiddler['title'] bag = tiddler['bag'] tiddler_json = simplejson.dumps(tiddler) tid = Tiddler(title) s = Serializer('json') s.object = tid s.from_string(tiddler_json) tid.bag = bag store.put(tid)
def test_tiddler_fields_as_html(): tiddler = Tiddler('feebles', bag='bag0') tiddler = store.get(tiddler) serializer = Serializer('html') serializer.object = tiddler wiki_string = serializer.to_string() assert 'field1="value1"' in wiki_string assert 'field2="value2"' in wiki_string assert 'title="feebles"' in wiki_string
def test_generate_json(): serializer = Serializer('json') bagfour.desc = 'a tasty little bag' bagfour.policy.manage = ['NONE'] serializer.object = bagfour string = serializer.to_string() json = simplejson.loads(string) assert json['policy']['manage'] == ['NONE'] assert json['desc'] == 'a tasty little bag'
def test_generated_html_with_revbag(): html_serializer = Serializer('html') tiddler_collection.is_revisions = True string = html_serializer.list_tiddlers(tiddler_collection) assert ('<li><a href="/bags/bagfour/tiddlers/TiddlerTwo/revisions/1">TiddlerTwo:1</a></li>' in string or '<li><a href="/bags/bagfour/tiddlers/TiddlerTwo/revisions/0">TiddlerTwo:0</a></li>' in string) tiddler_collection.is_revisions = False
def test_generated_text(): serializer = Serializer('text') serializer.object = recipe string = serializer.to_string() assert string == expected_string, \ 'serialized recipe looks like we expect. should be %s, got %s' \ % (expected_string, string) assert '%s' % serializer == expected_string, \ 'serializer goes to string as expected_string'
def test_generated_string_with_revbag(): serializer = Serializer('text') tiddler_collection.is_revisions = True string = ''.join(serializer.list_tiddlers(tiddler_collection)) # XXX: Check for presense of ':'. The value of the revision # changes based on test ordering. assert 'TiddlerOne:' in string assert 'TiddlerTwo:' in string assert 'TiddlerThree:' in string tiddler_collection.is_revisions = False
def _from_text(title, content): """ Generates a tiddler from an RFC822-style string This corresponds to TiddlyWeb's text serialization of TiddlerS. """ tiddler = Tiddler(title) serializer = Serializer('text') serializer.object = tiddler serializer.from_string(content) return tiddler