Compare commits

...

15 Commits

Author SHA1 Message Date
000f5bbaa6 bump deps
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-30 16:08:16 -07:00
d203dac078 factors out duration formatting to sneak/goutil
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-30 15:43:56 -07:00
4b745db52e add self-hosted matomo pageview tracking
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-28 20:04:11 -07:00
f129fddea9 change copy on about page
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-28 14:25:00 -07:00
8d1db5c15e restore old sorting
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-28 12:49:26 -07:00
51a0954b27 now sorts by hangtime asc, limits to 24h
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-28 10:54:00 -07:00
0cf05a0312 implement 48h limit and sort by hangtime asc
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-28 10:20:47 -07:00
c35608476f nuke/rebuild module
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-25 09:15:31 -07:00
67f317ed98 update ci config to always build
Some checks failed
continuous-integration/drone/push Build is failing
* hopefully
2020-03-25 09:13:48 -07:00
cccddb3172 bugfixes, i think
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-25 09:11:31 -07:00
0d9ed8874f made to suck less, including:
All checks were successful
continuous-integration/drone/push Build is passing
* `make` works again, exporting correct database file path for local dev
* better formatting of durations
* refactored duration math to misc functions
* now tracks and displays score
* displays short-lifetime fp wipeouts in red
2020-03-25 07:50:10 -07:00
fe1c4df4f1 broke the build, this fixes it.
All checks were successful
continuous-integration/drone/push Build is passing
2020-03-24 21:21:09 -07:00
5d7ecfa2cc update readme
Some checks failed
continuous-integration/drone/push Build is failing
2020-03-24 21:18:48 -07:00
b48a464536 fix typo, add link to @dang thread for /about
Some checks failed
continuous-integration/drone/push Build is failing
2020-03-24 21:16:02 -07:00
ffe6670ec8 will no longer grow db unbounded 2020-03-24 21:15:40 -07:00
19 changed files with 212 additions and 145 deletions

View File

@@ -6,13 +6,12 @@ steps:
image: plugins/docker image: plugins/docker
network_mode: bridge network_mode: bridge
settings: settings:
repo: sneak/hntransparency repo: sneak/orangesite
dry_run: true dry_run: true
username: username:
from_secret: docker_username from_secret: docker_username
password: password:
from_secret: docker_password from_secret: docker_password
auto_tag: true
tags: tags:
- ${DRONE_COMMIT_SHA} - ${DRONE_COMMIT_SHA}
- ${DRONE_BRANCH} - ${DRONE_BRANCH}

2
.gitignore vendored
View File

@@ -13,4 +13,4 @@
*.out *.out
server server
storage.db storage.sqlite

View File

@@ -1,6 +1,6 @@
FROM golang:1.14 as builder FROM golang:1.14 as builder
WORKDIR /go/src/git.eeqj.de/sneak/hntransparencylog WORKDIR /go/src/git.eeqj.de/sneak/orangesite
COPY . . COPY . .
#RUN make lint && make build #RUN make lint && make build
@@ -16,9 +16,9 @@ FROM alpine
RUN mkdir -p /app/bin RUN mkdir -p /app/bin
COPY --from=builder /go/src/git.eeqj.de/sneak/hntransparencylog/server /app/bin/server COPY --from=builder /go/src/git.eeqj.de/sneak/orangesite/server /app/bin/server
# FIXME figure out how to embed these stupid templates # FIXME figure out how to embed these stupid templates
COPY --from=builder /go/src/git.eeqj.de/sneak/hntransparencylog/view /app/view COPY --from=builder /go/src/git.eeqj.de/sneak/orangesite/view /app/view
# put the source in there too for safekeeping # put the source in there too for safekeeping
COPY --from=builder /go/go-src.tgz /usr/local/src/go-src.tgz COPY --from=builder /go/go-src.tgz /usr/local/src/go-src.tgz

View File

@@ -1,3 +1,6 @@
# for development, db in cwd
export DATABASE_PATH := ./storage.sqlite
VERSION := $(shell git rev-parse --short HEAD) VERSION := $(shell git rev-parse --short HEAD)
BUILDTIME := $(shell date -u '+%Y-%m-%dT%H:%M:%SZ') BUILDTIME := $(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
BUILDTIMEFILENAME := $(shell date -u '+%Y%m%d-%H%M%SZ') BUILDTIMEFILENAME := $(shell date -u '+%Y%m%d-%H%M%SZ')
@@ -7,7 +10,7 @@ BUILDHOST := $(shell hostname -s)
BUILDARCH := $(shell uname -m) BUILDARCH := $(shell uname -m)
FN := server FN := server
IMAGENAME := sneak/hntransparencylog IMAGENAME := sneak/orangesite
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)

View File

@@ -1,7 +1,18 @@
# hntransparencylog # Orangesite Transparency Log
Hacker News Transparency Log Live: https://orangesite.sneak.cloud
Shows stories that were on the HN front page within the last 48 hours, but Shows stories that were on the orangesite front page within the last 24
aren't any more. Sorted by the amount of time they remained on the front hours, but aren't any more. Sorted by when they exited the frontpage, most
page, smallest first. recent first.
Stories on the frontpage for less than a half hour (likely manually
moderator nuked if rank > 25 or so) are marked red for convenience.
# TODO
* continue to resist the urge to use the orange
# Author
* [sneak@sneak.berlin](mailto:sneak@sneak.berlin)

View File

@@ -4,7 +4,7 @@ package main
import ( import (
"os" "os"
"git.eeqj.de/sneak/hntransparencylog/hn" "git.eeqj.de/sneak/orangesite/hn"
) )
var Version string var Version string

16
go.mod
View File

@@ -1,21 +1,23 @@
module git.eeqj.de/sneak/hntransparencylog module git.eeqj.de/sneak/orangesite
go 1.14 go 1.14
require ( require (
github.com/UnnoTed/fileb0x v1.1.4 // indirect git.eeqj.de/sneak/goutil v0.0.0-20200330224956-7fad5dc142e5
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4
github.com/jinzhu/gorm v1.9.12 github.com/jinzhu/gorm v1.9.12
github.com/k0kubun/pp v3.0.1+incompatible github.com/juju/errors v0.0.0-20200330140219-3fe23663418f // indirect
github.com/labstack/echo v3.3.10+incompatible github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/echo/v4 v4.1.15 github.com/labstack/echo/v4 v4.1.16 // indirect
github.com/labstack/gommon v0.3.0 github.com/labstack/gommon v0.3.0
github.com/mattn/go-isatty v0.0.12 github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
github.com/mayowa/echo-pongo2 v0.0.0-20170410154925-661ce95e1767 github.com/mayowa/echo-pongo2 v0.0.0-20170410154925-661ce95e1767
github.com/nathan-osman/pongo2-fileb0x v0.0.0-20180406192709-b069fe2eec68
github.com/peterhellberg/hn v0.0.0-20160106115829-a27cdd2ca854 github.com/peterhellberg/hn v0.0.0-20160106115829-a27cdd2ca854
github.com/rs/zerolog v1.18.0 github.com/rs/zerolog v1.18.0
github.com/ziflex/lecho/v2 v2.0.0 github.com/ziflex/lecho/v2 v2.0.0
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 // indirect
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 // indirect
) )

69
go.sum
View File

@@ -1,25 +1,21 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= git.eeqj.de/sneak/goutil v0.0.0-20200330224009-e54964f792cd h1:LlQYjhr5NA5WK9f/s0QnnxHZE3YbnAhSkqQ/sJCdHk8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= git.eeqj.de/sneak/goutil v0.0.0-20200330224009-e54964f792cd/go.mod h1:eczIi5zp8IZnFLQbMF0Xufw6to+UMCbOxA4M4Hp7ORw=
github.com/UnnoTed/fileb0x v1.1.4 h1:IUgFzgBipF/ujNx9wZgkrKOF3oltUuXMSoaejrBws+A= git.eeqj.de/sneak/goutil v0.0.0-20200330224956-7fad5dc142e5 h1:0hBq85ulrB0pfC+lxb/UAMfGRHkykDMis0E8i2Di3zI=
github.com/UnnoTed/fileb0x v1.1.4/go.mod h1:X59xXT18tdNk/D6j+KZySratBsuKJauMtVuJ9cgOiZs= git.eeqj.de/sneak/goutil v0.0.0-20200330224956-7fad5dc142e5/go.mod h1:eczIi5zp8IZnFLQbMF0Xufw6to+UMCbOxA4M4Hp7ORw=
github.com/bmatcuk/doublestar v1.1.1 h1:YroD6BJCZBYx06yYFEWvUuKVWQn3vLLQAVmDmvTSaiQ=
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgrijalva/jwt-go v1.0.2 h1:KPldsxuKGsS2FPWsNeg9ZO18aCrGKujPoWXn2yo+KQM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 h1:GY1+t5Dr9OKADM64SYnQjw/w99HMYvQ0A8/JoUkxVmc= github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 h1:GY1+t5Dr9OKADM64SYnQjw/w99HMYvQ0A8/JoUkxVmc=
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc=
github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4 h1:60gBOooTSmNtrqNaRvrDbi8VAne0REaek2agjnITKSw=
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE=
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q= github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs= github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
@@ -27,55 +23,40 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 h1:rhqTjzJlm7EbkELJDKMTU7udov+Se0xZkWmugr6zGok= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 h1:rhqTjzJlm7EbkELJDKMTU7udov+Se0xZkWmugr6zGok=
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/errors v0.0.0-20200330140219-3fe23663418f h1:MCOvExGLpaSIzLYB4iQXEHP4jYVU6vmzLNQPdMVrxnM=
github.com/juju/errors v0.0.0-20200330140219-3fe23663418f/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/k0kubun/pp v1.3.0 h1:r9td75hcmetrcVbmsZRjnxcIbI9mhm+/N6iWyG4TWe0=
github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/karrick/godirwalk v1.7.8 h1:VfG72pyIxgtC7+3X9CMHI0AOl4LwyRAg98WAgsvffi8=
github.com/karrick/godirwalk v1.7.8/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/labstack/echo v1.4.4 h1:1bEiBNeGSUKxcPDGfZ/7IgdhJJZx8wV/pICJh4W2NJI= github.com/labstack/echo v1.4.4 h1:1bEiBNeGSUKxcPDGfZ/7IgdhJJZx8wV/pICJh4W2NJI=
github.com/labstack/echo v3.2.1+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg= github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/echo/v4 v4.1.10 h1:/yhIpO50CBInUbE/nHJtGIyhBv0dJe2cDAYxc3V3uMo=
github.com/labstack/echo/v4 v4.1.10/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/echo/v4 v4.1.10/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
github.com/labstack/echo/v4 v4.1.15 h1:4aE6KfJC+wCnMjODwcpeEGWGsRfszxZMwB3QVTECj2I= github.com/labstack/echo/v4 v4.1.16 h1:8swiwjE5Jkai3RPfZoahp8kjVCRNq+y7Q0hPji2Kz0o=
github.com/labstack/echo/v4 v4.1.15/go.mod h1:GWO5IBVzI371K8XJe50CSvHjQCafK6cw8R/moLhEU6o= github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
github.com/labstack/gommon v0.2.7/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw= github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/mayowa/echo-pongo2 v0.0.0-20170410154925-661ce95e1767 h1:T8fARjLT0o9OkyYmCAm3UuPVWm6/8yTAt4rmmWVTORI= github.com/mayowa/echo-pongo2 v0.0.0-20170410154925-661ce95e1767 h1:T8fARjLT0o9OkyYmCAm3UuPVWm6/8yTAt4rmmWVTORI=
github.com/mayowa/echo-pongo2 v0.0.0-20170410154925-661ce95e1767/go.mod h1:JCIHkkBgcmXEr/rc3YhaxQ9MgZ4GJe7wjEV/is2uuag= github.com/mayowa/echo-pongo2 v0.0.0-20170410154925-661ce95e1767/go.mod h1:JCIHkkBgcmXEr/rc3YhaxQ9MgZ4GJe7wjEV/is2uuag=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/nathan-osman/pongo2-fileb0x v0.0.0-20180406192709-b069fe2eec68 h1:h11XoSnZets0sfHYNDJTfN25OnC5u7YwVfqt2tEjTTc=
github.com/nathan-osman/pongo2-fileb0x v0.0.0-20180406192709-b069fe2eec68/go.mod h1:RQeQ4BP2ZHGo+QjbNu3b3C+ogX6fbX+dVz+5nuC3fE0=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/peterhellberg/hn v0.0.0-20160106115829-a27cdd2ca854 h1:K6zV6rLnXlmq8H7gqclq/K8ZANQyqpvhrzSkq70qoZw= github.com/peterhellberg/hn v0.0.0-20160106115829-a27cdd2ca854 h1:K6zV6rLnXlmq8H7gqclq/K8ZANQyqpvhrzSkq70qoZw=
github.com/peterhellberg/hn v0.0.0-20160106115829-a27cdd2ca854/go.mod h1:4NUrlv14rntJHyfqrF46i63j+7lUU8yIx/y6ORuO32M= github.com/peterhellberg/hn v0.0.0-20160106115829-a27cdd2ca854/go.mod h1:4NUrlv14rntJHyfqrF46i63j+7lUU8yIx/y6ORuO32M=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
@@ -83,11 +64,10 @@ github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThC
github.com/rs/zerolog v1.18.0 h1:CbAm3kP2Tptby1i9sYy2MGRg0uxIN9cyDb59Ys7W8z8= github.com/rs/zerolog v1.18.0 h1:CbAm3kP2Tptby1i9sYy2MGRg0uxIN9cyDb59Ys7W8z8=
github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50wTf68f99/Zt14pr046Tgt3Lp2vLyFZKzbFXTOabXw= github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4= github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
@@ -95,29 +75,34 @@ github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxt
github.com/ziflex/lecho v1.2.0 h1:/ykfd7V/aTsWUYNFimgbdhUiEMnWzvNaCxtbM/LX5F8= github.com/ziflex/lecho v1.2.0 h1:/ykfd7V/aTsWUYNFimgbdhUiEMnWzvNaCxtbM/LX5F8=
github.com/ziflex/lecho/v2 v2.0.0 h1:ggrWF5LaGAC+Y+WX71jFK7uYR7cUFbHjIgGqCyrYC5Q= github.com/ziflex/lecho/v2 v2.0.0 h1:ggrWF5LaGAC+Y+WX71jFK7uYR7cUFbHjIgGqCyrYC5Q=
github.com/ziflex/lecho/v2 v2.0.0/go.mod h1:s7dy9Fynjx6z+/7xE2BsK13vXIS3oQoo4ZaKXYG5xUs= github.com/ziflex/lecho/v2 v2.0.0/go.mod h1:s7dy9Fynjx6z+/7xE2BsK13vXIS3oQoo4ZaKXYG5xUs=
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180921000356-2f5d2388922f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20181019160139-8e24a49d80f8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 h1:TC0v2RSO1u2kn1ZugjrFXkRZAEaqMN/RW+OTZkBzmLE=
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -129,6 +114,4 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -17,6 +17,7 @@ type HNFrontPage struct {
HighestRank uint // frontpage index HighestRank uint // frontpage index
Rank uint // frontpage index Rank uint // frontpage index
Title string // submission title Title string // submission title
Score uint // updoots
URL string // duh URL string // duh
} }
@@ -27,6 +28,7 @@ type HNStoryRank struct {
Title string // submission title Title string // submission title
URL string // duh URL string // duh
Rank uint // frontpage index Rank uint // frontpage index
Score uint // updoots
FetchedAt time.Time // identical within fetchid FetchedAt time.Time // identical within fetchid
} }

View File

@@ -12,8 +12,6 @@ import (
"github.com/rs/zerolog" "github.com/rs/zerolog"
) )
const SQLITE_NULL_DATETIME = "0001-01-01 00:00:00+00:00"
func NewFetcher(db *gorm.DB) *Fetcher { func NewFetcher(db *gorm.DB) *Fetcher {
f := new(Fetcher) f := new(Fetcher)
f.db = db f.db = db
@@ -82,29 +80,39 @@ func (f *Fetcher) StoreFrontPage() error {
if err != nil { if err != nil {
return (err) return (err)
} }
/*
s := HNStoryRank{ s := HNStoryRank{
HNID: uint(id), HNID: uint(id),
Rank: uint(i + 1), Rank: uint(i + 1),
URL: item.URL, URL: item.URL,
Title: item.Title, Title: item.Title,
Score: item.Score,
FetchedAt: t, FetchedAt: t,
} }
*/
//f.log.Debug().Msgf("storing story with rank %d in db", (i + 1)) //f.log.Debug().Msgf("storing story with rank %d in db", (i + 1))
// FIXME this will grow unbounded and make the file too big if // FIXME this will grow unbounded and make the file too big if
// I don't clean this up or otherwise limit the data in here // I don't clean this up or otherwise limit the data in here
f.db.Create(&s) // disabled for now
//f.db.Create(&s)
//FIXME check to see if the same HNID was already on the frontpage
//or not so we don't spam the db
// check to see if the item was on the frontpage already or not // check to see if the item was on the frontpage already or not
var c int var c int
f.db.Model(&HNFrontPage{}).Where("hn_id = ? and disappeared is ?", id, SQLITE_NULL_DATETIME).Count(&c) f.db.Model(&HNFrontPage{}).Where("hn_id = ?", id).Count(&c)
if c == 0 { if c == 0 {
// first appearance on frontpage // first appearance on frontpage
r := HNFrontPage{ r := HNFrontPage{
HNID: uint(id), HNID: uint(id),
Appeared: t, Appeared: t,
Disappeared: time.Time{},
HighestRank: uint(i + 1), HighestRank: uint(i + 1),
Rank: uint(i + 1), Rank: uint(i + 1),
Title: item.Title, Title: item.Title,
Score: uint(item.Score),
URL: item.URL, URL: item.URL,
} }
f.db.Create(&r) f.db.Create(&r)
@@ -112,24 +120,25 @@ func (f *Fetcher) StoreFrontPage() error {
Uint("hnid", uint(id)). Uint("hnid", uint(id)).
Uint("rank", uint(i+1)). Uint("rank", uint(i+1)).
Str("title", item.Title). Str("title", item.Title).
Int("score", item.Score).
Str("url", item.URL). Str("url", item.URL).
Msg("HN new story on frontpage") Msg("HN new story on frontpage")
} else { } else {
// it's still here, compare its ranking // it's still here, (or back)
var old HNFrontPage var old HNFrontPage
f.db.Model(&HNFrontPage{}).Where("hn_id = ? and disappeared is ?", id, SQLITE_NULL_DATETIME).First(&old) f.db.Model(&HNFrontPage{}).Where("hn_id = ?", id).First(&old)
// FIXME update highestrank if new is lower
needSave := false
if old.Rank != uint(i+1) { if old.Rank != uint(i+1) {
f.log.Info(). f.log.Info().
Uint("hnid", uint(id)). Uint("hnid", uint(id)).
Uint("oldrank", old.Rank). Uint("oldrank", old.Rank).
Uint("newrank", uint(i+1)). Uint("newrank", uint(i+1)).
Int("score", item.Score).
Str("title", item.Title). Str("title", item.Title).
Str("url", item.URL). Str("url", item.URL).
Msg("HN story rank changed, recording new rank") Msg("HN story rank changed, recording new rank")
old.Rank = uint(i + 1) old.Rank = uint(i + 1)
needSave = true old.Score = uint(item.Score)
} }
if old.HighestRank > uint(i+1) { if old.HighestRank > uint(i+1) {
@@ -139,18 +148,22 @@ func (f *Fetcher) StoreFrontPage() error {
Uint("newrecord", uint(i+1)). Uint("newrecord", uint(i+1)).
Msg("recording new record high rank for story") Msg("recording new record high rank for story")
old.HighestRank = uint(i + 1) old.HighestRank = uint(i + 1)
needSave = true
} }
if needSave {
if old.Score != uint(item.Score) {
old.Score = uint(item.Score)
}
// in any case it's here now
old.Disappeared = time.Time{}
f.db.Save(&old) f.db.Save(&old)
} }
}
} }
// FIXME iterate over frontpage items still active in DB and note any // FIXME iterate over frontpage items still active in DB and note any
// that are no longer on the scrape // that are no longer on the scrape
fpitems, err := f.db.Model(&HNFrontPage{}).Where("disappeared is ?", SQLITE_NULL_DATETIME).Rows() fpitems, err := f.db.Model(&HNFrontPage{}).Where("disappeared is ?", time.Time{}).Rows()
if err != nil { if err != nil {
f.log.Error(). f.log.Error().
Err(err) Err(err)
@@ -181,8 +194,8 @@ func (f *Fetcher) StoreFrontPage() error {
} }
} }
fpitems.Close() // close tx before we do the update fpitems.Close() // close result before we do the update
f.db.Model(&HNFrontPage{}).Where("disappeared is ? and hn_id in (?)", SQLITE_NULL_DATETIME, toupdate).Update("Disappeared", t) f.db.Model(&HNFrontPage{}).Where("disappeared is ? and hn_id in (?)", time.Time{}, toupdate).Update("Disappeared", t)
return nil return nil
} }

View File

@@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"time" "time"
u "git.eeqj.de/sneak/goutil"
"github.com/flosch/pongo2" "github.com/flosch/pongo2"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/labstack/echo" "github.com/labstack/echo"
@@ -11,43 +12,54 @@ import (
type RequestHandlerSet struct { type RequestHandlerSet struct {
db *gorm.DB db *gorm.DB
version string
} }
func NewRequestHandlerSet(db *gorm.DB) *RequestHandlerSet { func NewRequestHandlerSet(version string, db *gorm.DB) *RequestHandlerSet {
rhs := new(RequestHandlerSet) rhs := new(RequestHandlerSet)
rhs.db = db rhs.db = db
rhs.version = version
return rhs return rhs
} }
func (r *RequestHandlerSet) indexHandler(c echo.Context) error { func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
last24h := time.Now().Add(time.Second * 86400 * -1)
var fpi []HNFrontPage var fpi []HNFrontPage
r.db.Where("disappeared is not ?", SQLITE_NULL_DATETIME).Order("disappeared desc").Find(&fpi) r.db.Where("disappeared is not ? and disappeared > ?", time.Time{}, last24h).Order("disappeared desc").Find(&fpi)
type fprow struct { type fprow struct {
Duration string Duration string
DurationSecs uint
URL string URL string
Title string Title string
HighestRank uint HighestRank uint
HNID uint HNID uint
Score uint
TimeGone string TimeGone string
TimeGoneSecs uint
} }
var fprows []fprow var fprows []fprow
for _, item := range fpi { for _, item := range fpi {
fprows = append(fprows, fprow{ fprows = append(fprows, fprow{
Duration: item.Disappeared.Round(time.Minute).Sub(item.Appeared.Round(time.Minute)).String(), Duration: u.TimeDiffHuman(item.Disappeared, item.Appeared),
DurationSecs: u.TimeDiffAbsSeconds(item.Disappeared, item.Appeared),
URL: item.URL, URL: item.URL,
HNID: item.HNID, HNID: item.HNID,
Score: item.Score,
Title: item.Title, Title: item.Title,
HighestRank: item.HighestRank, HighestRank: item.HighestRank,
TimeGone: time.Now().Round(time.Minute).Sub(item.Disappeared.Round(time.Minute)).String(), TimeGone: u.TimeDiffHuman(time.Now(), item.Disappeared),
TimeGoneSecs: u.TimeDiffAbsSeconds(time.Now(), item.Disappeared),
}) })
} }
type rowtwo struct { type rowtwo struct {
Duration string Duration string
DurationSecs uint
URL string URL string
Title string Title string
Score uint
HighestRank uint HighestRank uint
HNID uint HNID uint
Rank uint Rank uint
@@ -55,13 +67,15 @@ func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
var currentfp []rowtwo var currentfp []rowtwo
var cur []HNFrontPage var cur []HNFrontPage
r.db.Where("disappeared is ?", SQLITE_NULL_DATETIME).Order("rank asc").Find(&cur) r.db.Where("disappeared is ?", time.Time{}).Order("rank asc").Find(&cur)
for _, item := range cur { for _, item := range cur {
currentfp = append(currentfp, rowtwo{ currentfp = append(currentfp, rowtwo{
Duration: time.Now().Round(time.Minute).Sub(item.Appeared.Round(time.Minute)).String(), Duration: u.TimeDiffHuman(time.Now(), item.Appeared),
DurationSecs: u.TimeDiffAbsSeconds(time.Now(), item.Appeared),
URL: item.URL, URL: item.URL,
HNID: item.HNID, HNID: item.HNID,
Score: item.Score,
Title: item.Title, Title: item.Title,
HighestRank: item.HighestRank, HighestRank: item.HighestRank,
Rank: item.Rank, Rank: item.Rank,
@@ -72,6 +86,7 @@ func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
"time": time.Now().UTC().Format(time.RFC3339Nano), "time": time.Now().UTC().Format(time.RFC3339Nano),
"exits": fprows, "exits": fprows,
"current": currentfp, "current": currentfp,
"gitrev": r.version,
} }
return c.Render(http.StatusOK, "index.html", tc) return c.Render(http.StatusOK, "index.html", tc)
} }
@@ -79,6 +94,7 @@ func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
func (r *RequestHandlerSet) aboutHandler(c echo.Context) error { func (r *RequestHandlerSet) aboutHandler(c echo.Context) error {
tc := pongo2.Context{ tc := pongo2.Context{
"time": time.Now().UTC().Format(time.RFC3339Nano), "time": time.Now().UTC().Format(time.RFC3339Nano),
"gitrev": r.version,
} }
return c.Render(http.StatusOK, "about.html", tc) return c.Render(http.StatusOK, "about.html", tc)
} }

View File

@@ -122,7 +122,7 @@ func (a *App) runForever() int {
} }
a.e.Renderer = r a.e.Renderer = r
rhs := NewRequestHandlerSet(a.db) rhs := NewRequestHandlerSet(a.version, a.db)
// Routes // Routes
a.e.GET("/", rhs.indexHandler) a.e.GET("/", rhs.indexHandler)

View File

@@ -5,29 +5,27 @@
<div class="col-lg-12"> <div class="col-lg-12">
<h1>About This Site</h1> <h1>About This Site</h1>
<h2>IMPORTANT</h2> <h2>⚠️ Important!</h2>
<p>This is a third-party site, not affiliated with HN, provided for <p>This is a third-party site, not affiliated in any way with HN,
informational purposes only. <b>Do not</b> contact or hassle HN provided for informational purposes only.</p>
administrators about any information you learn here. Their site,
their rules. I repeat: <b>Do not hassle or interrogate the HN admins.</b>
</p>
<h2>Why?</h2> <h2>Why?</h2>
<p>I like reading stuff on the internet that is of interest to HN voters, <p>I like reading stuff on the internet that is of interest to HN
even if the HN administrators think it's off topic and don't want it on voters, even if the HN administrators think it's off topic and don't
the frontpage, which is a decision I respect. Again, their site, their want it on the frontpage, which is a decision I respect. Their
rules.</p> site, their rules.
<small>(<a href="https://news.ycombinator.com/item?id=22643777">more
info</a>)</small>
</p>
<h2>How?</h2> <h2>How?</h2>
<p><a href="https://git.eeqj.de/sneak/hntransparencylog">Go</a> and the <p>Go and the
graciously provided <a href="https://github.com/HackerNews/API">HN graciously provided <a href="https://github.com/HackerNews/API">HN
API</a>.</p> API</a>.</p>
<h2>Who</h2>
<p><a href="mailto:sneak@sneak.berlin">@sneak</a>.</p>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -13,16 +13,10 @@
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<style> <style>
body { {% include "style.css" %}
background: #f6f6ef;
}
#pagebody {
margin-top: 4em;
}
</style> </style>
{% include "matomo.html" %}
</head> </head>
<body> <body>

10
view/bodyfooter.html Normal file
View File

@@ -0,0 +1,10 @@
<footer>
<small>
A project by <a href="https://sneak.berlin">@sneak</a>.
&nbsp;&nbsp;&nbsp;&nbsp;
<code>{{gitrev}}</code>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="http://git.eeqj.de/sneak/orangesite">source</a> (<a
href="https://en.wikipedia.org/wiki/WTFPL">WTFPL</a>)
</small>
</footer>

View File

@@ -4,14 +4,15 @@
<div class="col-lg-12"> <div class="col-lg-12">
<h2>Links Exiting The Front Page</h2> <h2>Links Exiting The Front Page <small>(last 24h)</small></h2>
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
<thead class="thead-dark"> <thead class="thead-dark">
<tr> <tr>
<th scope="col">Hang Time</th> <th scope="col">Hang Time</th>
<th scope="col">Title</th> <th scope="col">Title</th>
<th scope="col">Highest Rank</th> <th scope="col">Highest Rank</th>
<th scope="col">Time Since Wipeout</th> <th scope="col">Time Since <a
href="https://www.youtube.com/watch?v=p13yZAjhU0M">Wipeout</a></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -21,8 +22,13 @@
--> -->
<tr> <tr>
{% if exit.DurationSecs < 1800 %}
<td scope="row" class="text-danger">{{exit.Duration}}</th>
{% else %}
<td scope="row">{{exit.Duration}}</th> <td scope="row">{{exit.Duration}}</th>
<td><a href="{{exit.URL}}">{{exit.Title}}</a> <small>(<a {% endif %}
<td><a href="{{exit.URL}}">{{exit.Title}}</a> <small>({{exit.Score}}
points, <a
href="https://news.ycombinator.com/item?id={{exit.HNID}}">comments</a>)</small></td> href="https://news.ycombinator.com/item?id={{exit.HNID}}">comments</a>)</small></td>
<td>{{exit.HighestRank}}</td> <td>{{exit.HighestRank}}</td>
<td>{{exit.TimeGone}}</td> <td>{{exit.TimeGone}}</td>
@@ -47,7 +53,7 @@
<tr> <tr>
<td scope="row">{{i.Duration}}</th> <td scope="row">{{i.Duration}}</th>
<td><a href="{{i.URL}}">{{i.Title}}</a> <small>(<a <td><a href="{{i.URL}}">{{i.Title}}</a> <small>({{i.Score}} points, <a
href="https://news.ycombinator.com/item?id={{i.HNID}}">comments</a>)</small></td> href="https://news.ycombinator.com/item?id={{i.HNID}}">comments</a>)</small></td>
<td>{{i.HighestRank}}</td> <td>{{i.HighestRank}}</td>
</tr> </tr>
@@ -55,8 +61,5 @@
</tbody> </tbody>
</table> </table>
<small>{{ time }}</small>
</div> </div>
{% endblock %} {% endblock %}

14
view/matomo.html Normal file
View File

@@ -0,0 +1,14 @@
<script type="text/javascript">
var _paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://t.sneak.cloud/";
_paq.push(['setTrackerUrl', u+'js/']);
_paq.push(['setSiteId', '2']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'js/'; s.parentNode.insertBefore(g,s);
})();
</script>
<noscript><p><img src="https://t.sneak.cloud/js/?idsite=2&amp;rec=1" style="border:0;" alt="" /></p></noscript>

View File

@@ -12,4 +12,5 @@
{% endblock %} {% endblock %}
</div> </div>
</div> </div>
{% include "bodyfooter.html" %}
{% endblock %} {% endblock %}

18
view/style.css Normal file
View File

@@ -0,0 +1,18 @@
body {
background: #f6f6ef;
}
#pagebody {
margin-top: 4em;
}
footer {
padding-left: 1em;
padding-top: 2em;
padding-bottom: 0.5em;
}
h1,h2,h3,h4 {
padding-top: 1em;
padding-bottom: 0.25em;
}