reading_time.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package processor // import "miniflux.app/v2/internal/reader/processor"
  4. import (
  5. "log/slog"
  6. "miniflux.app/v2/internal/model"
  7. "miniflux.app/v2/internal/reader/readingtime"
  8. "miniflux.app/v2/internal/storage"
  9. )
  10. func updateEntryReadingTime(store *storage.Storage, feed *model.Feed, entry *model.Entry, entryIsNew bool, user *model.User) {
  11. if !user.ShowReadingTime {
  12. slog.Debug("Skip reading time estimation for this user", slog.Int64("user_id", user.ID))
  13. return
  14. }
  15. // Define watch time fetching scenarios
  16. watchTimeScenarios := []struct {
  17. shouldFetch func(*model.Entry) bool
  18. fetchFunc func(string) (int, error)
  19. platform string
  20. }{
  21. {shouldFetchYouTubeWatchTimeForSingleEntry, fetchYouTubeWatchTimeForSingleEntry, "YouTube"},
  22. {shouldFetchNebulaWatchTime, fetchNebulaWatchTime, "Nebula"},
  23. {shouldFetchOdyseeWatchTime, fetchOdyseeWatchTime, "Odysee"},
  24. {shouldFetchBilibiliWatchTime, fetchBilibiliWatchTime, "Bilibili"},
  25. }
  26. // Iterate through scenarios and attempt to fetch watch time
  27. for _, scenario := range watchTimeScenarios {
  28. if scenario.shouldFetch(entry) {
  29. if entryIsNew {
  30. if watchTime, err := scenario.fetchFunc(entry.URL); err != nil {
  31. slog.Warn("Unable to fetch watch time",
  32. slog.String("platform", scenario.platform),
  33. slog.Int64("user_id", user.ID),
  34. slog.Int64("entry_id", entry.ID),
  35. slog.String("entry_url", entry.URL),
  36. slog.Int64("feed_id", feed.ID),
  37. slog.String("feed_url", feed.FeedURL),
  38. slog.Any("error", err),
  39. )
  40. } else {
  41. entry.ReadingTime = watchTime
  42. }
  43. } else {
  44. entry.ReadingTime = store.GetReadTime(feed.ID, entry.Hash)
  45. }
  46. break
  47. }
  48. }
  49. // Fallback to text-based reading time estimation
  50. if entry.ReadingTime == 0 && entry.Content != "" {
  51. entry.ReadingTime = readingtime.EstimateReadingTime(entry.Content, user.DefaultReadingSpeed, user.CJKReadingSpeed)
  52. }
  53. }