1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import os
18 import stat
19 import tarfile
20 import time
21
22 from libxyz.core.utils import ustring, bstring
23 from libxyz.vfs import types as vfstypes
24 from libxyz.vfs import vfsobj
25 from libxyz.vfs import util
26 from libxyz.vfs import mode
27
29 """
30 Tar archive interface
31 """
32
34 if self.root:
35 return a
36 else:
37 return b()
38
39
40
41 get_name = lambda self, x: os.path.basename(x.name)
42 get_path = lambda self, x: os.path.join(self.ext_path, x.lstrip(os.sep))
43
44 file_type_map = {
45 lambda obj: obj.isfile(): vfstypes.VFSTypeFile(),
46 lambda obj: obj.isdir(): vfstypes.VFSTypeDir(),
47 lambda obj: obj.issym(): vfstypes.VFSTypeLink(),
48 lambda obj: obj.ischr(): vfstypes.VFSTypeChar(),
49 lambda obj: obj.isblk(): vfstypes.VFSTypeBlock(),
50 lambda obj: obj.isfifo(): vfstypes.VFSTypeFifo(),
51 }
52
56
57
58
60 """
61 Directory tree walker
62 @return: tuple (parent, dir, dirs, files) where:
63 parent - parent dir *VFSObject instance
64 dir - current dir TarVFSObject instance
65 dirs - list of TarVFSObject objects of directories
66 files - list of TarVFSObject objects of files
67 """
68
69 tarobj = self._open_archive()
70 entries = tarobj.getmembers()
71
72 _dirs = [x for x in entries if x.isdir() and
73 self.in_dir(self.path, x.name)]
74 _files = [x for x in entries if not x.isdir() and
75 self.in_dir(self.path, x.name)]
76
77 _dirs.sort(cmp=lambda x, y: cmp(self.get_name(x),
78 self.get_name(y)))
79 _files.sort(cmp=lambda x, y: cmp(self.get_name(x),
80 self.get_name(y)))
81
82 if self.path == os.sep:
83 _parent = self.xyz.vfs.get_parent(self.parent.path, self.enc)
84 else:
85 _parent = self.xyz.vfs.dispatch(
86 self.get_path(os.path.dirname(self.path)), self.enc,
87 tarobj=self.tarobj)
88 _parent.name = ".."
89
90 return [
91 _parent,
92 self,
93 [self.xyz.vfs.dispatch(self.get_path(x.name),
94 self.enc, tarobj=self.tarobj)
95 for x in _dirs],
96 [self.xyz.vfs.dispatch(self.get_path(x.name),
97 self.enc, tarobj=self.tarobj)
98 for x in _files],
99 ]
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
118 if self.path == os.sep:
119 self.root = True
120 else:
121 self.root = False
122
123 self.tarobj = self.kwargs.get("tarobj", None)
124
125 if self.root:
126 self.obj = None
127 else:
128 self.obj = self._init_obj()
129
130 self.ftype = self._find_type()
131 self.vtype = self.ftype.vtype
132
133 self._set_attributes()
134
135 self.attributes = (
136 (_(u"Name"), ustring(self.name)),
137 (_(u"Type"), ustring(self.ftype)),
138 (_(u"Modification time"), ustring(time.ctime(self.mtime))),
139 (_(u"Size in bytes"), ustring(self.size)),
140 (_(u"Owner"), ustring(self.uid)),
141 (_(u"Group"), ustring(self.gid)),
142 (_(u"Access mode"), ustring(self.mode)),
143 (_(u"Type-specific data"), self.data),
144 )
145
146
147
149 return "<TarVFSObject object: %s>" % self.path
150
151
152
154 """
155 Filter only those archive entries which exist in the same
156 directory level
157 """
158
159 if e.startswith(d.lstrip(os.sep)) and \
160 len(util.split_path(e)) == (len(util.split_path(d)) + 1):
161 return True
162 else:
163 return False
164
165
166
168 """
169 Find out file type
170 """
171
172 if self.root:
173 return self.parent.ftype
174
175 for k, v in self.file_type_map.iteritems():
176 if k(self.obj):
177 return v
178
179 return vfstypes.VFSTypeUnknown()
180
181
182
184 """
185 Set file attibutes
186 """
187
188 def set_link_attributes():
189 """
190 Set appropriate soft link attibutes
191 """
192
193 self.info = ""
194 self.visual = "-> %s" % self.obj.linkname or ""
195
196
197
198 self.name = self.either(self.parent.name, lambda: self.name)
199 self.mtime = self.either(self.parent.mtime, lambda: self.obj.mtime)
200 self.size = self.either(self.parent.size, lambda: self.obj.size)
201 self.uid = self.either(self.parent.uid, lambda: self.obj.uid)
202 self.gid = self.either(self.parent.gid, lambda: self.obj.gid)
203 self.mode = mode.Mode(self.either(self.parent.mode.raw,
204 lambda: self.obj.mode), self.ftype)
205 self.visual = "%s%s" % (self.vtype, self.name)
206
207 self.info = "%s %s" % (util.format_size(self.size), self.mode)
208
209 if self.is_link():
210 set_link_attributes()
211 elif self.is_file():
212 _mode = stat.S_IMODE(self.mode.raw)
213
214
215 if _mode & 0111:
216 self.vtype = "*"
217 self.visual = "*%s" % self.name
218
219
220
222 tarobj = self._open_archive()
223 path = self.path.lstrip(os.sep)
224
225 try:
226 obj = tarobj.getmember(path)
227 except KeyError:
228 obj = tarobj.getmember(path + os.sep)
229
230 return obj
231
232
233
235 if self.tarobj is None:
236 _mode = "r"
237
238 if self.driver == "gztar":
239 _mode = "r:gz"
240 elif self.driver == "bz2tar":
241 _mode = "r:bz2"
242
243 self.tarobj = tarfile.open(self.parent.path, mode=_mode)
244
245 return self.tarobj
246