udemy-userAPI 0.3.7__py3-none-any.whl → 0.3.9__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.
- animation_consoles/__init__.py +1 -0
- animation_consoles/animation.py +64 -0
- ffmpeg_for_python/__config__.py +118 -0
- ffmpeg_for_python/__init__.py +8 -0
- ffmpeg_for_python/__utils.py +78 -0
- ffmpeg_for_python/__version__.py +6 -0
- ffmpeg_for_python/exeptions.py +91 -0
- ffmpeg_for_python/ffmpeg.py +203 -0
- m3u8_analyzer/M3u8Analyzer.py +807 -0
- m3u8_analyzer/__init__.py +7 -0
- m3u8_analyzer/__version__.py +1 -0
- m3u8_analyzer/exeptions.py +82 -0
- udemy_userAPI/__version__.py +1 -1
- udemy_userAPI/api.py +52 -30
- udemy_userAPI/bultins.py +6 -120
- udemy_userAPI/sections.py +42 -17
- udemy_userAPI/udemy.py +4 -13
- {udemy_userAPI-0.3.7.dist-info → udemy_userAPI-0.3.9.dist-info}/METADATA +2 -2
- udemy_userAPI-0.3.9.dist-info/RECORD +29 -0
- udemy_userAPI-0.3.7.dist-info/RECORD +0 -17
- {udemy_userAPI-0.3.7.dist-info → udemy_userAPI-0.3.9.dist-info}/LICENSE +0 -0
- {udemy_userAPI-0.3.7.dist-info → udemy_userAPI-0.3.9.dist-info}/WHEEL +0 -0
- {udemy_userAPI-0.3.7.dist-info → udemy_userAPI-0.3.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = '1.0.4.1'
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class M3u8AnalyzerExceptions(Exception):
|
2
|
+
def __init__(self, message="Erro na análise da playlist M3U8", errors=None):
|
3
|
+
"""
|
4
|
+
Exceção base para erros relacionados à análise de playlists M3U8.
|
5
|
+
|
6
|
+
Args:
|
7
|
+
message (str): Mensagem descritiva do erro. Padrão é "Erro na análise da playlist M3U8".
|
8
|
+
errors (list, optional): Lista de erros adicionais ou detalhes para diagnóstico. Padrão é None.
|
9
|
+
"""
|
10
|
+
super().__init__(message)
|
11
|
+
self.errors = errors
|
12
|
+
|
13
|
+
def __str__(self):
|
14
|
+
"""
|
15
|
+
Retorna a representação em string da exceção.
|
16
|
+
|
17
|
+
Returns:
|
18
|
+
str: Mensagem de erro formatada com detalhes adicionais, se presentes.
|
19
|
+
"""
|
20
|
+
if self.errors:
|
21
|
+
return f"{super().__str__()} | Erros adicionais: {self.errors}"
|
22
|
+
return super().__str__()
|
23
|
+
|
24
|
+
|
25
|
+
class M3u8DownloadError(M3u8AnalyzerExceptions):
|
26
|
+
def __init__(self, message="Erro durante o download da playlist M3U8", errors=None):
|
27
|
+
"""
|
28
|
+
Exceção para erros específicos ocorridos durante o download de uma playlist M3U8.
|
29
|
+
|
30
|
+
Args:
|
31
|
+
message (str): Mensagem descritiva do erro. Padrão é "Erro durante o download da playlist M3U8".
|
32
|
+
errors (list, optional): Lista de erros adicionais ou detalhes para diagnóstico. Padrão é None.
|
33
|
+
"""
|
34
|
+
super().__init__(message, errors)
|
35
|
+
|
36
|
+
|
37
|
+
class M3u8FfmpegDownloadError(M3u8AnalyzerExceptions):
|
38
|
+
def __init__(self, message="Erro durante o download da playlist M3U8 com ffmpeg", errors=None):
|
39
|
+
"""
|
40
|
+
Exceção para erros específicos ocorridos durante o download de uma playlist M3U8 usando ffmpeg.
|
41
|
+
|
42
|
+
Args:
|
43
|
+
message (str): Mensagem descritiva do erro. Padrão é "Erro durante o download da playlist M3U8 com ffmpeg".
|
44
|
+
errors (list, optional): Lista de erros adicionais ou detalhes para diagnóstico. Padrão é None.
|
45
|
+
"""
|
46
|
+
super().__init__(message, errors)
|
47
|
+
|
48
|
+
|
49
|
+
class M3u8NetworkingError(M3u8AnalyzerExceptions):
|
50
|
+
def __init__(self, message="Erro de rede durante o download da playlist M3U8", errors=None):
|
51
|
+
"""
|
52
|
+
Exceção para erros relacionados à rede durante o download de uma playlist M3U8.
|
53
|
+
|
54
|
+
Args:
|
55
|
+
message (str): Mensagem descritiva do erro. Padrão é "Erro de rede durante o download da playlist M3U8".
|
56
|
+
errors (list, optional): Lista de erros adicionais ou detalhes para diagnóstico. Padrão é None.
|
57
|
+
"""
|
58
|
+
super().__init__(message, errors)
|
59
|
+
|
60
|
+
|
61
|
+
class M3u8Error(M3u8AnalyzerExceptions):
|
62
|
+
def __init__(self, message="Erro inesperado na análise de playlist M3U8", errors=None):
|
63
|
+
"""
|
64
|
+
Exceção para erros inesperados que não se encaixam em outras categorias.
|
65
|
+
|
66
|
+
Args:
|
67
|
+
message (str): Mensagem descritiva do erro. Padrão é "Erro inesperado na análise de playlist M3U8".
|
68
|
+
errors (list, optional): Lista de erros adicionais ou detalhes para diagnóstico. Padrão é None.
|
69
|
+
"""
|
70
|
+
super().__init__(message, errors)
|
71
|
+
|
72
|
+
|
73
|
+
class M3u8FileError(M3u8AnalyzerExceptions):
|
74
|
+
def __init__(self, message="Erro ao manipular o arquivo da playlist M3U8", errors=None):
|
75
|
+
"""
|
76
|
+
Exceção para erros ocorridos ao manipular arquivos relacionados a playlists M3U8.
|
77
|
+
|
78
|
+
Args:
|
79
|
+
message (str): Mensagem descritiva do erro. Padrão é "Erro ao manipular o arquivo da playlist M3U8".
|
80
|
+
errors (list, optional): Lista de erros adicionais ou detalhes para diagnóstico. Padrão é None.
|
81
|
+
"""
|
82
|
+
super().__init__(message, errors)
|
udemy_userAPI/__version__.py
CHANGED
udemy_userAPI/api.py
CHANGED
@@ -186,53 +186,75 @@ def get_mpd_file(mpd_url):
|
|
186
186
|
|
187
187
|
|
188
188
|
def parser_chapters(results) -> list[dict]:
|
189
|
+
"""
|
190
|
+
Processa os dados do curso e retorna uma lista de capítulos com suas aulas e quizzes.
|
191
|
+
|
192
|
+
Se os resultados não contiverem capítulos (i.e. apenas aulas ou quizzes), todas as
|
193
|
+
aulas/quizzes serão agrupadas em um capítulo padrão.
|
194
|
+
|
195
|
+
Args:
|
196
|
+
results (dict): Dicionário com os resultados do curso, normalmente contendo a chave 'results'.
|
197
|
+
|
198
|
+
Returns:
|
199
|
+
list[dict]: Lista de capítulos, cada um com título, índice (se disponível) e lista de lectures/quizzes.
|
200
|
+
|
201
|
+
Raises:
|
202
|
+
UdemyUserApiExceptions: Se não for possível obter os detalhes do curso.
|
203
|
+
"""
|
189
204
|
if not results:
|
190
205
|
raise UdemyUserApiExceptions("Não foi possível obter detalhes do curso!")
|
191
206
|
|
192
|
-
|
193
|
-
chapters_dicts = [] # Lista
|
207
|
+
items = results.get('results', [])
|
208
|
+
chapters_dicts = [] # Lista de capítulos
|
194
209
|
current_chapter = None # Capítulo atual
|
195
210
|
|
196
|
-
|
211
|
+
# Nome padrão para o grupo quando não houver capítulos
|
212
|
+
default_chapter_title = "CourseFiles"
|
213
|
+
|
214
|
+
for dictionary in items:
|
197
215
|
_class = dictionary.get('_class')
|
198
|
-
chapter_index = dictionary.get('object_index')
|
216
|
+
chapter_index = dictionary.get('object_index', None)
|
199
217
|
|
200
|
-
# Quando encontrar um novo capítulo
|
201
218
|
if _class == 'chapter':
|
202
|
-
|
219
|
+
# Se já há um capítulo em andamento, adiciona-o à lista
|
220
|
+
if current_chapter:
|
203
221
|
chapters_dicts.append(current_chapter)
|
204
|
-
|
205
222
|
# Inicia um novo capítulo
|
206
223
|
current_chapter = {
|
207
|
-
'title': dictionary.get('title'),
|
224
|
+
'title': dictionary.get('title', 'Sem Título'),
|
208
225
|
'chapter_index': chapter_index,
|
209
226
|
'lectures': [] # Lista para armazenar aulas e quizzes
|
210
227
|
}
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
'
|
218
|
-
|
228
|
+
elif _class in ('lecture', 'quiz'):
|
229
|
+
# Se não houver um capítulo atual, cria um capítulo padrão
|
230
|
+
if current_chapter is None:
|
231
|
+
current_chapter = {
|
232
|
+
'title': default_chapter_title,
|
233
|
+
'chapter_index': None,
|
234
|
+
'lectures': []
|
235
|
+
}
|
236
|
+
# Processa a aula ou quiz
|
237
|
+
if _class == 'lecture':
|
238
|
+
asset = dictionary.get('asset')
|
239
|
+
if asset:
|
240
|
+
lecture_data = {
|
241
|
+
'asset_type': asset.get('asset_type', ''),
|
242
|
+
'title': dictionary.get('title', 'Aula'),
|
243
|
+
'lecture_id': dictionary.get('id', ''),
|
244
|
+
'asset_id': asset.get('id', '')
|
245
|
+
}
|
246
|
+
current_chapter['lectures'].append(lecture_data)
|
247
|
+
elif _class == 'quiz':
|
248
|
+
quiz_data = {
|
249
|
+
'asset_type': 'quiz',
|
250
|
+
'title': dictionary.get('title', 'Quiz'),
|
219
251
|
'lecture_id': dictionary.get('id', ''),
|
220
|
-
'
|
252
|
+
'type': dictionary.get('type', ''),
|
253
|
+
'asset_id': ''
|
221
254
|
}
|
222
|
-
current_chapter['lectures'].append(
|
223
|
-
|
224
|
-
# Se for um quiz, também adiciona ao capítulo atual
|
225
|
-
elif _class == 'quiz' and current_chapter:
|
226
|
-
quiz_data = {
|
227
|
-
'asset_type': 'quiz',
|
228
|
-
'title': dictionary.get('title', 'Quiz'),
|
229
|
-
'lecture_id': dictionary.get('id', ''),
|
230
|
-
'type': dictionary.get('type', ''),
|
231
|
-
'asset_id': ''
|
232
|
-
}
|
233
|
-
current_chapter['lectures'].append(quiz_data)
|
255
|
+
current_chapter['lectures'].append(quiz_data)
|
234
256
|
|
235
|
-
#
|
257
|
+
# Se houver um capítulo em andamento, adiciona-o à lista
|
236
258
|
if current_chapter:
|
237
259
|
chapters_dicts.append(current_chapter)
|
238
260
|
|
udemy_userAPI/bultins.py
CHANGED
@@ -162,115 +162,6 @@ class Quiz:
|
|
162
162
|
htmls = get_quizzes(lecture_id=self.id)
|
163
163
|
return htmls
|
164
164
|
|
165
|
-
|
166
|
-
class Caption:
|
167
|
-
"""Representa uma legenda."""
|
168
|
-
|
169
|
-
def __init__(self, caption: dict):
|
170
|
-
"""
|
171
|
-
Inicializa uma instância de Caption.
|
172
|
-
|
173
|
-
Args:
|
174
|
-
caption (dict): Dados da legenda.
|
175
|
-
"""
|
176
|
-
self._caption = caption
|
177
|
-
|
178
|
-
@property
|
179
|
-
def locale(self) -> str:
|
180
|
-
"""Retorna o idioma."""
|
181
|
-
return self._caption.get('video_label', '')
|
182
|
-
|
183
|
-
@property
|
184
|
-
def status(self) -> str:
|
185
|
-
"""Retorna o status da legenda 1 ou 0"""
|
186
|
-
return self._caption.get('status')
|
187
|
-
|
188
|
-
@property
|
189
|
-
def title(self) -> str:
|
190
|
-
"""Retorna o título da legenda."""
|
191
|
-
return self._caption.get('title', '')
|
192
|
-
|
193
|
-
@property
|
194
|
-
def created(self) -> str:
|
195
|
-
"""Retorna a data de criação da legenda."""
|
196
|
-
return self._caption.get('created', '')
|
197
|
-
|
198
|
-
@property
|
199
|
-
def id(self) -> int:
|
200
|
-
"""Retorna o ID da legenda."""
|
201
|
-
return self._caption.get('id', 0)
|
202
|
-
|
203
|
-
@property
|
204
|
-
def url(self) -> str:
|
205
|
-
"""Retorna a URL da legenda."""
|
206
|
-
return self._caption.get('url', '')
|
207
|
-
|
208
|
-
@property
|
209
|
-
def content(self) -> str:
|
210
|
-
"""Obtém o conteúdo da legenda."""
|
211
|
-
if self.url:
|
212
|
-
r = requests.get(headers=HEADERS_USER, url=self.url)
|
213
|
-
if r.status_code == 200:
|
214
|
-
return r.text
|
215
|
-
else:
|
216
|
-
raise ConnectionError(
|
217
|
-
f'status_code: {r.status_code}, Não foi possível obter o conteúdo da legenda!'
|
218
|
-
)
|
219
|
-
else:
|
220
|
-
raise FileNotFoundError(
|
221
|
-
'Não foi possível obter a URL da legenda!'
|
222
|
-
)
|
223
|
-
|
224
|
-
class Captions:
|
225
|
-
"""Gerencia as legendas de um vídeo."""
|
226
|
-
|
227
|
-
def __init__(self, caption_data: list):
|
228
|
-
"""
|
229
|
-
Inicializa uma instância de Captions.
|
230
|
-
|
231
|
-
Args:
|
232
|
-
caption_data (list): Dados das legendas.
|
233
|
-
"""
|
234
|
-
self._caption_data = caption_data
|
235
|
-
|
236
|
-
def languages(self) -> list[dict]:
|
237
|
-
"""Retorna a lista de idiomas disponíveis na aula."""
|
238
|
-
langs = []
|
239
|
-
for caption in self._caption_data:
|
240
|
-
locale_id = caption.get('locale_id', '')
|
241
|
-
video_label = caption.get('video_label','')
|
242
|
-
if locale_id:
|
243
|
-
langs.append({'locale_id': locale_id,'locale':video_label})
|
244
|
-
return langs
|
245
|
-
|
246
|
-
def get_lang(self, locale_id: str) -> Caption:
|
247
|
-
"""
|
248
|
-
Obtém a legenda para o idioma especificado.
|
249
|
-
|
250
|
-
|
251
|
-
Args:
|
252
|
-
locale_id (str): ID do idioma,pode ser obtido no método -> 'languages'
|
253
|
-
|
254
|
-
Returns:
|
255
|
-
Caption: Objeto Caption.
|
256
|
-
|
257
|
-
Raises:
|
258
|
-
FileNotFoundError: Se o idioma não estiver disponível na aula.
|
259
|
-
"""
|
260
|
-
is_t = False
|
261
|
-
cpt = {}
|
262
|
-
for caption in self._caption_data:
|
263
|
-
if locale_id == caption.get('locale_id'):
|
264
|
-
is_t = True
|
265
|
-
cpt = caption
|
266
|
-
if not is_t:
|
267
|
-
raise FileNotFoundError(
|
268
|
-
'Esse idioma não está disponível nessa aula!'
|
269
|
-
)
|
270
|
-
c = Caption(caption=cpt)
|
271
|
-
return c
|
272
|
-
|
273
|
-
|
274
165
|
class Lecture:
|
275
166
|
"""Cria objetos aula (lecture) do curso e extrai os dados."""
|
276
167
|
|
@@ -353,20 +244,15 @@ class Lecture:
|
|
353
244
|
return self.__asset.get('media_sources',[])
|
354
245
|
|
355
246
|
@property
|
356
|
-
def get_captions(self) ->
|
247
|
+
def get_captions(self) -> list:
|
357
248
|
"""
|
358
249
|
Obtém as legendas.
|
359
250
|
|
360
251
|
Returns:
|
361
|
-
|
252
|
+
list: Uma lista contendo as legendas.
|
362
253
|
"""
|
363
|
-
|
364
|
-
|
365
|
-
return c
|
366
|
-
else:
|
367
|
-
raise FileNotFoundError(
|
368
|
-
'Não foi encontrada legendas nessa aula!'
|
369
|
-
)
|
254
|
+
return self.__asset.get('captions',[])
|
255
|
+
|
370
256
|
@property
|
371
257
|
def get_external_url(self) -> list:
|
372
258
|
"""
|
@@ -602,12 +488,12 @@ class Course:
|
|
602
488
|
'title': video.get('title', ''),
|
603
489
|
'lecture_id': video.get('lecture_id', ''),
|
604
490
|
'asset_id': video.get('asset_id', ''),
|
605
|
-
'asset_type': video.get('asset_type', '')
|
491
|
+
'asset_type': video.get('asset_type', ''),
|
492
|
+
'section_order': chapter.get('chapter_index',1)
|
606
493
|
}
|
607
494
|
videos.append(dt)
|
608
495
|
|
609
496
|
return videos
|
610
|
-
|
611
497
|
def get_details_lecture(self, lecture_id: int) -> Lecture:
|
612
498
|
"""
|
613
499
|
Obtém detalhes de uma aula específica.
|
udemy_userAPI/sections.py
CHANGED
@@ -53,13 +53,13 @@ def get_courses_plan(tipe: str) -> list:
|
|
53
53
|
|
54
54
|
def get_details_courses(course_id):
|
55
55
|
"""
|
56
|
-
Obtém detalhes de um curso específico.
|
56
|
+
Obtém detalhes de um curso específico, realizando paginação caso haja múltiplas páginas.
|
57
57
|
|
58
58
|
Args:
|
59
59
|
course_id (int): ID do curso.
|
60
60
|
|
61
61
|
Returns:
|
62
|
-
dict: Dicionário contendo os detalhes do curso.
|
62
|
+
dict: Dicionário contendo os detalhes do curso com todos os itens concatenados.
|
63
63
|
|
64
64
|
Raises:
|
65
65
|
LoginException: Se a sessão estiver expirada.
|
@@ -70,22 +70,47 @@ def get_details_courses(course_id):
|
|
70
70
|
auth = UdemyAuth()
|
71
71
|
if not auth.verif_login():
|
72
72
|
raise LoginException("Sessão expirada!")
|
73
|
-
|
73
|
+
|
74
|
+
# URL base com parâmetros
|
75
|
+
base_url = (
|
74
76
|
f"https://www.udemy.com/api-2.0/courses/{course_id}/subscriber-curriculum-items/?"
|
75
|
-
f"
|
76
|
-
f"
|
77
|
-
f"
|
78
|
-
f"
|
79
|
-
f"
|
80
|
-
f"
|
81
|
-
f"
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
77
|
+
f"page_size=1000&"
|
78
|
+
f"fields[lecture]=title,object_index,is_published,sort_order,created,asset,supplementary_assets,is_free&"
|
79
|
+
f"fields[quiz]=title,object_index,is_published,sort_order,type&"
|
80
|
+
f"fields[practice]=title,object_index,is_published,sort_order&"
|
81
|
+
f"fields[chapter]=title,object_index,is_published,sort_order&"
|
82
|
+
f"fields[asset]=title,filename,asset_type,status,time_estimation,is_external&"
|
83
|
+
f"caching_intent=True"
|
84
|
+
)
|
85
|
+
|
86
|
+
try:
|
87
|
+
response = requests.get(base_url, headers=HEADERS_USER)
|
88
|
+
if response.status_code != 200:
|
89
|
+
raise UdemyUserApiExceptions(
|
90
|
+
f"Erro ao obter detalhes do curso! Código de status: {response.status_code}")
|
91
|
+
|
92
|
+
data = json.loads(response.text)
|
93
|
+
all_results = data.get('results', [])
|
94
|
+
next_page = data.get('next', '')
|
95
|
+
|
96
|
+
# Enquanto houver próxima página, faz requisição e junta os resultados
|
97
|
+
while next_page:
|
98
|
+
response = requests.get(next_page, headers=HEADERS_USER)
|
99
|
+
if response.status_code != 200:
|
100
|
+
# Caso ocorra erro na próxima página, pode-se optar por interromper ou registrar o erro.....por enquanto
|
101
|
+
# irei parar..mais se por acaso futuramente não der certo mudarei esta implementação!
|
102
|
+
# @pauloCesarDev404
|
103
|
+
break
|
104
|
+
next_data = json.loads(response.text)
|
105
|
+
all_results.extend(next_data.get('results', []))
|
106
|
+
next_page = next_data.get('next', '')
|
107
|
+
|
108
|
+
# Atualiza o dicionário final com todos os itens concatenados
|
109
|
+
data['results'] = all_results
|
110
|
+
return data
|
111
|
+
|
112
|
+
except Exception as e:
|
113
|
+
raise UdemyUserApiExceptions(f"Erro ao obter detalhes do curso! {e}")
|
89
114
|
|
90
115
|
|
91
116
|
def get_course_infor(course_id):
|
udemy_userAPI/udemy.py
CHANGED
@@ -19,6 +19,9 @@ class Udemy:
|
|
19
19
|
LoginException: Se a sessão estiver expirada.
|
20
20
|
"""
|
21
21
|
self.__headers = HEADERS_USER
|
22
|
+
if not verif_login:
|
23
|
+
raise LoginException("Sessão expirada!")
|
24
|
+
|
22
25
|
@staticmethod
|
23
26
|
def my_subscribed_courses_by_plan() -> list[dict]:
|
24
27
|
"""
|
@@ -30,10 +33,6 @@ class Udemy:
|
|
30
33
|
Raises:
|
31
34
|
UdemyUserApiExceptions: Se houver erro ao obter os cursos.
|
32
35
|
"""
|
33
|
-
if not verif_login:
|
34
|
-
raise LoginException(
|
35
|
-
"Nenhuma sessão ativa,primeiro efetue login!")
|
36
|
-
|
37
36
|
try:
|
38
37
|
courses = get_courses_plan(tipe='plan')
|
39
38
|
return courses
|
@@ -51,10 +50,6 @@ class Udemy:
|
|
51
50
|
Raises:
|
52
51
|
UdemyUserApiExceptions: Se houver erro ao obter os cursos.
|
53
52
|
"""
|
54
|
-
if not verif_login:
|
55
|
-
raise LoginException(
|
56
|
-
"Nenhuma sessão ativa,primeiro efetue login!")
|
57
|
-
|
58
53
|
try:
|
59
54
|
# Obtém os cursos
|
60
55
|
courses1 = get_courses_plan(tipe='default') # lista de cursos padrão
|
@@ -77,7 +72,7 @@ class Udemy:
|
|
77
72
|
raise UnhandledExceptions(e)
|
78
73
|
|
79
74
|
@staticmethod
|
80
|
-
def get_details_course(course_id)
|
75
|
+
def get_details_course(course_id):
|
81
76
|
"""
|
82
77
|
Obtém detalhes de um curso através do ID.
|
83
78
|
|
@@ -90,10 +85,6 @@ class Udemy:
|
|
90
85
|
Raises:
|
91
86
|
UnhandledExceptions: Se houver erro ao obter os detalhes do curso.
|
92
87
|
"""
|
93
|
-
if not verif_login:
|
94
|
-
raise LoginException(
|
95
|
-
"Nenhuma sessão ativa,primeiro efetue login!")
|
96
|
-
|
97
88
|
try:
|
98
89
|
d = get_details_courses(course_id)
|
99
90
|
b = Course(course_id=course_id, results=d)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: udemy_userAPI
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.9
|
4
4
|
Summary: Obtenha detalhes de cursos que o usuário esteja inscrito da plataforma Udemy,usando o EndPoint de usuário o mesmo que o navegador utiliza para acessar e redenrizar os cursos.
|
5
5
|
Author: PauloCesar-dev404
|
6
6
|
Author-email: paulocesar0073dev404@gmail.com
|
@@ -29,7 +29,7 @@ Dynamic: summary
|
|
29
29
|
# udemy-userAPI
|
30
30
|
|
31
31
|
|
32
|
-

|
33
33
|

|
34
34
|
[](https://paulocesar-dev404.github.io/me-apoiando-online/)
|
35
35
|
[](https://github.com/PauloCesar-dev404/udemy-userAPI/blob/main/docs/iniciando.md)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
animation_consoles/__init__.py,sha256=5uHhe-PVZ54FHWxbF1sNvNt4fuQf3FtZWVo2Mjo11a8,40
|
2
|
+
animation_consoles/animation.py,sha256=ZreNtdD0HYeqlRx-f1d1twUU4sOFTR7vJ3S6tMQpnHM,2122
|
3
|
+
ffmpeg_for_python/__config__.py,sha256=nCPrYs1NkMnyfyg5ITw9wOar4nUJOxwONrItVpVBVBM,4719
|
4
|
+
ffmpeg_for_python/__init__.py,sha256=-BMtoX8Yof_pnHra2OzoV3faxMubpMvUedMy8TqI8dc,214
|
5
|
+
ffmpeg_for_python/__utils.py,sha256=Qy3J5f4lOIPcSNbTwiawfiHjYPdZ_tq7hafStnnqwA4,3263
|
6
|
+
ffmpeg_for_python/__version__.py,sha256=HLFuN4n_leeJE5twr7yH2AAFyfIcEHzxElLRP1FUKmQ,422
|
7
|
+
ffmpeg_for_python/exeptions.py,sha256=tg-TBdaq_NHxZOCAhkMttzwtJVILPAQPLOKqofe5PPA,3627
|
8
|
+
ffmpeg_for_python/ffmpeg.py,sha256=G2VGHOIhErsqQI4OVlUnIQGmleNCjxyFqzNAMNnoD6I,7920
|
9
|
+
m3u8_analyzer/M3u8Analyzer.py,sha256=aUgxk2jS84MFDNbjlOT8FRiJerFI_jGcKMu9uv1EwcE,36620
|
10
|
+
m3u8_analyzer/__init__.py,sha256=v7CiVqsCq2YH347C-QR1kHPJtXFFdru8qole3E9adCY,217
|
11
|
+
m3u8_analyzer/__version__.py,sha256=YP3yT87ZKrU3eARUUdQ_pg4xAXLGfBXjH4ZgEoZSq1I,25
|
12
|
+
m3u8_analyzer/exeptions.py,sha256=fK6bU3YxNSbfsPmCp4yudUvmwy_g6dj2KwIkH0dW4LI,3672
|
13
|
+
udemy_userAPI/__init__.py,sha256=BPle89xE_CMTKKe_Lw6jioYLgpH-q_Lpho2S-n1PIUA,206
|
14
|
+
udemy_userAPI/__version__.py,sha256=a4LPtetqz-q5GvaAHS-Fgh8_av6e5cuiWN30jTnHd2w,405
|
15
|
+
udemy_userAPI/api.py,sha256=GVvbbs3vFN-rF-qLBwiuHz77sjehwk8HjAI-Dey_A6c,29167
|
16
|
+
udemy_userAPI/authenticate.py,sha256=IJRrCjmhe_x40CrQ2KrOMNP8VvotZf0QMWsrbcLl_rw,14225
|
17
|
+
udemy_userAPI/bultins.py,sha256=8L3FuEE09ySPLVUdyuy2EC7uXppDzr0KpSrNeG5AhRo,18629
|
18
|
+
udemy_userAPI/exeptions.py,sha256=kfnPdZpqYY8nd0gnl6_Vh-MIz-XupmmbRPIuFnyXupk,692
|
19
|
+
udemy_userAPI/sections.py,sha256=Q1PlVt2Bu5MSEP8g11-F_gilJDdhZq50TV1Bo400jcA,6389
|
20
|
+
udemy_userAPI/udemy.py,sha256=SpK0LI4hjO45nZDz5waw-Py-d0uulBb28TVjltyWBxM,2920
|
21
|
+
udemy_userAPI/.cache/.udemy_userAPI,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
+
udemy_userAPI/mpd_analyzer/__init__.py,sha256=i3JVWyvcFLaj5kPmx8c1PgjsLht7OUIQQClD4yqYbo8,102
|
23
|
+
udemy_userAPI/mpd_analyzer/bin.wvd,sha256=1rAJdCc120hQlX9qe5KUS628eY2ZHYxQSmyhGNefSzo,2956
|
24
|
+
udemy_userAPI/mpd_analyzer/mpd_parser.py,sha256=PgUkHc5x8FTuXFCuYkWPZr9TaO_nsKalb02EFYl_zeA,8926
|
25
|
+
udemy_userAPI-0.3.9.dist-info/LICENSE,sha256=l4jdKYt8gSdDFOGr09vCKnMn_Im55XIcQKqTDEtFfNs,1095
|
26
|
+
udemy_userAPI-0.3.9.dist-info/METADATA,sha256=MvhxygbgYvdBfmsoxVq_wssccc3Ph-MN1T0ArNj-MB4,1655
|
27
|
+
udemy_userAPI-0.3.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
28
|
+
udemy_userAPI-0.3.9.dist-info/top_level.txt,sha256=ijTINaSDRKhdahY_X7dmSRFTxBIwQErWv9ATCG55mog,14
|
29
|
+
udemy_userAPI-0.3.9.dist-info/RECORD,,
|
@@ -1,17 +0,0 @@
|
|
1
|
-
udemy_userAPI/__init__.py,sha256=BPle89xE_CMTKKe_Lw6jioYLgpH-q_Lpho2S-n1PIUA,206
|
2
|
-
udemy_userAPI/__version__.py,sha256=ZlJ4BqU7L0jruy2h0iTeuMxcPub8qGB7jbO8vbwvXbY,405
|
3
|
-
udemy_userAPI/api.py,sha256=jWWwJBYS9dJDjlozUj4Yi4uc8OCAy5PILqUiRWZMiq8,28153
|
4
|
-
udemy_userAPI/authenticate.py,sha256=IJRrCjmhe_x40CrQ2KrOMNP8VvotZf0QMWsrbcLl_rw,14225
|
5
|
-
udemy_userAPI/bultins.py,sha256=s12tXjbZgyKAnYrEtZxUzuTY-aIINXlm4mpbxR-r4Io,21932
|
6
|
-
udemy_userAPI/exeptions.py,sha256=kfnPdZpqYY8nd0gnl6_Vh-MIz-XupmmbRPIuFnyXupk,692
|
7
|
-
udemy_userAPI/sections.py,sha256=eRjUUlEApwrwlcCs9GWIk580qq1UVFqR5RmOgP6y65E,5424
|
8
|
-
udemy_userAPI/udemy.py,sha256=AAXc24iAtFTyDyVehhFeSx9CyhWMeFWsbYn1J80TgFw,3270
|
9
|
-
udemy_userAPI/.cache/.udemy_userAPI,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
-
udemy_userAPI/mpd_analyzer/__init__.py,sha256=i3JVWyvcFLaj5kPmx8c1PgjsLht7OUIQQClD4yqYbo8,102
|
11
|
-
udemy_userAPI/mpd_analyzer/bin.wvd,sha256=1rAJdCc120hQlX9qe5KUS628eY2ZHYxQSmyhGNefSzo,2956
|
12
|
-
udemy_userAPI/mpd_analyzer/mpd_parser.py,sha256=PgUkHc5x8FTuXFCuYkWPZr9TaO_nsKalb02EFYl_zeA,8926
|
13
|
-
udemy_userAPI-0.3.7.dist-info/LICENSE,sha256=l4jdKYt8gSdDFOGr09vCKnMn_Im55XIcQKqTDEtFfNs,1095
|
14
|
-
udemy_userAPI-0.3.7.dist-info/METADATA,sha256=B5tTj-p8_9DEWwgarUotK9gTteg6teb_R5oeLg7HznQ,1655
|
15
|
-
udemy_userAPI-0.3.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
16
|
-
udemy_userAPI-0.3.7.dist-info/top_level.txt,sha256=ijTINaSDRKhdahY_X7dmSRFTxBIwQErWv9ATCG55mog,14
|
17
|
-
udemy_userAPI-0.3.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|