Package libxyz :: Package vfs :: Module dispatcher
[hide private]
[frames] | no frames]

Source Code for Module libxyz.vfs.dispatcher

  1  #-*- coding: utf8 -* 
  2  # 
  3  # Max E. Kuznecov ~syhpoon <mek@mek.uz.ua> 2008-2009 
  4  # 
  5  # This file is part of XYZCommander. 
  6  # XYZCommander is free software: you can redistribute it and/or modify 
  7  # it under the terms of the GNU Lesser Public License as published by 
  8  # the Free Software Foundation, either version 3 of the License, or 
  9  # (at your option) any later version. 
 10  # XYZCommander is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 13  # GNU Lesser Public License for more details. 
 14  # You should have received a copy of the GNU Lesser Public License 
 15  # along with XYZCommander. If not, see <http://www.gnu.org/licenses/>. 
 16   
 17  """ 
 18  VFSDispatcher - Dispatching to appropriate VFS module based on path. 
 19  Path format is following: 
 20  [<prefix>]:<path_to_archive>#vfs#<path_inside_archive> 
 21  """ 
 22   
 23  import os 
 24  import re 
 25   
 26  from libxyz.vfs import VFSObject 
 27  from libxyz.exceptions import VFSError 
 28   
29 -class VFSDispatcher(object):
30 - def __init__(self, xyz):
31 self.xyz = xyz 32 self._handlers = {} 33 self.vfsre = re.compile(r'(#vfs-\w+#)') 34 self.vfsre2 = re.compile(r'^#vfs-(\w+)#$')
35 36 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37
38 - def register(self, prefix, vfs_obj_class):
39 """ 40 Register new VFS handler 41 42 @param prefix: Patch prefix 43 @param vfs_obj_class: VFSObject derived class 44 """ 45 46 if not issubclass(vfs_obj_class, VFSObject): 47 raise VFSError( 48 _(u"Invalid class: %s. VFSObject dervied expected.") % 49 str(vfs_obj_class)) 50 51 self._handlers[prefix] = vfs_obj_class
52 53 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54
55 - def dispatch(self, path, enc=None, **kwargs):
56 """ 57 Dispatch provided path to corresponding VFS object handler 58 """ 59 60 enc = enc or xyzenc 61 62 data = self._parse_path(path) 63 64 if not data: 65 raise VFSError(_(u"Invalid path: %s.") % path) 66 67 handler = None 68 69 for p, vfs in data: 70 if vfs not in self._handlers: 71 raise VFSError( 72 _(u"Unable to find VFS handler for %s.") % vfs) 73 else: 74 full_path = self.get_full_path(p, vfs, handler) 75 ext_path = self.get_ext_path(handler, vfs) 76 77 handler = self._handlers[vfs]( 78 self.xyz, 79 os.path.abspath(os.path.normpath(p)), 80 full_path, 81 ext_path, 82 vfs, 83 handler, 84 enc, 85 **kwargs) 86 87 return handler
88 89 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 90
91 - def _parse_path(self, path):
92 files = [] 93 94 driver = None 95 96 for entry in re.split(self.vfsre, path): 97 if not entry: 98 entry = os.sep 99 100 vfs = self.vfsre2.search(entry) 101 102 if driver is not None: 103 files.append((entry, driver)) 104 driver = None 105 elif vfs: 106 driver = vfs.group(1) 107 else: 108 files.append((entry, None)) 109 110 return files
111 112 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 113
114 - def get_parent(self, path, enc):
115 _parent = self.xyz.vfs.dispatch( 116 os.path.abspath(os.path.dirname(path)), enc) 117 _parent.name = ".." 118 119 return _parent
120 121 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122
123 - def get_full_path(self, path, vfs, parent):
124 """ 125 Return full path 126 """ 127 128 if parent: 129 p = parent.full_path 130 else: 131 p = "" 132 133 if vfs: 134 v = "#vfs-%s#" % vfs 135 else: 136 v = "" 137 138 return p + v + path
139 140 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 141
142 - def get_ext_path(self, parent, vfs):
143 """ 144 Return external path 145 """ 146 147 if parent: 148 p = parent.full_path 149 else: 150 p = "" 151 152 if vfs: 153 v = "#vfs-%s#" % vfs 154 else: 155 v = "" 156 157 return p + v
158