package scheduler import ( "context" "github.com/Fuwn/asa-news/internal/fetcher" "github.com/Fuwn/asa-news/internal/model" "github.com/Fuwn/asa-news/internal/parser" "github.com/Fuwn/asa-news/internal/webhook" "github.com/Fuwn/asa-news/internal/writer" "log/slog" ) func ProcessRefreshRequest( refreshContext context.Context, feed model.Feed, feedFetcher *fetcher.Fetcher, feedParser *parser.Parser, feedWriter *writer.Writer, webhookDispatcher *webhook.Dispatcher, logger *slog.Logger, ) { logger.Info( "processing feed refresh", "feed_identifier", feed.Identifier, "feed_url", feed.URL, ) var ownerIdentifier *string authenticationConfig := fetcher.AuthenticationConfiguration{} if feed.Visibility == "authenticated" { if feed.AuthenticationType == nil || feed.AuthenticationValue == nil { logger.Warn( "authenticated feed missing credentials, skipping", "feed_identifier", feed.Identifier, ) return } authenticationConfig = fetcher.AuthenticationConfiguration{ AuthenticationType: *feed.AuthenticationType, AuthenticationValue: *feed.AuthenticationValue, } ownerIdentifier = feed.SubscriberUserIdentifier } entityTag := "" if feed.EntityTag != nil { entityTag = *feed.EntityTag } lastModified := "" if feed.LastModified != nil { lastModified = *feed.LastModified } fetchResult, fetchError := feedFetcher.Fetch( refreshContext, feed.URL, entityTag, lastModified, authenticationConfig, ) if fetchError != nil { logger.Warn( "feed fetch failed", "feed_identifier", feed.Identifier, "error", fetchError, ) recordError := feedWriter.RecordFeedError(refreshContext, feed.Identifier, fetchError.Error()) if recordError != nil { logger.Error( "failed to record feed error", "feed_identifier", feed.Identifier, "error", recordError, ) } return } if fetchResult.NotModified { logger.Info( "feed not modified", "feed_identifier", feed.Identifier, ) metadataError := feedWriter.UpdateFeedMetadata( refreshContext, feed.Identifier, fetchResult.EntityTag, fetchResult.LastModifiedHeader, "", "", ) if metadataError != nil { logger.Error( "failed to update feed metadata after not-modified", "feed_identifier", feed.Identifier, "error", metadataError, ) } return } parseResult, parseError := feedParser.Parse(feed.Identifier, ownerIdentifier, fetchResult.Body) if parseError != nil { logger.Warn( "feed parse failed", "feed_identifier", feed.Identifier, "error", parseError, ) recordError := feedWriter.RecordFeedError(refreshContext, feed.Identifier, parseError.Error()) if recordError != nil { logger.Error( "failed to record parse error", "feed_identifier", feed.Identifier, "error", recordError, ) } return } rowsAffected, writeError := feedWriter.WriteEntries(refreshContext, parseResult.Entries) if writeError != nil { logger.Error( "failed to write feed entries", "feed_identifier", feed.Identifier, "error", writeError, ) recordError := feedWriter.RecordFeedError(refreshContext, feed.Identifier, writeError.Error()) if recordError != nil { logger.Error( "failed to record write error", "feed_identifier", feed.Identifier, "error", recordError, ) } return } if rowsAffected > 0 && webhookDispatcher != nil { webhookDispatcher.DispatchForFeed(refreshContext, feed.Identifier, parseResult.Entries) } metadataError := feedWriter.UpdateFeedMetadata( refreshContext, feed.Identifier, fetchResult.EntityTag, fetchResult.LastModifiedHeader, parseResult.FeedTitle, parseResult.SiteURL, ) if metadataError != nil { logger.Error( "failed to update feed metadata", "feed_identifier", feed.Identifier, "error", metadataError, ) } if parseResult.AudioEnclosureRatio > 0.5 { if feedTypeError := feedWriter.UpdateFeedType(refreshContext, feed.Identifier, "podcast"); feedTypeError != nil { logger.Error( "failed to update feed type to podcast", "feed_identifier", feed.Identifier, "error", feedTypeError, ) } } else if feed.FeedType != nil && *feed.FeedType == "podcast" { if feedTypeError := feedWriter.UpdateFeedType(refreshContext, feed.Identifier, "rss"); feedTypeError != nil { logger.Error( "failed to clear podcast feed type", "feed_identifier", feed.Identifier, "error", feedTypeError, ) } } logger.Info( "feed refresh completed", "feed_identifier", feed.Identifier, "entries_parsed", len(parseResult.Entries), "rows_affected", rowsAffected, ) }