udemy-userAPI 0.3.6__tar.gz → 0.3.8__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {udemy_userapi-0.3.6/udemy_userAPI.egg-info → udemy_userapi-0.3.8}/PKG-INFO +2 -2
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/README.md +1 -1
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/README_PYPI.md +1 -1
- udemy_userapi-0.3.8/udemy_userAPI/.cache/.udemy_userAPI +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/__version__.py +1 -1
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/api.py +52 -30
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/bultins.py +3 -7
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/sections.py +42 -16
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8/udemy_userAPI.egg-info}/PKG-INFO +2 -2
- udemy_userapi-0.3.6/udemy_userAPI/.cache/.udemy_userAPI +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/LICENSE +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/MANIFEST.in +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/setup.cfg +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/setup.py +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/__init__.py +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/authenticate.py +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/exeptions.py +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/mpd_analyzer/__init__.py +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/mpd_analyzer/bin.wvd +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/mpd_analyzer/mpd_parser.py +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI/udemy.py +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI.egg-info/SOURCES.txt +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI.egg-info/dependency_links.txt +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI.egg-info/not-zip-safe +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI.egg-info/requires.txt +0 -0
- {udemy_userapi-0.3.6 → udemy_userapi-0.3.8}/udemy_userAPI.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: udemy_userAPI
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.8
|
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)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
|
5
5
|
|
6
|
-

|
7
7
|

|
8
8
|
[](https://paulocesar-dev404.github.io/me-apoiando-online/)
|
9
9
|
[](https://github.com/PauloCesar-dev404/udemy-userAPI/blob/main/docs/iniciando.md)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# udemy-userAPI
|
2
2
|
|
3
3
|
|
4
|
-

|
5
5
|

|
6
6
|
[](https://paulocesar-dev404.github.io/me-apoiando-online/)
|
7
7
|
[](https://github.com/PauloCesar-dev404/udemy-userAPI/blob/main/docs/iniciando.md)
|
Binary file
|
@@ -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
|
|
@@ -475,11 +475,7 @@ class Course:
|
|
475
475
|
@property
|
476
476
|
def get_lectures(self) -> list:
|
477
477
|
"""
|
478
|
-
Obtém uma lista com todas as aulas.
|
479
|
-
|
480
|
-
Args:
|
481
|
-
data (list): Lista de capítulos contendo as aulas.
|
482
|
-
|
478
|
+
Obtém uma lista de dicionários com todas as aulas.
|
483
479
|
Returns:
|
484
480
|
list: Uma lista contendo todas as aulas.
|
485
481
|
"""
|
@@ -492,12 +488,12 @@ class Course:
|
|
492
488
|
'title': video.get('title', ''),
|
493
489
|
'lecture_id': video.get('lecture_id', ''),
|
494
490
|
'asset_id': video.get('asset_id', ''),
|
495
|
-
'asset_type': video.get('asset_type', '')
|
491
|
+
'asset_type': video.get('asset_type', ''),
|
492
|
+
'section_order': chapter.get('chapter_index',1)
|
496
493
|
}
|
497
494
|
videos.append(dt)
|
498
495
|
|
499
496
|
return videos
|
500
|
-
|
501
497
|
def get_details_lecture(self, lecture_id: int) -> Lecture:
|
502
498
|
"""
|
503
499
|
Obtém detalhes de uma aula específica.
|
@@ -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,21 +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
|
-
|
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}")
|
88
114
|
|
89
115
|
|
90
116
|
def get_course_infor(course_id):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: udemy_userAPI
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.8
|
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)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|