11 from rox
.SaveBox
import SaveBox
12 from rox
import support
13 from rox
import choices
21 """Return text with \ and ' escaped"""
22 return re
.sub("'", "'\"'\"'", text
)
24 def bg_system(command
, out
= None):
25 "system(command), but still process GUI events while waiting..."
26 "If 'out' is set then the child's stdout goes to that FD. 'out' is "
27 "closed in the parent process."
38 support
.report_error("fork() failed!")
51 os
.setpgid(0, 0) # Start a new process group
55 error
= os
.system(command
) != 0
66 def cb(src
, cond
, done
= done
):
67 data
= os
.read(src
, 100)
69 done
[0] = done
[0] + data
72 tag
= input_add(r
, INPUT_READ
, cb
)
80 (pid
, status
) = os
.waitpid(child_pid
, 0)
83 str = string
.strip(done
[0])
86 support
.report_error("Error: " + str)
88 support
.report_error("Operation failed")
92 def make_archiver(path
):
93 while path
[-1:] == '/':
95 if os
.path
.isdir(path
):
96 window
= ArchiveDir(path
)
99 f
= get_format(path
, archive_formats
)
101 window
= ExtractDir(path
, f
)
103 f
= get_format(path
, compressed_formats
)
105 window
= ExtractFile(path
, f
)
107 window
= ArchiveFile(path
)
109 window
.connect('destroy', lambda w
: support
.rox_toplevel_unref())
110 support
.rox_toplevel_ref()
114 "If dir contains only one subdir, move its contents into dir."
115 list = os
.listdir(dir)
119 subdir
= os
.path
.join(dir, list[0])
120 if not os
.path
.isdir(subdir
):
125 tmp
= os
.tempnam(dir)
126 os
.rename(subdir
, tmp
)
129 print "Warning: failed to rename(%s, %s)\n" % (subdir
, tmp
)
131 for file in os
.listdir(subdir
):
132 bg_system("mv '%s' ." % esc(os
.path
.join(subdir
, file)))
135 def report_known(formats
):
136 txt
= "Allowed extensions are:\n"
139 txt
= txt
+ f
[0] + '\n'
140 support
.report_error(txt
)
142 from os
import _exit
, fork
, execvp
, dup2
145 """Spawn a new process. Connect stderr to stdout."""
151 execvp(argv
[0], argv
)
154 print "Warning: exec('%s') failed!" % argv
[0]
157 print "Error: fork() failed!"
159 class Archive(SaveBox
):
160 def __init__(self
, win
, type):
161 SaveBox
.__init
__(self
, self
, self
.uri
, type);
162 self
.connect('destroy', self
.destroyed
)
164 if not hasattr(self
, 'changed'):
166 if hasattr(self
, 'set_type'):
167 self
.save_area
.entry
.connect('changed', self
.changed
)
169 print "(a newer version of ROX-Lib would be nice)"
171 def destroyed(self
, widget
):
175 os
.kill(-child_pid
, signal
.SIGTERM
)
177 def save_as_file(self
, path
):
178 self
.set_sensitive(FALSE
)
181 success
= self
.do_save(path
)
184 support
.report_exception()
185 self
.set_sensitive(TRUE
);
188 def set_uri(self
, uri
):
189 path
= support
.get_local_path(uri
)
191 child('rox', '-x', path
)
194 # save_as(path) - write data to file, TRUE on success
195 # set_uri(uri) - data is safely saved to this location
197 class ExtractDir(Archive
):
198 def __init__(self
, path
, format
):
201 self
.extract
= format
[1]
202 uri
= path
[:-len(ext
)]
204 found
= re
.match(r
'^(.*)-(\d+\.)*\d+$', uri
)
206 self
.uri
= found
.group(1)
209 Archive
.__init
__(self
, self
, 'special/directory')
211 def do_save(self
, path
):
214 if bg_system(self
.extract
% esc(self
.path
)):
220 class ExtractFile(Archive
):
221 def __init__(self
, path
, format
):
224 self
.extract
= format
[1]
225 self
.uri
= path
[:-len(ext
)]
226 Archive
.__init
__(self
, self
, 'text/plain')
228 def do_save(self
, path
):
229 if os
.path
.exists(path
):
230 support
.report_error("File `%s' already exists!" % path
)
232 stats
= os
.stat(self
.path
)
233 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
234 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
235 return bg_system(self
.extract
% esc(self
.path
), out
= out
) == 0
237 def save_as_selection(self
, selection_data
):
241 def cb(src
, cond
, self
= self
):
242 self
.data
= self
.data
+ os
.read(src
, 1024)
243 input_add(r
, INPUT_READ
, cb
)
245 bg_system(self
.extract
% esc(self
.path
), out
= w
)
248 new
= os
.read(r
, 1024)
251 self
.data
= self
.data
+ new
253 selection_data
.set(selection_data
.target
, 8, self
.data
)
256 class ArchiveFile(Archive
):
257 def __init__(self
, path
):
259 self
.uri
= path
+ '.gz'
260 Archive
.__init
__(self
, self
, 'application/x-gzip')
262 def do_save(self
, path
):
263 format
= get_format(path
, compressed_formats
)
264 if not format
or not format
[2]:
265 report_known(compressed_formats
)
268 if os
.path
.exists(path
):
269 support
.report_error("File `%s' already exists!" % path
)
271 stats
= os
.stat(self
.path
)
272 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
273 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
274 return bg_system(format
[2] % esc(self
.path
), out
= out
) == 0
276 def changed(self
, entry
):
277 path
= entry
.get_text()
278 format
= get_format(path
, compressed_formats
)
280 self
.set_type('error/unknown')
282 self
.set_type(format
[3])
284 class ArchiveDir(Archive
):
285 def __init__(self
, path
):
287 self
.uri
= path
+ '.tgz'
288 Archive
.__init
__(self
, self
, 'application/x-compressed-tar')
290 def do_save(self
, path
):
291 format
= get_format(path
, archive_formats
)
292 if not format
or not format
[2]:
293 report_known(archive_formats
)
296 os
.chdir(os
.path
.dirname(self
.uri
))
297 retval
= bg_system(format
[2] % {
298 'src' : esc(os
.path
.basename(self
.path
)),
303 def changed(self
, entry
):
304 path
= entry
.get_text()
305 format
= get_format(path
, archive_formats
)
306 if (not format
) or not format
[2]:
307 self
.set_type('error/unknown')
309 self
.set_type(format
[3])