table-stream 0.1.7__tar.gz → 0.1.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {table_stream-0.1.7 → table_stream-0.1.9}/PKG-INFO +1 -1
- {table_stream-0.1.7 → table_stream-0.1.9}/pyproject.toml +1 -1
- table_stream-0.1.9/table_stream/__init__.py +91 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/sysfiles.py +170 -154
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream.egg-info/PKG-INFO +1 -1
- table_stream-0.1.7/table_stream/__init__.py +0 -50
- {table_stream-0.1.7 → table_stream-0.1.9}/README.md +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/setup.cfg +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/erros.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/hash_map.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/notifier.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/pattner/__init__.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/pattner/adapter.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/sheet/__init__.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/sheet/check_mod.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/sheet/load.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/sheet/options.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/sheet/parse.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/sheet/save.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/state.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/table.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/thread.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream/workbook.py +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream.egg-info/SOURCES.txt +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream.egg-info/dependency_links.txt +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream.egg-info/requires.txt +0 -0
- {table_stream-0.1.7 → table_stream-0.1.9}/table_stream.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from .hash_map import (
|
|
2
|
+
HashMap,
|
|
3
|
+
hashMapName,
|
|
4
|
+
HashMapDataFrame,
|
|
5
|
+
HashMapDict,
|
|
6
|
+
ArrayList,
|
|
7
|
+
K,
|
|
8
|
+
T,
|
|
9
|
+
BaseObjetct,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from .notifier import ResultNotifier, Notifier, Listener
|
|
13
|
+
|
|
14
|
+
from .thread import (
|
|
15
|
+
ControllerThread,
|
|
16
|
+
ThreadStateValue,
|
|
17
|
+
exceptionValue,
|
|
18
|
+
stateName,
|
|
19
|
+
EventState,
|
|
20
|
+
InvalidStateTransition,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
from .sheet import (
|
|
24
|
+
SheetLoader,
|
|
25
|
+
InterfaceSheetLoad,
|
|
26
|
+
ParserData,
|
|
27
|
+
CsvOptions,
|
|
28
|
+
SplitData,
|
|
29
|
+
csvEncoding,
|
|
30
|
+
csvSeparator,
|
|
31
|
+
OptionsIOSheet,
|
|
32
|
+
SaveData,
|
|
33
|
+
FactorySaveData,
|
|
34
|
+
FactorySheetLoader,
|
|
35
|
+
SheetType,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
from .sysfiles import (
|
|
39
|
+
File,
|
|
40
|
+
Directory,
|
|
41
|
+
ContentFiles,
|
|
42
|
+
JsonConvert,
|
|
43
|
+
JsonData,
|
|
44
|
+
EnumDocuments,
|
|
45
|
+
ExtensionDocuments,
|
|
46
|
+
UserFileSystem,
|
|
47
|
+
PathElement,
|
|
48
|
+
create_table_from_file,
|
|
49
|
+
load_file_hash,
|
|
50
|
+
HeaderMetaData,
|
|
51
|
+
create_void_table_files,
|
|
52
|
+
hashFile,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
from .state import (
|
|
56
|
+
StateValue,
|
|
57
|
+
EventState,
|
|
58
|
+
ErrorState,
|
|
59
|
+
FinshState,
|
|
60
|
+
InvalidStateTransition,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
from .table import (
|
|
64
|
+
ColumnV,
|
|
65
|
+
RowH,
|
|
66
|
+
TableEmptyError,
|
|
67
|
+
EmptyRowError,
|
|
68
|
+
ColumnNotFoundError,
|
|
69
|
+
HeaderNotFoundError,
|
|
70
|
+
HeadersSizeNotIqualError,
|
|
71
|
+
concat_tables,
|
|
72
|
+
RowNotExistError,
|
|
73
|
+
TableData,
|
|
74
|
+
ListTablesEmptyError,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
from .erros import (
|
|
78
|
+
ColumnNotFoudError,
|
|
79
|
+
ColumnNotIqualSizeError,
|
|
80
|
+
SizeTableError,
|
|
81
|
+
EmptyRowError,
|
|
82
|
+
RowNotExistError,
|
|
83
|
+
TableEmptyError,
|
|
84
|
+
ListTablesEmptyError,
|
|
85
|
+
LoadWorkbookError,
|
|
86
|
+
NotImplementedModuleError,
|
|
87
|
+
HeaderNotFoundError,
|
|
88
|
+
HeadersSizeNotIqualError,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
__version__ = "0.1.9"
|
|
@@ -6,10 +6,10 @@ Atualizações:
|
|
|
6
6
|
- 2026-09-14
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
Dependência interna:
|
|
9
|
+
Dependência interna:
|
|
10
10
|
table_stream.hash_map
|
|
11
11
|
table_stream.table
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
@@ -23,7 +23,7 @@ from dataclasses import dataclass
|
|
|
23
23
|
import hashlib
|
|
24
24
|
|
|
25
25
|
from table_stream.hash_map import ArrayList, HashMapDict
|
|
26
|
-
from table_stream.table import
|
|
26
|
+
from table_stream.table import TableData, ColumnV, RowH
|
|
27
27
|
|
|
28
28
|
# Windows / Linux / ...
|
|
29
29
|
KERNEL_TYPE = platform.system()
|
|
@@ -31,46 +31,53 @@ KERNEL_TYPE = platform.system()
|
|
|
31
31
|
|
|
32
32
|
class ExtensionDocuments(StrEnum):
|
|
33
33
|
|
|
34
|
-
PNG =
|
|
35
|
-
JPG =
|
|
36
|
-
JPEG =
|
|
37
|
-
SVG =
|
|
38
|
-
PDF =
|
|
39
|
-
XLSX =
|
|
40
|
-
XLS =
|
|
41
|
-
CSV =
|
|
42
|
-
TXT =
|
|
43
|
-
ODS =
|
|
44
|
-
JSON =
|
|
45
|
-
DIR =
|
|
34
|
+
PNG = ".png"
|
|
35
|
+
JPG = ".jpg"
|
|
36
|
+
JPEG = ".jpeg"
|
|
37
|
+
SVG = ".svg"
|
|
38
|
+
PDF = ".pdf"
|
|
39
|
+
XLSX = ".xlsx"
|
|
40
|
+
XLS = ".xls"
|
|
41
|
+
CSV = ".csv"
|
|
42
|
+
TXT = ".txt"
|
|
43
|
+
ODS = ".ods"
|
|
44
|
+
JSON = ".json"
|
|
45
|
+
DIR = ".dir"
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
class EnumDocuments(Enum):
|
|
49
49
|
"""
|
|
50
|
-
|
|
50
|
+
Enum para tipos de documentos como imagens, PDFs, Planilhas e JSON.
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
|
-
IMAGE = [
|
|
54
|
-
PDF = [
|
|
55
|
-
DOCUMENTS = [
|
|
53
|
+
IMAGE = [".png", ".jpg", ".jpeg", ".svg"]
|
|
54
|
+
PDF = [".pdf"]
|
|
55
|
+
DOCUMENTS = [".png", ".jpg", ".jpeg", ".svg", ".pdf"]
|
|
56
56
|
#
|
|
57
|
-
EXCEL = [
|
|
58
|
-
CSV = [
|
|
59
|
-
TXT = [
|
|
60
|
-
ODS = [
|
|
57
|
+
EXCEL = [".xlsx", ".xls"]
|
|
58
|
+
CSV = [".csv", ".txt"]
|
|
59
|
+
TXT = [".txt"]
|
|
60
|
+
ODS = [".ods"]
|
|
61
61
|
#
|
|
62
|
-
SHEET = [
|
|
63
|
-
JSON = [
|
|
62
|
+
SHEET = [".csv", ".txt", ".xlsx", ".xls", ".ods"]
|
|
63
|
+
JSON = [".json"]
|
|
64
64
|
#
|
|
65
|
-
ZIP=[
|
|
65
|
+
ZIP = [".zip"]
|
|
66
66
|
#
|
|
67
67
|
ALL_DOCUMENTS = [
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
".png",
|
|
69
|
+
".jpg",
|
|
70
|
+
".jpeg",
|
|
71
|
+
".svg",
|
|
72
|
+
".csv",
|
|
73
|
+
".txt",
|
|
74
|
+
".xlsx",
|
|
75
|
+
".xls",
|
|
76
|
+
".ods",
|
|
77
|
+
".pdf",
|
|
78
|
+
".json",
|
|
79
|
+
".zip",
|
|
80
|
+
".*",
|
|
74
81
|
]
|
|
75
82
|
#
|
|
76
83
|
ALL = "ALL"
|
|
@@ -78,64 +85,71 @@ class EnumDocuments(Enum):
|
|
|
78
85
|
@property
|
|
79
86
|
def values(self) -> list[str]:
|
|
80
87
|
return [
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
".png",
|
|
89
|
+
".jpg",
|
|
90
|
+
".jpeg",
|
|
91
|
+
".svg",
|
|
92
|
+
".csv",
|
|
93
|
+
".txt",
|
|
94
|
+
".xlsx",
|
|
95
|
+
".xls",
|
|
96
|
+
".ods",
|
|
97
|
+
".pdf",
|
|
98
|
+
".json",
|
|
99
|
+
".zip",
|
|
100
|
+
".*",
|
|
101
|
+
]
|
|
88
102
|
|
|
89
103
|
|
|
90
104
|
class PathElement(ABC):
|
|
91
|
-
|
|
105
|
+
|
|
92
106
|
def __init__(self, path: str) -> None:
|
|
93
107
|
super().__init__()
|
|
94
108
|
self._path: str = os.path.abspath(path)
|
|
95
|
-
|
|
109
|
+
|
|
96
110
|
@abstractmethod
|
|
97
111
|
def basename(self) -> str:
|
|
98
112
|
pass
|
|
99
|
-
|
|
113
|
+
|
|
100
114
|
@abstractmethod
|
|
101
115
|
def name(self) -> str:
|
|
102
116
|
pass
|
|
103
|
-
|
|
117
|
+
|
|
104
118
|
@abstractmethod
|
|
105
119
|
def absolute(self) -> str:
|
|
106
120
|
pass
|
|
107
|
-
|
|
121
|
+
|
|
108
122
|
@abstractmethod
|
|
109
123
|
def is_file(self) -> bool:
|
|
110
124
|
pass
|
|
111
|
-
|
|
125
|
+
|
|
112
126
|
@abstractmethod
|
|
113
127
|
def is_dir(self) -> bool:
|
|
114
128
|
pass
|
|
115
|
-
|
|
129
|
+
|
|
116
130
|
@abstractmethod
|
|
117
131
|
def exists(self) -> bool:
|
|
118
132
|
pass
|
|
119
|
-
|
|
133
|
+
|
|
120
134
|
@abstractmethod
|
|
121
135
|
def parent(self) -> Directory:
|
|
122
136
|
pass
|
|
123
|
-
|
|
137
|
+
|
|
124
138
|
@abstractmethod
|
|
125
139
|
def extension(self) -> str:
|
|
126
140
|
pass
|
|
127
141
|
|
|
128
142
|
|
|
129
143
|
class File(PathElement):
|
|
130
|
-
|
|
144
|
+
|
|
131
145
|
def __init__(self, path: str) -> None:
|
|
132
146
|
super().__init__(path)
|
|
133
|
-
|
|
147
|
+
|
|
134
148
|
if os.path.isdir(path):
|
|
135
|
-
raise ValueError(f
|
|
136
|
-
|
|
149
|
+
raise ValueError(f"{__class__.__name__} File() não pode ser um diretório.")
|
|
150
|
+
|
|
137
151
|
def __repr__(self):
|
|
138
|
-
return f
|
|
152
|
+
return f"{__class__.__name__}(): {self.absolute()}"
|
|
139
153
|
|
|
140
154
|
def __eq__(self, value: File):
|
|
141
155
|
if not isinstance(value, File):
|
|
@@ -193,37 +207,37 @@ class File(PathElement):
|
|
|
193
207
|
extensão informada.
|
|
194
208
|
"""
|
|
195
209
|
current = self.extension()
|
|
196
|
-
full_path = self.absolute().replace(current,
|
|
197
|
-
return File(os.path.join(f
|
|
198
|
-
|
|
210
|
+
full_path = self.absolute().replace(current, "")
|
|
211
|
+
return File(os.path.join(f"{full_path}{e}"))
|
|
212
|
+
|
|
199
213
|
def parent(self) -> Directory:
|
|
200
214
|
return Directory(self.dirname())
|
|
201
215
|
|
|
202
216
|
def get_text(self) -> str | None:
|
|
203
217
|
try:
|
|
204
|
-
with open(self.absolute(),
|
|
218
|
+
with open(self.absolute(), "rt") as fp:
|
|
205
219
|
return fp.read()
|
|
206
220
|
except Exception as e:
|
|
207
|
-
print(f
|
|
221
|
+
print(f"{__class__.__name__} {e}")
|
|
208
222
|
return None
|
|
209
223
|
|
|
210
224
|
def name(self):
|
|
211
225
|
e = self.extension()
|
|
212
|
-
if (e is None) or (e ==
|
|
226
|
+
if (e is None) or (e == ""):
|
|
213
227
|
return os.path.basename(self._path)
|
|
214
|
-
return os.path.basename(self._path).replace(e,
|
|
228
|
+
return os.path.basename(self._path).replace(e, "")
|
|
215
229
|
|
|
216
230
|
def name_absolute(self) -> str:
|
|
217
231
|
e = self.extension()
|
|
218
|
-
if (e is None) or (e ==
|
|
232
|
+
if (e is None) or (e == ""):
|
|
219
233
|
return self._path
|
|
220
|
-
return self._path.replace(e,
|
|
234
|
+
return self._path.replace(e, "")
|
|
221
235
|
|
|
222
236
|
def extension(self) -> str:
|
|
223
237
|
"""
|
|
224
238
|
Retorna .pdf, .jpg, .png, .xlsx, .txt etc
|
|
225
239
|
"""
|
|
226
|
-
|
|
240
|
+
|
|
227
241
|
try:
|
|
228
242
|
return os.path.splitext(self.absolute())[1]
|
|
229
243
|
except:
|
|
@@ -252,18 +266,18 @@ class File(PathElement):
|
|
|
252
266
|
|
|
253
267
|
|
|
254
268
|
class Directory(PathElement):
|
|
255
|
-
|
|
269
|
+
|
|
256
270
|
def __init__(self, path: str) -> None:
|
|
257
271
|
super().__init__(path)
|
|
258
|
-
|
|
272
|
+
|
|
259
273
|
if os.path.isfile(path):
|
|
260
|
-
raise ValueError(f
|
|
274
|
+
raise ValueError(f"{__class__.__name__}() não pode ser um arquivo.")
|
|
261
275
|
|
|
262
276
|
def absolute(self) -> str:
|
|
263
277
|
return self._path
|
|
264
278
|
|
|
265
279
|
def __repr__(self):
|
|
266
|
-
return f
|
|
280
|
+
return f"{__class__.__name__}(): {self.absolute()}"
|
|
267
281
|
|
|
268
282
|
def __eq__(self, value):
|
|
269
283
|
if not isinstance(value, Directory):
|
|
@@ -272,7 +286,7 @@ class Directory(PathElement):
|
|
|
272
286
|
|
|
273
287
|
def __hash__(self):
|
|
274
288
|
return self.absolute().__hash__()
|
|
275
|
-
|
|
289
|
+
|
|
276
290
|
def extension(self) -> str:
|
|
277
291
|
return ".dir"
|
|
278
292
|
|
|
@@ -294,24 +308,20 @@ class Directory(PathElement):
|
|
|
294
308
|
def __content_recursive(self) -> ArrayList[File]:
|
|
295
309
|
_paths: ArrayList[str] = self.get_files()
|
|
296
310
|
values: ArrayList[File] = ArrayList()
|
|
297
|
-
|
|
311
|
+
|
|
298
312
|
for file_path in _paths:
|
|
299
313
|
if os.path.isfile(file_path):
|
|
300
|
-
values.append(
|
|
301
|
-
File(os.path.abspath(file_path))
|
|
302
|
-
)
|
|
314
|
+
values.append(File(os.path.abspath(file_path)))
|
|
303
315
|
return values
|
|
304
316
|
|
|
305
317
|
def __content_no_recursive(self) -> ArrayList[File]:
|
|
306
318
|
content_files: ArrayList[str] = ArrayList(os.listdir(self.absolute()))
|
|
307
319
|
values: ArrayList[File] = ArrayList()
|
|
308
|
-
|
|
320
|
+
|
|
309
321
|
for file in content_files:
|
|
310
322
|
fp: str = os.path.join(self.absolute(), file)
|
|
311
323
|
if os.path.isfile(fp):
|
|
312
|
-
values.append(
|
|
313
|
-
File(os.path.abspath(fp))
|
|
314
|
-
)
|
|
324
|
+
values.append(File(os.path.abspath(fp)))
|
|
315
325
|
return values
|
|
316
326
|
|
|
317
327
|
def content_files(self, *, recursive: bool = True) -> ArrayList[File]:
|
|
@@ -324,23 +334,19 @@ class Directory(PathElement):
|
|
|
324
334
|
retorna uma lista de diretórios
|
|
325
335
|
"""
|
|
326
336
|
values: ArrayList[Directory] = ArrayList()
|
|
327
|
-
|
|
337
|
+
|
|
328
338
|
if recursive:
|
|
329
339
|
_paths = self.get_files()
|
|
330
|
-
|
|
340
|
+
|
|
331
341
|
for p in _paths:
|
|
332
342
|
if os.path.isdir(p):
|
|
333
|
-
values.append(
|
|
334
|
-
Directory(os.path.abspath(p))
|
|
335
|
-
)
|
|
343
|
+
values.append(Directory(os.path.abspath(p)))
|
|
336
344
|
else:
|
|
337
345
|
_paths = os.listdir(self.absolute())
|
|
338
346
|
for d in _paths:
|
|
339
347
|
_dirpath = os.path.join(self.absolute(), d)
|
|
340
348
|
if os.path.isdir(_dirpath):
|
|
341
|
-
values.append(
|
|
342
|
-
Directory(os.path.abspath(_dirpath))
|
|
343
|
-
)
|
|
349
|
+
values.append(Directory(os.path.abspath(_dirpath)))
|
|
344
350
|
return values
|
|
345
351
|
|
|
346
352
|
def basename(self) -> str:
|
|
@@ -362,17 +368,13 @@ class Directory(PathElement):
|
|
|
362
368
|
return Directory(os.path.join(self.absolute(), d))
|
|
363
369
|
|
|
364
370
|
def parent(self) -> Directory:
|
|
365
|
-
return Directory(
|
|
366
|
-
os.path.abspath(os.path.dirname(self.absolute()))
|
|
367
|
-
)
|
|
371
|
+
return Directory(os.path.abspath(os.path.dirname(self.absolute())))
|
|
368
372
|
|
|
369
373
|
def join_file(self, name: str) -> File:
|
|
370
374
|
if name is None or name == "":
|
|
371
|
-
raise ValueError(f
|
|
372
|
-
|
|
373
|
-
return File(
|
|
374
|
-
os.path.join(self.absolute(), name)
|
|
375
|
-
)
|
|
375
|
+
raise ValueError(f"{__class__.__name__} Nome de arquivo vazio: {name}")
|
|
376
|
+
|
|
377
|
+
return File(os.path.join(self.absolute(), name))
|
|
376
378
|
|
|
377
379
|
def name(self) -> str:
|
|
378
380
|
return self.basename()
|
|
@@ -382,19 +384,19 @@ class Directory(PathElement):
|
|
|
382
384
|
|
|
383
385
|
def is_dir(self) -> bool:
|
|
384
386
|
return True
|
|
385
|
-
|
|
387
|
+
|
|
386
388
|
def exists(self) -> bool:
|
|
387
389
|
return os.path.exists(self.absolute())
|
|
388
390
|
|
|
389
391
|
|
|
390
392
|
class ContentFiles(object):
|
|
391
393
|
"""
|
|
392
|
-
|
|
394
|
+
Obter uma lista de arquivos/documentos do diretório informado.
|
|
393
395
|
"""
|
|
394
396
|
|
|
395
397
|
def __init__(self, d: Directory, *, max_files: int = 5000):
|
|
396
398
|
if not isinstance(d, Directory):
|
|
397
|
-
raise ValueError(f
|
|
399
|
+
raise ValueError(f"{__class__.__name__}\nUse: Directory(), não {type(d)}")
|
|
398
400
|
self._input_dir: Directory = d
|
|
399
401
|
self._max_files: int = max_files
|
|
400
402
|
|
|
@@ -409,21 +411,19 @@ class ContentFiles(object):
|
|
|
409
411
|
|
|
410
412
|
def get_files_with(self, *, infile: str, sort: bool = True) -> ArrayList[File]:
|
|
411
413
|
"""
|
|
412
|
-
|
|
414
|
+
Retorna arquivos que contém a ocorrência (infile) no nome absoluto.
|
|
413
415
|
"""
|
|
414
416
|
content_files: ArrayList[File] = ArrayList()
|
|
415
417
|
count: int = 0
|
|
416
418
|
paths: list[str] = self._input_dir.get_files()
|
|
417
419
|
file: str
|
|
418
|
-
|
|
420
|
+
|
|
419
421
|
for file in paths:
|
|
420
422
|
if not os.path.isfile(file):
|
|
421
423
|
continue
|
|
422
|
-
|
|
424
|
+
|
|
423
425
|
if infile in os.path.abspath(file):
|
|
424
|
-
content_files.append(
|
|
425
|
-
File(os.path.abspath(file))
|
|
426
|
-
)
|
|
426
|
+
content_files.append(File(os.path.abspath(file)))
|
|
427
427
|
count += 1
|
|
428
428
|
if count >= self._max_files:
|
|
429
429
|
break
|
|
@@ -431,20 +431,20 @@ class ContentFiles(object):
|
|
|
431
431
|
content_files.sort()
|
|
432
432
|
return content_files
|
|
433
433
|
|
|
434
|
-
def __get_files_recursive(
|
|
434
|
+
def __get_files_recursive(
|
|
435
|
+
self, *, file_type: EnumDocuments, sort: bool
|
|
436
|
+
) -> list[File]:
|
|
435
437
|
#
|
|
436
438
|
_paths: list[str] = self._input_dir.get_files()
|
|
437
439
|
_all_files: list[File] = list()
|
|
438
440
|
count: int = 0
|
|
439
|
-
|
|
441
|
+
|
|
440
442
|
if file_type == EnumDocuments.ALL:
|
|
441
443
|
# Todos os tipos de arquivos
|
|
442
444
|
for p in _paths:
|
|
443
445
|
if not os.path.isfile(p):
|
|
444
446
|
continue
|
|
445
|
-
_all_files.append(
|
|
446
|
-
File(os.path.abspath(p))
|
|
447
|
-
)
|
|
447
|
+
_all_files.append(File(os.path.abspath(p)))
|
|
448
448
|
count += 1
|
|
449
449
|
if count >= self._max_files:
|
|
450
450
|
break
|
|
@@ -455,21 +455,23 @@ class ContentFiles(object):
|
|
|
455
455
|
continue
|
|
456
456
|
|
|
457
457
|
file_suffix = os.path.splitext(p)[1]
|
|
458
|
-
|
|
459
|
-
if (file_suffix is None) or (file_suffix ==
|
|
458
|
+
|
|
459
|
+
if (file_suffix is None) or (file_suffix == ""):
|
|
460
460
|
continue
|
|
461
|
-
|
|
461
|
+
|
|
462
462
|
if file_suffix in file_type.value:
|
|
463
463
|
_all_files.append(File(os.path.abspath(p)))
|
|
464
464
|
count += 1
|
|
465
|
-
|
|
465
|
+
|
|
466
466
|
if count >= self._max_files:
|
|
467
467
|
break
|
|
468
468
|
if sort:
|
|
469
469
|
_all_files.sort(key=File.absolute)
|
|
470
470
|
return _all_files
|
|
471
471
|
|
|
472
|
-
def __get_files_no_recursive(
|
|
472
|
+
def __get_files_no_recursive(
|
|
473
|
+
self, *, file_type: EnumDocuments, sort: bool
|
|
474
|
+
) -> list[File]:
|
|
473
475
|
_content_files: list[File] = self._input_dir.content_files(recursive=False)
|
|
474
476
|
_all_files: list[File] = []
|
|
475
477
|
count: int = 0
|
|
@@ -494,19 +496,19 @@ class ContentFiles(object):
|
|
|
494
496
|
return _all_files
|
|
495
497
|
|
|
496
498
|
def get_files(
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
499
|
+
self,
|
|
500
|
+
file_type: EnumDocuments = EnumDocuments.ALL_DOCUMENTS,
|
|
501
|
+
*,
|
|
502
|
+
sort: bool = True,
|
|
503
|
+
recursive: bool = True,
|
|
504
|
+
) -> ArrayList[File]:
|
|
503
505
|
"""
|
|
504
506
|
Retorna uma lista de File() conforme o tipo de arquivo
|
|
505
507
|
especificado.
|
|
506
508
|
- LibraryDocs.ALL_DOCUMENTS => Retorna todos os documentos do diretório.
|
|
507
509
|
- LibraryDocs.EXCEL => Retorna arquivos que são planilhas excel.
|
|
508
510
|
- ...
|
|
509
|
-
|
|
511
|
+
|
|
510
512
|
"""
|
|
511
513
|
if recursive:
|
|
512
514
|
return ArrayList(self.__get_files_recursive(file_type=file_type, sort=sort))
|
|
@@ -515,35 +517,37 @@ class ContentFiles(object):
|
|
|
515
517
|
|
|
516
518
|
class JsonData(object):
|
|
517
519
|
"""
|
|
518
|
-
|
|
520
|
+
Representação de um dado JSON apartir de uma string python.
|
|
519
521
|
"""
|
|
520
522
|
|
|
521
523
|
def __init__(self, string: str):
|
|
522
524
|
if not isinstance(string, str):
|
|
523
|
-
raise ValueError(
|
|
525
|
+
raise ValueError(
|
|
526
|
+
f"{__class__.__name__} o JSON informado precisa ser do tipo string, não {type(string)}"
|
|
527
|
+
)
|
|
524
528
|
self.jsonString: str = string
|
|
525
529
|
|
|
526
530
|
def is_null(self) -> bool:
|
|
527
|
-
if (self.jsonString is None) or (self.jsonString ==
|
|
531
|
+
if (self.jsonString is None) or (self.jsonString == ""):
|
|
528
532
|
return True
|
|
529
533
|
return False
|
|
530
534
|
|
|
531
535
|
def to_dict(self) -> dict[str, Any]:
|
|
532
536
|
"""
|
|
533
|
-
|
|
537
|
+
Exportar/Converter o dado atual em um dicionário python.
|
|
534
538
|
"""
|
|
535
539
|
return json.loads(self.jsonString)
|
|
536
540
|
|
|
537
541
|
def to_file(self, f: File):
|
|
538
542
|
"""Exportar o dado atual para um arquivo.json"""
|
|
539
543
|
_data: str = json.loads(self.jsonString)
|
|
540
|
-
with open(f.absolute(),
|
|
544
|
+
with open(f.absolute(), "w", encoding="utf-8") as file:
|
|
541
545
|
json.dump(_data, file, indent=4, ensure_ascii=False)
|
|
542
546
|
|
|
543
547
|
|
|
544
548
|
class JsonConvert(object):
|
|
545
549
|
"""
|
|
546
|
-
|
|
550
|
+
Conversão de um dado JSON em dados python
|
|
547
551
|
"""
|
|
548
552
|
|
|
549
553
|
def __init__(self, data: JsonData):
|
|
@@ -552,7 +556,7 @@ class JsonConvert(object):
|
|
|
552
556
|
@classmethod
|
|
553
557
|
def from_file(cls, file: File) -> JsonConvert:
|
|
554
558
|
"""
|
|
555
|
-
|
|
559
|
+
Gerar um dado JsonData apartir de arquivo .json
|
|
556
560
|
"""
|
|
557
561
|
# Ler o arquivo e carregar o JSON em um dicionário Python
|
|
558
562
|
data = None
|
|
@@ -560,15 +564,17 @@ class JsonConvert(object):
|
|
|
560
564
|
with open(file.absolute(), "r", encoding="utf-8") as fp:
|
|
561
565
|
data: str = json.load(fp)
|
|
562
566
|
except Exception as e:
|
|
563
|
-
print(f
|
|
564
|
-
return cls(JsonData(
|
|
567
|
+
print(f"{__class__.__name__}\n{e}")
|
|
568
|
+
return cls(JsonData(""))
|
|
565
569
|
else:
|
|
566
|
-
return cls(
|
|
570
|
+
return cls(
|
|
571
|
+
JsonData(json.dumps(data, indent=4, ensure_ascii=False, sort_keys=True))
|
|
572
|
+
)
|
|
567
573
|
|
|
568
574
|
@classmethod
|
|
569
575
|
def from_string_json(cls, data: str) -> JsonConvert:
|
|
570
576
|
"""
|
|
571
|
-
|
|
577
|
+
Gerar um dado JsonData apartir de uma string.
|
|
572
578
|
"""
|
|
573
579
|
json_string = json.dumps(data, indent=4, ensure_ascii=False, sort_keys=True)
|
|
574
580
|
return cls(JsonData(json_string))
|
|
@@ -576,17 +582,19 @@ class JsonConvert(object):
|
|
|
576
582
|
@classmethod
|
|
577
583
|
def from_dict(cls, data: dict[str, object]) -> JsonConvert:
|
|
578
584
|
"""
|
|
579
|
-
|
|
585
|
+
Converte um dicionário em objeto JSON/JsonData.
|
|
580
586
|
"""
|
|
581
587
|
if not isinstance(data, dict):
|
|
582
|
-
raise ValueError(
|
|
588
|
+
raise ValueError(
|
|
589
|
+
f"{__class__.__name__} Informe um JSON em formato dict, não {type(data)}"
|
|
590
|
+
)
|
|
583
591
|
json_string = json.dumps(data, indent=4, ensure_ascii=False, sort_keys=True)
|
|
584
592
|
return cls(JsonData(json_string))
|
|
585
593
|
|
|
586
594
|
|
|
587
595
|
class UserFileSystem(object):
|
|
588
596
|
"""
|
|
589
|
-
|
|
597
|
+
Diretórios comuns para cache e configurações de usuário.
|
|
590
598
|
"""
|
|
591
599
|
|
|
592
600
|
def __init__(self, base_home: Directory = None):
|
|
@@ -594,16 +602,18 @@ class UserFileSystem(object):
|
|
|
594
602
|
if self.__base_home is None:
|
|
595
603
|
# _home = Directory(os.path.expanduser("~"))
|
|
596
604
|
# HOME (Unix) / USERPROFILE (Windows)
|
|
597
|
-
_home_str: str = os.environ.get(
|
|
605
|
+
_home_str: str = os.environ.get("HOME") or os.environ.get("USERPROFILE")
|
|
598
606
|
if _home_str is None or _home_str == "":
|
|
599
607
|
_home_str = os.path.expanduser("~")
|
|
600
|
-
|
|
608
|
+
|
|
601
609
|
self.__base_home = Directory(_home_str)
|
|
602
|
-
self.__user_downloads: Directory = self.__base_home.concat(
|
|
603
|
-
|
|
610
|
+
self.__user_downloads: Directory = self.__base_home.concat(
|
|
611
|
+
"Downloads", create=True
|
|
612
|
+
)
|
|
613
|
+
self.__user_var_dir: Directory = self.__base_home.concat("var", create=True)
|
|
604
614
|
|
|
605
615
|
def __repr__(self):
|
|
606
|
-
return f
|
|
616
|
+
return f"<{__class__.__name__}()>: Home {self.get_user_home()}"
|
|
607
617
|
|
|
608
618
|
def get_user_dir_var(self) -> Directory:
|
|
609
619
|
return self.__user_var_dir
|
|
@@ -616,10 +626,10 @@ class UserFileSystem(object):
|
|
|
616
626
|
|
|
617
627
|
def set_user_downloads(self, d: Directory) -> None:
|
|
618
628
|
self.__user_downloads = d
|
|
619
|
-
|
|
629
|
+
|
|
620
630
|
def get_user_documents(self) -> Directory:
|
|
621
|
-
d = self.get_user_home().concat(
|
|
622
|
-
return d if d.exists() else self.get_user_home().concat(
|
|
631
|
+
d = self.get_user_home().concat("Documents")
|
|
632
|
+
return d if d.exists() else self.get_user_home().concat("Documentos")
|
|
623
633
|
|
|
624
634
|
def get_user_home(self) -> Directory:
|
|
625
635
|
return self.__base_home
|
|
@@ -628,23 +638,24 @@ class UserFileSystem(object):
|
|
|
628
638
|
self.__base_home = d
|
|
629
639
|
|
|
630
640
|
def config_dir(self) -> Directory:
|
|
631
|
-
return self.__user_var_dir.concat(
|
|
641
|
+
return self.__user_var_dir.concat("config", create=True)
|
|
632
642
|
|
|
633
643
|
def cache_dir(self) -> Directory:
|
|
634
|
-
return self.__user_var_dir.concat(
|
|
644
|
+
return self.__user_var_dir.concat("cache", create=True)
|
|
645
|
+
|
|
635
646
|
|
|
636
647
|
# ================================================================ #
|
|
637
648
|
# Controle de hash md5 em arquivos
|
|
638
649
|
# ================================================================ #
|
|
639
650
|
|
|
640
651
|
|
|
641
|
-
hashFile = NewType(
|
|
652
|
+
hashFile = NewType("hashFile", str)
|
|
642
653
|
|
|
643
654
|
|
|
644
655
|
def load_file_hash(path: File) -> hashFile:
|
|
645
656
|
if not path.exists():
|
|
646
657
|
raise FileNotFoundError(path.absolute())
|
|
647
|
-
|
|
658
|
+
|
|
648
659
|
with open(path.absolute(), "rb") as f:
|
|
649
660
|
digest = hashlib.file_digest(f, "md5")
|
|
650
661
|
|
|
@@ -665,17 +676,18 @@ class MetaDataFile:
|
|
|
665
676
|
|
|
666
677
|
nome_arquivo: str
|
|
667
678
|
extensao_arquivo: ExtensionDocuments
|
|
668
|
-
arquivo: str
|
|
669
|
-
pasta_pai: str
|
|
679
|
+
arquivo: str
|
|
680
|
+
pasta_pai: str
|
|
670
681
|
md5: str = "MD5"
|
|
671
682
|
|
|
672
683
|
|
|
673
|
-
def create_void_table_files() ->
|
|
684
|
+
def create_void_table_files() -> TableData[HeaderMetaData]:
|
|
674
685
|
"""
|
|
675
686
|
Cria uma tabela VAZIA com todas as colunas de HeaderMetaData
|
|
676
687
|
"""
|
|
677
688
|
|
|
678
|
-
tb =
|
|
689
|
+
tb = TableData()
|
|
690
|
+
|
|
679
691
|
tb.add(ColumnV(HeaderMetaData.HASH_FILE))
|
|
680
692
|
tb.add(ColumnV(HeaderMetaData.FILE_NAME))
|
|
681
693
|
tb.add(ColumnV(HeaderMetaData.FILE_EXTENSION))
|
|
@@ -684,19 +696,23 @@ def create_void_table_files() -> TableMap[HeaderMetaData]:
|
|
|
684
696
|
return tb
|
|
685
697
|
|
|
686
698
|
|
|
687
|
-
def create_table_from_file(
|
|
699
|
+
def create_table_from_file(
|
|
700
|
+
file: File, md5: hashFile | None = None
|
|
701
|
+
) -> TableData[HeaderMetaData]:
|
|
688
702
|
"""
|
|
689
703
|
Cria uma tabela de linha única, se o parâmetro md5 for None o arquivo
|
|
690
|
-
deve existir no disco pois a hash será calculada internamente nessa função
|
|
704
|
+
deve existir no disco pois a hash será calculada internamente nessa função
|
|
691
705
|
antes de gerar a tabela, caso contrário será disparado uma exceção: FileNotFoundError()
|
|
692
706
|
"""
|
|
693
|
-
|
|
707
|
+
|
|
694
708
|
if md5 is None:
|
|
695
709
|
if not file.exists():
|
|
696
|
-
raise FileNotFoundError(
|
|
710
|
+
raise FileNotFoundError(
|
|
711
|
+
f"[DEBUG] create_row_table_file(): o arquivo não existe -> {file.absolute()}"
|
|
712
|
+
)
|
|
697
713
|
md5 = load_file_hash(file)
|
|
698
|
-
|
|
699
|
-
tb:
|
|
714
|
+
|
|
715
|
+
tb: TableData[HeaderMetaData] = create_void_table_files()
|
|
700
716
|
|
|
701
717
|
tb.get(HeaderMetaData.FILE_NAME).add(file.name())
|
|
702
718
|
tb.get(HeaderMetaData.FILE_EXTENSION).add(file.extension() or ".nan")
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
from .hash_map import (
|
|
2
|
-
HashMap, hashMapName, HashMapDataFrame, HashMapDict, ArrayList,
|
|
3
|
-
K, T, BaseObjetct
|
|
4
|
-
)
|
|
5
|
-
|
|
6
|
-
from .notifier import ResultNotifier, Notifier, Listener
|
|
7
|
-
|
|
8
|
-
from .thread import (
|
|
9
|
-
ControllerThread, ThreadStateValue, exceptionValue, stateName,
|
|
10
|
-
EventState, InvalidStateTransition,
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
from .sheet import (
|
|
14
|
-
SheetLoader, InterfaceSheetLoad, ParserData, CsvOptions, SplitData,
|
|
15
|
-
csvEncoding, csvSeparator, OptionsIOSheet, SaveData,
|
|
16
|
-
FactorySaveData, FactorySheetLoader, SheetType,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
from .sysfiles import (
|
|
20
|
-
File, Directory, ContentFiles, JsonConvert, JsonData,
|
|
21
|
-
EnumDocuments, ExtensionDocuments, UserFileSystem, PathElement,
|
|
22
|
-
create_table_from_file, load_file_hash, HeaderMetaData, create_void_table_files,
|
|
23
|
-
hashFile
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
from .state import (
|
|
27
|
-
StateValue, EventState, ErrorState, FinshState, InvalidStateTransition
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
from .table import (
|
|
31
|
-
TableMap,
|
|
32
|
-
ColumnV,
|
|
33
|
-
RowH,
|
|
34
|
-
TableEmptyError,
|
|
35
|
-
EmptyRowError,
|
|
36
|
-
ColumnNotFoundError,
|
|
37
|
-
HeaderNotFoundError,
|
|
38
|
-
HeadersSizeNotIqualError,
|
|
39
|
-
concat_tables,
|
|
40
|
-
RowNotExistError,
|
|
41
|
-
TableData,
|
|
42
|
-
ListTablesEmptyError,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
from .erros import (
|
|
46
|
-
ColumnNotFoudError, ColumnNotIqualSizeError,
|
|
47
|
-
SizeTableError, EmptyRowError, RowNotExistError, TableEmptyError,
|
|
48
|
-
ListTablesEmptyError, LoadWorkbookError, NotImplementedModuleError,
|
|
49
|
-
HeaderNotFoundError, HeadersSizeNotIqualError
|
|
50
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|