示例#1
0
def add_space_member(environ, start_response):
    """
    Add a member to a space if they are not already a member.
    If they are already a member, nothing happens. If the username
    given does not exist, raise 409. If the space does not exist
    raise 404.
    """
    store = environ['tiddlyweb.store']
    space_name = get_route_value(environ, 'space_name')
    user_name = get_route_value(environ, 'user_name')
    current_user = environ['tiddlyweb.usersign']

    _same_space_required(environ, space_name)

    try:
        change_space_member(store,
                            space_name,
                            add=user_name,
                            current_user=current_user)
    except (NoBagError, NoRecipeError):
        raise HTTP404('space %s does not exist' % space_name)
    except NoUserError:
        raise HTTP409('attempt to add non-existent user: %s' % user_name)

    start_response('204 No Content', [])
    return ['']
示例#2
0
def delete_space_member(environ, start_response):
    """
    Remove a member from a space. If the space does not exist
    raise 404. If the named member is not in the space, do
    nothing.
    """
    store = environ['tiddlyweb.store']
    space_name = get_route_value(environ, 'space_name')
    user_name = get_route_value(environ, 'user_name')
    current_user = environ['tiddlyweb.usersign']

    _same_space_required(environ, space_name)

    try:
        change_space_member(store,
                            space_name,
                            remove=user_name,
                            current_user=current_user)
    except (NoBagError, NoRecipeError):
        raise HTTP404('space %s does not exist' % space_name)
    except NoUserError:
        raise HTTP409('attempt to remove non-member user: %s' % user_name)

    start_response('204 No Content', [])
    return ['']
示例#3
0
文件: tiddler.py 项目: tup/tiddlyweb
def _determine_tiddler(environ, bag_finder, revisions=False):
    """
    Determine, using URL info, the target tiddler.
    This can be complicated because of the mechanics
    of recipes and bags.

    Set revisions to True when the current request ends in
    `/revisions` or `/revisions.*`. Doing so ensures that
    processing of extensions does not impact the name of
    the tiddler.
    """
    tiddler_name = get_route_value(environ, 'tiddler_name')
    tiddler = _base_tiddler_object(environ, tiddler_name, revisions)

    # We have to deserialize the tiddler here so that
    # PUTs to recipes are aware of values like tags when
    # doing filter checks.
    if environ['REQUEST_METHOD'] == 'PUT':
        _process_request_body(environ, tiddler)

    try:
        recipe_name = get_route_value(environ, 'recipe_name')
        recipe = Recipe(recipe_name)
        try:
            store = environ['tiddlyweb.store']
            recipe = store.get(recipe)
            tiddler.recipe = recipe_name
        except NoRecipeError, exc:
            raise HTTP404('%s not found via recipe, %s' % (tiddler.title, exc))

        try:
            bag = bag_finder(recipe, tiddler, environ)
        except NoBagError, exc:
            raise HTTP404('%s not found via bag, %s' % (tiddler.title, exc))
def _get_links(environ, start_response, linktype):
    """
    Form the links as tiddlers and then send them
    to send_tiddlers. This allows us to use the
    serialization and filtering subsystems on the
    lists of links.
    """
    bag_name = get_route_value(environ, 'bag_name')
    tiddler_title = get_route_value(environ, 'tiddler_name')
    store = environ['tiddlyweb.store']
    filters = environ['tiddlyweb.filters']
    collection_title = '%s for %s' % (linktype, tiddler_title)

    link = environ['SCRIPT_NAME']
    try:
        extension = environ['tiddlyweb.extension']
        link = link.rsplit('.%s' % extension)[0]
    except KeyError:
        pass

    host_tiddler = Tiddler(tiddler_title, bag_name)
    try:
        host_tiddler = store.get(host_tiddler)
    except StoreError, exc:
        raise HTTP404('No such tiddler: %s:%s, %s' % (host_tiddler.bag,
            host_tiddler.title, exc))
def bag_tiddler_uri_keys(environ):
    """
    We have a tiddler in a bag URI provide the tiddler key and the bag
    tiddler key.
    """
    bag_name = get_route_value(environ, 'bag_name')
    tiddler_title = get_route_value(environ, 'tiddler_name')
    tiddler = Tiddler(tiddler_title, bag_name)
    return [tiddler_key(tiddler), bag_key(tiddler.bag)]
示例#6
0
def post_revisions(environ, start_response):
    """
    Take a collection of JSON tiddlers, each with a
    text key and value, and process them into the store.
    That collection is known as a TiddlerChronicle.
    """
    tiddler_name = get_route_value(environ, 'tiddler_name')
    bag_name = get_route_value(environ, 'bag_name')
    tiddler = Tiddler(tiddler_name, bag_name)
    return _post_tiddler_revisions(environ, start_response, tiddler)
示例#7
0
def definition(environ, start_response):
    store = environ['tiddlyweb.store']
    manifesto = get_route_value(environ, 'manifesto_name')
    definition = get_route_value(environ, 'definition')

    try:
        recipe = Recipe(manifesto)
        recipe = store.get(recipe)
    except NoRecipeError, exc:
        raise HTTP404('no such manifesto: %s' % exc)
示例#8
0
def post_revisions(environ, start_response):
    """
    Handle a ``POST`` of a chronicle of :py:class:`tiddlers
    <tiddlyweb.model.tiddler.Tiddler>` at a tiddler revisions
    URI.

    Take a collection of ``JSON`` tiddlers, each with a
    text key and value, and process them into the store.
    """
    tiddler_name = get_route_value(environ, 'tiddler_name')
    bag_name = get_route_value(environ, 'bag_name')
    tiddler = Tiddler(tiddler_name, bag_name)
    return _post_tiddler_revisions(environ, start_response, tiddler)
示例#9
0
def post_revisions(environ, start_response):
    """
    Handle a ``POST`` of a chronicle of :py:class:`tiddlers
    <tiddlyweb.model.tiddler.Tiddler>` at a tiddler revisions
    URI.

    Take a collection of ``JSON`` tiddlers, each with a
    text key and value, and process them into the store.
    """
    tiddler_name = get_route_value(environ, 'tiddler_name')
    bag_name = get_route_value(environ, 'bag_name')
    tiddler = Tiddler(tiddler_name, bag_name)
    return _post_tiddler_revisions(environ, start_response, tiddler)
示例#10
0
def recipe_tiddler_uri_keys(environ):
    """
    We have a tiddler in a recipe URI, provide the tiddler and the bag
    tiddler key for all the bags in the recipe.
    """
    store = environ['tiddlyweb.store']
    recipe_name = get_route_value(environ, 'recipe_name')
    tiddler_title = get_route_value(environ, 'tiddler_name')
    recipe = store.get(Recipe(recipe_name))
    tiddler = Tiddler(tiddler_title)
    bag = determine_bag_from_recipe(recipe, tiddler, environ)
    tiddler.bag = bag.name
    return [recipe_key(recipe_name), tiddler_key(tiddler)] + [
            bag_key(bag) for bag, _ in recipe.get_recipe()]
示例#11
0
 def _get_container(self):
     routing_args = self.environ.get('wsgiorg.routing_args', ([], {}))[1]
     container_name = False
     container_type = 'bags'
     if routing_args:
         if 'recipe_name' in routing_args:
             container_name = get_route_value(self.environ, 'recipe_name')
             container_type = 'recipes'
         elif 'bag_name' in routing_args:
             container_name = get_route_value(self.environ, 'bag_name')
     if container_name:
         return "%s/%s" % (container_type, container_name)
     else:
         return ""
示例#12
0
def current_uri_keys(environ):
    """
    Return relevant keys for the current uri based on routing_args and
    and other factors.
    """
    config = environ.get('tiddlyweb.config', {})
    routing_keys = environ['wsgiorg.routing_args'][1]
    request_uri = (environ.get('SCRIPT_NAME', '') +
            environ.get('PATH_INFO', ''))
    fastly_selector = config.get('fastly.selector')

    if _uri_is_global(request_uri):
        return [DISPATCH[request_uri]()]

    route_keys = [route_name for route_name in routing_keys
            if route_name in ROUTE_NAMES]

    surrogate_keys = []

    try:
        if fastly_selector:
            # Find the selector method for this path (if any)
            method = fastly_selector.select(request_uri, 'GET')[0]
            surrogate_keys = method(environ, None)
            if surrogate_keys:
                return surrogate_keys
    except KeyError:
        pass
            
    if len(route_keys) == 1:
        name = route_keys[0]
        if '/tiddlers' not in request_uri:  # recipe or bag
            surrogate_keys = [DISPATCH[name](get_route_value(environ, name))]
        else:  # recipe or bags tiddlers
            if name == 'recipe_name':
                surrogate_keys = recipe_tiddlers_uri_keys(environ)
            elif name == 'bag_name':
                surrogate_keys = [bag_key(get_route_value(
                    environ, name))]
    else:  # a tiddler, revisions collection or single revision
        is_revision = 'revision' in route_keys
        if 'recipe_name' in route_keys:
            surrogate_keys = recipe_tiddler_uri_keys(environ)
        elif 'bag_name' in route_keys:
            if not is_revision:
                surrogate_keys = bag_tiddler_uri_keys(environ)

    return surrogate_keys
示例#13
0
def get_identities(environ, start_response):
    """
    Get a list of the identities associated with the named user.
    That named user must match the current user or the current
    user must be an admin.
    """
    store = environ['tiddlyweb.store']
    username = get_route_value(environ, 'username')
    usersign = environ['tiddlyweb.usersign']['name']
    roles = environ['tiddlyweb.usersign']['roles']

    if username != usersign and 'ADMIN' not in roles:
        raise HTTP403('Bad user for action')

    identities = []
    try:
        mapped_bag = store.get(Bag('MAPUSER'))
        tiddlers = store.list_bag_tiddlers(mapped_bag)
        matched_tiddlers = control.filter_tiddlers(
            tiddlers, 'select=mapped_user:%s' % username, environ)
        identities = [tiddler.title for tiddler in matched_tiddlers]
    except NoBagError:
        pass

    start_response('200 OK',
                   [('Content-Type', 'application/json; charset=UTF-8')])
    return [simplejson.dumps(identities)]
示例#14
0
文件: auth.py 项目: FND/tank
def destroy_key(environ, start_response):
    """
    Remove a key.
    """
    config = environ['tiddlyweb.config']
    store = environ['tiddlyweb.store']
    username = environ['tiddlyweb.usersign']['name']
    bag_name = config.get('oauth.tokens_bag', 'oauth_tokens')
    key_name = get_route_value(environ, 'key_name')

    tiddler = Tiddler(key_name, bag_name)
    try:
        tiddler = store.get(tiddler)
    except NoTiddlerError:
        raise HTTP404('key does not exist')

    if tiddler.modifier != username:
        raise HTTP409('owner mismatch')

    store.delete(tiddler)

    start_response('204 No Content', [
        ('Content-Type', 'text/plain')])

    return []
示例#15
0
def get_identities(environ, start_response):
    """
    Get a list of the identities associated with the named user.
    That named user must match the current user or the current
    user must be an admin.
    """
    store = environ['tiddlyweb.store']
    username = get_route_value(environ, 'username')
    usersign = environ['tiddlyweb.usersign']['name']
    roles = environ['tiddlyweb.usersign']['roles']

    if username != usersign and 'ADMIN' not in roles:
        raise HTTP403('Bad user for action')

    identities = []
    try:
        mapped_bag = store.get(Bag('MAPUSER'))
        tiddlers = store.list_bag_tiddlers(mapped_bag)
        matched_tiddlers = control.filter_tiddlers(tiddlers,
            'select=mapped_user:%s' % username, environ)
        identities = [tiddler.title for tiddler in matched_tiddlers]
    except NoBagError:
        pass

    start_response('200 OK', [
        ('Content-Type', 'application/json; charset=UTF-8')])
    return [simplejson.dumps(identities)]
示例#16
0
文件: __init__.py 项目: cdent/nitor
def record_climbs(environ, start_response):
    """
    Record a climb that has been accomplished.
    """
    query = environ['tiddlyweb.query']
    store = environ['tiddlyweb.store']
    current_user = environ['tiddlyweb.usersign']['name']
    gym = get_route_value(environ, 'gym')

    routes = query['route']
    dones = query['doneroute']
    
    for index, value in enumerate(dones):
        if value != '':
            route_title = routes[index]
            tiddler = Tiddler(route_title, current_user)
            try:
                tiddler = store.get(tiddler)
            except StoreError:
                pass
            if value in CLEAN_CLIMB:
                try:
                    tiddler.tags.remove('tickwish')
                except ValueError:
                    pass
            tiddler.fields['climbtype'] = value
            tiddler.fields['gym'] = gym
            tiddler.tags.append('climb')
            store.put(tiddler)

    raise HTTP303(server_base_url(environ) + environ['REQUEST_URI'])
示例#17
0
文件: __init__.py 项目: cdent/nitor
def make_ticklist(environ, start_response):
    """
    Record routes the user would like to climb.
    """
    store = environ['tiddlyweb.store']
    current_user = environ['tiddlyweb.usersign']['name']
    gym = get_route_value(environ, 'gym')
    tick_wishes = environ['tiddlyweb.query'].get('addroute', [])
    routes = _get_gym_routes(environ, gym)

    for route in routes:
        route.bag = current_user
        if route.title in tick_wishes:
            route.tags = ['tickwish']
            route.fields['gym'] = gym
            store.put(route)
        else:
            try:
                tiddler = store.get(route)
                tiddler.tags.remove('tickwish')
                store.put(tiddler)
            except (StoreError, ValueError):
                pass

    raise HTTP303(server_base_url(environ)
            + '/gyms/%s/ticklist' % encode_name(gym))
示例#18
0
def recent_changes(environ, start_response):
    """
    List recent changes for the named tank.
    """
    tank_name = get_route_value(environ, 'bag_name')
    store = environ['tiddlyweb.store']
    usersign = environ['tiddlyweb.usersign']
    days = environ['tiddlyweb.query'].get('d', [7])[0]

    try:
        bag = store.get(Bag(tank_name))
        bag.policy.allows(usersign, 'read')
    except NoBagError:
        raise HTTP404('no tank found for %s' % tank_name)

    tiddlers = (store.get(tiddler) for tiddler in filter_tiddlers(
        store.list_bag_tiddlers(bag), 'select=modified:>%sd;sort=-modified' %
        days, environ))

    start_response('200 OK', [('Content-Type', 'text/html; charset=UTF-8'),
                              ('Cache-Control', 'no-cache')])
    return send_template(environ, CHANGES_TEMPLATE, {
        'days': days,
        'tiddlers': tiddlers,
        'bag': bag,
    })
示例#19
0
文件: bag.py 项目: FND/tiddlyweb
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

    # 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))
示例#20
0
def get_tiddlers(environ, start_response): # TODO: rename
    config = environ['tiddlyweb.config']

    tags = get_route_value(environ, 'tags')
    tags = csv.reader([tags]).next()

    start_response('200 OK', [('Content-Type', 'text/html; charset=UTF-8')])

    tiddlers = []
    tiddler_ids = []
    for _id, tiddler in commands.get_readable_tagged_tiddlers(environ, tags): # XXX: smell
        tiddlers.append(tiddler)
        tiddler_ids.append(_id)

    yield '<h2 id="tags">Related Tags</h2>\n'
    for tag in commands.get_readable_related_tags(environ, tags, tiddler_ids):
        params = sorted(tags + [tag]) # sorting ensures consistency

        csv_out = StringIO()
        writer = csv.writer(csv_out)
        writer.writerow(params)
        csv_out.seek(0)
        params = csv_out.read().rstrip()

        uri = '/tags/%s' % params # XXX: server prefix & encoding
        yield '<a href="%s">%s</a>\n' % (uri, tag)

    yield '<h2 id="tiddlers">Tiddlers</h2>\n'
    for tiddler in tiddlers:
        uri = '/bags/%s/tiddlers/%s' % (tiddler.bag, tiddler.title) # XXX: server prefix & encoding
        yield '<a href="%s">%s</a>\n' % (uri, tiddler.title)
示例#21
0
文件: bag.py 项目: funkyeah/tiddlyweb
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)
示例#22
0
文件: __init__.py 项目: cdent/nitor
def gym_routes(environ, start_response):
    """
    Display the routes from a single gym.
    """
    store = environ['tiddlyweb.store']
    current_user = environ['tiddlyweb.usersign']['name']
    gym = get_route_value(environ, 'gym')
    routes = _get_gym_routes(environ, gym)
    climbtypes = [tiddler.title for tiddler in
            store.list_bag_tiddlers(Bag(CLIMBTYPES))]
    if current_user:# != 'GUEST':
        search_query = 'bag:%s tag:climb gym:%s _limit:%s' % (current_user,
                gym, len(routes))
        recent_climbs = dict([(tiddler.title, store.get(tiddler))
            for tiddler in store.search(search_query)])
        search_query = 'bag:%s tag:tickwish gym:%s _limit:%s' % (current_user,
                gym, len(routes))
        wished_climbs = [tiddler.title for tiddler in store.search(search_query)]
        for route in routes:
            if route.title in recent_climbs:
                route.fields['climbtype'] = recent_climbs[
                        route.title].fields['climbtype']
            if route.title in wished_climbs:
                route.fields['do'] = True

    return send_template(environ, 'gym_routes.html', {
        'gym': gym,
        'climbtypes': [''] + climbtypes,
        'title': 'Routes @%s' % gym,
        'routes': routes})
示例#23
0
文件: bag.py 项目: tup/tiddlyweb
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)
示例#24
0
文件: wiki.py 项目: pads/tank
def recent_changes(environ, start_response):
    """
    List recent changes for the named tank.
    """
    tank_name = get_route_value(environ, 'bag_name')
    store = environ['tiddlyweb.store']
    usersign = environ['tiddlyweb.usersign']
    config = environ['tiddlyweb.config']
    days = environ['tiddlyweb.query'].get('d', [7])[0]

    try:
        bag = store.get(Bag(tank_name))
        bag.policy.allows(usersign, 'read')
    except NoBagError:
        raise HTTP404('no tank found for %s' % tank_name)

    tiddlers = filter_tiddlers(store.list_bag_tiddlers(bag),
        'select=modified:>%sd;sort=-modified' % days, environ)

    changes_template = get_template(environ, CHANGES_TEMPLATE)
    start_response('200 OK', [
        ('Content-Type', 'text/html; charset=UTF-8'),
        ('Cache-Control', 'no-cache')])
    return changes_template.generate({
        'socket_link': config.get('socket.link'),
        'csrf_token': get_nonce(environ),
        'days': days,
        'tiddlers': tiddlers,
        'bag': bag,
        'gravatar': gravatar(environ),
        'user': usersign['name'],
    })
示例#25
0
 def get_container(environ):
   routing_args = environ.get('wsgiorg.routing_args', ([], {}))[1]
   container_name = False
   container_type = 'bags'
   store = environ['tiddlyweb.store']
   if routing_args:
       if 'recipe_name' in routing_args:
           container_name = get_route_value(self.environ,
               'recipe_name')
           container_type = 'recipes'
       elif 'bag_name' in routing_args:
           container_name = get_route_value(self.environ, 'bag_name')
   if container_name:
       return "%s/%s" % (container_type, container_name)
   else:
       return ""
示例#26
0
文件: bag.py 项目: tup/tiddlyweb
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)
示例#27
0
文件: bag.py 项目: funkyeah/tiddlyweb
def delete(environ, start_response):
    """
    Remove a bag and its tiddlers from the store.
    How the store chooses to handle remove and what
    it means is up to the store.
    """
    bag_name = web.get_route_value(environ, 'bag_name')
    bag_name = web.handle_extension(environ, bag_name)

    usersign = environ['tiddlyweb.usersign']

    bag = _get_bag(environ, bag_name)
    bag.policy.allows(usersign, 'manage')
    # reuse the store attribute that was set on the
    # bag when we "got" it.
    # we don't need to check for existence here because
    # the above get already did
    try:
        store = environ['tiddlyweb.store']
        store.delete(bag)
    except StoreMethodNotImplemented:
        raise HTTP400('Bag DELETE not supported')

    start_response("204 No Content", [])
    return []
示例#28
0
文件: __init__.py 项目: cdent/nitor
def ticklist(environ, start_response):
    """
    Display a user's own ticklist.
    """
    store = environ['tiddlyweb.store']
    current_user = environ['tiddlyweb.usersign']['name']
    gym = get_route_value(environ, 'gym')
    routes = _get_gym_routes(environ, gym)

    climbtypes = [tiddler.title for tiddler in
            store.list_bag_tiddlers(Bag(CLIMBTYPES))]

    search_query = 'bag:%s tag:tickwish gym:%s _limit:%s' % (current_user,
            gym, len(routes))
    wished_climbs = dict([(tiddler.title, store.get(tiddler))
        for tiddler in store.search(search_query)])
    for route in routes:
        if route.title in wished_climbs:
            wished_climbs[route.title].fields['do'] = True

    return send_template(environ, 'gym_routes.html', {
        'gym': gym,
        'climbtypes': [''] + climbtypes,
        'title': 'Ticklist for %s@%s' % (current_user, gym),
        'routes': wished_climbs.values()})
示例#29
0
文件: __init__.py 项目: FND/nitor
def manage_gym(environ, start_response):
    store = environ['tiddlyweb.store']
    gym = get_route_value(environ, 'gym')
    routes_bag = store.get(Bag('%s_climbs' % gym))
    news_bag = Bag('%s_news' % gym)
    # Bail out if we are not allowed to manage. 
    routes_bag.policy.allows(environ['tiddlyweb.usersign'], 'manage')
    gym_tiddler = store.get(Tiddler(gym, GYMS_BAG))

    try:
        latest_news = [tiddler for tiddler in filter_tiddlers(
            store.list_bag_tiddlers(news_bag),
            'sort=-modified;limit=1', environ)][0]
        latest_news = store.get(latest_news)
        news_html = render_wikitext(latest_news, environ)
        latest_news.fields['html'] = news_html
    except IndexError:
        latest_news = Tiddler('tmp')
        latest_news.fields['html'] = '<p>No News</p>'

    routes = _get_gym_routes(environ, gym)

    return send_template(environ, 'manage_gym.html', {
        'title': 'Manage %s' % gym,
        'gym_tiddler': gym_tiddler,
        'latest_news': latest_news,
        'routes': routes})
示例#30
0
文件: bag.py 项目: funkyeah/tiddlyweb
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)
示例#31
0
文件: bag.py 项目: tup/tiddlyweb
def delete(environ, start_response):
    """
    Remove a bag and its tiddlers from the store.
    How the store chooses to handle remove and what
    it means is up to the store.
    """
    bag_name = web.get_route_value(environ, 'bag_name')
    bag_name = web.handle_extension(environ, bag_name)

    usersign = environ['tiddlyweb.usersign']

    bag = _get_bag(environ, bag_name)
    bag.policy.allows(usersign, 'manage')
    # reuse the store attribute that was set on the
    # bag when we "got" it.
    # we don't need to check for existence here because
    # the above get already did
    try:
        store = environ['tiddlyweb.store']
        store.delete(bag)
    except StoreMethodNotImplemented:
        raise HTTP400('Bag DELETE not supported')

    start_response("204 No Content", [])
    return []
示例#32
0
def create_space(environ, start_response):
    """
    Create a space if it does not yet exists. If it does
    raise 409.
    """
    space_name = get_route_value(environ, 'space_name')
    _validate_space_name(environ, space_name)
    return _create_space(environ, start_response, space_name)
示例#33
0
    def list_tiddlers(self, tiddlers):
        """
        If the URL is a list of bag tiddlers, we present a bag
        editing interface. Otherwise we use the parent serialization.
        """
        if (self.environ['wsgiorg.routing_args'][1].get('tiddler_name')):
            return HTMLSerialization.list_tiddlers(self, tiddlers)

        try:
            name = get_route_value(environ, 'bag_name')
            return self._bag_list(tiddlers)
        except KeyError:  # not a bag link
            try:
                name = get_route_value(environ, 'recipe_name')
                return self._recipe_list(tiddlers, name)
            except KeyError:
                return self._bag_list(tiddlers)
示例#34
0
    def list_tiddlers(self, tiddlers):
        """
        If the URL is a list of bag tiddlers, we present a bag
        editing interface. Otherwise we use the parent serialization.
        """
        if (self.environ['wsgiorg.routing_args'][1].get('tiddler_name')):
            return HTMLSerialization.list_tiddlers(self, tiddlers)

        try:
            name = get_route_value(environ, 'bag_name')
            return self._bag_list(tiddlers)
        except KeyError:  # not a bag link
            try:
                name = get_route_value(environ, 'recipe_name')
                return self._recipe_list(tiddlers, name)
            except KeyError:
                return self._bag_list(tiddlers)
示例#35
0
def create_space(environ, start_response):
    """
    Create a space if it does not yet exists. If it does
    raise 409.
    """
    space_name = get_route_value(environ, 'space_name')
    _validate_space_name(environ, space_name)
    return _create_space(environ, start_response, space_name)
示例#36
0
def atom_profile(environ, start_response):
    """
    Send the atom profile, which is actually a search
    for tiddlers modified by the user.
    """
    username = get_route_value(environ, 'username')
    search_string = _search_string(username)
    environ['tiddlyweb.query']['q'] = [search_string]
    return search(environ, start_response)
示例#37
0
def recipe_tiddlers_uri_keys(environ):
    """
    All the tiddlers in the recipe, provide BT of all the bags.
    """
    store = environ['tiddlyweb.store']
    recipe_name = get_route_value(environ, 'recipe_name')
    recipe = store.get(Recipe(recipe_name))
    return [recipe_key(recipe_name)] + [
            bag_key(bag) for bag, _ in recipe.get_recipe()]
示例#38
0
def atom_profile(environ, start_response):
    """
    Send the atom profile, which is actually a search
    for tiddlers modified by the user.
    """
    username = get_route_value(environ, 'username')
    search_string = _search_string(username)
    environ['tiddlyweb.query']['q'] = [search_string]
    return search(environ, start_response)
示例#39
0
文件: __init__.py 项目: FND/nitor
def gym_routes(environ, start_response):
    """
    Display the routes from a single gym.
    """
    gym = get_route_value(environ, 'gym')
    routes = _get_gym_routes(environ, gym)
    return send_template(environ, 'gym_routes.html', {
        'title': 'Routes @%s' % gym,
        'routes': routes})
def _get_links(environ, start_response, linktype):
    """
    Form the links as tiddlers and then send them 
    to send_tiddlers. This allows us to use the 
    serialization and filtering subsystems on the
    lists of links.
    """
    bag_name = get_route_value(environ, 'bag_name')
    tiddler_title = get_route_value(environ, 'tiddler_name')
    store = environ['tiddlyweb.store']
    filters = environ['tiddlyweb.filters']
    title = '%s for %s' % (linktype, tiddler_title)

    tiddler = Tiddler(tiddler_title, bag_name)
    try:
        tiddler = store.get(tiddler)
    except StoreError, exc:
        raise HTTP404('No such tiddler: %s:%s, %s' % (tiddler.bag,
            tiddler.title, exc))
示例#41
0
文件: __init__.py 项目: FND/nitor
def gym_editor(environ, start_response):
    store = environ['tiddlyweb.store']
    gym = get_route_value(environ, 'gym')
    try:
        tiddler = Tiddler(gym, GYMS_BAG)
        tiddler = store.get(tiddler)
    except StoreError:
        pass  # new gym

    return send_template(environ, 'gym_editor.html', {'tiddler': tiddler,
        'title': 'Edit Gym %s' % gym})
示例#42
0
    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'
示例#43
0
def _determine_tiddler(environ, bag_finder, revisions=False):
    """
    Determine, using URL info, the target tiddler.
    This can be complicated because of the mechanics
    of recipes and bags.

    Set revisions to True when the current request ends in
    ``/revisions`` or ``/revisions.*``. Doing so ensures that
    processing of extensions does not impact the name of
    the tiddler.
    """
    tiddler_name = get_route_value(environ, 'tiddler_name')
    tiddler = _base_tiddler_object(environ, tiddler_name, revisions)

    # We have to deserialize the tiddler here so that
    # PUTs to recipes are aware of values like tags when
    # doing filter checks.
    if environ['REQUEST_METHOD'] == 'PUT':
        _process_request_body(environ, tiddler)

    try:
        recipe_name = get_route_value(environ, 'recipe_name')
        recipe = Recipe(recipe_name)
        try:
            store = environ['tiddlyweb.store']
            recipe = store.get(recipe)
            tiddler.recipe = recipe_name
        except NoRecipeError as exc:
            raise HTTP404('%s not found via recipe, %s' % (tiddler.title, exc))

        try:
            bag = bag_finder(recipe, tiddler, environ)
        except NoBagError as exc:
            raise HTTP404('%s not found via bag, %s' % (tiddler.title, exc))

        bag_name = bag.name
    except KeyError:
        bag_name = get_route_value(environ, 'bag_name')

    tiddler.bag = bag_name
    return tiddler
示例#44
0
文件: bag.py 项目: funkyeah/tiddlyweb
def get(environ, start_response):
    """
    Get a representation in some serialization of
    a bag (the bag itself not the tiddlers within).
    """
    bag_name = web.get_route_value(environ, 'bag_name')
    bag_name = web.handle_extension(environ, bag_name)
    bag = _get_bag(environ, bag_name)

    bag.policy.allows(environ['tiddlyweb.usersign'], 'manage')

    return send_entity(environ, start_response, bag)
示例#45
0
def _determine_tiddler(environ, bag_finder):
    """
    Determine, using URL info, the target tiddler.
    This can be complicated because of the mechanics
    of recipes and bags.
    """
    tiddler_name = web.get_route_value(environ, 'tiddler_name')
    try:
        revision = web.get_route_value(environ, 'revision')
        revision = web.handle_extension(environ, revision)
    except KeyError:
        tiddler_name = web.handle_extension(environ, tiddler_name)
        revision = None

    tiddler = Tiddler(tiddler_name)
    if revision:
        try:
            revision = int(revision)
            tiddler.revision = revision
        except ValueError, exc:
            raise HTTP404('%s not a revision of %s: %s' %
                          (revision, tiddler_name, exc))
示例#46
0
def put(environ, start_response):
    """
    Handle ``PUT`` on a single recipe URI.

    Put a :py:class:`recipe <tiddlyweb.model.recipe.Recipe>` to the server,
    meaning the description, policy and recipe list of the recipe,
    if :py:class:`policy <tiddlyweb.model.policy.Policy>` allows.
    """
    recipe_name = web.get_route_value(environ, 'recipe_name')
    recipe_name = web.handle_extension(environ, recipe_name)

    recipe = Recipe(recipe_name)
    store = environ['tiddlyweb.store']
    length, _ = web.content_length_and_type(environ)

    usersign = environ['tiddlyweb.usersign']

    try:
        recipe = store.get(recipe)
        recipe.policy.allows(usersign, 'manage')
    except NoRecipeError:
        create_policy_check(environ, 'recipe', usersign)

    try:
        serialize_type = web.get_serialize_type(environ)[0]
    except TypeError:
        raise HTTP400('Content-type header required')

    try:
        serializer = Serializer(serialize_type, environ)
        serializer.object = recipe
        content = web.read_request_body(environ, length)
        serializer.from_string(content.decode('utf-8'))

        recipe.policy.owner = usersign['name']

        _validate_recipe(environ, recipe)
        store.put(recipe)
    except RecipeFormatError as exc:
        raise HTTP400('unable to put recipe: %s' % exc)
    except TypeError as exc:
        raise HTTP400('malformed input: %s' % exc)
    except NoSerializationError:
        raise HTTP415('Content type %s not supported' % serialize_type)

    start_response("204 No Content",
                   [('Location', web.recipe_url(environ, recipe))])

    return []
示例#47
0
def _determine_recipe(environ):
    """
    Interpret URL information to determine the target
    recipe and then get it from the store.
    """
    recipe_name = web.get_route_value(environ, 'recipe_name')
    recipe_name = web.handle_extension(environ, recipe_name)
    recipe = Recipe(recipe_name)

    store = environ['tiddlyweb.store']

    try:
        recipe = store.get(recipe)
    except NoRecipeError, exc:
        raise HTTP404('%s not found, %s' % (recipe.name, exc))
示例#48
0
def confirm_space(environ, start_response):
    """
    Confirm a spaces exists. If it does, raise 204. If
    not, raise 404.
    """
    store = environ['tiddlyweb.store']
    space_name = get_route_value(environ, 'space_name')
    try:
        space = Space(space_name)
        store.get(Recipe(space.public_recipe()))
        store.get(Recipe(space.private_recipe()))
    except (NoRecipeError, ValueError):
        raise HTTP404('%s does not exist' % space_name)
    start_response('204 No Content', [])
    return ['']
示例#49
0
def subscribe_space(environ, start_response):
    """
    Subscribe and/or unsubscribe the spaces named in the JSON
    content of the request to the space named in the URI. The current
    user must be a member of the space. Raise 409 if the
    JSON is no good. Raise 404 if the space does not exist.
    Raise 409 if a space in the JSON does not exist.
    """
    store = environ['tiddlyweb.store']
    space_name = get_route_value(environ, 'space_name')
    current_user = environ['tiddlyweb.usersign']
    try:
        current_space = Space(space_name)
    except ValueError, exc:
        raise HTTP409('Invalid space name: %s' % exc)
示例#50
0
def get(environ, start_response):
    """
    Handle ``GET`` on a single bag URI.

    Get a representation in some serialization determined by
    :py:mod:`tiddlyweb.web.negotiate` of a :py:class:`bag
    <tiddlyweb.model.bag.Bag>` (the bag itself, not the tiddlers within).
    """
    bag_name = web.get_route_value(environ, 'bag_name')
    bag_name = web.handle_extension(environ, bag_name)
    bag = _get_bag(environ, bag_name)

    bag.policy.allows(environ['tiddlyweb.usersign'], 'manage')

    return send_entity(environ, start_response, bag)
示例#51
0
def _determine_challenger(environ, challenger_name=None):
    """
    Determine which challenger we are using and import it as necessary.
    """
    if challenger_name is None:
        challenger_name = get_route_value(environ, 'challenger')
    # If the challenger is not in config, do a 404, we don't want
    # to import any old code.
    if challenger_name not in environ['tiddlyweb.config']['auth_systems']:
        raise HTTP404('Challenger Not Found')
    try:
        return _get_challenger_module(challenger_name)
    except ImportError as exc:
        raise HTTP404('Unable to import challenger %s: %s' %
                      (challenger_name, exc))
示例#52
0
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 []
示例#53
0
def list_space_members(environ, start_response):
    """
    List the members of the named space. You must be a member
    to list the members.
    """
    store = environ['tiddlyweb.store']
    space_name = get_route_value(environ, 'space_name')
    current_user = environ['tiddlyweb.usersign']
    try:
        space = Space(space_name)
        private_space_bag = store.get(Bag(space.private_bag()))
        private_space_bag.policy.allows(current_user, 'manage')
        members = [
            member for member in private_space_bag.policy.manage
            if not member.startswith('R:')
        ]
    except (ValueError, NoBagError):
        raise HTTP404('No space for %s' % space_name)
    start_response('200 OK',
                   [('Cache-Control', 'no-cache'),
                    ('Content-Type', 'application/json; charset=UTF-8')])
    return simplejson.dumps(members)
示例#54
0
def comp(environ, start_response):
    usersign = environ['tiddlyweb.usersign']
    store = environ['tiddlyweb.store']
    recipe_name = get_route_value(environ, 'recipe_name')

    tiddler = Tiddler('app')

    recipe = Recipe(recipe_name)
    try:
        recipe = store.get(recipe)
        recipe.policy.allows(usersign, 'read')
    except NoRecipeError as exc:
        raise HTTP404('unable to find recipe %s' % recipe_name)

    try:
        bag = determine_bag_from_recipe(recipe, tiddler, environ)
    except NoBagError as exc:
        raise HTTP404('%s not found via bag, %s' % (tiddler.title, exc))

    tiddler.bag = bag.name

    return _send_tiddler(environ, start_response, tiddler)
示例#55
0
def _base_tiddler_object(environ, tiddler_name, revisions):
    """
    Create a tiddler object, without bag or recipe, based on
    URI values.

    ``revisions`` is true when the request is for a revisions
    collection. When true, extension handling is not done on
    the tiddler_name.
    """
    if not revisions:
        try:
            revision = get_route_value(environ, 'revision')
            revision = handle_extension(environ, revision)
        except KeyError:
            tiddler_name = handle_extension(environ, tiddler_name)
            revision = None
    else:
        revision = None

    tiddler = Tiddler(tiddler_name)
    tiddler.revision = revision  # reset to default None if HEAD
    return tiddler
示例#56
0
def closet(environ, start_response):
    """
    Read file input and write it to special storage.
    """
    store = environ['tiddlyweb.store']
    usersign = environ['tiddlyweb.usersign']
    bag_name = get_route_value(environ, 'bag_name')
    redir = environ['tiddlyweb.query'].get('redir', [False])[0]
    target_name = environ['tiddlyweb.query'].get('name', [None])[0]

    bag = store.get(Bag(bag_name))

    bag.policy.allows(usersign, 'create')
    bag.policy.allows(usersign, 'write')

    files = environ['tiddlyweb.input_files']

    if not files:
        raise HTTP400('missing file input')

    tiddlers = []
    for input_file in files:
        if target_name is None:
            target_name = input_file.filename
        if pseudo_binary(input_file.type):
            tiddler = _regular_tiddler(environ, bag_name, input_file,
                                       target_name)
        else:
            tiddler = _binary_tiddler(environ, bag_name, input_file,
                                      target_name)
        tiddlers.append(tiddler)

    response_code = '303 See Other' if redir else '204 No Content'

    start_response(response_code,
                   [('Location', tiddler_url(environ, tiddlers[-1]))])
    return []
示例#57
0
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)
示例#58
0
def put(environ, start_response):
    """
    Put a new recipe to the server.
    """
    recipe_name = web.get_route_value(environ, 'recipe_name')
    recipe_name = web.handle_extension(environ, recipe_name)

    recipe = Recipe(recipe_name)
    store = environ['tiddlyweb.store']
    length = environ['CONTENT_LENGTH']

    usersign = environ['tiddlyweb.usersign']

    try:
        recipe = store.get(recipe)
        recipe.policy.allows(usersign, 'manage')
    except NoRecipeError:
        create_policy_check(environ, 'recipe', usersign)

    try:
        serialize_type = web.get_serialize_type(environ)[0]
    except TypeError:
        raise HTTP400('Content-type header required')

    try:
        serializer = Serializer(serialize_type, environ)
        serializer.object = recipe
        content = environ['wsgi.input'].read(int(length))
        serializer.from_string(content.decode('utf-8'))

        recipe.policy.owner = usersign['name']

        _validate_recipe(environ, recipe)
        store.put(recipe)
    except RecipeFormatError, exc:
        raise HTTP400('unable to put recipe: %s' % exc)
示例#59
0
def destroy_key(environ, start_response):
    """
    Remove a key.
    """
    config = environ['tiddlyweb.config']
    store = environ['tiddlyweb.store']
    username = environ['tiddlyweb.usersign']['name']
    bag_name = config.get('oauth.tokens_bag', 'oauth_tokens')
    key_name = get_route_value(environ, 'key_name')

    tiddler = Tiddler(key_name, bag_name)
    try:
        tiddler = store.get(tiddler)
    except NoTiddlerError:
        raise HTTP404('key does not exist')

    if tiddler.modifier != username:
        raise HTTP409('owner mismatch')

    store.delete(tiddler)

    start_response('204 No Content', [('Content-Type', 'text/plain')])

    return []
示例#60
0
def html_profile(environ, start_response):
    """
    Send the HTML profile, made up for the user's SiteIcon,
    their profile from their space, and their most recently
    modified tiddlers.
    """
    username = get_route_value(environ, 'username')
    usersign = environ['tiddlyweb.usersign']

    store = environ['tiddlyweb.store']

    # Confirm username is a real User
    try:
        store.get(User(username))
    except NoUserError:
        raise HTTP404('Profile not found for %s' % username)

    activity_feed = profile_atom_url(environ, username)

    profile_tiddler = Tiddler('profile', '%s_public' % username)
    try:
        profile_tiddler = store.get(profile_tiddler)
    except StoreError, exc:
        raise HTTP404('No profile for %s: %s' % (username, exc))