@mo7yw4ng/openape 1.0.2 → 1.0.3
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 +8 -5
- package/esm/deno.js +1 -1
- 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 +3 -7
- package/esm/src/commands/forums.d.ts.map +1 -1
- package/esm/src/commands/forums.js +11 -16
- package/esm/src/commands/materials.d.ts.map +1 -1
- package/esm/src/commands/materials.js +171 -11
- package/esm/src/commands/videos.d.ts.map +1 -1
- package/esm/src/commands/videos.js +108 -75
- package/esm/src/index.js +2 -2
- package/esm/src/lib/moodle.d.ts +47 -1
- package/esm/src/lib/moodle.d.ts.map +1 -1
- package/esm/src/lib/moodle.js +169 -26
- package/esm/src/lib/types.d.ts +1 -0
- package/esm/src/lib/types.d.ts.map +1 -1
- package/esm/src/lib/utils.d.ts +20 -0
- package/esm/src/lib/utils.d.ts.map +1 -1
- package/esm/src/lib/utils.js +34 -3
- package/package.json +1 -2
- package/script/deno.js +1 -1
- 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 +4 -8
- package/script/src/commands/forums.d.ts.map +1 -1
- package/script/src/commands/forums.js +11 -16
- package/script/src/commands/materials.d.ts.map +1 -1
- package/script/src/commands/materials.js +173 -13
- package/script/src/commands/videos.d.ts.map +1 -1
- package/script/src/commands/videos.js +109 -76
- package/script/src/index.js +1 -1
- package/script/src/lib/moodle.d.ts +47 -1
- package/script/src/lib/moodle.d.ts.map +1 -1
- package/script/src/lib/moodle.js +172 -26
- package/script/src/lib/types.d.ts +1 -0
- package/script/src/lib/types.d.ts.map +1 -1
- package/script/src/lib/utils.d.ts +20 -0
- package/script/src/lib/utils.d.ts.map +1 -1
- package/script/src/lib/utils.js +37 -3
- package/skills/openape/SKILL.md +6 -26
|
@@ -54,6 +54,7 @@ export declare function getForumsApi(session: {
|
|
|
54
54
|
cmid: number;
|
|
55
55
|
name: string;
|
|
56
56
|
courseid: number;
|
|
57
|
+
timemodified: number;
|
|
57
58
|
}>>;
|
|
58
59
|
/**
|
|
59
60
|
* Get discussions in a forum via WS API (no browser required).
|
|
@@ -108,6 +109,10 @@ export declare function getCourseGradesApi(session: {
|
|
|
108
109
|
/**
|
|
109
110
|
* Visit a SuperVideo activity page and extract view_id + duration.
|
|
110
111
|
*/
|
|
112
|
+
/**
|
|
113
|
+
* Optimized video metadata extraction - minimal page load overhead.
|
|
114
|
+
* Blocks images, fonts, stylesheets to speed up viewId extraction.
|
|
115
|
+
*/
|
|
111
116
|
export declare function getVideoMetadata(page: Page, activityUrl: string, log: Logger): Promise<{
|
|
112
117
|
name: string;
|
|
113
118
|
url: string;
|
|
@@ -132,7 +137,25 @@ export declare function downloadVideo(page: Page, metadata: {
|
|
|
132
137
|
type?: string;
|
|
133
138
|
}>;
|
|
134
139
|
/**
|
|
135
|
-
* Complete a video
|
|
140
|
+
* Complete a video using WS API (mobile service only).
|
|
141
|
+
* Uses mod_supervideo_progress_save_mobile which is accessible via moodle_mobile_app service token.
|
|
142
|
+
*/
|
|
143
|
+
export declare function completeVideoApi(session: {
|
|
144
|
+
wsToken: string;
|
|
145
|
+
moodleBaseUrl: string;
|
|
146
|
+
}, video: {
|
|
147
|
+
viewId: number;
|
|
148
|
+
duration: number;
|
|
149
|
+
url: string;
|
|
150
|
+
cmid?: string;
|
|
151
|
+
}): Promise<{
|
|
152
|
+
success: boolean;
|
|
153
|
+
error?: string;
|
|
154
|
+
result?: any;
|
|
155
|
+
}>;
|
|
156
|
+
/**
|
|
157
|
+
* Complete a video by forging progress AJAX call (legacy, requires browser).
|
|
158
|
+
* Note: This uses sesskey-based AJAX which works for mod_supervideo_progress_save.
|
|
136
159
|
*/
|
|
137
160
|
export declare function completeVideo(page: Page, session: SessionInfo, video: {
|
|
138
161
|
viewId: number;
|
|
@@ -140,8 +163,17 @@ export declare function completeVideo(page: Page, session: SessionInfo, video: {
|
|
|
140
163
|
url: string;
|
|
141
164
|
cmid?: string;
|
|
142
165
|
}, log: Logger): Promise<boolean>;
|
|
166
|
+
/**
|
|
167
|
+
* Update activity completion status manually via WS API.
|
|
168
|
+
* Used for marking resources as complete/incomplete.
|
|
169
|
+
*/
|
|
170
|
+
export declare function updateActivityCompletionStatusManually(session: {
|
|
171
|
+
wsToken: string;
|
|
172
|
+
moodleBaseUrl: string;
|
|
173
|
+
}, cmid: number, completed: boolean): Promise<boolean>;
|
|
143
174
|
/**
|
|
144
175
|
* Get site info including current user ID via pure WS API.
|
|
176
|
+
* Results are cached for 5 minutes to avoid redundant calls.
|
|
145
177
|
*/
|
|
146
178
|
export declare function getSiteInfoApi(session: {
|
|
147
179
|
wsToken: string;
|
|
@@ -152,6 +184,20 @@ export declare function getSiteInfoApi(session: {
|
|
|
152
184
|
fullname: string;
|
|
153
185
|
sitename: string;
|
|
154
186
|
}>;
|
|
187
|
+
/**
|
|
188
|
+
* Get incomplete supervideos with completion tracking enabled via WS API.
|
|
189
|
+
* Uses core_completion_get_activities_completion_status to get only videos that:
|
|
190
|
+
* 1. Have completion tracking enabled (hascompletion: true)
|
|
191
|
+
* 2. Are not yet completed (isoverallcomplete: false or state !== 1)
|
|
192
|
+
*/
|
|
193
|
+
export declare function getIncompleteVideosApi(session: {
|
|
194
|
+
wsToken: string;
|
|
195
|
+
moodleBaseUrl: string;
|
|
196
|
+
}, courseId: number): Promise<Array<{
|
|
197
|
+
cmid: number;
|
|
198
|
+
name: string;
|
|
199
|
+
url: string;
|
|
200
|
+
}>>;
|
|
155
201
|
/**
|
|
156
202
|
* Get course contents and filter for SuperVideo modules via pure WS API.
|
|
157
203
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moodle.d.ts","sourceRoot":"","sources":["../../../src/src/lib/moodle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"moodle.d.ts","sourceRoot":"","sources":["../../../src/src/lib/moodle.ts"],"names":[],"mappings":"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"}
|
package/script/src/lib/moodle.js
CHANGED
|
@@ -47,24 +47,17 @@ exports.getCalendarEventsApi = getCalendarEventsApi;
|
|
|
47
47
|
exports.getCourseGradesApi = getCourseGradesApi;
|
|
48
48
|
exports.getVideoMetadata = getVideoMetadata;
|
|
49
49
|
exports.downloadVideo = downloadVideo;
|
|
50
|
+
exports.completeVideoApi = completeVideoApi;
|
|
50
51
|
exports.completeVideo = completeVideo;
|
|
52
|
+
exports.updateActivityCompletionStatusManually = updateActivityCompletionStatusManually;
|
|
51
53
|
exports.getSiteInfoApi = getSiteInfoApi;
|
|
54
|
+
exports.getIncompleteVideosApi = getIncompleteVideosApi;
|
|
52
55
|
exports.getSupervideosInCourseApi = getSupervideosInCourseApi;
|
|
53
56
|
exports.getQuizzesByCoursesApi = getQuizzesByCoursesApi;
|
|
54
57
|
exports.getResourcesByCoursesApi = getResourcesByCoursesApi;
|
|
55
58
|
exports.getMessagesApi = getMessagesApi;
|
|
56
59
|
const dntShim = __importStar(require("../../_dnt.shims.js"));
|
|
57
|
-
const node_html_parser_1 = require("node-html-parser");
|
|
58
60
|
const utils_js_1 = require("./utils.js");
|
|
59
|
-
// ── HTML Parsing Helpers ──────────────────────────────────────────────────
|
|
60
|
-
/**
|
|
61
|
-
* Get the HTML content of a page and parse it.
|
|
62
|
-
*/
|
|
63
|
-
async function fetchAndParse(page, url) {
|
|
64
|
-
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
|
|
65
|
-
const content = await page.content();
|
|
66
|
-
return (0, node_html_parser_1.parse)(content);
|
|
67
|
-
}
|
|
68
61
|
// ── Core Moodle AJAX Wrapper ───────────────────────────────────────────
|
|
69
62
|
/**
|
|
70
63
|
* Moodle WS API functions that are known to work via /webservice/rest/server.php
|
|
@@ -77,6 +70,12 @@ const WS_API_FUNCTIONS = new Set([
|
|
|
77
70
|
"gradereport_user_get_grade_items",
|
|
78
71
|
"core_calendar_get_calendar_events",
|
|
79
72
|
"core_course_get_contents",
|
|
73
|
+
"core_course_get_course_module",
|
|
74
|
+
"core_completion_get_activities_completion_status",
|
|
75
|
+
"core_completion_update_activity_completion_status_manually",
|
|
76
|
+
"mod_supervideo_progress_save",
|
|
77
|
+
"mod_supervideo_progress_save_mobile",
|
|
78
|
+
"mod_supervideo_view_supervideo",
|
|
80
79
|
"mod_quiz_get_quizzes_by_courses",
|
|
81
80
|
"mod_resource_get_resources_by_courses",
|
|
82
81
|
"core_message_get_messages",
|
|
@@ -250,15 +249,17 @@ async function getCourseState(page, session, courseId) {
|
|
|
250
249
|
async function getSupervideosInCourse(page, session, courseId, log, options = {}) {
|
|
251
250
|
const state = await getCourseState(page, session, courseId);
|
|
252
251
|
const cms = state?.cm ?? [];
|
|
253
|
-
log.debug(` Course state returned ${cms.length} modules`);
|
|
254
|
-
// Debug: log first few modules
|
|
255
|
-
for (let i = 0; i < Math.min(3, cms.length); i++) {
|
|
256
|
-
log.debug(` Module ${i}: ${JSON.stringify(cms[i])}`);
|
|
257
|
-
}
|
|
258
252
|
const allSupervideos = cms.filter((cm) => cm.module === "supervideo" || cm.modname === "supervideo");
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
253
|
+
// Filter: Only include videos with completion tracking enabled (have completionstate field)
|
|
254
|
+
// and are not yet completed (completionstate != 1 or isoverallcomplete != true)
|
|
255
|
+
const incomplete = allSupervideos.filter((cm) => {
|
|
256
|
+
// Has completionstate field = completion tracking is enabled for this video
|
|
257
|
+
const hasCompletionTracking = "completionstate" in cm;
|
|
258
|
+
// Is not yet completed
|
|
259
|
+
const isIncomplete = cm.completionstate !== 1 && cm.isoverallcomplete !== true;
|
|
260
|
+
return hasCompletionTracking && isIncomplete;
|
|
261
|
+
});
|
|
262
|
+
log.debug(` SuperVideo: ${allSupervideos.length} total, ${incomplete.length} incomplete (with completion enabled)`);
|
|
262
263
|
// Return only incomplete if requested, otherwise return all
|
|
263
264
|
const videos = options.incompleteOnly ? incomplete : allSupervideos;
|
|
264
265
|
return videos.map((cm) => ({
|
|
@@ -280,6 +281,7 @@ async function getForumsApi(session, courseIds) {
|
|
|
280
281
|
cmid: f.cmid,
|
|
281
282
|
name: f.name,
|
|
282
283
|
courseid: f.course, // API returns 'course' not 'courseid'
|
|
284
|
+
timemodified: f.timemodified,
|
|
283
285
|
}));
|
|
284
286
|
}
|
|
285
287
|
/**
|
|
@@ -427,7 +429,13 @@ async function getCourseGradesApi(session, courseId) {
|
|
|
427
429
|
/**
|
|
428
430
|
* Visit a SuperVideo activity page and extract view_id + duration.
|
|
429
431
|
*/
|
|
432
|
+
/**
|
|
433
|
+
* Optimized video metadata extraction - minimal page load overhead.
|
|
434
|
+
* Blocks images, fonts, stylesheets to speed up viewId extraction.
|
|
435
|
+
*/
|
|
430
436
|
async function getVideoMetadata(page, activityUrl, log) {
|
|
437
|
+
// Block unnecessary resources for faster loading
|
|
438
|
+
await page.route("**/*.{png,jpg,jpeg,gif,webp,svg,ico,woff,woff2,ttf,css}", (route) => route.abort());
|
|
431
439
|
await page.goto(activityUrl, { waitUntil: "domcontentloaded", timeout: 20000 });
|
|
432
440
|
const name = await page.title();
|
|
433
441
|
const pageSource = await page.content();
|
|
@@ -574,7 +582,7 @@ async function downloadVideo(page, metadata, outputPath, log) {
|
|
|
574
582
|
// Get array buffer and convert to Uint8Array
|
|
575
583
|
const arrayBuffer = await response.arrayBuffer();
|
|
576
584
|
const uint8Array = new Uint8Array(arrayBuffer);
|
|
577
|
-
// Write to file
|
|
585
|
+
// Write to file
|
|
578
586
|
await dntShim.Deno.writeFile(outputPath, uint8Array);
|
|
579
587
|
return { success: true, path: outputPath, type: "direct" };
|
|
580
588
|
}
|
|
@@ -609,21 +617,55 @@ async function downloadVideo(page, metadata, outputPath, log) {
|
|
|
609
617
|
}
|
|
610
618
|
// ── Progress Completion (from original progress.ts) ───────────────────────
|
|
611
619
|
/**
|
|
612
|
-
*
|
|
620
|
+
* Build duration map array for video progress tracking.
|
|
621
|
+
* Cached and scaled per duration to avoid repeated allocations.
|
|
613
622
|
*/
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
// Build duration map array (required by Moodle)
|
|
623
|
+
function buildDurationMap(duration) {
|
|
624
|
+
// Build the map array (0% to 100% in 1% increments)
|
|
617
625
|
const map = Array.from({ length: 100 }, (_, i) => ({
|
|
618
626
|
time: Math.round((duration * i) / 100),
|
|
619
627
|
percent: i,
|
|
620
628
|
}));
|
|
629
|
+
return JSON.stringify(map);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Complete a video using WS API (mobile service only).
|
|
633
|
+
* Uses mod_supervideo_progress_save_mobile which is accessible via moodle_mobile_app service token.
|
|
634
|
+
*/
|
|
635
|
+
async function completeVideoApi(session, video) {
|
|
636
|
+
const { viewId, duration } = video;
|
|
637
|
+
try {
|
|
638
|
+
const result = await moodleApiCall(session, "mod_supervideo_progress_save_mobile", // Use mobile service specific function
|
|
639
|
+
{
|
|
640
|
+
view_id: viewId,
|
|
641
|
+
currenttime: duration,
|
|
642
|
+
duration: duration,
|
|
643
|
+
percent: 100,
|
|
644
|
+
mapa: buildDurationMap(duration),
|
|
645
|
+
});
|
|
646
|
+
// Debug: log the full result
|
|
647
|
+
console.debug(`completeVideoApi result:`, JSON.stringify(result));
|
|
648
|
+
const success = result?.[0]?.success === true || result?.success === true;
|
|
649
|
+
return { success, error: success ? undefined : `API returned success=false, result=${JSON.stringify(result)}`, result };
|
|
650
|
+
}
|
|
651
|
+
catch (err) {
|
|
652
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
653
|
+
console.debug(`completeVideoApi error: ${msg}`);
|
|
654
|
+
return { success: false, error: msg };
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Complete a video by forging progress AJAX call (legacy, requires browser).
|
|
659
|
+
* Note: This uses sesskey-based AJAX which works for mod_supervideo_progress_save.
|
|
660
|
+
*/
|
|
661
|
+
async function completeVideo(page, session, video, log) {
|
|
662
|
+
const { viewId, duration } = video;
|
|
621
663
|
const payload = {
|
|
622
664
|
view_id: viewId,
|
|
623
665
|
currenttime: duration,
|
|
624
666
|
duration: duration,
|
|
625
667
|
percent: 100,
|
|
626
|
-
mapa:
|
|
668
|
+
mapa: buildDurationMap(duration),
|
|
627
669
|
};
|
|
628
670
|
const url = `${session.moodleBaseUrl}/lib/ajax/service.php?sesskey=${session.sesskey}&info=mod_supervideo_progress_save`;
|
|
629
671
|
const ajaxPayload = [{ index: 0, methodname: "mod_supervideo_progress_save", args: payload }];
|
|
@@ -647,18 +689,94 @@ async function completeVideo(page, session, video, log) {
|
|
|
647
689
|
return false;
|
|
648
690
|
}
|
|
649
691
|
}
|
|
692
|
+
/**
|
|
693
|
+
* Update activity completion status manually via WS API.
|
|
694
|
+
* Used for marking resources as complete/incomplete.
|
|
695
|
+
*/
|
|
696
|
+
async function updateActivityCompletionStatusManually(session, cmid, completed) {
|
|
697
|
+
try {
|
|
698
|
+
const result = await moodleApiCall(session, "core_completion_update_activity_completion_status_manually", {
|
|
699
|
+
cmid: cmid,
|
|
700
|
+
completed: completed ? 1 : 0,
|
|
701
|
+
});
|
|
702
|
+
return result.status === true;
|
|
703
|
+
}
|
|
704
|
+
catch (e) {
|
|
705
|
+
console.debug(`Failed to update completion status for cmid ${cmid}: ${e}`);
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
650
709
|
// ── Site Info (Get User ID) ───────────────────────────────────────────────────
|
|
710
|
+
/** Cache for site info to avoid redundant API calls */
|
|
711
|
+
let siteInfoCache = null;
|
|
712
|
+
let siteInfoCacheTime = 0;
|
|
713
|
+
const SITE_INFO_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
651
714
|
/**
|
|
652
715
|
* Get site info including current user ID via pure WS API.
|
|
716
|
+
* Results are cached for 5 minutes to avoid redundant calls.
|
|
653
717
|
*/
|
|
654
718
|
async function getSiteInfoApi(session) {
|
|
719
|
+
const now = Date.now();
|
|
720
|
+
if (siteInfoCache && (now - siteInfoCacheTime) < SITE_INFO_CACHE_TTL) {
|
|
721
|
+
return siteInfoCache;
|
|
722
|
+
}
|
|
655
723
|
const data = await moodleApiCall(session, "core_webservice_get_site_info", {});
|
|
656
|
-
|
|
724
|
+
siteInfoCache = {
|
|
657
725
|
userid: data.userid,
|
|
658
726
|
username: data.username,
|
|
659
727
|
fullname: data.fullname,
|
|
660
728
|
sitename: data.sitename,
|
|
661
729
|
};
|
|
730
|
+
siteInfoCacheTime = now;
|
|
731
|
+
return siteInfoCache;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Get incomplete supervideos with completion tracking enabled via WS API.
|
|
735
|
+
* Uses core_completion_get_activities_completion_status to get only videos that:
|
|
736
|
+
* 1. Have completion tracking enabled (hascompletion: true)
|
|
737
|
+
* 2. Are not yet completed (isoverallcomplete: false or state !== 1)
|
|
738
|
+
*/
|
|
739
|
+
async function getIncompleteVideosApi(session, courseId) {
|
|
740
|
+
// Get user ID
|
|
741
|
+
const siteInfo = await getSiteInfoApi(session);
|
|
742
|
+
// Get completion status for all activities
|
|
743
|
+
const completionData = await moodleApiCall(session, "core_completion_get_activities_completion_status", { courseid: courseId, userid: siteInfo.userid });
|
|
744
|
+
if (!completionData?.statuses) {
|
|
745
|
+
return [];
|
|
746
|
+
}
|
|
747
|
+
// Get course contents to get URLs
|
|
748
|
+
const contentsData = await moodleApiCall(session, "core_course_get_contents", { courseid: courseId });
|
|
749
|
+
// Create a map of cmid to URL
|
|
750
|
+
const urlMap = new Map();
|
|
751
|
+
for (const section of contentsData || []) {
|
|
752
|
+
if (!section.modules)
|
|
753
|
+
continue;
|
|
754
|
+
for (const module of section.modules) {
|
|
755
|
+
if (module.id) {
|
|
756
|
+
urlMap.set(module.id, module.url);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
// Filter for incomplete supervideos with completion tracking enabled
|
|
761
|
+
const incompleteVideos = [];
|
|
762
|
+
for (const status of completionData.statuses) {
|
|
763
|
+
// Only supervideo modules
|
|
764
|
+
if (status.modname !== "supervideo")
|
|
765
|
+
continue;
|
|
766
|
+
// Must have completion enabled
|
|
767
|
+
if (!status.hascompletion)
|
|
768
|
+
continue;
|
|
769
|
+
// Must be incomplete
|
|
770
|
+
if (status.isoverallcomplete === true || status.state === 1)
|
|
771
|
+
continue;
|
|
772
|
+
const url = urlMap.get(status.cmid) || "";
|
|
773
|
+
incompleteVideos.push({
|
|
774
|
+
cmid: status.cmid,
|
|
775
|
+
name: status.name,
|
|
776
|
+
url,
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
return incompleteVideos;
|
|
662
780
|
}
|
|
663
781
|
// ── Videos via WS API ─────────────────────────────────────────────────────────
|
|
664
782
|
/**
|
|
@@ -679,11 +797,39 @@ async function getSupervideosInCourseApi(session, courseId) {
|
|
|
679
797
|
cmid: module.id.toString(),
|
|
680
798
|
name: module.name,
|
|
681
799
|
url: module.url,
|
|
682
|
-
|
|
800
|
+
instance: module.instance, // supervideo instance id (not cmid!)
|
|
801
|
+
isComplete: false, // Will be updated from completion API
|
|
683
802
|
});
|
|
684
803
|
}
|
|
685
804
|
}
|
|
686
805
|
}
|
|
806
|
+
// Get completion status using core_completion_get_activities_completion_status
|
|
807
|
+
try {
|
|
808
|
+
// First get user ID
|
|
809
|
+
const siteInfo = await getSiteInfoApi(session);
|
|
810
|
+
const completionData = await moodleApiCall(session, "core_completion_get_activities_completion_status", { courseid: courseId, userid: siteInfo.userid });
|
|
811
|
+
// Create a map of cmid to completion status
|
|
812
|
+
const completionMap = new Map();
|
|
813
|
+
if (completionData?.statuses) {
|
|
814
|
+
for (const status of completionData.statuses) {
|
|
815
|
+
// Only include modules that have completion enabled
|
|
816
|
+
if (status.hascompletion) {
|
|
817
|
+
completionMap.set(status.cmid, status.isoverallcomplete === true);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
// Update isComplete based on completion data
|
|
822
|
+
for (const video of videos) {
|
|
823
|
+
const cmid = parseInt(video.cmid, 10);
|
|
824
|
+
if (completionMap.has(cmid)) {
|
|
825
|
+
video.isComplete = completionMap.get(cmid) ?? false;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
catch (e) {
|
|
830
|
+
// If completion API fails, continue with isComplete=false
|
|
831
|
+
console.debug(`Failed to get completion status: ${e}`);
|
|
832
|
+
}
|
|
687
833
|
return videos;
|
|
688
834
|
}
|
|
689
835
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/lib/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/lib/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OutputFormat } from "./types.js";
|
|
1
2
|
/**
|
|
2
3
|
* Returns the base directory for config/storage resolving.
|
|
3
4
|
* Handles both Deno (raw/compiled) and Node.js (npx).
|
|
@@ -14,4 +15,23 @@ export declare function stripHtmlTags(html: string): string;
|
|
|
14
15
|
* Example: "{mlang zh-tw}1142爵士樂賞析(遠距)-楊曊恩..." -> "爵士樂賞析"
|
|
15
16
|
*/
|
|
16
17
|
export declare function extractCourseName(fullname: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Get output format from command options (global or local).
|
|
20
|
+
* Defaults to "json" if not specified.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getOutputFormat(command: {
|
|
23
|
+
optsWithGlobals(): {
|
|
24
|
+
output?: OutputFormat;
|
|
25
|
+
};
|
|
26
|
+
}): OutputFormat;
|
|
27
|
+
/**
|
|
28
|
+
* Determine if logs should be silenced based on output format and verbosity.
|
|
29
|
+
* JSON output without verbose flag silences logs.
|
|
30
|
+
*/
|
|
31
|
+
export declare function shouldSilenceLogs(outputFormat: OutputFormat, verbose?: boolean): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Sanitize filename by removing invalid characters and limiting length.
|
|
34
|
+
* Replaces invalid characters with underscores and limits to maxLength.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sanitizeFilename(name: string, maxLength?: number): string;
|
|
17
37
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/src/lib/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/src/lib/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAcnC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAelD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE;IAAE,eAAe,IAAI;QAAE,MAAM,CAAC,EAAE,YAAY,CAAA;KAAE,CAAA;CAAE,GAAG,YAAY,CAGvG;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAExF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,CAK9E"}
|
package/script/src/lib/utils.js
CHANGED
|
@@ -36,6 +36,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.getBaseDir = getBaseDir;
|
|
37
37
|
exports.stripHtmlTags = stripHtmlTags;
|
|
38
38
|
exports.extractCourseName = extractCourseName;
|
|
39
|
+
exports.getOutputFormat = getOutputFormat;
|
|
40
|
+
exports.shouldSilenceLogs = shouldSilenceLogs;
|
|
41
|
+
exports.sanitizeFilename = sanitizeFilename;
|
|
39
42
|
const dntShim = __importStar(require("../../_dnt.shims.js"));
|
|
40
43
|
const node_path_1 = require("node:path");
|
|
41
44
|
/**
|
|
@@ -45,9 +48,15 @@ const node_path_1 = require("node:path");
|
|
|
45
48
|
function getBaseDir() {
|
|
46
49
|
// @ts-ignore - Deno global is available in Deno
|
|
47
50
|
if (typeof dntShim.Deno !== "undefined" && typeof dntShim.Deno.execPath === "function") {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
try {
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
const exeDir = (0, node_path_1.dirname)(dntShim.Deno.execPath());
|
|
54
|
+
return exeDir.includes("deno") ? process.cwd() : exeDir;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Deno shim (dnt) or Deno not installed
|
|
58
|
+
return process.cwd();
|
|
59
|
+
}
|
|
51
60
|
}
|
|
52
61
|
// Node.js or dnt runtime
|
|
53
62
|
return process.cwd();
|
|
@@ -87,3 +96,28 @@ function extractCourseName(fullname) {
|
|
|
87
96
|
const match = cleaned.match(/\d{4,}([^([-]+)/);
|
|
88
97
|
return match ? match[1].trim() : fullname;
|
|
89
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Get output format from command options (global or local).
|
|
101
|
+
* Defaults to "json" if not specified.
|
|
102
|
+
*/
|
|
103
|
+
function getOutputFormat(command) {
|
|
104
|
+
const opts = command.optsWithGlobals();
|
|
105
|
+
return opts.output || "json";
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Determine if logs should be silenced based on output format and verbosity.
|
|
109
|
+
* JSON output without verbose flag silences logs.
|
|
110
|
+
*/
|
|
111
|
+
function shouldSilenceLogs(outputFormat, verbose) {
|
|
112
|
+
return outputFormat === "json" && !verbose;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Sanitize filename by removing invalid characters and limiting length.
|
|
116
|
+
* Replaces invalid characters with underscores and limits to maxLength.
|
|
117
|
+
*/
|
|
118
|
+
function sanitizeFilename(name, maxLength = 200) {
|
|
119
|
+
return name
|
|
120
|
+
.replace(/[<>:"/\\|?*]/g, "_")
|
|
121
|
+
.replace(/\s+/g, "_")
|
|
122
|
+
.substring(0, maxLength);
|
|
123
|
+
}
|
package/skills/openape/SKILL.md
CHANGED
|
@@ -9,39 +9,29 @@ Use the `openape` command to access CYCU iLearning (Moodle) platform. OpenApe pr
|
|
|
9
9
|
|
|
10
10
|
## Setup
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
If `openape` is not installed:
|
|
13
13
|
```bash
|
|
14
14
|
npm install -g @mo7yw4ng/openape
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Or run without installing:
|
|
18
|
-
```bash
|
|
19
|
-
npx @mo7yw4ng/openape --help
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Or install via Deno/JSR:
|
|
23
|
-
```bash
|
|
24
|
-
deno install -A -g -n openape jsr:@openape/openape
|
|
25
|
-
```
|
|
26
|
-
|
|
27
17
|
If not authenticated, run:
|
|
28
18
|
```bash
|
|
29
19
|
openape login
|
|
30
20
|
```
|
|
31
|
-
A browser will open for Microsoft OAuth SSO. Complete MFA login manually
|
|
21
|
+
A browser will open for Microsoft OAuth SSO. Complete MFA login manually.
|
|
32
22
|
|
|
33
23
|
Session is saved to `.auth/storage-state.json` and persists between runs. If session expires, run `openape login` again.
|
|
34
24
|
|
|
35
25
|
## Discovering Commands
|
|
36
26
|
|
|
37
|
-
Every command supports `--help` for full option details
|
|
27
|
+
**Every command supports `--help` for full option details:**
|
|
38
28
|
```bash
|
|
39
29
|
openape --help
|
|
40
30
|
openape courses --help
|
|
41
31
|
openape videos complete --help
|
|
42
32
|
```
|
|
43
33
|
|
|
44
|
-
Add `--output json` to any command for machine-readable output. Use `--output csv` for spreadsheet format, `--output table` for human-readable tables
|
|
34
|
+
Add `--output json` to any command for machine-readable output. Use `--output csv` for spreadsheet format, `--output table` for human-readable tables.
|
|
45
35
|
|
|
46
36
|
## Course Commands
|
|
47
37
|
|
|
@@ -94,18 +84,10 @@ openape videos list <course-id> --incomplete-only
|
|
|
94
84
|
# Complete all incomplete videos in a course
|
|
95
85
|
openape videos complete <course-id>
|
|
96
86
|
|
|
97
|
-
# Dry-run: discover videos without completing
|
|
98
|
-
openape videos complete <course-id> --dry-run
|
|
99
|
-
|
|
100
87
|
# Complete all incomplete videos across all courses
|
|
101
88
|
openape videos complete-all
|
|
102
|
-
|
|
103
|
-
# Dry-run all courses
|
|
104
|
-
openape videos complete-all --dry-run
|
|
105
89
|
```
|
|
106
90
|
|
|
107
|
-
**Note:** Video completion forges SuperVideo progress AJAX calls to simulate watching the entire video. The server accepts the progress but completion status may take time to update in the course state.
|
|
108
|
-
|
|
109
91
|
### Downloading videos
|
|
110
92
|
|
|
111
93
|
```bash
|
|
@@ -305,6 +287,7 @@ openape courses syllabus <course-id>
|
|
|
305
287
|
**Review discussions:** Catch up on forum activity.
|
|
306
288
|
```bash
|
|
307
289
|
openape forums list --level in_progress
|
|
290
|
+
openape forums list-all
|
|
308
291
|
openape forums discussions <forum-id>
|
|
309
292
|
openape forums posts <discussion-id>
|
|
310
293
|
```
|
|
@@ -323,9 +306,6 @@ openape materials download-all --level in_progress
|
|
|
323
306
|
|
|
324
307
|
## Tips
|
|
325
308
|
|
|
326
|
-
- Use `--dry-run` with `videos complete` to preview what will be completed
|
|
327
309
|
- Use `--level in_progress` (default) to focus on active courses
|
|
328
310
|
- Use `--output json` for scripting and automation
|
|
329
|
-
- Use `--output table` for human-readable output
|
|
330
|
-
- Session persists after login, no need to re-authenticate
|
|
331
|
-
- WS API mode is used by default for faster performance; browser mode is fallback
|
|
311
|
+
- Use `--output table` for human-readable output
|