Updated for the new Keyword API.

On 8/1/06, Edward Duffy <[EMAIL PROTECTED]> wrote:
On 8/1/06, Jamie McCracken <[EMAIL PROTECTED]> wrote:
> Edward Duffy wrote:
> > I put together a Nautilus plugin for adding a 'Tags' tab on the
> > Properties page for any file.  It acts just like tracker-tag, you can
> > add and remove tags to and from files (batch works..mostly).  Anyway,
> > attached is the plugin, just copy it into your
> > ~/.nautilus/python-extensions folder and restart nautilus.  Tracker
> > from CVS is required.
> >
> > It's just a first shot...comments welcome.
> >
> >
>
> yeah it looks good
>
thanks

> It would be cool if you could display the tag totals in brackets for
> each tag
I tried mimicking the way Epiphany does it... editable GtkEntry with
comma seperated tags.  Works pretty well considering all the events
being fired off at Tracker (new version attached).


> (its already great you sort by most used tag!)
Hell, why not? The API already provided it.
The sorting could use some work, I just don't have enough tags in
there yet to get an idea of what'll work best.  Epiphany moves all
your selected tags to the top.  I was thinking it would be cool to put
the most common tags for the file type you're editing up top.  So, if
I go to change the tags for a video, the tags most common to video
files would be at the top.  But the API doesn't provide an easy way to
do that, as far as I can tell.  Is there a way to map file URI to a
list of services?  So '/home/user/music/song.mp3' returns
['Files','Music']?
>
> I'm thinking of changing the way tags are done so that each tag can have
>   an icon/emblem and maybe a short description in tracker. Will look how
> nautilus does it for inspiration :)
>
>
> --
> Mr Jamie McCracken
> http://jamiemcc.livejournal.com/
>
>



import gtk
import dbus
import urllib
import operator
import nautilus

class TrackerTagsPage(nautilus.PropertyPageProvider):

   def __init__(self):
      bus = dbus.SessionBus()
      obj = bus.get_object('org.freedesktop.Tracker',
                           '/org/freedesktop/tracker')
      self.tracker = dbus.Interface(obj, 'org.freedesktop.Tracker')
      self.keywords = dbus.Interface(obj, 'org.freedesktop.Tracker.Keywords')

   def _on_toggle(self, cell, path, files):
      on = not self.store.get_value(self.store.get_iter(path), 0)
      self.store.set_value(self.store.get_iter(path), 0, on)
      tag = self.store.get_value(self.store.get_iter(path), 1)
      if on: func = self.keywords.Add
      else:  func = self.keywords.Remove
      for f in files:
         func('Files', f, [tag])

   def _on_add_tag(self, button):
      self.store.append([False, ''])

   def _on_edit_tag(self, cell, path, text, files):
      old_text = self.store.get_value(self.store.get_iter(path), 1)
      on = self.store.get_value(self.store.get_iter(path), 0)
      if on:
         for f in files:
            self.keywords.Remove('Files', f, [old_text])
            self.keywords.Add('Files', f, [text])
      self.store.set_value(self.store.get_iter(path), 1, text)

   def _on_update_tag_summary(self, store, path, iter):
      tags = [ ]
      for row in store:
         if row[0]:
            tags.append(row[1])
      self.entry_tag.handler_block(self.entry_changed_id)
      self.entry_tag.set_text(','.join(tags))
      self.entry_tag.handler_unblock(self.entry_changed_id)

   def _on_tag_summary_changed(self, entry, files):
      new_tags = set(entry.get_text().split(','))
      new_tags.discard('') # remove the empty string
      for f in files:
         old_tags = set(self.keywords.Get('Files', f))
         tbr = list(old_tags.difference(new_tags))
         tba = list(new_tags.difference(old_tags))
         if tbr:
            self.keywords.Remove('Files', f, tbr)
         if tba:
            self.keywords.Add('Files', f, tba)

      # update check-box list (remove outdated tags, add the new ones)
      self.store.handler_block(self.store_changed_id)
      all_tags = [ t for t,c in self.keywords.GetList('Files') ]
      i = 0
      while i < len(self.store):
         if self.store[i][1] in all_tags:
            self.store[i][0] = (self.store[i][1] in new_tags)
            all_tags.remove(self.store[i][1])
            i += 1
         else:
            del self.store[i]
      #  assert len(all_tags) == 1 ???
      for t in all_tags:
         self.store.append([True, t])
      self.store.handler_unblock(self.store_changed_id)

   def get_property_pages(self, files):
      property_label = gtk.Label('Tags')
      property_label.show()
      print 'Tracker version:',self.tracker.GetVersion()

      # get the list of tags
      all_tags = self.keywords.GetList('Files')
      # convert usage count to an integer
      all_tags = [ (t,int(c[0])) for t,c in all_tags ]
      # sort by usage count
      all_tags = sorted(all_tags, key=operator.itemgetter(1))
      all_tags.reverse()
      # strip away usage count
      all_tags = [ t for t,c in all_tags ]

      files = [ urllib.url2pathname(f.get_uri()[7:]) for f in files ]
      indiv_count = dict([ (t,0) for t in all_tags ])
      tags = { }
      for f in files:
         tags[f] = self.keywords.Get('Files', f)
         for t in tags[f]:
            indiv_count[t] += 1

      main = gtk.VBox()

      hbox = gtk.HBox()
      hbox.set_border_width(6)
      hbox.set_spacing(12)
      label = gtk.Label('Tags: ')
      self.entry_tag = gtk.Entry()
      # self.entry_tag.props.editable = False
      hbox.pack_start(label, False, False)
      hbox.pack_start(self.entry_tag, True, True)
      main.pack_start(hbox, False, False)
      self.entry_changed_id = self.entry_tag.connect(
                  'changed', self._on_tag_summary_changed, files)

      sw = gtk.ScrolledWindow()
      sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
      sw.set_shadow_type(gtk.SHADOW_ETCHED_OUT)

      self.store = gtk.ListStore(bool, str)
      self.store_changed_id = self.store.connect(
                  'row-changed', self._on_update_tag_summary)
      for tag in all_tags:
         iter = self.store.append([False, tag])
         if indiv_count[tag] == len(files):
            self.store.set_value(iter, 0, True)
         elif indiv_count[tag] == 0:
            self.store.set_value(iter, 0, False)
         else:
            print 'inconsistant'
      tv = gtk.TreeView(self.store)
      tv.set_headers_visible(False)

      column = gtk.TreeViewColumn()
      tv.append_column(column)
      cell = gtk.CellRendererToggle()
      column.pack_start(cell, True)
      column.add_attribute(cell, 'active', 0)
      # column.add_attribute(cell, 'inconsistent', 0)
      cell.connect('toggled', self._on_toggle, files)
      cell.set_property('activatable', True)
      # cell.set_property('inconsistent', True)

      column = gtk.TreeViewColumn()
      tv.append_column(column)
      cell = gtk.CellRendererText()
      column.pack_start(cell, True)
      column.add_attribute(cell, 'text', 1)
      cell.connect('edited', self._on_edit_tag, files)
      cell.set_property('editable', True)

      sw.add(tv)
      main.pack_start(sw)

      hbox = gtk.HBox()
      hbox.set_border_width(6)
      btn = gtk.Button(stock='gtk-add')
      btn.get_child().get_child().get_children()[1].props.label = '_Add Tag'
      btn.connect('clicked', self._on_add_tag)
      hbox.pack_end(btn, False, False)
      main.pack_start(hbox, False, False)
      
      main.show_all()

      return nautilus.PropertyPage("NautilusPython::tags", property_label, main),
_______________________________________________
tracker-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/tracker-list

Reply via email to