Example #1
0
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)
Example #2
0
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 from_special(uri, handle, mime=None):
    """
    Import a binary or pseudo binary tiddler. If a mime is provided,
    set the type of the tiddler to that. Otherwise use the type determined
    by the URL handler. If a meta file is present and has a type, it will
    be used.

    This code is inspired by @bengillies bimport.
    """
    title = _get_title_from_uri(uri)
    if mime:
        content_type = mime
    else:
        content_type = handle.headers['content-type'].split(';')[0]
    data = handle.read()

    meta_uri = '%s.meta' % uri
    try:
        meta_content = _get_url(meta_uri)
        tiddler = _from_text(title, meta_content + '\n\n')
    except (HTTPError, URLError, IOError, OSError):
        tiddler = Tiddler(title)

    if not tiddler.type and content_type:
        tiddler.type = content_type

    if pseudo_binary(tiddler.type):
        data = data.decode('utf-8', 'ignore')

    tiddler.text = data

    return tiddler
Example #4
0
def from_special(uri, handle, mime=None):
    """
    Import a binary or pseudo binary tiddler. If a mime is provided,
    set the type of the tiddler to that. Otherwise use the type determined
    by the URL handler. If a meta file is present and has a type, it will
    be used.

    This code is inspired by @bengillies bimport.
    """
    title = _get_title_from_uri(uri)
    if mime:
        content_type = mime
    else:
        content_type = handle.headers['content-type'].split(';')[0]
    data = handle.read()

    meta_uri = '%s.meta' % uri
    try:
        meta_content = _get_url(meta_uri)
        tiddler = _from_text(title, meta_content + '\n\n')
    except (HTTPError, URLError, IOError, OSError):
        tiddler = Tiddler(title)

    if not tiddler.type and content_type:
        tiddler.type = content_type

    if pseudo_binary(tiddler.type):
        data = data.decode('utf-8', 'ignore')

    tiddler.text = data

    return tiddler
Example #5
0
def _send_tiddler(environ, start_response, tiddler):
    """
    Push a single tiddler out the network in the
    form of the chosen serialization.
    """
    store = environ['tiddlyweb.store']

    bag = Bag(tiddler.bag)
    # this will raise 403 if constraint does not pass
    try:
        check_bag_constraint(environ, bag, 'read')
    except NoBagError as exc:
        raise HTTP404('%s not found, no bag %s, %s' %
                (tiddler.title, tiddler.bag, exc))

    try:
        tiddler = store.get(tiddler)
    except NoTiddlerError as exc:
        raise HTTP404('%s not found, %s' % (tiddler.title, exc))

    # this will raise 304
    # have to do this check after we read from the store because
    # we need the revision, which is sad
    last_modified, etag = validate_tiddler_headers(environ, tiddler)

    # make choices between binary or serialization
    content, mime_type, serialized = _get_tiddler_content(environ, tiddler)

    vary_header = ('Vary', 'Accept')
    cache_header = ('Cache-Control', 'no-cache')
    if CACHE_CONTROL_FIELD in tiddler.fields:
        try:
            cache_header = ('Cache-Control', 'max-age=%s'
                    % int(tiddler.fields[CACHE_CONTROL_FIELD]))
        except ValueError:
            pass  # if the value is not an int use default header

    # Add charset to pseudo_binary tiddler
    if not serialized and pseudo_binary(tiddler.type):
        mime_type = '%s; charset=UTF-8' % mime_type
    content_header = ('Content-Type', str(mime_type))

    response = [cache_header, content_header, vary_header]
    if last_modified:
        response.append(last_modified)
    if etag:
        response.append(etag)
    start_response('200 OK', response)

    if isinstance(content, basestring) or isinstance(content, bytes):
        return [content]
    else:
        return content
Example #6
0
def _send_tiddler(environ, start_response, tiddler):
    """
    Push a single tiddler out the network in the
    form of the chosen serialization.
    """
    store = environ['tiddlyweb.store']

    bag = Bag(tiddler.bag)
    # this will raise 403 if constraint does not pass
    try:
        check_bag_constraint(environ, bag, 'read')
    except NoBagError as exc:
        raise HTTP404('%s not found, no bag %s, %s' %
                (tiddler.title, tiddler.bag, exc))

    try:
        tiddler = store.get(tiddler)
    except NoTiddlerError as exc:
        raise HTTP404('%s not found, %s' % (tiddler.title, exc))

    # this will raise 304
    # have to do this check after we read from the store because
    # we need the revision, which is sad
    last_modified, etag = validate_tiddler_headers(environ, tiddler)

    # make choices between binary or serialization
    content, mime_type, serialized = _get_tiddler_content(environ, tiddler)

    vary_header = ('Vary', 'Accept')
    cache_header = ('Cache-Control', 'no-cache')
    if CACHE_CONTROL_FIELD in tiddler.fields:
        try:
            cache_header = ('Cache-Control', 'max-age=%s'
                    % int(tiddler.fields[CACHE_CONTROL_FIELD]))
        except ValueError:
            pass  # if the value is not an int use default header

    # Add charset to pseudo_binary tiddler
    if not serialized and pseudo_binary(tiddler.type):
        mime_type = '%s; charset=UTF-8' % mime_type
    content_header = ('Content-Type', str(mime_type))

    response = [cache_header, content_header, vary_header]
    if last_modified:
        response.append(last_modified)
    if etag:
        response.append(etag)
    start_response('200 OK', response)

    if isinstance(content, basestring) or isinstance(content, bytes):
        return [content]
    else:
        return content
def get_remote_tiddler_html(environ, uri, title):
    """
    Retrieve a webpage as a tiddler. Type comes from
    content-type. Text is set to the body.
    TODO: use response metadata to set other attributes
    """
    response, content = retrieve_remote(uri)
    tiddler = RemoteTiddler(title, uri)
    try:
        content_type = response['content-type'].split(';', 1)[0]
    except KeyError:
        content_type = 'text/html'
    if pseudo_binary(content_type):
        tiddler.text = content.decode('utf-8', 'replace')
    else:
        tiddler.text = content
    tiddler.type = content_type
    return tiddler
Example #8
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 []
Example #9
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 []
Example #10
0
            try:
                # XXX HACK! We don't want to decode content unless
                # the serializer has a as_tiddler. We should be able
                # to just rely on NoSerializationError, but we need
                # to call the method to do that, and to call the method we
                # need to decode the string...
                serialize_type = web.get_serialize_type(environ)[0]
                serializer = Serializer(serialize_type, environ)
                serializer.object = tiddler
                try:
                    serializer.from_string(content.decode('utf-8'))
                except TiddlerFormatError, exc:
                    raise HTTP400('unable to put tiddler: %s' % exc)
            except NoSerializationError:
                tiddler.type = content_type
                if pseudo_binary(tiddler.type):
                    tiddler.text = content.decode('utf-8')
                else:
                    tiddler.text = content
        except UnicodeDecodeError, exc:
            raise HTTP400('unable to decode tiddler, utf-8 expected: %s', exc)

    try:
        recipe_name = web.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))
Example #11
0
            try:
                # XXX HACK! We don't want to decode content unless
                # the serializer has a as_tiddler. We should be able
                # to just rely on NoSerializationError, but we need
                # to call the method to do that, and to call the method we
                # need to decode the string...
                serialize_type = web.get_serialize_type(environ)[0]
                serializer = Serializer(serialize_type, environ)
                serializer.object = tiddler
                try:
                    serializer.from_string(content.decode('utf-8'))
                except TiddlerFormatError, exc:
                    raise HTTP400('unable to put tiddler: %s' % exc)
            except NoSerializationError:
                tiddler.type = content_type
                if pseudo_binary(tiddler.type):
                    tiddler.text = content.decode('utf-8')
                else:
                    tiddler.text = content
        except UnicodeDecodeError, exc:
            raise HTTP400('unable to decode tiddler, utf-8 expected: %s', exc)

    try:
        recipe_name = web.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))
Example #12
0
        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, 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, exc:
        raise HTTP400('unable to decode tiddler, utf-8 expected: %s', exc)


def _check_and_validate_tiddler(environ, bag, tiddler):
    """
    If the tiddler does not exist, check we have create
    in the bag. If the tiddler does exist, check we
    have edit. In either case, check ETag to be sure
    that if it is set, that it maches what is currently
    in the store.
    """