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),
24 ('.rar', "rar x '%s'", "rar a '%(dst)s' '%(src)s'"),
26 ('.tgz', "gunzip -c '%s' | tar xf -",
27 "tar cf - '%(src)s' | gzip > '%(dst)s'"),
28 ('.tar.gz', "gunzip -c '%s' | tar xf -",
29 "tar cf - '%(src)s' | gzip > '%(dst)s'"),
31 ('.tbz', "bunzip2 -c '%s' | tar xf -",
32 "tar cf - '%(src)s' | bzip2 > '%(dst)s'"),
33 ('.tar.bz', "bunzip2 -c '%s' | tar xf -",
34 "tar cf - '%(src)s' | bzip2 > '%(dst)s'"),
35 ('.tbz2', "bunzip2 -c '%s' | tar xf -",
36 "tar cf - '%(src)s' | bzip2 > '%(dst)s'"),
37 ('.tar.bz2', "bunzip2 -c '%s' | tar xf -",
38 "tar cf - '%(src)s' | bzip2 > '%(dst)s'")
41 compressed_formats
= [
42 # Ext, extract, compress, type
43 ('.gz', "gunzip -c '%s'", "gzip -c '%s'", 'x-gzip'),
44 ('.bz', "bunzip2 -ck '%s'", "bzip2 -c '%s'", 'x-bzip'),
45 ('.bz2', "bunzip2 -ck '%s'", "bzip2 -c '%s'", 'x-bzip')
48 def get_format(path
, formats
):
51 if ext
== path
[-len(ext
):]:
56 """Return text with \ and ' escaped"""
57 return re
.sub("'", "'\"'\"'", text
)
59 def bg_system(command
, out
= None):
60 "system(command), but still process GUI events while waiting..."
61 "If 'out' is set then the child's stdout goes to that FD. 'out' is "
62 "closed in the parent process."
73 report_error("fork() failed!")
86 os
.setpgid(0, 0) # Start a new process group
90 error
= os
.system(command
) != 0
101 def cb(src
, cond
, done
= done
):
102 data
= os
.read(src
, 100)
104 done
[0] = done
[0] + data
107 tag
= input_add(r
, INPUT_READ
, cb
)
115 (pid
, status
) = waitpid(child_pid
, 0)
118 str = string
.strip(done
[0])
121 report_error("Error: " + str)
123 report_error("Operation failed")
127 def make_archiver(path
):
128 while path
[-1:] == '/':
130 if os
.path
.isdir(path
):
131 window
= ArchiveDir(path
)
134 f
= get_format(path
, archive_formats
)
136 window
= ExtractDir(path
, f
)
138 f
= get_format(path
, compressed_formats
)
140 window
= ExtractFile(path
, f
)
142 window
= ArchiveFile(path
)
144 window
.connect('destroy', mainquit
)
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
):
157 for file in os
.listdir(subdir
):
158 bg_system("mv '%s' ." % esc(os
.path
.join(subdir
, file)))
161 def report_known(formats
):
162 txt
= "Allowed extensions are:\n"
165 txt
= txt
+ f
[0] + '\n'
168 class Archive(SaveBox
):
169 def __init__(self
, win
, media
, sub
):
170 SaveBox
.__init
__(self
, win
, media
, sub
);
171 self
.connect('destroy', self
.destroyed
)
173 def destroyed(self
, widget
):
177 os
.kill(-child_pid
, signal
.SIGTERM
)
179 def save_as(self
, path
):
180 self
.set_sensitive(FALSE
);
183 success
= self
.do_save(path
)
187 self
.set_sensitive(TRUE
);
190 def set_uri(self
, uri
):
191 path
= get_local_path(uri
)
193 child('rox', '-x', path
)
196 # save_as(path) - write data to file, TRUE on success
197 # set_uri(uri) - data is safely saved to this location
199 class ExtractDir(Archive
):
200 def __init__(self
, path
, format
):
203 self
.extract
= format
[1]
204 self
.uri
= path
[:-len(ext
)]
205 Archive
.__init
__(self
, self
, 'special', 'directory')
207 def do_save(self
, path
):
210 if bg_system(self
.extract
% esc(self
.path
)):
216 class ExtractFile(Archive
):
217 def __init__(self
, path
, format
):
220 self
.extract
= format
[1]
221 self
.uri
= path
[:-len(ext
)]
222 Archive
.__init
__(self
, self
, 'text', 'plain')
224 def do_save(self
, path
):
225 if os
.path
.exists(path
):
226 report_error("File `%s' already exists!" % path
)
228 stats
= os
.stat(self
.path
)
229 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
230 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
231 return bg_system(self
.extract
% esc(self
.path
), out
= out
) == 0
233 def send_raw(self
, selection_data
):
237 def cb(src
, cond
, self
= self
):
238 self
.data
= self
.data
+ os
.read(src
, 1024)
239 input_add(r
, INPUT_READ
, cb
)
241 bg_system(self
.extract
% esc(self
.path
), out
= w
)
244 new
= os
.read(r
, 1024)
247 self
.data
= self
.data
+ new
249 selection_data
.set(selection_data
.target
, 8, self
.data
)
252 class ArchiveFile(Archive
):
253 def __init__(self
, path
):
255 self
.uri
= path
+ '.gz'
256 Archive
.__init
__(self
, self
, 'application', 'x-gzip')
258 def do_save(self
, path
):
259 format
= get_format(path
, compressed_formats
)
260 if not format
or not format
[2]:
261 report_known(compressed_formats
)
264 if os
.path
.exists(path
):
265 report_error("File `%s' already exists!" % path
)
267 stats
= os
.stat(self
.path
)
268 mode
= stat
.S_IMODE(stats
[stat
.ST_MODE
]) & 0x1ff;
269 out
= os
.open(path
, os
.O_WRONLY | os
.O_CREAT
, mode
)
270 return bg_system(format
[2] % esc(self
.path
), out
= out
) == 0
272 class ArchiveDir(Archive
):
273 def __init__(self
, path
):
275 self
.uri
= path
+ '.tgz'
276 Archive
.__init
__(self
, self
, 'application', 'x-compressed-tar')
278 def do_save(self
, path
):
279 format
= get_format(path
, archive_formats
)
280 if not format
or not format
[2]:
281 report_known(archive_formats
)
284 os
.chdir(os
.path
.dirname(self
.uri
))
285 retval
= bg_system(format
[2] % {
286 'src' : esc(os
.path
.basename(self
.path
)),