Example #1
0
def test_index_query_in_recipe():
    config['indexer'] = 'test.indexernot'

    bag = Bag('noop')
    store.put(bag)
    tiddler = Tiddler('dwell', 'noop')
    store.put(tiddler)

    recipe = Recipe('coolio')
    recipe.set_recipe([('noop', ''), ('fwoop', '')])
    recipe.store = store

    tiddler = Tiddler('swell')
    py.test.raises(ImportError,
                   'determine_bag_from_recipe(recipe, tiddler, environ)')

    config['indexer'] = 'test.indexer'
    bag = determine_bag_from_recipe(recipe, tiddler, environ)
    assert bag.name == 'fwoop'

    tiddler = Tiddler('dwell')
    bag = determine_bag_from_recipe(recipe, tiddler, environ)
    assert bag.name == 'noop'

    tiddler = Tiddler('carnaby')  # nowhere
    py.test.raises(NoBagError,
                   'determine_bag_from_recipe(recipe, tiddler, environ)')
Example #2
0
def test_index_query_in_recipe():
    config['indexer'] = 'test.indexernot'

    bag = Bag('noop')
    store.put(bag)
    tiddler = Tiddler('dwell', 'noop')
    store.put(tiddler)

    recipe = Recipe('coolio')
    recipe.set_recipe([('noop', u''), ('fwoop', u'')])
    recipe.store = store

    tiddler = Tiddler('swell')
    py.test.raises(ImportError,
            'determine_bag_from_recipe(recipe, tiddler, environ)')

    config['indexer'] = 'test.indexer'
    bag = determine_bag_from_recipe(recipe, tiddler, environ)
    assert bag.name == 'fwoop'

    tiddler = Tiddler('dwell')
    bag = determine_bag_from_recipe(recipe, tiddler, environ)
    assert bag.name == 'noop'

    tiddler = Tiddler('carnaby')  # nowhere
    py.test.raises(NoBagError,
            'determine_bag_from_recipe(recipe, tiddler, environ)')
Example #3
0
def _determine_tiddler(environ):
    """
    Inspect the environment to determine which tiddler from which
    bag will provide content for the page named in the URL. If
    the page exists, and we have permission to read the bag in 
    which it is stored, the return the tiddler.

    If we do not have permission, a login interface will be shown.

    If the tiddler does not exist, an empty tiddler with stub
    text will be returned.
    """
    user = environ['tiddlyweb.usersign']
    config = environ['tiddlyweb.config']
    store = environ['tiddlyweb.store']
    recipe = Recipe(_get_recipe(config))
    recipe = store.get(recipe)
    recipe.policy.allows(user, 'read')

    tiddler_name = environ['wsgiorg.routing_args'][1]['tiddler_name']
    tiddler_name = urllib.unquote(tiddler_name)
    tiddler_name = unicode(tiddler_name, 'utf-8')
    tiddler = Tiddler(tiddler_name)

    try:
        bag = control.determine_bag_from_recipe(recipe, tiddler, environ)
        bag.policy.allows(user, 'read')
        tiddler.bag = bag.name
        tiddler = store.get(tiddler)
    except NoBagError, exc:
        # Apparently the tiddler doesn't exist, let's fill in an empty one
        # then.
        tiddler.text = 'That Page does not yet exist.'
        tiddler.type = 'text/x-markdown'
def get(environ, start_response):
    """
    Using query parameters, determine the current tiddler
    and produce an editor for it.
    """
    usersign = environ["tiddlyweb.usersign"]
    try:
        tiddler_name = environ["tiddlyweb.query"].get("tiddler", [""])[0]
        recipe_name = environ["tiddlyweb.query"].get("recipe", [""])[0]
        bag_name = environ["tiddlyweb.query"].get("bag", [""])[0]
    except (KeyError, IndexError):
        raise HTTP400("tiddler, recipe and bag query strings required")

    store = environ["tiddlyweb.store"]

    tiddler = Tiddler(tiddler_name)
    if bag_name:
        tiddler.bag = bag_name
    else:
        recipe = Recipe(recipe_name)
        try:
            recipe = store.get(recipe)
            tiddler.bag = determine_bag_from_recipe(recipe, tiddler).name
            tiddler.recipe = recipe.name
        except NoRecipeError, exc:
            raise HTTP404("unable to edit %s, recipe %s not found: %s" % (tiddler.title, recipe_name, exc))
        except NoBagError, exc:
            raise HTTP404("unable to edit %s: %s" % (tiddler.title, exc))
    def _get_status_tiddler(self, environ, status):
        """
        Load up the tiddler associated with the current status.
        If the tiddler is not present in the recipe, load up
        the tiddler with title 'default'. If that tiddler is
        not present, use DEFAULT_TEXT.
        """
        try:
            tiddler = Tiddler(status)
            store = environ['tiddlyweb.store']
            recipe_name = environ['tiddlyweb.config'].get('prettyerror.recipe',
                    '_errors')
            recipe = Recipe(recipe_name)
            recipe = store.get(recipe)
            bag = determine_bag_from_recipe(recipe, tiddler, environ)
            tiddler.bag = bag.name
            tiddler = store.get(tiddler)
        except (NoRecipeError, NoBagError):
            if status == 'default':
                tiddler.text = DEFAULT_TEXT
            else:
                tiddler = self._get_status_tiddler(environ, 'default')
        except (NoTiddlerError):
            # If there is no default tiddler we get recursion error.
            tiddler = self._get_status_tiddler(environ, 'default')
        except:  # Deal with failures early in the stack
            tiddler.text = DEFAULT_TEXT

        return tiddler
def get_bag_from_recipe(environ, recipe_name, tiddler):
    """
    Check recipe policy, determine which bag this tiddler
    ought to come from, and check that bag's policy too.
    Raises StoreError and PermissionsError.
    """
    store = environ['tiddlyweb.store']
    recipe = store.get(Recipe(recipe_name))
    recipe.policy.allows(environ['tiddlyweb.usersign'], 'read')
    bag = determine_bag_from_recipe(recipe, tiddler, environ)
    bag = store.get(Bag(bag.name))
    bag.policy.allows(environ['tiddlyweb.usersign'], 'read')
    return bag
Example #7
0
def send_template(environ, template_name, template_data=None):
    """
    Set some defaults for a template and send the output.
    """
    if template_data == None:
        template_data = {}
    template = get_template(environ, template_name)

    store = environ['tiddlyweb.store']

    linked_resources = {
        'HtmlCss': ['/bags/common/tiddlers/profile.css'],
        'HtmlJavascript': []
    }

    # Load CSS and JavaScript overrides.
    current_space = determine_space(environ, determine_host(environ)[0])
    if current_space:
        recipe_name = determine_space_recipe(environ, current_space)
        try:
            recipe = store.get(Recipe(recipe_name))
            for title in linked_resources:
                try:
                    tiddler = Tiddler(title)
                    bag = control.determine_bag_from_recipe(
                        recipe, tiddler, environ)
                    tiddler.bag = bag.name
                    try:
                        tiddler = store.get(tiddler)
                        if 'Javascript' in title:
                            urls = tiddler.text.strip().rstrip().split('\n')
                            linked_resources[title] = urls
                        else:
                            url = '/bags/%s/tiddlers/%s' % (encode_name(
                                tiddler.bag), title)
                            linked_resources[title] = [url]
                    except StoreError:
                        continue
                except StoreError:
                    pass
        except StoreError:
            pass

    template_defaults = {
        'original_server_host': original_server_host_url(environ),
        'css': linked_resources['HtmlCss'],
        'js': linked_resources['HtmlJavascript'],
        'server_host': server_base_url(environ),
    }
    template_defaults.update(template_data)
    return template.generate(template_defaults)
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()]
Example #9
0
def send_template(environ, template_name, template_data=None):
    """
    Set some defaults for a template and send the output.
    """
    if template_data == None:
        template_data = {}
    template = get_template(environ, template_name)

    store = environ['tiddlyweb.store']

    linked_resources = {
            'HtmlCss': ['/bags/common/tiddlers/profile.css'],
            'HtmlJavascript': []}

    # Load CSS and JavaScript overrides.
    current_space = determine_space(environ, determine_host(environ)[0])
    if current_space:
        recipe_name = determine_space_recipe(environ, current_space)
        try:
            recipe = store.get(Recipe(recipe_name))
            for title in linked_resources:
                try:
                    tiddler = Tiddler(title)
                    bag = control.determine_bag_from_recipe(recipe,
                            tiddler, environ)
                    tiddler.bag = bag.name
                    try:
                        tiddler = store.get(tiddler)
                        if 'Javascript' in title:
                            urls = tiddler.text.strip().rstrip().split('\n')
                            linked_resources[title] = urls
                        else:
                            url = '/bags/%s/tiddlers/%s' % (encode_name(
                                tiddler.bag), title)
                            linked_resources[title] = [url]
                    except StoreError:
                        continue
                except StoreError:
                    pass
        except StoreError:
            pass

    template_defaults = {
            'original_server_host': original_server_host_url(environ),
            'css': linked_resources['HtmlCss'],
            'js': linked_resources['HtmlJavascript'],
            'server_host': server_base_url(environ),
            }
    template_defaults.update(template_data)
    return template.generate(template_defaults)
Example #10
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)
def _process_for_transclusion(output, tiddler, environ):
    """
    Process the output for transclusions.
    """
    if 'twikified.seen_titles' in environ:
        seen_titles = environ['twikified.seen_titles']
    else:
        seen_titles = []

    parser = html5lib.HTMLParser(
        tree=html5lib.treebuilders.getTreeBuilder("dom"))

    output = output.decode('utf-8', 'replace')
    try:
        dom = parser.parse('<div>' + output + '</div>')
        spans = dom.getElementsByTagName('span')
        for span in spans:
            for attribute in span.attributes.keys():
                if attribute == 'tiddler':
                    attr = span.attributes[attribute]
                    interior_title = attr.value
                    try:
                        span_class = span.attributes['class'].value
                        if span_class.startswith('@'):
                            interior_recipe = span_class[1:] + '_public'
                        else:
                            interior_recipe = ''
                    except KeyError:
                        interior_recipe = ''
                    title_semaphore = '%s:%s' % (interior_title,
                                                 interior_recipe)
                    if title_semaphore not in seen_titles:
                        seen_titles.append(title_semaphore)
                        interior_tiddler = Tiddler(interior_title)
                        try:
                            store = environ['tiddlyweb.store']
                            if interior_recipe:
                                recipe = store.get(Recipe(interior_recipe))
                                interior_tiddler.recipe = interior_recipe
                                interior_tiddler.bag = (
                                    determine_bag_from_recipe(
                                        recipe, interior_tiddler,
                                        environ).name)
                            else:
                                if tiddler.recipe:
                                    interior_tiddler.recipe = tiddler.recipe
                                    recipe = store.get(Recipe(tiddler.recipe))
                                    interior_tiddler.bag = (
                                        determine_bag_from_recipe(
                                            recipe, interior_tiddler,
                                            environ).name)
                                else:
                                    interior_tiddler.bag = tiddler.bag
                            interior_bag = store.get(Bag(interior_tiddler.bag))
                            interior_bag.policy.allows(
                                environ['tiddlyweb.usersign'], 'read')
                            interior_tiddler = store.get(interior_tiddler)
                        except (StoreError, PermissionsError):
                            continue
                        if renderable(interior_tiddler, environ):
                            environ['twikified.seen_titles'] = seen_titles
                            interior_content = render_wikitext(
                                interior_tiddler, environ)
                            interior_dom = parser.parse('<div>' +
                                                        interior_content
                                                        + '</div>')
                            span.appendChild(
                                interior_dom.getElementsByTagName(
                                    'div')[0])

        output = dom.getElementsByTagName('div')[0].toxml()
    except ExpatError, exc:
        # If expat couldn't process the output, we need to make it
        # unicode as what came over the socket was utf-8 but expat
        # needs that in the first place.
        LOGGER.warn('got expat error: %s:%s %s',
                    tiddler.bag, tiddler.title, exc)
        output = output.decode('utf-8', 'replace')
Example #12
0
                    title_semaphore = '%s:%s' % (interior_title, interior_bag)
                    if title_semaphore not in seen_titles:
                        seen_titles.append(title_semaphore)
                        interior_tiddler = Tiddler(interior_title)
                        try:
                            store = environ['tiddlyweb.store']
                            if interior_bag:
                                public_bag = store.get(Bag(interior_bag))
                                public_bag.policy.allows(
                                        environ['tiddlyweb.usersign'], 'read')
                                interior_tiddler.bag = interior_bag
                            else:
                                if tiddler.recipe:
                                    interior_tiddler.recipe = tiddler.recipe
                                    recipe = store.get(Recipe(tiddler.recipe))
                                    interior_tiddler.bag = determine_bag_from_recipe(
                                            recipe, interior_tiddler, environ).name
                                else:
                                    interior_tiddler.bag = tiddler.bag
                            interior_tiddler = store.get(interior_tiddler)
                        except (StoreError, PermissionsError):
                            continue
                        if renderable(interior_tiddler, environ):
                            interior_content = render(interior_tiddler, environ,
                                    seen_titles)
                            interior_dom = parser.parse('<div>' + 
                                    interior_content
                                    + '</div>')
                            span.appendChild(interior_dom.getElementsByTagName('div')[0])

        output = dom.getElementsByTagName('div')[0].toxml()
    except ExpatError, exc:
    for link in links:
        if is_link(link):  # external link
            continue
        else:
            container, title = link.split(':', 1)
            if not title:  # plain space link
                continue
            elif title:
                if container != bag_name:
                    if container.endswith('_public'):
                        try:
                            recipe = Recipe(container)
                            recipe = store.get(recipe)
                            tiddler = Tiddler(title)
                            tiddler.recipe = container
                            bag = determine_bag_from_recipe(recipe, tiddler,
                                    environ)
                            tiddler.bag = bag.name
                        except StoreError, exc:
                            tiddler = Tiddler(title, bag_name)
                            tiddler.recipe = container
                    else:
                        tiddler = Tiddler(title, container)
                else:
                    tiddler = Tiddler(title, bag_name)
                try:
                    tiddler = store.get(tiddler)
                except StoreError:
                    tiddler.store = store
        if _is_readable(environ, tiddler):
            tiddlers.add(tiddler)
Example #14
0
def send_template(environ, template_name, template_data=None):
    """
    Set some defaults for a template and send the output.
    """
    default_css_tiddler = '/bags/common/tiddlers/profile.css'
    if template_data is None:
        template_data = {}
    html_template_prefix = environ['tiddlyweb.space_settings']['htmltemplate']
    if html_template_prefix:
        default_css_tiddler = ('/bags/common/tiddlers/%s.css' %
                               html_template_prefix)
        html_template_prefix += '/'
        try:
            name = html_template_prefix + template_name
            template = get_template(environ, name)
        except TemplateNotFound:
            template = get_template(environ, template_name)
    else:
        template = get_template(environ, template_name)

    store = environ['tiddlyweb.store']

    linked_resources = {'HtmlCss': [], 'HtmlJavascript': []}

    if not html_template_prefix or template_name in CUSTOMIZABLES:
        linked_resources['HtmlCss'] = [default_css_tiddler]
        # Load CSS and JavaScript overrides.
        current_space = determine_space(environ, determine_host(environ)[0])
        if current_space:
            recipe_name = determine_space_recipe(environ, current_space)
            try:
                recipe = store.get(Recipe(recipe_name))
                for title in linked_resources:
                    try:
                        tiddler = Tiddler(title)
                        bag = control.determine_bag_from_recipe(
                            recipe, tiddler, environ)
                        tiddler.bag = bag.name
                        try:
                            tiddler = store.get(tiddler)
                            if 'Javascript' in title:
                                url_content = tiddler.text.strip()
                                if url_content:
                                    urls = url_content.split('\n')
                                    linked_resources[title] = urls
                            else:
                                url = '/bags/%s/tiddlers/%s' % (encode_name(
                                    tiddler.bag), title)
                                linked_resources[title] = [url]
                        except StoreError:
                            continue
                    except StoreError:
                        pass
            except StoreError:
                pass

    template_defaults = {
        'original_server_host': original_server_host_url(environ),
        'css': linked_resources['HtmlCss'],
        'js': linked_resources['HtmlJavascript'],
        'server_host': server_base_url(environ),
    }
    template_defaults.update(template_data)
    return template.generate(template_defaults)
def _process_for_transclusion(output, tiddler, environ):
    """
    Process the output for transclusions.
    """
    if 'twikified.seen_titles' in environ:
        seen_titles = environ['twikified.seen_titles']
    else:
        seen_titles = []

    parser = html5lib.HTMLParser(
        tree=html5lib.treebuilders.getTreeBuilder("dom"))

    output = output.decode('utf-8', 'replace')
    try:
        dom = parser.parse('<div>' + output + '</div>')
        spans = dom.getElementsByTagName('span')
        for span in spans:
            for attribute in span.attributes.keys():
                if attribute == 'tiddler':
                    attr = span.attributes[attribute]
                    interior_title = attr.value
                    try:
                        span_class = span.attributes['class'].value
                        if span_class.startswith('@'):
                            interior_recipe = span_class[1:] + '_public'
                        else:
                            interior_recipe = ''
                    except KeyError:
                        interior_recipe = ''
                    title_semaphore = '%s:%s' % (interior_title,
                                                 interior_recipe)
                    if title_semaphore not in seen_titles:
                        seen_titles.append(title_semaphore)
                        interior_tiddler = Tiddler(interior_title)
                        try:
                            store = environ['tiddlyweb.store']
                            if interior_recipe:
                                recipe = store.get(Recipe(interior_recipe))
                                interior_tiddler.recipe = interior_recipe
                                interior_tiddler.bag = (
                                    determine_bag_from_recipe(
                                        recipe, interior_tiddler,
                                        environ).name)
                            else:
                                if tiddler.recipe:
                                    interior_tiddler.recipe = tiddler.recipe
                                    recipe = store.get(Recipe(tiddler.recipe))
                                    interior_tiddler.bag = (
                                        determine_bag_from_recipe(
                                            recipe, interior_tiddler,
                                            environ).name)
                                else:
                                    interior_tiddler.bag = tiddler.bag
                            interior_bag = store.get(Bag(interior_tiddler.bag))
                            interior_bag.policy.allows(
                                environ['tiddlyweb.usersign'], 'read')
                            interior_tiddler = store.get(interior_tiddler)
                        except (StoreError, PermissionsError):
                            continue
                        if renderable(interior_tiddler, environ):
                            environ['twikified.seen_titles'] = seen_titles
                            interior_content = render_wikitext(
                                interior_tiddler, environ)
                            interior_dom = parser.parse('<div>' +
                                                        interior_content +
                                                        '</div>')
                            span.appendChild(
                                interior_dom.getElementsByTagName('div')[0])

        output = dom.getElementsByTagName('div')[0].toxml()
    except ExpatError, exc:
        # If expat couldn't process the output, we need to make it
        # unicode as what came over the socket was utf-8 but expat
        # needs that in the first place.
        LOGGER.warn('got expat error: %s:%s %s', tiddler.bag, tiddler.title,
                    exc)
        output = output.decode('utf-8', 'replace')
Example #16
0
def send_template(environ, template_name, template_data=None):
    """
    Set some defaults for a template and send the output.
    """
    default_css_tiddler = '/bags/common/tiddlers/profile.css'
    if template_data is None:
        template_data = {}
    html_template_prefix = environ['tiddlyweb.space_settings']['htmltemplate']
    if html_template_prefix:
        default_css_tiddler = ('/bags/common/tiddlers/%s.css' %
                html_template_prefix)
        html_template_prefix += '/'
        try:
            name = html_template_prefix + template_name
            template = get_template(environ, name)
        except TemplateNotFound:
            template = get_template(environ, template_name)
    else:
        template = get_template(environ, template_name)

    store = environ['tiddlyweb.store']

    linked_resources = {
            'HtmlCss': [],
            'HtmlJavascript': []}

    if not html_template_prefix or template_name in CUSTOMIZABLES:
        linked_resources['HtmlCss'] = [default_css_tiddler]
        # Load CSS and JavaScript overrides.
        current_space = determine_space(environ, determine_host(environ)[0])
        if current_space:
            recipe_name = determine_space_recipe(environ, current_space)
            try:
                recipe = store.get(Recipe(recipe_name))
                for title in linked_resources:
                    try:
                        tiddler = Tiddler(title)
                        bag = control.determine_bag_from_recipe(recipe,
                                tiddler, environ)
                        tiddler.bag = bag.name
                        try:
                            tiddler = store.get(tiddler)
                            if 'Javascript' in title:
                                url_content = tiddler.text.strip()
                                if url_content:
                                    urls = url_content.split('\n')
                                    linked_resources[title] = urls
                            else:
                                url = '/bags/%s/tiddlers/%s' % (encode_name(
                                    tiddler.bag), title)
                                linked_resources[title] = [url]
                        except StoreError:
                            continue
                    except StoreError:
                        pass
            except StoreError:
                pass

    template_defaults = {
            'original_server_host': original_server_host_url(environ),
            'css': linked_resources['HtmlCss'],
            'js': linked_resources['HtmlJavascript'],
            'server_host': server_base_url(environ),
    }
    template_defaults.update(template_data)
    return template.generate(template_defaults)
Example #17
0
                    title_semaphore = '%s:%s' % (interior_title, interior_bag)
                    if title_semaphore not in seen_titles:
                        seen_titles.append(title_semaphore)
                        interior_tiddler = Tiddler(interior_title)
                        try:
                            store = environ['tiddlyweb.store']
                            if interior_bag:
                                public_bag = store.get(Bag(interior_bag))
                                public_bag.policy.allows(
                                    environ['tiddlyweb.usersign'], 'read')
                                interior_tiddler.bag = interior_bag
                            else:
                                if tiddler.recipe:
                                    interior_tiddler.recipe = tiddler.recipe
                                    recipe = store.get(Recipe(tiddler.recipe))
                                    interior_tiddler.bag = determine_bag_from_recipe(
                                        recipe, interior_tiddler, environ).name
                                else:
                                    interior_tiddler.bag = tiddler.bag
                            interior_tiddler = store.get(interior_tiddler)
                        except (StoreError, PermissionsError):
                            continue
                        if renderable(interior_tiddler, environ):
                            interior_content = render(interior_tiddler,
                                                      environ, seen_titles)
                            interior_dom = parser.parse('<div>' +
                                                        interior_content +
                                                        '</div>')
                            span.appendChild(
                                interior_dom.getElementsByTagName('div')[0])

        output = dom.getElementsByTagName('div')[0].toxml()