pyflutter-app 0.1.7__tar.gz → 0.1.8__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.
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/PKG-INFO +1 -1
- pyflutter_app-0.1.8/converter/file_documents.py +234 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/lib_toi.py +94 -161
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/page_forms/model_forms.py +1 -1
- pyflutter_app-0.1.8/main.py +40 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyproject.toml +1 -1
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/__init__.py +4 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/hash_map.py +4 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/sysfiles.py +96 -39
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/uv.lock +5 -5
- pyflutter_app-0.1.7/main.py +0 -21
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/.gitignore +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/.idea/.gitignore +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/.idea/inspectionProfiles/Project_Default.xml +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/.idea/misc.xml +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/.idea/modules.xml +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/.idea/pyflutter.iml +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/.idea/vcs.xml +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/README.md +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/__init__.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/__main__.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/assets/forms_config.json +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/config_app.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/home_page/__init__.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/home_page/_page_edit.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/home_page/controller.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/home_page/model.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/home_page/view.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/page_forms/__init__.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/page_forms/common.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/page_forms/config.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/page_forms/controller_forms.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/page_forms/service.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/run.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/table_widget.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/whatsapp/__init__.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/converter/whatsapp/model.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/export_app.sh +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/local_build/linux.sh +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/local_build/send.sh +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyflutter_ui/__init__.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyflutter_ui/app.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyflutter_ui/core.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyflutter_ui/file_picker.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyflutter_ui/list_builder.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyflutter_ui/navigator.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyflutter_ui/theme.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/pyflutter_ui/widgets.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/erros.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/notifier.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/pattner/__init__.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/pattner/adapter.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/pattner/observer.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/sheet/__init__.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/sheet/check_mod.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/sheet/load.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/sheet/options.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/sheet/parse.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/sheet/save.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/state.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/thread.py +0 -0
- {pyflutter_app-0.1.7 → pyflutter_app-0.1.8}/table_stream/workbook.py +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
#
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from enum import Enum, StrEnum, auto
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from table_stream import ArrayList, File, Directory, HashMapDict, ContentFiles, PathElement
|
|
7
|
+
import shutil
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ORGANIZABLE_DOC_NAME(StrEnum):
|
|
11
|
+
|
|
12
|
+
IMG_WP = auto()
|
|
13
|
+
IMG_WP_DOWNLOADED = auto()
|
|
14
|
+
FILE_TOI = auto()
|
|
15
|
+
FILE_DIGITALIZED = auto()
|
|
16
|
+
FILE_CAM_SCANNER = auto()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class NameDocumentOrganizable(ABC):
|
|
20
|
+
|
|
21
|
+
def __init__(self, name: str) -> None:
|
|
22
|
+
super().__init__()
|
|
23
|
+
self._name: str = name
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def date(self) -> str:
|
|
27
|
+
return self.date_time().strftime("%Y-%m-%d")
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def year(self) -> str:
|
|
31
|
+
return f"{self.date_time().year}"
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def mon(self) -> str:
|
|
35
|
+
return f"{self.date_time().month}"
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def day(self) -> str:
|
|
39
|
+
return f"{self.date_time().day}"
|
|
40
|
+
|
|
41
|
+
def __hash__(self) -> int:
|
|
42
|
+
return self._name.__hash__()
|
|
43
|
+
|
|
44
|
+
def hash(self) -> int:
|
|
45
|
+
return self.__hash__()
|
|
46
|
+
|
|
47
|
+
def get_name_list(self, separator: str) -> ArrayList[str]:
|
|
48
|
+
return ArrayList.from_string(self._name, separator)
|
|
49
|
+
|
|
50
|
+
@abstractmethod
|
|
51
|
+
def hour(self) -> str | None:
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
@abstractmethod
|
|
55
|
+
def key_id(self) -> str:
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
@abstractmethod
|
|
59
|
+
def date_time(self) -> datetime:
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class NameImageWhatsApp(NameDocumentOrganizable):
|
|
64
|
+
|
|
65
|
+
def __init__(self, name: str) -> None:
|
|
66
|
+
super().__init__(name)
|
|
67
|
+
|
|
68
|
+
def hour(self) -> str | None:
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
def key_id(self) -> str:
|
|
72
|
+
return self._name.split("-")[2]
|
|
73
|
+
|
|
74
|
+
def date_time(self) -> datetime:
|
|
75
|
+
date_str = self.get_name_list("-")[1]
|
|
76
|
+
y = date_str[0:4]
|
|
77
|
+
m = date_str[4:6]
|
|
78
|
+
d = date_str[6:8]
|
|
79
|
+
return datetime.strptime(f"{y}-{m}-{d}", "%Y-%m-%d")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class NameImageWhatsAppDownloaded(NameDocumentOrganizable):
|
|
83
|
+
|
|
84
|
+
def __init__(self, name: str) -> None:
|
|
85
|
+
super().__init__(name)
|
|
86
|
+
|
|
87
|
+
def hour(self) -> str | None:
|
|
88
|
+
hour_list = self.get_name_list(" ")
|
|
89
|
+
hour_base:str = hour_list[4]
|
|
90
|
+
return hour_base.replace('.', ':')
|
|
91
|
+
|
|
92
|
+
def key_id(self) -> str:
|
|
93
|
+
h = self.hour().replace(':', '_')
|
|
94
|
+
d = self.date
|
|
95
|
+
return f'{d}-{h}'
|
|
96
|
+
|
|
97
|
+
def date_time(self) -> datetime:
|
|
98
|
+
dt = self.get_name_list(" ")[2]
|
|
99
|
+
return datetime.strptime(dt, "%Y-%m-%d")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class NameDocumentToi(NameDocumentOrganizable):
|
|
103
|
+
|
|
104
|
+
def __init__(self, name: str) -> None:
|
|
105
|
+
super().__init__(name)
|
|
106
|
+
|
|
107
|
+
def hour(self) -> str | None:
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
def key_id(self) -> str:
|
|
111
|
+
name_list = self.get_name_list(" ")
|
|
112
|
+
return f"{name_list[0]}-{name_list[1]}"
|
|
113
|
+
|
|
114
|
+
def date_time(self) -> datetime:
|
|
115
|
+
name_list = self.get_name_list(" ")[2:5]
|
|
116
|
+
y = name_list[2]
|
|
117
|
+
m = name_list[1]
|
|
118
|
+
d = name_list[0]
|
|
119
|
+
return datetime.strptime(f'{y}-{m}-{d}', '%Y-%m-%d')
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class FactoryNameDocument(object):
|
|
123
|
+
|
|
124
|
+
def __init__(self, doc: ORGANIZABLE_DOC_NAME) -> None:
|
|
125
|
+
self.doc: ORGANIZABLE_DOC_NAME = doc
|
|
126
|
+
|
|
127
|
+
def check_name(self, name: str) -> bool:
|
|
128
|
+
if self.doc == ORGANIZABLE_DOC_NAME.IMG_WP:
|
|
129
|
+
if len(name.split("-")) < 3:
|
|
130
|
+
return False
|
|
131
|
+
elif self.doc == ORGANIZABLE_DOC_NAME.IMG_WP_DOWNLOADED:
|
|
132
|
+
if len(name.split(" ")) < 5:
|
|
133
|
+
return False
|
|
134
|
+
elif self.doc == ORGANIZABLE_DOC_NAME.FILE_TOI:
|
|
135
|
+
if len(name.split(" ")) < 5:
|
|
136
|
+
return False
|
|
137
|
+
return True
|
|
138
|
+
|
|
139
|
+
def create(self, name: str) -> NameDocumentOrganizable | None:
|
|
140
|
+
if not self.check_name(name):
|
|
141
|
+
return None
|
|
142
|
+
|
|
143
|
+
if self.doc == ORGANIZABLE_DOC_NAME.IMG_WP:
|
|
144
|
+
return NameImageWhatsApp(name)
|
|
145
|
+
elif self.doc == ORGANIZABLE_DOC_NAME.IMG_WP_DOWNLOADED:
|
|
146
|
+
return NameImageWhatsAppDownloaded(name)
|
|
147
|
+
elif self.doc == ORGANIZABLE_DOC_NAME.FILE_TOI:
|
|
148
|
+
return NameDocumentToi(name)
|
|
149
|
+
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class FactoryCreateMapDocuments(object):
|
|
154
|
+
|
|
155
|
+
def __init__(self, src: Directory) -> None:
|
|
156
|
+
self.src: Directory = src
|
|
157
|
+
|
|
158
|
+
def get_dirs(self, recursive: bool = False) -> ArrayList[Directory]:
|
|
159
|
+
return self.src.content_dirs(recursive)
|
|
160
|
+
|
|
161
|
+
def get_files(self, recursive: bool = False) -> ArrayList[File]:
|
|
162
|
+
content = ContentFiles(self.src)
|
|
163
|
+
|
|
164
|
+
imgs = content.get_images(recursive)
|
|
165
|
+
imgs.extend(
|
|
166
|
+
content.get_pdfs(recursive)
|
|
167
|
+
)
|
|
168
|
+
return imgs
|
|
169
|
+
|
|
170
|
+
def create_map_names(self, doc: ORGANIZABLE_DOC_NAME) -> HashMapDict[NameDocumentOrganizable, PathElement]:
|
|
171
|
+
tb = HashMapDict()
|
|
172
|
+
factory_names = FactoryNameDocument(doc)
|
|
173
|
+
files = self.get_files()
|
|
174
|
+
files.extend(self.get_dirs())
|
|
175
|
+
|
|
176
|
+
print(f'Arquivos ... {files.size()}')
|
|
177
|
+
print(f'Diretórios ... {self.get_dirs().size()}')
|
|
178
|
+
|
|
179
|
+
f: PathElement
|
|
180
|
+
n: NameDocumentOrganizable | None
|
|
181
|
+
for f in files:
|
|
182
|
+
n = factory_names.create(f.name())
|
|
183
|
+
if n is None:
|
|
184
|
+
print(f'Pulando ... {f.basename()}')
|
|
185
|
+
continue
|
|
186
|
+
|
|
187
|
+
print(f'Adicionando ... {f.basename()}')
|
|
188
|
+
tb[n] = f
|
|
189
|
+
return tb
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class OrganizeDocumentsNames(object):
|
|
193
|
+
|
|
194
|
+
def __init__(self, output: Directory) -> None:
|
|
195
|
+
self.output: Directory = output
|
|
196
|
+
|
|
197
|
+
def get_final_dir(self, doc: NameDocumentOrganizable) -> Directory:
|
|
198
|
+
y = doc.year
|
|
199
|
+
m = doc.mon
|
|
200
|
+
d = doc.day
|
|
201
|
+
dt = f'{y}-{m}'
|
|
202
|
+
|
|
203
|
+
return self.output.concat(dt).concat(d, True)
|
|
204
|
+
|
|
205
|
+
def move(self, src: PathElement, dest: PathElement):
|
|
206
|
+
print(f'[MOVENDO] ... {dest.absolute()}')
|
|
207
|
+
shutil.move(src.absolute(), dest.absolute())
|
|
208
|
+
|
|
209
|
+
def organize(self, map: HashMapDict[NameDocumentOrganizable, PathElement]):
|
|
210
|
+
|
|
211
|
+
k: NameDocumentOrganizable
|
|
212
|
+
v: PathElement
|
|
213
|
+
|
|
214
|
+
for k, v in map.get_real_hash_map().items():
|
|
215
|
+
final_dir = self.get_final_dir(k)
|
|
216
|
+
new_path = final_dir.concat(v.basename())
|
|
217
|
+
|
|
218
|
+
self.move(v, new_path)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def main():
|
|
222
|
+
|
|
223
|
+
src = Directory("/home/bruno/Documentos/Arquivos WhatsApp/CARTAS TOI RURAL")
|
|
224
|
+
out = Directory('/home/bruno/Downloads/test')
|
|
225
|
+
|
|
226
|
+
map = FactoryCreateMapDocuments(src).create_map_names(ORGANIZABLE_DOC_NAME.IMG_WP)
|
|
227
|
+
value = OrganizeDocumentsNames(out)
|
|
228
|
+
value.organize(map)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
if __name__ == '__main__':
|
|
232
|
+
main()
|
|
233
|
+
|
|
234
|
+
|
|
@@ -131,7 +131,7 @@ class PathFile(FilePath):
|
|
|
131
131
|
|
|
132
132
|
|
|
133
133
|
#===================================================================#
|
|
134
|
-
#
|
|
134
|
+
# Map para colunas de analitico
|
|
135
135
|
#===================================================================#
|
|
136
136
|
|
|
137
137
|
class MapColumnsAnalitico(TypedDict):
|
|
@@ -139,11 +139,53 @@ class MapColumnsAnalitico(TypedDict):
|
|
|
139
139
|
livro:str
|
|
140
140
|
local: str
|
|
141
141
|
rota: str
|
|
142
|
+
roteiro: str
|
|
142
143
|
latitude: str
|
|
143
144
|
longitude: str
|
|
144
145
|
|
|
145
146
|
|
|
147
|
+
columnsAnalitico: MapColumnsAnalitico = {
|
|
148
|
+
"uc": "numcdc",
|
|
149
|
+
"livro": "numliv",
|
|
150
|
+
"local": "codlcd",
|
|
151
|
+
"rota": "numrota",
|
|
152
|
+
"latitude": "vlr_coordenada_latitude",
|
|
153
|
+
"longitude": "vlr_coordenada_longitude",
|
|
154
|
+
"roteiro": "concatenar",
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def columns_analitico_rotas() -> MapColumnsAnalitico:
|
|
160
|
+
"""
|
|
161
|
+
Retorna um mapa de colunas, formatado para o analitico
|
|
162
|
+
de rotas.
|
|
163
|
+
"""
|
|
164
|
+
return {
|
|
165
|
+
"uc": "numcdc",
|
|
166
|
+
"livro": "numliv",
|
|
167
|
+
"local": "codlcd",
|
|
168
|
+
"rota": "numrota",
|
|
169
|
+
"latitude": "vlr_coordenada_latitude",
|
|
170
|
+
"longitude": "vlr_coordenada_longitude",
|
|
171
|
+
"roteiro": "concatenar",
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def map_columns_analitico_repasse() -> MapColumnsAnalitico:
|
|
176
|
+
"""
|
|
177
|
+
Retorna um mapa de colunas, formatado para o analitico de repasse.
|
|
178
|
+
"""
|
|
179
|
+
columnsAnalitico["uc"] = "num_uc"
|
|
180
|
+
columnsAnalitico["livro"] = "num_livro"
|
|
181
|
+
columnsAnalitico["local"] = "cod_localidade"
|
|
182
|
+
columnsAnalitico["rota"] = "num_rota"
|
|
183
|
+
return columnsAnalitico
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
#===================================================================#
|
|
146
187
|
# Identificar uc, toi, data e etc pelo nome de arquivo.
|
|
188
|
+
#===================================================================#
|
|
147
189
|
class MapIdDocuments(TypedDict):
|
|
148
190
|
|
|
149
191
|
uc: int
|
|
@@ -186,7 +228,7 @@ def map_id_documents() -> MapIdDocuments:
|
|
|
186
228
|
}
|
|
187
229
|
|
|
188
230
|
|
|
189
|
-
class
|
|
231
|
+
class NameDocument(object):
|
|
190
232
|
|
|
191
233
|
def __init__(self, path: FilePath, get_map_id: Callable[[], MapIdDocuments]) -> None:
|
|
192
234
|
self.path: FilePath = path
|
|
@@ -226,7 +268,7 @@ class MapNameDocument(object):
|
|
|
226
268
|
return f'{self.day}/{self.mon}/{self.year}'
|
|
227
269
|
|
|
228
270
|
@classmethod
|
|
229
|
-
def from_file_path(cls, fp: FilePath) ->
|
|
271
|
+
def from_file_path(cls, fp: FilePath) -> NameDocument:
|
|
230
272
|
return cls(fp, map_id_documents)
|
|
231
273
|
|
|
232
274
|
@staticmethod
|
|
@@ -243,11 +285,11 @@ class MapNameDocument(object):
|
|
|
243
285
|
return final
|
|
244
286
|
|
|
245
287
|
@staticmethod
|
|
246
|
-
def create_list_map_names(d: Directory) -> ArrayList[
|
|
247
|
-
paths: ArrayList[FilePath] =
|
|
248
|
-
|
|
288
|
+
def create_list_map_names(d: Directory) -> ArrayList[NameDocument]:
|
|
289
|
+
paths: ArrayList[FilePath] = NameDocument.get_valid_documents(
|
|
290
|
+
NameDocument.create_list_paths(d)
|
|
249
291
|
)
|
|
250
|
-
return ArrayList([
|
|
292
|
+
return ArrayList([NameDocument.from_file_path(x) for x in paths])
|
|
251
293
|
|
|
252
294
|
@staticmethod
|
|
253
295
|
def is_valid_document_name(doc: FilePath) -> bool:
|
|
@@ -258,36 +300,14 @@ class MapNameDocument(object):
|
|
|
258
300
|
final = ArrayList[FilePath]()
|
|
259
301
|
p: FilePath
|
|
260
302
|
for p in values:
|
|
261
|
-
if
|
|
303
|
+
if NameDocument.is_valid_document_name(p):
|
|
262
304
|
final.append(p)
|
|
263
305
|
return final
|
|
264
306
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
"local": "codlcd",
|
|
270
|
-
"rota": "numrota",
|
|
271
|
-
"latitude": "vlr_coordenada_latitude",
|
|
272
|
-
"longitude": "vlr_coordenada_longitude"
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
def columns_analitico_rotas() -> MapColumnsAnalitico:
|
|
277
|
-
"""
|
|
278
|
-
Retorna um mapa de colunas, formatado para o analitico
|
|
279
|
-
de rotas.
|
|
280
|
-
"""
|
|
281
|
-
return columnsAnalitico
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
def map_columns_analitico_repasse() -> MapColumnsAnalitico:
|
|
285
|
-
columnsAnalitico["uc"] = "num_uc"
|
|
286
|
-
columnsAnalitico["livro"] = "num_livro"
|
|
287
|
-
columnsAnalitico["local"] = "cod_localidade"
|
|
288
|
-
columnsAnalitico["rota"] = "num_rota"
|
|
289
|
-
return columnsAnalitico
|
|
290
|
-
|
|
307
|
+
|
|
308
|
+
#===================================================================#
|
|
309
|
+
# Dividir um DataFrame apartir dos valores de uma coluna
|
|
310
|
+
#===================================================================#
|
|
291
311
|
|
|
292
312
|
class SplitDataToMap(object):
|
|
293
313
|
|
|
@@ -442,13 +462,12 @@ class ElementUC(object):
|
|
|
442
462
|
|
|
443
463
|
class TableAnalitico(HashMapDataFrame):
|
|
444
464
|
|
|
445
|
-
def __init__(self, df: pd.DataFrame) -> None:
|
|
465
|
+
def __init__(self, df: pd.DataFrame, map_analitico: MapColumnsAnalitico = None) -> None:
|
|
446
466
|
super().__init__(df)
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
self.
|
|
451
|
-
self.col_roteiro: str = 'concatenar'
|
|
467
|
+
if map_analitico is None:
|
|
468
|
+
map_analitico = columns_analitico_rotas()
|
|
469
|
+
|
|
470
|
+
self.map_analitico: MapColumnsAnalitico = map_analitico
|
|
452
471
|
self.separator_roteiro: str = '_'
|
|
453
472
|
|
|
454
473
|
@property
|
|
@@ -472,7 +491,8 @@ class TableAnalitico(HashMapDataFrame):
|
|
|
472
491
|
return ParserData(self.get_real_hash_map())
|
|
473
492
|
|
|
474
493
|
def get_ucs(self) -> ArrayList[UC]:
|
|
475
|
-
col: pd.Series = self.get_value(self.
|
|
494
|
+
col: pd.Series = self.get_value(self.map_analitico["uc"]).drop_duplicates()
|
|
495
|
+
|
|
476
496
|
if (col is None) or (len(col) < 1):
|
|
477
497
|
return ArrayList()
|
|
478
498
|
|
|
@@ -481,10 +501,10 @@ class TableAnalitico(HashMapDataFrame):
|
|
|
481
501
|
|
|
482
502
|
def get_roteiros(self) -> ArrayList[Roteiro]:
|
|
483
503
|
|
|
484
|
-
if not self.header().contains(self.
|
|
485
|
-
raise ValueError(f"[FALHA] ... a coluna não exite ... {self.
|
|
504
|
+
if not self.header().contains(self.map_analitico["roteiro"]):
|
|
505
|
+
raise ValueError(f"[FALHA] ... a coluna não exite ... {self.map_analitico["roteiro"]}")
|
|
486
506
|
|
|
487
|
-
rotas: list[str] = self.get_value(self.
|
|
507
|
+
rotas: list[str] = self.get_value(self.map_analitico["roteiro"]).drop_duplicates().astype('str')
|
|
488
508
|
final = ArrayList[Roteiro]()
|
|
489
509
|
for i in rotas:
|
|
490
510
|
final.append(
|
|
@@ -513,11 +533,11 @@ class TableAnalitico(HashMapDataFrame):
|
|
|
513
533
|
final = ArrayList[ElementUC]()
|
|
514
534
|
uc: UC
|
|
515
535
|
for uc in ucs_list:
|
|
516
|
-
df = self.filter_item(self.
|
|
536
|
+
df = self.filter_item(self.map_analitico["uc"], uc.value)
|
|
517
537
|
if df.empty:
|
|
518
538
|
continue
|
|
519
539
|
|
|
520
|
-
roteiro: str = self.get_first_value(df, self.
|
|
540
|
+
roteiro: str = self.get_first_value(df, self.map_analitico["roteiro"])
|
|
521
541
|
if roteiro is None:
|
|
522
542
|
continue
|
|
523
543
|
|
|
@@ -563,35 +583,6 @@ def find_index_uc(values: ArrayList[ElementUC], uc: UC) -> int | None:
|
|
|
563
583
|
return idx
|
|
564
584
|
|
|
565
585
|
|
|
566
|
-
def include_roteiro(src_data: pd.DataFrame, *, col_uc = 'UC', tb: TableAnalitico) -> pd.DataFrame:
|
|
567
|
-
"""
|
|
568
|
-
Adiciona uma coluna com o nome [roteiro] com os roteiros concatenados de cada UC livro local e rota
|
|
569
|
-
"""
|
|
570
|
-
|
|
571
|
-
if not col_uc in src_data.columns.tolist():
|
|
572
|
-
raise ValueError(f"Coluna não encontrada ... {col_uc}")
|
|
573
|
-
|
|
574
|
-
data: pd.DataFrame = tb.get_parser().select_columns([tb.col_uc, tb.col_roteiro]).get_data().astype('str')
|
|
575
|
-
ucs: ArrayList[str] = ArrayList(src_data[col_uc].astype('str').values.tolist())
|
|
576
|
-
final_column: ArrayList[str] = ArrayList()
|
|
577
|
-
|
|
578
|
-
uc:str
|
|
579
|
-
for uc in ucs:
|
|
580
|
-
current_df = data[data[tb.col_uc] == uc]
|
|
581
|
-
if current_df is None:
|
|
582
|
-
final_column.append('-')
|
|
583
|
-
continue
|
|
584
|
-
if current_df.empty:
|
|
585
|
-
final_column.append('-')
|
|
586
|
-
continue
|
|
587
|
-
|
|
588
|
-
current_roteiro = current_df[tb.col_roteiro].values.tolist()[0]
|
|
589
|
-
final_column.append(current_roteiro)
|
|
590
|
-
|
|
591
|
-
src_data["roteiro"] = pd.Series(final_column)
|
|
592
|
-
return src_data
|
|
593
|
-
|
|
594
|
-
|
|
595
586
|
def save_map_roteiro(hash_map: HashMapDict[UC, Roteiro], opt_save: OptionsIOSheet, output: File) -> None:
|
|
596
587
|
data = dict[str, str]()
|
|
597
588
|
header: ArrayList[UC] = hash_map.header()
|
|
@@ -605,89 +596,15 @@ def save_map_roteiro(hash_map: HashMapDict[UC, Roteiro], opt_save: OptionsIOShee
|
|
|
605
596
|
save.save(df, output)
|
|
606
597
|
|
|
607
598
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
a nova coluna incluida tem o nome [roteiro] com livro, local e rota concatenados e
|
|
612
|
-
separados por um '_'.
|
|
613
|
-
"""
|
|
614
|
-
|
|
615
|
-
def __init__(self, files_data_base: ArrayList[File], *, output_dir: Directory) -> None:
|
|
616
|
-
"""
|
|
617
|
-
output_dir: Diretório para exportar os dados
|
|
618
|
-
files_data_base: Lista de arquivos EXCEL contendo UCs e roteiros.
|
|
619
|
-
"""
|
|
620
|
-
|
|
621
|
-
self.files_data_base: ArrayList[File] = files_data_base
|
|
622
|
-
self.output_dir: Directory = output_dir
|
|
623
|
-
self.temp_dir = self.output_dir.concat('Temp', create=True)
|
|
624
|
-
self.temp_files: ArrayList[File] = ArrayList()
|
|
625
|
-
self._counter: int = 0
|
|
626
|
-
self._temp_data: pd.DataFrame = None
|
|
627
|
-
self.current_base: pd.DataFrame = None
|
|
628
|
-
|
|
629
|
-
def _check_void_roteiro(self, df: pd.DataFrame) -> pd.DataFrame:
|
|
630
|
-
df_void = df[df["roteiro"] == '-']
|
|
631
|
-
return pd.DataFrame() if df_void is None else df_void
|
|
632
|
-
|
|
633
|
-
def _check_ok_roteiro(self, df: pd.DataFrame) -> pd.DataFrame:
|
|
634
|
-
df_ok = df[df["roteiro"] != '-']
|
|
635
|
-
return pd.DataFrame() if df_ok is None else df_ok
|
|
636
|
-
|
|
637
|
-
def join_all_files(self):
|
|
638
|
-
"""
|
|
639
|
-
Junta os arquivos processados em um unico arquivo excel.
|
|
640
|
-
"""
|
|
641
|
-
if self.temp_files.size() == 0:
|
|
642
|
-
print(f'[!] Nenhum Dado para exportar')
|
|
643
|
-
return
|
|
644
|
-
|
|
645
|
-
final_file = self.output_dir.join_file('RoteirosFinal.xlsx')
|
|
646
|
-
data_list = ArrayList()
|
|
647
|
-
|
|
648
|
-
f: File
|
|
649
|
-
for f in self.temp_files:
|
|
650
|
-
data_list.append(pd.read_excel(f.absolute()))
|
|
651
|
-
|
|
652
|
-
final_data: pd.DataFrame = pd.concat(data_list)
|
|
653
|
-
print(f'Exportando ... {final_file.absolute()}')
|
|
654
|
-
final_data.to_excel(final_file.absolute())
|
|
655
|
-
|
|
656
|
-
def include(self, df: pd.DataFrame, *, col_uc: str = 'UC'):
|
|
657
|
-
"""
|
|
658
|
-
Inclui uma coluna com roteiros em um DataFrame() que contenha uma coluna de UCs
|
|
659
|
-
"""
|
|
660
|
-
self.current_base = df
|
|
661
|
-
file_path: File
|
|
662
|
-
total = self.files_data_base.size()
|
|
663
|
-
for n, file_path in enumerate(self.files_data_base):
|
|
664
|
-
print(f'Lendo base ... [{n+1} / {total}] {file_path.basename()}')
|
|
665
|
-
|
|
666
|
-
if file_path.is_excel():
|
|
667
|
-
opt_load = OptionsIOSheet(SheetType.EXCEL)
|
|
668
|
-
elif file_path.is_csv():
|
|
669
|
-
opt_load = OptionsIOSheet(SheetType.CSV)
|
|
670
|
-
else:
|
|
671
|
-
print(f'[PULANDO] ... {file_path.basename()}')
|
|
672
|
-
continue
|
|
673
|
-
|
|
674
|
-
loader = SheetLoader.create(opt_load, file_path)
|
|
675
|
-
df_roteiros = include_roteiro(df, col_uc=col_uc, tb=TableAnalitico(loader.load()))
|
|
676
|
-
|
|
677
|
-
df_ok = self._check_ok_roteiro(df_roteiros)
|
|
678
|
-
if not df_ok.empty:
|
|
679
|
-
self._counter += 1
|
|
680
|
-
save_file = self.temp_dir.join_file(f'temp-{self._counter}.xlsx')
|
|
681
|
-
df_ok.to_excel(save_file.absolute())
|
|
682
|
-
self.temp_files.append(save_file)
|
|
683
|
-
|
|
684
|
-
df_void = self._check_void_roteiro(df_roteiros)
|
|
685
|
-
if df_void.empty:
|
|
686
|
-
break
|
|
687
|
-
|
|
688
|
-
self.current_base = df_void
|
|
689
|
-
self.join_all_files()
|
|
599
|
+
#===================================================================#
|
|
600
|
+
# Organizar arquivos no disco
|
|
601
|
+
#===================================================================#
|
|
690
602
|
|
|
603
|
+
class OrganizableDocuments(ABC):
|
|
604
|
+
|
|
605
|
+
def __init__(self) -> None:
|
|
606
|
+
super().__init__()
|
|
607
|
+
|
|
691
608
|
|
|
692
609
|
class DocumentsToTable(object):
|
|
693
610
|
|
|
@@ -735,8 +652,8 @@ class DocumentsToTable(object):
|
|
|
735
652
|
ENUM_COLUMNS_TOI.TIPO_DOC: ArrayList(),
|
|
736
653
|
}
|
|
737
654
|
|
|
738
|
-
names: ArrayList[
|
|
739
|
-
name:
|
|
655
|
+
names: ArrayList[NameDocument] = NameDocument.create_list_map_names(self.src)
|
|
656
|
+
name: NameDocument
|
|
740
657
|
for name in names:
|
|
741
658
|
|
|
742
659
|
local = "OUTRO"
|
|
@@ -803,8 +720,8 @@ class DocumentsToTable(object):
|
|
|
803
720
|
|
|
804
721
|
def organize(self) -> None:
|
|
805
722
|
|
|
806
|
-
names: ArrayList[
|
|
807
|
-
name:
|
|
723
|
+
names: ArrayList[NameDocument] = NameDocument.create_list_map_names(self.src)
|
|
724
|
+
name: NameDocument
|
|
808
725
|
|
|
809
726
|
for name in names:
|
|
810
727
|
output_dir = self.src.concat(name.year).concat(name.mon).concat(name.day)
|
|
@@ -812,7 +729,23 @@ class DocumentsToTable(object):
|
|
|
812
729
|
final_path = output_dir.join_file(name.path.basename())
|
|
813
730
|
|
|
814
731
|
self._move(name.path.absolute(), final_path.absolute())
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
#===================================================================#
|
|
735
|
+
# Organizar arquivos do WhatsApp
|
|
736
|
+
#===================================================================#
|
|
737
|
+
|
|
738
|
+
class WhatsAppFiles(object):
|
|
739
|
+
|
|
740
|
+
def __init__(self, src: Directory) -> None:
|
|
741
|
+
self.src: Directory = src
|
|
815
742
|
|
|
743
|
+
def organize_by_types(self, output: Directory) -> None:
|
|
744
|
+
pass
|
|
745
|
+
|
|
746
|
+
def organize_by_date(self, output: Directory) -> None:
|
|
747
|
+
pass
|
|
748
|
+
|
|
816
749
|
|
|
817
750
|
def main():
|
|
818
751
|
pass
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import pandas as pd
|
|
3
|
+
|
|
4
|
+
def load_whats_csv(f: str) -> pd.DataFrame:
|
|
5
|
+
|
|
6
|
+
# Lê o arquivo direto definindo o LRM (\u200e) ou o '***' como separador
|
|
7
|
+
# O engine='python' é necessário para separadores com regex ou múltiplos caracteres
|
|
8
|
+
df = pd.read_csv(
|
|
9
|
+
f,
|
|
10
|
+
sep=r"\u200e|\*\*\*", # Aceita tanto \u200e quanto *** como delimitador
|
|
11
|
+
engine="python",
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
return df
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test():
|
|
18
|
+
from table_stream.sysfiles import File, Directory, UserFileSystem
|
|
19
|
+
from table_stream.sysfiles import JsonConvert, JsonData
|
|
20
|
+
from converter.lib_toi import DocumentsToTable
|
|
21
|
+
|
|
22
|
+
wp_name = "WhatsApp Image 2026-09-02 at 14.59.45"
|
|
23
|
+
name = 'IMG-20260406-WA0045.jpg'
|
|
24
|
+
list_name = name.split('-')
|
|
25
|
+
|
|
26
|
+
f = "/home/bruno/Documentos/CARTAS TOI/WP CARTAS TOI RURAL/Conversa do WhatsApp com CARTAS TOI RURAL.txt"
|
|
27
|
+
out = "/home/bruno/Documentos/CARTAS TOI/WP CARTAS TOI RURAL/final.xlsx"
|
|
28
|
+
data = load_whats_csv(f)
|
|
29
|
+
print(data.head())
|
|
30
|
+
|
|
31
|
+
data.to_excel(out)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def main() -> None:
|
|
35
|
+
from converter import run_ui
|
|
36
|
+
#run_ui()
|
|
37
|
+
test()
|
|
38
|
+
|
|
39
|
+
if __name__ == '__main__':
|
|
40
|
+
main()
|
|
@@ -9,4 +9,8 @@ from .sheet import (
|
|
|
9
9
|
csvEncoding, csvSeparator, OptionsIOSheet, SaveData,
|
|
10
10
|
FactorySaveData, FactorySheetLoader, SheetType,
|
|
11
11
|
)
|
|
12
|
+
from .sysfiles import (
|
|
13
|
+
File, Directory, ContentFiles, JsonConvert, JsonData,
|
|
14
|
+
EnumDocuments, ExtensionDocuments, UserFileSystem, PathElement
|
|
15
|
+
)
|
|
12
16
|
from .state import ContextState, EventState
|
|
@@ -48,6 +48,10 @@ class ArrayList[T](list):
|
|
|
48
48
|
return True
|
|
49
49
|
return False
|
|
50
50
|
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_string(cls, value: str, separator: str = " ") -> ArrayList[str]:
|
|
53
|
+
return cls(value.split(separator))
|
|
54
|
+
|
|
51
55
|
|
|
52
56
|
#========================================================#
|
|
53
57
|
# Base para HashMap().
|
|
@@ -8,9 +8,11 @@ Atualizações:
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
from typing import Any
|
|
10
10
|
from enum import Enum
|
|
11
|
+
from abc import ABC, abstractmethod
|
|
11
12
|
import os
|
|
12
13
|
import json
|
|
13
14
|
import platform
|
|
15
|
+
from table_stream.hash_map import ArrayList
|
|
14
16
|
|
|
15
17
|
# Windows / Linux / ...
|
|
16
18
|
KERNEL_TYPE = platform.system()
|
|
@@ -70,12 +72,42 @@ class EnumDocuments(Enum):
|
|
|
70
72
|
]
|
|
71
73
|
|
|
72
74
|
|
|
73
|
-
class
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
self.
|
|
75
|
+
class PathElement(ABC):
|
|
76
|
+
|
|
77
|
+
def __init__(self, path: str) -> None:
|
|
78
|
+
super().__init__()
|
|
79
|
+
self._path: str = os.path.abspath(path)
|
|
80
|
+
|
|
81
|
+
@abstractmethod
|
|
82
|
+
def basename(self) -> str:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
@abstractmethod
|
|
86
|
+
def name(self) -> str:
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
@abstractmethod
|
|
90
|
+
def absolute(self) -> str:
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def is_file(self) -> bool:
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
@abstractmethod
|
|
98
|
+
def is_dir(self) -> bool:
|
|
99
|
+
pass
|
|
100
|
+
|
|
78
101
|
|
|
102
|
+
|
|
103
|
+
class File(PathElement):
|
|
104
|
+
|
|
105
|
+
def __init__(self, path: str) -> None:
|
|
106
|
+
super().__init__(path)
|
|
107
|
+
|
|
108
|
+
if os.path.isdir(path):
|
|
109
|
+
raise ValueError(f'{__class__.__name__} File() não pode ser um diretório.')
|
|
110
|
+
|
|
79
111
|
def __repr__(self):
|
|
80
112
|
return f'<{__class__.__name__}()>: {self.absolute()}'
|
|
81
113
|
|
|
@@ -149,14 +181,14 @@ class File(object):
|
|
|
149
181
|
def name(self):
|
|
150
182
|
e = self.extension()
|
|
151
183
|
if (e is None) or (e == ''):
|
|
152
|
-
return os.path.basename(self.
|
|
153
|
-
return os.path.basename(self.
|
|
184
|
+
return os.path.basename(self._path)
|
|
185
|
+
return os.path.basename(self._path).replace(e, '')
|
|
154
186
|
|
|
155
187
|
def name_absolute(self) -> str:
|
|
156
188
|
e = self.extension()
|
|
157
189
|
if (e is None) or (e == ''):
|
|
158
|
-
return self.
|
|
159
|
-
return self.
|
|
190
|
+
return self._path
|
|
191
|
+
return self._path.replace(e, '')
|
|
160
192
|
|
|
161
193
|
def extension(self) -> str | None:
|
|
162
194
|
try:
|
|
@@ -165,28 +197,38 @@ class File(object):
|
|
|
165
197
|
return None
|
|
166
198
|
|
|
167
199
|
def dirname(self) -> str:
|
|
168
|
-
return os.path.dirname(self.
|
|
200
|
+
return os.path.dirname(self._path)
|
|
169
201
|
|
|
170
202
|
def basename(self) -> str:
|
|
171
|
-
return os.path.basename(self.
|
|
203
|
+
return os.path.basename(self._path)
|
|
172
204
|
|
|
173
205
|
def exists(self) -> bool:
|
|
174
206
|
return os.path.exists(self.absolute())
|
|
175
207
|
|
|
176
208
|
def absolute(self) -> str:
|
|
177
|
-
return self.
|
|
209
|
+
return self._path
|
|
178
210
|
|
|
179
211
|
def size(self):
|
|
180
|
-
return os.path.getsize(self.
|
|
212
|
+
return os.path.getsize(self._path)
|
|
181
213
|
|
|
214
|
+
def is_file(self) -> bool:
|
|
215
|
+
return True
|
|
182
216
|
|
|
183
|
-
|
|
217
|
+
def is_dir(self) -> bool:
|
|
218
|
+
return False
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class Directory(PathElement):
|
|
184
223
|
|
|
185
|
-
def __init__(self,
|
|
186
|
-
|
|
224
|
+
def __init__(self, path: str) -> None:
|
|
225
|
+
super().__init__(path)
|
|
226
|
+
|
|
227
|
+
if os.path.isfile(path):
|
|
228
|
+
raise ValueError(f'{__class__.__name__}() não pode ser um arquivo.')
|
|
187
229
|
|
|
188
230
|
def absolute(self) -> str:
|
|
189
|
-
return self.
|
|
231
|
+
return self._path
|
|
190
232
|
|
|
191
233
|
def __repr__(self):
|
|
192
234
|
return f'{__class__.__name__}(): {self.absolute()}'
|
|
@@ -199,11 +241,11 @@ class Directory(object):
|
|
|
199
241
|
def __hash__(self):
|
|
200
242
|
return self.absolute().__hash__()
|
|
201
243
|
|
|
202
|
-
def get_files(self) ->
|
|
244
|
+
def get_files(self) -> ArrayList[str]:
|
|
203
245
|
"""
|
|
204
246
|
Retorna a lista de diretórios e sub pastas.
|
|
205
247
|
"""
|
|
206
|
-
path_list =
|
|
248
|
+
path_list = ArrayList()
|
|
207
249
|
# os.walk percorre a árvore de diretórios recursivamente
|
|
208
250
|
for root, dirs, files in os.walk(self.absolute()):
|
|
209
251
|
# Adiciona os diretórios encontrados
|
|
@@ -214,9 +256,10 @@ class Directory(object):
|
|
|
214
256
|
path_list.append(os.path.join(root, name))
|
|
215
257
|
return path_list
|
|
216
258
|
|
|
217
|
-
def __content_recursive(self) ->
|
|
218
|
-
_paths:
|
|
219
|
-
values:
|
|
259
|
+
def __content_recursive(self) -> ArrayList[File]:
|
|
260
|
+
_paths: ArrayList[str] = self.get_files()
|
|
261
|
+
values: ArrayList[File] = ArrayList()
|
|
262
|
+
|
|
220
263
|
for file_path in _paths:
|
|
221
264
|
if os.path.isfile(file_path):
|
|
222
265
|
values.append(
|
|
@@ -224,9 +267,10 @@ class Directory(object):
|
|
|
224
267
|
)
|
|
225
268
|
return values
|
|
226
269
|
|
|
227
|
-
def __content_no_recursive(self) ->
|
|
228
|
-
content_files:
|
|
229
|
-
values:
|
|
270
|
+
def __content_no_recursive(self) -> ArrayList[File]:
|
|
271
|
+
content_files: ArrayList[str] = ArrayList(os.listdir(self.absolute()))
|
|
272
|
+
values: ArrayList[File] = ArrayList()
|
|
273
|
+
|
|
230
274
|
for file in content_files:
|
|
231
275
|
fp: str = os.path.join(self.absolute(), file)
|
|
232
276
|
if os.path.isfile(fp):
|
|
@@ -235,18 +279,20 @@ class Directory(object):
|
|
|
235
279
|
)
|
|
236
280
|
return values
|
|
237
281
|
|
|
238
|
-
def content_files(self, *, recursive: bool = True) ->
|
|
282
|
+
def content_files(self, *, recursive: bool = True) -> ArrayList[File]:
|
|
239
283
|
if recursive:
|
|
240
284
|
return self.__content_recursive()
|
|
241
285
|
return self.__content_no_recursive()
|
|
242
286
|
|
|
243
|
-
def content_dirs(self, recursive: bool = True) ->
|
|
287
|
+
def content_dirs(self, recursive: bool = True) -> ArrayList[Directory]:
|
|
244
288
|
"""
|
|
245
289
|
retorna uma lista de diretórios
|
|
246
290
|
"""
|
|
247
|
-
values:
|
|
291
|
+
values: ArrayList[Directory] = ArrayList()
|
|
292
|
+
|
|
248
293
|
if recursive:
|
|
249
294
|
_paths = self.get_files()
|
|
295
|
+
|
|
250
296
|
for p in _paths:
|
|
251
297
|
if os.path.isdir(p):
|
|
252
298
|
values.append(
|
|
@@ -290,6 +336,16 @@ class Directory(object):
|
|
|
290
336
|
os.path.join(self.absolute(), name)
|
|
291
337
|
)
|
|
292
338
|
|
|
339
|
+
def name(self) -> str:
|
|
340
|
+
return self.basename()
|
|
341
|
+
|
|
342
|
+
def is_file(self) -> bool:
|
|
343
|
+
return False
|
|
344
|
+
|
|
345
|
+
def is_dir(self) -> bool:
|
|
346
|
+
return True
|
|
347
|
+
|
|
348
|
+
|
|
293
349
|
|
|
294
350
|
class ContentFiles(object):
|
|
295
351
|
"""
|
|
@@ -302,23 +358,24 @@ class ContentFiles(object):
|
|
|
302
358
|
self._input_dir: Directory = d
|
|
303
359
|
self.__max_files: int = max_files
|
|
304
360
|
|
|
305
|
-
def get_images(self) ->
|
|
306
|
-
return self.get_files(file_type=EnumDocuments.IMAGE)
|
|
361
|
+
def get_images(self, recursive: bool = True) -> ArrayList[File]:
|
|
362
|
+
return self.get_files(file_type=EnumDocuments.IMAGE, recursive=recursive)
|
|
307
363
|
|
|
308
|
-
def get_pdfs(self) ->
|
|
309
|
-
return self.get_files(file_type=EnumDocuments.PDF)
|
|
364
|
+
def get_pdfs(self, recursive: bool = True) -> ArrayList[File]:
|
|
365
|
+
return self.get_files(file_type=EnumDocuments.PDF, recursive=recursive)
|
|
310
366
|
|
|
311
|
-
def get_sheets(self) ->
|
|
312
|
-
return self.get_files(file_type=EnumDocuments.SHEET)
|
|
367
|
+
def get_sheets(self, recursive: bool = True) -> ArrayList[File]:
|
|
368
|
+
return self.get_files(file_type=EnumDocuments.SHEET, recursive=recursive)
|
|
313
369
|
|
|
314
|
-
def get_files_with(self, *, infile: str, sort: bool = True) ->
|
|
370
|
+
def get_files_with(self, *, infile: str, sort: bool = True) -> ArrayList[File]:
|
|
315
371
|
"""
|
|
316
372
|
Retorna arquivos que contém a ocorrência (infile) no nome absoluto.
|
|
317
373
|
"""
|
|
318
|
-
content_files:
|
|
374
|
+
content_files: ArrayList[File] = ArrayList()
|
|
319
375
|
count: int = 0
|
|
320
376
|
paths: list[str] = self._input_dir.get_files()
|
|
321
377
|
file: str
|
|
378
|
+
|
|
322
379
|
for file in paths:
|
|
323
380
|
if not os.path.isfile(file):
|
|
324
381
|
continue
|
|
@@ -398,7 +455,7 @@ class ContentFiles(object):
|
|
|
398
455
|
file_type: EnumDocuments = EnumDocuments.ALL_DOCUMENTS,
|
|
399
456
|
sort: bool = True,
|
|
400
457
|
recursive: bool = True
|
|
401
|
-
) ->
|
|
458
|
+
) -> ArrayList[File]:
|
|
402
459
|
"""
|
|
403
460
|
Retorna uma lista de File() conforme o tipo de arquivo
|
|
404
461
|
especificado.
|
|
@@ -408,8 +465,8 @@ class ContentFiles(object):
|
|
|
408
465
|
|
|
409
466
|
"""
|
|
410
467
|
if recursive:
|
|
411
|
-
return self.__get_files_recursive(file_type=file_type, sort=sort)
|
|
412
|
-
return self.__get_files_no_recursive(file_type=file_type, sort=sort)
|
|
468
|
+
return ArrayList(self.__get_files_recursive(file_type=file_type, sort=sort))
|
|
469
|
+
return ArrayList(self.__get_files_no_recursive(file_type=file_type, sort=sort))
|
|
413
470
|
|
|
414
471
|
|
|
415
472
|
class JsonData(object):
|
|
@@ -35,7 +35,7 @@ name = "cffi"
|
|
|
35
35
|
version = "2.1.1"
|
|
36
36
|
source = { registry = "https://pypi.org/simple" }
|
|
37
37
|
dependencies = [
|
|
38
|
-
{ name = "pycparser", marker = "implementation_name != 'PyPy'
|
|
38
|
+
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
|
|
39
39
|
]
|
|
40
40
|
sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" }
|
|
41
41
|
wheels = [
|
|
@@ -169,7 +169,7 @@ name = "cryptography"
|
|
|
169
169
|
version = "50.0.1"
|
|
170
170
|
source = { registry = "https://pypi.org/simple" }
|
|
171
171
|
dependencies = [
|
|
172
|
-
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'
|
|
172
|
+
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
|
173
173
|
]
|
|
174
174
|
sdist = { url = "https://files.pythonhosted.org/packages/bb/ad/5d6702db60b1e40b41ef513b6967ff5848f307d50f8449baf1634f5908f1/cryptography-50.0.1.tar.gz", hash = "sha256:5dd9bda1c12b4162f6ff568eeb5e0ff956c28d14406e875cfe8a63a2d414ff20", size = 880381, upload-time = "2026-08-25T19:45:45.499Z" }
|
|
175
175
|
wheels = [
|
|
@@ -454,7 +454,7 @@ wheels = [
|
|
|
454
454
|
|
|
455
455
|
[[package]]
|
|
456
456
|
name = "pyflutter-app"
|
|
457
|
-
version = "0.1.
|
|
457
|
+
version = "0.1.8"
|
|
458
458
|
source = { editable = "." }
|
|
459
459
|
dependencies = [
|
|
460
460
|
{ name = "openpyxl" },
|
|
@@ -586,8 +586,8 @@ name = "secretstorage"
|
|
|
586
586
|
version = "3.5.0"
|
|
587
587
|
source = { registry = "https://pypi.org/simple" }
|
|
588
588
|
dependencies = [
|
|
589
|
-
{ name = "cryptography"
|
|
590
|
-
{ name = "jeepney"
|
|
589
|
+
{ name = "cryptography" },
|
|
590
|
+
{ name = "jeepney" },
|
|
591
591
|
]
|
|
592
592
|
sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" }
|
|
593
593
|
wheels = [
|
pyflutter_app-0.1.7/main.py
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
def test():
|
|
3
|
-
from table_stream.sysfiles import File, Directory, UserFileSystem
|
|
4
|
-
from table_stream.sysfiles import JsonConvert, JsonData
|
|
5
|
-
from converter.lib_toi import DocumentsToTable
|
|
6
|
-
|
|
7
|
-
d = Directory("/home/bruno/Downloads/2026-08-25 TOIS (TARDE)/POLO 2/GM E NM/OK LANÇADO FALTA PLANILHAR")
|
|
8
|
-
f = File("/home/bruno/Downloads/RFA/cartas-toi.xlsx")
|
|
9
|
-
|
|
10
|
-
conv = DocumentsToTable(d)
|
|
11
|
-
conv.save(f)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def main() -> None:
|
|
16
|
-
from converter import run_ui
|
|
17
|
-
run_ui()
|
|
18
|
-
#test()
|
|
19
|
-
|
|
20
|
-
if __name__ == '__main__':
|
|
21
|
-
main()
|
|
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
|
|
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
|
|
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
|