11 from rox
.SaveBox
import SaveBox
13 from rox
import choices
19 # Extension, extract, create
20 ('.tar', "tar xf '%s'", "tar cf '%(dst)s' '%(src)s'"),
21 ('.zip', "unzip '%s'", "zip -r '%(dst)s' '%(src)s'"),
22 ('.deb', "ar x '%s'", None),
23 ('.rar', "rar x '%s'", "rar a '%(dst)s' '%(src)s'"),
25 ('.tgz', "gunzip -c '%s' | tar xf -",
26 "tar cf - '%(src)s' | gzip > '%(dst)s'"),
27 ('.tar.gz', "gunzip -c '%s' | tar xf -",
28 "tar cf - '%(src)s' | gzip > '%(dst)s'"),
30 ('.tbz', "bunzip2 -c '%s' | tar xf -",
31 "tar cf - '%(src)s' | bzip2 > '%(dst)s'"),
32 ('.tar.bz', "bunzip2 -c '%s' | tar xf -",
33 "tar cf - '%(src)s' | bzip2 > '%(dst)s'"),
34 ('.tbz2', "bunzip2 -c '%s' | tar xf -",
35 "tar cf - '%(src)s' | bzip2 > '%(dst)s'"),
36 ('.tar.bz2', "bunzip2 -c '%s' | tar xf -",
37 "tar cf - '%(src)s' | bzip2 > '%(dst)s'")
40 compressed_formats
= [
41 # Ext, extract, compress, type
42 ('.gz', "gunzip -c '%s'", "gzip -c '%s'", 'x-gzip'),
43 ('.bz', "bunzip2 -ck '%s'", "bzip2 -c '%s'", 'x-bzip'),
44 ('.bz2', "bunzip2 -ck '%s'", "bzip2 -c '%s'", 'x-bzip')
47 def get_format(path
, formats
):
50 if ext
== string
.lower(path
[-len(ext
):]):
55 """Return text with \ and ' escaped"""
56 return re
.sub("'", "'\"'\"'", text
)
58 def bg_system(command
, out
= None):
59 "system(command), but still process GUI events while waiting..."
60 "If 'out' is set then the child's stdout goes to that FD. 'out' is "
61 "closed in the parent process."
72 report_error("fork() failed!")
85 os
.setpgid(0, 0) # Start a new process group
89 error
= os
.system(command
) != 0
100 def cb(src
, cond
, done
= done
):
101 data
= os
.read(src
, 100)
103 done
[0] = done
[0] + data
106 tag
= input_add(r
, INPUT_READ
, cb
)
114 (pid
, status
) = waitpid(child_pid
, 0)
117 str = string
.strip(done
[0])
120 report_error("Error: " + str)
122 report_error("Operation failed")
126 def make_archiver(path
):
127 while path
[-1:] == '/':
129 if os
.path
.isdir(path
):
130 window
= ArchiveDir(path
)
133 f
= get_format(path
, archive_formats
)
135 window
= ExtractDir(path
, f
)
137 f
= get_format(path
, compressed_formats
)
139 window
= ExtractFile(path
, f
)
141 window
= ArchiveFile(path
)
143 window
.connect('destroy', lambda w
: rox_toplevel_unref())
148 "If dir contains only one subdir, move its contents into dir."
149 list = os
.listdir(dir)
153 subdir
= os
.path
.join(dir, list[0])
154 if not os
.path
.isdir(subdir
):
159 tmp
= os
.tempnam(dir)
160 os
.rename(subdir
, tmp
)
163 print "Warning: failed to rename(%s, %s)\n" % (subdir
, tmp
)
165 for file in os
.listdir(subdir
):
166 bg_system("mv '%s' ." % esc(os
.path
.join(subdir
, file)))
169 def report_known(formats
):
170 txt
= "Allowed extensions are:\n"
173 txt
= txt
+ f
[0] + '\n'
176 class Archive(SaveBox
):
177 def __init__(self
, win
, type):
178 SaveBox
.__init
__(self
, self
, self
.uri
, type);
179 self
.connect('destroy', self
.destroyed
)
181 def destroyed(self
, widget
):
185 os
.kill(-child_pid
, signal
.SIGTERM
)
187 def save_as_file(self
, path
):
188 self
.set_sensitive(FALSE
)
191 success
= self
.do_save(path
)
195 self
.set_sensitive(TRUE
);
198 def set_uri(self
, uri
):
199 path
= get_local_path(uri
)
201 child('rox', '-x', path
)
204 # save_as(path) - write data to file, TRUE on success
205 # set_uri(uri) - data is safely saved to this location
207 class ExtractDir(Archive
):
208 def __init__(self
, path
, format
):
211 self
.extract
= format
[1]
212 self
.uri
= path
[:-len(ext
)]
213 Archive
.__init
__(self
, self
, 'special/directory')
215 def do_save(self
, path
):
218 if bg_system(self
.extract
% esc(self
.path
)):
224 class ExtractFile(Archive
):
225 def __init__(self
, path
, format
):
228 self
.extract
= format
[1]
229 self
.uri
= path
[:-len(ext
)]
230 Archive
.__init
__(self
, self
, 'text/plain')
232 def do_save(self
, path
):
233 if os
.path
.exists(path
):
234 report_error("File `%s' already exists!" % path
)
236 stats
= os
.stat(self
.path
)
237 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
238 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
239 return bg_system(self
.extract
% esc(self
.path
), out
= out
) == 0
241 def save_as_selection(self
, selection_data
):
245 def cb(src
, cond
, self
= self
):
246 self
.data
= self
.data
+ os
.read(src
, 1024)
247 input_add(r
, INPUT_READ
, cb
)
249 bg_system(self
.extract
% esc(self
.path
), out
= w
)
252 new
= os
.read(r
, 1024)
255 self
.data
= self
.data
+ new
257 selection_data
.set(selection_data
.target
, 8, self
.data
)
260 class ArchiveFile(Archive
):
261 def __init__(self
, path
):
263 self
.uri
= path
+ '.gz'
264 Archive
.__init
__(self
, self
, 'application/x-gzip')
266 def do_save(self
, path
):
267 format
= get_format(path
, compressed_formats
)
268 if not format
or not format
[2]:
269 report_known(compressed_formats
)
272 if os
.path
.exists(path
):
273 report_error("File `%s' already exists!" % path
)
275 stats
= os
.stat(self
.path
)
276 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
277 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
278 return bg_system(format
[2] % esc(self
.path
), out
= out
) == 0
280 class ArchiveDir(Archive
):
281 def __init__(self
, path
):
283 self
.uri
= path
+ '.tgz'
284 Archive
.__init
__(self
, self
, 'application/x-compressed-tar')
286 def do_save(self
, path
):
287 format
= get_format(path
, archive_formats
)
288 if not format
or not format
[2]:
289 report_known(archive_formats
)
292 os
.chdir(os
.path
.dirname(self
.uri
))
293 retval
= bg_system(format
[2] % {
294 'src' : esc(os
.path
.basename(self
.path
)),