made to suck less, including:
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			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
This commit is contained in:
		
							parent
							
								
									fe1c4df4f1
								
							
						
					
					
						commit
						0d9ed8874f
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -13,4 +13,4 @@
 | 
				
			|||||||
*.out
 | 
					*.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
server
 | 
					server
 | 
				
			||||||
storage.db
 | 
					storage.sqlite
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							@ -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')
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							@ -6,6 +6,7 @@ require (
 | 
				
			|||||||
	github.com/UnnoTed/fileb0x v1.1.4 // indirect
 | 
						github.com/UnnoTed/fileb0x v1.1.4 // indirect
 | 
				
			||||||
	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
 | 
						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/k0kubun/pp v3.0.1+incompatible
 | 
				
			||||||
	github.com/labstack/echo v3.3.10+incompatible
 | 
						github.com/labstack/echo v3.3.10+incompatible
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							@ -20,6 +20,8 @@ github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclK
 | 
				
			|||||||
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=
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								hn/db.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								hn/db.go
									
									
									
									
									
								
							@ -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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -88,6 +88,7 @@ func (f *Fetcher) StoreFrontPage() error {
 | 
				
			|||||||
				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,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		*/
 | 
							*/
 | 
				
			||||||
@ -109,6 +110,7 @@ func (f *Fetcher) StoreFrontPage() error {
 | 
				
			|||||||
				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)
 | 
				
			||||||
@ -116,6 +118,7 @@ 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 {
 | 
				
			||||||
@ -129,10 +132,12 @@ func (f *Fetcher) StoreFrontPage() error {
 | 
				
			|||||||
					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)
 | 
				
			||||||
 | 
									old.Score = uint(item.Score)
 | 
				
			||||||
				needSave = true
 | 
									needSave = true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -145,6 +150,12 @@ func (f *Fetcher) StoreFrontPage() error {
 | 
				
			|||||||
				old.HighestRank = uint(i + 1)
 | 
									old.HighestRank = uint(i + 1)
 | 
				
			||||||
				needSave = true
 | 
									needSave = true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if old.Score != uint(item.Score) {
 | 
				
			||||||
 | 
									old.Score = uint(item.Score)
 | 
				
			||||||
 | 
									needSave = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if needSave {
 | 
								if needSave {
 | 
				
			||||||
				f.db.Save(&old)
 | 
									f.db.Save(&old)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -24,33 +24,41 @@ func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
 | 
				
			|||||||
	r.db.Where("disappeared is not ?", SQLITE_NULL_DATETIME).Order("disappeared desc").Find(&fpi)
 | 
						r.db.Where("disappeared is not ?", SQLITE_NULL_DATETIME).Order("disappeared desc").Find(&fpi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type fprow struct {
 | 
						type fprow struct {
 | 
				
			||||||
		Duration    string
 | 
							Duration     string
 | 
				
			||||||
		URL         string
 | 
							DurationSecs uint
 | 
				
			||||||
		Title       string
 | 
							URL          string
 | 
				
			||||||
		HighestRank uint
 | 
							Title        string
 | 
				
			||||||
		HNID        uint
 | 
							HighestRank  uint
 | 
				
			||||||
		TimeGone    string
 | 
							HNID         uint
 | 
				
			||||||
 | 
							Score        uint
 | 
				
			||||||
 | 
							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:     timeDiffHuman(item.Disappeared, item.Appeared),
 | 
				
			||||||
			URL:         item.URL,
 | 
								DurationSecs: timeDiffAbsSeconds(item.Disappeared, item.Appeared),
 | 
				
			||||||
			HNID:        item.HNID,
 | 
								URL:          item.URL,
 | 
				
			||||||
			Title:       item.Title,
 | 
								HNID:         item.HNID,
 | 
				
			||||||
			HighestRank: item.HighestRank,
 | 
								Score:        item.Score,
 | 
				
			||||||
			TimeGone:    time.Now().Round(time.Minute).Sub(item.Disappeared.Round(time.Minute)).String(),
 | 
								Title:        item.Title,
 | 
				
			||||||
 | 
								HighestRank:  item.HighestRank,
 | 
				
			||||||
 | 
								TimeGone:     timeDiffHuman(time.Now(), item.Disappeared),
 | 
				
			||||||
 | 
								TimeGoneSecs: timeDiffAbsSeconds(time.Now(), item.Disappeared),
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type rowtwo struct {
 | 
						type rowtwo struct {
 | 
				
			||||||
		Duration    string
 | 
							Duration     string
 | 
				
			||||||
		URL         string
 | 
							DurationSecs uint
 | 
				
			||||||
		Title       string
 | 
							URL          string
 | 
				
			||||||
		HighestRank uint
 | 
							Title        string
 | 
				
			||||||
		HNID        uint
 | 
							Score        uint
 | 
				
			||||||
		Rank        uint
 | 
							HighestRank  uint
 | 
				
			||||||
 | 
							HNID         uint
 | 
				
			||||||
 | 
							Rank         uint
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var currentfp []rowtwo
 | 
						var currentfp []rowtwo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -59,12 +67,14 @@ func (r *RequestHandlerSet) indexHandler(c echo.Context) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	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:     timeDiffHuman(time.Now(), item.Appeared),
 | 
				
			||||||
			URL:         item.URL,
 | 
								DurationSecs: timeDiffAbsSeconds(time.Now(), item.Appeared),
 | 
				
			||||||
			HNID:        item.HNID,
 | 
								URL:          item.URL,
 | 
				
			||||||
			Title:       item.Title,
 | 
								HNID:         item.HNID,
 | 
				
			||||||
			HighestRank: item.HighestRank,
 | 
								Score:        item.Score,
 | 
				
			||||||
			Rank:        item.Rank,
 | 
								Title:        item.Title,
 | 
				
			||||||
 | 
								HighestRank:  item.HighestRank,
 | 
				
			||||||
 | 
								Rank:         item.Rank,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								hn/misc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								hn/misc.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					package hn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"math"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/hako/durafmt"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func timeDiffHuman(first time.Time, second time.Time) string {
 | 
				
			||||||
 | 
						if first.Before(second) {
 | 
				
			||||||
 | 
							return durafmt.ParseShort(second.Sub(first)).String()
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return durafmt.ParseShort(first.Sub(second)).String()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func timeDiffAbsSeconds(first time.Time, second time.Time) uint {
 | 
				
			||||||
 | 
						return uint(math.Abs(first.Sub(second).Truncate(time.Second).Seconds()))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -11,7 +11,8 @@
 | 
				
			|||||||
  <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>
 | 
				
			||||||
      <td scope="row">{{exit.Duration}}</th>
 | 
					        {% if exit.DurationSecs < 1800 %}
 | 
				
			||||||
      <td><a href="{{exit.URL}}">{{exit.Title}}</a> <small>(<a
 | 
					          <td scope="row" class="text-danger">{{exit.Duration}}</th>
 | 
				
			||||||
 | 
					      {% else %}
 | 
				
			||||||
 | 
					          <td scope="row">{{exit.Duration}}</th>
 | 
				
			||||||
 | 
					        {% 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>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user