Skip to content

Commit 9c6ad07

Browse files
Merge branch 'master' into enh-27p
2 parents 4d94afe + e9547a5 commit 9c6ad07

File tree

14 files changed

+145
-45
lines changed

14 files changed

+145
-45
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ jobs:
3131
pnpm build
3232
- name: Test
3333
run: |
34-
pnpm test
34+
SKIP_NETWORK_TEST=true pnpm test

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
------------------
33
* センシティブフラグの判定を `<meta property="rating">` および `rating` ヘッダでも行うように
44
* レスポンスに`Cache-Control`ヘッダを含むように
5+
* Bluesky(bsky.app)のプレビューに対応
6+
* `fediverse:creator` のパースに対応
57
* 依存関係の更新
68
* eslintの設定を更新
79

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,16 @@ A Promise of an Object that contains properties below:
8585

8686
| Property | Type | Description |
8787
|:----------------|:-------------------|:-----------------------------------------------------------|
88-
| **title** | *string* \| *null* | The title of the web page |
89-
| **icon** | *string* \| *null* | The url of the icon of the web page |
90-
| **description** | *string* \| *null* | The description of the web page |
91-
| **thumbnail** | *string* \| *null* | The url of the thumbnail of the web page |
92-
| **sitename** | *string* \| *null* | The name of the web site |
93-
| **player** | *Player* | The player of the web page |
94-
| **sensitive** | *boolean* | Whether the url is sensitive |
95-
| **activityPub** | *string* \| *null* | The url of the ActivityPub representation of that web page |
96-
| **url** | *string* | The url of the web page |
88+
| **title** | *string* \| *null* | The title of the web page |
89+
| **icon** | *string* \| *null* | The url of the icon of the web page |
90+
| **description** | *string* \| *null* | The description of the web page |
91+
| **thumbnail** | *string* \| *null* | The url of the thumbnail of the web page |
92+
| **sitename** | *string* \| *null* | The name of the web site |
93+
| **player** | *Player* | The player of the web page |
94+
| **sensitive** | *boolean* | Whether the url is sensitive |
95+
| **activityPub** | *string* \| *null* | The url of the ActivityPub representation of that web page |
96+
| **fediverseCreator** | *string* \| *null* | The pages fediverse handle |
97+
| **url** | *string* | The url of the web page |
9798

9899
#### Summary
99100

src/general.ts

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,7 @@ export type GeneralScrapingOptions = {
138138
contentLengthRequired?: boolean;
139139
}
140140

141-
function headerEqualValueContains(search: string, headerValue: string | string[] | undefined) {
142-
if (!headerValue) {
143-
return false;
144-
}
145-
146-
if (Array.isArray(headerValue)) {
147-
return headerValue.some(value => value.toLowerCase() === search.toLowerCase());
148-
}
149-
150-
return headerValue.toLowerCase() === search.toLowerCase();
151-
}
152-
153-
export async function parseGeneral(_url: URL | string, opts?: GeneralScrapingOptions): Promise<Summary | null> {
141+
export async function general(_url: URL | string, opts?: GeneralScrapingOptions): Promise<Summary | null> {
154142
let lang = opts?.lang;
155143
if (lang && !lang.match(/^[\w-]+(\s*,\s*[\w-]+)*$/)) lang = null;
156144

@@ -164,6 +152,24 @@ export async function parseGeneral(_url: URL | string, opts?: GeneralScrapingOpt
164152
contentLengthLimit: opts?.contentLengthLimit,
165153
contentLengthRequired: opts?.contentLengthRequired,
166154
});
155+
156+
return await parseGeneral(url, res);
157+
}
158+
159+
function headerEqualValueContains(search: string, headerValue: string | string[] | undefined) {
160+
if (!headerValue) {
161+
return false;
162+
}
163+
164+
if (Array.isArray(headerValue)) {
165+
return headerValue.some(value => value.toLowerCase() === search.toLowerCase());
166+
}
167+
168+
return headerValue.toLowerCase() === search.toLowerCase();
169+
}
170+
171+
export async function parseGeneral(_url: URL | string, res: Awaited<ReturnType<typeof scpaping>>): Promise<Summary | null> {
172+
const url = typeof _url === 'string' ? new URL(_url) : _url;
167173
const $ = res.$;
168174
const twitterCard =
169175
$('meta[name="twitter:card"]').attr('content') ||
@@ -245,6 +251,9 @@ export async function parseGeneral(_url: URL | string, opts?: GeneralScrapingOpt
245251
const activityPub =
246252
$('link[rel="alternate"][type="application/activity+json"]').attr('href') || null;
247253

254+
const fediverseCreator: string | null =
255+
$('meta[name=\'fediverse:creator\']').attr('content') || null;
256+
248257
// https://developer.mixi.co.jp/connect/mixi_plugin/mixi_check/spec_mixi_check/#toc-18-
249258
const sensitive =
250259
$('meta[property=\'mixi:content-rating\']').attr('content') === '1' ||
@@ -293,5 +302,6 @@ export async function parseGeneral(_url: URL | string, opts?: GeneralScrapingOpt
293302
sitename: siteName || null,
294303
sensitive,
295304
activityPub,
305+
fediverseCreator,
296306
};
297307
}

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { got, type Agents as GotAgents } from 'got';
77
import type { FastifyInstance } from 'fastify';
88
import { SummalyResult } from '@/summary.js';
99
import { SummalyPlugin as _SummalyPlugin } from '@/iplugin.js';
10-
import { parseGeneral, type GeneralScrapingOptions } from '@/general.js';
10+
import { general, type GeneralScrapingOptions } from '@/general.js';
1111
import { DEFAULT_OPERATION_TIMEOUT, DEFAULT_RESPONSE_TIMEOUT, agent, setAgent } from '@/utils/got.js';
1212
import { plugins as builtinPlugins } from '@/plugins/index.js';
1313

@@ -125,7 +125,7 @@ export const summaly = async (url: string, options?: SummalyOptions): Promise<Su
125125
};
126126

127127
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
128-
const summary = await (match ? match.summarize : parseGeneral)(_url, scrapingOptions);
128+
const summary = await (match ? match.summarize : general)(_url, scrapingOptions);
129129

130130
if (summary == null) {
131131
throw new Error('failed summarize');

src/plugins/amazon.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ export async function summarize(url: URL): Promise<summary> {
5555
},
5656
sitename: 'Amazon',
5757
activityPub: null,
58+
fediverseCreator: null,
5859
};
5960
}

src/plugins/bluesky.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as cheerio from 'cheerio';
2+
import type Summary from '@/summary.js';
3+
import { getResponse, getGotOptions } from '@/utils/got.js';
4+
import { parseGeneral, type GeneralScrapingOptions } from '@/general.js';
5+
6+
export function test(url: URL): boolean {
7+
return url.hostname === 'bsky.app';
8+
}
9+
10+
export async function summarize(url: URL, opts?: GeneralScrapingOptions): Promise<Summary | null> {
11+
const args = getGotOptions(url.href, opts);
12+
13+
// HEADで取ると404が返るためGETのみで取得
14+
const res = await getResponse({
15+
...args,
16+
method: 'GET',
17+
});
18+
const body = res.body;
19+
const $ = cheerio.load(body);
20+
21+
return await parseGeneral(url, {
22+
body,
23+
$,
24+
response: res,
25+
});
26+
}

src/plugins/branchio-deeplinks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { parseGeneral, type GeneralScrapingOptions } from '@/general.js';
1+
import { general, type GeneralScrapingOptions } from '@/general.js';
22
import Summary from '@/summary.js';
33

44
export function test(url: URL): boolean {
@@ -12,5 +12,5 @@ export async function summarize(url: URL, opts?: GeneralScrapingOptions): Promis
1212
// Web版に強制リダイレクトすることでbranch.ioの独自ページが開くのを防ぐ
1313
url.searchParams.append('$web_only', 'true');
1414

15-
return await parseGeneral(url, opts);
15+
return await general(url, opts);
1616
}

src/plugins/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import * as amazon from './amazon.js';
2+
import * as bluesky from './bluesky.js';
23
import * as wikipedia from './wikipedia.js';
34
import * as branchIoDeeplinks from './branchio-deeplinks.js';
45
import { SummalyPlugin } from '@/iplugin.js';
56

67
export const plugins: SummalyPlugin[] = [
78
amazon,
9+
bluesky,
810
wikipedia,
911
branchIoDeeplinks,
1012
];

src/plugins/wikipedia.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ export async function summarize(url: URL): Promise<summary> {
4343
},
4444
sitename: 'Wikipedia',
4545
activityPub: null,
46+
fediverseCreator: null,
4647
};
4748
}

0 commit comments

Comments
 (0)