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