8 from rox
.saving
import SaveBox
9 from rox
import g
, choices
16 """Return text with \ and ' escaped"""
17 return re
.sub("'", "'\"'\"'", text
)
19 def bg_system(command
, out
= None):
20 "system(command), but still process GUI events while waiting..."
21 "If 'out' is set then the child's stdout goes to that FD. 'out' is "
22 "closed in the parent process."
33 support
.alert("fork() failed!")
46 os
.setpgid(0, 0) # Start a new process group
50 error
= os
.system(command
) != 0
61 def cb(src
, cond
, done
= done
):
62 data
= os
.read(src
, 100)
64 done
[0] = done
[0] + data
67 tag
= gtk
.input_add_full(r
, gtk
.gdk
.INPUT_READ
, cb
)
75 (pid
, status
) = os
.waitpid(child_pid
, 0)
78 str = string
.strip(done
[0])
83 support
.alert("Operation failed")
87 def make_archiver(path
):
88 while path
[-1:] == '/':
90 if os
.path
.isdir(path
):
91 window
= ArchiveDir(path
)
94 f
= get_format(path
, archive_formats
)
96 window
= ExtractDir(path
, f
)
98 f
= get_format(path
, compressed_formats
)
100 window
= ExtractFile(path
, f
)
102 window
= ArchiveFile(path
)
107 "If dir contains only one subdir, move its contents into dir."
108 list = os
.listdir(dir)
112 subdir
= os
.path
.join(dir, list[0])
113 if not os
.path
.isdir(subdir
):
118 tmp
= os
.tempnam(dir)
119 os
.rename(subdir
, tmp
)
122 print "Warning: failed to rename(%s, %s)\n" % (subdir
, tmp
)
124 for file in os
.listdir(subdir
):
125 bg_system("mv '%s' ." % esc(os
.path
.join(subdir
, file)))
128 def report_known(formats
):
129 txt
= "Allowed extensions are:\n"
132 txt
= txt
+ f
[0] + '\n'
135 from os
import _exit
, fork
, execvp
, dup2
138 """Spawn a new process. Connect stderr to stdout."""
144 execvp(argv
[0], argv
)
147 print "Warning: exec('%s') failed!" % argv
[0]
150 print "Error: fork() failed!"
152 class Archive(SaveBox
):
153 def __init__(self
, win
, type):
154 SaveBox
.__init
__(self
, self
, self
.uri
, type);
155 self
.connect('destroy', self
.destroyed
)
157 if not hasattr(self
, 'changed'):
159 self
.save_area
.entry
.connect('changed', self
.changed
)
161 def destroyed(self
, widget
):
165 os
.kill(-child_pid
, signal
.SIGTERM
)
167 def save_as_file(self
, path
):
168 self
.set_sensitive(FALSE
)
171 success
= self
.do_save(path
)
174 support
.report_exception()
175 self
.set_sensitive(TRUE
);
178 def set_uri(self
, uri
):
179 path
= support
.get_local_path(uri
)
181 child('rox', '-x', path
)
184 # save_as(path) - write data to file, TRUE on success
185 # set_uri(uri) - data is safely saved to this location
187 class ExtractDir(Archive
):
188 def __init__(self
, path
, format
):
191 self
.extract
= format
[1]
192 uri
= path
[:-len(ext
)]
194 found
= re
.match(r
'^(.*)-(\d+\.)*\d+$', uri
)
196 self
.uri
= found
.group(1)
199 Archive
.__init
__(self
, self
, 'special/directory')
201 def do_save(self
, path
):
204 if bg_system(self
.extract
% esc(self
.path
)):
210 class ExtractFile(Archive
):
211 def __init__(self
, path
, format
):
214 self
.extract
= format
[1]
215 self
.uri
= path
[:-len(ext
)]
216 Archive
.__init
__(self
, self
, 'text/plain')
218 def do_save(self
, path
):
219 if os
.path
.exists(path
):
220 support
.alert("File `%s' already exists!" % path
)
222 stats
= os
.stat(self
.path
)
223 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
224 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
225 return bg_system(self
.extract
% esc(self
.path
), out
= out
) == 0
227 def save_as_selection(self
, selection_data
):
231 def cb(src
, cond
, self
= self
):
232 self
.data
= self
.data
+ os
.read(src
, 1024)
233 gtk
.input_add_full(r
, gtk
.gdk
.INPUT_READ
, cb
)
235 bg_system(self
.extract
% esc(self
.path
), out
= w
)
238 new
= os
.read(r
, 1024)
241 self
.data
= self
.data
+ new
243 selection_data
.set(selection_data
.target
, 8, self
.data
)
246 class ArchiveFile(Archive
):
247 def __init__(self
, path
):
249 self
.uri
= path
+ '.gz'
250 Archive
.__init
__(self
, self
, 'application/x-gzip')
252 def do_save(self
, path
):
253 format
= get_format(path
, compressed_formats
)
254 if not format
or not format
[2]:
255 report_known(compressed_formats
)
258 if os
.path
.exists(path
):
259 support
.alert("File `%s' already exists!" % path
)
261 stats
= os
.stat(self
.path
)
262 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
263 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
264 return bg_system(format
[2] % esc(self
.path
), out
= out
) == 0
266 def changed(self
, entry
):
267 path
= entry
.get_text()
268 format
= get_format(path
, compressed_formats
)
270 self
.set_type('error/unknown')
272 self
.set_type(format
[3])
274 class ArchiveDir(Archive
):
275 def __init__(self
, path
):
277 self
.uri
= path
+ '.tgz'
278 Archive
.__init
__(self
, self
, 'application/x-compressed-tar')
280 def do_save(self
, path
):
281 format
= get_format(path
, archive_formats
)
282 if not format
or not format
[2]:
283 report_known(archive_formats
)
286 os
.chdir(os
.path
.dirname(self
.uri
))
287 retval
= bg_system(format
[2] % {
288 'src' : esc(os
.path
.basename(self
.path
)),
293 def changed(self
, entry
):
294 path
= entry
.get_text()
295 format
= get_format(path
, archive_formats
)
296 if (not format
) or not format
[2]:
297 self
.set_type('error/unknown')
299 self
.set_type(format
[3])