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)
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)
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'
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
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
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()
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'
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
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
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')
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)
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)
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
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()]))
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()]))
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]
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
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
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())
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
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'
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
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)]
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
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
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()
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
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
def test_exception(): filter, _ = parse_for_filters('limit=-1,2') with py.test.raises(FilterError): recursive_filter(filter, tiddlers)
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)
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()]))
def filter(environ, filter_string, entities): return recursive_filter( parse_for_filters(filter_string, environ)[0], entities)
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()]))
def filter(filter_string, tiddlers): return recursive_filter(parse_for_filters(filter_string)[0], tiddlers)
def filter(environ, filter_string, entities): return recursive_filter(parse_for_filters( filter_string, environ)[0], entities)