-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlibwebwar.py
More file actions
120 lines (88 loc) · 2.38 KB
/
libwebwar.py
File metadata and controls
120 lines (88 loc) · 2.38 KB
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""
Python library for interacting with WebWar archives
"""
import os
from enum import Enum
from pathlib import Path
import zipfile
class AssetNotFoundError(Exception):
pass
class UnknownArchiveFormatError(Exception):
pass
class ArchiveAssetManager:
"""
Read an archive as a directory on the file system
"""
def __init__(self, path, read_only=False):
self.path = path
def read(self, path):
"""
Read a file
"""
p = Path(f"{self.path}/{path}")
if not p.is_file():
raise AssetNotFoundError()
return p.read_bytes()
def write(self, path, content):
"""
Write a file
"""
p = Path(f"{self.path}/{path}")
os.makedirs(p.parent, exist_ok=True)
p.write_bytes(bytes(content, 'utf-8') if type(content) == str else content)
def listdir(self, path):
"""
List the contents of a directory
"""
return os.listdir(f"{self.path}/{path}")
@staticmethod
def may_match(path):
"""
Infer if the path may be used with this type of asset manager
"""
return Path(path).is_dir()
class ZipArchiveAssetManager:
"""
An asset manager for archives stored as zip files
"""
def __init__(self, path, read_only=False):
self.z = zipfile.ZipFile(path, mode='r' if read_only else 'a')
def read(self, path):
if not zipfile.Path(self.z, path).is_file():
raise AssetNotFoundError()
return self.z.read(path)
def write(self, path, content):
self.z.writestr(path, content)
def listdir(self, path):
items = []
for p in zipfile.Path(self.z, path).iterdir():
items.append(p.name)
return items
@staticmethod
def may_match(path):
return Path(path).is_file() and path.lower().endswith(".zip")
ASSET_MANAGER_TYPES = [
ArchiveAssetManager,
ZipArchiveAssetManager,
]
class Archive:
"""
An archive of a collection of requests
"""
def __init__(self, path, read_only=False):
self.path = path
for amt in ASSET_MANAGER_TYPES:
if amt.may_match(path):
self.asset_manager = amt(path, read_only)
self.asset_manager_type = amt.__name__
break
else:
raise UnknownArchiveFormatError("Unknown archive format")
def __repr__(self):
return f"<{self.__class__.__name__}: {self.asset_manager_type} {repr(self.path)}>"
def read(self, path):
return self.asset_manager.read(path)
def write(self, path, content):
self.asset_manager.write(path, content)
def listdir(self, path):
return self.asset_manager.listdir(path)