title: Speed up nautilus python-extensions for reading image's Exif
body: <p>I've written a Nautilus extension which reads picture's metadata (executing <code>exiftool</code>), but when I open folders with many files, it really slows down the file manager and hangs until it finishes reading the file's data.</p>
  
  <p>Is there a way to make Nautilus keep its work while it runs my extension? Perhaps the Exif data could appear gradually in the columns while I go on with my work.</p>
  
  <pre><code>#!/usr/bin/python
  
  # Richiede:
  # nautilus-python
  # exiftool
  # gconf-python
  
  # Versione 0.15
  
  import gobject
  import nautilus
  from subprocess import Popen, PIPE
  from urllib import unquote
  import gconf
  
  def getexiftool(filename):
      options = '-fast2 -f -m -q -q -s3 -ExifIFD:DateTimeOriginal -IFD0:Software -ExifIFD:Flash -Composite:ImageSize -IFD0:Model'
      exiftool=Popen(['/usr/bin/exiftool'] + options.split() + [filename],stdout=PIPE,stderr=PIPE)
      #'-Nikon:ShutterCount' non utilizzabile con l'argomento -fast2
      output,errors=exiftool.communicate()
      return output.split('\n')
  
  class ColumnExtension(nautilus.ColumnProvider, nautilus.InfoProvider, gobject.GObject):
      def __init__(self):
          pass
  
      def get_columns(self):
          return (
              nautilus.Column("NautilusPython::ExifIFD:DateTimeOriginal","ExifIFD:DateTimeOriginal","Data (ExifIFD)","Data di scatto"),
              nautilus.Column("NautilusPython::IFD0:Software","IFD0:Software","Software (IFD0)","Software utilizzato"),
              nautilus.Column("NautilusPython::ExifIFD:Flash","ExifIFD:Flash","Flash (ExifIFD)","Modalit\u00e0 del flash"),
              nautilus.Column("NautilusPython::Composite:ImageSize","Composite:ImageSize","Risoluzione (Exif)","Risoluzione dell'immagine"),
              nautilus.Column("NautilusPython::IFD0:Model","IFD0:Model","Fotocamera (IFD0)","Modello fotocamera"),
              #nautilus.Column("NautilusPython::Nikon:ShutterCount","Nikon:ShutterCount","Contatore scatti (Nikon)","Numero di scatti effettuati dalla macchina a questo file"),
              nautilus.Column("NautilusPython::Mp","Mp","Megapixel (Exif)","Dimensione dell'immagine in megapixel"),
          )
  
      def update_file_info_full(self, provider, handle, closure, file):
          client = gconf.client_get_default()
  
          if not client.get_bool('/apps/nautilus/nautilus-metadata/enable'):
              client.set_bool('/apps/nautilus/nautilus-metadata/enable',0)
              return
  
          if file.get_uri_scheme() != 'file':
              return
  
          if file.get_mime_type() in ('image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/x-nikon-nef', 'image/x-xcf', 'image/vnd.adobe.photoshop'):
              gobject.timeout_add_seconds(1, self.update_exif, provider, handle, closure, file)
              return Nautilus.OperationResult.IN_PROGRESS
  
          file.add_string_attribute('ExifIFD:DateTimeOriginal','')
          file.add_string_attribute('IFD0:Software','')
          file.add_string_attribute('ExifIFD:Flash','')
          file.add_string_attribute('Composite:ImageSize','')
          file.add_string_attribute('IFD0:Model','')
          file.add_string_attribute('Nikon:ShutterCount','')
          file.add_string_attribute('Mp','')
  
          return Nautilus.OperationResult.COMPLETE
  
      def update_exif(self, provider, handle, closure, file):
          filename = unquote(file.get_uri()[7:])
  
          data = getexiftool(filename)
  
          file.add_string_attribute('ExifIFD:DateTimeOriginal',data[0].replace(':','-',2))
          file.add_string_attribute('IFD0:Software',data[1])
          file.add_string_attribute('ExifIFD:Flash',data[2])
          file.add_string_attribute('Composite:ImageSize',data[3])
          file.add_string_attribute('IFD0:Model',data[4])
          #file.add_string_attribute('Nikon:ShutterCount',data[5])
          width, height = data[3].split('x')
          mp = float(width) * float(height) / 1000000
          mp = "%.2f" % mp
          file.add_string_attribute('Mp',str(mp) + ' Mp')
  
          Nautilus.info_provider_update_complete_invoke(closure, provider, handle, Nautilus.OperationResult.COMPLETE)
  
          return false
  </code></pre>