def get_items(self, resource, context, if_modified_since=None): # Base query (workflow aware, image, state ...) query = self.get_base_query(resource, context) # Allowed formats formats = self.get_allowed_formats(resource, context) if formats: if len(formats) > 1: query2 = OrQuery(*[ PhraseQuery('format', format) for format in formats ]) else: query2 = PhraseQuery('format', formats[0]) query.append(query2) # Excluded formats excluded_formats = self.get_excluded_formats(resource, context) if excluded_formats: if len(excluded_formats) > 1: query2 = OrQuery(*[ PhraseQuery('format', format) for format in excluded_formats ]) else: query2 = PhraseQuery('format', excluded_formats[0]) query.append(NotQuery(query2)) # Excluded paths excluded_paths = self.get_excluded_paths(resource, context) if excluded_paths: if len(excluded_paths) > 1: query2 = OrQuery(*[ PhraseQuery('abspath', str(path)) for path in excluded_paths ]) else: query2 = PhraseQuery('abspath', str(excluded_paths[0])) query.append(NotQuery(query2)) # Excluded container paths excluded_cpaths = self.get_excluded_container_paths(resource, context) if excluded_cpaths: if len(excluded_cpaths) > 1: query2 = OrQuery(*[ get_base_path_query(str(path)) for path in excluded_cpaths ]) else: query2 = get_base_path_query(str(excluded_cpaths[0])) query.append(NotQuery(query2)) # An If-Modified-Since ? query2 = self.get_if_modified_since_query(resource, context, if_modified_since) if query2: query.append(query2) query = AndQuery(*query) return resource.get_root().search(query)
def get_search_types(self, resource, context): # FIXME get_search_types and get_items compute almost the same query # The only difference is that get_items take into account search_template # (type filter and text filter) root = context.root # Get the container container = self._get_container(resource, context) container_abspath = container.get_canonical_path() # 1. Build the query of all objects to search if self.search_on_current_folder_recursive: query = get_base_path_query(str(container_abspath)) else: query = PhraseQuery('parent_path', str(container_abspath)) # Exclude '/theme/' if isinstance(resource, WebSite): theme_path = container_abspath.resolve_name('theme') theme = get_base_path_query(str(theme_path), True) query = AndQuery(query, NotQuery(theme)) if self.ignore_internal_resources: query = AndQuery(query, PhraseQuery('is_content', True)) if self.ignore_box_aware: query = AndQuery(query, NotQuery(PhraseQuery('box_aware', True))) # 2. Compute children_formats children_formats = set() for child in root.search(query).get_documents(): children_formats.add(child.format) # 3. Do not show two options with the same title formats = {} for type in children_formats: cls = get_resource_class(type) title = cls.class_title.gettext() formats.setdefault(title, []).append(type) # 4. Build the namespace types = [] for title, type in formats.items(): type = ','.join(type) types.append({'name': type, 'value': title}) types.sort(key=lambda x: x['value'].lower()) return types
def itws_get_additional_args(resource): args = [] # Current folder abspath = resource.get_canonical_path() args.append(get_base_path_query(abspath, depth=1)) # Ignore query method = getattr(resource, 'get_internal_use_resource_names', None) if method: exclude_query = [] resource_abspath = resource.get_abspath() for name in method(): abspath = resource_abspath.resolve2(name) q = get_base_path_query(str(abspath), include_container=True) exclude_query.append(q) args.append(NotQuery(OrQuery(*exclude_query))) return args
def export_csv(self, resource, context, form): columns = ['name', 'customer_id', 'workflow_state', 'total_pre_vat', 'total_vat', 'total_price', 'total_paid', 'ctime'] header = [MSG(u'Order ref.'), MSG(u'Customer ref.'), MSG(u'State'), MSG(u'Total VAT not inc.'), MSG(u'VAT'), MSG(u'Total VAT inc.'), MSG(u'Total paid'), MSG(u'Date')] header = [x.gettext().encode('utf-8') for x in header] csv = CSVFile() csv.add_row(header) lines = [] site_root = resource.get_site_root() since = datetime.combine(form['since'], time(0,0)) orders = context.root.search(AndQuery(PhraseQuery('is_order', True), get_base_path_query(site_root.get_canonical_path()), RangeQuery('ctime', since, None))) for brain in orders.get_documents(sort_by='ctime'): item_resource = resource.get_resource(brain.abspath) item = brain, item_resource row = [] for c in columns: value = self.get_csv_value(resource, context, item, c) if isinstance(value, unicode): value = value.encode('utf-8') else: value = str(value) row.append(value) csv.add_row(row) separator = ',' context.set_content_type('text/comma-separated-values') context.set_content_disposition('attachment; filename="Orders.csv"') return csv.to_str(separator=separator)
def get_products_namespace(self, context): root = context.root query = AndQuery( get_base_path_query(self.get_canonical_path()), PhraseQuery('format', 'order-product')) l = [] for brain in root.search(query).get_documents(): resource = root.get_resource(brain.abspath, soft=True) if resource is None: log_warning('ORDER-PRODUCT not found : %s' % brain.abspath) continue # Get base product namespace kw = {} for key in ['reference', 'title', 'tax', 'quantity']: kw[key] = resource.get_property(key) kw['pre_tax_price'] = resource.get_property('pre_tax_price') tax = kw['tax'] / decimal(100) + 1 kw['price_with_tax'] = get_arrondi(kw['pre_tax_price'] * tax) total_price = kw['price_with_tax'] * kw['quantity'] kw['pre_tax_price'] = self.format_price(kw['pre_tax_price']) kw['total_price'] = self.format_price(total_price) kw['price_with_tax'] = self.format_price(kw['price_with_tax']) # Get product link (if exist) abspath = resource.get_property('abspath') product = root.get_resource(abspath, soft=True) if product: # Add link only if edit allowed link = None ac = resource.get_access_control() if ac.is_allowed_to_edit(context.user, product): link = context.get_link(product) kw['link'] = link # Add product to list of products l.append(kw) return l
def get_new_resource_name(self, form): if form.has_key('name') and form['name'].strip(): name = form['name'].strip() elif form.has_key('title'): name = form['title'].strip() else: # Number context = get_context() abspath = context.resource.get_canonical_path() query = AndQuery( get_base_path_query(str(abspath), depth=1), PhraseQuery('format', self.add_cls.class_id)) search = context.root.search(query) if len(search): doc = search.get_documents(sort_by='name', reverse=True)[0] if self.new_resource_name_prefix: start = len(self.new_resource_name_prefix) else: start = 0 name = int(doc.name[start+1:]) + 1 else: name = 1 name = str(name) if self.new_resource_name_prefix: name = '%s-%s' % (self.new_resource_name_prefix, name) return checkid(name)
def get_items_query(self, resource, context): site_root = resource.parent abspath = site_root.get_canonical_path() query = [ get_base_path_query(str(abspath)), PhraseQuery('workflow_state', 'public'), PhraseQuery('is_image', False), PhraseQuery('is_content', True)] # Allow news folder newsfolder = site_root.get_news_folder(context) if newsfolder: news_query = list(query) news_format = newsfolder.news_class.class_id query.append(NotQuery(PhraseQuery('format', news_format))) news_query += [ PhraseQuery('format', news_format), RangeQuery('pub_datetime', EPOCH, datetime.now())] query = OrQuery(AndQuery(*query), AndQuery(*news_query)) else: query = AndQuery(*query) query = OrQuery(query, PhraseQuery('abspath', str(abspath))) return query
def get_items(self, resource, context, *args): proxy = super(NewsFolder_BrowseContent, self) results = proxy.get_items(resource, context, *args) # Return only direct children abspath = str(resource.get_canonical_path()) query = get_base_path_query(abspath, depth=1) return results.search(query)
def get_options(cls): context = get_context() root = context.root resource = context.resource view = context.view # Get the container container = view._get_container(resource, context) container_abspath = container.get_canonical_path() # 1. Build the query of all objects to search if view.search_on_current_folder_recursive: query = get_base_path_query(str(container_abspath)) else: query = get_base_path_query(str(container_abspath), depth=1) # Exclude '/theme/' if isinstance(resource, WebSite): theme_path = container_abspath.resolve_name('theme') theme = get_base_path_query(str(theme_path), True) query = AndQuery(query, NotQuery(theme)) if view.ignore_internal_resources: query = AndQuery(query, PhraseQuery('is_content', True)) if view.ignore_box_aware: query = AndQuery(query, NotQuery(PhraseQuery('box_aware', True))) # 2. Compute children_formats children_formats = set() for child in root.search(query).get_documents(): children_formats.add(child.format) # 3. Do not show two options with the same title formats = {} for type in children_formats: cls = get_resource_class(type) title = cls.class_title.gettext() formats.setdefault(title, []).append(type) # 4. Build the namespace types = [] for title, type in formats.items(): type = ','.join(type) types.append({'name': type, 'value': title}) types.sort(key=lambda x: x['value'].lower()) return types
def get_base_query(self, resource, context): today = datetime.now() min_date = datetime(1900, 1, 1) # Filter by news folder abspath = resource.get_canonical_path() return [ get_base_path_query(str(abspath)), PhraseQuery('workflow_state', 'public'), RangeQuery('pub_datetime', min_date, today)]
def test_multilingual_search(self): with Database('demo.hforge.org', 19500, 20500) as database: with database.init_context(): root = root = database.get_resource('/') container = root.make_resource('test-multilingual', Folder) # Create N resources for i in range(0, 20): kw = {'title': {'fr': u'Bonjour', 'en': u'Hello'}} container.make_resource(str(i), Text, **kw) database.save_changes() # Check if resource exists query = AndQuery(get_base_path_query('/test-multilingual'), PhraseQuery('format', 'text')) search = database.search(query) self.assertEqual(len(search), 20) # Check if resource exists query = AndQuery( PhraseQuery('format', 'text'), PhraseQuery('title', u'Hello'), get_base_path_query('/test-multilingual'), ) search = database.search(query) self.assertEqual(len(search), 20) query = AndQuery( PhraseQuery('format', 'text'), PhraseQuery('title_en', u'Hello'), get_base_path_query('/test-multilingual'), ) search = database.search(query) self.assertEqual(len(search), 20) query = AndQuery( PhraseQuery('format', 'text'), PhraseQuery('title_fr', u'Bonjour'), get_base_path_query('/test-multilingual'), ) search = database.search(query) self.assertEqual(len(search), 20) query = AndQuery( PhraseQuery('format', 'text'), PhraseQuery('title_es', u'Hola'), get_base_path_query('/test-multilingual'), ) search = database.search(query) self.assertEqual(len(search), 0) # Close database database.close()
def get_payments(self, as_results=False): """Get order payments as brains.""" query = AndQuery( get_base_path_query(self.get_canonical_path()), PhraseQuery('is_payment', True)) results = self.get_root().search(query) if as_results is True: return results return results.get_documents()
def get_payment_ways(self, enabled=None, as_results=False): query = AndQuery( get_base_path_query(self.get_canonical_path()), PhraseQuery('is_payment_way', True)) if enabled is not None: query.append(PhraseQuery('enabled', enabled)) results = self.get_root().search(query) if as_results is True: return results return results.get_documents()
def get_base_query(self, resource, context): # Filter by website abspath = resource.get_site_root().get_canonical_path() query = [ get_base_path_query(str(abspath)), PhraseQuery('is_content', True) ] # Filter by pub_datetime today = datetime.now() min_date = datetime(1900, 1, 1) query.append(RangeQuery('pub_datetime', min_date, today)) # Do not show image query.append(PhraseQuery('is_image', False)) return query
def get_options(cls): context = get_context() root = context.root query = [get_base_path_query(str(context.site_root.get_abspath())), PhraseQuery('format','news'), PhraseQuery('workflow_state', 'public')] search = root.search(AndQuery(*query)) resources = [root.get_resource(brain.abspath) for brain in search.get_documents(sort_by='mtime', reverse=True)] return [{'name': str(res.get_abspath()), 'value': res.get_title()} for res in resources]
def get_items_query(self, resource, context): site_root = resource.parent abspath = site_root.get_canonical_path() query = [ get_base_path_query(str(abspath)), PhraseQuery('workflow_state', 'public'), PhraseQuery('is_image', False), PhraseQuery('is_content', True)] query = AndQuery(*query) query = OrQuery(query, PhraseQuery('abspath', str(abspath))) return query
def get_vat_details(self, context): vat = 0 pre_vat = 0 query = AndQuery( get_base_path_query(self.get_canonical_path()), PhraseQuery('format', 'order-product')) for brain in context.root.search(query).get_documents(): resource = context.root.get_resource(brain.abspath) tax = resource.get_property('tax') / decimal(100) pre_tax_price = resource.get_property('pre_tax_price') pre_vat += pre_tax_price vat += tax * pre_tax_price return pre_vat, vat
def test_close_transaction(self): """ Test if flush is done when we close database """ with Database('demo.hforge.org', 19500, 20500) as database: with database.init_context(): root = database.get_resource('/') container = root.make_resource('folder-test-close-transaction', Folder) kw = { 'title': { 'fr': u'Bonjour', 'en': u'Hello' }, 'data': 'this is text' } resource = container.make_resource(None, Text, **kw) self.assertEqual(str(resource.abspath), '/folder-test-close-transaction/0') database.save_changes() query = AndQuery( get_base_path_query('/folder-test-close-transaction'), PhraseQuery('format', 'text')) search = database.search(query) self.assertEqual(len(search), 1) resource = root.make_resource(None, Text) database.close() with Database('demo.hforge.org', 19500, 20500) as database: with database.init_context(): query = AndQuery( get_base_path_query('/folder-test-close-transaction'), PhraseQuery('format', 'text')) search = database.search(query) self.assertEqual(len(search), 1) self.assertEqual( root.get_resource('/folder-test-close-transaction/1', soft=True), None)
def get_news_folder(self, context): # News folder MUST be in root '/foo' abspath = self.get_canonical_path() query = [get_base_path_query(abspath, depth=1), PhraseQuery('format', self.newsfolder_class.class_id)] # Search results = context.root.search(AndQuery(*query), sort_by='name') if len(results): database = context.database doc = results.get_documents()[0] path = doc.abspath if type(context.database) is not ROGitDatabase: path = database.resources_old2new.get(path, path) return self.get_resource(path) return None
def get_tag_brains(self, context, sort_by="name", size=0, states=["public"]): # tags abspath = self.get_canonical_path() tags_query = [get_base_path_query(abspath, depth=1), PhraseQuery("format", Tag.class_id)] # If state is not defined, don't filter on workflow state if states: workflow_query = [PhraseQuery("workflow_state", state) for state in states] if len(workflow_query) == 1: tags_query.append(workflow_query[0]) else: tags_query.append(OrQuery(*workflow_query)) tags_query = AndQuery(*tags_query) tags_results = context.root.search(tags_query) documents = tags_results.get_documents(sort_by=sort_by, size=size) return [x for x in documents]
def get_content_query(self, resource, context): args = [] # Get the container container = self._get_container(resource, context) container_abspath = container.get_canonical_path() if self.search_on_current_folder_recursive is False: # Limit result to direct children args.append(get_base_path_query(str(container_abspath), depth=1)) else: # Limit results to whole sub children args.append(get_base_path_query(str(container_abspath))) # Exclude '/theme/' if isinstance(resource, WebSite): theme_path = container_abspath.resolve_name('theme') theme = get_base_path_query(str(theme_path), True) args.append(NotQuery(theme)) # Search specific format(s) ? search_class_id = self.search_class_id if search_class_id is not None: if isinstance(search_class_id, str): args.append(PhraseQuery('format', search_class_id)) elif (isinstance(search_class_id, (list, tuple)) and len(search_class_id) == 1): args.append(PhraseQuery('format', search_class_id[0])) else: args.append(OrQuery(*[PhraseQuery('format', x) for x in search_class_id])) # Ignore resources if self.ignore_internal_resources: args.append(PhraseQuery('is_content', True)) if self.ignore_box_aware: args.append(NotQuery(PhraseQuery('box_aware', True))) return args
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 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 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 export_pdf(self, resource, context, form): list_pdf = [] site_root = resource.get_site_root() since = datetime.combine(form['since'], time(0,0)) orders = context.root.search(AndQuery(PhraseQuery('is_order', True), get_base_path_query(site_root.get_canonical_path()), RangeQuery('ctime', since, None))) for brain in orders.get_documents(sort_by='ctime'): order = resource.get_resource(brain.abspath) pdf = order.get_bill() if pdf is None: continue path = context.database.fs.get_absolute_path(pdf.handler.key) list_pdf.append(path) # Join pdf pdf = join_pdfs(list_pdf) if pdf is None: context.message = ERROR(u"Error: Can't merge PDF") return context.set_content_type('application/pdf') context.set_content_disposition('attachment; filename="Orders.pdf"') return pdf
def get_items(self, resource, context, *args): """ Same that Folder_BrowseContent but we allow to define var 'search_on_current_folder'""" # Check parameters if self.search_on_current_folder and self.search_on_current_folder_recursive: msg = '{0} and {1} are mutually exclusive.' raise ValueError, msg.format('search_on_current_folder', 'search_on_current_folder_recursive') root = context.root # Query args = list(args) # Get the container container = self._get_container(resource, context) container_abspath = container.get_canonical_path() if self.search_on_current_folder is True: # Limit result to direct children args.append(PhraseQuery('parent_path', str(container_abspath))) else: # Limit results to whole sub children args.append(get_base_path_query(str(container_abspath))) # Search only on current folder ? if self.search_on_current_folder_recursive is True: # Already done before, because if search_on_current_folder and # search_on_current_folder_recursive are exclusive # Exclude '/theme/' if isinstance(resource, WebSite): theme_path = container_abspath.resolve_name('theme') theme = get_base_path_query(str(theme_path), True) args.append(NotQuery(theme)) # Filter by type if self.search_template: search_type = self._get_query_value(resource, context, 'search_type') if search_type: if ',' in search_type: search_type = search_type.split(',') search_type = [ PhraseQuery('format', x) for x in search_type ] search_type = OrQuery(*search_type) else: search_type = PhraseQuery('format', search_type) args.append(search_type) # Text search search_text = self._get_query_value(resource, context, 'search_text') search_text = search_text.strip() if search_text: args.append(OrQuery(TextQuery('title', search_text), TextQuery('text', search_text), PhraseQuery('name', search_text))) if self.ignore_internal_resources: args.append(PhraseQuery('is_content', True)) if self.ignore_box_aware: args.append(NotQuery(PhraseQuery('box_aware', True))) # Ok if len(args) == 1: query = args[0] else: query = AndQuery(*args) return root.search(query)
def search_forms(self): query = AndQuery(PhraseQuery('base_classes', 'form'), get_base_path_query(self.abspath)) return get_context().search(query)
def get_items(self, container, context, level=1, only_ordered=False): root = context.root here_abspath = context.resource.abspath here_level = len(list(here_abspath)) # Stop condition if here_level < level: return None container_resource = root.get_resource(container.abspath) # XXX Site root should use menu as ordered resources if only_ordered is True and isinstance(container_resource, Section): # Only ordered resources are allowed container_abspath = container_resource.get_abspath() allowed = [ container_abspath.resolve2(name) for name in container_resource.get_ordered_names() ] query = OrQuery(*[ PhraseQuery('abspath', str(abspath)) for abspath in allowed ]) results = root.search(query) # Same API as below items_docs = [] for path in allowed: item = container_resource.get_resource(name) sub_result = results.search(PhraseQuery('name', path.get_name())) doc = sub_result.get_documents()[0] items_docs.append((item, doc)) else: # Compute the query and get the documents query = get_base_path_query(container.abspath, depth=1) # format format_query = [ PhraseQuery('format', cls.class_id) for cls in self.get_classes() ] format_query = OrQuery(*format_query) query = AndQuery(query, format_query) results = root.search(query) # Sort documents by title.lower docs = results.get_documents() docs.sort(key=lambda x: x.title.lower()) items_docs = [ (root.get_resource(doc.abspath), doc) for doc in docs ] # Compute 'in path' path for the current level prefix = ['..' for x in range(here_level-(level+1))] current_level_in_path = here_abspath.resolve2('/'.join(prefix)) items = [] user = context.user for item, doc in items_docs: # ACL ac = item.get_access_control() if ac.is_allowed_to_view(user, item) is False: continue d = {'href': context.get_link(doc), 'title': doc.title or doc.name, 'format': doc.format, 'abspath': doc.abspath} sub_items = [] css = None if doc.abspath == current_level_in_path: q = AndQuery(PhraseQuery('abspath', str(doc.abspath)), PhraseQuery('is_folder', True)) if len(root.search(q)) == 1: sub_items = self.get_items(doc, context, level+1, only_ordered) if doc.abspath == here_abspath: css = 'active' else: css = 'in-path' d['items'] = sub_items d['css'] = css items.append(d) # FIXME BoxView API if len(items): self.set_view_is_empty(False) template = context.resource.get_resource(self.tree_template) return stl(template, namespace={'items': items, 'css': 'root' if level == 1 else None})
def action(self, resource, context, form): filename, mimetype, body = form['file'] # Clean up f*ing Google export with no quote body = cleanup_gmail_csv(body) csv = CSVFile() csv.load_state_from_string(body) rows = csv.get_rows() # Decode header header = rows.next() root = context.root language = context.site_root.get_default_language() companies = resource.get_resource('companies') contacts = resource.get_resource('contacts') abspath = str(resource.get_canonical_path()) base_path_query = get_base_path_query(abspath) contacts_added = {} contacts_updated = [] companies_added = {} for row in rows: # Find company company_title = find_value_by_column(header, row, GMAIL_COMPANY) if company_title: company = None # FIXME the catalog should do this key = company_title.lower().translate(transmap) if key in companies_added: # Already added company = companies_added[key] else: # Search existing company query = AndQuery(base_path_query, PhraseQuery('format', 'company'), TextQuery('title', company_title)) results = root.search(query) for document in results.get_documents(): # Found company = root.get_resource(document.abspath) break else: # Creating company company = companies.add_company( title={language: company_title}) companies_added[key] = company else: company = thingy(name=None) # Find contact by name and company if available contact = None firstname = find_value_by_column(header, row, GMAIL_FIRST_NAME) lastname = find_value_by_column(header, row, GMAIL_LAST_NAME) email = find_value_by_column(header, row, GMAIL_EMAIL) key = (firstname, lastname, email, company_title) if key in contacts_added: # Already added contact = contacts_added[key] else: # Search existing contact query = AndQuery(base_path_query, PhraseQuery('format', 'contact')) if firstname: query.append(TextQuery('crm_p_firstname', firstname)) if lastname: query.append(TextQuery('crm_p_lastname', lastname)) if email: query.append(TextQuery('crm_p_email', email)) if company.name is not None: query.append(PhraseQuery('crm_p_company', company.name)) results = root.search(query) for document in results.get_documents(): # Found contact = root.get_resource(document.abspath) contacts_updated.append(contact) break else: # Creating contact contact = contacts.add_contact( crm_p_firstname=firstname, crm_p_lastname=lastname, crm_p_email=email, crm_p_company=company.name, crm_p_status='lead') contacts_added[key] = contact # Update contact for title, name in import_columns.iteritems(): if title in (GMAIL_FIRST_NAME, GMAIL_LAST_NAME, GMAIL_EMAIL, GMAIL_COMPANY): continue value = find_value_by_column(header, row, title) if value is not None: datatype = contact.get_property_datatype(name) if issubclass(datatype, String): value = value.encode('utf8') contact.set_property(name, value) message = [] pattern = u'<a href="{0}">{1}</a>' if contacts_added: n = len(contacts_added) contacts_added = u", ".join(pattern.format( context.get_link(contact), XMLContent.encode(contact.get_title())) for contact in contacts_added.itervalues()) message.append(MSG_CONTACTS_ADDED(n=n, added=contacts_added)) if contacts_updated: n = len(contacts_updated) contacts_updated = u", ".join(pattern.format( context.get_link(contact), XMLContent.encode(contact.get_title())) for contact in contacts_updated) message.append(MSG_CONTACTS_UPDATED(n=n, updated=contacts_updated)) if not message: message = ERR_NO_CONTACT_FOUND context.message = message
def get_crm_path_query(crm_resource): crm_path = str(crm_resource.get_abspath()) return get_base_path_query(crm_path, include_container=True)
def get_items(self, resource, context, *args): path = resource.get_canonical_path() query = AndQuery(get_base_path_query(str(path)), PhraseQuery('format', 'mailing-letter')) return context.root.search(query)