Skip to content

Commit

Permalink
Merge pull request #252 from maretol/add-capture-images
Browse files Browse the repository at this point in the history
Add capture images
  • Loading branch information
maretol authored Jan 12, 2025
2 parents 53a41ad + d759f8e commit e553d68
Show file tree
Hide file tree
Showing 12 changed files with 403 additions and 272 deletions.
4 changes: 2 additions & 2 deletions cms-data-fetcher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
"devDependencies": {
"typescript": "^5.7.2",
"@cloudflare/workers-types": "^4.20241230.0",
"@cloudflare/vitest-pool-workers": "^0.5.40",
"@cloudflare/vitest-pool-workers": "^0.5.41",
"vitest": "2.1.8",
"wrangler": "^3.99.0"
"wrangler": "^3.100.0"
},
"dependencies": {
"cheerio": "^1.0.0",
Expand Down
100 changes: 52 additions & 48 deletions cms-data-fetcher/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,41 @@ export function parse(content: string) {
}

function getPOption(text: string) {
let pOpt = 'normal'
if (isImage(text)) {
pOpt = 'image'
} else if (isPhoto(text)) {
pOpt = 'photo'
} else if (isComicPage(text)) {
pOpt = 'comic'
} else if (isYouTube(text)) {
pOpt = 'youtube'
} else if (isTwitter(text)) {
pOpt = 'twitter'
} else if (isAmazon(text)) {
pOpt = 'amazon'
} else if (isBlog(text)) {
pOpt = 'blog'
} else if (isArtifact(text)) {
pOpt = 'artifact'
} else if (isURL(text)) {
pOpt = 'url'
} else if (text === '') {
pOpt = 'empty'
} else if (isCommand(text)) {
pOpt = text.replaceAll('/', '')
// URLではない場合
if (!URL.canParse(text)) {
if (text === '') {
return 'empty'
} else if (isCommand(text)) {
return text.replaceAll('/', '')
}
return 'normal'
}

// URLの場合
const textURL = new URL(text)
if (isImage(textURL.hostname, text)) {
return 'image'
} else if (isPhoto(textURL.hostname, text)) {
return 'photo'
} else if (isComicPage(textURL.hostname, textURL.pathname)) {
return 'comic'
} else if (isYouTube(textURL.hostname)) {
return 'youtube'
} else if (isTwitter(textURL.hostname)) {
return 'twitter'
} else if (isAmazon(textURL.hostname)) {
return 'amazon'
} else if (isBlog(textURL.hostname, textURL.pathname)) {
return 'blog'
} else if (isArtifact(textURL.hostname, textURL.pathname)) {
return 'artifact'
} else {
return 'url'
}
return pOpt
}

function isImage(text: string) {
if (text.indexOf('https://r2.maretol.xyz/') === 0) {
function isImage(hostname: string, text: string) {
if (hostname === 'r2.maretol.xyz') {
const ext = text.split('.').pop() || ''
if (['jpg', 'jpeg', 'png', 'gif'].includes(ext)) {
return true
Expand All @@ -77,47 +83,43 @@ function isImage(text: string) {
}
}

function isPhoto(text: string) {
if (text.indexOf('https://photos.maretol.xyz') === 0) {
const photoURL = text.split('@@')[0] // 画像URL。@@以降はキャプション
function isPhoto(hostname: string, text: string) {
const photoDomain = ['photos.maretol.xyz', 'capture.maretol.xyz']
if (photoDomain.includes(hostname)) {
const photoURL = text.split('@@')[0] // 画像URL。@@以降はタイトルやキャプション
const ext = photoURL.split('.').pop() || ''
if (['jpg', 'jpeg', 'png', 'gif'].includes(ext)) {
return true
}
}
return
return false
}

function isComicPage(text: string) {
return text.indexOf('https://www.maretol.xyz/comics/') === 0 || text.indexOf('https://maretol.xyz/comics/') === 0
function isComicPage(hostname: string, pathname: string) {
const comicDomain = ['maretol.xyz', 'www.maretol.xyz']
return comicDomain.includes(hostname) && pathname.indexOf('/comics/') === 0
}

function isYouTube(text: string) {
return text.indexOf('https://youtu.be/') === 0 || text.indexOf('https://www.youtube.com/') === 0
function isYouTube(hostname: string) {
return ['youtu.be', 'www.youtube.com'].includes(hostname)
}

function isTwitter(text: string) {
return (
text.indexOf('https://twitter.com/') === 0 ||
text.indexOf('https://www.twitter.com/') === 0 ||
text.indexOf('https://x.com/') === 0
)
function isTwitter(hostname: string) {
return ['twitter.com', 'www.twitter.com', 'x.com'].includes(hostname)
}

function isAmazon(text: string) {
return text.indexOf('https://www.amazon.co.jp/') === 0 || text.indexOf('https://amzn.to/') === 0
function isAmazon(hostname: string) {
return ['www.amazon.co.jp', 'amzn.to'].includes(hostname)
}

// ブログ記事のリンクの場合
function isBlog(text: string) {
return text.indexOf('https://www.maretol.xyz/blog/') === 0 || text.indexOf('https://maretol.xyz/blog/') === 0
function isBlog(hostname: string, pathname: string) {
return ['maretol.xyz', 'www.maretol.xyz'].includes(hostname) && pathname.indexOf('/blog/') === 0
}

// artifactのリンクの場合
function isArtifact(text: string) {
return (
text.indexOf('https://www.maretol.xyz/artifacts/') === 0 || text.indexOf('https://maretol.xyz/artifacts/') === 0
)
function isArtifact(hostname: string, pathname: string) {
return ['maretol.xyz', 'www.maretol.xyz'].includes(hostname) && pathname.indexOf('/artifacts/') === 0
}

function isURL(text: string) {
Expand Down Expand Up @@ -150,3 +152,5 @@ function getSubText(text: string) {
}
return null
}

export { getPOption }
118 changes: 94 additions & 24 deletions cms-data-fetcher/test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,95 @@
// test/index.spec.ts
import { env, createExecutionContext, waitOnExecutionContext, SELF } from 'cloudflare:test';
import { describe, it, expect } from 'vitest';
import worker from '../src/index';
import { describe, it, expect } from 'vitest'
import { getPOption } from '../src/parse'

// For now, you'll need to do something like this to get a correctly-typed
// `Request` to pass to `worker.fetch()`.
const IncomingRequest = Request<unknown, IncomingRequestCfProperties>;

describe('Hello World worker', () => {
it('responds with Hello World! (unit style)', async () => {
const request = new IncomingRequest('http://example.com');
// Create an empty context to pass to `worker.fetch()`.
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
// Wait for all `Promise`s passed to `ctx.waitUntil()` to settle before running test assertions
await waitOnExecutionContext(ctx);
expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`);
});

it('responds with Hello World! (integration style)', async () => {
const response = await SELF.fetch('https://example.com');
expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`);
});
});
describe('parse_getPOptionのテスト', () => {
it('通常テキストの場合', () => {
const text = 'test text'
const result = getPOption(text)
expect(result).toBe('normal')
})
it('空文字の場合', () => {
const text = ''
const result = getPOption(text)
expect(result).toBe('empty')
})
it('画像の場合', () => {
const text = 'https://r2.maretol.xyz/test.png'
const result = getPOption(text)
expect(result).toBe('image')
})
it('写真の場合', () => {
const text = 'https://photos.maretol.xyz/test.jpg'
const result = getPOption(text)
expect(result).toBe('photo')
})
it('写真(スクリーンショット)の場合', () => {
const text = 'https://capture.maretol.xyz/test.jpg'
const result = getPOption(text)
expect(result).toBe('photo')
})
it('写真でサブテキストがあった場合', () => {
const text = 'https://photos.maretol.xyz/test.jpg@@subtext_key::subtext_value@@subtext::サブテキスト'
const result = getPOption(text)
expect(result).toBe('photo')
})
it('漫画リンクの場合', () => {
const text = 'https://www.maretol.xyz/comics/test'
const result = getPOption(text)
expect(result).toBe('comic')
})
it('YouTubeリンクの場合', () => {
const text = 'https://www.youtube.com/watch?v=test'
const result = getPOption(text)
expect(result).toBe('youtube')
})
it('Youtube短縮URLリンクの場合', () => {
const text = 'https://youtu.be/test'
const result = getPOption(text)
expect(result).toBe('youtube')
})
it('Twitterリンクの場合', () => {
const text = 'https://twitter.com/test'
const result = getPOption(text)
expect(result).toBe('twitter')
})
it('Twitterリンク(wwwあり)の場合', () => {
const text = 'https://www.twitter.com/test'
const result = getPOption(text)
expect(result).toBe('twitter')
})
it('Xリンクの場合', () => {
const text = 'https://x.com/test'
const result = getPOption(text)
expect(result).toBe('twitter')
})
it('Amazonリンクの場合', () => {
const text = 'https://www.amazon.co.jp/test'
const result = getPOption(text)
expect(result).toBe('amazon')
})
it('Amazon短縮URLリンクの場合', () => {
const text = 'https://amzn.to/test'
const result = getPOption(text)
expect(result).toBe('amazon')
})
it('ブログリンクの場合', () => {
const text = 'https://www.maretol.xyz/blog/test'
const result = getPOption(text)
expect(result).toBe('blog')
})
it('artifactリンクの場合', () => {
const text = 'https://www.maretol.xyz/artifacts/test'
const result = getPOption(text)
expect(result).toBe('artifact')
})
it('その他のURLの場合', () => {
const text = 'https://example.com'
const result = getPOption(text)
expect(result).toBe('url')
})
it('コマンド入力の場合', () => {
const text = '/test_command'
const result = getPOption(text)
expect(result).toBe('test_command')
})
})
4 changes: 2 additions & 2 deletions ogp-data-fetcher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
"cf-typegen": "wrangler types"
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "^0.5.40",
"@cloudflare/vitest-pool-workers": "^0.5.41",
"@cloudflare/workers-types": "^4.20241230.0",
"typescript": "^5.7.2",
"vitest": "2.1.8",
"wrangler": "^3.99.0"
"wrangler": "^3.100.0"
},
"dependencies": {
"open-graph-scraper-lite": "^2.1.0"
Expand Down
Loading

0 comments on commit e553d68

Please sign in to comment.