Allow "" as a valid value in a OptionsBox menu (reported by Guido Schimmels).
[rox-lib.git] / python / rox / fileutils.py
blob9ed51ba242ebfde6e391c7bd48bc42860a72be1e
1 """Utilities to perform various operations on paths, with support for
2 opening the ROX filer to examine locations if things go wrong.
4 Typical usage:
6 import rox.fileutils
7 rox.fileutils.makedirs('/path/for/new/directory')
8 """
10 import os
11 from rox import _
13 def report_patherror(message, path):
14 """Display a <Cancel>/<Retry>/<Examine> dialog.
15 This will raise an OSError exception if the user selects Cancel, or
16 will return successfully if the user chooses to retry."""
17 from rox import g, filer, toplevel_ref, toplevel_unref, ButtonMixed
18 toplevel_ref()
19 box = g.MessageDialog(None, 0, g.MESSAGE_QUESTION,
20 g.BUTTONS_CANCEL, message)
22 button = ButtonMixed(g.STOCK_REDO, _('Retry'))
23 button.set_flags(g.CAN_DEFAULT)
24 button.show()
25 box.add_action_widget(button, g.RESPONSE_OK)
27 button = ButtonMixed(g.STOCK_JUMP_TO, _('Examine'))
28 button.set_flags(g.CAN_DEFAULT)
29 button.show()
30 box.add_action_widget(button, g.RESPONSE_APPLY)
32 box.set_position(g.WIN_POS_CENTER)
33 box.set_title(_('Error:'))
34 box.set_default_response(g.RESPONSE_APPLY)
35 while 1:
36 resp = box.run()
37 if resp != g.RESPONSE_APPLY: break
38 filerpath = os.path.normpath(path)
39 filer.show_file(filerpath)
40 box.destroy()
41 toplevel_unref()
42 if resp != g.RESPONSE_OK:
43 raise OSError, message
45 def _makedirs_recursive(path, mode):
46 """Recursive part of makedirs. Calls itself to ensure head
47 of path exists, and then makes a new directory at path. Returns
48 an Exception if it can't make a directory at path."""
49 if os.path.isdir(path): return
50 head, tail = os.path.split(path)
51 if not tail:
52 head, tail = os.path.split(head)
53 if head and tail:
54 _makedirs_recursive(head, mode)
56 while True:
57 if os.path.exists(path):
58 report_patherror( \
59 _("Could not create directory `%s' because a file already exists at that path.\n") % path, path)
60 continue
61 try:
62 os.mkdir(path, mode)
63 return
64 except OSError, msg:
65 report_patherror(("%s.\n" + _("Could not create directory `%s'.\n")) \
66 % (msg[1], path), path)
68 def makedirs(path, mode=0777):
69 """Make a directory at the specified path, creating intermediate
70 directories if necessary. No error if 'path' is already a directory.
72 On error, a dialog which allows the user to open the filer to fix
73 things and then retry will be opened.
75 Returns successfully if all directories get created (or already exist),
76 Raises an OSError if there is a problem, in which case the application
77 should not open a dialog box to inform the user, since one will already
78 have been displayed.
79 """
80 # Get rid of any ..'s in the path
81 path = os.path.normpath(path)
82 _makedirs_recursive(path, mode)