Package plugins :: Package vfs :: Package vfsutils :: Module main
[hide private]
[frames] | no frames]

Source Code for Module plugins.vfs.vfsutils.main

  1  #-*- coding: utf8 -* 
  2  # 
  3  # Max E. Kuznecov <syhpoon@syhpoon.name> 2009 
  4  # 
  5   
  6  import threading 
  7   
  8  import libxyz.ui as uilib 
  9   
 10  from libxyz.core.utils import ustring, bstring 
 11  from libxyz.core.plugins import BasePlugin 
 12   
 13  from box_copy import CopyBox 
 14   
15 -class XYZPlugin(BasePlugin):
16 """ 17 Plugin vfsutils 18 """ 19 20 NAME = u"vfsutils" 21 AUTHOR = u"Max E. Kuznecov <syhpoon@syhpoon.name>" 22 VERSION = u"0.1" 23 BRIEF_DESCRIPTION = _(u"Useful VFS routines") 24 FULL_DESCRIPTION = _(u"Dialogs for common VFS operations") 25 NAMESPACE = u"vfs" 26 MIN_XYZ_VERSION = None 27 DOC = None 28 HOMEPAGE = "http://xyzcmd.syhpoon.name" 29
30 - def __init__(self, xyz):
31 super(XYZPlugin, self).__init__(xyz) 32 33 self.keys = uilib.Keys() 34 self._panel = None 35 36 self.export(self.mkdir) 37 self.export(self.remove) 38 self.export(self.copy) 39 self.export(self.move)
40 41 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 42
43 - def mkdir(self):
44 """ 45 Create new directory dialog 46 """ 47 48 self._load_panel() 49 50 _box = uilib.InputBox(self.xyz, self.xyz.top, 51 _(u"New directory name"), 52 title=_(u"Create directory")) 53 54 _dir = _box.show() 55 56 if not _dir: 57 return 58 else: 59 _dir = bstring(_dir) 60 61 try: 62 self._panel.get_current().mkdir(_dir) 63 except Exception, e: 64 xyzlog.error(_(u"Unable to create directory: %s") % 65 ustring(str(e))) 66 else: 67 self._panel.reload() 68 self._panel.select(_dir)
69 70 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 71
72 - def remove(self):
73 """ 74 Remove VFS object dialog 75 """ 76 77 self._load_panel() 78 objs = self._panel.get_active() 79 80 if not objs: 81 return 82 83 _len = len(objs) 84 85 if _len > 1: 86 msg = _(u"Really remove %d objects?") % _len 87 else: 88 selected = objs[0] 89 msg = _(u"Really remove %s (%s)?") % \ 90 (ustring(selected.name), ustring(selected.ftype)) 91 92 _deletep = uilib.YesNoBox(self.xyz, self.xyz.top, msg, 93 title=_(u"Remove object")) 94 95 if not _deletep.show(): 96 return 97 98 force = False 99 100 CODE_ALL = 10 101 CODE_YES = 20 102 CODE_NO = 30 103 CODE_ABORT = 40 104 105 buttons = [ 106 (_(u"All"), CODE_ALL), 107 (_(u"Yes"), CODE_YES), 108 (_(u"No"), CODE_NO), 109 (_(u"Abort"), CODE_ABORT), 110 ] 111 112 for obj in objs: 113 if not force and obj.is_dir() and not obj.is_dir_empty(): 114 _rec = uilib.ButtonBox( 115 self.xyz, self.xyz.top, 116 _(u"Directory is not empty\nRemove it recursively?"), 117 buttons, 118 title=_(u"Remove %s") % ustring(obj.full_path)).show() 119 120 if _rec == CODE_ABORT: 121 break 122 elif _rec == CODE_ALL: 123 force = True 124 elif _rec == CODE_NO: 125 continue 126 127 uilib.MessageBox(self.xyz, self.xyz.top, 128 _(u"Removing object: %s") % 129 ustring(obj.full_path), 130 _(u"Removing")).show(wait=False) 131 132 try: 133 obj.remove() 134 except Exception, e: 135 uilib.ErrorBox(self.xyz, self.xyz.top, 136 _(u"Unable to remove object: %s") % 137 (ustring(str(e))), 138 _(u"Error")).show() 139 xyzlog.error(_(u"Error removing object: %s") % 140 ustring(str(e))) 141 break 142 143 self._panel.reload()
144 145 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 146
147 - def copy(self, move=False):
148 """ 149 Copy objects dialog 150 """ 151 152 self._load_panel() 153 objs = self._panel.get_active() 154 155 if not objs: 156 return 157 158 if len(objs) == 1: 159 srctxt = ustring(objs[0].full_path) 160 else: 161 srctxt = _(u"%d objects") % len(objs) 162 163 srctxt = bstring(srctxt) 164 165 if move: 166 _m = _(u"Move") 167 msg = _(u"Moving object: %s") 168 caption = _(u"Moving") 169 unable_msg = _(u"Unable to move object: %s") 170 unable_caption = _(u"Move error") 171 else: 172 _m = _(u"Copy") 173 msg = _(u"Copying object: %s") 174 caption = _(u"Copying") 175 unable_msg = _(u"Unable to copy object: %s") 176 unable_caption = _(u"Copy error") 177 178 msg += _(u"\nESCAPE to abort") 179 data = CopyBox(self.xyz, srctxt, self._panel.cwd(active=False), 180 bstring(_m)).show() 181 182 if data is None: 183 return 184 185 stopped = threading.Event() 186 cancel = threading.Event() 187 free = threading.Event() 188 free.set() 189 190 def existcb(vfsobj): 191 free.clear() 192 193 buttons = [ 194 (_(u"Yes"), "override"), 195 (_(u"All"), "override all"), 196 (_(u"Skip"), "skip"), 197 (_(u"Skip all"), "skip all"), 198 (_(u"Abort"), "abort"), 199 ] 200 201 try: 202 name = ustring(vfsobj.name) 203 204 _rec = uilib.ButtonBox( 205 self.xyz, self.xyz.top, 206 _(u"Object %s already exists. Really override?") % name, 207 buttons, title=_(u"Override %s") % name).show() 208 209 uilib.MessageBox(self.xyz, self.xyz.top, 210 caption, caption).show(wait=False) 211 212 free.set() 213 return _rec or 'abort' 214 except Exception: 215 free.set()
216 217 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 218 219 def errorcb(vfsobj, errstr): 220 free.clear() 221 222 buttons = [ 223 (_(u"Skip"), "skip"), 224 (_(u"Skip all"), "skip all"), 225 (_(u"Abort"), "abort"), 226 ] 227 228 try: 229 _rec = uilib.ButtonBox( 230 self.xyz, self.xyz.top, 231 _(u"An error occured %s: %s") % ( 232 ustring(vfsobj.full_path), ustring(errstr)), 233 buttons, title=_(u"Copy error")).show() 234 235 uilib.MessageBox(self.xyz, self.xyz.top, 236 caption, caption).show(wait=False) 237 238 free.set() 239 return _rec or 'abort' 240 except Exception: 241 free.set()
242 243 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 244 245 args = { 246 "existcb": existcb, 247 "errorcb": errorcb, 248 "save_attrs": data["save_attributes"], 249 "follow_links": data["follow_links"], 250 "cancel": cancel 251 } 252 253 runner_error = [] 254 255 def frun(o, err): 256 stopped.clear() 257 258 try: 259 if move: 260 attr = "move" 261 else: 262 attr = "copy" 263 264 getattr(o, attr)(data["dst"], **args) 265 except StopIteration, e: 266 pass 267 except Exception, e: 268 err.append(ustring(str(e))) 269 270 stopped.set() 271 272 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 273 274 for obj in objs: 275 if cancel.isSet(): 276 break 277 278 uilib.MessageBox(self.xyz, self.xyz.top, 279 msg % ustring(obj.full_path), 280 caption).show(wait=False) 281 282 try: 283 runner = threading.Thread(target=lambda: 284 frun(obj, runner_error)) 285 runner.start() 286 287 # While runner is running, poll for the user input 288 # abort if ESCAPE pressed 289 while True: 290 # Callback handler is active 291 if not free.isSet(): 292 free.wait() 293 294 # Runner thread terminated, continue 295 if stopped.isSet(): 296 runner.join() 297 if runner_error: 298 uilib.ErrorBox(self.xyz, self.xyz.top, 299 unable_msg % runner_error[0], 300 unable_caption).show() 301 xyzlog.error(unable_msg % runner_error[0]) 302 303 break 304 305 _in = self.xyz.input.get(True) 306 307 # User abort 308 if self.keys.ESCAPE in _in: 309 cancel.set() 310 runner.join() 311 break 312 except Exception: 313 break 314 315 self._panel.reload() 316 self._panel.reload(active=False) 317 318 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319
320 - def move(self):
321 """ 322 Move objects dialog 323 """ 324 325 return self.copy(move=True)
326 327 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 328
329 - def _load_panel(self):
330 """ 331 Load :sys:panel plugin 332 """ 333 334 if self._panel is None: 335 self._panel = self.xyz.pm.load(":sys:panel")
336