diff --git a/.gitignore b/.gitignore index 5ad385c..5b604d3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ *.out server +storage.db diff --git a/Makefile b/Makefile index 8c72eeb..15633c0 100644 --- a/Makefile +++ b/Makefile @@ -47,8 +47,7 @@ lint: fmt .lintsetup go-get: cd cmd/$(FN) && go get -v -#./$(FN): */*.go cmd/*/*.go go-get -./$(FN): cmd/*/*.go go-get +./$(FN): */*.go cmd/*/*.go go-get cd cmd/$(FN) && go build -o ../../$(FN) $(GOFLAGS) . fmt: diff --git a/_layouts/base.html b/_layouts/base.html deleted file mode 100644 index 2b6825e..0000000 --- a/_layouts/base.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - {{block "title" .}} - default title - {{end}} - - - - - - - - {{block "body" .}} - - - - -
-
-
-

A Bootstrap 4 Starter Template

-

Complete with pre-defined file paths and responsive navigation!

-
    -
  • Bootstrap 4.3.1
  • -
  • jQuery 3.4.1
  • -
-
-
-
- {{end}} - - - - - - - - diff --git a/_pages/index.html b/_pages/index.html deleted file mode 100644 index d61de61..0000000 --- a/_pages/index.html +++ /dev/null @@ -1 +0,0 @@ -indexpage diff --git a/cmd/server/main.go b/cmd/server/main.go index 2ebbfb4..c35bb46 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -1,3 +1,4 @@ +//go:generate go run github.com/UnnoTed/fileb0x b0x.yaml package main import ( diff --git a/go.mod b/go.mod index cb21b04..9c62757 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,19 @@ module git.eeqj.de/sneak/hntransparencylog go 1.14 require ( + github.com/UnnoTed/fileb0x v1.1.4 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 github.com/jinzhu/gorm v1.9.12 + github.com/k0kubun/pp v3.0.1+incompatible github.com/labstack/echo v3.3.10+incompatible github.com/labstack/echo/v4 v4.1.15 github.com/labstack/gommon v0.3.0 github.com/mattn/go-isatty v0.0.12 + 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/rs/zerolog v1.18.0 github.com/ziflex/lecho/v2 v2.0.0 + golang.org/x/net v0.0.0-20200226121028-0de0cce0169b ) diff --git a/go.sum b/go.sum index 7d55488..ec67a62 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,22 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/UnnoTed/fileb0x v1.1.4 h1:IUgFzgBipF/ujNx9wZgkrKOF3oltUuXMSoaejrBws+A= +github.com/UnnoTed/fileb0x v1.1.4/go.mod h1:X59xXT18tdNk/D6j+KZySratBsuKJauMtVuJ9cgOiZs= +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/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/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/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/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/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-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/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -13,24 +25,57 @@ github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= 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/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +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/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/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/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/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= 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.15/go.mod h1:GWO5IBVzI371K8XJe50CSvHjQCafK6cw8R/moLhEU6o= +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/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= 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/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 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-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.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 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-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/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +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/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/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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -38,9 +83,11 @@ 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/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= 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/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 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/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4= github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= @@ -48,6 +95,7 @@ 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/v2 v2.0.0 h1:ggrWF5LaGAC+Y+WX71jFK7uYR7cUFbHjIgGqCyrYC5Q= 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-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -55,12 +103,14 @@ golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPh 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/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 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/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -72,9 +122,13 @@ 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/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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/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= diff --git a/hn/db.go b/hn/db.go new file mode 100644 index 0000000..df78766 --- /dev/null +++ b/hn/db.go @@ -0,0 +1,29 @@ +package hn + +import ( + "time" + + "github.com/jinzhu/gorm" +) + +type HNStoryRank struct { + gorm.Model + InternalStoryID uint64 `gorm:"primary_key;auto_increment:true` + HNID uint // HN integer id + Title string // submission title + URL string // duh + FetchID uint // integer identifying fetch batch + Rank uint // frontpage index + FetchedAt time.Time // identical within fetchid +} + +type FrontPageCache struct { + gorm.Model + CacheID uint64 `gorm:"primary_key;auto_increment:true` + HNID uint + HighestRankReached uint + URL string + Title string + Appeared time.Time + Disappeared time.Time +} diff --git a/hn/fetcher.go b/hn/fetcher.go new file mode 100644 index 0000000..8d37570 --- /dev/null +++ b/hn/fetcher.go @@ -0,0 +1,83 @@ +package hn + +import ( + "net/http" + "time" + + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/sqlite" + "github.com/peterhellberg/hn" + "github.com/rs/zerolog" +) + +func NewFetcher(db *gorm.DB) *Fetcher { + f := new(Fetcher) + f.db = db + f.fetchIntervalSecs = 60 + f.hn = hn.NewClient(&http.Client{ + Timeout: time.Duration(5 * time.Second), + }) + return f +} + +type Fetcher struct { + nextFetch time.Time + fetchIntervalSecs uint + db *gorm.DB + hn *hn.Client + log *zerolog.Logger +} + +func (f *Fetcher) AddLogger(l *zerolog.Logger) { + f.log = l +} + +func (f *Fetcher) run() { + f.db.AutoMigrate(&HNStoryRank{}) + f.db.AutoMigrate(&FrontPageCache{}) + + for { + f.log.Info(). + Msg("fetching top stories from HN") + f.nextFetch = time.Now().Add(time.Duration(f.fetchIntervalSecs) * time.Second) + err := f.StoreFrontPage() + if err != nil { + panic(err) + } + until := time.Until(f.nextFetch) + countdown := time.NewTimer(until) + f.log.Info().Msgf("waiting %s until next fetch", until) + <-countdown.C + } +} + +func (f *Fetcher) StoreFrontPage() error { + + // FIXME set fetchid + r := f.db.Select("max(FetchID)").Find(&HNStoryRank) + + ids, err := f.hn.TopStories() + t := time.Now() + if err != nil { + return err + } + + for i, id := range ids[:30] { + + item, err := f.hn.Item(id) + if err != nil { + return (err) + } + s := HNStoryRank{ + HNID: uint(id), + FetchID: uint(0), + Rank: uint(i + 1), + URL: item.URL, + Title: item.Title, + FetchedAt: t, + } + f.log.Info().Msgf("storing story with rank %d in db", (i + 1)) + f.db.Create(&s) + } + return nil +} diff --git a/hn/handlers.go b/hn/handlers.go index 42be59f..a7b70f6 100644 --- a/hn/handlers.go +++ b/hn/handlers.go @@ -2,10 +2,22 @@ package hn import ( "net/http" + "time" + "github.com/flosch/pongo2" "github.com/labstack/echo" ) func indexHandler(c echo.Context) error { - return c.Render(http.StatusOK, "index", nil) + tc := pongo2.Context{ + "time": time.Now().UTC().Format(time.RFC3339Nano), + } + return c.Render(http.StatusOK, "index.html", tc) +} + +func aboutHandler(c echo.Context) error { + tc := pongo2.Context{ + "time": time.Now().UTC().Format(time.RFC3339Nano), + } + return c.Render(http.StatusOK, "about.html", tc) } diff --git a/hn/server.go b/hn/server.go index eb47cff..a9bfe0f 100644 --- a/hn/server.go +++ b/hn/server.go @@ -8,19 +8,23 @@ import ( _ "github.com/jinzhu/gorm/dialects/sqlite" "github.com/labstack/echo" "github.com/labstack/echo/middleware" - "github.com/labstack/gommon/log" + gl "github.com/labstack/gommon/log" + "github.com/mattn/go-isatty" + ep2 "github.com/mayowa/echo-pongo2" "github.com/ziflex/lecho/v2" -) -// required for orm + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" +) type App struct { version string buildarch string e *echo.Echo - logger *string + log *zerolog.Logger db *gorm.DB startup time.Time + fetcher *Fetcher } func RunServer(version string, buildarch string) int { @@ -28,18 +32,69 @@ func RunServer(version string, buildarch string) int { a.version = version a.buildarch = buildarch a.startup = time.Now() - a.runForever() - return 0 + + a.init() + defer a.db.Close() + + a.fetcher = NewFetcher(a.db) + a.fetcher.AddLogger(a.log) + + go a.fetcher.run() + + return a.runForever() } -func (a *App) runForever() { +func (a *App) init() { + // setup logging + l := log.With().Caller().Logger() + log.Logger = l + tty := isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) + if tty { + out := zerolog.NewConsoleWriter( + func(w *zerolog.ConsoleWriter) { + // Customize time format + w.TimeFormat = time.RFC3339 + }, + ) + log.Logger = log.Output(out) + } + // always log in UTC + zerolog.TimestampFunc = func() time.Time { + return time.Now().UTC() + } + zerolog.SetGlobalLevel(zerolog.InfoLevel) + if os.Getenv("DEBUG") != "" { + zerolog.SetGlobalLevel(zerolog.DebugLevel) + } + + a.log = &log.Logger + + a.identify() + + // open db + // FIXME make configurable path + db, err := gorm.Open("sqlite3", "storage.db") + if err != nil { + panic("failed to connect database") + } + a.db = db +} + +func (a *App) identify() { + log.Info(). + Str("version", a.version). + Str("buildarch", a.buildarch). + Msg("starting") +} + +func (a *App) runForever() int { // Echo instance a.e = echo.New() - lev := log.INFO + lev := gl.INFO if os.Getenv("DEBUG") != "" { - lev = log.DEBUG + lev = gl.DEBUG } logger := lecho.New( @@ -55,11 +110,17 @@ func (a *App) runForever() { a.e.Use(middleware.Logger()) a.e.Use(middleware.Recover()) - a.e.Renderer = NewTemplate("./view/") - + r, err := ep2.NewRenderer("view") + if err != nil { + a.e.Logger.Fatal(err) + } + a.e.Renderer = r // Routes a.e.GET("/", indexHandler) + a.e.GET("/about", aboutHandler) // Start server a.e.Logger.Fatal(a.e.Start(":8080")) + + return 0 //FIXME setup graceful shutdown } diff --git a/hn/templates.go b/hn/templates.go deleted file mode 100644 index f4a304a..0000000 --- a/hn/templates.go +++ /dev/null @@ -1,40 +0,0 @@ -package hn - -import ( - "errors" - "html/template" - "io" - - "github.com/labstack/echo" -) - -// Define the template registry struct -type TemplateRegistry struct { - templates map[string]*template.Template -} - -// Implement e.Renderer interface -func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c echo.Context) error { - tmpl, ok := t.templates[name] - if !ok { - err := errors.New("Template not found -> " + name) - return err - } - return tmpl.ExecuteTemplate(w, "base.html", data) -} - -func NewTemplate(templatesDir string) *TemplateRegistry { - //ext := ".html" - - ins := TemplateRegistry{ - templates: map[string]*template.Template{}, - } - - //layout := templatesDir + "base" + ext - - templates := make(map[string]*template.Template) - templates["index"] = template.Must(template.ParseFiles("_pages/index.html", "_layouts/base.html")) - //templates["about.html"] = template.Must(template.ParseFiles("view/about.html", "view/base.html")) - - return &ins -} diff --git a/view/about.html b/view/about.html new file mode 100644 index 0000000..fb108ca --- /dev/null +++ b/view/about.html @@ -0,0 +1,29 @@ +{% extends "page.html" %} + +{% block content %} + +
+

About

+
+ +

First Let's Get One Thing Straight

+ +

This is a third-party site, not affiliated with HN, provided for + informational purposes only. Do not contact or hassle HN + administrators about any information you learn here.

+ +

Why?

+ +

I like reading stuff on the internet that is of interest to HN voters, + even if the HN administrators think it's off topic.

+ +

How?

+ +

Go and the + graciously-provided HN + API.

+ +

{{ time }}

+ +
+{% endblock %} diff --git a/view/base.html b/view/base.html new file mode 100644 index 0000000..f1ead83 --- /dev/null +++ b/view/base.html @@ -0,0 +1,31 @@ + + + + + + + + + {{ htmltitle }} + + + + + + + + {% block body %} + {% endblock %} + + + + + + diff --git a/view/index.html b/view/index.html new file mode 100644 index 0000000..16099e9 --- /dev/null +++ b/view/index.html @@ -0,0 +1,9 @@ +{% extends "page.html" %} + +{% block content %} +
+

Index Page

+ +

{{ time }}

+
+{% endblock %} diff --git a/view/navbar.html b/view/navbar.html new file mode 100644 index 0000000..00e3e6a --- /dev/null +++ b/view/navbar.html @@ -0,0 +1,19 @@ + + diff --git a/view/page.html b/view/page.html new file mode 100644 index 0000000..c0e91e2 --- /dev/null +++ b/view/page.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} + +{% block body %} + {% include "navbar.html" %} + +
+
+ {% block content %} +
+

View Not Found

+
+ {% endblock %} +
+
+{% endblock %}