mirror of
https://github.com/miniflux/v2.git
synced 2025-08-01 17:38:37 +00:00
Enable go-critic linter and fix various issues detected
This commit is contained in:
parent
f6404290ba
commit
b1e73fafdf
34 changed files with 126 additions and 109 deletions
|
@ -179,11 +179,12 @@ func (a *Atom10Text) Body() string {
|
|||
func (a *Atom10Text) Title() string {
|
||||
var content string
|
||||
|
||||
if strings.EqualFold(a.Type, "xhtml") {
|
||||
switch {
|
||||
case strings.EqualFold(a.Type, "xhtml"):
|
||||
content = a.xhtmlContent()
|
||||
} else if strings.Contains(a.InnerXML, "<![CDATA[") {
|
||||
case strings.Contains(a.InnerXML, "<![CDATA["):
|
||||
content = html.UnescapeString(a.CharData)
|
||||
} else {
|
||||
default:
|
||||
content = a.CharData
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"miniflux.app/v2/internal/locale"
|
||||
)
|
||||
|
@ -94,23 +96,18 @@ func (r *ResponseHandler) ReadBody(maxBodySize int64) ([]byte, *locale.Localized
|
|||
|
||||
func (r *ResponseHandler) LocalizedError() *locale.LocalizedErrorWrapper {
|
||||
if r.clientErr != nil {
|
||||
switch r.clientErr.(type) {
|
||||
case x509.CertificateInvalidError, x509.HostnameError:
|
||||
switch {
|
||||
case isSSLError(r.clientErr):
|
||||
return locale.NewLocalizedErrorWrapper(fmt.Errorf("fetcher: %w", r.clientErr), "error.tls_error", r.clientErr)
|
||||
case *net.OpError:
|
||||
case isNetworkError(r.clientErr):
|
||||
return locale.NewLocalizedErrorWrapper(fmt.Errorf("fetcher: %w", r.clientErr), "error.network_operation", r.clientErr)
|
||||
case net.Error:
|
||||
networkErr := r.clientErr.(net.Error)
|
||||
if networkErr.Timeout() {
|
||||
return locale.NewLocalizedErrorWrapper(fmt.Errorf("fetcher: %w", r.clientErr), "error.network_timeout", r.clientErr)
|
||||
}
|
||||
}
|
||||
|
||||
if errors.Is(r.clientErr, io.EOF) {
|
||||
case os.IsTimeout(r.clientErr):
|
||||
return locale.NewLocalizedErrorWrapper(fmt.Errorf("fetcher: %w", r.clientErr), "error.network_timeout", r.clientErr)
|
||||
case errors.Is(r.clientErr, io.EOF):
|
||||
return locale.NewLocalizedErrorWrapper(fmt.Errorf("fetcher: %w", r.clientErr), "error.http_empty_response")
|
||||
default:
|
||||
return locale.NewLocalizedErrorWrapper(fmt.Errorf("fetcher: %w", r.clientErr), "error.http_client_error", r.clientErr)
|
||||
}
|
||||
|
||||
return locale.NewLocalizedErrorWrapper(fmt.Errorf("fetcher: %w", r.clientErr), "error.http_client_error", r.clientErr)
|
||||
}
|
||||
|
||||
switch r.httpResponse.StatusCode {
|
||||
|
@ -145,3 +142,32 @@ func (r *ResponseHandler) LocalizedError() *locale.LocalizedErrorWrapper {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isNetworkError(err error) bool {
|
||||
if _, ok := err.(*url.Error); ok {
|
||||
return true
|
||||
}
|
||||
if err == io.EOF {
|
||||
return true
|
||||
}
|
||||
var opErr *net.OpError
|
||||
if ok := errors.As(err, &opErr); ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isSSLError(err error) bool {
|
||||
var certErr x509.UnknownAuthorityError
|
||||
if errors.As(err, &certErr) {
|
||||
return true
|
||||
}
|
||||
|
||||
var hostErr x509.HostnameError
|
||||
if errors.As(err, &hostErr) {
|
||||
return true
|
||||
}
|
||||
|
||||
var algErr x509.InsecureAlgorithmError
|
||||
return errors.As(err, &algErr)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ package json // import "miniflux.app/v2/internal/reader/json"
|
|||
|
||||
import (
|
||||
"log/slog"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -118,24 +118,21 @@ func (j *JSONAdapter) BuildFeed(feedURL string) *model.Feed {
|
|||
}
|
||||
|
||||
// Populate the entry author.
|
||||
itemAuthors := append(item.Authors, j.jsonFeed.Authors...)
|
||||
itemAuthors := j.jsonFeed.Authors
|
||||
itemAuthors = append(itemAuthors, item.Authors...)
|
||||
itemAuthors = append(itemAuthors, item.Author, j.jsonFeed.Author)
|
||||
|
||||
authorNamesMap := make(map[string]bool)
|
||||
var authorNames []string
|
||||
for _, author := range itemAuthors {
|
||||
authorName := strings.TrimSpace(author.Name)
|
||||
if authorName != "" {
|
||||
authorNamesMap[authorName] = true
|
||||
authorNames = append(authorNames, authorName)
|
||||
}
|
||||
}
|
||||
|
||||
var authors []string
|
||||
for authorName := range authorNamesMap {
|
||||
authors = append(authors, authorName)
|
||||
}
|
||||
|
||||
sort.Strings(authors)
|
||||
entry.Author = strings.Join(authors, ", ")
|
||||
slices.Sort(authorNames)
|
||||
authorNames = slices.Compact(authorNames)
|
||||
entry.Author = strings.Join(authorNames, ", ")
|
||||
|
||||
// Populate the entry enclosures.
|
||||
for _, attachment := range item.Attachments {
|
||||
|
|
|
@ -93,8 +93,6 @@ func (mc *Content) MimeType() string {
|
|||
return "video/*"
|
||||
case mc.Type == "" && mc.Medium == "audio":
|
||||
return "audio/*"
|
||||
case mc.Type == "" && mc.Medium == "video":
|
||||
return "video/*"
|
||||
case mc.Type != "":
|
||||
return mc.Type
|
||||
default:
|
||||
|
|
|
@ -401,11 +401,11 @@ func parseISO8601(from string) (time.Duration, error) {
|
|||
|
||||
switch name {
|
||||
case "hour":
|
||||
d = d + (time.Duration(val) * time.Hour)
|
||||
d += (time.Duration(val) * time.Hour)
|
||||
case "minute":
|
||||
d = d + (time.Duration(val) * time.Minute)
|
||||
d += (time.Duration(val) * time.Minute)
|
||||
case "second":
|
||||
d = d + (time.Duration(val) * time.Second)
|
||||
d += (time.Duration(val) * time.Second)
|
||||
default:
|
||||
return 0, fmt.Errorf("unknown field %s", name)
|
||||
}
|
||||
|
|
|
@ -45,11 +45,12 @@ func (c *candidate) String() string {
|
|||
id, _ := c.selection.Attr("id")
|
||||
class, _ := c.selection.Attr("class")
|
||||
|
||||
if id != "" && class != "" {
|
||||
switch {
|
||||
case id != "" && class != "":
|
||||
return fmt.Sprintf("%s#%s.%s => %f", c.Node().DataAtom, id, class, c.score)
|
||||
} else if id != "" {
|
||||
case id != "":
|
||||
return fmt.Sprintf("%s#%s => %f", c.Node().DataAtom, id, c.score)
|
||||
} else if class != "" {
|
||||
case class != "":
|
||||
return fmt.Sprintf("%s.%s => %f", c.Node().DataAtom, class, c.score)
|
||||
}
|
||||
|
||||
|
@ -222,7 +223,7 @@ func getCandidates(document *goquery.Document) candidateList {
|
|||
// should have a relatively small link density (5% or less) and be mostly
|
||||
// unaffected by this operation
|
||||
for _, candidate := range candidates {
|
||||
candidate.score = candidate.score * (1 - getLinkDensity(candidate.selection))
|
||||
candidate.score *= (1 - getLinkDensity(candidate.selection))
|
||||
}
|
||||
|
||||
return candidates
|
||||
|
|
|
@ -376,7 +376,8 @@ func addHackerNewsLinksUsing(entryContent, app string) string {
|
|||
return
|
||||
}
|
||||
|
||||
if app == "opener" {
|
||||
switch app {
|
||||
case "opener":
|
||||
params := url.Values{}
|
||||
params.Add("url", hn_uri.String())
|
||||
|
||||
|
@ -389,12 +390,12 @@ func addHackerNewsLinksUsing(entryContent, app string) string {
|
|||
|
||||
open_with_opener := `<a href="` + url.String() + `">Open with Opener</a>`
|
||||
a.Parent().AppendHtml(" " + open_with_opener)
|
||||
} else if app == "hack" {
|
||||
case "hack":
|
||||
url := strings.Replace(hn_uri.String(), hn_prefix, "hack://", 1)
|
||||
|
||||
open_with_hack := `<a href="` + url + `">Open with HACK</a>`
|
||||
a.Parent().AppendHtml(" " + open_with_hack)
|
||||
} else {
|
||||
default:
|
||||
slog.Warn("Unknown app provided for openHackerNewsLinksWith rewrite rule",
|
||||
slog.String("app", app),
|
||||
)
|
||||
|
|
|
@ -190,17 +190,18 @@ func sanitizeAttributes(baseURL, tagName string, attributes []html.Attribute) ([
|
|||
}
|
||||
|
||||
if isExternalResourceAttribute(attribute.Key) {
|
||||
if tagName == "iframe" {
|
||||
switch {
|
||||
case tagName == "iframe":
|
||||
if !isValidIframeSource(baseURL, attribute.Val) {
|
||||
continue
|
||||
}
|
||||
value = rewriteIframeURL(attribute.Val)
|
||||
} else if tagName == "img" && attribute.Key == "src" && isValidDataAttribute(attribute.Val) {
|
||||
case tagName == "img" && attribute.Key == "src" && isValidDataAttribute(attribute.Val):
|
||||
value = attribute.Val
|
||||
} else if isAnchor("a", attribute) {
|
||||
case isAnchor("a", attribute):
|
||||
value = attribute.Val
|
||||
isAnchorLink = true
|
||||
} else {
|
||||
default:
|
||||
value, err = urllib.AbsoluteURL(baseURL, value)
|
||||
if err != nil {
|
||||
continue
|
||||
|
|
|
@ -27,8 +27,7 @@ func StripTags(input string) string {
|
|||
}
|
||||
|
||||
token := tokenizer.Token()
|
||||
switch token.Type {
|
||||
case html.TextToken:
|
||||
if token.Type == html.TextToken {
|
||||
buffer.WriteString(token.Data)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ func filterValidXMLChar(r rune) rune {
|
|||
func procInst(param, s string) string {
|
||||
// TODO: this parsing is somewhat lame and not exact.
|
||||
// It works for all actual cases, though.
|
||||
param = param + "="
|
||||
param += "="
|
||||
idx := strings.Index(s, param)
|
||||
if idx == -1 {
|
||||
return ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue