""" A pythonic interface to the 'Keywords' interface. """ __author__ = "Tiago Cogumbreiro " __license__ = "MIT " import dbus import random from tracker import _tracker _keywords = dbus.Interface(_tracker, 'org.freedesktop.Tracker.Keywords') def search(service, keywords, step=10): """ Gets a list of all unique keywords/tags that are in use by the specified service irrespective of the uri or id of the entity. """ live_id = random.randint(0,65000) offset = 0 while True: found = False for hit in _keywords.Search(live_id, service, keywords, offset, step): yield unicode(hit) found = True offset += 1 if not found: break class Keywords(object): """ Wraps all operations that affect the keywords of an id. The interface is set-like. Containing the operations that apply to sets. """ def __init__(self, track_id, service="Files"): self.filename = track_id self.service = service def __iter__(self): return iter(self.data) def _get_data(self): try: return self._data except AttributeError: self._data = set(map(unicode, _keywords.Get(self.service, self.filename))) return self._data def _set_data(self, new_data): data = self.data if data == new_data: return # make it atomic self.clear() self.update(new_data) data = property(get_data, set_data) def __contains__(self, keyword): return keyword in self.data def __repr__(self): return "Keywords(%r,%s" % (self.filename, repr(self.data)[len("set("):]) def _reset_data(self): # Clear cache try: del self._data except AttributeError: pass def clear(self): """ Remove all elements from this set. """ _keywords.RemoveAll(self.service, self.filename) self._reset_data() def difference_update(self, keywords): """ Remove all elements of another set from this set. """ if len(keywords) == 0: return _keywords.Remove(self.service, self.filename, keywords) self._reset_data() def update(self, keywords): """ Update a set with the union of itself and another. """ if len(keywords) == 0: return _keywords.Add(self.service, self.filename, keywords) self._reset_data() def add(self, keyword): """ Add an element to a set. This has no effect if the element is already present. """ self.update([keyword]) def discard(self, keyword): """ Remove an element from a set if it is a member. """ self.difference_update((keyword,)) def intersection_update(self, other_set): """ Update a set with the intersection of itself and another. """ new_data = self.data.copy() new_data.intersection_update() self.data = new_data def issubset(self, other_set): """ Report whether another set contains this set. """ return self.data.issubset(other_set) def issuperset(self, other_set): """ Report whether this set contains another set. """ return self.data.issuperset(other_set) def pop(self, other_set): """ Remove and return an arbitrary set element. """ self.discard(self.data.pop()) def remove(self, keyword): """ Remove an element from a set; it must be a member. If the element is not a member, raise a KeyError. """ if keyword in self: self.discard(keyword) raise KeyError(keyword) def symmetric_difference_update(self, other_set): """ Return the symmetric difference of two sets as a new set. (i.e. all elements that are in exactly one of the sets.) """ new_data = self.data.copy() new_data.symmetric_difference_update(other_set) self.data = new_data