Esempio n. 1
0
    def get_search_query(self):
        permission = self.get_value('permission')
        if permission == 'add':
            names = ['path']
        else:
            names = ['path', 'format']

        # Query
        query = AndQuery()
        for name in names:
            field_name = 'search_%s' % name
            field = self.get_field(field_name)
            value = field.get_value(self, field_name)
            if not value:
                continue

            if name == 'path':
                depth = self.get_value('search_path_depth')
                depth = None if depth == '*' else int(depth)
                subquery = get_base_path_query(value, 0, depth)
            elif field.multiple:
                err = "access rules don't yet support multiple fields"
                raise NotImplementedError, err
            else:
                subquery = PhraseQuery(name, value)

            query.append(subquery)

        # Ok
        return query
Esempio n. 2
0
 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()
Esempio n. 3
0
def get_resource_by_uuid_query(uuid, base_class_id=None, class_id=None):
    # Base query
    query = AndQuery(PhraseQuery('uuid', uuid))
    # Add filtering query elements
    if base_class_id:
        query.append(PhraseQuery('base_classes', base_class_id))
    elif class_id:
        query.append(PhraseQuery('format', class_id))
    # Ok
    return query
Esempio n. 4
0
 def check(self, value):
     from itools.database import AndQuery, NotQuery
     from itools.database import PhraseQuery
     if not value:
         return
     context = self.context
     here = context.resource
     query = AndQuery(
         NotQuery(PhraseQuery('abspath', str(here.abspath))),
         PhraseQuery(self.field_name, value))
     if self.base_query:
         query.append(self.base_query)
     search = context.database.search(query)
     nb_results = len(search)
     if nb_results > 0:
         kw = {'nb_results': nb_results}
         self.raise_default_error(kw)
Esempio n. 5
0
    def get_events(self, day=None, *args):
        query = AndQuery(*args)
        query.append(PhraseQuery('base_classes', 'event'))
        if day:
            query.append(PhraseQuery('dates', day))

        # Do not show hidden calendars
        context = get_context()
        for calendar in context.search(format='calendar').get_resources():
            if context.user.name in calendar.get_value('hidden_for_users'):
                abspath = str(calendar.abspath)
                query.append(NotQuery(PhraseQuery('calendar', abspath)))

        # Ok
        search = self.context.search(query)
        return search.get_resources(sort_by='dtstart')
Esempio n. 6
0
 def test_AndQuery_single(self):
     query = AndQuery(PhraseQuery("data", u"mouse"))
     query.append(NotQuery(PhraseQuery("data", u"lion")))
     results = self.database.search(query)
     self.assertEqual(len(results), 2)
Esempio n. 7
0
    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
Esempio n. 8
0
 def test_AndQuery_empty(self):
     query = AndQuery()
     query.append(PhraseQuery('data', u'mouse'))
     query.append(NotQuery(PhraseQuery('data', u'lion')))
     results = self.database.search(query)
     self.assertEqual(len(results), 2)
Esempio n. 9
0
 def get_search_query(self, resource, context):
     query = AndQuery()
     form = context.query
     for key, datatype in self.search_schema.items():
         value = form[key]
         if value is None or value == '':
             continue
         # Special case: search on text, title and name AS AndQuery
         if key == 'text':
             text_query = []
             value = value.split(' ')
             for v in value:
                 t_query = OrQuery(TextQuery('title', v),
                                   TextQuery('text', v),
                                   PhraseQuery('name', v))
                 text_query.append(t_query)
             if len(text_query) == 1:
                 text_query = text_query[0]
             else:
                 text_query = AndQuery(*text_query)
             query.append(text_query)
         # Special case: type
         elif key == 'format':
             squery = [ PhraseQuery('format', x) for x in value.split(',') ]
             squery = squery[0] if len(squery) == 1 else OrQuery(*squery)
             query.append(squery)
         # Multiple
         elif datatype.multiple is True:
             query.append(OrQuery(*[ PhraseQuery(key, x) for x in value ]))
         # Singleton
         else:
             if value is False:
                 # FIXME No value means False in xapian
                 query.append(NotQuery(PhraseQuery(key, True)))
             else:
                 query.append(PhraseQuery(key, value))
     return query
Esempio n. 10
0
def find_versions_to_update(context, force=False):
    database = context.database
    cls_errors = []
    cls_to_update = []
    # Find classes
    for cls in database.get_resource_classes():
        # Class version
        class_version = class_version_to_date(cls.class_version)
        class_version_tomorrow = class_version + timedelta(days=1)
        # Search for code older than the instance
        query = AndQuery(
            PhraseQuery('format', cls.class_id),
            RangeQuery('class_version', class_version_tomorrow, None))
        search = database.search(query)
        if search:
            resource = search.get_resources().next()
            kw = {
                'class_id': resource.class_id,
                'class_title': resource.class_title,
                'abspath': str(resource.abspath),
                'resource_version': resource.metadata.version,
                'cls_version': resource.class_version
            }
            cls_errors.append(kw)
            if force is False:
                break
        # Find out the versions to upgrade
        classes_and_versions = []
        for sub_cls in cls.mro():
            for name in sub_cls.__dict__.keys():
                if not name.startswith('update_'):
                    continue
                kk, version = name.split('_', 1)
                if len(version) != 8:
                    continue
                if not version.isdigit():
                    continue
                class_version = class_version_to_date(version)
                if class_version > class_version_to_date(cls.class_version):
                    msg = "'{0}' class_version is bad ({1} > {2})"
                    msg = msg.format(sub_cls.class_id, version,
                                     cls.class_version)
                    raise ValueError(msg)
                class_version_yesterday = class_version - timedelta(days=1)
                query = AndQuery(
                    PhraseQuery('format', cls.class_id),
                    RangeQuery('class_version', None, class_version_yesterday))
                search = database.search(query)
                if not search:
                    continue
                class_and_version = (cls.class_id, version)
                if class_and_version in classes_and_versions:
                    # Overriden update method in sub classes
                    # So update method should be done one time
                    continue
                classes_and_versions.append(class_and_version)
                update_title_name = 'update_{0}_title'.format(version)
                update_title = getattr(cls, update_title_name, MSG(u'Unknow'))
                if isinstance(update_title, MSG):
                    update_title = update_title.gettext()
                kw = {
                    'class_id': cls.class_id,
                    'class_title': cls.class_title,
                    'class_version': version,
                    'class_version_date': class_version,
                    'class_version_pretty': context.format_date(class_version),
                    'update_title': update_title,
                    'nb_resources': len(search)
                }
                cls_to_update.append(kw)
    # Sort
    cls_to_update.sort(key=itemgetter('class_version_date'))
    # Ok
    return {'cls_to_update': cls_to_update, 'cls_errors': cls_errors}
Esempio n. 11
0
def run_next_update_method(context, force=False):
    """Update the database to the given versions.
    """
    database = context.database
    log = open('{0}/log/update'.format(database.path), 'w')
    messages = []

    versions = find_versions_to_update(context, force)
    if not versions['cls_to_update']:
        return
    # Update
    version = versions['cls_to_update'][0]
    class_version = version['class_version_date']
    class_version_yesterday = class_version - timedelta(days=1)
    query = AndQuery(
        PhraseQuery('format', version['class_id']),
        RangeQuery('class_version', None, class_version_yesterday))
    search = context.database.search(query)
    # Commit message (Do not override the mtime/author)
    git_message = u'Upgrade {0} to version {1}'.format(
        version['class_id'], version['class_version'])
    print(git_message)
    context.git_message = git_message
    context.set_mtime = False
    # Update
    i = 0
    resources_old2new = database.resources_old2new
    for resource in search.get_resources():
        i += 1
        path = str(resource.abspath)
        abspath = resources_old2new.get(path, path)
        if abspath is None:
            # resource deleted
            continue

        # Inconsistency on resource: we reindex it
        obj_version = resource.metadata.version
        cls_version = resource.class_version
        next_versions = resource.get_next_versions()
        if (obj_version == cls_version or not next_versions
                or next_versions[0] != version['class_version']):
            database.catalog.unindex_document(str(resource.abspath))
            values = resource.get_catalog_values()
            database.catalog.index_document(values)
            continue

        try:
            if resource is not None:
                # If resource has not been deleted by update method, we update class_version
                resource.update(version['class_version'])
        except Exception:
            line = 'ERROR: "{0}" - class_id: "{1}"\n'.format(
                resource.abspath, resource.__class__.class_id)
            log.write(line)
            print_exc(file=log)
            log.write('\n')
            # Add message
            messages.append(line)
            if force is False:
                return messages
        # Commit every 200 resources for better performances
        if i % 200 == 0:
            database.save_changes()
    # Commit
    if not database.has_changed:
        # We reindex so the class_version is reindexed
        database.catalog.save_changes()
    else:
        database.save_changes()
    # Ok
    return messages
Esempio n. 12
0
 def search_forms(self):
     query = AndQuery(PhraseQuery('base_classes', 'form'),
                      get_base_path_query(self.abspath))
     return get_context().search(query)