koishi-plugin-apple-rank 0.0.3 → 0.0.4

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.
Files changed (2) hide show
  1. package/lib/index.js +47 -18
  2. package/package.json +4 -1
package/lib/index.js CHANGED
@@ -25,6 +25,7 @@ __export(src_exports, {
25
25
  name: () => name
26
26
  });
27
27
  module.exports = __toCommonJS(src_exports);
28
+ var import_jimp = require("jimp");
28
29
  var import_koishi = require("koishi");
29
30
  var name = "apple-rank";
30
31
  var Config = import_koishi.Schema.object({
@@ -90,10 +91,10 @@ function formatUpdatedAt(updated) {
90
91
  return `更新时间:${date.toLocaleString("zh-CN", { timeZone: "Asia/Shanghai", hour12: false })}`;
91
92
  }
92
93
  __name(formatUpdatedAt, "formatUpdatedAt");
93
- function formatFootnote() {
94
- return "口径:Apple 公开榜单,只代表 iOS 排名,不代表全平台流水";
94
+ function formatNote() {
95
+ return "说明:Apple 公开榜单,只代表 iOS 排名,不代表全平台流水";
95
96
  }
96
- __name(formatFootnote, "formatFootnote");
97
+ __name(formatNote, "formatNote");
97
98
  function joinBlocks(blocks) {
98
99
  return blocks.filter(Boolean).join("\n\n");
99
100
  }
@@ -114,6 +115,7 @@ function apply(ctx, config) {
114
115
  let cachedFeed = "";
115
116
  let cachedRankFeed = { ranks: [], actualLimit: 0 };
116
117
  const recentReplies = /* @__PURE__ */ new Map();
118
+ const grayscaleIconCache = /* @__PURE__ */ new Map();
117
119
  async function fetchRanks(feedType = "topgrossingapplications") {
118
120
  const now = Date.now();
119
121
  if (cachedFeed === feedType && cachedRankFeed.ranks.length && now - cachedAt < config.cacheTtl * 1e3) {
@@ -144,6 +146,21 @@ function apply(ctx, config) {
144
146
  return true;
145
147
  }
146
148
  __name(shouldReplyOnce, "shouldReplyOnce");
149
+ async function toGrayscaleIcon(url) {
150
+ if (!url) return void 0;
151
+ const cached = grayscaleIconCache.get(url);
152
+ if (cached) return cached;
153
+ try {
154
+ const image = await import_jimp.Jimp.read(url);
155
+ image.greyscale();
156
+ const base64 = await image.getBase64("image/png");
157
+ grayscaleIconCache.set(url, base64);
158
+ return base64;
159
+ } catch {
160
+ return url;
161
+ }
162
+ }
163
+ __name(toGrayscaleIcon, "toGrayscaleIcon");
147
164
  async function searchApp(keyword) {
148
165
  const url = "https://itunes.apple.com/search";
149
166
  const response = parseJson(await ctx.http.get(url, {
@@ -197,7 +214,10 @@ function apply(ctx, config) {
197
214
  const lines = feed.ranks.slice(0, Math.min(limit, actualLimit)).map(formatRankItemWithIcon);
198
215
  return joinBlocks([
199
216
  `App Store ${config.country.toUpperCase()} ${feedLabels[feedType]} Top ${actualLimit}`,
200
- formatUpdatedAt(feed.updated),
217
+ [
218
+ formatUpdatedAt(feed.updated),
219
+ formatNote()
220
+ ].join("\n"),
201
221
  lines.join("\n")
202
222
  ]);
203
223
  });
@@ -211,24 +231,26 @@ function apply(ctx, config) {
211
231
  if (!item) {
212
232
  return joinBlocks([
213
233
  detail?.artworkUrl100 ? import_koishi.h.image(detail.artworkUrl100) : "",
214
- `「${detail?.trackName || game}」未进入 App Store ${config.country.toUpperCase()} ${feedLabels[feedType]} Top ${actualLimit}`,
234
+ `${detail?.trackName || game}`,
235
+ `未进入 App Store ${config.country.toUpperCase()} ${feedLabels[feedType]} Top ${actualLimit}`,
215
236
  [
216
237
  formatUpdatedAt(updated),
217
238
  detail?.artistName ? `开发者:${detail.artistName}` : "",
218
- detail?.primaryGenreName ? `分类:${detail.genres?.join(" / ") || detail.primaryGenreName}` : ""
219
- ].filter(Boolean).join("\n"),
220
- formatFootnote()
239
+ detail?.primaryGenreName ? `分类:${detail.genres?.join(" / ") || detail.primaryGenreName}` : "",
240
+ formatNote()
241
+ ].filter(Boolean).join("\n")
221
242
  ]);
222
243
  }
223
244
  return joinBlocks([
224
245
  item.icon ? import_koishi.h.image(item.icon) : "",
225
- `${item.name} iOS ${feedLabels[feedType]}:第 ${item.rank} 名`,
246
+ `${item.name}`,
226
247
  [
248
+ `排名:App Store ${config.country.toUpperCase()} ${feedLabels[feedType]} 第 ${item.rank} 名`,
227
249
  formatUpdatedAt(updated),
228
250
  `开发者:${item.artist}`,
229
- `分类:${item.category || "未知"}`
230
- ].join("\n"),
231
- formatFootnote()
251
+ `分类:${item.category || "未知"}`,
252
+ formatNote()
253
+ ].join("\n")
232
254
  ]);
233
255
  });
234
256
  ctx.command("ios对比 <games:text>", "对比多个游戏的 iOS 畅销榜排名").action(async ({ session }, games) => {
@@ -238,27 +260,34 @@ function apply(ctx, config) {
238
260
  const feed = await fetchRanks();
239
261
  const actualLimit = feed.actualLimit || feed.ranks.length;
240
262
  const details = await Promise.all(names.map(resolveAppDetail));
263
+ const grayIcons = await Promise.all(details.map((detail) => toGrayscaleIcon(detail?.artworkUrl100)));
241
264
  const results = names.map((game, index) => {
242
265
  const detail = details[index];
266
+ const grayIcon = grayIcons[index];
243
267
  const appId = detail?.trackId.toString() || config.aliases[game] || (/^\d+$/.test(game) ? game : void 0);
244
268
  if (!appId) return `${game}:未找到应用`;
245
269
  const item = feed.ranks.find((item2) => item2.appId === appId);
246
270
  if (!item) {
247
271
  return joinBlocks([
248
- detail?.artworkUrl100 ? import_koishi.h.image(detail.artworkUrl100) : "",
249
- `${detail?.trackName || game}:未进入畅销榜 Top ${actualLimit}`
272
+ grayIcon ? import_koishi.h.image(grayIcon) : "",
273
+ `${detail?.trackName || game}`,
274
+ `未进入畅销榜 Top ${actualLimit}`
250
275
  ]);
251
276
  }
252
277
  return joinBlocks([
253
278
  item.icon ? import_koishi.h.image(item.icon) : "",
254
- `${item.name}:第 ${item.rank} 名`
279
+ `${item.name}`,
280
+ `排名:第 ${item.rank} 名`
255
281
  ]);
256
282
  });
257
283
  return joinBlocks([
258
284
  `App Store ${config.country.toUpperCase()} 畅销榜对比`,
259
- formatUpdatedAt(feed.updated),
260
- results.join("\n\n"),
261
- formatFootnote()
285
+ [
286
+ formatUpdatedAt(feed.updated),
287
+ `榜单条数:${actualLimit}`,
288
+ formatNote()
289
+ ].join("\n"),
290
+ results.join("\n\n")
262
291
  ]);
263
292
  });
264
293
  ctx.command("ios搜索 <keyword:text>", "搜索 App Store 应用").action(async ({ session }, keyword) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-apple-rank",
3
3
  "description": "给二游痴看流水用的,数据来自苹果的rss",
4
- "version": "0.0.3",
4
+ "version": "0.0.4",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -14,6 +14,9 @@
14
14
  "koishi",
15
15
  "plugin"
16
16
  ],
17
+ "dependencies": {
18
+ "jimp": "^1.6.0"
19
+ },
17
20
  "peerDependencies": {
18
21
  "koishi": "^4.18.7"
19
22
  }