Created
December 7, 2009 15:08
-
-
Save psd/250854 to your computer and use it in GitHub Desktop.
XML TiddlyWeb serializer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
XML TiddlyWeb serializer. | |
""" | |
from tiddlywebplugins.simplerizer import Simplerization as SerializationInterface | |
from tiddlywebplugins.xml.marshaller import dumps, loads | |
__version__ = "0.1" | |
def init(config): | |
# register serializer | |
content_type = "text/xml" | |
config["extension_types"]["xml"] = content_type | |
config["serializers"][content_type] = [__name__, "text/xml; charset=UTF-8"] | |
class Serialization(SerializationInterface): | |
"""Access TiddlyWeb resources using the XML representation.""" | |
def dump(self, object): | |
"""Dump a dictionary object to a XML string.""" | |
return dumps(object) | |
def load(self, input_string): | |
"""Load a dictionary object from a XML string.""" | |
return loads(input_string) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
simple tiddlyweb.xml twinstance | |
$twanager server | |
ERROR: ImportError: No module named marshal | |
addrole: Add a role to an existing user. <username> [role] [role] [role] | |
adduser: Add or update a user to the database: <username> <password> [[role] [role] ...] | |
bag: Create or update a bag with the json text on stdin: <bag> | |
imwiki: Import tiddlers from a Tiddlywiki document into a bag: <bag> <filename> | |
info: Display info about TiddlyWeb. | |
lbags: List all the bags on the system. | |
lrecipes: List all the recipes on the system. | |
ltiddlers: List all the tiddlers on the system. [<bag> <bag> <bag>] to limit. | |
lusers: List all the users on the system | |
recipe: Create or update a recipe with the recipe text on stdin: <recipe> | |
server: Start the server using config settings. Provide <host name or IP number> <port> to override. | |
tiddler: Import a single tiddler into an existing bag from stdin: <bag> <tiddler> | |
twimport: Import one or more plugins, tiddlers or recipes in Cook format: <bag> <URI> | |
update: Update all instance_tiddlers in the current instance. | |
usage: List this help | |
userpass: Change the password of an existing user. <username> <password> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
adjusts module path to account for virtual namespace | |
This is required primarily for testing. | |
""" | |
import sys | |
import os | |
VIRTUAL_NAMESPACE = "tiddlywebplugins" | |
local_package = os.path.abspath(VIRTUAL_NAMESPACE) | |
sys.modules[VIRTUAL_NAMESPACE].__dict__["__path__"].insert(0, local_package) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Specialization of pyxml's marshaling to apply | |
more document style markup and handle Unicode. | |
""" | |
from __future__ import absolute_import | |
import os | |
os.environ['PY_USE_XMLPLUS'] = '1' | |
from xml.marshal import generic | |
class Marshaller(generic.Marshaller): | |
tag_unicode = 'unicode' | |
def m_unicode(self, value, dict): | |
name = self.tag_unicode | |
L = ['<' + name + '>'] | |
s = value.encode('utf-8') | |
if '&' in s or '>' in s or '<' in s: | |
s = s.replace('&', '&') | |
s = s.replace('<', '<') | |
s = s.replace('>', '>') | |
L.append(s) | |
L.append('</' + name + '>') | |
return L | |
class Unmarshaller(generic.Unmarshaller): | |
def __init__(self): | |
self.unmarshal_meth['unicode'] = ('um_start_unicode','um_end_unicode') | |
generic.Unmarshaller.__init__(self) | |
um_start_unicode = generic.Unmarshaller.um_start_generic | |
def um_end_unicode(self, name): | |
ds = self.data_stack | |
ds[-1] = ''.join(ds[-1]) | |
self.accumulating_chars = 0 | |
def dumps(input_string): | |
return Marshaller().dumps(input_string) | |
def loads(object): | |
return Unmarshaller().loads(object) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
TiddlyWeb serializer base class. | |
""" | |
from tiddlyweb.model.bag import Bag | |
from tiddlyweb.model.policy import Policy | |
from tiddlyweb.serializations import SerializationInterface | |
__version__ = "0.1" | |
class Simplerization(SerializationInterface): | |
"""Access TiddlyWeb resources using a generic representation.""" | |
def dump(self, object): | |
"""Dumps a dictionary object to a string.""" | |
raise NoSerializationError | |
def load(self, input_string): | |
"""Loads a dictionary object from a string.""" | |
raise NoSerializationError | |
def __init__(self, environ=None): | |
SerializationInterface.__init__(self, environ) | |
self._bag_perms_cache = {} | |
def list_recipes(self, recipes): | |
"""Creates representation of a list of recipe names.""" | |
return self.dump([recipe.name for recipe in recipes]) | |
def list_bags(self, bags): | |
"""Creates representation of a list of bag names.""" | |
return self.dump([bag.name for bag in bags]) | |
def list_tiddlers(self, bag): | |
"""Creates representation of the list of tiddlers in a bag.""" | |
return self.dump([self._tiddler_dict(tiddler) for | |
tiddler in bag.gen_tiddlers()]) | |
def recipe_as(self, recipe): | |
"""Creates representation of a recipe.""" | |
policy_dict = self._get_policy(recipe) | |
info = dict(desc=recipe.desc, policy=policy_dict, recipe=recipe.get_recipe()) | |
return self.dump(info) | |
def tiddler_as(self, tiddler): | |
tiddler_dict = self._tiddler_dict(tiddler) | |
if (tiddler.type and tiddler.type != 'None' and not | |
tiddler.type.startswith('text/')): | |
tiddler_dict['text'] = b64encode(tiddler.text) | |
else: | |
tiddler_dict['text'] = tiddler.text | |
return self.dump(tiddler_dict) | |
def bag_as(self, bag): | |
"""Creates representation of a bag.""" | |
policy_dict = self._get_policy(bag) | |
info = dict(desc=bag.desc, policy=policy_dict) | |
return self.dump(info) | |
def as_recipe(self, recipe, input_string): | |
"""Creates a recipe from representation.""" | |
info = self.load(input_string) | |
recipe.set_recipe(info.get('recipe', [])) | |
recipe.desc = info.get('desc', '') | |
self._set_policy(info, recipe) | |
return recipe | |
def as_bag(self, bag, input_string): | |
"""Creates a bag from a representation.""" | |
info = self.load(input_string) | |
bag.desc = info.get('desc', '') | |
self._set_policy(info, bag) | |
return bag | |
def as_tiddler(self, tiddler, input_string): | |
"""Creates a tiddler from a representation.""" | |
dict_from_input = self.load(input_string) | |
accepted_keys = ['created', 'modified', 'modifier', 'tags', 'fields', | |
'text', 'type'] | |
for key, value in dict_from_input.iteritems(): | |
if value is not None and key in accepted_keys: | |
setattr(tiddler, key, value) | |
if (tiddler.type and tiddler.type != 'None' and not | |
tiddler.type.startswith('text/')): | |
tiddler.text = b64decode(tiddler.text) | |
return tiddler | |
def _get_policy(self, object): | |
"""Generates a policy dictionary for an object.""" | |
policy = object.policy | |
policy_dict = {} | |
for key in Policy.attributes: | |
policy_dict[key] = getattr(policy, key) | |
return policy_dict | |
def _set_policy(self, info, object): | |
"""Applies a policy dictionary to an object.""" | |
if info.get('policy', {}): | |
object.policy = Policy() | |
for key, value in info['policy'].object(): | |
object.policy.__setattr__(key, value) | |
def _tiddler_dict(self, tiddler): | |
""" | |
Creates a dictionary of header tiddler fields and values | |
under the control of the query_string option 'fat' which | |
when '1' also includes the tiddler content. | |
""" | |
unwanted_keys = ['text', 'store'] | |
wanted_keys = [attribute for attribute in tiddler.slots if | |
attribute not in unwanted_keys] | |
wanted_info = {} | |
for attribute in wanted_keys: | |
wanted_info[attribute] = getattr(tiddler, attribute, None) | |
wanted_info['permissions'] = self._tiddler_permissions(tiddler) | |
try: | |
fat = self.environ['tiddlyweb.query'].get('fat', [None])[0] | |
if fat: | |
wanted_info['text'] = tiddler.text | |
except KeyError: | |
pass # tiddlyweb.query is not there | |
return dict(wanted_info) | |
def _tiddler_permissions(self, tiddler): | |
""" | |
Makes a list of the permissions the current user has | |
to access this tiddler. | |
""" | |
def _read_bag_perms(environ, tiddler): | |
""" | |
Reads the permissions for the bag containing | |
this tiddler. | |
""" | |
perms = [] | |
if 'tiddlyweb.usersign' in environ: | |
store = tiddler.store | |
if store: | |
bag = Bag(tiddler.bag) | |
bag.skinny = True | |
bag = store.get(bag) | |
perms = bag.policy.user_perms( | |
environ['tiddlyweb.usersign']) | |
return perms | |
bag_name = tiddler.bag | |
perms = [] | |
if len(self._bag_perms_cache): | |
if bag_name in self._bag_perms_cache: | |
perms = self._bag_perms_cache[bag_name] | |
else: | |
perms = _read_bag_perms(self.environ, tiddler) | |
self._bag_perms_cache[bag_name] = perms | |
return perms |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A basic configuration. | |
# Run 'pydoc tiddlyweb.config' for details on configuration items. | |
import mangler | |
config = { | |
'system_plugins': ['tiddlywebwiki', 'tiddlywebplugins.status', 'differ', 'tiddlywebplugins.xml'], | |
'secret': '2bb70de5a2817098b4431b2abd6d2cafb7ebd0f3', | |
'twanager_plugins': ['tiddlywebwiki'] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment