1
1
import io
2
- import os
3
2
import ntpath
3
+ import os
4
4
import re
5
- from typing import List , Callable , Dict , Union
5
+ from typing import Callable , Dict , List , Optional , Union
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
-
12
- from .files import File , ObjectReader , SerializedFile
13
11
from .enums import FileType
14
- from .helpers import ImportHelper
12
+ from .files import BundleFile , File , ObjectReader , SerializedFile , WebFile
13
+ from .helpers .ImportHelper import (
14
+ FileSourceType ,
15
+ check_file_type ,
16
+ find_sensitive_path ,
17
+ parse_file ,
18
+ )
15
19
from .streams import EndianBinaryReader
16
20
17
21
reSplit = re .compile (r"(.*?([^\/\\]+?))\.split\d+" )
18
22
19
23
20
24
class Environment :
21
- files : dict
22
- cabs : dict
25
+ files : Dict [ str , Union [ SerializedFile , BundleFile , WebFile , EndianBinaryReader ]]
26
+ cabs : Dict [ str , Union [ SerializedFile , EndianBinaryReader ]]
23
27
path : str
24
28
local_files : List [str ]
25
29
local_files_simple : List [str ]
26
30
27
- def __init__ (self , * args , fs : AbstractFileSystem = None ):
31
+ def __init__ (self , * args : FileSourceType , fs : Optional [ AbstractFileSystem ] = None ):
28
32
self .files = {}
29
33
self .cabs = {}
30
34
self .path = None
@@ -71,7 +75,7 @@ def load_folder(self, path: str):
71
75
]
72
76
)
73
77
74
- def load (self , files : list ):
78
+ def load (self , files : List [ str ] ):
75
79
"""Loads all files into the Environment."""
76
80
self .files .update (
77
81
{
@@ -81,8 +85,8 @@ def load(self, files: list):
81
85
}
82
86
)
83
87
84
- def _load_split_file (self , basename ) :
85
- file = []
88
+ def _load_split_file (self , basename : str ) -> bytes :
89
+ file : list [ str ] = []
86
90
for i in range (0 , 999 ):
87
91
item = f"{ basename } .split{ i } "
88
92
if self .fs .exists (item ):
@@ -94,9 +98,9 @@ def _load_split_file(self, basename):
94
98
95
99
def load_file (
96
100
self ,
97
- file : Union [ io . IOBase , str ] ,
98
- parent : Union ["Environment" , File ] = None ,
99
- name : str = None ,
101
+ file : FileSourceType ,
102
+ parent : Optional [ Union ["Environment" , File ] ] = None ,
103
+ name : Optional [ str ] = None ,
100
104
is_dependency : bool = False ,
101
105
):
102
106
if not parent :
@@ -105,9 +109,10 @@ def load_file(
105
109
if isinstance (file , str ):
106
110
split_match = reSplit .match (file )
107
111
if split_match :
108
- basepath , basename = split_match .groups ()
112
+ basepath , _basename = split_match .groups ()
113
+ assert isinstance (basepath , str )
109
114
name = basepath
110
- file = self ._load_split_file (name )
115
+ file = self ._load_split_file (basepath )
111
116
else :
112
117
name = file
113
118
if not os .path .exists (file ):
@@ -119,14 +124,14 @@ def load_file(
119
124
file = self ._load_split_file (file )
120
125
# Unity paths are case insensitive, 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 = ImportHelper . find_sensitive_path (self .path , file )
127
+ file = find_sensitive_path (self .path , file )
123
128
# nonexistent files might be packaging errors or references to Unity's global Library/
124
129
if file is None :
125
130
return
126
131
if type (file ) == str :
127
132
file = self .fs .open (file , "rb" )
128
133
129
- typ , reader = ImportHelper . check_file_type (file )
134
+ typ , reader = check_file_type (file )
130
135
131
136
stream_name = (
132
137
name
@@ -141,15 +146,15 @@ def load_file(
141
146
if typ == FileType .ZIP :
142
147
f = self .load_zip_file (file )
143
148
else :
144
- f = ImportHelper . parse_file (
149
+ f = parse_file (
145
150
reader , self , name = stream_name , typ = typ , is_dependency = is_dependency
146
151
)
147
-
152
+
148
153
if isinstance (f , (SerializedFile , EndianBinaryReader )):
149
154
self .register_cab (stream_name , f )
150
155
151
156
self .files [stream_name ] = f
152
-
157
+ return f
153
158
154
159
def load_zip_file (self , value ):
155
160
buffer = None
@@ -274,7 +279,7 @@ def load_assets(self, assets: List[str], open_f: Callable[[str], io.IOBase]):
274
279
for path in assets :
275
280
splitMatch = reSplit .match (path )
276
281
if splitMatch :
277
- basepath , basename = splitMatch .groups ()
282
+ basepath , _basename = splitMatch .groups ()
278
283
279
284
if basepath in split_files :
280
285
continue
@@ -306,21 +311,33 @@ def find_file(self, name: str, is_dependency: bool = True) -> Union[File, None]:
306
311
cab = self .get_cab (simple_name )
307
312
if cab :
308
313
return cab
314
+ fp = self .fs .sep .join ([self .path , name ])
315
+ if self .fs .exists (fp ):
316
+ return self .load_file (fp , name = name , is_dependency = is_dependency )
309
317
310
318
if len (self .local_files ) == 0 and self .path :
311
319
for root , _ , files in self .fs .walk (self .path ):
312
- for name in files :
313
- self .local_files .append (self .fs .sep .join ([root , name ]))
320
+ for f in files :
321
+ self .local_files .append (self .fs .sep .join ([root , f ]))
322
+ self .local_files_simple .append (
323
+ self .fs .sep .join ([root , simplify_name (f )])
324
+ )
314
325
315
326
if name in self .local_files :
316
327
fp = name
317
328
elif simple_name in self .local_files_simple :
318
329
fp = self .local_files [self .local_files_simple .index (simple_name )]
319
330
else :
320
- raise FileNotFoundError (f"File { name } not found in { self .path } " )
321
-
322
- f = self .load_file (fp , name = name , is_dependency = is_dependency )
323
- return f
331
+ fp = next ((f for f in self .local_files if f .endswith (name )), None )
332
+ if not fp :
333
+ fp = next (
334
+ (f for f in self .local_files_simple if f .endswith (simple_name )),
335
+ None ,
336
+ )
337
+ if not fp :
338
+ raise FileNotFoundError (f"File { name } not found in { self .path } " )
339
+
340
+ return self .load_file (fp , name = name , is_dependency = is_dependency )
324
341
325
342
326
343
def simplify_name (name : str ) -> str :
0 commit comments