def get_namespace(self, resource, context): root = context.root # Categories filters = [] order = resource.get_resource('order') for name in order.get_ordered_names(): criterium = resource.get_resource(name) items = criterium.get_items(context) # Count base query filters.append({'title': criterium.get_title(), 'items': items}) # Base Count query query = { 'base': AndQuery(*[ PhraseQuery('format', 'product'), PhraseQuery('workflow_state', 'public') ]) } for f in filters: for item in f['items']: if item['selected'] and item['query']: query[item['criterium']] = item['query'] # Count each item for f in filters: for item in f['items']: s = [y for x, y in query.items() if x != item['criterium']] if item['query']: s.append(item['query']) item['nb_products'] = len(root.search(AndQuery(*s))) # Return namespace return {'title': resource.get_title(), 'filters': filters}
def get_base_query(self, resource, context): query = NeutralWS_RSS.get_base_query(self, resource, context) # Add products site_root = resource.get_site_root() shop = site_root.get_resource('shop') # XXX Search only on website product_query = [ PhraseQuery('format', shop.product_class.class_id), PhraseQuery('workflow_state', 'public') ] return [OrQuery(AndQuery(*query), AndQuery(*product_query))]
def get_namespace(self, resource, context): ref = context.query['ref'] if ref is None: return {'ref': MSG(u'-'), 'amount': None, 'top_view': None} # Get informations about payment payment_handler = resource.get_resource('payments').handler query = [ PhraseQuery('ref', ref), PhraseQuery('user', context.user.name) ] results = payment_handler.search(AndQuery(*query)) if not results: raise ValueError, u'Payment invalid' record = results[0] amount = payment_handler.get_record_value(record, 'amount') # Get top view resource_validator = payment_handler.get_record_value( record, 'resource_validator') resource_validator = context.root.get_resource(resource_validator) top_view = None if resource_validator.end_view_top: top_view = resource_validator.end_view_top.GET(resource, context) return { 'ref': context.query['ref'], 'amount': format_price(amount), 'top_view': top_view }
def set_user(self, email=None, password=None): context = get_context() shop = get_shop(context.resource) # Calculate the user id user_id = self.get_next_user_id() # Add the user cls = shop.user_class user = cls.make_resource(cls, self, user_id) # Set the email and paswword if email is not None: user.set_property('email', email) if password is not None: user.set_password(password) # Set default group root = context.root query = [ PhraseQuery('format', 'user-group'), PhraseQuery('name', 'default') ] search = root.search(AndQuery(*query)) documents = search.get_documents() group = documents[0] group = root.get_resource(group.abspath) user.set_property('user_group', str(group.get_abspath())) user_is_enabled = group.get_property('user_is_enabled_when_register') user.set_property('is_enabled', user_is_enabled) # Return the user return user
def get_payments_records(self, context, ref=None, user=None, payment_way=None, state=None, queries=None): records = [] queries = queries or [] if ref: queries.append(PhraseQuery('ref', ref)) if user: queries.append(PhraseQuery('user', user)) if (state is True) or (state is False): queries.append(PhraseQuery('state', state)) for payment_way in self.search_resources(cls=PaymentWay, format=payment_way): payments = payment_way.get_resource('payments') if queries: for record in payments.handler.search(AndQuery(*queries)): ts = payments.handler.get_record_value(record, 'ts') records.append((payment_way, record, ts)) else: for record in payments.handler.get_records(): ts = payments.handler.get_record_value(record, 'ts') records.append((payment_way, record, ts)) # Sort by ts records.sort(key=itemgetter(2)) records.reverse() records = [(x, y) for x, y, z in records] return records
def create_new_image(self, context, image): images = self.get_resource('images') query = [ PhraseQuery('parent_path', str(images.get_canonical_path())), PhraseQuery('is_image', True) ] root = context.root results = root.search(AndQuery(*query)) if len(results) == 0: name = '0' else: doc = results.get_documents(sort_by='name', reverse=True)[0] name = str(int(doc.name) + 1) # XXX Temp fix while images.get_resource(name, soft=True) is not None: name = int(name) + 1 name = str(name) # End of temp fix filename, mimetype, body = image _name, type, language = FileName.decode(filename) cls = Image kw = { 'format': mimetype, 'filename': filename, 'extension': type, 'state': 'public' } return self.make_resource(cls, images, name, body, **kw)
def nb_orders(self): # XXX Orders states root = self.get_root() queries = [ PhraseQuery('format', 'order'), PhraseQuery('customer_id', self.name) ] return len(root.search(AndQuery(*queries)))
def has_pro_price(self): # XXX Improve in future root = self.get_root() query = [ PhraseQuery('format', 'user-group'), PhraseQuery('name', 'pro') ] search = root.search(AndQuery(*query)) return len(search) > 0
def get_new_resource_name(self, form): context = get_context() root = context.root abspath = context.resource.get_canonical_path() query = AndQuery(PhraseQuery('parent_path', str(abspath)), PhraseQuery('format', 'shop_module_a_report')) search = root.search(query) id_report = len(search.get_documents()) + 1 return str('report_%s' % id_report)
def _get_current_reviews_query(self, context, form): if form['abspath']: product = context.root.get_resource(form['abspath']) abspath = product.get_canonical_path().resolve2('reviews') else: abspath = context.resource.get_canonical_path() query = AndQuery(PhraseQuery('parent_path', str(abspath)), PhraseQuery('format', 'shop_module_a_review')) return query
def get_group(self, context): root = context.root query = [ PhraseQuery('format', 'user-group'), PhraseQuery('name', 'default') ] search = root.search(AndQuery(*query)) documents = search.get_documents() group = documents[0] return root.get_resource(group.abspath)
def get_items(self, resource, context, *args): path = str(resource.parent.get_canonical_path()) query = [ PhraseQuery('parent_path', path), NotQuery(PhraseQuery('name', '404')), OrQuery(PhraseQuery('format', 'shop-section'), PhraseQuery('format', 'products-feed'), PhraseQuery('format', 'webpage'), PhraseQuery('format', 'news-folder')) ] return context.root.search(AndQuery(*query))
def get_items(self, resource, context, *args): root = context.root items = [] id_query = PhraseQuery('customer_id', resource.name) cls_query = PhraseQuery('format', 'order') args = AndQuery(id_query, cls_query) orders = root.search(args) for brain in orders.get_documents(): resource = root.get_resource(brain.abspath) items.append(resource) return items
def get_nb_products(self, only_public=False): root = self.get_root() shop = get_shop(self) abspath = self.get_canonical_path() query = [ PhraseQuery('parent_paths', str(abspath)), PhraseQuery('format', shop.product_class.class_id) ] if shop.get_property('hide_not_buyable_products') is True: context = get_context() group_name = get_group_name(shop, context) query.append( NotQuery(PhraseQuery('not_buyable_by_groups', group_name))) if only_public is True: query.append(PhraseQuery('workflow_state', 'public')) return len(root.search(AndQuery(*query)))
def get_module(resource, class_id): site_root = resource.get_site_root() # XXX use parent_paths query = [ PhraseQuery('is_shop_module', True), PhraseQuery('format', class_id) ] # Search root = site_root.parent results = root.search(AndQuery(*query)) if len(results) == 0: return None # XXX if more than one module ??? doc = results.get_documents(sort_by='name')[0] return root.get_resource(doc.abspath)
def render_for_product(self, resource, context): reviews = resource.get_resource('reviews', soft=True) if reviews is None: return { 'nb_reviews': 0, 'last_review': None, 'note': None, 'link': context.get_link(self), 'here_abspath': str(context.resource.get_abspath()), 'product_abspath': resource.get_abspath(), 'viewboxes': {} } # XXX Should be in catalog for performances abspath = reviews.get_canonical_path() queries = [ PhraseQuery('parent_path', str(abspath)), PhraseQuery('workflow_state', 'public'), PhraseQuery('format', 'shop_module_a_review') ] search = context.root.search(AndQuery(*queries)) brains = list(search.get_documents(sort_by='mtime', reverse=True)) nb_reviews = len(brains) if brains: last_review = brains[0] last_review = reduce_string( brains[0].shop_module_review_description, 200, 200) else: last_review = None note = 0 for brain in brains: note += brain.shop_module_review_note # Get viewboxes viewboxes = [] for brain in brains[:5]: review = context.root.get_resource(brain.abspath) viewbox = Review_Viewbox().GET(review, context) viewboxes.append(viewbox) return { 'nb_reviews': nb_reviews, 'last_review': last_review, 'link': context.get_link(self), 'viewboxes': viewboxes, 'here_abspath': str(context.resource.get_abspath()), 'product_abspath': resource.get_abspath(), 'note': note / nb_reviews if nb_reviews else None }
def get_namespace(self, resource, context): root = context.root products = [] abspath = str(resource.get_abspath()) query = AndQuery(PhraseQuery('format', 'product'), PhraseQuery('manufacturer', abspath), PhraseQuery('workflow_state', 'public')) results = root.search(query) for result in results.get_documents(): product = root.get_resource(result.abspath) products.append(product.viewbox.GET(product, context)) return { 'title': resource.get_title(), 'data': resource.get_property('data'), 'photo': resource.get_property('photo'), 'products': products }
def action(self, resource, context, form): for key in self.schema.keys(): resource.set_property(key, form[key]) # Check there's only one default declination if form['is_default'] is True: product = resource.parent query = AndQuery(PhraseQuery('format', 'product-declination'), PhraseQuery('is_default', True), get_base_path_query(str(product.get_abspath()))) search = context.root.search(query) if len(search) >= 1: message = ERROR(u"There's already a default declination") context.message = message context.commit = False return # Ok context.message = messages.MSG_CHANGES_SAVED
def render_for_user(self, resource, context): # Get review that belong to user query = [ PhraseQuery('shop_module_review_author', resource.name), PhraseQuery('workflow_state', 'public'), PhraseQuery('format', 'shop_module_a_review') ] search = context.root.search(AndQuery(*query)) brains = list(search.get_documents(sort_by='mtime', reverse=True)) nb_reviews = len(brains) # Get viewboxes viewboxes = [] for brain in brains[:5]: review = context.root.get_resource(brain.abspath) viewbox = Review_Viewbox().GET(review, context) viewboxes.append(viewbox) # Return namespace return {'nb_reviews': nb_reviews, 'viewboxes': viewboxes}
def get_options(cls): options = [{'name': '*', 'value': MSG(u'The whole site')}] context = get_context() resource = context.resource root = context.root site_root = resource.get_site_root() categories = site_root.get_resource('categories') query = [PhraseQuery('format', 'category'), PhraseQuery('parent_path', str(categories.get_abspath()))] for brain in root.search(AndQuery(*query)).get_documents(): categorie = root.get_resource(brain.abspath) nb_products = categorie.get_nb_products(only_public=True) if nb_products == 0: continue small_title = categorie.get_property('breadcrumb_title') options.append({'name': brain.abspath, 'value': small_title or categorie.get_title()}) return options
def _get_form(self, resource, context): form = NewInstance._get_form(self, resource, context) # Check if the user has already fill a review query = self._get_current_reviews_query(context, form) author_query = PhraseQuery('shop_module_review_author', context.user.name) query = AndQuery(query, author_query) if len(context.root.search(query)): raise FormError, ERROR(u'You already have filled a review.') # form = NewInstance._get_form(self, resource, context) # Check images image = form['images'] # XXX not yet multiple if image: filename, mimetype, body = image if mimetype.startswith('image/') is False: raise FormError, MSG_UNEXPECTED_MIMETYPE(mimetype=mimetype) return form
def test_everything(self): catalog = Catalog('tests/catalog', Document.fields) # Simple Search, hit results = catalog.search(data=u'lion') self.assertEqual(len(results), 4) documents = [x.name for x in results.get_documents(sort_by='name')] self.assertEqual(documents, ['03.txt', '08.txt', '10.txt', '23.txt']) # Simple Search, miss self.assertEqual(len(catalog.search(data=u'tiger')), 0) # Unindex, Search, Abort, Search catalog.unindex_document('03.txt') results = catalog.search(data=u'lion') self.assertEqual(len(catalog.search(data=u'lion')), 3) catalog.abort_changes() self.assertEqual(len(catalog.search(data=u'lion')), 4) # Query on indexed boolean self.assertEqual(len(catalog.search(about_wolf=True)), 5) # Query on stored boolean results = catalog.search(about_wolf=True) longer_stories = 0 for result in results.get_documents(): if result.is_long: longer_stories += 1 self.assertEqual(longer_stories, 0) # Phrase Query results = catalog.search(data=u'this is a double death') self.assertEqual(len(results), 1) # Range Query query = RangeQuery('name', '03.txt', '06.txt') results = catalog.search(query) self.assertEqual(len(results), 4) # Not Query (1/2) query = NotQuery(PhraseQuery('data', 'lion')) results = catalog.search(query) self.assertEqual(len(results), 27) # Not Query (2/2) query1 = PhraseQuery('data', 'mouse') query2 = NotQuery(PhraseQuery('data', 'lion')) query = AndQuery(query1, query2) results = catalog.search(query) self.assertEqual(len(results), 2)
def get_items(self, resource, context): site_root = resource.get_site_root() shop = site_root.get_resource('shop') abspath = site_root.get_canonical_path() query = [PhraseQuery('parent_paths', str(abspath)), PhraseQuery('format', shop.product_class.class_id), PhraseQuery('workflow_state', 'public')] category = context.query['category'] if category and category != '*': query.append(PhraseQuery('parent_paths', category)) search_word = context.query['product_search_text'] if search_word: for word in split_unicode(search_word): alternative = (word + u"s" if not word.endswith(u's') else word[:-1]) plain_text = OrQuery( # By reference #PhraseQuery('reference', word.upper()), #encode('utf-8')), #.upper()), # On product PhraseQuery('title', word), PhraseQuery('description', word), PhraseQuery('data', word), PhraseQuery('text', word), # XXX Hack manufacturer #PhraseQuery('manufacturer', checkid(word)), # Alternative PhraseQuery('title', alternative), PhraseQuery('description', alternative), PhraseQuery('data', alternative), PhraseQuery('text', alternative)) query.append(plain_text) # Add query of filter for key, datatype in self.get_query_schema().items(): value = context.query[key] if key == 'stored_price' and value: query.append(RangeQuery('stored_price', value[0], value[1])) # TODO Add other filters results = context.root.search(AndQuery(*query)) # XXX Hack results self.nb_results = len(results) return results
def get_search_query(search_schema, context, query): base_query = [] if query is not None: base_query.extend(query) form = context.query for key, datatype in search_schema.items(): if form[key] and issubclass(datatype, RangeDatatype): minimum, maximum = form[key] if minimum or maximum: base_query.append(RangeQuery(key, minimum, maximum)) elif form[key] and key == 'abspath': base_query.append(StartQuery(key, form[key])) elif form[key] and datatype.multiple is True: base_query.append( OrQuery(*[PhraseQuery(key, x) for x in form[key]])) elif form[key]: base_query.append(PhraseQuery(key, form[key])) if len(base_query) > 1: return AndQuery(*base_query) elif len(base_query) == 1: return base_query[0] return None
def get_sub_categories_namespace(self, resource, context): namespace = [] search_word = context.query['product_search_text'] query = AndQuery(PhraseQuery('format', 'category'), PhraseQuery('title', search_word)) for brain in context.root.search(query).get_documents(): cat = context.root.get_resource(brain.abspath) nb_products = cat.get_nb_products() if nb_products == 0: continue img = cat.get_property('image_category') path_cat = resource.get_pathto(cat) namespace.append( {'name': cat.name, 'link': context.get_link(cat), 'title': cat.get_title(), 'breadcrumb_title': cat.get_property('breadcrumb_title'), 'css': None, 'nb_products': nb_products, 'img': str(path_cat.resolve2(img)) if img else None}) if namespace: namespace[0]['css'] = 'start' namespace[-1]['css'] = 'end' return namespace
def get_items(self, resource, context, *args): """ Same that Folder_BrowseContent but we allow to define var 'search_on_current_folder'""" # Query args = list(args) # Search only on current folder ? if self.search_on_current_folder is True: path = resource.get_canonical_path() query = get_base_path_query(str(path)) args.append(query) # Exclude '/theme/' if resource.get_abspath() == '/': theme_path = path.resolve_name('theme') theme = get_base_path_query(str(theme_path), True) args.append(NotQuery(theme)) # Ok if len(args) == 1: query = args[0] else: query = AndQuery(*args) return context.root.search(query)
def search_events_in_range(self, dtstart, dtend, sortby=None, **kw): """Return a list of Records objects of type 'VEVENT' matching the given dates range and sorted if requested. If kw is filled, it calls search_events on the found subset to return only components matching filters. RangeSearch is [left, right[ """ # Check type of dates, we need datetime for method in_range if not isinstance(dtstart, datetime): dtstart = datetime(dtstart.year, dtstart.month, dtstart.day) if not isinstance(dtend, datetime): dtend = datetime(dtend.year, dtend.month, dtend.day) # dtend is include into range dtend = dtend + timedelta(days=1) - resolution # Get only the events which matches dtstart_limit = dtstart + resolution dtend_limit = dtend + resolution dtstart = dtstart dtend = dtend query = AndQuery( PhraseQuery('type', 'VEVENT'), OrQuery( RangeQuery('DTSTART', dtstart, dtend), RangeQuery('DTEND', dtstart_limit, dtend_limit), AndQuery(RangeQuery('DTSTART', None, dtstart), RangeQuery('DTEND', dtend, None)))) results = self.search(query) if results == []: return [] # Check filters if kw: results = self.search_events(subset=results, **kw) # Nothing to sort or inactive if sortby is None or len(results) <= 1: return results # Get results as a dict to sort them res_events = [] for event in results: version = event[-1] value = { 'dtstart': version['DTSTART'].value, 'dtend': version['DTEND'].value, 'event': event } res_events.append(value) # Sort by dtstart res_events = sorted(res_events, key=itemgetter('dtstart')) # Sort by dtend res = [] current = [res_events[0]] for e in res_events[1:]: if e['dtstart'] == current[0]['dtstart']: current.append(e) else: res.extend(x['event'] for x in sorted(current, key=itemgetter('dtend'))) current = [e] res.extend(x['event'] for x in sorted(current, key=itemgetter('dtend'))) return res
def get_nb_categories(self): root = self.get_root() abspath = self.get_canonical_path() query = AndQuery(PhraseQuery('parent_paths', str(abspath)), PhraseQuery('format', 'category')) return len(root.search(query))
def get_namespace(self, resource, context): root = context.root here = context.resource site_root = here.get_site_root() site_root_abspath = site_root.get_abspath() shop = site_root.get_resource('shop') categories_abspath = str(site_root_abspath.resolve2('categories')) show_nb_products = resource.get_property('show_nb_products') show_first_category = resource.get_property('show_first_category') show_second_level = resource.get_property('show_second_level') here_abspath = here.get_abspath() here_real_abspath = str(here_abspath) here_parent_abspath = here_abspath.resolve2('..') current_level = here_real_abspath.count('/') if here.metadata.format == 'category': here_abspath = str(here.get_abspath()) # Max level deploy = count '/' + 1 # here_abspath at level 1 does not contain '/' here_abspath_level = here_abspath.count('/') max_level_deploy = here_abspath_level + 1 else: if here.metadata.format == 'product': # Special case for the product, here_* values are compute # with here = parent category parent_category = here.parent parent_category_abspath = parent_category.get_abspath() here_abspath = str(parent_category_abspath) here_abspath_level = here_abspath.count('/') max_level_deploy = here_abspath_level + 1 here_parent_abspath = parent_category_abspath.resolve2('..') else: # Tweak here_abspath here_abspath = categories_abspath here_abspath_level = here_abspath.count('/') max_level_deploy = categories_abspath.count('/') + 1 here_abspath_p = Path(here_abspath) # Get search with all publics products all_products = root.search( AndQuery(PhraseQuery('format', shop.product_class.class_id), PhraseQuery('workflow_state', 'public'))) # Get search with all categories all_categories = root.search( AndQuery(PhraseQuery('parent_paths', categories_abspath), PhraseQuery('format', 'category'))) # Build a dict with brains by level cat_per_level = {} for index, cat in enumerate( all_categories.get_documents(sort_by='abspath')): # Skip first category --> /categories if index == 0 and show_first_category is False: continue level = cat.abspath.count('/') # Skip second level (if we are not on level /categories/') if (show_second_level is False and current_level > 2 and level == 3 and not here_real_abspath == cat.abspath and not here_parent_abspath == cat.abspath): continue # Skip bad level if level > max_level_deploy: continue diff_level = here_abspath_level - level path_to_resolve = ['..' for x in range(diff_level)] path_to_resolve = '/'.join(path_to_resolve) # Path uses to compute the prefix with the current category here_prefix = here_abspath_p.resolve2(path_to_resolve) # Compute the prefix prefix = here_prefix.get_prefix(cat.abspath) if prefix == here_prefix: # special case when prefix equals here_prefix pass elif len(prefix) != level - 1: # bad, not in the same arborescence continue # Get the product number in the category sub_results = all_products.search( PhraseQuery('parent_paths', cat.abspath)) cats = cat_per_level.setdefault(level, []) cats.append({'doc': cat, 'nb_products': len(sub_results)}) # Build the tree starting with the higher level tree_template = resource.get_resource(self.tree_template) levels = sorted(cat_per_level.keys(), reverse=True) tree = None for level in levels: items = [] for data in cat_per_level[level]: doc = data['doc'] if here_abspath.startswith(doc.abspath): sub_tree = tree css = 'in-path ' else: sub_tree = None css = '' css = 'active ' if here_abspath == doc.abspath else css # Href (get_link emulation) href = str(site_root_abspath.get_pathto(doc.abspath)) css += checkid(href) css = css.replace('.', '-dot-') if resource.get_property('use_small_title'): title = doc.m_breadcrumb_title or doc.m_title or doc.name else: title = doc.m_title or doc.name d = { 'title': title, 'href': '/%s' % href, 'sub_tree': sub_tree, 'nb_products': data['nb_products'], 'css': css } items.append(d) tree = stl(tree_template, { 'items': items, 'show_nb_products': show_nb_products, 'css': None }) return {'title': resource.get_title(), 'tree': tree}
def get_items(self, resource, context, *args): abspath = resource.get_canonical_path() query = AndQuery(PhraseQuery('parent_path', str(abspath)), PhraseQuery('format', 'shop_module_a_review')) return context.root.search(query)