diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a9bbf22..693338fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,11 +50,11 @@ jobs: COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 - name: set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: available platforms run: echo ${{ steps.buildx.outputs.platforms }} diff --git a/backend/.golangci.yml b/backend/.golangci.yml index 0264a282..b26073f2 100644 --- a/backend/.golangci.yml +++ b/backend/.golangci.yml @@ -30,6 +30,7 @@ linters: - unparam - unused - whitespace + - modernize settings: goconst: min-len: 2 @@ -80,4 +81,4 @@ formatters: paths: - third_party$ - builtin$ - - examples$ \ No newline at end of file + - examples$ diff --git a/backend/extractor/pics.go b/backend/extractor/pics.go index 4d6720c2..efbc5b44 100644 --- a/backend/extractor/pics.go +++ b/backend/extractor/pics.go @@ -1,9 +1,10 @@ package extractor import ( + "cmp" "io" "net/http" - "sort" + "slices" "sync" "time" @@ -39,7 +40,7 @@ func (f *UReadability) extractPics(iselect *goquery.Selection, url string) (main images[r.size] = r.url allImages = append(allImages, r.url) } - sort.Strings(allImages) + slices.Sort(allImages) if len(images) == 0 { return "", nil, false } @@ -49,7 +50,7 @@ func (f *UReadability) extractPics(iselect *goquery.Selection, url string) (main for k := range images { keys = append(keys, k) } - sort.Sort(sort.Reverse(sort.IntSlice(keys))) + slices.SortFunc(keys, func(a, b int) int { return cmp.Compare(b, a) }) mainImage = images[keys[0]] log.Printf("[DEBUG] total images from %s = %d, main=%s (%d)", url, len(images), mainImage, keys[0]) return mainImage, allImages, true diff --git a/backend/extractor/text.go b/backend/extractor/text.go index cf3c288c..2ae986b2 100644 --- a/backend/extractor/text.go +++ b/backend/extractor/text.go @@ -41,10 +41,7 @@ func (f *UReadability) getText(content, title string) string { // get snippet from clean text content func (f *UReadability) getSnippet(cleanText string) string { cleanText = strings.ReplaceAll(cleanText, "\n", " ") - size := len([]rune(cleanText)) - if size > f.SnippetSize { - size = f.SnippetSize - } + size := min(len([]rune(cleanText)), f.SnippetSize) snippet := []rune(cleanText)[:size] // go back in snippet and found first space for i := len(snippet) - 1; i >= 0; i-- { diff --git a/backend/main.go b/backend/main.go index 8fd2f0f3..a01f7196 100644 --- a/backend/main.go +++ b/backend/main.go @@ -34,12 +34,7 @@ func main() { if _, err := flags.Parse(&opts); err != nil { os.Exit(1) } - var options []log.Option - if opts.Debug { - options = []log.Option{log.Debug, log.CallerFile} - } - options = append(options, log.Msec, log.LevelBraces) - log.Setup(options...) + setupLog(opts.Debug, opts.MongoURI, opts.Token) log.Printf("[INFO] started ukeeper-readability service %s", revision) db, err := datastore.New(opts.MongoURI, opts.MongoDB, opts.MongoDelay) @@ -69,3 +64,12 @@ func main() { srv.Run(ctx, opts.Address, opts.Port, opts.FrontendDir) } + +func setupLog(dbg bool, secrets ...string) { //nolint:revive // control flag is fine for init helper + log.Secret(secrets...) + if dbg { + log.Setup(log.Debug, log.CallerFile, log.Msec, log.LevelBraces) + return + } + log.Setup(log.Msec, log.LevelBraces) +} diff --git a/backend/rest/server.go b/backend/rest/server.go index 153de0e3..0c9d3164 100644 --- a/backend/rest/server.go +++ b/backend/rest/server.go @@ -204,8 +204,8 @@ func (s *Server) extractArticleEmulateReadability(w http.ResponseWriter, r *http // generates previews for the provided test URLs func (s *Server) handlePreview(w http.ResponseWriter, r *http.Request) { - err := r.ParseForm() - if err != nil { + r.Body = http.MaxBytesReader(w, r.Body, 64<<20) // limit to 64MB + if err := r.ParseForm(); err != nil { http.Error(w, "Failed to parse form", http.StatusBadRequest) return } @@ -268,8 +268,7 @@ func (s *Server) handlePreview(w http.ResponseWriter, r *http.Request) { Results: results, } - err = s.rulePage.ExecuteTemplate(w, "preview.gohtml", data) - if err != nil { + if err := s.rulePage.ExecuteTemplate(w, "preview.gohtml", data); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -277,8 +276,8 @@ func (s *Server) handlePreview(w http.ResponseWriter, r *http.Request) { // saveRule upsert rule, forcing enabled=true func (s *Server) saveRule(w http.ResponseWriter, r *http.Request) { - err := r.ParseForm() - if err != nil { + r.Body = http.MaxBytesReader(w, r.Body, 64<<20) // limit to 64MB + if err := r.ParseForm(); err != nil { http.Error(w, "Failed to parse form", http.StatusBadRequest) return }