udemy-userAPI 0.3.5__py3-none-any.whl → 0.3.6__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,64 +0,0 @@
1
- import sys
2
- import time
3
- import threading
4
- from colorama import init, Fore, Style
5
-
6
- # Inicializa o suporte a cores no Windows
7
- init(autoreset=True)
8
-
9
-
10
- class AnimationConsole:
11
- def __init__(self, text="Loading", color=Fore.GREEN, color_frame=Fore.BLUE):
12
- """
13
- Cria uma animação de loading com uma mensagem colorida no console.
14
- :param text: Texto inicial da mensagem de loading.
15
- :param color: Cor do texto, usando Fore do colorama.
16
- """
17
- self._color_frame = color_frame
18
- self._text = text
19
- self._color = color
20
- self._running = False
21
- self._animation_thread = None
22
- self._frames = ["-", "\\", "|", "/"]
23
- self._index = 0
24
-
25
- def start(self):
26
- """
27
- Inicia a animação no console.
28
- """
29
- if self._running:
30
- return # Previne múltiplas execuções
31
- self._running = True
32
- self._animation_thread = threading.Thread(target=self._animate, daemon=True)
33
- self._animation_thread.start()
34
-
35
- def stop(self):
36
- """
37
- Para a animação no console.
38
- """
39
- self._running = False
40
- if self._animation_thread:
41
- self._animation_thread.join()
42
- sys.stdout.write("\r" + " " * (len(self._text) + 20) + "\r") # Limpa a linha
43
-
44
- def update_message(self, new_text, new_color=None):
45
- """
46
- Atualiza a mensagem exibida junto à animação.
47
- :param new_text: Novo texto a ser exibido.
48
- :param new_color: Nova cor para o texto (opcional).
49
- """
50
- self._text = new_text
51
- if new_color:
52
- self._color = new_color
53
-
54
- def _animate(self):
55
- """
56
- Animação interna do console.
57
- """
58
- while self._running:
59
- frame = self._frames[self._index]
60
- self._index = (self._index + 1) % len(self._frames)
61
- sys.stdout.write(
62
- f"\r{self._color}{self._text}{Style.RESET_ALL} {self._color_frame}{frame}{Style.RESET_ALL}")
63
- sys.stdout.flush()
64
- time.sleep(0.1)
@@ -1,118 +0,0 @@
1
- import sys
2
- import os
3
- import requests
4
- import zipfile
5
- import shutil
6
- import stat
7
- from .exeptions import *
8
- from .__utils import URL_PLATAFOMR, system
9
-
10
- lib_name = os.path.dirname(__file__)
11
- URL_BASE_REPO = "https://raw.githubusercontent.com/PauloCesar-dev404/binarios/main/"
12
-
13
-
14
- class Configurate:
15
- """Configura variáveis de ambiente no ambiente virtual ou globalmente."""
16
-
17
- def __init__(self):
18
- self.VERSION = self.__read_version
19
- self.FFMPEG_URL = os.getenv('FFMPEG_URL')
20
- self.FFMPEG_BINARY = os.getenv('FFMPEG_BINARY')
21
- PATH = os.path.join(lib_name, 'ffmpeg-bin')
22
- os.makedirs(PATH, exist_ok=True)
23
- dirpath = PATH
24
- self.INSTALL_DIR = os.getenv('INSTALL_DIR', dirpath)
25
- self.configure()
26
-
27
- def configure(self):
28
- """Configura as variáveis de ambiente com base no sistema operacional."""
29
- if not self.FFMPEG_URL or not self.FFMPEG_BINARY:
30
- platform_name = system
31
- if platform_name == 'Windows':
32
- self.FFMPEG_URL = URL_PLATAFOMR
33
- self.FFMPEG_BINARY = 'ffmpeg.exe'
34
- elif platform_name == 'Linux':
35
- self.FFMPEG_URL = URL_PLATAFOMR
36
- self.FFMPEG_BINARY = 'ffmpeg'
37
- else:
38
- raise DeprecationWarning(f"Arquitetura '{platform_name}' ainda não suportada...\n\n"
39
- f"Versão atual da lib: {self.VERSION}")
40
- os.environ['FFMPEG_URL'] = self.FFMPEG_URL
41
- os.environ['FFMPEG_BINARY'] = self.FFMPEG_BINARY
42
-
43
- if not os.getenv('INSTALL_DIR'):
44
- os.environ['INSTALL_DIR'] = self.INSTALL_DIR
45
-
46
- @property
47
- def __read_version(self):
48
- """Lê a versão do arquivo __version__.py."""
49
- version_file = os.path.join(os.path.dirname(os.path.abspath(__file__)).split('.')[0], '__version__.py')
50
- if os.path.isfile(version_file):
51
- with open(version_file, 'r') as file:
52
- version_line = file.readline().strip()
53
- if version_line.startswith('__version__'):
54
- return version_line.split('=')[1].strip().strip("'")
55
- return 'Unknown Version'
56
-
57
- def __download_file(self, url: str, local_filename: str):
58
- """Baixa um arquivo do URL para o caminho local especificado."""
59
- try:
60
- response = requests.get(url, stream=True)
61
- response.raise_for_status()
62
- total_length = int(response.headers.get('content-length', 0))
63
-
64
- with open(local_filename, 'wb') as f:
65
- start_time = time.time()
66
- downloaded = 0
67
-
68
- for data in response.iter_content(chunk_size=4096):
69
- downloaded += len(data)
70
- f.write(data)
71
-
72
- elapsed_time = time.time() - start_time
73
- elapsed_time = max(elapsed_time, 0.001)
74
- speed_kbps = (downloaded / 1024) / elapsed_time
75
- percent_done = (downloaded / total_length) * 100
76
-
77
-
78
- except requests.RequestException as e:
79
- raise Exception(f"Erro durante o download: {e}")
80
-
81
- def __extract_zip(self, zip_path: str, extract_to: str):
82
- """Descompacta o arquivo ZIP no diretório especificado."""
83
- try:
84
- with zipfile.ZipFile(zip_path, 'r') as zip_ref:
85
- zip_ref.extractall(extract_to)
86
- except zipfile.BadZipFile as e:
87
- sys.stderr.write(f"Erro ao descompactar o arquivo: {e}\n")
88
- raise
89
- finally:
90
- os.remove(zip_path)
91
-
92
- def remove_file(self, file_path: str):
93
- """Remove o arquivo ou diretório especificado."""
94
- if os.path.exists(file_path):
95
- try:
96
- shutil.rmtree(file_path, onerror=self.handle_remove_readonly)
97
- except Exception as e:
98
- print(f"Erro ao remover {file_path}: {e}")
99
- raise
100
-
101
- def install_bins(self):
102
- """Instala o ffmpeg baixando e descompactando o binário apropriado."""
103
- zip_path = os.path.join(self.INSTALL_DIR, "ffmpeg.zip")
104
- os.makedirs(self.INSTALL_DIR, exist_ok=True)
105
- self.__download_file(self.FFMPEG_URL, zip_path)
106
- self.__extract_zip(zip_path, self.INSTALL_DIR)
107
- self.remove_file(zip_path)
108
- os.environ["PATH"] += os.pathsep + self.INSTALL_DIR
109
- return
110
-
111
- def handle_remove_readonly(self, func, path, exc_info):
112
- """Callback para lidar com arquivos somente leitura."""
113
- os.chmod(path, stat.S_IWRITE)
114
- func(path)
115
-
116
-
117
- if __name__ == "__main__":
118
- FFmpegExceptions("erro de runtime...")
@@ -1,8 +0,0 @@
1
- # ffmpeg-and-python/__init__.py
2
-
3
- from .ffmpeg import FFmpeg
4
- from .exeptions import FFmpegExceptions
5
-
6
- __all__ = ['FFmpeg', 'FFmpegExceptions']
7
- if __name__ == '__main__':
8
- raise RuntimeError("no escope!")
@@ -1,78 +0,0 @@
1
- import platform
2
- import os
3
-
4
- URL_PLATAFOMR = ''
5
-
6
-
7
- def get_processor_info():
8
- system = platform.system()
9
- architecture = platform.architecture()[0]
10
- processor = ''
11
- if system == "Windows":
12
- processor = platform.processor()
13
- elif system in ["Linux", "Darwin"]: # Darwin é o nome do sistema para macOS
14
- try:
15
- if system == "Linux":
16
- # Obtém informações detalhadas do processador no Linux
17
- with open("/proc/cpuinfo") as f:
18
- cpuinfo = f.read()
19
- if "model name" in cpuinfo:
20
- processor = cpuinfo.split("model name")[1].split(":")[1].split("\n")[0].strip()
21
- else:
22
- processor = "Unknown"
23
- elif system == "Darwin":
24
- # Obtém informações detalhadas do processador no macOS
25
- processor = os.popen("sysctl -n machdep.cpu.brand_string").read().strip()
26
- except FileNotFoundError:
27
- processor = "Unknown"
28
- d = (f"System: {system} "
29
- f"Architecture: {architecture} "
30
- f"Processor: {processor} ")
31
- return d
32
-
33
-
34
- # Processa a informação do processador e limpa a string
35
- data = (get_processor_info().replace('Architecture:', '').replace('System:', '').
36
- replace('Processor:', '').strip().split())
37
-
38
- # Remove entradas vazias e limpa espaços em branco
39
- cleaned_data = [item.strip() for item in data if item.strip()]
40
-
41
- # Garantindo que há pelo menos três elementos
42
- if len(cleaned_data) >= 2:
43
- system = cleaned_data[0]
44
- architecture = cleaned_data[1]
45
- processor = ' '.join(cleaned_data[2:]) # Junta o restante como o processador
46
-
47
- URL_BASE_REPO = "https://raw.githubusercontent.com/PauloCesar-dev404/binarios/main/"
48
- # Mapeamento para Linux
49
- linux_mapping = {
50
- "x86_64": "amd64",
51
- "i686": "i686",
52
- "arm64": "arm64",
53
- "armhf": "armhf",
54
- "armel": "armel"
55
- }
56
- # Formata a URL com base no sistema e arquitetura
57
- if system == "Linux" and ('intel' in processor.lower() or 'amd' in processor.lower()):
58
- url = f"{URL_BASE_REPO}linux/ffmpeg-7.0.2-{linux_mapping.get('x86_64')}.zip"
59
- elif system == "Linux" and 'i686' in architecture.lower():
60
- url = f"{URL_BASE_REPO}linux/ffmpeg-7.0.2-{linux_mapping.get('i686')}.zip"
61
- elif system == "Linux" and 'arm64' in architecture.lower():
62
- url = f"{URL_BASE_REPO}linux/ffmpeg-7.0.2-{linux_mapping.get('arm64')}.zip"
63
- elif system == "Linux" and 'armhf' in architecture.lower():
64
- url = f"{URL_BASE_REPO}linux/ffmpeg-7.0.2-{linux_mapping.get('armhf')}.zip"
65
- elif system == "Linux" and 'armel' in architecture.lower():
66
- url = f"{URL_BASE_REPO}linux/ffmpeg-7.0.2-{linux_mapping.get('armel')}.zip"
67
- elif system == "Windows" and architecture == '64bit':
68
- url = f"{URL_BASE_REPO}windows/win-ffmpeg-7.0.2-full-amd64-intel64.zip"
69
- else:
70
- url = f"Unsupported system or architecture"
71
-
72
- URL_PLATAFOMR = url
73
-
74
- else:
75
- raise DeprecationWarning("Não foi possível obter seu sistema ....consulte o desenvolvedor!")
76
-
77
- if __name__ == '__main__':
78
- raise RuntimeError("este é uma função interna!")
@@ -1,6 +0,0 @@
1
- __version__ = '0.3.5'
2
- __lib_name__ = 'ffmpeg_for_python'
3
- __autor__ = 'PauloCesar-dev404'
4
- __repo__ = 'https://github.com/PauloCesar-dev404/ffmpeg-for-python'
5
- __lib__ = f'https://raw.githubusercontent.com/PauloCesar-dev404/ffmpeg-for-python/main/{__lib_name__}-{__version__}-py3-none-any.whl'
6
- __source__ = f'https://raw.githubusercontent.com/PauloCesar-dev404/ffmpeg-for-python/main/{__lib_name__}-{__version__}.tar.gz'
@@ -1,91 +0,0 @@
1
- import time
2
-
3
- INPUT_ERROR = [
4
- 'Error opening input: No such file or directory',
5
- 'Error opening input: Permission denied',
6
- 'Error opening input: Invalid argument',
7
- 'Error opening input: Protocol not found',
8
- 'Error opening input: Unsupported protocol',
9
- 'Error opening input: File format not recognized',
10
- 'Error opening input: Could not open file',
11
- 'Error opening input: Invalid data found when processing input',
12
- 'Error opening input: Input stream is empty',
13
- 'Error opening input: Cannot open file for reading',
14
- 'Error opening input: File is too short',
15
- 'Error opening input: End of file while parsing input',
16
- 'Error opening input: Codec not found',
17
- 'Error opening input: No decoder for codec',
18
- 'Error opening input: Stream not found',
19
- 'Error opening input: Stream codec not found',
20
- 'Error opening input: Stream index out of range',
21
- 'Error opening input: Invalid timestamp',
22
- 'Error opening input: Corrupt file',
23
- 'Error opening input: Unsupported codec',
24
- 'Error opening input: Failed to initialize filter',
25
- 'Error opening input: Error while opening codec',
26
- 'Error opening input: Device not found',
27
- 'Error opening input: Device or resource busy',
28
- 'Error opening input: Invalid option',
29
- 'Error opening input: Unable to seek',
30
- 'Error opening input: Input format not found'
31
- ]
32
- OUTPUT_ERROR = [
33
- 'Error opening output file: No such file or directory',
34
- 'Error opening output file: Permission denied',
35
- 'Error opening output file: Invalid argument',
36
- 'Error opening output file: Unsupported protocol',
37
- 'Error opening output file: Protocol not found',
38
- 'Error opening output file: File format not recognized',
39
- 'Error opening output file: Could not open file for writing',
40
- 'Error opening output file: Disk full or quota exceeded',
41
- 'Error opening output file: Cannot create file',
42
- 'Error opening output file: Invalid data found when processing output',
43
- 'Error opening output file: Output stream not found',
44
- 'Error opening output file: Cannot write to file',
45
- 'Error opening output file: File already exists',
46
- 'Error opening output file: Unsupported codec',
47
- 'Error opening output file: Codec not found',
48
- 'Error opening output file: Cannot open codec for writing',
49
- 'Error opening output file: Failed to initialize filter',
50
- 'Error opening output file: Invalid option',
51
- 'Error opening output file: Invalid timestamp',
52
- 'Error opening output file: Corrupt file',
53
- 'Error opening output file: Device or resource busy',
54
- 'Error opening output file: Cannot seek',
55
- 'Error opening output file: Stream index out of range',
56
- 'Error opening output file: Stream codec not found'
57
- ]
58
- ERROS = []
59
- for er in INPUT_ERROR:
60
- ERROS.append(er)
61
- for er in OUTPUT_ERROR:
62
- ERROS.append(er)
63
-
64
-
65
- class FFmpegExceptions(Exception):
66
- def __init__(self, message: str):
67
- super().__init__(message)
68
-
69
- def __str__(self):
70
- """
71
- Retorna a representação em string da exceção.
72
-
73
- Returns:
74
- str: Mensagem de erro formatada com detalhes adicionais, se presentes.
75
- """
76
-
77
- return super().__str__()
78
-
79
-
80
- def wraper_erros(line: str):
81
- """Verifica se a linha de saida do ffmpeg está no dict de erros e retorna sua categoria"""
82
-
83
- if "Error" in line:
84
- erro = line.split('Error')[1]
85
- return erro.strip()
86
- elif 'already exists. Overwrite? [y/N]' in line:
87
- erro = line.split('File')[1]
88
- return erro.strip()
89
-
90
-
91
-
@@ -1,203 +0,0 @@
1
- import os
2
- import platform
3
- import subprocess
4
- import time
5
- from typing import List
6
- from .__config__ import Configurate
7
- from .exeptions import wraper_erros, FFmpegExceptions
8
-
9
- parser = Configurate()
10
- parser.configure()
11
- ffmpeg_binarie = os.path.join(parser.INSTALL_DIR, parser.FFMPEG_BINARY)
12
-
13
-
14
- def ffmpeg(cls):
15
- """Decorador que instancia automaticamente a classe FFmpeg."""
16
-
17
- def wrapper(*args, **kwargs):
18
- # Cria e retorna uma instância da classe FFmpeg
19
- instance = cls(*args, **kwargs)
20
- return instance
21
-
22
- return wrapper
23
-
24
-
25
- @ffmpeg
26
- class FFmpeg:
27
- """Wrapper para o binário FFmpeg, permitindo o uso de comandos FFmpeg via Python."""
28
-
29
- def __init__(self):
30
- # Verifica se o binário do FFmpeg existe
31
- if not self.__verify_path(bin_path=ffmpeg_binarie, path_type='file'):
32
- parser.install_bins()
33
- self.__ffmpeg_path = str(ffmpeg_binarie)
34
- self.__command = [self.__ffmpeg_path]
35
- self.__overwrite_output = False
36
-
37
- def args(self, arguments: List[str]) -> 'FFmpeg':
38
- """Adiciona múltiplos argumentos personalizados ao comando FFmpeg."""
39
- if not all(isinstance(arg, str) for arg in arguments):
40
- raise TypeError("All arguments should be provided as strings.")
41
- self.__command.extend(arguments)
42
- return self
43
-
44
- def run(self, capture_output: bool = False):
45
- """Executa o comando FFmpeg construído.
46
-
47
- Args:
48
- capture_output (bool): Se verdadeiro, captura a saída e printa no console.
49
- Se False, a saída é retornada assincronamente em tempo real.
50
-
51
- Yields:
52
- str: Cada linha da saída filtrada do FFmpeg quando capture_output é False.
53
- """
54
-
55
- configs = self.__oculte_comands_your_system.get('startupinfo')
56
-
57
- # Executa o comando utilizando subprocess
58
- with subprocess.Popen(
59
- self.__command,
60
- startupinfo=configs,
61
- stdout=subprocess.PIPE,
62
- stderr=subprocess.PIPE,
63
- stdin=subprocess.PIPE,
64
- text=True,
65
- bufsize=1, # Linha por linha
66
- universal_newlines=True # Garante que novas linhas sejam interpretadas corretamente
67
- ) as process:
68
- try:
69
- # Lê a saída de erro padrão (stderr) em tempo real
70
- for linha in process.stderr:
71
- time.sleep(0.01) # Simulação de latência, opcional
72
-
73
- # Filtra a linha de erro padrão
74
- linha_filtrada = wraper_erros(linha)
75
-
76
- if linha_filtrada:
77
- # Se houver um erro detectado, o processo é encerrado
78
- process.terminate()
79
- raise FFmpegExceptions(message=f'Erro na execução do ffmpeg: "{linha_filtrada}"')
80
- else:
81
- if capture_output:
82
- # Se `capture_output` estiver ativado, imprime a saída
83
- print(linha.strip())
84
- else:
85
- # Retorna a linha assincronamente quando capture_output é False
86
- yield linha.strip()
87
-
88
- # Aguarda a conclusão do processo
89
- process.wait()
90
-
91
- except Exception as e:
92
- process.terminate()
93
- raise FFmpegExceptions(message=f'Erro no processo FFmpeg: {str(e)}')
94
-
95
- def input(self, file_path: str) -> 'FFmpeg':
96
- """Define o arquivo de entrada para o FFmpeg."""
97
- cmd = ['-i', file_path]
98
- self.args(cmd)
99
- return self
100
-
101
- def output(self, output_path: str) -> 'FFmpeg':
102
- """Define o arquivo de saída para o FFmpeg e verifica se a sobrescrita está permitida."""
103
- if os.path.exists(output_path):
104
- if not self.__overwrite_output:
105
- raise FFmpegExceptions(f"O arquivo de saída '{output_path}' já existe! Use 'overwrite_output' para "
106
- f"sobrescrevê-lo.")
107
-
108
- # Adiciona o arquivo de saída ao comando
109
- cmd = [output_path]
110
- self.args(cmd)
111
- return self
112
-
113
- @property
114
- def overwrite_output(self):
115
- """
116
- Adiciona o parâmetro '-y' ao comando FFmpeg, o que permite sobrescrever o arquivo de saída
117
- caso ele já exista.
118
-
119
- Importante: Esta propriedade deve ser definida antes dos parâmetros de entrada e saída
120
- para garantir que o comando FFmpeg seja construído corretamente. Caso contrário, o comando
121
- pode não ser executado como esperado.
122
-
123
- Returns:
124
- FFmpeg: Retorna a instância atual para encadeamento de métodos.
125
- """
126
- self.__overwrite_output = True
127
- cmd = ['-y']
128
- self.args(cmd)
129
- return self
130
-
131
- @property
132
- def hide_banner(self) -> 'FFmpeg':
133
- """oculta o baner do ffmpeg"""
134
- self.__command.extend(['-hide_banner'])
135
- return self
136
-
137
- @property
138
- def copy(self) -> 'FFmpeg':
139
- """Adiciona o parâmetro '-c copy"""
140
- self.__command.extend(['-c', 'copy'])
141
- return self
142
-
143
- @property
144
- def copy_codecs(self):
145
- """para remuxar"""
146
- self.__command.extend(['-c:a', 'copy', '-c:v', 'copy'])
147
- return self
148
-
149
- def reset_ffmpeg(self) -> 'FFmpeg':
150
- """Reseta o comando para reutilização do objeto,isso é necessário em caso de uso em loops,
151
- a cada execução execute o reset para ter certeza que estar limpo o cache de comandos"""
152
- self.__command = [self.__ffmpeg_path]
153
- return self
154
-
155
- @staticmethod
156
- def __verify_path(bin_path, path_type: str) -> bool:
157
- """
158
- Verifica se um caminho de arquivo ou diretório existe.
159
-
160
- Args:
161
- bin_path : O caminho a ser verificado.
162
- path_type (str): O tipo de caminho ('file' para arquivo, 'dir' para diretório).
163
-
164
- Returns:
165
- bool: True se o caminho existir e for do tipo especificado, False caso contrário.
166
- """
167
- if path_type == 'file':
168
- return os.path.isfile(bin_path)
169
- elif path_type == 'dir':
170
- return os.path.isdir(bin_path)
171
- else:
172
- raise ValueError("Invalid path_type. Use 'file' or 'dir'.")
173
-
174
- @property
175
- def __oculte_comands_your_system(self) -> dict:
176
- """Identifica o sistema do usuário e cria um dicionário de parâmetros para ocultar saídas de janelas e do
177
- terminal."""
178
- system_user = platform.system()
179
- startupinfo_options = {}
180
-
181
- if system_user == "Windows":
182
- # Configuração específica para ocultar o terminal no Windows
183
- startupinfo = subprocess.STARTUPINFO()
184
- startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
185
- startupinfo.wShowWindow = subprocess.SW_HIDE
186
- startupinfo_options['startupinfo'] = startupinfo
187
-
188
- # Definindo stdout, stderr e stdin para DEVNULL para esconder saídas
189
- startupinfo_options['stdout'] = subprocess.DEVNULL
190
- startupinfo_options['stderr'] = subprocess.DEVNULL
191
- startupinfo_options['stdin'] = subprocess.DEVNULL
192
-
193
- elif system_user in ["Linux", "Darwin"]:
194
- # Para Linux e macOS, ocultar stdout, stderr e stdin
195
- startupinfo_options['stdout'] = subprocess.DEVNULL
196
- startupinfo_options['stderr'] = subprocess.DEVNULL
197
- startupinfo_options['stdin'] = subprocess.DEVNULL
198
-
199
- else:
200
- # Exceção para sistemas não suportados
201
- raise NotImplementedError(f"O sistema {system_user} não é suportado para ocultação de comandos.")
202
-
203
- return startupinfo_options