@@ -4,12 +4,13 @@ import chalk from "chalk";
44import { rm } from "fs/promises" ;
55
66import type { ChannelOptions , SubscriptionSettings } from "./types.js" ;
7- import type { ContentPost , VideoContent } from "floatplane/content" ;
7+ import type { ContentPost } from "floatplane/content" ;
88import type { BlogPost } from "floatplane/creator" ;
99
1010import { Video } from "./Video.js" ;
1111
1212import { settings } from "./helpers.js" ;
13+ import { ItemCache } from "./Caches.js" ;
1314
1415const removeRepeatedSentences = ( postTitle : string , attachmentTitle : string ) => {
1516 const separators = / (?: \s + | ^ ) ( (?: [ ^ . , ; : ! ? - ] + [ \s ] * [ . , ; : ! ? - ] + ) + ) (?: \s + | $ ) / g;
@@ -24,16 +25,29 @@ const removeRepeatedSentences = (postTitle: string, attachmentTitle: string) =>
2425 return `${ postTitle . trim ( ) } - ${ uniqueAttachmentTitleSentences . join ( "" ) . trim ( ) } ` . trim ( ) . replace ( / [ \s ] * [ . , ; : ! ? - ] + [ \s ] * $ / , "" ) ;
2526} ;
2627
27- const t24Hrs = 24 * 60 * 60 * 1000 ;
28-
28+ type BlogPosts = typeof fApi . creator . blogPostsIterable ;
2929export default class Subscription {
3030 public channels : SubscriptionSettings [ "channels" ] ;
3131
3232 public readonly creatorId : string ;
3333
34+ private static AttachmentsCache = new ItemCache ( "./db/attachmentCache.json" , fApi . content . video , 24 * 60 ) ;
35+
36+ private static PostCache = new ItemCache ( "./db/postCache.json" , fApi . creator . blogPosts , 60 ) ;
37+ private static async * PostIterable ( creatorGUID : Parameters < BlogPosts > [ "0" ] , options : Parameters < BlogPosts > [ "1" ] ) : ReturnType < BlogPosts > {
38+ let fetchAfter = 0 ;
39+ // First request should always not hit cache incase looking for new videos
40+ let blogPosts = await Subscription . PostCache . get ( creatorGUID , { ...options , fetchAfter } , true ) ;
41+ while ( blogPosts . length > 0 ) {
42+ yield * blogPosts ;
43+ fetchAfter += 20 ;
44+ // After that use the cached data
45+ blogPosts = await Subscription . PostCache . get ( creatorGUID , { ...options , fetchAfter } ) ;
46+ }
47+ }
48+
3449 constructor ( subscription : SubscriptionSettings ) {
3550 this . creatorId = subscription . creatorId ;
36-
3751 this . channels = subscription . channels ;
3852 }
3953
@@ -67,22 +81,6 @@ export default class Subscription {
6781
6882 private static getIgnoreBeforeTimestamp = ( channel : ChannelOptions ) => Date . now ( ) - ( channel . daysToKeepVideos ?? 0 ) * 24 * 60 * 60 * 1000 ;
6983
70- private static attachmentCache = new Map < string , { t : number ; attachment : VideoContent } > ( ) ;
71- private static fetchAttachment = async ( attachmentId : string ) : Promise < VideoContent > => {
72- if ( Subscription . attachmentCache . has ( attachmentId ) ) {
73- const { attachment, t } = Subscription . attachmentCache . get ( attachmentId ) ! ;
74- // Remove expired entries older than 24hrs
75- if ( Date . now ( ) - t > t24Hrs ) {
76- Subscription . attachmentCache . delete ( attachmentId ) ;
77- return Subscription . fetchAttachment ( attachmentId ) ;
78- }
79- return attachment ;
80- }
81- const attachment = await fApi . content . video ( attachmentId ) ;
82- Subscription . attachmentCache . set ( attachmentId , { t : Date . now ( ) , attachment } ) ;
83- return attachment ;
84- } ;
85-
8684 private async * matchChannel ( blogPost : BlogPost ) : AsyncGenerator < Video > {
8785 if ( blogPost . videoAttachments === undefined ) return ;
8886 let dateOffset = 0 ;
@@ -91,7 +89,7 @@ export default class Subscription {
9189 const post = { ...blogPost } ;
9290 if ( blogPost . videoAttachments . length > 1 ) {
9391 dateOffset ++ ;
94- const { title : attachmentTitle } = await Subscription . fetchAttachment ( attachment ) ;
92+ const { title : attachmentTitle } = await Subscription . AttachmentsCache . get ( attachment ) ;
9593 post . title = removeRepeatedSentences ( post . title , attachmentTitle ) ;
9694 }
9795
@@ -168,7 +166,7 @@ export default class Subscription {
168166 public async * fetchNewVideos ( ) : AsyncGenerator < Video > {
169167 if ( settings . floatplane . videosToSearch === 0 ) return ;
170168 let videosSearched = 0 ;
171- for await ( const blogPost of fApi . creator . blogPostsIterable ( this . creatorId , { hasVideo : true } ) ) {
169+ for await ( const blogPost of Subscription . PostIterable ( this . creatorId , { hasVideo : true } ) ) {
172170 for await ( const video of this . matchChannel ( blogPost ) ) {
173171 if ( ( await video . getState ( ) ) !== Video . State . Muxed ) yield video ;
174172 }
0 commit comments