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 }