/ clis / bilibili / history.js
history.js
 1  import { cli, Strategy } from '@jackwener/opencli/registry';
 2  import { apiGet, payloadData } from './utils.js';
 3  cli({
 4      site: 'bilibili',
 5      name: 'history',
 6      description: '我的观看历史',
 7      domain: 'www.bilibili.com',
 8      strategy: Strategy.COOKIE,
 9      args: [
10          { name: 'limit', type: 'int', default: 20, help: 'Number of results' },
11      ],
12      columns: ['rank', 'title', 'author', 'progress', 'url'],
13      func: async (page, kwargs) => {
14          const { limit = 20 } = kwargs;
15          const payload = await apiGet(page, '/x/web-interface/history/cursor', {
16              params: { ps: Math.min(Number(limit), 30), type: 'archive' },
17          });
18          const list = payloadData(payload)?.list ?? [];
19          return list.slice(0, Number(limit)).map((item, i) => {
20              const progress = item.progress ?? 0;
21              const duration = item.duration ?? 0;
22              let progressStr;
23              if (progress < 0 || progress >= duration) {
24                  progressStr = '已看完';
25              }
26              else {
27                  const pct = duration > 0 ? Math.round(progress / duration * 100) : 0;
28                  progressStr = `${formatDuration(progress)}/${formatDuration(duration)} (${pct}%)`;
29              }
30              return {
31                  rank: i + 1,
32                  title: item.title ?? '',
33                  author: item.author_name ?? '',
34                  progress: progressStr,
35                  url: item.history?.bvid ? `https://www.bilibili.com/video/${item.history.bvid}` : '',
36              };
37          });
38      },
39  });
40  function formatDuration(seconds) {
41      const m = Math.floor(seconds / 60);
42      const s = seconds % 60;
43      return `${m}:${s.toString().padStart(2, '0')}`;
44  }