/ clis / linux-do / categories.js
categories.js
 1  import { cli, Strategy } from '@jackwener/opencli/registry';
 2  import { fetchLinuxDoJson } from './feed.js';
 3  cli({
 4      site: 'linux-do',
 5      name: 'categories',
 6      description: 'linux.do 分类列表',
 7      domain: 'linux.do',
 8      strategy: Strategy.COOKIE,
 9      browser: true,
10      args: [
11          { name: 'subcategories', type: 'boolean', default: false, help: 'Include subcategories' },
12          { name: 'limit', type: 'int', default: 20, help: 'Number of categories' },
13      ],
14      columns: ['name', 'slug', 'id', 'topics', 'description'],
15      func: async (page, kwargs) => {
16          const data = await fetchLinuxDoJson(page, '/categories.json');
17          const cats = (data?.category_list?.categories || []);
18          const showSub = !!kwargs.subcategories;
19          const limit = kwargs.limit;
20          const results = [];
21          for (const c of cats) {
22              if (results.length >= limit)
23                  break;
24              results.push({
25                  name: c.name,
26                  slug: c.slug,
27                  id: c.id,
28                  topics: c.topic_count,
29                  description: (c.description_text || '').slice(0, 80),
30              });
31              if (showSub && Array.isArray(c.subcategory_ids) && c.subcategory_ids.length > 0) {
32                  const subData = await fetchLinuxDoJson(page, `/categories.json?parent_category_id=${c.id}`, { skipNavigate: true });
33                  const subCats = (subData?.category_list?.categories || []);
34                  for (const sc of subCats) {
35                      if (results.length >= limit)
36                          break;
37                      results.push({
38                          name: c.name + ' / ' + sc.name,
39                          slug: sc.slug,
40                          id: sc.id,
41                          topics: sc.topic_count,
42                          description: (sc.description_text || '').slice(0, 80),
43                      });
44                  }
45              }
46          }
47          return results;
48      },
49  });