@mo7yw4ng/openape 1.0.2 → 1.0.4
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.
- package/README.md +37 -9
- package/esm/deno.js +1 -1
- package/esm/src/commands/announcements.d.ts.map +1 -1
- package/esm/src/commands/announcements.js +13 -14
- package/esm/src/commands/assignments.d.ts +3 -0
- package/esm/src/commands/assignments.d.ts.map +1 -0
- package/esm/src/commands/assignments.js +230 -0
- package/esm/src/commands/auth.d.ts +1 -1
- package/esm/src/commands/auth.d.ts.map +1 -1
- package/esm/src/commands/auth.js +24 -8
- package/esm/src/commands/calendar.d.ts.map +1 -1
- package/esm/src/commands/calendar.js +17 -18
- package/esm/src/commands/courses.js +3 -3
- package/esm/src/commands/forums.d.ts.map +1 -1
- package/esm/src/commands/forums.js +132 -45
- package/esm/src/commands/materials.d.ts.map +1 -1
- package/esm/src/commands/materials.js +176 -48
- package/esm/src/commands/quizzes.d.ts.map +1 -1
- package/esm/src/commands/quizzes.js +165 -65
- package/esm/src/commands/skills.d.ts.map +1 -1
- package/esm/src/commands/skills.js +4 -8
- package/esm/src/commands/upload.d.ts +3 -0
- package/esm/src/commands/upload.d.ts.map +1 -0
- package/esm/src/commands/upload.js +58 -0
- package/esm/src/commands/videos.d.ts.map +1 -1
- package/esm/src/commands/videos.js +113 -79
- package/esm/src/index.d.ts.map +1 -1
- package/esm/src/index.js +14 -3
- package/esm/src/lib/auth.d.ts +23 -1
- package/esm/src/lib/auth.d.ts.map +1 -1
- package/esm/src/lib/auth.js +36 -3
- package/esm/src/lib/moodle.d.ts +226 -2
- package/esm/src/lib/moodle.d.ts.map +1 -1
- package/esm/src/lib/moodle.js +648 -37
- package/esm/src/lib/types.d.ts +82 -164
- package/esm/src/lib/types.d.ts.map +1 -1
- package/esm/src/lib/types.js +1 -0
- package/esm/src/lib/utils.d.ts +40 -0
- package/esm/src/lib/utils.d.ts.map +1 -1
- package/esm/src/lib/utils.js +82 -4
- package/package.json +1 -2
- package/script/deno.js +1 -1
- package/script/src/commands/announcements.d.ts.map +1 -1
- package/script/src/commands/announcements.js +12 -13
- package/script/src/commands/assignments.d.ts +3 -0
- package/script/src/commands/assignments.d.ts.map +1 -0
- package/script/src/commands/assignments.js +269 -0
- package/script/src/commands/auth.d.ts +1 -1
- package/script/src/commands/auth.d.ts.map +1 -1
- package/script/src/commands/auth.js +24 -8
- package/script/src/commands/calendar.d.ts.map +1 -1
- package/script/src/commands/calendar.js +16 -17
- package/script/src/commands/courses.js +2 -2
- package/script/src/commands/forums.d.ts.map +1 -1
- package/script/src/commands/forums.js +132 -45
- package/script/src/commands/materials.d.ts.map +1 -1
- package/script/src/commands/materials.js +177 -49
- package/script/src/commands/quizzes.d.ts.map +1 -1
- package/script/src/commands/quizzes.js +163 -63
- package/script/src/commands/skills.d.ts.map +1 -1
- package/script/src/commands/skills.js +4 -8
- package/script/src/commands/upload.d.ts +3 -0
- package/script/src/commands/upload.d.ts.map +1 -0
- package/script/src/commands/upload.js +64 -0
- package/script/src/commands/videos.d.ts.map +1 -1
- package/script/src/commands/videos.js +114 -80
- package/script/src/index.d.ts.map +1 -1
- package/script/src/index.js +13 -2
- package/script/src/lib/auth.d.ts +23 -1
- package/script/src/lib/auth.d.ts.map +1 -1
- package/script/src/lib/auth.js +70 -3
- package/script/src/lib/moodle.d.ts +226 -2
- package/script/src/lib/moodle.d.ts.map +1 -1
- package/script/src/lib/moodle.js +663 -37
- package/script/src/lib/types.d.ts +82 -164
- package/script/src/lib/types.d.ts.map +1 -1
- package/script/src/lib/types.js +1 -0
- package/script/src/lib/utils.d.ts +40 -0
- package/script/src/lib/utils.d.ts.map +1 -1
- package/script/src/lib/utils.js +89 -3
- package/skills/openape/SKILL.md +73 -291
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.registerAssignmentsCommand = registerAssignmentsCommand;
|
|
40
|
+
const utils_js_1 = require("../lib/utils.js");
|
|
41
|
+
const moodle_js_1 = require("../lib/moodle.js");
|
|
42
|
+
const auth_js_1 = require("../lib/auth.js");
|
|
43
|
+
const index_js_1 = require("../index.js");
|
|
44
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
45
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
46
|
+
function registerAssignmentsCommand(program) {
|
|
47
|
+
const assignmentsCmd = program.command("assignments");
|
|
48
|
+
assignmentsCmd.description("Assignment operations");
|
|
49
|
+
assignmentsCmd
|
|
50
|
+
.command("list")
|
|
51
|
+
.description("List assignments in a course")
|
|
52
|
+
.argument("<course-id>", "Course ID")
|
|
53
|
+
.option("--output <format>", "Output format: json|csv|table|silent")
|
|
54
|
+
.action(async (courseId, options, command) => {
|
|
55
|
+
const output = (0, utils_js_1.getOutputFormat)(command);
|
|
56
|
+
const apiContext = await (0, auth_js_1.createApiContext)(options, command);
|
|
57
|
+
if (!apiContext) {
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const apiAssignments = await (0, moodle_js_1.getAssignmentsByCoursesApi)(apiContext.session, [parseInt(courseId, 10)]);
|
|
62
|
+
const assignments = apiAssignments.map(a => ({
|
|
63
|
+
id: a.id,
|
|
64
|
+
courseName: courseId,
|
|
65
|
+
name: a.name,
|
|
66
|
+
url: a.url,
|
|
67
|
+
cmid: a.cmid,
|
|
68
|
+
duedate: (0, utils_js_1.formatMoodleDate)(a.duedate),
|
|
69
|
+
cutoffdate: (0, utils_js_1.formatMoodleDate)(a.cutoffdate),
|
|
70
|
+
allowSubmissionsFromDate: (0, utils_js_1.formatMoodleDate)(a.allowSubmissionsFromDate),
|
|
71
|
+
}));
|
|
72
|
+
apiContext.log.info(`\n找到 ${assignments.length} 個作業。`);
|
|
73
|
+
(0, index_js_1.formatAndOutput)(assignments, output, apiContext.log);
|
|
74
|
+
});
|
|
75
|
+
assignmentsCmd
|
|
76
|
+
.command("list-all")
|
|
77
|
+
.description("List all assignments across all courses")
|
|
78
|
+
.option("--level <type>", "Course level: in_progress (default) | all", "in_progress")
|
|
79
|
+
.option("--output <format>", "Output format: json|csv|table|silent")
|
|
80
|
+
.action(async (options, command) => {
|
|
81
|
+
const output = (0, utils_js_1.getOutputFormat)(command);
|
|
82
|
+
const apiContext = await (0, auth_js_1.createApiContext)(options, command);
|
|
83
|
+
if (!apiContext) {
|
|
84
|
+
process.exitCode = 1;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const classification = options.level === "all" ? undefined : "inprogress";
|
|
88
|
+
const courses = await (0, moodle_js_1.getEnrolledCoursesApi)(apiContext.session, {
|
|
89
|
+
classification,
|
|
90
|
+
});
|
|
91
|
+
// Get assignments via WS API (no browser needed!)
|
|
92
|
+
const courseIds = courses.map(c => c.id);
|
|
93
|
+
const apiAssignments = await (0, moodle_js_1.getAssignmentsByCoursesApi)(apiContext.session, courseIds);
|
|
94
|
+
// Build a map of courseId -> course for quick lookup
|
|
95
|
+
const courseMap = new Map(courses.map(c => [c.id, c]));
|
|
96
|
+
const allAssignments = [];
|
|
97
|
+
for (const a of apiAssignments) {
|
|
98
|
+
const course = courseMap.get(a.courseId);
|
|
99
|
+
if (course) {
|
|
100
|
+
allAssignments.push({
|
|
101
|
+
id: a.id,
|
|
102
|
+
courseName: course.fullname,
|
|
103
|
+
name: a.name,
|
|
104
|
+
url: a.url,
|
|
105
|
+
cmid: a.cmid,
|
|
106
|
+
duedate: (0, utils_js_1.formatMoodleDate)(a.duedate),
|
|
107
|
+
cutoffdate: (0, utils_js_1.formatMoodleDate)(a.cutoffdate),
|
|
108
|
+
allowSubmissionsFromDate: (0, utils_js_1.formatMoodleDate)(a.allowSubmissionsFromDate),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
apiContext.log.info(`\n總計發現 ${allAssignments.length} 個作業。`);
|
|
113
|
+
(0, index_js_1.formatAndOutput)(allAssignments, output, apiContext.log);
|
|
114
|
+
});
|
|
115
|
+
// ── Submission Status ───────────────────────────────────────────────────────
|
|
116
|
+
assignmentsCmd
|
|
117
|
+
.command("status")
|
|
118
|
+
.description("Check assignment submission status")
|
|
119
|
+
.argument("<assignment-id>", "Assignment instance ID (from list-all)")
|
|
120
|
+
.option("--output <format>", "Output format: json|csv|table|silent")
|
|
121
|
+
.action(async (assignmentId, options, command) => {
|
|
122
|
+
const output = (0, utils_js_1.getOutputFormat)(command);
|
|
123
|
+
const apiContext = await (0, auth_js_1.createApiContext)(options, command);
|
|
124
|
+
if (!apiContext) {
|
|
125
|
+
process.exitCode = 1;
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const id = parseInt(assignmentId, 10);
|
|
129
|
+
apiContext.log.info("檢查繳交狀態...");
|
|
130
|
+
const status = await (0, moodle_js_1.getSubmissionStatusApi)(apiContext.session, id);
|
|
131
|
+
// Build status data object
|
|
132
|
+
const statusData = {
|
|
133
|
+
submitted: status.submitted,
|
|
134
|
+
submitted_text: status.submitted ? "已繳交" : "尚未繳交",
|
|
135
|
+
graded: status.graded,
|
|
136
|
+
graded_text: status.graded ? "已評分" : "尚未評分",
|
|
137
|
+
last_modified: status.lastModified ? new Date(status.lastModified * 1000).toISOString() : null,
|
|
138
|
+
last_modified_text: status.lastModified ? new Date(status.lastModified * 1000).toLocaleString("zh-TW") : null,
|
|
139
|
+
grader: status.grader,
|
|
140
|
+
grade: status.grade,
|
|
141
|
+
feedback: status.feedback,
|
|
142
|
+
files: status.extensions.map(f => ({
|
|
143
|
+
filename: f.filename,
|
|
144
|
+
filesize: f.filesize,
|
|
145
|
+
filesize_kb: (0, utils_js_1.formatFileSize)(f.filesize),
|
|
146
|
+
})),
|
|
147
|
+
};
|
|
148
|
+
(0, index_js_1.formatAndOutput)(statusData, output, apiContext.log);
|
|
149
|
+
});
|
|
150
|
+
// ── Submit Assignment ────────────────────────────────────────────────────────
|
|
151
|
+
assignmentsCmd
|
|
152
|
+
.command("submit")
|
|
153
|
+
.description("Submit an assignment (online text or file)")
|
|
154
|
+
.argument("<assignment-id>", "Assignment instance ID (from list-all)")
|
|
155
|
+
.option("--text <content>", "Online text content to submit")
|
|
156
|
+
.option("--file-id <id>", "Draft file ID from file upload")
|
|
157
|
+
.option("--file <path>", "Upload and submit a file directly")
|
|
158
|
+
.option("--output <format>", "Output format: json|csv|table|silent")
|
|
159
|
+
.action(async (assignmentId, options, command) => {
|
|
160
|
+
const output = (0, utils_js_1.getOutputFormat)(command);
|
|
161
|
+
const apiContext = await (0, auth_js_1.createApiContext)(options, command);
|
|
162
|
+
if (!apiContext) {
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const id = parseInt(assignmentId, 10);
|
|
167
|
+
// Check submission status first
|
|
168
|
+
const status = await (0, moodle_js_1.getSubmissionStatusApi)(apiContext.session, id);
|
|
169
|
+
let fileUploaded;
|
|
170
|
+
let cancelled = false;
|
|
171
|
+
if (status.submitted) {
|
|
172
|
+
const confirm = await promptConfirm("此作業已經繳交!確定要重新繳交嗎?(y/N): ");
|
|
173
|
+
if (!confirm) {
|
|
174
|
+
cancelled = true;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (cancelled) {
|
|
178
|
+
const cancelResult = {
|
|
179
|
+
success: false,
|
|
180
|
+
cancelled: true,
|
|
181
|
+
message: "Submission cancelled by user",
|
|
182
|
+
};
|
|
183
|
+
(0, index_js_1.formatAndOutput)(cancelResult, output, apiContext.log);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Validate options
|
|
187
|
+
if (!options.text && !options.fileId && !options.file) {
|
|
188
|
+
const errorResult = {
|
|
189
|
+
success: false,
|
|
190
|
+
error: "請提供 --text、--file-id 或 --file 選項。",
|
|
191
|
+
};
|
|
192
|
+
(0, index_js_1.formatAndOutput)(errorResult, output, apiContext.log);
|
|
193
|
+
process.exitCode = 1;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
let fileId = options.fileId ? parseInt(options.fileId, 10) : undefined;
|
|
197
|
+
// Upload file if --file option is provided
|
|
198
|
+
if (options.file) {
|
|
199
|
+
const resolvedPath = node_path_1.default.resolve(options.file);
|
|
200
|
+
// Check if file exists
|
|
201
|
+
try {
|
|
202
|
+
await promises_1.default.access(resolvedPath);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
const errorResult = {
|
|
206
|
+
success: false,
|
|
207
|
+
error: `檔案不存在: ${options.file}`,
|
|
208
|
+
};
|
|
209
|
+
(0, index_js_1.formatAndOutput)(errorResult, output, apiContext.log);
|
|
210
|
+
process.exitCode = 1;
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const stats = await promises_1.default.stat(resolvedPath);
|
|
214
|
+
const fileSizeKB = (0, utils_js_1.formatFileSize)(stats.size);
|
|
215
|
+
const uploadResult = await (0, moodle_js_1.uploadFileApi)(apiContext.session, resolvedPath);
|
|
216
|
+
if (!uploadResult.success) {
|
|
217
|
+
const errorResult = {
|
|
218
|
+
success: false,
|
|
219
|
+
error: `檔案上傳失敗: ${uploadResult.error}`,
|
|
220
|
+
};
|
|
221
|
+
(0, index_js_1.formatAndOutput)(errorResult, output, apiContext.log);
|
|
222
|
+
process.exitCode = 1;
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
fileId = uploadResult.draftId;
|
|
226
|
+
fileUploaded = {
|
|
227
|
+
filename: node_path_1.default.basename(resolvedPath),
|
|
228
|
+
filesize: stats.size,
|
|
229
|
+
filesize_kb: (0, utils_js_1.formatFileSize)(stats.size),
|
|
230
|
+
draft_id: fileId,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
// Submit
|
|
234
|
+
const result = await (0, moodle_js_1.saveSubmissionApi)(apiContext.session, id, {
|
|
235
|
+
onlineText: options.text ? { text: options.text } : undefined,
|
|
236
|
+
fileId: fileId,
|
|
237
|
+
});
|
|
238
|
+
const submitResult = {
|
|
239
|
+
success: result.success,
|
|
240
|
+
assignment_id: id,
|
|
241
|
+
submitted: !!result.success,
|
|
242
|
+
online_text: !!options.text,
|
|
243
|
+
file_uploaded: fileUploaded,
|
|
244
|
+
file_id: fileId ?? null,
|
|
245
|
+
error: result.success ? undefined : result.error,
|
|
246
|
+
message: result.success ? "Assignment submitted successfully" : result.error,
|
|
247
|
+
};
|
|
248
|
+
(0, index_js_1.formatAndOutput)(submitResult, output, apiContext.log);
|
|
249
|
+
if (!result.success) {
|
|
250
|
+
process.exitCode = 1;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Prompt user for yes/no confirmation.
|
|
256
|
+
*/
|
|
257
|
+
async function promptConfirm(prompt) {
|
|
258
|
+
const readline = await Promise.resolve().then(() => __importStar(require("node:readline")));
|
|
259
|
+
const rl = readline.createInterface({
|
|
260
|
+
input: process.stdin,
|
|
261
|
+
output: process.stdout,
|
|
262
|
+
});
|
|
263
|
+
return new Promise((resolve) => {
|
|
264
|
+
rl.question(prompt, (answer) => {
|
|
265
|
+
rl.close();
|
|
266
|
+
resolve(/^y/i.test(answer));
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/src/commands/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/src/commands/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuRtD"}
|
|
@@ -3,18 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.registerCommand = registerCommand;
|
|
7
7
|
const utils_js_1 = require("../lib/utils.js");
|
|
8
8
|
const playwright_core_1 = require("playwright-core");
|
|
9
9
|
const logger_js_1 = require("../lib/logger.js");
|
|
10
10
|
const auth_js_1 = require("../lib/auth.js");
|
|
11
11
|
const token_js_1 = require("../lib/token.js");
|
|
12
|
+
const moodle_js_1 = require("../lib/moodle.js");
|
|
12
13
|
const node_path_1 = __importDefault(require("node:path"));
|
|
13
14
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
|
-
function
|
|
15
|
-
const authCmd = program.command("auth");
|
|
16
|
-
authCmd.description("Authentication commands");
|
|
17
|
-
// Register login directly on program (not under auth subcommand)
|
|
15
|
+
function registerCommand(program) {
|
|
18
16
|
program
|
|
19
17
|
.command("login")
|
|
20
18
|
.description("Login to iLearning manually and save session")
|
|
@@ -192,8 +190,7 @@ function registerAuthCommand(program) {
|
|
|
192
190
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
193
191
|
}
|
|
194
192
|
});
|
|
195
|
-
|
|
196
|
-
authCmd
|
|
193
|
+
program
|
|
197
194
|
.command("status")
|
|
198
195
|
.description("Check session status")
|
|
199
196
|
.option("--session <path>", "Session file path", ".auth/storage-state.json")
|
|
@@ -221,6 +218,25 @@ function registerAuthCommand(program) {
|
|
|
221
218
|
exists: false
|
|
222
219
|
}
|
|
223
220
|
};
|
|
221
|
+
// Try to get user info from WS API
|
|
222
|
+
try {
|
|
223
|
+
const wsToken = (0, token_js_1.loadWsToken)(sessionPath);
|
|
224
|
+
if (wsToken) {
|
|
225
|
+
const session = {
|
|
226
|
+
wsToken,
|
|
227
|
+
moodleBaseUrl: "https://ilearning.cycu.edu.tw"
|
|
228
|
+
};
|
|
229
|
+
const siteInfo = await (0, moodle_js_1.getSiteInfoApi)(session);
|
|
230
|
+
result.user = {
|
|
231
|
+
userid: siteInfo.userid,
|
|
232
|
+
username: siteInfo.username,
|
|
233
|
+
fullname: siteInfo.fullname
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// WS token might not be available or expired, skip user info
|
|
239
|
+
}
|
|
224
240
|
console.log(JSON.stringify(result, null, 2));
|
|
225
241
|
}
|
|
226
242
|
catch {
|
|
@@ -242,7 +258,7 @@ function registerAuthCommand(program) {
|
|
|
242
258
|
console.log(JSON.stringify(result, null, 2));
|
|
243
259
|
}
|
|
244
260
|
});
|
|
245
|
-
|
|
261
|
+
program
|
|
246
262
|
.command("logout")
|
|
247
263
|
.description("Remove saved session")
|
|
248
264
|
.option("--session <path>", "Session file path", ".auth/storage-state.json")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../src/src/commands/calendar.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../src/src/commands/calendar.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmM9D"}
|
|
@@ -97,29 +97,28 @@ function registerCalendarCommand(program) {
|
|
|
97
97
|
if (options.upcoming) {
|
|
98
98
|
filteredEvents = allEvents.filter(e => e.timestart > now);
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
console.log(JSON.stringify({
|
|
101
101
|
status: "success",
|
|
102
102
|
timestamp: new Date().toISOString(),
|
|
103
|
-
|
|
103
|
+
total_events: allEvents.length,
|
|
104
|
+
upcoming: allEvents.filter(e => e.timestart > now).length,
|
|
105
|
+
by_type: allEvents.reduce((acc, e) => {
|
|
106
|
+
acc[e.eventtype] = (acc[e.eventtype] || 0) + 1;
|
|
107
|
+
return acc;
|
|
108
|
+
}, {}),
|
|
109
|
+
}));
|
|
110
|
+
for (const e of filteredEvents) {
|
|
111
|
+
console.log(JSON.stringify({
|
|
104
112
|
id: e.id,
|
|
105
113
|
name: e.name,
|
|
106
114
|
description: e.description,
|
|
107
115
|
course_id: e.courseid,
|
|
108
116
|
event_type: e.eventtype,
|
|
109
|
-
start_time:
|
|
110
|
-
end_time: e.timeduration ?
|
|
117
|
+
start_time: (0, utils_js_1.formatTimestamp)(e.timestart),
|
|
118
|
+
end_time: e.timeduration ? (0, utils_js_1.formatTimestamp)(e.timestart + Math.floor(e.timeduration / 1000)) : null,
|
|
111
119
|
location: e.location,
|
|
112
|
-
}))
|
|
113
|
-
|
|
114
|
-
total_events: allEvents.length,
|
|
115
|
-
upcoming: allEvents.filter(e => e.timestart > now).length,
|
|
116
|
-
by_type: allEvents.reduce((acc, e) => {
|
|
117
|
-
acc[e.eventtype] = (acc[e.eventtype] || 0) + 1;
|
|
118
|
-
return acc;
|
|
119
|
-
}, {}),
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
console.log(JSON.stringify(output));
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
123
122
|
});
|
|
124
123
|
calendarCmd
|
|
125
124
|
.command("export")
|
|
@@ -167,8 +166,8 @@ function registerCalendarCommand(program) {
|
|
|
167
166
|
description: e.description,
|
|
168
167
|
course_id: e.courseid,
|
|
169
168
|
event_type: e.eventtype,
|
|
170
|
-
start_time:
|
|
171
|
-
end_time: e.timeduration ?
|
|
169
|
+
start_time: (0, utils_js_1.formatTimestamp)(e.timestart),
|
|
170
|
+
end_time: e.timeduration ? (0, utils_js_1.formatTimestamp)(e.timestart + Math.floor(e.timeduration / 1000)) : null,
|
|
172
171
|
location: e.location,
|
|
173
172
|
})),
|
|
174
173
|
summary: {
|
|
@@ -117,8 +117,8 @@ function registerCoursesCommand(program) {
|
|
|
117
117
|
courseId: course.id,
|
|
118
118
|
courseName: course.fullname,
|
|
119
119
|
progress: course.progress ?? 0,
|
|
120
|
-
startDate: course.startdate ?
|
|
121
|
-
endDate: course.enddate ?
|
|
120
|
+
startDate: course.startdate ? (0, utils_js_1.formatTimestamp)(course.startdate) : null,
|
|
121
|
+
endDate: course.enddate ? (0, utils_js_1.formatTimestamp)(course.enddate) : null,
|
|
122
122
|
};
|
|
123
123
|
(0, index_js_1.formatAndOutput)(progressData, output, apiContext.log);
|
|
124
124
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forums.d.ts","sourceRoot":"","sources":["../../../src/src/commands/forums.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"forums.d.ts","sourceRoot":"","sources":["../../../src/src/commands/forums.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkX5D"}
|