udemy-userAPI 0.3.5__py3-none-any.whl → 0.3.7__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- udemy_userAPI/__version__.py +1 -1
- udemy_userAPI/api.py +139 -39
- udemy_userAPI/authenticate.py +1 -1
- udemy_userAPI/bultins.py +243 -56
- udemy_userAPI/sections.py +2 -1
- udemy_userAPI/udemy.py +13 -4
- {udemy_userAPI-0.3.5.dist-info → udemy_userAPI-0.3.7.dist-info}/METADATA +13 -3
- udemy_userAPI-0.3.7.dist-info/RECORD +17 -0
- {udemy_userAPI-0.3.5.dist-info → udemy_userAPI-0.3.7.dist-info}/WHEEL +1 -1
- animation_consoles/__init__.py +0 -1
- animation_consoles/animation.py +0 -64
- ffmpeg_for_python/__config__.py +0 -118
- ffmpeg_for_python/__init__.py +0 -8
- ffmpeg_for_python/__utils.py +0 -78
- ffmpeg_for_python/__version__.py +0 -6
- ffmpeg_for_python/exeptions.py +0 -91
- ffmpeg_for_python/ffmpeg.py +0 -203
- m3u8_analyzer/M3u8Analyzer.py +0 -807
- m3u8_analyzer/__init__.py +0 -7
- m3u8_analyzer/__version__.py +0 -1
- m3u8_analyzer/exeptions.py +0 -82
- udemy_userAPI-0.3.5.dist-info/RECORD +0 -29
- {udemy_userAPI-0.3.5.dist-info → udemy_userAPI-0.3.7.dist-info}/LICENSE +0 -0
- {udemy_userAPI-0.3.5.dist-info → udemy_userAPI-0.3.7.dist-info}/top_level.txt +0 -0
udemy_userAPI/__version__.py
CHANGED
udemy_userAPI/api.py
CHANGED
@@ -134,7 +134,8 @@ def extract(pssh, license_token):
|
|
134
134
|
from .authenticate import UdemyAuth
|
135
135
|
auth = UdemyAuth()
|
136
136
|
if not auth.verif_login():
|
137
|
-
raise LoginException(
|
137
|
+
raise LoginException(
|
138
|
+
"Sessão expirada!")
|
138
139
|
license_url = (f"https://www.udemy.com/api-2.0/media-license-server/validate-auth-token?drm_type=widevine"
|
139
140
|
f"&auth_token={license_token}")
|
140
141
|
session_id = cdm.open()
|
@@ -184,43 +185,58 @@ def get_mpd_file(mpd_url):
|
|
184
185
|
raise UnhandledExceptions(f"Errro Ao Obter Mídias:{e}")
|
185
186
|
|
186
187
|
|
187
|
-
def
|
188
|
-
"""
|
189
|
-
:param results:
|
190
|
-
:return:
|
191
|
-
"""
|
192
|
-
if not results:
|
193
|
-
raise UdemyUserApiExceptions("Não foi possível obter detalhes do curso!")
|
194
|
-
results = results.get('results', None)
|
188
|
+
def parser_chapters(results) -> list[dict]:
|
195
189
|
if not results:
|
196
190
|
raise UdemyUserApiExceptions("Não foi possível obter detalhes do curso!")
|
197
|
-
chapters_dict = {} # Dicionário para armazenar os capítulos e seus vídeos correspondentes
|
198
191
|
|
199
|
-
|
200
|
-
|
192
|
+
results = results.get('results', [])
|
193
|
+
chapters_dicts = [] # Lista que armazena todos os capítulos
|
194
|
+
current_chapter = None # Capítulo atual
|
195
|
+
|
201
196
|
for dictionary in results:
|
202
197
|
_class = dictionary.get('_class')
|
198
|
+
chapter_index = dictionary.get('object_index')
|
203
199
|
|
200
|
+
# Quando encontrar um novo capítulo
|
204
201
|
if _class == 'chapter':
|
205
|
-
|
202
|
+
if current_chapter: # Se já há um capítulo atual, adicionamos
|
203
|
+
chapters_dicts.append(current_chapter)
|
204
|
+
|
205
|
+
# Inicia um novo capítulo
|
206
206
|
current_chapter = {
|
207
|
-
'
|
208
|
-
'
|
207
|
+
'title': dictionary.get('title'),
|
208
|
+
'chapter_index': chapter_index,
|
209
|
+
'lectures': [] # Lista para armazenar aulas e quizzes
|
209
210
|
}
|
210
|
-
|
211
|
-
|
211
|
+
|
212
|
+
# Se for uma aula, adiciona ao capítulo atual
|
213
|
+
elif _class == 'lecture' and current_chapter:
|
212
214
|
asset = dictionary.get('asset')
|
213
215
|
if asset:
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
'
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
216
|
+
lecture_data = {
|
217
|
+
'asset_type': asset.get('asset_type', ''),
|
218
|
+
'title': dictionary.get('title', 'Files'),
|
219
|
+
'lecture_id': dictionary.get('id', ''),
|
220
|
+
'asset_id': asset.get('id', '')
|
221
|
+
}
|
222
|
+
current_chapter['lectures'].append(lecture_data)
|
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)
|
234
|
+
|
235
|
+
# Adiciona o último capítulo processado
|
236
|
+
if current_chapter:
|
237
|
+
chapters_dicts.append(current_chapter)
|
238
|
+
|
239
|
+
return chapters_dicts
|
224
240
|
|
225
241
|
|
226
242
|
def get_add_files(course_id: int):
|
@@ -304,11 +320,11 @@ def get_links(course_id: int, id_lecture: int):
|
|
304
320
|
erro ao obter dados das aulas.
|
305
321
|
"""
|
306
322
|
get = (f"https://www.udemy.com/api-2.0/users/me/subscribed-courses/{course_id}/lectures/{id_lecture}/?"
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
323
|
+
f"fields[lecture]"
|
324
|
+
f"=asset,description,download_url,is_free,last_watched_second&fields[asset]=asset_type,length,"
|
325
|
+
f"media_license_token,course_is_drmed,media_sources,captions,thumbnail_sprite,slides,slide_urls,"
|
326
|
+
f"download_urls,"
|
327
|
+
f"external_url&q=0.3108014137011559/?fields[asset]=download_urls")
|
312
328
|
from .authenticate import UdemyAuth
|
313
329
|
auth = UdemyAuth()
|
314
330
|
if not auth.verif_login():
|
@@ -322,18 +338,96 @@ def get_links(course_id: int, id_lecture: int):
|
|
322
338
|
a = json.loads(response.text)
|
323
339
|
return a
|
324
340
|
else:
|
325
|
-
raise UnhandledExceptions(
|
341
|
+
raise UnhandledExceptions(
|
342
|
+
f"Erro ao obter dados da aula! Código de status: {response.status_code}")
|
326
343
|
|
327
344
|
except requests.ConnectionError as e:
|
328
|
-
raise UdemyUserApiExceptions(
|
345
|
+
raise UdemyUserApiExceptions(
|
346
|
+
f"Erro de conexão: {e}")
|
329
347
|
except requests.Timeout as e:
|
330
|
-
raise UdemyUserApiExceptions(
|
348
|
+
raise UdemyUserApiExceptions(
|
349
|
+
f"Tempo de requisição excedido: {e}")
|
331
350
|
except requests.TooManyRedirects as e:
|
332
|
-
raise UdemyUserApiExceptions(
|
351
|
+
raise UdemyUserApiExceptions(
|
352
|
+
f"Limite de redirecionamentos excedido: {e}")
|
333
353
|
except requests.HTTPError as e:
|
334
|
-
raise UdemyUserApiExceptions(
|
354
|
+
raise UdemyUserApiExceptions(
|
355
|
+
f"Erro HTTP: {e}")
|
335
356
|
except Exception as e:
|
336
|
-
raise UnhandledExceptions(
|
357
|
+
raise UnhandledExceptions(
|
358
|
+
f"Erro ao obter mídias: {e}")
|
359
|
+
|
360
|
+
def get_assessments(course_id: int,lecture_id:int):
|
361
|
+
get = (f'https://www.udemy.com/api-2.0/users/me/subscribed-courses/{course_id}/quizzes/{lecture_id}/?draft='
|
362
|
+
f'false&fields[quiz]=id,type,title,description,object_index,num_assessments,version,duration,'
|
363
|
+
f'is_draft,pass_percent,changelog')
|
364
|
+
from .authenticate import UdemyAuth
|
365
|
+
auth = UdemyAuth()
|
366
|
+
if not auth.verif_login():
|
367
|
+
raise LoginException("Sessão expirada!")
|
368
|
+
try:
|
369
|
+
# Faz a solicitação GET com os cabeçalhos
|
370
|
+
response = requests.get(get, headers=HEADERS_USER)
|
371
|
+
data = []
|
372
|
+
# Exibe o código de status
|
373
|
+
if response.status_code == 200:
|
374
|
+
a = json.loads(response.text)
|
375
|
+
return a
|
376
|
+
else:
|
377
|
+
raise ConnectionError(
|
378
|
+
f"Erro ao obter dados da aula! Código de status: {response.status_code}\n"
|
379
|
+
f"{response.text}"
|
380
|
+
)
|
381
|
+
|
382
|
+
except requests.ConnectionError as e:
|
383
|
+
raise UdemyUserApiExceptions(
|
384
|
+
f"Erro de conexão: {e}")
|
385
|
+
except requests.Timeout as e:
|
386
|
+
raise UdemyUserApiExceptions(
|
387
|
+
f"Tempo de requisição excedido: {e}")
|
388
|
+
except requests.TooManyRedirects as e:
|
389
|
+
raise UdemyUserApiExceptions(
|
390
|
+
f"Limite de redirecionamentos excedido: {e}")
|
391
|
+
except requests.HTTPError as e:
|
392
|
+
raise UdemyUserApiExceptions(
|
393
|
+
f"Erro HTTP: {e}")
|
394
|
+
|
395
|
+
|
396
|
+
def get_quizzes(lecture_id:int):
|
397
|
+
get = (f'https://www.udemy.com/api-2.0/quizzes/{lecture_id}/assessments/?version=1&page_size=1000&fields[assessment]'
|
398
|
+
f'=id,assessment_type,prompt,correct_response,section,question_plain,related_lectures&use_remote_version=true'
|
399
|
+
)
|
400
|
+
from .authenticate import UdemyAuth
|
401
|
+
auth = UdemyAuth()
|
402
|
+
if not auth.verif_login():
|
403
|
+
raise LoginException("Sessão expirada!")
|
404
|
+
try:
|
405
|
+
# Faz a solicitação GET com os cabeçalhos
|
406
|
+
response = requests.get(get, headers=HEADERS_USER)
|
407
|
+
data = []
|
408
|
+
# Exibe o código de status
|
409
|
+
if response.status_code == 200:
|
410
|
+
a = json.loads(response.text)
|
411
|
+
return a
|
412
|
+
else:
|
413
|
+
raise UnhandledExceptions(
|
414
|
+
f"Erro ao obter dados da aula! Código de status: {response.status_code}")
|
415
|
+
|
416
|
+
except requests.ConnectionError as e:
|
417
|
+
raise UdemyUserApiExceptions(
|
418
|
+
f"Erro de conexão: {e}")
|
419
|
+
except requests.Timeout as e:
|
420
|
+
raise UdemyUserApiExceptions(
|
421
|
+
f"Tempo de requisição excedido: {e}")
|
422
|
+
except requests.TooManyRedirects as e:
|
423
|
+
raise UdemyUserApiExceptions(
|
424
|
+
f"Limite de redirecionamentos excedido: {e}")
|
425
|
+
except requests.HTTPError as e:
|
426
|
+
raise UdemyUserApiExceptions(
|
427
|
+
f"Erro HTTP: {e}")
|
428
|
+
except Exception as e:
|
429
|
+
raise UnhandledExceptions(
|
430
|
+
f"Erro ao obter mídias: {e}")
|
337
431
|
|
338
432
|
|
339
433
|
def remove_tag(d: str):
|
@@ -607,6 +701,7 @@ def assets_infor(course_id: int, id_lecture: int, assets_id: int):
|
|
607
701
|
f"{r.text}")
|
608
702
|
|
609
703
|
|
704
|
+
|
610
705
|
def save_html(body, title_lecture):
|
611
706
|
html_content = f"""<!DOCTYPE html>
|
612
707
|
<html lang="en">
|
@@ -621,7 +716,6 @@ def save_html(body, title_lecture):
|
|
621
716
|
|
622
717
|
return html_content
|
623
718
|
|
624
|
-
|
625
719
|
def J(e, t):
|
626
720
|
"""
|
627
721
|
Gera um identificador único baseado na data atual e nas funções X e ee.
|
@@ -689,3 +783,9 @@ def te(e, t):
|
|
689
783
|
s = t[:r]
|
690
784
|
o = ''.join(format(byte, '08b') for byte in s)
|
691
785
|
return o.startswith('0' * e)
|
786
|
+
def is_lecture_in_course(lectures,lecture_id) -> bool:
|
787
|
+
# Verifica se o lecture_id está presente na lista de aulas
|
788
|
+
for lecture in lectures:
|
789
|
+
if lecture.get('lecture_id') == lecture_id:
|
790
|
+
return True
|
791
|
+
return False
|
udemy_userAPI/authenticate.py
CHANGED
@@ -105,7 +105,7 @@ class UdemyAuth:
|
|
105
105
|
except requests.HTTPError as e:
|
106
106
|
raise UdemyUserApiExceptions(f"Erro HTTP: {e}")
|
107
107
|
except Exception as e:
|
108
|
-
raise UnhandledExceptions(f"
|
108
|
+
raise UnhandledExceptions(f"{e}")
|
109
109
|
else:
|
110
110
|
return False
|
111
111
|
|