File: zippath.py

package info (click to toggle)
pathlib-abc 0.5.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 316 kB
  • sloc: python: 2,634; makefile: 3
file content (88 lines) | stat: -rw-r--r-- 2,481 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import posixpath

from pathlib_abc import PathInfo, ReadablePath


class MissingInfo(PathInfo):
    __slots__ = ()

    def exists(self, follow_symlinks=True): return False
    def is_dir(self, follow_symlinks=True): return False
    def is_file(self, follow_symlinks=True): return False
    def is_symlink(self): return False


class ZipPathInfo(PathInfo):
    __slots__ = ('zip_info', 'children')

    def __init__(self):
        self.zip_info = None
        self.children = {}

    def exists(self, follow_symlinks=True):
        return True

    def is_dir(self, follow_symlinks=True):
        if self.zip_info is None:
            return True
        else:
            return self.zip_info.filename.endswith('/')

    def is_file(self, follow_symlinks=True):
        if self.zip_info is None:
            return False
        else:
            return not self.zip_info.filename.endswith('/')

    def is_symlink(self):
        return False

    def resolve(self, path, create=False):
        if not path:
            return self
        name, _, path = path.partition('/')
        if not name:
            info = self
        elif name in self.children:
            info = self.children[name]
        elif create:
            info = self.children[name] = ZipPathInfo()
        else:
            return MissingInfo()
        return info.resolve(path, create)


class ZipPath(ReadablePath):
    __slots__ = ('_segments', 'zip_file')
    parser = posixpath

    def __init__(self, *pathsegments, zip_file):
        self._segments = pathsegments
        self.zip_file = zip_file
        if not hasattr(zip_file, 'filetree'):
            # Read the contents into a tree of ZipPathInfo objects.
            zip_file.filetree = ZipPathInfo()
            for zip_info in zip_file.filelist:
                info = zip_file.filetree.resolve(zip_info.filename, create=True)
                info.zip_info = zip_info

    def __str__(self):
        if not self._segments:
            return ''
        return self.parser.join(*self._segments)

    def with_segments(self, *pathsegments):
        return type(self)(*pathsegments, zip_file=self.zip_file)

    @property
    def info(self):
        return self.zip_file.filetree.resolve(str(self))

    def __open_rb__(self, buffering=-1):
        return self.zip_file.open(self.info.zip_info, 'r')

    def iterdir(self):
        return (self / name for name in self.info.children)

    def readlink(self):
        raise NotImplementedError