soup-files 1.0.1__py3-none-any.whl → 1.2.1__py3-none-any.whl
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.
- soup_files/__init__.py +14 -1
- soup_files/{soup_files.py → files.py} +115 -32
- soup_files/progress.py +108 -0
- soup_files/version.py +3 -0
- soup_files-1.2.1.dist-info/METADATA +10 -0
- soup_files-1.2.1.dist-info/RECORD +8 -0
- {soup_files-1.0.1.dist-info → soup_files-1.2.1.dist-info}/WHEEL +1 -1
- soup_files-1.0.1.dist-info/METADATA +0 -19
- soup_files-1.0.1.dist-info/RECORD +0 -6
- {soup_files-1.0.1.dist-info → soup_files-1.2.1.dist-info}/top_level.txt +0 -0
soup_files/__init__.py
CHANGED
@@ -1,3 +1,16 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
|
3
|
-
from .
|
3
|
+
from .version import __version__
|
4
|
+
from .progress import ProgressBarAdapter, ProgressBarSimple, ABCProgressBar
|
5
|
+
from .files import (
|
6
|
+
File,
|
7
|
+
Directory,
|
8
|
+
JsonData,
|
9
|
+
JsonConvert,
|
10
|
+
InputFiles,
|
11
|
+
LibraryDocs,
|
12
|
+
UserFileSystem,
|
13
|
+
UserAppDir,
|
14
|
+
KERNEL_TYPE,
|
15
|
+
)
|
16
|
+
|
@@ -13,12 +13,13 @@ import platform
|
|
13
13
|
from pathlib import Path
|
14
14
|
from hashlib import md5
|
15
15
|
|
16
|
-
__version__ = '1.0'
|
17
16
|
|
18
17
|
# Windows / Linux / ...
|
19
18
|
KERNEL_TYPE = platform.system()
|
20
19
|
|
20
|
+
|
21
21
|
class LibraryDocs(Enum):
|
22
|
+
|
22
23
|
IMAGE = ['.png', '.jpg', '.jpeg', '.svg']
|
23
24
|
PDF = ['.pdf']
|
24
25
|
DOCUMENTS = ['.png', '.jpg', '.jpeg', '.svg', '.pdf']
|
@@ -40,11 +41,11 @@ class LibraryDocs(Enum):
|
|
40
41
|
|
41
42
|
|
42
43
|
class File(object):
|
43
|
-
def __init__(self, filename:str):
|
44
|
+
def __init__(self, filename: str):
|
44
45
|
if os.path.isdir(filename):
|
45
46
|
raise ValueError(f'{__class__.__name__} File() não pode ser um diretório.')
|
46
|
-
self.filename:str = os.path.abspath(filename)
|
47
|
-
self.__path:Path = Path(self.filename)
|
47
|
+
self.filename: str = os.path.abspath(filename)
|
48
|
+
self.__path: Path = Path(self.filename)
|
48
49
|
|
49
50
|
@property
|
50
51
|
def path(self) -> Path:
|
@@ -94,7 +95,7 @@ class File(object):
|
|
94
95
|
except:
|
95
96
|
return False
|
96
97
|
|
97
|
-
def update_extension(self, e:str) -> File:
|
98
|
+
def update_extension(self, e: str) -> File:
|
98
99
|
"""
|
99
100
|
Retorna uma instância de File() no mesmo diretório com a nova
|
100
101
|
extensão informada.
|
@@ -113,7 +114,7 @@ class File(object):
|
|
113
114
|
def write_string(self, s:str):
|
114
115
|
self.__path.write_text(s)
|
115
116
|
|
116
|
-
def write_list(self, items:List[str]):
|
117
|
+
def write_list(self, items: List[str]):
|
117
118
|
# Abrindo o arquivo em modo de escrita
|
118
119
|
with open(self.filename, "w", encoding="utf-8") as file:
|
119
120
|
for string in items:
|
@@ -162,8 +163,8 @@ class File(object):
|
|
162
163
|
|
163
164
|
class Directory(object):
|
164
165
|
def __init__(self, dirpath:str):
|
165
|
-
self.dirpath:str = os.path.abspath(dirpath)
|
166
|
-
self.path:Path = Path(self.dirpath)
|
166
|
+
self.dirpath: str = os.path.abspath(dirpath)
|
167
|
+
self.path: Path = Path(self.dirpath)
|
167
168
|
|
168
169
|
def __eq__(self, value):
|
169
170
|
if not isinstance(value, Directory):
|
@@ -175,8 +176,8 @@ class Directory(object):
|
|
175
176
|
|
176
177
|
def iterpaths(self) -> List[Path]:
|
177
178
|
return self.path.rglob('*')
|
178
|
-
|
179
|
-
def
|
179
|
+
|
180
|
+
def __content_recursive(self) -> List[File]:
|
180
181
|
_paths = self.iterpaths()
|
181
182
|
values = []
|
182
183
|
for p in _paths:
|
@@ -187,6 +188,39 @@ class Directory(object):
|
|
187
188
|
)
|
188
189
|
)
|
189
190
|
return values
|
191
|
+
|
192
|
+
def __content_no_recursive(self) -> List[File]:
|
193
|
+
files = os.listdir(self.absolute())
|
194
|
+
values: List[File] = []
|
195
|
+
for f in files:
|
196
|
+
if os.path.isfile(f):
|
197
|
+
values.append(
|
198
|
+
File(os.path.abspath(f))
|
199
|
+
)
|
200
|
+
return values
|
201
|
+
|
202
|
+
def content_files(self, *, recursive: bool = True) -> List[File]:
|
203
|
+
if recursive:
|
204
|
+
return self.__content_recursive()
|
205
|
+
return self.__content_no_recursive()
|
206
|
+
|
207
|
+
def content_dirs(self, recursive: bool = True) -> List[Directory]:
|
208
|
+
values: List[Directory] = []
|
209
|
+
if recursive:
|
210
|
+
_paths = self.iterpaths()
|
211
|
+
for p in _paths:
|
212
|
+
if p.is_dir():
|
213
|
+
values.append(
|
214
|
+
Directory(os.path.abspath(p.absolute()))
|
215
|
+
)
|
216
|
+
else:
|
217
|
+
_paths = os.listdir(self.absolute())
|
218
|
+
for d in _paths:
|
219
|
+
if os.path.isdir(d):
|
220
|
+
values.append(
|
221
|
+
Directory(os.path.abspath(d))
|
222
|
+
)
|
223
|
+
return values
|
190
224
|
|
191
225
|
def basename(self) -> str:
|
192
226
|
return os.path.basename(self.absolute())
|
@@ -225,18 +259,18 @@ class InputFiles(object):
|
|
225
259
|
"""
|
226
260
|
Obeter uma lista de arquivos/documentos do diretório informado.
|
227
261
|
"""
|
228
|
-
def __init__(self, d:Directory, *, maxFiles:int=5000):
|
262
|
+
def __init__(self, d: Directory, *, maxFiles: int = 5000):
|
229
263
|
if not isinstance(d, Directory):
|
230
264
|
raise ValueError(f'{__class__.__name__}\nUse: Directory(), não {type(d)}')
|
231
|
-
self.input_dir:Directory = d
|
232
|
-
self.maxFiles:int = maxFiles
|
265
|
+
self.input_dir: Directory = d
|
266
|
+
self.maxFiles: int = maxFiles
|
233
267
|
|
234
|
-
def get_files_with(self, *, infile:str, sort:bool=True) -> List[File]:
|
268
|
+
def get_files_with(self, *, infile: str, sort: bool = True) -> List[File]:
|
235
269
|
"""
|
236
270
|
Retorna arquivos que contém a ocorrência (infile) no nome absoluto.
|
237
271
|
"""
|
238
|
-
content_files:List[File] = []
|
239
|
-
count:int = 0
|
272
|
+
content_files: List[File] = []
|
273
|
+
count: int = 0
|
240
274
|
paths = self.input_dir.iterpaths()
|
241
275
|
for file in paths:
|
242
276
|
if not file.is_file():
|
@@ -250,24 +284,20 @@ class InputFiles(object):
|
|
250
284
|
break
|
251
285
|
return content_files
|
252
286
|
|
253
|
-
def
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
- LibraryDocs.ALL_DOCUMENTS => Retorna todos os documentos do diretório.
|
258
|
-
- LibraryDocs.EXCEL => Retorna arquivos que são planilhas excel.
|
259
|
-
- ...
|
260
|
-
|
261
|
-
"""
|
262
|
-
_paths = self.input_dir.iterpaths()
|
287
|
+
def __get_files_recursive(self, *, file_type: LibraryDocs, sort: bool) -> List[File]:
|
288
|
+
#
|
289
|
+
#
|
290
|
+
_paths: List[Path] = self.input_dir.iterpaths()
|
263
291
|
_all_files = []
|
264
|
-
count:int = 0
|
292
|
+
count: int = 0
|
265
293
|
if file_type == LibraryDocs.ALL:
|
266
294
|
# Todos os tipos de arquivos
|
267
295
|
for p in _paths:
|
268
296
|
if not p.is_file():
|
269
297
|
continue
|
270
|
-
_all_files.append(
|
298
|
+
_all_files.append(
|
299
|
+
File(os.path.abspath(p.absolute()))
|
300
|
+
)
|
271
301
|
count += 1
|
272
302
|
if count >= self.maxFiles:
|
273
303
|
break
|
@@ -279,14 +309,67 @@ class InputFiles(object):
|
|
279
309
|
if (p.suffix is None) or (p.suffix == ''):
|
280
310
|
continue
|
281
311
|
if p.suffix in file_type.value:
|
282
|
-
_all_files.append(
|
312
|
+
_all_files.append(
|
313
|
+
File(os.path.abspath(p.absolute()))
|
314
|
+
)
|
283
315
|
count += 1
|
284
316
|
if count >= self.maxFiles:
|
285
317
|
break
|
286
|
-
if sort
|
318
|
+
if sort:
|
287
319
|
_all_files.sort(key=File.absolute)
|
288
320
|
return _all_files
|
289
321
|
|
322
|
+
def __get_files_no_recursive(self, *, file_type: LibraryDocs, sort: bool):
|
323
|
+
_paths: List[str] = os.listdir(self.input_dir.absolute())
|
324
|
+
_all_files = []
|
325
|
+
count: int = 0
|
326
|
+
if file_type == LibraryDocs.ALL:
|
327
|
+
# Todos os tipos de arquivos
|
328
|
+
for p in _paths:
|
329
|
+
if os.path.isfile(p):
|
330
|
+
_all_files.append(
|
331
|
+
File(os.path.abspath(p))
|
332
|
+
)
|
333
|
+
count += 1
|
334
|
+
if count >= self.maxFiles:
|
335
|
+
break
|
336
|
+
else:
|
337
|
+
# Arquivos especificados em LibraryDocs
|
338
|
+
for p in _paths:
|
339
|
+
if os.path.isfile(p):
|
340
|
+
_path_file = Path(p)
|
341
|
+
if (_path_file.suffix is None) or (_path_file.suffix == ''):
|
342
|
+
continue
|
343
|
+
if _path_file.suffix in file_type.value:
|
344
|
+
_all_files.append(
|
345
|
+
File(os.path.abspath(_path_file.absolute()))
|
346
|
+
)
|
347
|
+
count += 1
|
348
|
+
if count >= self.maxFiles:
|
349
|
+
break
|
350
|
+
if sort:
|
351
|
+
_all_files.sort(key=File.absolute)
|
352
|
+
return _all_files
|
353
|
+
|
354
|
+
def get_files(
|
355
|
+
self, *,
|
356
|
+
file_type: LibraryDocs = LibraryDocs.ALL_DOCUMENTS,
|
357
|
+
sort: bool = True,
|
358
|
+
recursive: bool = True
|
359
|
+
) -> List[File]:
|
360
|
+
"""
|
361
|
+
Retorna uma lista de File() de acordo com o tipo de arquivo
|
362
|
+
especificado.
|
363
|
+
- LibraryDocs.ALL_DOCUMENTS => Retorna todos os documentos do diretório.
|
364
|
+
- LibraryDocs.EXCEL => Retorna arquivos que são planilhas excel.
|
365
|
+
- ...
|
366
|
+
|
367
|
+
"""
|
368
|
+
if recursive:
|
369
|
+
return self.__get_files_recursive(file_type=file_type, sort=sort)
|
370
|
+
else:
|
371
|
+
return self.__get_files_no_recursive(file_type=file_type, sort=sort)
|
372
|
+
|
290
373
|
|
291
374
|
class JsonData(object):
|
292
375
|
"""
|
@@ -322,8 +405,8 @@ class JsonConvert(object):
|
|
322
405
|
"""
|
323
406
|
Conversão de um dado JSON em dados python
|
324
407
|
"""
|
325
|
-
def __init__(self, jsonData:JsonData):
|
326
|
-
self.jsonData:JsonData = jsonData
|
408
|
+
def __init__(self, jsonData: JsonData):
|
409
|
+
self.jsonData: JsonData = jsonData
|
327
410
|
|
328
411
|
def to_json_data(self) -> JsonData:
|
329
412
|
return self.jsonData
|
soup_files/progress.py
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
from abc import ABC, abstractmethod
|
4
|
+
|
5
|
+
|
6
|
+
class ABCProgressBar(ABC):
|
7
|
+
"""
|
8
|
+
Barra de progresso Abstrata
|
9
|
+
"""
|
10
|
+
|
11
|
+
def __init__(self):
|
12
|
+
super().__init__()
|
13
|
+
self._num_progress: float = 0
|
14
|
+
self.pbar_real: object = None
|
15
|
+
|
16
|
+
@property
|
17
|
+
def num_progress(self) -> float:
|
18
|
+
return self._num_progress
|
19
|
+
|
20
|
+
@num_progress.setter
|
21
|
+
def num_progress(self, new: float):
|
22
|
+
if isinstance(new, float):
|
23
|
+
self._num_progress = new
|
24
|
+
return
|
25
|
+
try:
|
26
|
+
_prog = float(new)
|
27
|
+
except Exception as e:
|
28
|
+
print(e)
|
29
|
+
else:
|
30
|
+
self._num_progress = _prog
|
31
|
+
|
32
|
+
@abstractmethod
|
33
|
+
def set_percent(self, percent: float):
|
34
|
+
"""Seta o progresso com float de porcentagem, ex: '42.8'"""
|
35
|
+
pass
|
36
|
+
|
37
|
+
@abstractmethod
|
38
|
+
def set_text(self, text: str):
|
39
|
+
"""Seta um texto indicando a situação atual"""
|
40
|
+
pass
|
41
|
+
|
42
|
+
def start(self):
|
43
|
+
"""Inicia a barra de progresso (pode ser vazio dependendo da implementação)"""
|
44
|
+
pass
|
45
|
+
|
46
|
+
def stop(self):
|
47
|
+
"""Para a barra de progresso (pode ser vazio dependendo da implementação)"""
|
48
|
+
pass
|
49
|
+
|
50
|
+
|
51
|
+
class ProgressBarSimple(ABCProgressBar):
|
52
|
+
"""Barra de progresso simples para mostrar no terminal."""
|
53
|
+
|
54
|
+
def __init__(self, simple_pbar=None):
|
55
|
+
super().__init__()
|
56
|
+
self.pbar_real = simple_pbar
|
57
|
+
self._text: str = 'Aguarde!'
|
58
|
+
self.num_progress: float = 0
|
59
|
+
|
60
|
+
def set_percent(self, percent: float):
|
61
|
+
if not isinstance(percent, float):
|
62
|
+
return
|
63
|
+
if len(f'{percent}') > 4:
|
64
|
+
percent = round(float(percent), 2)
|
65
|
+
self.num_progress = percent
|
66
|
+
#print(f'[{self.num_progress}%] {self._text}', end='\r')
|
67
|
+
|
68
|
+
def set_text(self, text: str):
|
69
|
+
self._text = text
|
70
|
+
print(f'[{self.num_progress}%] {self._text}', end='\r')
|
71
|
+
|
72
|
+
def start(self):
|
73
|
+
pass
|
74
|
+
|
75
|
+
def stop(self):
|
76
|
+
pass
|
77
|
+
|
78
|
+
|
79
|
+
class ProgressBarAdapter(object):
|
80
|
+
def __init__(self, progress_bar: ABCProgressBar = ProgressBarSimple()):
|
81
|
+
self.pbar_implement: ABCProgressBar = progress_bar
|
82
|
+
|
83
|
+
def get_current_percent(self) -> float:
|
84
|
+
return self.pbar_implement.num_progress
|
85
|
+
|
86
|
+
def update_text(self, text: str = "-"):
|
87
|
+
self.pbar_implement.set_text(text)
|
88
|
+
|
89
|
+
def update_percent(self, percent: float = 0):
|
90
|
+
if not isinstance(percent, float):
|
91
|
+
try:
|
92
|
+
percent = float(percent)
|
93
|
+
except Exception as e:
|
94
|
+
print(f'{__class__.__name__} {e}')
|
95
|
+
percent = 0
|
96
|
+
self.pbar_implement.set_percent(percent)
|
97
|
+
|
98
|
+
def update(self, percent: float, status: str = "-"):
|
99
|
+
self.update_percent(percent)
|
100
|
+
self.update_text(status)
|
101
|
+
#self.pbar_implement.set_text(status)
|
102
|
+
|
103
|
+
def start(self):
|
104
|
+
self.pbar_implement.start()
|
105
|
+
|
106
|
+
def stop(self):
|
107
|
+
self.pbar_implement.stop()
|
108
|
+
|
soup_files/version.py
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
soup_files/__init__.py,sha256=G91WhdwJvUJJLiIDL2XSGSqZNwLoJ7gfLfiYquUkNpk,299
|
2
|
+
soup_files/files.py,sha256=QN29DUXrQtqS_wI_KawqUB0XCyjnzH4cgyolaXdkg04,15784
|
3
|
+
soup_files/progress.py,sha256=kGPESPQCmoIlgJoy7Y8sF5ZG9tfx6uafXYrcBAPibfY,2903
|
4
|
+
soup_files/version.py,sha256=TpmZmL9rNerchvGdpdGh4bPNo516cs6BzzXctjsbRq8,46
|
5
|
+
soup_files-1.2.1.dist-info/METADATA,sha256=jqN1cgUQJGoi-kCfi2aU901x6o1af2lIwmr5vti9s54,174
|
6
|
+
soup_files-1.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
7
|
+
soup_files-1.2.1.dist-info/top_level.txt,sha256=CBSaCdIqL_Rlkr74APmmI0kXkPK9pVf6HTlOPZ-Kk4E,11
|
8
|
+
soup_files-1.2.1.dist-info/RECORD,,
|
@@ -1,19 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: soup-files
|
3
|
-
Version: 1.0.1
|
4
|
-
Summary: Leitura e manipulação de arquivos
|
5
|
-
Author: Bruno
|
6
|
-
License: MIT
|
7
|
-
Requires-Python: >=3.11
|
8
|
-
Description-Content-Type: text/markdown
|
9
|
-
|
10
|
-
# file-utils
|
11
|
-
|
12
|
-
# Uso
|
13
|
-
from soup_files import File, Directory
|
14
|
-
|
15
|
-
filename:str = 'path/to/file'
|
16
|
-
dirpath:str = 'path/to/dir'
|
17
|
-
|
18
|
-
f = File(filename)
|
19
|
-
d = Directory(dirpath)
|
@@ -1,6 +0,0 @@
|
|
1
|
-
soup_files/__init__.py,sha256=O9oM7fGDdnzHAhpsxXSqO_SH2yMn2O_6t0n2EyyzOFY,49
|
2
|
-
soup_files/soup_files.py,sha256=JhigMvXDorHa_2io-kJSTmX8Z2U7B8MoGV5NOj9mXds,12891
|
3
|
-
soup_files-1.0.1.dist-info/METADATA,sha256=ixYhA3xag-tz-mIwO2cegFzOHaFZ08fKR2DN9EoSG-4,352
|
4
|
-
soup_files-1.0.1.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
5
|
-
soup_files-1.0.1.dist-info/top_level.txt,sha256=CBSaCdIqL_Rlkr74APmmI0kXkPK9pVf6HTlOPZ-Kk4E,11
|
6
|
-
soup_files-1.0.1.dist-info/RECORD,,
|
File without changes
|