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.
@@ -1,4 +1,4 @@
1
- __version__ = '0.3.5'
1
+ __version__ = '0.3.7'
2
2
  __lib_name__ = 'udemy_userAPI' # local name
3
3
  __repo_name__ = 'udemy-userAPI'
4
4
  __autor__ = 'PauloCesar-dev404'
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("Sessão expirada!")
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 parser_chapers(results):
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
- # Primeiro, construímos um dicionário de capítulos
200
- current_chapter = None
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
- chapter_index = dictionary.get('object_index')
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
- 'title_chapter': dictionary.get('title'),
208
- 'videos_in_chapter': []
207
+ 'title': dictionary.get('title'),
208
+ 'chapter_index': chapter_index,
209
+ 'lectures': [] # Lista para armazenar aulas e quizzes
209
210
  }
210
- chapters_dict[f"chapter_{chapter_index}"] = current_chapter
211
- elif _class == 'lecture' and current_chapter is not None:
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
- video_title = dictionary.get('title', None)
215
- if not video_title:
216
- video_title = 'Files'
217
- current_chapter['videos_in_chapter'].append({
218
- 'video_title': video_title,
219
- 'title_lecture': dictionary.get('title'),
220
- 'lecture_id': dictionary.get('id'),
221
- 'asset_id': asset.get('id')
222
- })
223
- return chapters_dict
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
- f"fields[lecture]"
308
- f"=asset,description,download_url,is_free,last_watched_second&fields[asset]=asset_type,length,"
309
- f"media_license_token,course_is_drmed,media_sources,captions,thumbnail_sprite,slides,slide_urls,"
310
- f"download_urls,"
311
- f"external_url&q=0.3108014137011559/?fields[asset]=download_urls")
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(f"Erro ao obter dados de aulas! Código de status: {response.status_code}")
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(f"Erro de conexão: {e}")
345
+ raise UdemyUserApiExceptions(
346
+ f"Erro de conexão: {e}")
329
347
  except requests.Timeout as e:
330
- raise UdemyUserApiExceptions(f"Tempo de requisição excedido: {e}")
348
+ raise UdemyUserApiExceptions(
349
+ f"Tempo de requisição excedido: {e}")
331
350
  except requests.TooManyRedirects as e:
332
- raise UdemyUserApiExceptions(f"Limite de redirecionamentos excedido: {e}")
351
+ raise UdemyUserApiExceptions(
352
+ f"Limite de redirecionamentos excedido: {e}")
333
353
  except requests.HTTPError as e:
334
- raise UdemyUserApiExceptions(f"Erro HTTP: {e}")
354
+ raise UdemyUserApiExceptions(
355
+ f"Erro HTTP: {e}")
335
356
  except Exception as e:
336
- raise UnhandledExceptions(f"Erro ao obter mídias: {e}")
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
@@ -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"Unhandled-ERROR: {e}")
108
+ raise UnhandledExceptions(f"{e}")
109
109
  else:
110
110
  return False
111
111