1 from string
import rfind
12 from rox
.SaveBox
import SaveBox
14 from rox
import choices
20 # Extension, extract, create
21 ('.tar', "tar xf '%s'", "tar cf '%(dst)s' '%(src)s'"),
22 ('.zip', "unzip '%s'", "zip -r '%(dst)s' '%(src)s'"),
23 ('.deb', "ar x '%s'", None),
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
== 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
88 error
= os
.system(command
) != 0
99 def cb(src
, cond
, done
= done
):
100 data
= os
.read(src
, 100)
102 done
[0] = done
[0] + data
105 tag
= input_add(r
, INPUT_READ
, cb
)
113 (pid
, status
) = waitpid(child_pid
, 0)
116 str = string
.strip(done
[0])
119 report_error("Error: " + str)
121 report_error("Operation failed")
125 def make_archiver(path
):
126 while path
[-1:] == '/':
128 if os
.path
.isdir(path
):
129 window
= ArchiveDir(path
)
132 f
= get_format(path
, archive_formats
)
134 window
= ExtractDir(path
, f
)
136 f
= get_format(path
, compressed_formats
)
138 window
= ExtractFile(path
, f
)
140 window
= ArchiveFile(path
)
142 window
.connect('destroy', mainquit
)
146 "If dir contains only one subdir, move its contents into dir."
147 list = os
.listdir(dir)
151 subdir
= os
.path
.join(dir, list[0])
152 if not os
.path
.isdir(subdir
):
155 for file in os
.listdir(subdir
):
156 bg_system("mv '%s' ." % esc(os
.path
.join(subdir
, file)))
159 def report_known(formats
):
160 txt
= "Allowed extensions are:\n"
163 txt
= txt
+ f
[0] + '\n'
166 class Archive(SaveBox
):
167 def __init__(self
, win
, media
, sub
):
168 SaveBox
.__init
__(self
, win
, media
, sub
);
169 self
.connect('destroy', self
.destroyed
)
171 def destroyed(self
, widget
):
175 os
.kill(-child_pid
, signal
.SIGTERM
)
177 def save_as(self
, path
):
178 self
.set_sensitive(FALSE
);
181 success
= self
.do_save(path
)
185 self
.set_sensitive(TRUE
);
188 def set_uri(self
, uri
):
189 path
= 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 self
.uri
= path
[:-len(ext
)]
203 Archive
.__init
__(self
, self
, 'special', 'directory')
205 def do_save(self
, path
):
208 if bg_system(self
.extract
% esc(self
.path
)):
214 class ExtractFile(Archive
):
215 def __init__(self
, path
, format
):
218 self
.extract
= format
[1]
219 self
.uri
= path
[:-len(ext
)]
220 Archive
.__init
__(self
, self
, 'text', 'plain')
222 def do_save(self
, path
):
223 if os
.path
.exists(path
):
224 report_error("File `%s' already exists!" % path
)
226 stats
= os
.stat(self
.path
)
227 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
228 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
229 return bg_system(self
.extract
% esc(self
.path
), out
= out
) == 0
231 def send_raw(self
, selection_data
):
235 def cb(src
, cond
, self
= self
):
236 self
.data
= self
.data
+ os
.read(src
, 1024)
237 input_add(r
, INPUT_READ
, cb
)
239 bg_system(self
.extract
% esc(self
.path
), out
= w
)
242 new
= os
.read(r
, 1024)
245 self
.data
= self
.data
+ new
247 selection_data
.set(selection_data
.target
, 8, self
.data
)
250 class ArchiveFile(Archive
):
251 def __init__(self
, path
):
253 self
.uri
= path
+ '.gz'
254 Archive
.__init
__(self
, self
, 'application', 'x-gzip')
256 def do_save(self
, path
):
257 format
= get_format(path
, compressed_formats
)
258 if not format
or not format
[2]:
259 report_known(compressed_formats
)
262 if os
.path
.exists(path
):
263 report_error("File `%s' already exists!" % path
)
265 stats
= os
.stat(self
.path
)
266 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
267 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
268 return bg_system(format
[2] % esc(self
.path
), out
= out
) == 0
270 class ArchiveDir(Archive
):
271 def __init__(self
, path
):
273 self
.uri
= path
+ '.tgz'
274 Archive
.__init
__(self
, self
, 'application', 'x-compressed-tar')
276 def do_save(self
, path
):
277 format
= get_format(path
, archive_formats
)
278 if not format
or not format
[2]:
279 report_known(archive_formats
)
282 os
.chdir(os
.path
.dirname(self
.uri
))
283 retval
= bg_system(format
[2] % {
284 'src' : esc(os
.path
.basename(self
.path
)),