bring repo into policy compliance; vendor assets; Gitea CI
Vendor the front-end assets and drop the third-party CDN dependencies (BootstrapCDN is being sunset): the bootstrap 4.0.0 css/js, jquery 3.2.1 slim, and popper 1.12.9 now live under static/ and are served from the app, byte-for-byte identical to the previous SRI-pinned files. Migrate CI from Drone to a Gitea Actions workflow that runs docker build . on push, with the checkout action pinned by SHA. Bring the repo up to standard: - add REPO_POLICIES.md, .editorconfig, .dockerignore, .golangci.yml, and a comprehensive root-anchored .gitignore - rewrite the Makefile with the required test/lint/fmt/fmt-check/check/ docker/hooks targets (golangci-lint, 30s test timeout, verbose rerun on failure, check modifies nothing) - rewrite the Dockerfile as a hash-pinned multistage build: a lint stage (golangci-lint), a glibc build+test stage (the legacy sqlite driver needs cgo+glibc), and a debian-slim runtime carrying the binary, templates, and static assets - add real tests for the hn package - bring the code into golangci-lint (default: all) compliance: fix the malformed gorm struct tags, check previously-ignored errors, dispatch the zerolog error event, avoid a uint->Duration overflow, split long functions, and add doc comments — all behaviour-preserving - expand the README with the required sections
This commit is contained in:
@@ -10,38 +10,58 @@ import (
|
||||
"github.com/labstack/echo"
|
||||
)
|
||||
|
||||
// RequestHandlerSet holds the dependencies shared by the HTTP handlers.
|
||||
type RequestHandlerSet struct {
|
||||
db *gorm.DB
|
||||
version string
|
||||
}
|
||||
|
||||
// NewRequestHandlerSet builds a RequestHandlerSet for the given version and
|
||||
// database handle.
|
||||
func NewRequestHandlerSet(version string, db *gorm.DB) *RequestHandlerSet {
|
||||
rhs := new(RequestHandlerSet)
|
||||
rhs.db = db
|
||||
rhs.version = version
|
||||
|
||||
return rhs
|
||||
}
|
||||
|
||||
func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
|
||||
// exitRow is a story that has left the front page within the last 24h.
|
||||
type exitRow struct {
|
||||
Duration string
|
||||
DurationSecs uint
|
||||
URL string
|
||||
Title string
|
||||
HighestRank uint
|
||||
HNID uint
|
||||
Score uint
|
||||
TimeGone string
|
||||
TimeGoneSecs uint
|
||||
}
|
||||
|
||||
// currentRow is a story currently on the front page.
|
||||
type currentRow struct {
|
||||
Duration string
|
||||
DurationSecs uint
|
||||
URL string
|
||||
Title string
|
||||
Score uint
|
||||
HighestRank uint
|
||||
HNID uint
|
||||
Rank uint
|
||||
}
|
||||
|
||||
// exitedRows returns the stories that left the front page in the last 24h,
|
||||
// most recently departed first.
|
||||
func (r *RequestHandlerSet) exitedRows() []exitRow {
|
||||
last24h := time.Now().Add(time.Second * 86400 * -1)
|
||||
|
||||
var fpi []HNFrontPage
|
||||
r.db.Where("disappeared is not ? and disappeared > ?", time.Time{}, last24h).Order("disappeared desc").Find(&fpi)
|
||||
|
||||
type fprow struct {
|
||||
Duration string
|
||||
DurationSecs uint
|
||||
URL string
|
||||
Title string
|
||||
HighestRank uint
|
||||
HNID uint
|
||||
Score uint
|
||||
TimeGone string
|
||||
TimeGoneSecs uint
|
||||
}
|
||||
var fprows []fprow
|
||||
|
||||
rows := make([]exitRow, 0, len(fpi))
|
||||
for _, item := range fpi {
|
||||
fprows = append(fprows, fprow{
|
||||
rows = append(rows, exitRow{
|
||||
Duration: u.TimeDiffHuman(item.Disappeared, item.Appeared),
|
||||
DurationSecs: u.TimeDiffAbsSeconds(item.Disappeared, item.Appeared),
|
||||
URL: item.URL,
|
||||
@@ -54,23 +74,17 @@ func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
type rowtwo struct {
|
||||
Duration string
|
||||
DurationSecs uint
|
||||
URL string
|
||||
Title string
|
||||
Score uint
|
||||
HighestRank uint
|
||||
HNID uint
|
||||
Rank uint
|
||||
}
|
||||
var currentfp []rowtwo
|
||||
return rows
|
||||
}
|
||||
|
||||
// currentRows returns the stories currently on the front page, best rank first.
|
||||
func (r *RequestHandlerSet) currentRows() []currentRow {
|
||||
var cur []HNFrontPage
|
||||
r.db.Where("disappeared is ?", time.Time{}).Order("rank asc").Find(&cur)
|
||||
|
||||
rows := make([]currentRow, 0, len(cur))
|
||||
for _, item := range cur {
|
||||
currentfp = append(currentfp, rowtwo{
|
||||
rows = append(rows, currentRow{
|
||||
Duration: u.TimeDiffHuman(time.Now(), item.Appeared),
|
||||
DurationSecs: u.TimeDiffAbsSeconds(time.Now(), item.Appeared),
|
||||
URL: item.URL,
|
||||
@@ -82,12 +96,17 @@ func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
|
||||
tc := pongo2.Context{
|
||||
"time": time.Now().UTC().Format(time.RFC3339Nano),
|
||||
"exits": fprows,
|
||||
"current": currentfp,
|
||||
"exits": r.exitedRows(),
|
||||
"current": r.currentRows(),
|
||||
"gitrev": r.version,
|
||||
}
|
||||
|
||||
return c.Render(http.StatusOK, "index.html", tc)
|
||||
}
|
||||
|
||||
@@ -96,5 +115,6 @@ func (r *RequestHandlerSet) aboutHandler(c echo.Context) error {
|
||||
"time": time.Now().UTC().Format(time.RFC3339Nano),
|
||||
"gitrev": r.version,
|
||||
}
|
||||
|
||||
return c.Render(http.StatusOK, "about.html", tc)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user