odysee.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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. "errors"
  6. "fmt"
  7. "log/slog"
  8. "net/url"
  9. "strconv"
  10. "github.com/PuerkitoBio/goquery"
  11. "miniflux.app/v2/internal/config"
  12. "miniflux.app/v2/internal/model"
  13. "miniflux.app/v2/internal/proxyrotator"
  14. "miniflux.app/v2/internal/reader/fetcher"
  15. )
  16. func shouldFetchOdyseeWatchTime(entry *model.Entry) bool {
  17. if !config.Opts.FetchOdyseeWatchTime() {
  18. return false
  19. }
  20. u, err := url.Parse(entry.URL)
  21. if err != nil {
  22. return false
  23. }
  24. return u.Hostname() == "odysee.com"
  25. }
  26. func fetchOdyseeWatchTime(websiteURL string) (int, error) {
  27. requestBuilder := fetcher.NewRequestBuilder()
  28. requestBuilder.WithTimeout(config.Opts.HTTPClientTimeout())
  29. requestBuilder.WithProxyRotator(proxyrotator.ProxyRotatorInstance)
  30. requestBuilder.WithCustomApplicationProxyURL(config.Opts.HTTPClientProxyURL())
  31. responseHandler := fetcher.NewResponseHandler(requestBuilder.ExecuteRequest(websiteURL))
  32. defer responseHandler.Close()
  33. if localizedError := responseHandler.LocalizedError(); localizedError != nil {
  34. slog.Warn("Unable to fetch Odysee watch time", slog.String("website_url", websiteURL), slog.Any("error", localizedError.Error()))
  35. return 0, localizedError.Error()
  36. }
  37. doc, docErr := goquery.NewDocumentFromReader(responseHandler.Body(config.Opts.HTTPClientMaxBodySize()))
  38. if docErr != nil {
  39. return 0, docErr
  40. }
  41. durs, exists := doc.FindMatcher(goquery.Single(`meta[property="og:video:duration"]`)).Attr("content")
  42. // durs contains video watch time in seconds
  43. if !exists {
  44. return 0, errors.New("duration has not found")
  45. }
  46. dur, err := strconv.ParseInt(durs, 10, 64)
  47. if err != nil {
  48. return 0, fmt.Errorf("unable to parse duration %s: %v", durs, err)
  49. }
  50. return int(dur / 60), nil
  51. }