2
2
import ntpath
3
3
import os
4
4
import re
5
- from typing import TYPE_CHECKING , Callable , Dict , List , Optional , Union
5
+ from typing import TYPE_CHECKING , BinaryIO , Callable , Dict , List , Optional , Union , cast
6
6
from zipfile import ZipFile
7
7
8
8
from fsspec import AbstractFileSystem
9
9
from fsspec .implementations .local import LocalFileSystem
10
10
11
11
from .enums import FileType
12
12
from .files import BundleFile , File , ObjectReader , SerializedFile , WebFile
13
+ from .helpers .ContainerHelper import ContainerHelper
13
14
from .helpers .ImportHelper import (
14
15
FileSourceType ,
15
16
check_file_type ,
@@ -32,14 +33,22 @@ class Environment:
32
33
local_files_simple : List [str ]
33
34
typetree_generator : Optional ["TypeTreeGenerator" ] = None
34
35
35
- def __init__ (self , * args : FileSourceType , fs : Optional [AbstractFileSystem ] = None ):
36
+ def __init__ (self , * args : FileSourceType , fs : Optional [AbstractFileSystem ] = None , path : Optional [ str ] = None ):
36
37
self .files = {}
37
38
self .cabs = {}
38
- self .path = None
39
39
self .fs = fs or LocalFileSystem ()
40
40
self .local_files = []
41
41
self .local_files_simple = []
42
42
43
+ if path is None :
44
+ # if no path is given, use the current working directory
45
+ if isinstance (self .fs , LocalFileSystem ):
46
+ self .path = os .getcwd ()
47
+ else :
48
+ self .path = ""
49
+ else :
50
+ self .path = path
51
+
43
52
if args :
44
53
for arg in args :
45
54
if isinstance (arg , str ):
@@ -56,15 +65,11 @@ def __init__(self, *args: FileSourceType, fs: Optional[AbstractFileSystem] = Non
56
65
self .path = arg
57
66
self .load_folder (arg )
58
67
else :
59
- self .path = None
60
68
self .load_file (file = arg )
61
69
62
70
if len (self .files ) == 1 :
63
71
self .file = list (self .files .values ())[0 ]
64
72
65
- if self .path == "" :
66
- self .path = os .getcwd ()
67
-
68
73
def load_files (self , files : List [str ]):
69
74
"""Loads all files (list) into the Environment and merges .split files for common usage."""
70
75
self .load_assets (files , lambda x : open (x , "rb" ))
@@ -80,12 +85,12 @@ def load(self, files: List[str]):
80
85
)
81
86
82
87
def _load_split_file (self , basename : str ) -> bytes :
83
- file : list [ str ] = []
88
+ file : List [ bytes ] = []
84
89
for i in range (0 , 999 ):
85
90
item = f"{ basename } .split{ i } "
86
91
if self .fs .exists (item ):
87
92
with self .fs .open (item , "rb" ) as f :
88
- file .append (f .read ())
93
+ file .append (f .read ()) # type: ignore
89
94
elif i :
90
95
break
91
96
return b"" .join (file )
@@ -119,10 +124,13 @@ def load_file(
119
124
# Unity paths are case insensitive,
120
125
# so we need to find "Resources/Foo.asset" when the record says "resources/foo.asset"
121
126
elif not os .path .exists (file ):
122
- file = find_sensitive_path (self .path , file )
123
- # nonexistent files might be packaging errors or references to Unity's global Library/
124
- if file is None :
125
- return
127
+ file_path = find_sensitive_path (self .path , file )
128
+ if file_path :
129
+ file = file_path
130
+ else :
131
+ return None
132
+ # raise FileNotFoundError(f"File {file} not found in {self.path}")
133
+
126
134
if isinstance (file , str ):
127
135
file = self .fs .open (file , "rb" )
128
136
@@ -134,7 +142,7 @@ def load_file(
134
142
else getattr (
135
143
file ,
136
144
"name" ,
137
- str (file .__hash__ ()) if hasattr (file , "__hash__" ) else "" ,
145
+ str (file .__hash__ ()) if hasattr (file , "__hash__" ) else "" , # type: ignore
138
146
)
139
147
)
140
148
@@ -150,16 +158,17 @@ def load_file(
150
158
return f
151
159
152
160
def load_zip_file (self , value ):
153
- buffer = None
154
161
if isinstance (value , str ) and self .fs .exists (value ):
155
- buffer = open (value , "rb" )
156
- elif isinstance (value , (bytes , bytearray )):
162
+ buffer = cast ( io . BufferedReader , self . fs . open (value , "rb" ) )
163
+ elif isinstance (value , (bytes , bytearray , memoryview )):
157
164
buffer = io .BytesIO (value )
158
165
elif isinstance (value , (io .BufferedReader , io .BufferedIOBase )):
159
166
buffer = value
167
+ else :
168
+ raise TypeError ("Unsupported type for loading zip file" )
160
169
161
170
z = ZipFile (buffer )
162
- self .load_assets (z .namelist (), lambda x : z .open (x , "r" ))
171
+ self .load_assets (z .namelist (), lambda x : z .open (x , "r" )) # type: ignore
163
172
z .close ()
164
173
165
174
def save (self , pack = "none" , out_path = "output" ):
@@ -195,14 +204,14 @@ def search(item):
195
204
return search (self )
196
205
197
206
@property
198
- def container (self ) -> Dict [ str , ObjectReader ] :
207
+ def container (self ) -> ContainerHelper :
199
208
"""Returns a dictionary of all objects in the Environment."""
200
- return {
201
- path : obj
202
- for f in self . files . values ()
203
- if isinstance ( f , File ) and not f . is_dependency
204
- for path , obj in f . container . items ()
205
- }
209
+ container = []
210
+ for f in self . cabs . values ():
211
+ if isinstance ( f , SerializedFile ) and not f . is_dependency :
212
+ container . extend ( f . container . container )
213
+
214
+ return ContainerHelper ( container )
206
215
207
216
@property
208
217
def assets (self ) -> list :
@@ -228,7 +237,7 @@ def gen_all_asset_files(file, ret: Optional[list] = None):
228
237
def get (self , key : str , default = None ):
229
238
return getattr (self , key , default )
230
239
231
- def register_cab (self , name : str , item : File ) -> None :
240
+ def register_cab (self , name : str , item : Union [ SerializedFile , EndianBinaryReader ] ) -> None :
232
241
"""
233
242
Registers a cab file.
234
243
@@ -241,7 +250,7 @@ def register_cab(self, name: str, item: File) -> None:
241
250
"""
242
251
self .cabs [simplify_name (name )] = item
243
252
244
- def get_cab (self , name : str ) -> File :
253
+ def get_cab (self , name : str ) -> Union [ SerializedFile , EndianBinaryReader , None ] :
245
254
"""
246
255
Returns the cab file with the given name.
247
256
@@ -257,7 +266,7 @@ def get_cab(self, name: str) -> File:
257
266
"""
258
267
return self .cabs .get (simplify_name (name ), None )
259
268
260
- def load_assets (self , assets : List [str ], open_f : Callable [[str ], io . IOBase ]):
269
+ def load_assets (self , assets : List [str ], open_f : Callable [[str ], BinaryIO ]):
261
270
"""
262
271
Load all assets from a list of files via the given open_f function.
263
272
0 commit comments