~ubuntu-branches/ubuntu/precise/zeitgeist/precise-proposed

« back to all changes in this revision

Viewing changes to _zeitgeist/engine/main.py

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-08-05 17:43:20 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100805174320-13gmataeza5i2gdo
Tags: 0.5.0-0ubuntu1
* New upstream release.  "Atomic Flounder"
+ Engine:
  - FindEvent*: Event subjects are now joined by a logical AND instead of OR
    (LP: #592599).
  - Extensions found in the extensions directory are now automatically loaded.
  - Install a .pc file so out of tree extensions can figure out the install
    path.
  - Load extensions found in ~/.local/share/zeitgeist/extensions.
  - Let the GtkRecentlyUsed data-source ignore any exceptions while trying to
    parse .desktop files (LP: #523761).
  - Fix return value of the SetDataSourceEnabled D-Bus method.
  - Extensions: Hooks have been renamed and most of them now have pre and post
    variants (LP: #592599, #604747).
  - Add new ResultTypes for sorting by subject origin
  - Change the hooks API for the Extension class to use pre_* and post* hooks
    to make it clearer when they are run. This change also brings in a few
    new hooks.
+ Python API:
  - ZeitgeistDBusInterface.get_extension is no longer a classmethod (in fact,
    it never really was).
  - ZeitgeistDBusInterface.get_extension now has a third optional parameter to
    change the bus name.
+ Overall:
  - Build system fixes (LP: #595577).
  - Manpage updates.
  - Translation updates.
* remove debian/patches/01_zeitgeist-hardwire-fts-extension.patch:
  - no more needed
* debian/control.in:
  - recommends zeitgeist-fts-extension
  - bump Standards-Version to latest

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
from zeitgeist.datamodel import Event as OrigEvent, StorageState, TimeRange, \
35
35
        ResultType, get_timestamp_for_now, Interpretation, Symbol, NEGATION_OPERATOR, WILDCARD
36
36
from _zeitgeist.engine.datamodel import Event, Subject
37
 
from _zeitgeist.engine.extension import ExtensionsCollection, load_class
 
37
from _zeitgeist.engine.extension import ExtensionsCollection, get_extensions
38
38
from _zeitgeist.engine import constants
39
39
from _zeitgeist.engine.sql import get_default_cursor, unset_cursor, \
40
40
        TableLookup, WhereClause
116
116
                        raise RuntimeError("old database version")
117
117
                
118
118
                # Load extensions
119
 
                default_extensions = map(load_class, constants.DEFAULT_EXTENSIONS)
 
119
                default_extensions = get_extensions()
120
120
                self.__extensions = ExtensionsCollection(self,
121
 
                        defaults=default_extensions)
 
121
                                                         defaults=default_extensions)
122
122
                
123
123
                self._interpretation = TableLookup(cursor, "interpretation")
124
124
                self._manifestation = TableLookup(cursor, "manifestation")
214
214
        
215
215
                where_or = WhereClause(WhereClause.OR)
216
216
                
217
 
                for (event_template, subject_template) in self._build_templates(templates):
 
217
                for template in templates:
 
218
                        event_template = Event((template[0], [], None))
 
219
                        if template[1]:
 
220
                                subject_templates = [Subject(data) for data in template[1]]
 
221
                        else:
 
222
                                subject_templates = None
 
223
                        # first of all we need to check if the query is supported at all
218
224
                        # we do not support searching by storage field for now
219
225
                        # see LP: #580364
220
 
                        if subject_template[Subject.Storage]:
221
 
                                raise ValueError("zeitgeist does not support searching by 'storage' field")
 
226
                        if subject_templates is not None:
 
227
                                if any(data[Subject.Storage] for data in subject_templates):
 
228
                                        raise ValueError("zeitgeist does not support searching by 'storage' field")
222
229
                        
223
230
                        subwhere = WhereClause(WhereClause.AND)
224
231
                        
246
253
                                if event_manif_where:
247
254
                                        subwhere.extend(event_manif_where)
248
255
                                
249
 
                                value, negation, wildcard = parse_operators(Subject, Subject.Interpretation, subject_template.interpretation)
250
 
                                # Expand subject interpretation children
251
 
                                su_interp_where = WhereClause(WhereClause.OR, negation)
252
 
                                for child_interp in (Symbol.find_child_uris_extended(value)):
253
 
                                        if child_interp:
254
 
                                                su_interp_where.add_text_condition("subj_interpretation",
255
 
                                                                    child_interp, like=wildcard, cache=self._interpretation)
256
 
                                if su_interp_where:
257
 
                                        subwhere.extend(su_interp_where)
258
 
                                
259
 
                                value, negation, wildcard = parse_operators(Subject, Subject.Manifestation, subject_template.manifestation)
260
 
                                # Expand subject manifestation children
261
 
                                su_manif_where = WhereClause(WhereClause.OR, negation)
262
 
                                for child_manif in (Symbol.find_child_uris_extended(value)):
263
 
                                        if child_manif:
264
 
                                                su_manif_where.add_text_condition("subj_manifestation",
265
 
                                                                   child_manif, like=wildcard, cache=self._manifestation)
266
 
                                if su_manif_where:
267
 
                                        subwhere.extend(su_manif_where)
268
 
                                
269
 
                                # FIXME: Expand mime children as well.
270
 
                                # Right now we only do exact matching for mimetypes
271
 
                                # thekorn: this will be fixed when wildcards are supported
272
 
                                value, negation, wildcard = parse_operators(Subject, Subject.Mimetype, subject_template.mimetype)
273
 
                                if value:
274
 
                                        subwhere.add_text_condition("subj_mimetype",
275
 
                                                     value, wildcard, negation, cache=self._mimetype)
276
 
                                
277
256
                                value, negation, wildcard = parse_operators(Event, Event.Actor, event_template.actor)
278
257
                                if value:
279
258
                                        subwhere.add_text_condition("actor", value, wildcard, negation, cache=self._actor)
 
259
                                
 
260
                                if subject_templates is not None:
 
261
                                        for subject_template in subject_templates:
 
262
                                                value, negation, wildcard = parse_operators(Subject, Subject.Interpretation, subject_template.interpretation)
 
263
                                                # Expand subject interpretation children
 
264
                                                su_interp_where = WhereClause(WhereClause.OR, negation)
 
265
                                                for child_interp in (Symbol.find_child_uris_extended(value)):
 
266
                                                        if child_interp:
 
267
                                                                su_interp_where.add_text_condition("subj_interpretation",
 
268
                                                                                                        child_interp, like=wildcard, cache=self._interpretation)
 
269
                                                if su_interp_where:
 
270
                                                        subwhere.extend(su_interp_where)
 
271
                                                
 
272
                                                value, negation, wildcard = parse_operators(Subject, Subject.Manifestation, subject_template.manifestation)
 
273
                                                # Expand subject manifestation children
 
274
                                                su_manif_where = WhereClause(WhereClause.OR, negation)
 
275
                                                for child_manif in (Symbol.find_child_uris_extended(value)):
 
276
                                                        if child_manif:
 
277
                                                                su_manif_where.add_text_condition("subj_manifestation",
 
278
                                                                                                   child_manif, like=wildcard, cache=self._manifestation)
 
279
                                                if su_manif_where:
 
280
                                                        subwhere.extend(su_manif_where)
 
281
                                                
 
282
                                                # FIXME: Expand mime children as well.
 
283
                                                # Right now we only do exact matching for mimetypes
 
284
                                                # thekorn: this will be fixed when wildcards are supported
 
285
                                                value, negation, wildcard = parse_operators(Subject, Subject.Mimetype, subject_template.mimetype)
 
286
                                                if value:
 
287
                                                        subwhere.add_text_condition("subj_mimetype",
 
288
                                                                                 value, wildcard, negation, cache=self._mimetype)
 
289
                                
 
290
                                                for key in ("uri", "origin", "text"):
 
291
                                                        value = getattr(subject_template, key)
 
292
                                                        if value:
 
293
                                                                value, negation, wildcard = parse_operators(Subject, getattr(Subject, key.title()), value)
 
294
                                                                subwhere.add_text_condition("subj_%s" %key, value, wildcard, negation)
280
295
                        except KeyError, e:
281
296
                                # Value not in DB
282
297
                                log.debug("Unknown entity in query: %s" % e)
283
298
                                where_or.register_no_result()
284
299
                                continue
285
 
                                
286
 
                        for key in ("uri", "origin", "text"):
287
 
                                value = getattr(subject_template, key)
288
 
                                if value:
289
 
                                        value, negation, wildcard = parse_operators(Subject, getattr(Subject, key.title()), value)
290
 
                                        subwhere.add_text_condition("subj_%s" %key, value, wildcard, negation)
291
 
                        where_or.extend(subwhere)
292
 
                
 
300
                        where_or.extend(subwhere) 
293
301
                return where_or
294
302
        
295
303
        def _build_sql_event_filter(self, time_range, templates, storage_state):
350
358
                        " ORDER BY timestamp ASC",
351
359
                        " GROUP BY subj_uri ORDER BY timestamp DESC",
352
360
                        " GROUP BY subj_uri ORDER BY timestamp ASC",
353
 
                        " GROUP BY subj_uri ORDER BY COUNT(id) DESC, timestamp DESC",
354
 
                        " GROUP BY subj_uri ORDER BY COUNT(id) ASC, timestamp ASC",
355
 
                        " GROUP BY actor ORDER BY COUNT(id) DESC, timestamp DESC",
356
 
                        " GROUP BY actor ORDER BY COUNT(id) ASC, timestamp ASC",
357
 
                        " GROUP BY actor", # implicit: ORDER BY max(timestamp) DESC
358
 
                        " ORDER BY timestamp ASC")[order]
 
361
                        " GROUP BY subj_uri ORDER BY COUNT(subj_uri) DESC, timestamp DESC",
 
362
                        " GROUP BY subj_uri ORDER BY COUNT(subj_uri) ASC, timestamp ASC",
 
363
                        " GROUP BY actor ORDER BY COUNT(actor) DESC, timestamp DESC", 
 
364
                        " GROUP BY actor ORDER BY COUNT(actor) ASC, timestamp ASC",
 
365
                        " GROUP BY actor ORDER BY timestamp DESC",
 
366
                        " GROUP BY actor ORDER BY timestamp ASC",
 
367
                        " GROUP BY subj_origin ORDER BY timestamp DESC",
 
368
                        " GROUP BY subj_origin ORDER BY timestamp ASC",
 
369
                        " GROUP BY subj_origin ORDER BY COUNT(subj_origin) DESC, timestamp DESC",
 
370
                        " GROUP BY subj_origin ORDER BY COUNT(subj_origin) ASC, timestamp ASC")[order]
359
371
                
360
372
                if max_events > 0:
361
373
                        sql += " LIMIT %d" % max_events
499
511
                
500
512
                id = self.next_event_id()
501
513
                event[0][Event.Id] = id         
502
 
                event = self.extensions.apply_insert_hooks(event, sender)
 
514
                event = self.extensions.apply_pre_insert(event, sender)
503
515
                if event is None:
504
516
                        raise AssertionError("Inserting of event was blocked by an extension")
505
517
                elif not issubclass(type(event), OrigEvent):
557
569
                                                self._mimetype[subject.mimetype],
558
570
                                                subject.text,
559
571
                                                subject.storage))
 
572
                                
 
573
                        self.extensions.apply_post_insert(event, sender)
 
574
                                
560
575
                except sqlite3.IntegrityError:
561
576
                        # The event was already registered.
562
577
                        # Rollback _last_event_id and return the ID of the original event
593
608
                        # Don't use None here, as that'd be inserted literally into the DB
594
609
                        return ""
595
610
 
596
 
        def delete_events (self, ids):
 
611
        def delete_events (self, ids, sender=None):
 
612
                ids = self.extensions.apply_pre_delete(ids, sender)
597
613
                # Extract min and max timestamps for deleted events
598
614
                self._cursor.execute("""
599
615
                        SELECT MIN(timestamp), MAX(timestamp)
609
625
                                % ",".join(["?"] * len(ids)), ids)
610
626
                        self._cursor.connection.commit()
611
627
                        log.debug("Deleted %s" % map(int, ids))
 
628
                        
 
629
                        self.extensions.apply_post_delete(ids, sender)
 
630
                        
612
631
                        return timestamps
613
632
                else:
614
633
                        log.debug("Tried to delete non-existing event(s): %s" % map(int, ids))