utils.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. "regexp"
  8. "strconv"
  9. "time"
  10. "github.com/tdewolff/minify/v2"
  11. "github.com/tdewolff/minify/v2/html"
  12. )
  13. // TODO: use something less horrible than a regex to parse ISO 8601 durations.
  14. var (
  15. iso8601Regex = regexp.MustCompile(`^P((?P<year>\d+)Y)?((?P<month>\d+)M)?((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$`)
  16. )
  17. func parseISO8601(from string) (time.Duration, error) {
  18. var match []string
  19. var d time.Duration
  20. if iso8601Regex.MatchString(from) {
  21. match = iso8601Regex.FindStringSubmatch(from)
  22. } else {
  23. return 0, errors.New("processor: could not parse duration string")
  24. }
  25. for i, name := range iso8601Regex.SubexpNames() {
  26. part := match[i]
  27. if i == 0 || name == "" || part == "" {
  28. continue
  29. }
  30. val, err := strconv.ParseInt(part, 10, 64)
  31. if err != nil {
  32. return 0, err
  33. }
  34. switch name {
  35. case "hour":
  36. d += time.Duration(val) * time.Hour
  37. case "minute":
  38. d += time.Duration(val) * time.Minute
  39. case "second":
  40. d += time.Duration(val) * time.Second
  41. default:
  42. return 0, fmt.Errorf("processor: unknown field %s", name)
  43. }
  44. }
  45. return d, nil
  46. }
  47. func minifyContent(content string) string {
  48. m := minify.New()
  49. // Options required to avoid breaking the HTML content.
  50. m.Add("text/html", &html.Minifier{
  51. KeepEndTags: true,
  52. KeepQuotes: true,
  53. KeepComments: false,
  54. KeepSpecialComments: false,
  55. KeepDefaultAttrVals: false,
  56. })
  57. if minifiedHTML, err := m.String("text/html", content); err == nil {
  58. content = minifiedHTML
  59. }
  60. return content
  61. }