tronclass-auto 1.2.7 → 1.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tronclass-auto",
3
- "version": "1.2.7",
3
+ "version": "1.3.2",
4
4
  "description": "自動觀看 eclass/TronClass 影片、填寫表單的 CLI 工具",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -26,7 +26,20 @@ async function getUncompleted(page, courseId) {
26
26
  const a = actScope.activity;
27
27
  let completeness = '';
28
28
  try { completeness = scope.getActivityCompleteness(a); } catch (e) {}
29
- if (completeness !== 'full') {
29
+ if (completeness === 'full') return;
30
+
31
+ let isUpcoming = false;
32
+ let isExpired = false;
33
+ try { isUpcoming = scope.activityUpcoming(a); } catch (e) {}
34
+ try { isExpired = scope.activityExpired(a); } catch (e) {}
35
+ if (isUpcoming) return;
36
+
37
+ let timeRange = '';
38
+ try {
39
+ const txt = actEl.textContent || '';
40
+ const tm = txt.match(/時間:\s*(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})\s*~\s*(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})/);
41
+ if (tm) timeRange = tm[0];
42
+ } catch (e) {}
30
43
  let durationSec = 0;
31
44
  try {
32
45
  const durText = actEl.querySelector('.activity-attribute');
@@ -48,9 +61,9 @@ async function getUncompleted(page, courseId) {
48
61
  id: a.id,
49
62
  title: (a.title || '').substring(0, 60),
50
63
  type: a.type || '',
51
- durationSec
64
+ durationSec,
65
+ timeRange
52
66
  });
53
- }
54
67
  });
55
68
  return result;
56
69
  });
@@ -161,23 +174,30 @@ async function showStatus() {
161
174
  try {
162
175
  const uncompleted = await getUncompleted(page, courseId);
163
176
  const videos = uncompleted.filter(u => u.type === 'online_video');
177
+ const remaining = videos.filter(v => !isDone(courseId, v.id));
164
178
  const exams = uncompleted.filter(u => u.type === 'exam').length;
165
- const other = uncompleted.length - videos.length - exams;
166
179
  totalVideos += videos.length;
167
- totalRemaining += videos.length;
180
+ totalRemaining += remaining.length;
168
181
  totalExams += exams;
169
182
 
170
- const bar = generateBar(videos.length, 50);
171
- console.log(chalk.cyan('│') + ` [${courseId}] ${videos.length} videos ${exams} exams`.padEnd(50) + chalk.cyan('│'));
172
- console.log(chalk.cyan('│') + ` ${bar}`.padEnd(50) + chalk.cyan('│'));
183
+ const pct = videos.length > 0 ? Math.floor(((videos.length - remaining.length) / videos.length) * 100) : 100;
184
+ const filled = Math.floor(50 * pct / 100);
185
+ const empty = 50 - filled;
186
+ const bar = pct === 100
187
+ ? chalk.green('█'.repeat(50))
188
+ : chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
189
+
190
+ const doneCount = videos.length - remaining.length;
191
+ console.log(chalk.cyan('│') + ` [${courseId}] ${doneCount}/${videos.length} videos ${exams} exams`.padEnd(50) + chalk.cyan('│'));
192
+ console.log(chalk.cyan('│') + ` ${bar} ${pct}%`.padEnd(52) + chalk.cyan('│'));
173
193
  } catch (e) {
174
194
  console.log(chalk.cyan('│') + ` [${courseId}] ERROR`.padEnd(50) + chalk.cyan('│'));
175
195
  }
176
196
  }
177
197
 
178
198
  console.log(chalk.cyan('├' + '─'.repeat(48) + '┤'));
179
- console.log(chalk.cyan('│') + ` 總計: ${totalRemaining} videos, ${totalExams} exams`.padEnd(50) + chalk.cyan('│'));
180
- console.log(chalk.cyan('│') + ` 預估時間: ${formatTime(totalRemaining * 120)}`.padEnd(50) + chalk.cyan('│'));
199
+ console.log(chalk.cyan('│') + ` 剩餘: ${totalRemaining} videos | 考試: ${totalExams}`.padEnd(50) + chalk.cyan('│'));
200
+ console.log(chalk.cyan('│') + ` 預估: ${formatTime(totalRemaining * 120)}`.padEnd(50) + chalk.cyan('│'));
181
201
  console.log(chalk.cyan('└' + '─'.repeat(48) + '┘'));
182
202
  console.log('');
183
203
 
package/src/video.js CHANGED
@@ -17,8 +17,7 @@ function progress(msg) {
17
17
  }
18
18
 
19
19
  function log(msg) {
20
- process.stdout.write('\n');
21
- progress(msg);
20
+ console.log(msg);
22
21
  }
23
22
 
24
23
  async function watchVideo(page, stats) {