-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add * implement card link * style: $ bun run format * update bun.lockb * update date * refine fetching script * collapse descriptions * add mergin to cardlink * linkize * adjust style * remove invalid og image * adjust for mobile * いつまでセールやってるかわからないので消す --------- Co-authored-by: fohte-bot[bot] <139195068+fohte-bot[bot]@users.noreply.github.com>
- Loading branch information
1 parent
b7524e2
commit ed68174
Showing
7 changed files
with
332 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { promises as fs } from 'fs' | ||
import { JSDOM } from 'jsdom' | ||
|
||
const files = await fs.readdir('./src/contents/posts') | ||
|
||
const urls = ( | ||
await Promise.all( | ||
files.map(async (file) => { | ||
// extract urls from CardLink components | ||
const content = await fs.readFile(`./src/contents/posts/${file}`, 'utf-8') | ||
|
||
const regex = /<CardLink href="(.+)"/g | ||
const matches = content.matchAll(regex) | ||
|
||
return Array.from(matches, (match) => match[1]) | ||
}), | ||
) | ||
).flat() | ||
|
||
console.log(urls) | ||
|
||
type Data = { | ||
[url: string]: { | ||
title?: string | null | ||
description?: string | null | ||
image?: string | null | ||
} | ||
} | ||
|
||
const fetchOgp = async (url: string): Promise<Data[string]> => { | ||
const res = await fetch(url) | ||
const html = await res.text() | ||
const dom = new JSDOM(html) | ||
|
||
const data = { | ||
title: dom.window.document | ||
.querySelector('meta[property="og:title"]') | ||
?.getAttribute('content'), | ||
description: dom.window.document | ||
.querySelector('meta[property="og:description"]') | ||
?.getAttribute('content'), | ||
image: dom.window.document | ||
.querySelector('meta[property="og:image"]') | ||
?.getAttribute('content'), | ||
} | ||
|
||
if (data.title == null) { | ||
data.title = dom.window.document.querySelector('title')?.textContent | ||
} | ||
|
||
if (data.image == null) { | ||
// if amazon | ||
if (res.url.startsWith('https://www.amazon.co.jp/')) { | ||
const asin = res.url.match(/dp\/(\w+)/)?.[1] | ||
if (asin == null) { | ||
throw new Error(`ASIN not found: ${res.url}`) | ||
} | ||
|
||
data.image = `https://images.amazon.com/images/P/${asin}.09_SL110_.jpg` | ||
} else { | ||
// favicon | ||
data.image = dom.window.document | ||
.querySelector('link[rel="icon"]') | ||
?.getAttribute('href') | ||
} | ||
} | ||
|
||
return data | ||
} | ||
|
||
const json: Data = JSON.parse(await fs.readFile('./src/data/ogp.json', 'utf-8')) | ||
|
||
for (const url of urls) { | ||
if (json[url] != null) { | ||
continue | ||
} | ||
|
||
console.log(`fetching ${url}...`) | ||
const data = await fetchOgp(url) | ||
|
||
json[url] = data | ||
fs.writeFile('./src/data/ogp.json', JSON.stringify(json, null, 2) + '\n') | ||
|
||
console.log(`fetched ${url}`) | ||
|
||
// sleep | ||
await new Promise((resolve) => setTimeout(resolve, 1000)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
'use client' | ||
|
||
import { Box, Image, Text } from '@chakra-ui/react' | ||
|
||
import { type LinkProps } from '@/components/Link' | ||
import ogpData from '@/data/ogp.json' | ||
|
||
export interface Props extends LinkProps { | ||
href: string | ||
} | ||
|
||
type OgpData = { | ||
[url: string]: { | ||
title?: string | null | ||
description?: string | null | ||
image?: string | null | ||
} | ||
} | ||
|
||
const collapseDescription = (description: string): string => { | ||
const maxLength = 80 | ||
|
||
const newDescription = description.substring(0, maxLength) | ||
if (description !== newDescription) { | ||
return `${newDescription}…` | ||
} | ||
return newDescription | ||
} | ||
|
||
export const CardLink: React.FC<Props> = ({ href }) => { | ||
const ogp = (ogpData as OgpData)[href] | ||
|
||
if (ogp == null) { | ||
throw new Error(`OGP not found: ${href}`) | ||
} | ||
|
||
const domain = new URL(href).hostname | ||
|
||
return ( | ||
<Box | ||
as="a" | ||
href={href} | ||
borderWidth="1px" | ||
borderColor="gray.200" | ||
rounded="md" | ||
overflow="hidden" | ||
textDecoration="none" | ||
display="flex" | ||
alignItems="center" | ||
justifyContent="center" | ||
my={4} | ||
py={4} | ||
px={4} | ||
gap={6} | ||
> | ||
{ogp.image && ( | ||
<Image | ||
src={ogp.image} | ||
alt="Link preview image" | ||
height="100%" | ||
maxW="min(40%, 250px)" | ||
maxH="200px" | ||
objectFit="cover" | ||
/> | ||
)} | ||
<Box flex="1"> | ||
<Text fontSize="md" fontWeight="bold"> | ||
{ogp.title} | ||
</Text> | ||
<Text fontSize="sm" color="gray.600"> | ||
{domain} | ||
</Text> | ||
{ogp.description && ( | ||
<Text fontSize="xs" color="gray.600" mt={1}> | ||
{collapseDescription(ogp.description)} | ||
</Text> | ||
)} | ||
</Box> | ||
</Box> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
--- | ||
title: '2024 年 5 月 振り返り' | ||
date: '2024-06-07T00:45:54+09:00' | ||
--- | ||
|
||
5 月は充実した一月だった。せっかくだし記録に残しておきたいので、もう 6 月に入って一週間が経とうとしているが、一ヶ月間を振り返ってみる。 | ||
|
||
## ゴールデンウィーク | ||
|
||
今年は 10 連休にした。もはや年末年始休暇よりも長いし、暇を持て余していた。 | ||
たまの長期休暇だしめちゃくちゃ生産的な活動をしようと試みていたが、実際は家から出ずにゲームしかしていなかった。 | ||
ワーケーション的なことをやろうとしたが、思い立ったのは GW 一週間前あたりで、良さげな宿がなく断念した。次の長期休暇は前もって行動したい。 | ||
とはいえゲーム三昧はそれはそれで楽しかったので特に後悔はしてない。なんならもっとゲームしたい。 | ||
|
||
## 登壇 | ||
|
||
ここ最近は登壇意欲が高いが、5 月はさらに増していろいろやっていた。 | ||
|
||
- 司会 @ [【初心者歓迎】登壇者と攻略するRubyKaigi 2024【プロも歓迎】 - connpass](https://smartbank.connpass.com/event/313812/) | ||
- [The Journey of rubocop-daemon into RuboCop - Speaker Deck](https://speakerdeck.com/fohte/the-journey-of-rubocop-daemon-into-rubocop) @ [LT - RubyKaigi 2024](https://rubykaigi.org/2024/presentations/lt/) | ||
- [Datadog Logs を活用して SLO 監視基盤を構築する - Speaker Deck](https://speakerdeck.com/fohte/datadog-logs-wohuo-yong-site-slo-jian-shi-ji-pan-wogou-zhu-suru) @ [Japan Datadog User Group Meetup#4 - connpass](https://datadog-jp.connpass.com/event/317091/) | ||
- [RubyKaigi で LT 初登壇したきっかけと感想 - Speaker Deck](https://speakerdeck.com/fohte/rubykaigi-te-lt-chu-deng-tan-sitakitukaketogan-xiang) @ [RubyKaigi 2024事後勉強会 - connpass](https://smarthr.connpass.com/event/319010/) | ||
|
||
今月だけでなく今年は頻繁に登壇していることもあり、だいぶ登壇慣れしてきた。 | ||
|
||
登壇のモチベーションやメリットは RubyKaigi 2024 事後勉強会でも話したが、コミュニティに認知してもらえることや自分の発信に対するフィードバックがもらえることが特に嬉しいしありがたい。一連の rubocop-daemon 関連の発表では多くの人に共感してもらえたと思っているし、直近業務で難産だった Datadog Logs 活用の話では同じことをやられていた方から共感してもらえたり、新たなアイデアをもらえたりした。 | ||
|
||
また、RubyKaigi で参加だけでなく LT までできたことはとても光栄に感じている。あの大規模な会場で話せたことは自信に繋がった。貴重な経験になった。次回も発表したいし KaigiEffect でなんらかをやっていきたい。 | ||
|
||
## ゲーム | ||
|
||
### モンスターハンターライズ: サンブレイク | ||
|
||
<CardLink href="https://store.steampowered.com/app/1446780/MONSTER_HUNTER_RISE/?l=japanese" /> | ||
|
||
GW でセールをしていたので、友人を誘ってやり始めた。今もまだやっていて、MR 80 くらいまで進んだ。 | ||
|
||
モンハンは PS4 でプレーしたワールドぶりなのでかなり久々感がある。 | ||
ライズははじめ Switch でリリースされていたこともあり、さすがにグラフィックやフレームレート的に厳しいと感じてプレーしていなかったのだが、Steam 版がリリースされて気になっていた。 | ||
いまは UWQHD 144 fps でプレーしていてとても満足している。ヌルヌルサクサクだしグラフィックも感嘆するほど。 | ||
|
||
アクション性が特に満足度高い。翔虫がとにかく良くて、これ無しのモンハンにはもう戻れない。移動が縦にも横にも快適になるし、鉄蟲糸技 (翔虫を使った攻撃技) も回避しながら攻撃できたりして楽しい。 | ||
|
||
武器は弓を使っている。弓は見た目もいいし使用感も良く気に入っている。過去作ではハンマーメインで弓がサブだったけど、ライズでは弓しか使っていない。 | ||
今作は弓が強い (らしい) というのもあるが、入れ替え技の身躱し矢斬りが火力を出しつつ回避の楽しさもあって特に面白い。以前は回避ランサーも好きだった [^1] し、それと似たような楽しさがある。 | ||
スキルで狂化奮闘が出てからは特に強くて楽しい。無限スタミナだし、ワンパン乙みたいなこともなくなってとにかく快適。無限に身躱し矢斬りで攻撃しながら回避しつつ溜め 4 剛射を打ち続けられて、火力は出るし回避はいつでもできるし操作感が著しく改善された。スタミナ無限じゃないモンハンにはもう戻れない。 | ||
|
||
[^1]: MHF でベルキュロス相手に極長ランスで回避しながら突くのめちゃくちゃ楽しかったし、またやりたい。 | ||
|
||
そんな感じで、失った少年の心を取り戻すかの勢いでかなりハマっている。対人でもないからストレスが溜まらないのも良いポイント。 | ||
|
||
### Sixtar Gate: STARTRAIL | ||
|
||
<CardLink href="https://store.steampowered.com/app/1802720/_/?l=japanese" /> | ||
|
||
上から降ってくるタイプの音ゲー。BEMANI 機種でいうと SDVX が一番近い。ツマミがなく、白鍵盤が 5 つある SDVX。 | ||
|
||
beatmania IIDX をやらなくなって久しいが、音ゲーはたまにやりたくなるので、最近はよくこれをやっている。家でぱっとできてかつ IIDX をある程度やっていた人でも楽しめるくらいの難易度の音ゲーとしてちょうど良い。 | ||
|
||
かわいらしいデザインとは裏腹に音ゲーマーでもしっかりと楽しめるちゃんとした音ゲーなので、ぜひやってほしい。 | ||
サウンドディレクターと譜面デザイナーが Sound Souler 氏なので、分かる人には音ゲーとしてちゃんとしていることが分かると思う。曲も某イベントの上位曲が入っていたり、譜面も最高難易度はしっかり難しくて、ちゃんと音ゲーしてる。 | ||
|
||
目指せ全 PB (無理)。まずは全 SS から。いまは難易度 17 の SS に苦戦しているところで、S で精一杯。 | ||
|
||
### Antimatter Dimensions | ||
|
||
<CardLink href="https://store.steampowered.com/app/1399720/Antimatter_Dimensions/" /> | ||
|
||
[人生で最も時間を破壊された放置ゲー|zubu](https://note.com/zubububu/n/n62602227c1cc) を読んで軽い気持ちで始めてみたらめちゃくちゃ時間を溶かしてしまっている放置ゲー。 | ||
Cookie Clicker に 10 倍くらい「数を増やす」要素を付け足したゲーム。1e100 とかそういうレベルではなく 1e1e9 とかになるくらい桁が無尽蔵に増えていく。 | ||
Cookie Clicker にハマった人にはおすすめしたいゲーム。放置ゲーとはいいつつ適度にクリックする必要があり、時間は溶けるので注意。 | ||
|
||
いまは Reality を解禁して 1e40 RM くらい。Reality は後から大型アップデートとして追加されただけあって、頻繁に新しい要素が追加されていくのが難しくもあり面白い。とりあえずクリア (クリアという概念はあるんだろうか) まではやりたい。 | ||
|
||
### Vampire Survivors | ||
|
||
<CardLink href="https://store.steampowered.com/app/1794680/Vampire_Survivors/?l=japanese" /> | ||
|
||
無双ゲー。2 年前くらいに流行っていたので知っている人も多そう。 | ||
|
||
その流行っていた 2 年前にもプレーしていたのだが、最近また手を出してみたら要素が 2 年前の 10 倍くらい増えていた。死神を倒すために作られたような進化武器が追加されていたりする。 | ||
|
||
なぜ今になってまたハマったかというと、Antimatter Dimensions で実績を解除していくのが楽しくて Steam 実績を集めるのが趣味になってしまったから。Vampire Survivors は 1 ゲームで 1 実績解除くらいできるので楽しい。本来の楽しみ方とは違うけど、実績解除ゲーとして楽しんでいる。 | ||
|
||
## 映画 | ||
|
||
### デッドデッドデーモンズデデデデデストラクション | ||
|
||
<Mastodon url="https://social.fohte.net/@fohte/112500420724317611" /> | ||
|
||
前編後編見た。漫画を全巻読破して感慨深い気持ちになっていたときに、ちょうど映画が上映されていることを知ったので見に行った。 | ||
|
||
映画は漫画版が忠実に映像化されているという印象でとても良かった。特に音の臨場感が良く、漫画では味わえない壮大さを感じられた。 | ||
|
||
ポストアポカリプス系の物語が好きなので、デデデデも例に漏れず刺さった。浅野いにおさんの作品はデデデデが初めてで、漫画の 1, 2 巻あたりはハイテンションについていけずなんだこれとなっていたが、読み進めていくとどんどん深みが出て面白くなった。ネタバレになるので書くことが限られるのだが、絶望的な展開が晴れていくような物語が好きな人にはおすすめ。 | ||
|
||
## 漫画 | ||
|
||
### それでも町は廻っている | ||
|
||
<CardLink href="https://amzn.to/3V4nwxq" /> | ||
|
||
同じ作者の『[天国大魔境](https://amzn.to/4e6XW3r)』がとにかく面白く、同じ作者であれば絶対に面白いだろうと信じて読んだらやはり期待通りとても面白かった。 | ||
『天国大魔境』はポストアポカリプス系でくすっと笑えるコメディ要素が入った漫画なのだが、この作品はコメディ全振りでよかった。ギャグのテンポが早くて心地よいし、シュールな笑いが持続する感じがとてもよい。 | ||
読破してしまったけど、無限に続いてほしい作品だった。 | ||
|
||
### おやすみプンプン | ||
|
||
<CardLink href="https://amzn.to/3Vf9Z62" /> | ||
|
||
デデデデの作者である浅野いにおさんの漫画。これはポストアポカリプス系ではなく、デデデデに似た謎のテンションで始まり話が進むにつれて深みが出てくるタイプの作品だった。 | ||
救いのない鬱展開だったが面白く読めた。個人的に好きな展開としては鬱展開から這い上がっていく物語が好きなのだが、この作品は這い上がらずにそのまま鬱展開のまま進んでいくのがなかなか味わえない良い意味での気味悪さがあった。 | ||
|
||
結局最後まで訳が分からない部分もあったのだが、以下の考察記事を読んでかなり納得感があった。読破した人は読んでほしい。 | ||
|
||
<CardLink href="https://gumichoko.hatenablog.com/entry/2019/07/26/230937" /> | ||
|
||
## 最後に | ||
|
||
ブログは書きたいけど適切な粒度が見つからない、見つかっても書くハードルが高いなと思っていたので、月次振り返りはちょうどいいかもしれない。来月は今月分も振り返っていきたい。 | ||
その振り返るためのネタができるくらいには人生をやっていきたい所存。KaigiEffect もやっていきたい。 |
Oops, something went wrong.