some clean up

added Makefile
This commit is contained in:
Mahmoud Rahbar Azad 2018-10-25 21:18:45 +02:00
parent 8f1463b2ef
commit 5d5c779b43
No known key found for this signature in database
GPG Key ID: 7DBBD39E2BFEB784
8 changed files with 98 additions and 43 deletions

44
Makefile Normal file
View File

@ -0,0 +1,44 @@
SHELL := /bin/bash
TARGET := hetzner-sb-notifier
.DEFAULT_GOAL: $(TARGET)
# These will be provided to the target
VERSION := 1.0.0
BUILD := `git rev-parse HEAD`
.PHONY: all build clean uninstall fmt simplify check run
all: check build
$(TARGET):
@go build -o $(TARGET)
build: $(TARGET)
@true
clean:
@echo "Performing clean"
@rm -f $(TARGET)
uninstall: clean
@echo "Performing uninstall"
@rm -f $$(which ${TARGET})
fmt:
@echo "Performing fmt"
@gofmt -l -w .
simplify:
@echo "Performing simplify"
@gofmt -s -l -w .
check:
@echo "Performing check"
@test -z $(shell gofmt -l main.go | tee /dev/stderr) || echo "[WARN] Fix formatting issues with 'make fmt'"
@for d in $$(go list ./...); do golint $${d}; done
@go tool vet .
run: install
@echo "Performing run"
@$(TARGET)

View File

@ -1,6 +1,10 @@
The aim of my-bloody-hetzner-sb-notifier is a simple CLI to fetch the current Hetzner Serverbörse deals and filter them according to CLI parameters sorted by score.
The score is calculated from the amount of HDD space as well as RAM and CPU-Benchnmark for better comparability.
The CLI interface looks like this:
```` ````
Usage of my-bloody-hetzner-sb-notifier: Usage of hetzner-sb-notifier:
-alert-on-score int -alert-on-score int
set alert on score set alert on score
-max-benchmark int -max-benchmark int
@ -23,11 +27,19 @@ Usage of my-bloody-hetzner-sb-notifier:
set min price set min price
-min-ram int -min-ram int
set min ram set min ram
-notifier-password string ````
set notifier password
-notifier-recipient string
set notifier recipient
-notifier-sender string
set notifier sender
```` ## Example
./hetzner-sb-notifier --max-price 77 --min-ram 128 --min-hdd-count 2 --min-hdd-size 4096
````
Got 545 offers. Filtered offers: 3
ID| Ram| HDD| CPU| Price| Score| Reduce time|Specials
SB64-935022| 128 GB| 2x 2 TB (4096)| Intel Xeon E5-1650V2 (12518)| 64.00 €| 91.84| 47h 48m|ECC, Ent. HDD, iNIC
SB72-927788| 128 GB| 2x 2 TB (4096)| Intel Xeon E5-1650V3 (13335)| 72.00 €| 86.17| 21h 08m|ECC, Ent. HDD, iNIC
SB73-910394| 128 GB| 3x 2 TB (6144)| Intel Xeon E5-1650V2 (12518)| 73.00 €| 86.13| 03h 04m|ECC, Ent. HDD, iNIC
````
## Build
The Go project uses Go Modules

View File

@ -12,7 +12,7 @@ type Client struct {
func NewClient() *Client { func NewClient() *Client {
crawler := &Client{ crawler := &Client{
&http.Client{Timeout: 10 * time.Second} , &http.Client{Timeout: 10 * time.Second},
} }
return crawler return crawler

View File

@ -67,16 +67,15 @@ func (c *Crawler) Print(servers []hetzner.Server) {
c.tabWriter.Flush() c.tabWriter.Flush()
} }
func (c *Crawler) isFiltered(server hetzner.Server) bool { func (c *Crawler) isFiltered(server hetzner.Server) bool {
filtered := true filtered := true
priceParsed := server.ParsePrice() priceParsed := server.ParsePrice()
if server.Cpu_benchmark >= c.minBenchmark && server.Cpu_benchmark <= c.maxBenchmark && if server.CpuBenchmark >= c.minBenchmark && server.CpuBenchmark <= c.maxBenchmark &&
priceParsed >= c.minPrice && priceParsed <= c.maxPrice && priceParsed >= c.minPrice && priceParsed <= c.maxPrice &&
server.Ram >= c.minRam && server.Ram <= c.maxRam && server.Ram >= c.minRam && server.Ram <= c.maxRam &&
server.TotalHdd() >= c.minHddSize && server.TotalHdd() <= c.maxHddSize && server.TotalHdd() >= c.minHddSize && server.TotalHdd() <= c.maxHddSize &&
server.Hdd_count >= c.minHddCount && server.Hdd_count <= c.maxHddCount { server.HddCount >= c.minHddCount && server.HddCount <= c.maxHddCount {
filtered = false filtered = false
} }

View File

@ -7,6 +7,6 @@ import (
const hetznerlivedataurl = "https://www.hetzner.de/a_hz_serverboerse/live_data.json" const hetznerlivedataurl = "https://www.hetzner.de/a_hz_serverboerse/live_data.json"
func MakeUrl() string { func MakeURL() string {
return fmt.Sprintf("%s?m=%v", hetznerlivedataurl, time.Now().UnixNano()) return fmt.Sprintf("%s?m=%v", hetznerlivedataurl, time.Now().UnixNano())
} }

View File

@ -19,45 +19,45 @@ type Server struct {
Datacenter []string `json:"datacenter"` Datacenter []string `json:"datacenter"`
Specials []string `json:"specials"` Specials []string `json:"specials"`
Traffic string `json:"traffic"` Traffic string `json:"traffic"`
Bandwith int `json:"bandwith"` Bandwidth int `json:"bandwith"`
Price string `json:"price"` Price string `json:"price"`
Price_v string `json:"price_v"` PriceV string `json:"price_v"`
Setup_price string `json:"setup_price"` SetupPrice string `json:"setup_price"`
Cpu string `json:"cpu"` Cpu string `json:"cpu"`
Cpu_benchmark int `json:"cpu_benchmark"` CpuBenchmark int `json:"cpu_benchmark"`
Cpu_count int `json:"cpu_count"` CpuCount int `json:"cpu_count"`
Ram int `json:"ram"` Ram int `json:"ram"`
Ram_hr string `json:"ram_hr"` RamHr string `json:"ram_hr"`
Hdd_size int `json:"hdd_size"` HddSize int `json:"hdd_size"`
Hdd_hr string `json:"hdd_hr"` HddHr string `json:"hdd_hr"`
Hdd_count int `json:"hdd_count"` HddCount int `json:"hdd_count"`
SpecialHdd string `json:"specialHdd"` SpecialHdd string `json:"specialHdd"`
Next_reduce int `json:"next_reduce"` NextReduce int `json:"next_reduce"`
Next_reduce_hr string `json:"next_reduce_hr"` NextReduceHr string `json:"next_reduce_hr"`
Fixed_price bool `json:"fixed_price"` FixedPrice bool `json:"fixed_price"`
Is_highio bool `json:"is_highio"` IsHighio bool `json:"is_highio"`
Is_ecc bool `json:"is_ecc"` IsEcc bool `json:"is_ecc"`
} }
func (s *Server) TotalHdd() int { func (s *Server) TotalHdd() int {
return s.Hdd_count*s.Hdd_size return s.HddCount * s.HddSize
} }
func (s *Server) Score() float64 { func (s *Server) Score() float64 {
return (float64(s.TotalHdd())*0.2 + float64(s.Ram)*0.4 + float64(s.Cpu_benchmark)*0.4)/s.ParsePrice() return (float64(s.TotalHdd())*0.2 + float64(s.Ram)*0.4 + float64(s.CpuBenchmark)*0.4) / s.ParsePrice()
} }
func (s *Server) ParsePrice() float64 { func (s *Server) ParsePrice() float64 {
priceParsed, err := strconv.ParseFloat(s.Price, 32) priceParsed, err := strconv.ParseFloat(s.Price, 32)
if err != nil { if err != nil {
fmt.Printf("Could not parse price %s for server %s: %s", s.Price, s.Key, err) fmt.Printf("Could not parse price %s for server %d: %s", s.Price, s.Key, err)
return -1 return -1
} }
return priceParsed*1.19 return priceParsed * 1.19
} }
func (s *Server) Header() string { func (s *Server) Header() string {
@ -66,9 +66,9 @@ func (s *Server) Header() string {
func (s *Server) ToString() string { func (s *Server) ToString() string {
fixedPriceSymbol := "*" fixedPriceSymbol := "*"
if !s.Fixed_price { if !s.FixedPrice {
fixedPriceSymbol = "" fixedPriceSymbol = ""
} }
specials := strings.Join(s.Specials, ", ") specials := strings.Join(s.Specials, ", ")
return fmt.Sprintf("%s-%d\t%s\t%s (%d)\t%s (%d)\t%.2f €%s\t%.2f\t%s\t%s", s.Name, s.Key, s.Ram_hr, s.Hdd_hr, s.TotalHdd(), s.Cpu, s.Cpu_benchmark, s.ParsePrice(), fixedPriceSymbol, s.Score(), s.Next_reduce_hr, specials) return fmt.Sprintf("%s-%d\t%s\t%s (%d)\t%s (%d)\t%.2f €%s\t%.2f\t%s\t%s", s.Name, s.Key, s.RamHr, s.HddHr, s.TotalHdd(), s.Cpu, s.CpuBenchmark, s.ParsePrice(), fixedPriceSymbol, s.Score(), s.NextReduceHr, specials)
} }

View File

@ -1,11 +1,11 @@
package instrumentation package instrumentation
type Instrumenter struct{ type Instrumenter struct {
projectId string projectID string
} }
func NewInstrumenter(projectId string) *Instrumenter { func NewInstrumenter(projectID string) *Instrumenter {
return &Instrumenter{ return &Instrumenter{
projectId: projectId, projectID: projectID,
} }
} }

View File

@ -75,7 +75,7 @@ func main() {
flag.Parse() flag.Parse()
offers := &hetzner.Offers{} offers := &hetzner.Offers{}
err := client.NewClient().DoRequest(hetzner.MakeUrl(), offers) err := client.NewClient().DoRequest(hetzner.MakeURL(), offers)
if err != nil { if err != nil {
panic(fmt.Errorf("failed to get hetzner live data: %s", err)) panic(fmt.Errorf("failed to get hetzner live data: %s", err))
} }