changedetection.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package feed
  2. import (
  3. "fmt"
  4. "log/slog"
  5. "net/http"
  6. "time"
  7. )
  8. type changeDetectionResponseJson struct {
  9. Name string `json:"title"`
  10. Url string `json:"url"`
  11. LastChanged int `json:"last_changed"`
  12. }
  13. func parseLastChangeTime(t int) time.Time {
  14. parsedTime := time.Unix(int64(t), 0)
  15. return parsedTime
  16. }
  17. func FetchLatestDetectedChanges(watches []string, token string) (ChangeWatches, error) {
  18. changeWatches := make(ChangeWatches, 0, len(watches))
  19. if len(watches) == 0 {
  20. return changeWatches, nil
  21. }
  22. requests := make([]*http.Request, len(watches))
  23. for i, repository := range watches {
  24. request, _ := http.NewRequest("GET", fmt.Sprintf("https://changedetection.knhash.in/api/v1/watch/%s", repository), nil)
  25. if token != "" {
  26. request.Header.Add("x-api-key", token)
  27. }
  28. requests[i] = request
  29. }
  30. task := decodeJsonFromRequestTask[changeDetectionResponseJson](defaultClient)
  31. job := newJob(task, requests).withWorkers(15)
  32. responses, errs, err := workerPoolDo(job)
  33. if err != nil {
  34. return nil, err
  35. }
  36. var failed int
  37. for i := range responses {
  38. if errs[i] != nil {
  39. failed++
  40. slog.Error("Failed to fetch or parse change detections", "error", errs[i], "url", requests[i].URL)
  41. continue
  42. }
  43. watch := responses[i]
  44. changeWatches = append(changeWatches, ChangeWatch{
  45. Name: watch.Name,
  46. Url: watch.Url,
  47. LastChanged: parseLastChangeTime(watch.LastChanged),
  48. })
  49. }
  50. if len(changeWatches) == 0 {
  51. return nil, ErrNoContent
  52. }
  53. changeWatches.SortByNewest()
  54. if failed > 0 {
  55. return changeWatches, fmt.Errorf("%w: could not get %d watches", ErrPartialContent, failed)
  56. }
  57. return changeWatches, nil
  58. }