cmd: modernize -fix ./cmd/...

This commit is contained in:
nkanaev
2026-04-27 20:44:24 +01:00
parent 7a5f8a5e41
commit 49c704037b
15 changed files with 53 additions and 75 deletions

View File

@@ -51,7 +51,7 @@ func Template(path string) *template.Template {
return tmpl
}
func Render(path string, writer io.Writer, data interface{}) {
func Render(path string, writer io.Writer, data any) {
tmpl := Template(path)
tmpl.Execute(writer, data)
}

View File

@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"regexp"
"slices"
"strconv"
"strings"
@@ -225,10 +226,8 @@ func hasRequiredAttributes(tagName string, attributes []string) bool {
for element, attrs := range elements {
if tagName == element {
for _, attribute := range attributes {
for _, attr := range attrs {
if attr == attribute {
return true
}
if slices.Contains(attrs, attribute) {
return true
}
}
@@ -285,13 +284,7 @@ func isValidIframeSource(baseURL, src string) bool {
return true
}
for _, safeDomain := range whitelist {
if safeDomain == domain {
return true
}
}
return false
return slices.Contains(whitelist, domain)
}
func getTagAllowList() map[string][]string {
@@ -355,13 +348,7 @@ func getTagAllowList() map[string][]string {
}
func inList(needle string, haystack []string) bool {
for _, element := range haystack {
if element == needle {
return true
}
}
return false
return slices.Contains(haystack, needle)
}
func isBlockedTag(tagName string) bool {
@@ -371,13 +358,7 @@ func isBlockedTag(tagName string) bool {
"style",
}
for _, element := range blacklist {
if element == tagName {
return true
}
}
return false
return slices.Contains(blacklist, tagName)
}
/*

View File

@@ -2,6 +2,7 @@ package scraper
import (
"net/url"
"slices"
"strings"
"github.com/nkanaev/yarr/src/content/htmlutil"
@@ -22,10 +23,8 @@ func FindFeeds(body string, base string) map[string]string {
isFeedLink := func(n *html.Node) bool {
if n.Type == html.ElementNode && n.Data == "link" {
t := htmlutil.Attr(n, "type")
for _, tt := range linkTypes {
if tt == t {
return true
}
if slices.Contains(linkTypes, t) {
return true
}
}
return false

View File

@@ -216,7 +216,7 @@ func TestRSSTitleHTMLTags(t *testing.T) {
`))
have := []string{feed.Items[0].Title, feed.Items[1].Title}
want := []string{"title in p", "very strong title"}
for i := 0; i < len(want); i++ {
for i := range want {
if want[i] != have[i] {
t.Errorf("title doesn't match\nwant: %#v\nhave: %#v\n", want[i], have[i])
}
@@ -241,7 +241,7 @@ func TestRSSIsPermalink(t *testing.T) {
URL: "http://example.com/posts/1",
},
}
for i := 0; i < len(want); i++ {
for i := range want {
if !reflect.DeepEqual(want, have) {
t.Errorf("Failed to handle isPermalink\nwant: %#v\nhave: %#v\n", want[i], have[i])
}

View File

@@ -46,7 +46,7 @@ func TestSafeXMLReaderPartial1(t *testing.T) {
f = NewSafeXMLReader(f)
buf := make([]byte, 1)
for i := 0; i < len(want); i++ {
for i := range want {
n, err := f.Read(buf)
if err != nil {
t.Fatal(err)

View File

@@ -44,7 +44,7 @@ func (m *Middleware) Handler(c *router.Context) {
c.Redirect(rootUrl)
return
} else {
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]any{
"username": username,
"error": "Invalid username/password",
"settings": m.DB.GetSettings(),
@@ -52,7 +52,7 @@ func (m *Middleware) Handler(c *router.Context) {
return
}
}
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{
c.HTML(http.StatusOK, assets.Template("login.html"), map[string]any{
"settings": m.DB.GetSettings(),
})
}

View File

@@ -53,7 +53,7 @@ type FeverFavicon struct {
Data string `json:"data"`
}
func writeFeverJSON(c *router.Context, data map[string]interface{}, lastRefreshed int64) {
func writeFeverJSON(c *router.Context, data map[string]any, lastRefreshed int64) {
data["api_version"] = 3
data["auth"] = 1
data["last_refreshed_on_time"] = lastRefreshed
@@ -78,7 +78,7 @@ func (s *Server) feverAuth(c *router.Context) bool {
if s.Username != "" && s.Password != "" {
apiKey := c.Req.FormValue("api_key")
apiKey = strings.ToLower(apiKey)
md5HashValue := md5.Sum([]byte(fmt.Sprintf("%s:%s", s.Username, s.Password)))
md5HashValue := md5.Sum(fmt.Appendf(nil, "%s:%s", s.Username, s.Password))
hexMD5HashValue := fmt.Sprintf("%x", md5HashValue[:])
if !auth.StringsEqual(apiKey, hexMD5HashValue) {
return false
@@ -97,7 +97,7 @@ func formHasValue(values url.Values, value string) bool {
func (s *Server) handleFever(c *router.Context) {
c.Req.ParseForm()
if !s.feverAuth(c) {
c.JSON(http.StatusOK, map[string]interface{}{
c.JSON(http.StatusOK, map[string]any{
"api_version": 3,
"auth": 0,
"last_refreshed_on_time": 0,
@@ -123,7 +123,7 @@ func (s *Server) handleFever(c *router.Context) {
case formHasValue(c.Req.Form, "mark"):
s.feverMarkHandler(c)
default:
c.JSON(http.StatusOK, map[string]interface{}{
c.JSON(http.StatusOK, map[string]any{
"api_version": 3,
"auth": 1,
"last_refreshed_on_time": getLastRefreshedOnTime(s.db.ListHTTPStates()),
@@ -168,7 +168,7 @@ func (s *Server) feverGroupsHandler(c *router.Context) {
for i, folder := range folders {
groups[i] = &FeverGroup{ID: folder.Id, Title: folder.Title}
}
writeFeverJSON(c, map[string]interface{}{
writeFeverJSON(c, map[string]any{
"groups": groups,
"feeds_groups": feedGroups(s.db),
}, getLastRefreshedOnTime(s.db.ListHTTPStates()))
@@ -194,7 +194,7 @@ func (s *Server) feverFeedsHandler(c *router.Context) {
LastUpdated: lastUpdated,
}
}
writeFeverJSON(c, map[string]interface{}{
writeFeverJSON(c, map[string]any{
"feeds": feverFeeds,
"feeds_groups": feedGroups(s.db),
}, getLastRefreshedOnTime(httpStates))
@@ -216,7 +216,7 @@ func (s *Server) feverFaviconsHandler(c *router.Context) {
favicons[i] = &FeverFavicon{ID: feed.Id, Data: data}
}
writeFeverJSON(c, map[string]interface{}{
writeFeverJSON(c, map[string]any{
"favicons": favicons,
}, getLastRefreshedOnTime(s.db.ListHTTPStates()))
}
@@ -280,15 +280,15 @@ func (s *Server) feverItemsHandler(c *router.Context) {
totalItems := s.db.CountItems(storage.ItemFilter{})
writeFeverJSON(c, map[string]interface{}{
writeFeverJSON(c, map[string]any{
"items": feverItems,
"total_items": totalItems,
}, getLastRefreshedOnTime(s.db.ListHTTPStates()))
}
func (s *Server) feverLinksHandler(c *router.Context) {
writeFeverJSON(c, map[string]interface{}{
"links": make([]interface{}, 0),
writeFeverJSON(c, map[string]any{
"links": make([]any, 0),
}, getLastRefreshedOnTime(s.db.ListHTTPStates()))
}
@@ -309,7 +309,7 @@ func (s *Server) feverUnreadItemIDsHandler(c *router.Context) {
}
itemFilter.After = &items[len(items)-1].Id
}
writeFeverJSON(c, map[string]interface{}{
writeFeverJSON(c, map[string]any{
"unread_item_ids": joinInts(itemIds),
}, getLastRefreshedOnTime(s.db.ListHTTPStates()))
}
@@ -331,7 +331,7 @@ func (s *Server) feverSavedItemIDsHandler(c *router.Context) {
}
itemFilter.After = &items[len(items)-1].Id
}
writeFeverJSON(c, map[string]interface{}{
writeFeverJSON(c, map[string]any{
"saved_item_ids": joinInts(itemIds),
}, getLastRefreshedOnTime(s.db.ListHTTPStates()))
}
@@ -386,7 +386,7 @@ func (s *Server) feverMarkHandler(c *router.Context) {
c.Out.WriteHeader(http.StatusBadRequest)
return
}
c.JSON(http.StatusOK, map[string]interface{}{
c.JSON(http.StatusOK, map[string]any{
"api_version": 3,
"auth": 1,
})

View File

@@ -24,7 +24,7 @@ func (c *Context) Next() {
c.chain[c.index](c)
}
func (c *Context) JSON(status int, data interface{}) {
func (c *Context) JSON(status int, data any) {
body, err := json.Marshal(data)
if err != nil {
log.Fatal(err)
@@ -35,7 +35,7 @@ func (c *Context) JSON(status int, data interface{}) {
c.Out.Write([]byte("\n"))
}
func (c *Context) HTML(status int, tmpl *template.Template, data interface{}) {
func (c *Context) HTML(status int, tmpl *template.Template, data any) {
c.Out.Header().Set("Content-Type", "text/html")
c.Out.WriteHeader(status)
tmpl.Execute(c.Out, data)

View File

@@ -64,7 +64,7 @@ func (s *Server) handler() http.Handler {
}
func (s *Server) handleIndex(c *router.Context) {
c.HTML(http.StatusOK, assets.Template("index.html"), map[string]interface{}{
c.HTML(http.StatusOK, assets.Template("index.html"), map[string]any{
"settings": s.db.GetSettings(),
"authenticated": s.Username != "" && s.Password != "",
})
@@ -82,14 +82,14 @@ func (s *Server) handleStatic(c *router.Context) {
}
func (s *Server) handleManifest(c *router.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
c.JSON(http.StatusOK, map[string]any{
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
"name": "yarr!",
"short_name": "yarr",
"description": "yet another rss reader",
"display": "standalone",
"start_url": "/" + strings.TrimPrefix(s.BasePath, "/"),
"icons": []map[string]interface{}{
"icons": []map[string]any{
{
"src": s.BasePath + "/static/graphicarts/favicon.png",
"sizes": "64x64",
@@ -100,7 +100,7 @@ func (s *Server) handleManifest(c *router.Context) {
}
func (s *Server) handleStatus(c *router.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
c.JSON(http.StatusOK, map[string]any{
"running": s.worker.FeedsPending(),
"stats": s.db.FeedStats(),
})
@@ -239,7 +239,7 @@ func (s *Server) handleFeedList(c *router.Context) {
case len(result.Sources) > 0:
c.JSON(
http.StatusOK,
map[string]interface{}{"status": "multiple", "choice": result.Sources},
map[string]any{"status": "multiple", "choice": result.Sources},
)
case result.Feed != nil:
feed := s.db.CreateFeed(
@@ -257,7 +257,7 @@ func (s *Server) handleFeedList(c *router.Context) {
}
s.worker.FindFeedFavicon(*feed)
c.JSON(http.StatusOK, map[string]interface{}{
c.JSON(http.StatusOK, map[string]any{
"status": "success",
"feed": feed,
})
@@ -279,7 +279,7 @@ func (s *Server) handleFeed(c *router.Context) {
c.Out.WriteHeader(http.StatusBadRequest)
return
}
body := make(map[string]interface{})
body := make(map[string]any)
if err := json.NewDecoder(c.Req.Body).Decode(&body); err != nil {
log.Print(err)
c.Out.WriteHeader(http.StatusBadRequest)
@@ -391,7 +391,7 @@ func (s *Server) handleItemList(c *router.Context) {
items[i].Title = htmlutil.TruncateText(text, 140)
}
}
c.JSON(http.StatusOK, map[string]interface{}{
c.JSON(http.StatusOK, map[string]any{
"list": items,
"has_more": hasMore,
})
@@ -415,7 +415,7 @@ func (s *Server) handleSettings(c *router.Context) {
if c.Req.Method == "GET" {
c.JSON(http.StatusOK, s.db.GetSettings())
} else if c.Req.Method == "PUT" {
settings := make(map[string]interface{})
settings := make(map[string]any)
if err := json.NewDecoder(c.Req.Body).Decode(&settings); err != nil {
c.Out.WriteHeader(http.StatusBadRequest)
return
@@ -472,7 +472,6 @@ func (s *Server) handleOPMLExport(c *router.Context) {
feedsByFolderID := make(map[int64][]*storage.Feed)
for _, feed := range s.db.ListFeeds() {
feed := feed
if feed.FolderId == nil {
doc.Feeds = append(doc.Feeds, opml.Feed{
Title: feed.Title,

View File

@@ -16,7 +16,7 @@ type Server struct {
Addr string
db *storage.Storage
worker *worker.Worker
cache map[string]interface{}
cache map[string]any
cache_mutex *sync.Mutex
BasePath string
@@ -34,7 +34,7 @@ func NewServer(db *storage.Storage, addr string) *Server {
db: db,
Addr: addr,
worker: worker.NewWorker(db),
cache: make(map[string]interface{}),
cache: make(map[string]any),
cache_mutex: &sync.Mutex{},
}
}

View File

@@ -24,7 +24,7 @@ func TestCreateFeedSameLink(t *testing.T) {
t.Fatal("expected feed")
}
for i := 0; i < 10; i++ {
for range 10 {
db.CreateFeed("title", "", "", "http://example2.com/feed.xml", nil)
}

View File

@@ -169,9 +169,9 @@ func (s *Storage) CreateItems(items []Item) bool {
return true
}
func listQueryPredicate(filter ItemFilter, newestFirst bool) (string, []interface{}) {
func listQueryPredicate(filter ItemFilter, newestFirst bool) (string, []any) {
cond := make([]string, 0)
args := make([]interface{}, 0)
args := make([]any, 0)
if filter.FolderID != nil {
cond = append(cond, "i.feed_id in (select id from feeds where folder_id = :folder_id)")
args = append(args, sql.Named("folder_id", *filter.FolderID))

View File

@@ -6,8 +6,8 @@ import (
"log"
)
func settingsDefaults() map[string]interface{} {
return map[string]interface{}{
func settingsDefaults() map[string]any {
return map[string]any{
"filter": "",
"feed": "",
"feed_list_width": 300,
@@ -20,7 +20,7 @@ func settingsDefaults() map[string]interface{} {
}
}
func (s *Storage) GetSettingsValue(key string) interface{} {
func (s *Storage) GetSettingsValue(key string) any {
row := s.db.QueryRow(`select val from settings where key=:key`, sql.Named("key", key))
if row == nil {
return settingsDefaults()[key]
@@ -30,7 +30,7 @@ func (s *Storage) GetSettingsValue(key string) interface{} {
if len(val) == 0 {
return nil
}
var valDecoded interface{}
var valDecoded any
if err := json.Unmarshal([]byte(val), &valDecoded); err != nil {
log.Print(err)
return nil
@@ -48,7 +48,7 @@ func (s *Storage) GetSettingsValueInt64(key string) int64 {
return 0
}
func (s *Storage) GetSettings() map[string]interface{} {
func (s *Storage) GetSettings() map[string]any {
result := settingsDefaults()
rows, err := s.db.Query(`select key, val from settings;`)
if err != nil {
@@ -58,7 +58,7 @@ func (s *Storage) GetSettings() map[string]interface{} {
for rows.Next() {
var key string
var val []byte
var valDecoded interface{}
var valDecoded any
rows.Scan(&key, &val)
if err = json.Unmarshal([]byte(val), &valDecoded); err != nil {
@@ -70,7 +70,7 @@ func (s *Storage) GetSettings() map[string]interface{} {
return result
}
func (s *Storage) UpdateSettings(kv map[string]interface{}) bool {
func (s *Storage) UpdateSettings(kv map[string]any) bool {
defaults := settingsDefaults()
for key, val := range kv {
if defaults[key] == nil {

View File

@@ -141,7 +141,6 @@ func findFavicon(siteUrl, feedUrl string) (*[]byte, error) {
func ConvertItems(items []parser.Item, feed storage.Feed) []storage.Item {
result := make([]storage.Item, len(items))
for i, item := range items {
item := item
mediaLinks := make(storage.MediaLinks, 0)
for _, link := range item.MediaLinks {
mediaLinks = append(mediaLinks, storage.MediaLink(link))

View File

@@ -113,14 +113,14 @@ func (w *Worker) refresher(feeds []storage.Feed) {
srcqueue := make(chan storage.Feed, len(feeds))
dstqueue := make(chan []storage.Item)
for i := 0; i < NUM_WORKERS; i++ {
for range NUM_WORKERS {
go w.worker(srcqueue, dstqueue)
}
for _, feed := range feeds {
srcqueue <- feed
}
for i := 0; i < len(feeds); i++ {
for range feeds {
items := <-dstqueue
if len(items) > 0 {
w.db.CreateItems(items)