@@ -3,40 +3,52 @@ import { logger } from './logger';
33import { imageCacheOptions } from '../../common/eleventy-cache-option' ;
44import { to } from 'await-to-js' ;
55import { CustomRssParserFeed , CustomRssParserItem , OgObjectMap } from './feed-crawler' ;
6- import EleventyFetch from '@11ty/eleventy-fetch' ;
6+ import EleventyImage from '@11ty/eleventy-img' ;
7+ import constants from '../../common/constants' ;
8+
9+ const THUMBNAIL_OUTPUT_DIR = 'public/images/feed-thumbnails' ;
10+ const THUMBNAIL_URL_PATH = `${ constants . siteUrlStem } /images/feed-thumbnails/` ;
11+
12+ export type ThumbnailUrlMap = Map < string , string > ;
713
814export class ImagePrecacher {
915 public async fetchAndCacheFeedImages (
1016 feeds : CustomRssParserFeed [ ] ,
1117 feedItems : CustomRssParserItem [ ] ,
1218 ogObjectMap : OgObjectMap ,
1319 concurrency : number ,
14- ) : Promise < void > {
20+ ) : Promise < ThumbnailUrlMap > {
21+ const thumbnailUrlMap : ThumbnailUrlMap = new Map ( ) ;
1522 let ogImageUrls : string [ ] = [ ] ;
1623
1724 for ( const feed of feeds ) {
18- ogImageUrls . push ( ogObjectMap . get ( feed . link ) ?. customOgImage ?. url || '' ) ;
25+ const url = ogObjectMap . get ( feed . link ) ?. customOgImage ?. url ;
26+ if ( url ) ogImageUrls . push ( url ) ;
1927 }
2028
2129 for ( const feedItem of feedItems ) {
22- ogImageUrls . push ( ogObjectMap . get ( feedItem . link ) ?. customOgImage ?. url || '' ) ;
30+ const url = ogObjectMap . get ( feedItem . link ) ?. customOgImage ?. url ;
31+ if ( url ) ogImageUrls . push ( url ) ;
2332 }
2433
25- // フィルタ
26- ogImageUrls = ogImageUrls . filter ( Boolean ) ;
34+ // 重複排除
35+ ogImageUrls = [ ... new Set ( ogImageUrls ) ] ;
2736
28- // 画像取得
2937 const ogImageUrlsLength = ogImageUrls . length ;
3038 let fetchProcessCounter = 1 ;
3139
3240 await PromisePool . for ( ogImageUrls )
3341 . withConcurrency ( concurrency )
3442 . process ( async ( ogImageUrl ) => {
35- const [ error ] = await to (
36- EleventyFetch ( ogImageUrl , {
37- type : 'buffer' ,
38- duration : imageCacheOptions . duration ,
39- concurrency,
43+ const [ error , metadata ] = await to < EleventyImage . Metadata > (
44+ EleventyImage ( ogImageUrl , {
45+ widths : [ 150 , 450 ] ,
46+ formats : [ 'webp' , 'jpeg' ] ,
47+ outputDir : THUMBNAIL_OUTPUT_DIR ,
48+ urlPath : THUMBNAIL_URL_PATH ,
49+ cacheOptions : imageCacheOptions ,
50+ sharpWebpOptions : { quality : 50 } ,
51+ sharpJpegOptions : { quality : 70 } ,
4052 } ) ,
4153 ) ;
4254 if ( error ) {
@@ -45,9 +57,17 @@ export class ImagePrecacher {
4557 return ;
4658 }
4759
60+ // 最大サイズのjpegをfeed用サムネイルURLとして登録
61+ const jpegImages = metadata . jpeg ;
62+ const largestJpeg = jpegImages ?. [ jpegImages . length - 1 ] ;
63+ if ( largestJpeg ?. url ) {
64+ thumbnailUrlMap . set ( ogImageUrl , largestJpeg . url ) ;
65+ }
4866 logger . info ( '[cache-og-image] fetched' , `${ fetchProcessCounter ++ } /${ ogImageUrlsLength } ` , ogImageUrl ) ;
4967 } ) ;
5068
5169 logger . info ( '[cache-og-image] finished' ) ;
70+
71+ return thumbnailUrlMap ;
5272 }
5373}
0 commit comments