// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package processor // import "miniflux.app/v2/internal/reader/processor" import ( "errors" "fmt" "regexp" "strconv" "time" "github.com/tdewolff/minify/v2" "github.com/tdewolff/minify/v2/html" ) // TODO: use something less horrible than a regex to parse ISO 8601 durations. var ( iso8601Regex = regexp.MustCompile(`^P((?P\d+)Y)?((?P\d+)M)?((?P\d+)W)?((?P\d+)D)?(T((?P\d+)H)?((?P\d+)M)?((?P\d+)S)?)?$`) ) func parseISO8601(from string) (time.Duration, error) { var match []string var d time.Duration if iso8601Regex.MatchString(from) { match = iso8601Regex.FindStringSubmatch(from) } else { return 0, errors.New("youtube: could not parse duration string") } for i, name := range iso8601Regex.SubexpNames() { part := match[i] if i == 0 || name == "" || part == "" { continue } val, err := strconv.ParseInt(part, 10, 64) if err != nil { return 0, err } switch name { case "hour": d += time.Duration(val) * time.Hour case "minute": d += time.Duration(val) * time.Minute case "second": d += time.Duration(val) * time.Second default: return 0, fmt.Errorf("youtube: unknown field %s", name) } } return d, nil } func minifyContent(content string) string { m := minify.New() // Options required to avoid breaking the HTML content. m.Add("text/html", &html.Minifier{ KeepEndTags: true, KeepQuotes: true, }) if minifiedHTML, err := m.String("text/html", content); err == nil { content = minifiedHTML } return content }