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