Пример #1
0
def get_space_tiddlers(environ, start_response):
    """
    Get the tiddlers that make up the current space in
    whatever the reqeusted representation is. Choose recipe
    based on membership status.
    """
    _setup_friendly_environ(environ)
    _extra_query_update(environ)

    ext = environ.get('tiddlyweb.extension')
    types = environ['tiddlyweb.config']['extension_types']

    # If not a wiki, limit the tiddlers
    if 'text/x-tiddlywiki' not in environ['tiddlyweb.type']:
        # If sort filter not set, sort by -modified
        filter_types = [
            filter[1][0] for filter in environ['tiddlyweb.filters']
        ]
        if 'sort' not in filter_types:
            environ['tiddlyweb.filters'] = parse_for_filters(
                'sort=-modified', environ)[0] + environ['tiddlyweb.filters']

        # Filter out core bags.
        core_bag_filters = []
        for bag in Space.core_bags():
            core_bag_filters.append('select=bag:!%s' % bag)
        core_bag_filters = parse_for_filters(';'.join(core_bag_filters),
                                             environ)[0]
        environ['tiddlyweb.filters'] = (core_bag_filters +
                                        environ['tiddlyweb.filters'])

    if ext and ext not in types:
        environ['wsgiorg.routing_args'][1]['recipe_name'] += '.%s' % ext
    return get_tiddlers(environ, start_response)
Пример #2
0
def get_space_tiddlers(environ, start_response):
    """
    Get the tiddlers that make up the current space in
    whatever the reqeusted representation is. Choose recipe
    based on membership status.
    """
    _setup_friendly_environ(environ)
    _extra_query_update(environ)

    ext = environ.get('tiddlyweb.extension')
    types = environ['tiddlyweb.config']['extension_types']

    # If not a wiki, limit the tiddlers
    if 'text/x-tiddlywiki' not in environ['tiddlyweb.type']:
        # If filters not set, sort by -modified.
        if not environ['tiddlyweb.filters']:
            environ['tiddlyweb.filters'] = parse_for_filters(
                    'sort=-modified', environ)[0]

        # Filter out core bags.
        core_bag_filters = []
        for bag in Space.core_bags():
            core_bag_filters.append('select=bag:!%s' % bag)
        core_bag_filters = parse_for_filters(';'.join(core_bag_filters),
                environ)[0]
        environ['tiddlyweb.filters'].extend(core_bag_filters)

    if ext and ext not in types:
        environ['wsgiorg.routing_args'][1]['recipe_name'] += '.%s' % ext
    return get_tiddlers(environ, start_response)
Пример #3
0
def test_filter_bag_by_filter():
    """
    Confirm a bag will properly filter.
    """
    bagfour = Bag('bagfour')
    store.put(bagfour)
    bagfour.store = store
    for tiddler in tiddlers:
        tiddler.bag = 'bagfour'
        store.put(tiddler)

    filtered_tiddlers = list(control._filter_tiddlers_from_bag(bagfour,
        'select=title:TiddlerOne', environ=environ))
    assert len(filtered_tiddlers) == 1
    assert filtered_tiddlers[0].title == 'TiddlerOne'

    filtered_tiddlers = list(control._filter_tiddlers_from_bag(bagfour,
        'select=tag:tagone', environ=environ))
    assert len(filtered_tiddlers) == 2

    filters, thing = parse_for_filters(
            'select=tag:tagone;select=title:TiddlerThree', environ=environ)
    filtered_tiddlers = list(control._filter_tiddlers_from_bag(bagfour,
        filters, environ=environ))
    assert len(filtered_tiddlers) == 1
    assert filtered_tiddlers[0].title == 'TiddlerThree'
Пример #4
0
def match_related_articles(title, matches, tiddlers): 
    def empty_generator(): return ;yield 'never'
    tiddlers = [tiddler for tiddler in tiddlers]
    try:
        source_tiddler = recursive_filter(parse_for_filters('select=title:%s' % title)[0], tiddlers).next()
    except StopIteration:
        #nothing to match on, so return an empty generator
        return empty_generator()
                         
    sort_set = []
    for tiddler in tiddlers: 
        count = 0
        for match in matches:
            try:
                source = getattr(source_tiddler, match)
                test = getattr(tiddler, match)
                test_func = ATTRIBUTE_SELECTOR.get(match, compare_text)
                count += test_func(source, test)
            except AttributeError:
                count += compare_fields(source_tiddler.fields, tiddler.fields, match)
                            
        if count > 0 and source_tiddler.title != tiddler.title:
            sort_set.append([tiddler,count])
    
    def sort_function(a,b): return cmp(b[1],a[1]) 
    sort_set.sort(sort_function)
    
    result = (tiddler_set[0] for tiddler_set in sort_set)
    
    return result
Пример #5
0
    def extract_query(self, environ):
        """
        Read the ``QUERY_STRING`` and body (if a POSTed form) to extract
        query parameters. Put the results in ``tiddlyweb.query`` in
        environ. The query names and values are decoded from UTF-8 to
        unicode.

        If there are file uploads in posted form data, the files are
        not put into ``tiddlyweb.query``. Instead the file handles are
        appended to ``tiddlyweb.input_files``.
        """
        content_type = environ.get('CONTENT_TYPE', '')
        environ['tiddlyweb.query'] = {}
        environ['tiddlyweb.input_files'] = []
        if _cgi_post(environ, content_type):
            _process_post(environ, content_type)
        filters, leftovers = parse_for_filters(
                environ.get('QUERY_STRING', ''), environ)
        query_data = parse_qs(leftovers, keep_blank_values=True)
        try:
            _update_tiddlyweb_query(environ, query_data, encoded=ENCODED_QUERY)
        except UnicodeDecodeError as exc:
            raise HTTP400(
                    'Invalid encoding in query string, utf-8 required: %s',
                    exc)
        environ['tiddlyweb.filters'] = filters
Пример #6
0
def profile_listing_tiddlers():
    store = Store('text', environ=environ)
    environ['tiddlyweb.store'] = store

    bag = Bag('profiler')
    bag.skinny = True
    store.get(bag)

    print 'filter', time()
    filter_string = 'select=tag:100'
    filters, leftovers = parse_for_filters(filter_string, environ)
    tiddlers = control.filter_tiddlers_from_bag(bag, filters)

    print 'tmp bag', time()
    tmp_bag = Bag('tmp_bag', tmpbag=True)
    tmp_bag.add_tiddlers(tiddlers)

    print 'output', time()
    print[tiddler.title for tiddler in control.get_tiddlers_from_bag(tmp_bag)]

    #print 'serializer', time()
    #serializer = Serializer('wiki', environ)
    #print 'wikify', time()
    #output = serializer.list_tiddlers(tmp_bag)

    print 'done', time()
Пример #7
0
def test_filter_bag_by_filter():
    """
    Confirm a bag will properly filter.
    """

    bagfour = Bag('bagfour')
    store.put(bagfour)
    bagfour.store = store
    for tiddler in tiddlers:
        tiddler.bag = 'bagfour'
        store.put(tiddler)

    filtered_tiddlers = list(
        control._filter_tiddlers_from_bag(bagfour,
                                          'select=title:TiddlerOne',
                                          environ=environ))
    assert len(filtered_tiddlers) == 1
    assert filtered_tiddlers[0].title == 'TiddlerOne'

    filtered_tiddlers = list(
        control._filter_tiddlers_from_bag(bagfour,
                                          'select=tag:tagone',
                                          environ=environ))
    assert len(filtered_tiddlers) == 2

    filters, thing = parse_for_filters(
        'select=tag:tagone;select=title:TiddlerThree', environ=environ)
    filtered_tiddlers = list(
        control._filter_tiddlers_from_bag(bagfour, filters, environ=environ))
    assert len(filtered_tiddlers) == 1
    assert filtered_tiddlers[0].title == 'TiddlerThree'
Пример #8
0
 def generate_html(self, plugin_name, plugins, base_tiddlers):
     """
     recurse through the template stack and generate the HTML on the way back out.
     """
     plugin_html = {}
     if isinstance(plugins, dict):
         for template in plugins:
             recipe_data = plugins[template].split('?', 1)
             recipe = _get_recipe(self.environ, recipe_data[0])
             plugin_tiddlers = control.get_tiddlers_from_recipe(recipe, self.environ)
             if len(recipe_data) == 2:
                 filters = parse_for_filters(recipe_data[1])[0]
                 plugin_tiddlers = recursive_filter(filters, plugin_tiddlers)
             try:
                 plugin_plugins = self.environ['tiddlyweb.config']['tw_pages_serializers'][template]['plugins']
                 plugin_html[template] = self.generate_html(template, plugin_plugins, plugin_tiddlers)
             except KeyError:
                 #there is no plugin by that name, so try a (non TiddlyWebPages) serializer instead
                 plugin_html[template] = self.pass_through_external_serializer(template, plugin_tiddlers)
     server_prefix = self.get_server_prefix()
     try:
         self.template.set_template(plugin_name)
         content = self.template.render(tiddlers=base_tiddlers, extra=plugin_html, prefix=server_prefix, query=self.query, root_vars=self.environ['tiddlyweb.recipe_template'])
     except KeyError:
         content = self.pass_through_external_serializer(plugin_name, base_tiddlers)
     return content
Пример #9
0
    def extract_query(self, environ):
        """
        Read the ``QUERY_STRING`` and body (if a POSTed form) to extract
        query parameters. Put the results in ``tiddlyweb.query`` in
        environ. The query names and values are decoded from UTF-8 to
        unicode.

        If there are file uploads in posted form data, the files are
        not put into ``tiddlyweb.query``. Instead the file handles are
        appended to ``tiddlyweb.input_files``.
        """
        content_type = environ.get('CONTENT_TYPE', '')
        environ['tiddlyweb.query'] = {}
        environ['tiddlyweb.input_files'] = []
        if _cgi_post(environ, content_type):
            _process_post(environ, content_type)
        filters, leftovers = parse_for_filters(environ.get('QUERY_STRING', ''),
                                               environ)
        query_data = parse_qs(leftovers, keep_blank_values=True)
        try:
            _update_tiddlyweb_query(environ, query_data, encoded=ENCODED_QUERY)
        except UnicodeDecodeError as exc:
            raise HTTP400(
                'Invalid encoding in query string, utf-8 required: %s', exc)
        environ['tiddlyweb.filters'] = filters
Пример #10
0
    def list_tiddlers(self, tiddlers):
        """
        Turn the contents of a Tiddlers into an Atom Feed.
        """

        authors = set()
        try:
            from tiddlyweb.model.collections import Tiddlers
            config = self.environ['tiddlyweb.config']
            default_filter = config['atom.default_filter']
            filters, _ = parse_for_filters(default_filter, self.environ)
            new_tiddlers = Tiddlers()
            new_tiddlers.is_search = tiddlers.is_search
            new_tiddlers.is_revisions = tiddlers.is_revisions
            new_tiddlers.bag = tiddlers.bag
            new_tiddlers.recipe = tiddlers.recipe
            new_tiddlers.link = tiddlers.link
            for tiddler in recursive_filter(filters, tiddlers):
                new_tiddlers.add(tiddler)
                authors.add(tiddler.modifier)
            new_tiddlers.title = tiddlers.title
            new_tiddlers.is_search = tiddlers.is_search
            new_tiddlers.is_revisions = tiddlers.is_revisions
            tiddlers = new_tiddlers
        except (KeyError, ImportError):
            pass

        author_name = None
        author_link = None
        author_avatar = None
        if len(authors) == 1:
            author_name = authors.pop()
            author_link = self._get_author_link(author_name)
            author_avatar = self._get_author_avatar(author_name)

        hub = self.environ.get('tiddlyweb.config', {}).get('atom.hub', None)

        if tiddlers.link:
            link = tiddlers.link
        else:
            link = self._current_url()
        if not link.startswith('http'):
            link = u'%s%s' % (self._host_url(), link)

        feed = AtomFeed(link=link,
            language=u'en',
            hub=hub,
            author_name=author_name,
            author_link=author_link,
            author_avatar=author_avatar,
            title=tiddlers.title,
            description=tiddlers.title)

        for tiddler in tiddlers:
            self._add_tiddler_to_feed(feed, tiddler)

        # can we avoid sending utf-8 and let the wrapper handle it?
        return feed.writeString('utf-8')
Пример #11
0
def filter_tiddlers(tiddlers, filters, environ=None):
    """
    Return a generator of tiddlers resulting from filtering the provided
    iterator of tiddlers by the provided filters.

    If filters is a string, it will be parsed for filters.
    """
    if isinstance(filters, basestring):
        filters, _ = parse_for_filters(filters, environ)
    return recursive_filter(filters, tiddlers)
Пример #12
0
def filter_tiddlers(tiddlers, filters, environ=None):
    """
    Return a generator of tiddlers resulting from filtering the provided
    iterator of tiddlers by the provided filters.

    If filters is a string, it will be parsed for filters.
    """
    if isinstance(filters, basestring):
        filters, _ = parse_for_filters(filters, environ)
    return recursive_filter(filters, tiddlers)
Пример #13
0
def _filter_tiddlers_from_bag(bag, filters, environ=None):
    """
    Return the list of tiddlers resulting from filtering bag by filter.
    The filter is a string that will be parsed to a list of filters.
    """
    indexable = bag

    if isinstance(filters, basestring):
        filters, _ = parse_for_filters(filters, environ)
    return recursive_filter(filters, bag.store.list_bag_tiddlers(bag), indexable=indexable)
Пример #14
0
def _filter_tiddlers_from_bag(bag, filters, environ=None):
    """
    Return the list of tiddlers resulting from filtering bag by filter.
    The filter is a string that will be parsed to a list of filters.
    """
    indexable = bag

    if isinstance(filters, basestring):
        filters, _ = parse_for_filters(filters, environ)
    return recursive_filter(filters, bag.store.list_bag_tiddlers(bag),
            indexable=indexable)
Пример #15
0
 def extract_query(self, environ):
     content_type = environ.get('CONTENT_TYPE', '')
     environ['tiddlyweb.query'] = {}
     if environ['REQUEST_METHOD'].upper() == 'POST' and \
             content_type.startswith('application/x-www-form-urlencoded'):
         length = environ['CONTENT_LENGTH']
         content = environ['wsgi.input'].read(int(length))
         posted_data = cgi.parse_qs(content)
         environ['tiddlyweb.query'].update(posted_data)
     filters, leftovers = parse_for_filters(environ.get('QUERY_STRING', ''))
     environ['tiddlyweb.query'].update(cgi.parse_qs(leftovers))
     environ['tiddlyweb.filters'] = filters
Пример #16
0
def _extra_query_update(environ):
    """
    If extra_query is set via ServerSettings, then process that
    information as query strings and filters.
    """
    extra_query = environ['tiddlyweb.space_settings']['extra_query']
    if extra_query:
        filters, leftovers = parse_for_filters(extra_query, environ)
        environ['tiddlyweb.filters'].extend(filters)
        query_data = parse_qs(leftovers, keep_blank_values=True)
        environ['tiddlyweb.query'].update(
            dict([(key, [value for value in values])
                  for key, values in query_data.items()]))
Пример #17
0
def _extra_query_update(environ):
    """
    If extra_query is set via ServerSettings, then process that
    information as query strings and filters.
    """
    extra_query = environ['tiddlyweb.space_settings']['extra_query']
    if extra_query:
        filters, leftovers = parse_for_filters(extra_query, environ)
        environ['tiddlyweb.filters'].extend(filters)
        query_data = parse_qs(leftovers, keep_blank_values=True)
        environ['tiddlyweb.query'].update(dict(
            [(key, [value for value in values])
                for key, values in query_data.items()]))
Пример #18
0
def profile_listing_tiddlers():
    store = Store('text', environ['tiddlyweb.config']['server_store'][1], environ)
    environ['tiddlyweb.store'] = store

    bag = Bag('profiler')

    print 'filter', time()
    filter_string = 'select=tag:1'
    filters, leftovers = parse_for_filters(filter_string, environ)
    tiddlers = control.filter_tiddlers(store.list_bag_tiddlers(bag), filters, environ=environ)

    print 'output', time()
    print [tiddler.title for tiddler in tiddlers]
Пример #19
0
def update_space_settings(environ, name):
    """
    Read a tiddler named by SPACE_SERVER_SETTINGS in the current
    space's public bag. Parse each line as a key:value pair which
    is then injected tiddlyweb.query. The goal here is to allow
    a space member to force incoming requests to use specific
    settings, such as alpha or externalized.
    """
    store = environ['tiddlyweb.store']
    space = Space(name)
    bag_name = space.public_bag()
    tiddler = Tiddler(SPACE_SERVER_SETTINGS, bag_name)
    data_text = ''
    try:
        tiddler = store.get(tiddler)
        data_text = tiddler.text
    except StoreError:
        return _figure_default_index(environ, bag_name, space), False

    query_strings = []
    index = ''
    lazy = False
    for line in data_text.split('\n'):
        try:
            key, value = line.split(':', 1)
            key = key.rstrip().lstrip()
            value = value.rstrip().lstrip()
            if key == 'index':
                index = value
            elif key == 'lazy':
                if value.lower() == 'true':
                    lazy = True
            else:
                query_strings.append('%s=%s' % (key, value))
        except ValueError:
            pass

    index = _figure_default_index(environ, bag_name, space, index)

    query_string = ';'.join(query_strings)

    filters, leftovers = parse_for_filters(query_string, environ)
    environ['tiddlyweb.filters'].extend(filters)
    query_data = parse_qs(leftovers, keep_blank_values=True)
    environ['tiddlyweb.query'].update(
        dict([(key, [value for value in values])
              for key, values in query_data.items()]))

    return index, lazy
Пример #20
0
def update_space_settings(environ, name):
    """
    Read a tiddler named by SPACE_SERVER_SETTINGS in the current
    space's public bag. Parse each line as a key:value pair which
    is then injected tiddlyweb.query. The goal here is to allow
    a space member to force incoming requests to use specific
    settings, such as alpha or externalized.
    """
    store = environ['tiddlyweb.store']
    space = Space(name)
    bag_name = space.public_bag()
    tiddler = Tiddler(SPACE_SERVER_SETTINGS, bag_name)
    data_text = ''
    try:
        tiddler = store.get(tiddler)
        data_text = tiddler.text
    except StoreError:
        return _figure_default_index(environ, bag_name, space), False

    query_strings = []
    index = ''
    lazy = False
    for line in data_text.split('\n'):
        try:
            key, value = line.split(':', 1)
            key = key.rstrip().lstrip()
            value = value.rstrip().lstrip()
            if key == 'index':
                index = value
            elif key == 'lazy':
                if value.lower() == 'true':
                    lazy = True
            else:
                query_strings.append('%s=%s' % (key, value))
        except ValueError:
            pass

    index = _figure_default_index(environ, bag_name, space, index)

    query_string = ';'.join(query_strings)

    filters, leftovers = parse_for_filters(query_string, environ)
    environ['tiddlyweb.filters'].extend(filters)
    query_data = parse_qs(leftovers, keep_blank_values=True)
    environ['tiddlyweb.query'].update(dict(
        [(key, [value for value in values])
            for key, values in query_data.items()]))

    return index, lazy
Пример #21
0
def filter_tiddlers_from_bag(bag, filters):
    """
    Return the list of tiddlers resulting from filtering
    bag by filter. The filter is a string that will be
    parsed to a list of filters.
    """
    store = bag.store

    # XXX isinstance considered harmful
    if isinstance(filters, basestring):
        filters, leftovers = parse_for_filters(filters)
    if store:
        return recursive_filter(filters, get_tiddlers_from_bag(bag))
    else:
        return recursive_filter(filters, bag.list_tiddlers())
Пример #22
0
 def extract_query(self, environ):
     """
     Read the QUERY_STRING and body (if a POSTed form) to extract
     query paremeters. Put the results in tiddlyweb.query.
     """
     content_type = environ.get('CONTENT_TYPE', '')
     environ['tiddlyweb.query'] = {}
     if environ['REQUEST_METHOD'].upper() == 'POST' and \
             content_type.startswith('application/x-www-form-urlencoded'):
         length = environ['CONTENT_LENGTH']
         content = environ['wsgi.input'].read(int(length))
         posted_data = parse_qs(content, keep_blank_values=True)
         _update_tiddlyweb_query(environ, posted_data)
     filters, leftovers = parse_for_filters(environ.get('QUERY_STRING', ''), environ)
     query_data = parse_qs(leftovers, keep_blank_values=True)
     _update_tiddlyweb_query(environ, query_data)
     environ['tiddlyweb.filters'] = filters
Пример #23
0
def test_filter_bag_by_filter():
    """
    Confirm a bag will properly filter.
    """

    filtered_tiddlers = control.filter_tiddlers_from_bag(bagfour, 'select=title:TiddlerOne')

    assert len(filtered_tiddlers) == 1
    assert filtered_tiddlers[0].title == 'TiddlerOne'

    filtered_tiddlers = control.filter_tiddlers_from_bag(bagfour, 'select=tag:tagone')
    assert len(filtered_tiddlers) == 2

    filters, thing = parse_for_filters('select=tag:tagone;select=title:TiddlerThree')
    filtered_tiddlers = control.filter_tiddlers_from_bag(bagfour, filters)
    assert len(filtered_tiddlers) == 1
    assert filtered_tiddlers[0].title == 'TiddlerThree'
Пример #24
0
 def extract_query(self, environ):
     """
     Read the QUERY_STRING and body (if a POSTed form) to extract
     query paremeters. Put the results in tiddlyweb.query.
     """
     content_type = environ.get('CONTENT_TYPE', '')
     environ['tiddlyweb.query'] = {}
     if environ['REQUEST_METHOD'].upper() == 'POST' and \
             content_type.startswith('application/x-www-form-urlencoded'):
         length = environ['CONTENT_LENGTH']
         content = environ['wsgi.input'].read(int(length))
         posted_data = parse_qs(content, keep_blank_values=True)
         _update_tiddlyweb_query(environ, posted_data)
     filters, leftovers = parse_for_filters(environ.get('QUERY_STRING', ''),
                                            environ)
     query_data = parse_qs(leftovers, keep_blank_values=True)
     _update_tiddlyweb_query(environ, query_data)
     environ['tiddlyweb.filters'] = filters
Пример #25
0
def geo_near_tiddlers(lat, lng, radius, tiddlers, units="kms"):
    # create bounding box around
    if units == "miles":
        degrees = radius / SINGLE_DEG_AT_ZERO_ZERO_IN_MILES
    elif units == "kms":
        degrees = radius / SINGLE_DEG_AT_ZERO_ZERO_IN_KMS
    else:
        raise "unknown unit type: please use kms or miles"
    lat1 = lat - degrees
    lat2 = lat + degrees
    lng1 = lng - degrees
    lng2 = lng + degrees
    filter_string = "select=field:%s&select=field:%s&select=%s:>%s&select=%s:<%s&select=%s:>%s&select=%s:<%s" % (
        LONGITUDE_FIELD,
        LATITUDE_FIELD,
        LATITUDE_FIELD,
        lat1,
        LATITUDE_FIELD,
        lat2,
        LONGITUDE_FIELD,
        lng1,
        LONGITUDE_FIELD,
        lng2,
    )
    logging.debug("filter string lt gt %s" % filter_string)
    filtered_sample = list(filters.recursive_filter(filters.parse_for_filters(filter_string)[0], tiddlers))
    near_tiddlers = []
    for tiddler in filtered_sample:
        testlat = tiddler.fields[LATITUDE_FIELD]
        testlng = tiddler.fields[LONGITUDE_FIELD]
        if testlat and testlng:

            try:
                testlat = float(testlat)
                testlng = float(testlng)
                isNear = geoproximity(lat, lng, radius, testlat, testlng, units=units)
                if isNear[0]:
                    tiddler.fields["_geo.proximity"] = "%.2f" % isNear[1]
                    yield tiddler
            except ValueError:
                # ignore tiddlers which have an empty string for this value
                pass
    return
Пример #26
0
def profile_listing_tiddlers():
    store = Store('text', environ=environ)
    environ['tiddlyweb.store'] = store

    bag = Bag('profiler')
    bag.skinny = True
    store.get(bag)

    print 'filter', time()
    filter_string = 'select=tag:100'
    filters, leftovers = parse_for_filters(filter_string, environ)
    tiddlers = control.filter_tiddlers_from_bag(bag, filters)

    print 'tmp bag', time()
    tmp_bag = Bag('tmp_bag', tmpbag=True)
    tmp_bag.add_tiddlers(tiddlers)

    print 'output', time()
    print [tiddler.title for tiddler in control.get_tiddlers_from_bag(tmp_bag)]
Пример #27
0
def figure_filters(filters, custom_filters):
    """
    figure out the filters that have been added to the query
    string and match them with filters in the destination. 
    
    Override any that match.
    
    return a list of filter functions
    """
    if custom_filters:
        custom_filters = parse_for_filters(custom_filters)[0]
        #strip duplicate filters
        user_filters = [user_filter[1][0] for user_filter in filters]
        result_filters = [custom_filter for custom_filter in custom_filters \
            if custom_filter[1][0] not in user_filters]
        if len(filters) > 0:
            result_filters.extend(filters)
        return result_filters
    return filters
Пример #28
0
def filter_tiddlers_from_bag(bag, filters):
    """
    Return the list of tiddlers resulting from filtering
    bag by filter. The filter is a string that will be
    parsed to a list of filters.
    """
    store = bag.store

    if bag.tmpbag or bag.revbag or bag.searchbag:
        indexable = False
    else:
        indexable = bag

    # XXX isinstance considered harmful
    if isinstance(filters, basestring):
        filters, leftovers = parse_for_filters(filters)
    if store:
        return recursive_filter(filters, get_tiddlers_from_bag(bag), indexable=indexable)
    else:
        return recursive_filter(filters, bag.gen_tiddlers(), indexable=indexable)
 def generate_html(self, plugin_name, plugins, base_tiddlers):
     """
     recurse through the template stack and generate the HTML on the way back out.
     """
     plugin_html = {}
     if isinstance(plugins, dict):
         for template in plugins:
             recipe_data = plugins[template].split('?', 1)
             recipe = _get_recipe(self.environ, recipe_data[0])
             plugin_tiddlers = control.get_tiddlers_from_recipe(
                 recipe, self.environ)
             if len(recipe_data) == 2:
                 filters = parse_for_filters(recipe_data[1])[0]
                 plugin_tiddlers = recursive_filter(filters,
                                                    plugin_tiddlers)
             try:
                 plugin_plugins = self.environ['tiddlyweb.config'][
                     'tw_pages_serializers'][template]['plugins']
                 plugin_html[template] = self.generate_html(
                     template, plugin_plugins, plugin_tiddlers)
             except KeyError:
                 #there is no plugin by that name, so try a (non TiddlyWebPages) serializer instead
                 plugin_html[
                     template] = self.pass_through_external_serializer(
                         template, plugin_tiddlers)
     server_prefix = self.get_server_prefix()
     try:
         self.template.set_template(plugin_name)
         content = self.template.render(
             tiddlers=base_tiddlers,
             extra=plugin_html,
             prefix=server_prefix,
             query=self.query,
             root_vars=self.environ['tiddlyweb.recipe_template'])
     except KeyError:
         content = self.pass_through_external_serializer(
             plugin_name, base_tiddlers)
     return content
Пример #30
0
def profile_listing_tiddlers():
    store = Store('text', environ['tiddlyweb.config']['server_store'][1],
                  environ)
    environ['tiddlyweb.store'] = store

    bag = Bag('profiler')

    print 'filter', time()
    filter_string = 'select=tag:1'
    filters, leftovers = parse_for_filters(filter_string, environ)
    tiddlers = control.filter_tiddlers(store.list_bag_tiddlers(bag),
                                       filters,
                                       environ=environ)

    print 'output', time()
    print[tiddler.title for tiddler in tiddlers]

    #print 'serializer', time()
    #serializer = Serializer('wiki', environ)
    #print 'wikify', time()
    #output = serializer.list_tiddlers(tmp_bag)

    print 'done', time()
Пример #31
0
def match_related_articles(title, matches, tiddlers):
    def empty_generator():
        return
        yield 'never'

    tiddlers = [tiddler for tiddler in tiddlers]
    try:
        source_tiddler = recursive_filter(
            parse_for_filters('select=title:%s' % title)[0], tiddlers).next()
    except StopIteration:
        #nothing to match on, so return an empty generator
        return empty_generator()

    sort_set = []
    for tiddler in tiddlers:
        count = 0
        for match in matches:
            try:
                source = getattr(source_tiddler, match)
                test = getattr(tiddler, match)
                test_func = ATTRIBUTE_SELECTOR.get(match, compare_text)
                count += test_func(source, test)
            except AttributeError:
                count += compare_fields(source_tiddler.fields, tiddler.fields,
                                        match)

        if count > 0 and source_tiddler.title != tiddler.title:
            sort_set.append([tiddler, count])

    def sort_function(a, b):
        return cmp(b[1], a[1])

    sort_set.sort(sort_function)

    result = (tiddler_set[0] for tiddler_set in sort_set)

    return result
Пример #32
0
 def extract_query(self, environ):
     """
     Read the ``QUERY_STRING`` and body (if a POSTed form) to extract
     query parameters. Put the results in ``tiddlyweb.query`` in
     environ. The query names and values are decoded from UTF-8 to
     unicode.
     """
     content_type = environ.get('CONTENT_TYPE', '')
     environ['tiddlyweb.query'] = {}
     if environ['REQUEST_METHOD'].upper() == 'POST' and \
             content_type.startswith('application/x-www-form-urlencoded'):
         try:
             try:
                 length = environ['CONTENT_LENGTH']
                 content = read_request_body(environ, length)
                 if not ENCODED_QUERY:
                     content = content.decode('UTF-8')
             except KeyError as exc:
                 raise HTTP400('Invalid post, unable to read content: %s'
                         % exc)
             posted_data = parse_qs(content, keep_blank_values=True)
             _update_tiddlyweb_query(environ, posted_data,
                     encoded=ENCODED_QUERY)
         except UnicodeDecodeError as exc:
             raise HTTP400(
                     'Invalid encoding in query data, utf-8 required: %s',
                     exc)
     filters, leftovers = parse_for_filters(
             environ.get('QUERY_STRING', ''), environ)
     query_data = parse_qs(leftovers, keep_blank_values=True)
     try:
         _update_tiddlyweb_query(environ, query_data, encoded=ENCODED_QUERY)
     except UnicodeDecodeError as exc:
         raise HTTP400(
                 'Invalid encoding in query string, utf-8 required: %s',
                 exc)
     environ['tiddlyweb.filters'] = filters
Пример #33
0
def test_exception():
    filter, _ = parse_for_filters('limit=-1,2')
    with py.test.raises(FilterError):
        recursive_filter(filter, tiddlers)
Пример #34
0
    def _handle_core_request(self, environ, req_uri):
        """
        Override a core request, adding filters or sending 404s where
        necessary to limit the view of entities.

        filtering can be disabled with a custom HTTP header X-ControlView set
        to false
        """
        http_host, host_url = determine_host(environ)

        request_method = environ['REQUEST_METHOD']

        disable_ControlView = environ.get('HTTP_X_CONTROLVIEW') == 'false'
        if http_host != host_url and not disable_ControlView:
            space_name = determine_space(environ, http_host)
            if space_name == None:
                return
            recipe_name = determine_space_recipe(environ, space_name)
            store = environ['tiddlyweb.store']
            try:
                recipe = store.get(Recipe(recipe_name))
            except NoRecipeError, exc:
                raise HTTP404('No recipe for space: %s', exc)

            space = Space(space_name)

            template = recipe_template(environ)
            bags = space.extra_bags()
            for bag, _ in recipe.get_recipe(template):
                bags.append(bag)
            bags.extend(ADMIN_BAGS)

            filter_string = None
            if req_uri.startswith('/recipes') and req_uri.count('/') == 1:
                filter_string = 'oom=name:'
                if recipe_name == space.private_recipe():
                    filter_parts = space.list_recipes()
                else:
                    filter_parts = [space.public_recipe()]
                filter_string += ','.join(filter_parts)
            elif req_uri.startswith('/bags') and req_uri.count('/') == 1:
                filter_string = 'oom=name:'
                filter_parts = bags
                filter_string += ','.join(filter_parts)
            elif req_uri.startswith('/search') and req_uri.count('/') == 1:
                filter_string = 'oom=bag:'
                filter_parts = bags
                filter_string += ','.join(filter_parts)
            else:
                entity_name = req_uri.split('/')[2]
                if '/recipes/' in req_uri:
                    valid_recipes = space.list_recipes()
                    if entity_name not in valid_recipes:
                        raise HTTP404('recipe %s not found' % entity_name)
                else:
                    if entity_name not in bags:
                        raise HTTP404('bag %s not found' % entity_name)

            if filter_string:
                filters, _ = parse_for_filters(filter_string)
                for single_filter in filters:
                    environ['tiddlyweb.filters'].insert(0, single_filter)
Пример #35
0
        environ['tiddlyweb.query'] = {}
        if environ['REQUEST_METHOD'].upper() == 'POST' and \
                content_type.startswith('application/x-www-form-urlencoded'):
            try:
                length = environ['CONTENT_LENGTH']
                content = environ['wsgi.input'].read(int(length))
            except KeyError, exc:
                raise HTTP400('Invalid post, unable to read content: %s' % exc)
            posted_data = parse_qs(content, keep_blank_values=True)
            try:
                _update_tiddlyweb_query(environ, posted_data)
            except UnicodeDecodeError, exc:
                raise HTTP400(
                    'Invalid encoding in query string, utf-8 required: %s',
                    exc)
        filters, leftovers = parse_for_filters(environ.get('QUERY_STRING', ''),
                                               environ)
        query_data = parse_qs(leftovers, keep_blank_values=True)
        try:
            _update_tiddlyweb_query(environ, query_data)
        except UnicodeDecodeError, exc:
            raise HTTP400(
                'Invalid encoding in query string, utf-8 required: %s', exc)
        environ['tiddlyweb.filters'] = filters


def _update_tiddlyweb_query(environ, data):
    environ['tiddlyweb.query'].update(
        dict([(unicode(key,
                       'UTF-8'), [unicode(value, 'UTF-8') for value in values])
              for key, values in data.items()]))
Пример #36
0
    def _handle_core_request(self, environ, req_uri):
        """
        Override a core request, adding filters or sending 404s where
        necessary to limit the view of entities.

        filtering can be disabled with a custom HTTP header X-ControlView set
        to false
        """
        http_host, host_url = determine_host(environ)

        request_method = environ['REQUEST_METHOD']

        disable_ControlView = environ.get('HTTP_X_CONTROLVIEW') == 'false'
        if http_host != host_url and not disable_ControlView:
            space_name = determine_space(environ, http_host)
            if space_name == None:
                return
            recipe_name = determine_space_recipe(environ, space_name)
            store = environ['tiddlyweb.store']
            try:
                recipe = store.get(Recipe(recipe_name))
            except NoRecipeError, exc:
                raise HTTP404('No recipe for space: %s', exc)

            space = Space(space_name)

            template = recipe_template(environ)
            bags = space.extra_bags()
            for bag, _ in recipe.get_recipe(template):
                bags.append(bag)
            bags.extend(ADMIN_BAGS)

            filter_string = None
            if req_uri.startswith('/recipes') and req_uri.count('/') == 1:
                filter_string = 'oom=name:'
                if recipe_name == space.private_recipe():
                    filter_parts = space.list_recipes()
                else:
                    filter_parts = [space.public_recipe()]
                filter_string += ','.join(filter_parts)
            elif req_uri.startswith('/bags') and req_uri.count('/') == 1:
                filter_string = 'oom=name:'
                filter_parts = bags
                filter_string += ','.join(filter_parts)
            elif req_uri.startswith('/search') and req_uri.count('/') == 1:
                filter_string = 'oom=bag:'
                filter_parts = bags
                filter_string += ','.join(filter_parts)
            else:
                entity_name = req_uri.split('/')[2]
                if '/recipes/' in req_uri:
                    valid_recipes = space.list_recipes()
                    if entity_name not in valid_recipes:
                        raise HTTP404('recipe %s not found' % entity_name)
                else:
                    if entity_name not in bags:
                        raise HTTP404('bag %s not found' % entity_name)

            if filter_string:
                filters, _ = parse_for_filters(filter_string)
                for single_filter in filters:
                    environ['tiddlyweb.filters'].insert(0, single_filter)
Пример #37
0
 def filter(environ, filter_string, entities):
     return recursive_filter(
         parse_for_filters(filter_string, environ)[0], entities)
Пример #38
0
        if environ['REQUEST_METHOD'].upper() == 'POST' and \
                content_type.startswith('application/x-www-form-urlencoded'):
            try:
                length = environ['CONTENT_LENGTH']
                content = environ['wsgi.input'].read(int(length))
            except KeyError, exc:
                raise HTTP400('Invalid post, unable to read content: %s'
                        % exc)
            posted_data = parse_qs(content, keep_blank_values=True)
            try:
                _update_tiddlyweb_query(environ, posted_data)
            except UnicodeDecodeError, exc:
                raise HTTP400(
                        'Invalid encoding in query string, utf-8 required: %s',
                        exc)
        filters, leftovers = parse_for_filters(
                environ.get('QUERY_STRING', ''), environ)
        query_data = parse_qs(leftovers, keep_blank_values=True)
        try:
            _update_tiddlyweb_query(environ, query_data)
        except UnicodeDecodeError, exc:
            raise HTTP400(
                    'Invalid encoding in query string, utf-8 required: %s',
                    exc)
        environ['tiddlyweb.filters'] = filters


def _update_tiddlyweb_query(environ, data):
    environ['tiddlyweb.query'].update(dict(
        [(unicode(key, 'UTF-8'), [unicode(value, 'UTF-8') for value in values])
            for key, values in data.items()]))
Пример #39
0
def filter(filter_string, tiddlers):
    return recursive_filter(parse_for_filters(filter_string)[0], tiddlers)
Пример #40
0
def filter(filter_string, tiddlers):
    return recursive_filter(parse_for_filters(filter_string)[0], tiddlers)
Пример #41
0
 def filter(environ, filter_string, entities):
     return recursive_filter(parse_for_filters(
         filter_string, environ)[0], entities)