home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / deskbar-applet / handlers / files.py < prev    next >
Encoding:
Python Source  |  2006-08-29  |  7.6 KB  |  248 lines

  1. import os, urllib, sys, cgi, ConfigParser
  2. from os.path import join, basename, normpath, abspath, dirname
  3. from os.path import split, expanduser, exists, isfile, isdir
  4. from gettext import gettext as _
  5. import gobject, gtk, gnome, gnome.ui, gnomevfs
  6.  
  7. import deskbar, deskbar.Indexer
  8. import deskbar.Handler
  9. import deskbar.Match
  10.  
  11. from deskbar.defs import VERSION
  12. from deskbar.Watcher import FileWatcher
  13.  
  14.  
  15. HANDLERS = {
  16.     "FileFolderHandler" : {
  17.         "name": _("Files, Folders and Places"),
  18.         "description": _("View your files, folders, bookmarks, drives, network places by name"),
  19.         "version": VERSION,
  20.     },
  21. }
  22.  
  23. NETWORK_URIS = ["http", "ftp", "smb", "sftp"]
  24. AUDIO_URIS = ["cdda"]
  25. MONITOR = gnomevfs.VolumeMonitor()
  26.  
  27. GTK_BOOKMARKS_FILE = expanduser("~/.gtk-bookmarks")
  28.  
  29. class FileMatch(deskbar.Match.Match):
  30.     def __init__(self, backend, name=None, absname=None, **args):
  31.         deskbar.Match.Match.__init__(self, backend, name=name, **args)
  32.         self._icon = deskbar.Utils.load_icon_for_file(absname)
  33.         
  34.         self.absname = absname
  35.                 
  36.     def action(self, text=None):
  37.         gnome.url_show(self.absname)
  38.     
  39.     def is_valid(self, text=None):
  40.         return exists(self.absname)
  41.         
  42.     def get_category(self):
  43.         return "files"
  44.         
  45.     def get_verb(self):
  46.         return _("Open %s") % "<b>%(name)s</b>"
  47.     
  48.     def get_hash(self, text=None):
  49.         return self.absname
  50.  
  51. class FolderMatch(deskbar.Match.Match):
  52.     def __init__(self, backend, name=None, absname=None, **args):
  53.         deskbar.Match.Match.__init__(self, backend, name=name, **args)
  54.         self._icon = deskbar.Utils.load_icon_for_file(absname)
  55.         
  56.         self.absname = absname
  57.         
  58.     def action(self, text=None):
  59.         gnome.url_show(self.absname)
  60.     
  61.     def is_valid(self, text=None):
  62.         return exists(self.absname)
  63.         
  64.     def get_category(self):
  65.         return "places"
  66.     
  67.     def get_verb(self):
  68.         return _("Open folder %s") % "<b>%(name)s</b>"
  69.     
  70.     def get_hash(self, text=None):
  71.         return self.absname
  72.  
  73. class GtkBookmarkMatch(deskbar.Match.Match):
  74.     def __init__(self, backend, name=None, path=None, **args):
  75.         deskbar.Match.Match.__init__(self, backend, name=name, **args)
  76.         self.path = path
  77.         
  78.     def action(self, text=None):
  79.         gobject.spawn_async(["nautilus", self.path], flags=gobject.SPAWN_SEARCH_PATH)
  80.     
  81.     def is_valid(self, text=None):
  82.         return exists(self.path)
  83.         
  84.     def get_category(self):
  85.         return "places"
  86.     
  87.     def get_verb(self):
  88.         return _("Open location %s") % "<b>%(name)s</b>"
  89.     
  90.     def get_hash(self, text=None):
  91.         return self.path
  92.  
  93. class VolumeMatch (deskbar.Match.Match):
  94.     def __init__(self, backend, name=None, drive=None, icon=None):
  95.         deskbar.Match.Match.__init__(self, backend, name=name, icon=icon)
  96.         self.drive = drive
  97.     
  98.     def action(self, text=None):
  99.         gobject.spawn_async(["nautilus", self.drive], flags=gobject.SPAWN_SEARCH_PATH)
  100.     
  101.     def is_valid(self, text=None):
  102.         return exists(self.drive)
  103.         
  104.     def get_category(self):
  105.         return "places"
  106.      
  107.     def get_verb(self):
  108.         if self.drive == None:
  109.             uri_scheme = None
  110.         else:
  111.             uri_scheme = gnomevfs.get_uri_scheme(self.drive) 
  112.             
  113.         if uri_scheme in NETWORK_URIS:
  114.             return _("Open network place %s") % "<b>%(name)s</b>"
  115.         elif uri_scheme in AUDIO_URIS:
  116.             return _("Open audio disc %s") % "<b>%(name)s</b>"
  117.         else:
  118.             return _("Open location %s") % "<b>%(name)s</b>"
  119.     
  120.     def get_hash(self, text=None):
  121.         return self.drive
  122.         
  123. class FileFolderHandler(deskbar.Handler.Handler):
  124.     def __init__(self):
  125.         deskbar.Handler.Handler.__init__(self, gtk.STOCK_OPEN)
  126.         self._locations = {}
  127.         
  128.     def initialize(self):
  129.         # Gtk Bookmarks --
  130.         if not hasattr(self, 'watcher'):
  131.             self.watcher = FileWatcher()
  132.             self.watcher.connect('changed', lambda watcher, f: self._scan_bookmarks_files())
  133.         
  134.         self.watcher.add(GTK_BOOKMARKS_FILE)
  135.         self._scan_bookmarks_files()
  136.  
  137.     def stop(self):
  138.         self.watcher.remove(GTK_BOOKMARKS_FILE)
  139.         
  140.     def query(self, query):
  141.         
  142.         result = []
  143.         result += self.query_filefolder(query, False)
  144.         result += self.query_filefolder(query, True)
  145.         
  146.         # Gtk Bookmarks
  147.         query = query.lower()
  148.         for bmk, (name, loc) in self._locations.items():
  149.             if bmk.startswith(query):
  150.                 result.append(GtkBookmarkMatch(self, name, loc))
  151.         
  152.         # Volumes        
  153.         # We search both mounted_volumes() and connected_drives.
  154.         # This way an audio cd in the cd drive will show up both
  155.         # on "au" and "cd".
  156.         # Drives returned by mounted_volumes() and connected_drives()
  157.         # does not have the same display_name() strings.
  158.         for drive in MONITOR.get_mounted_volumes() + MONITOR.get_connected_drives():
  159.             if not drive.is_user_visible() : continue
  160.             if not drive.is_mounted () : continue
  161.             if not drive.get_display_name().lower().startswith(query): continue
  162.             
  163.             result.append (VolumeMatch (self, drive.get_display_name(), drive.get_activation_uri(), drive.get_icon()))
  164.         
  165.         
  166.         return result
  167.     
  168.     def query_filefolder(self, query, is_file):
  169.         completions, prefix, relative = filesystem_possible_completions(query, is_file)
  170.         if is_file:
  171.             return [FileMatch(self, join(prefix, basename(completion)), "file://"+completion) for completion in completions]
  172.         else:
  173.             return [FolderMatch(self, join(prefix, basename(completion)), "file://"+completion) for completion in completions]
  174.     
  175.     def _scan_bookmarks_files(self):
  176.         if not exists(GTK_BOOKMARKS_FILE):
  177.             return
  178.             
  179.         for line in file(GTK_BOOKMARKS_FILE):
  180.             line = line.strip()
  181.             try:
  182.                 if gnomevfs.exists(line):
  183.                     uri = urllib.unquote(line)
  184.                     head, tail = split(uri)
  185.                     # Sometimes tail=="" when for example using "file:///tmp"
  186.                     if tail == "":
  187.                          i = head.rfind("/")
  188.                          tail = head[i+1:]
  189.                     self._locations[tail.lower()] = (tail, line)
  190.             except Exception, msg:
  191.                 print 'Error:_scan_bookmarks_files:', msg
  192.                 
  193. def filesystem_possible_completions(prefix, is_file=False):
  194.     """
  195.     Given an path prefix, retreive the file/folders in it.
  196.     If files is False return only the folder, else return only the files.
  197.     Return a tuple (list, prefix, relative)
  198.       list is a list of files whose name starts with prefix
  199.       prefix is the prefix effectively used, and is always a directory
  200.       relative is a flag indicating wether the given prefix was given without ~ or /
  201.     """
  202.     relative = False
  203.     # Path with no leading ~ or / are considered relative to ~
  204.     if not prefix.startswith("~") and not prefix.startswith("/"):
  205.         relative = True
  206.         prefix = join("~/", prefix)
  207.     # Path starting with ~test are considered in ~/test
  208.     if prefix.startswith("~") and not prefix.startswith("~/") and len(prefix) > 1:
  209.         prefix = join("~/", prefix[1:])
  210.     if prefix.endswith("/"):
  211.         prefix = prefix[:-1]
  212.         
  213.     if prefix == "~":
  214.         return ([expanduser(prefix)], dirname(expanduser(prefix)), relative)
  215.  
  216.     # Now we see if the typed name matches exactly a file/directory, or
  217.     # If we must take the parent directory and match the beginning of each file
  218.     start = None
  219.     path = normpath(abspath(expanduser(prefix)))        
  220.  
  221.     prefix, start = split(prefix)
  222.     path = normpath(abspath(expanduser(prefix)))    
  223.     if not exists(path):
  224.         # The parent dir wasn't a valid file, exit
  225.         return ([], prefix, relative)
  226.     
  227.     # Now we list all files contained in path. Depending on the parameter we return all
  228.     # files or all directories only. If there was a "start" we also match each name
  229.     # to that prefix so typing ~/cvs/x will match in fact ~/cvs/x*
  230.     
  231.     # First if we have an exact file match, and we requested file matches we return it alone,
  232.     # else, we return the empty file set
  233.     if my_isfile(path):
  234.         print 'Myisfile:', is_file
  235.         if is_file:
  236.             return ([path], dirname(prefix), relative)
  237.         else:
  238.             return ([], prefix, relative)
  239.  
  240.     return ([f
  241.         for f in map(lambda x: join(path, x), os.listdir(path))
  242.         if my_isfile(f) == is_file and not basename(f).startswith(".") and (start == None or basename(f).startswith(start))
  243.     ], prefix, relative)
  244.  
  245. #FIXME: gross hack to detect .savedSearches from nautilus as folders
  246. def my_isfile(path):
  247.     return isfile(path) and not path.endswith(".savedSearch")
  248.