<commit_before>/*
fperf allows you to build your performace tools easily

Three steps to create your own testcase

1. Create the "NewClient" function

	package demo

	import (
		"fmt"
		"github.com/shafreeck/fperf/client"
		"time"
	)

	type DemoClient struct{}

	func NewDemoClient(flag *client.FlagSet) client.Client {
		return &DemoClient{}
	}

2. Implement the UnaryClient or StreamClient

	func (c *DemoClient) Dial(addr string) error {
		fmt.Println("Dial to", addr)
		return nil
	}

	func (c *DemoClient) Request() error {
		time.Sleep(100 * time.Millisecond)
		return nil
	}

3. Register to fperf

	func init() {
		client.Register("demo", NewDemoClient, "This is a demo client discription")
	}

Run the buildin testcase

http is a simple builtin testcase to benchmark http servers

	fperf -cpu 8 -connection 10 http http://example.com
*/
package main

import (
	"flag"
	"fmt"
	db "github.com/influxdata/influxdb/client/v2"
	"github.com/shafreeck/fperf/client"
	hist "github.com/shafreeck/fperf/stats"
	"golang.org/x/net/context"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"runtime"
	"sync"
	"syscall"
	"time"
)

type setting struct {
	Connection int
	Stream     int
	Goroutine  int
	CPU        int
	Burst      int
	N          int //number of requests
	Tick       time.Duration
	Address    string
	Send       bool
	Recv       bool
	Delay      time.Duration
	Async      bool
	Target     string
	CallType   string
	InfluxDB   string
}

type statistics struct {
	latencies []time.Duration
	histogram *hist.Histogram
}

type roundtrip struct {
	start time.Time
	end   time.Time
	ack   bool
}

func createClients(n int, addr string) []client.Client {
	clients := make([]client.Client, n)
	for i := 0; i < n; i++ {
		cli := client.NewClient(s.Target)
		if cli == nil {
			log.Fatalf("Can not find client %q for benchmark\n", s.Target)
		}

		if err := cli.Dial(addr); err != nil {
			log.Fatalln(err)
		}
		clients[i] = cli
	}
	return clients
}
func createStreams(n int, clients []client.Client) []client.Stream {
	streams := make([]client.Stream, n*len(clients))
	for cur, cli := range clients {
		for i := 0; i < n; i++ {
			if cli, ok := cli.(client.StreamClient); ok {
				stream, err := cli.CreateStream(context.Background())
				if err != nil {
					log.Fatalf("StreamCall faile to create new stream, %v", err)
				}
				streams[cur*n+i] = stream
			} else {
				log.Fatalln(s.Target, " do not implement the client.StreamClient")
			}
		}
	}
	return streams
}

func benchmarkStream(n int, streams []client.Stream) {
	var wg sync.WaitGroup
	for _, stream := range streams {
		for i := 0; i < n; i++ {
			//Notice here. we must pass stream as a parameter because the varibale stream
			//would be changed after the goroutine created
			if s.Async {
				wg.Add(2)
				go func(stream client.Stream) { send(nil, stream); wg.Done() }(stream)
				go func(stream client.Stream) { recv(nil, stream); wg.Done() }(stream)
			} else {
				wg.Add(1)
				go func(stream client.Stream) { run(nil, stream); wg.Done() }(stream)
			}
		}
	}
	go statPrint()
	wg.Wait()
}
func benchmarkUnary(n int, clients []client.Client) {
	var wg sync.WaitGroup
	for _, cli := range clients {
		for i := 0; i < n; i++ {
			wg.Add(1)
			if cli, ok := cli.(client.UnaryClient); ok {
				go func(cli client.UnaryClient) { runUnary(nil, cli); wg.Done() }(cli)
			} else {
				log.Fatalln(s.Target, " does not implement the client.UnaryClient")
			}
		}
	}
	go statPrint()
	wg.Wait()
}

func runUnary(done <-chan int, cli client.UnaryClient) {
	for i := 0; s.N == 0 || i < s.N; i++ {
		//select {
		//case <-done:
		//	log.Println("run goroutine exit done")
		//	return
		//default:
		start := time.Now()
		if err := cli.Request(); err != nil {
			log.Println(err)
		}
		eplase := time.Since(start)
		stats.latencies = append(stats.latencies, eplase)
		stats.histogram.Add(int64(eplase))
		if s.Delay > 0 {
			time.Sleep(s.Delay)
		}
		//	}
	}
}
func run(done <-chan int, stream client.Stream) {
	for i := 0; s.N == 0 || i < s.N; i++ {
		select {
		case <-done:
			log.Println("run goroutine exit done")
			return
		default:
			start := time.Now()
			if s.Send {
				stream.DoSend()
			}
			if s.Recv {
				stream.DoRecv()
			}
			eplase := time.Since(start)
			stats.latencies = append(stats.latencies, eplase)
			stats.histogram.Add(int64(eplase))
			if s.Delay > 0 {
				time.Sleep(s.Delay)
			}
		}
	}
}

func send(done <-chan int, stream client.Stream) {
	timer := time.NewTimer(time.Second)
	for i := 0; s.N == 0 || i < s.N; i++ {
		select {
		case <-done:
			log.Println("send goroutine exit, done")
			return
		default:
			select {
			case rtts <- &roundtrip{start: time.Now(), ack: false}:
				timer.Reset(time.Second)
			case <-timer.C:
				log.Println("blocked on send rtts")
			}

			if burst != nil {
				select {
				case burst <- 0:
					timer.Reset(time.Second)
				case <-timer.C:
					log.Println("blocked on send burst chan")
				}
			}

			stream.DoSend()
			if s.Delay > 0 {
				time.Sleep(s.Delay)
			}
		}
	}
}
func recv(done <-chan int, stream client.Stream) {
	timer := time.NewTimer(time.Second)
	for i := 0; s.N == 0 || i < s.N; i++ {
		select {
		case <-done:
			log.Println("recv goroutine exit, done")
			return
		default:
			if burst != nil {
				select {
				case <-burst:
					timer.Reset(time.Second)
				case <-timer.C:
					log.Println("blocked on recv burst chan")
				}
			}
			err := stream.DoRecv()
			if err != nil {
				log.Println("recv goroutine exit", err)
				return
			}
			select {
			case rtt := <-rtts:
				timer.Reset(time.Second)
				rtt.ack = true
				eplase := time.Since(rtt.start)
				stats.latencies = append(stats.latencies, eplase)
				stats.histogram.Add(int64(eplase))
			case <-timer.C:
				log.Println("blocked on recv rtts")
			}
			if s.Delay > 0 {
				time.Sleep(s.Delay)
			}
		}
	}
}

func statPrint() {
	tickc := time.Tick(s.Tick)
	var latencies []time.Duration
	total := int64(0)
	for {
		select {
		case <-tickc:
			latencies = stats.latencies
			stats.latencies = stats.latencies[:0]

			sum := time.Duration(0)
			for _, eplase := range latencies {
				total++
				sum += eplase
			}
			count := len(latencies)
			if count != 0 {
				log.Printf("latency %v qps %d total %v\n", sum/time.Duration(count), int64(float64(count)/float64(s.Tick)*float64(time.Second)), total)
				if influxdb != nil {
					bp, _ := db.NewBatchPoints(db.BatchPointsConfig{
						Database:  "fperf",
						Precision: "s",
					})
					tags := map[string]string{"latency": "latency", "qps": "qps"}
					fields := map[string]interface{}{
						"latency": float64(sum) / float64(count) / 1000.0,
						"qps":     int64(float64(count) / float64(s.Tick) * float64(time.Second)),
					}
					pt, err := db.NewPoint("benchmark", tags, fields, time.Now())
					if err != nil {
						log.Println("Error: ", err.Error())
					}
					bp.AddPoint(pt)

					// Write the batch
					err = influxdb.Write(bp)
					if err != nil {
						log.Println("Error: ", err.Error())
					}
				}
			} else {
				log.Printf("blocking...")
			}
		}
	}
}

var s setting
var stats statistics
var rtts = make(chan *roundtrip, 10*1024*1024)
var mutex sync.RWMutex
var burst chan int
var influxdb db.Client

func usage() {
	fmt.Printf("Usage: %v [options] <client>\noptions:\n", os.Args[0])
	flag.PrintDefaults()
	fmt.Println("clients:")
	for name, desc := range client.AllClients() {
		fmt.Printf(" %s", name)
		if len(desc) > 0 {
			fmt.Printf("\t: %s", desc)
		}
		fmt.Println()
	}
}

func main() {
	flag.IntVar(&s.Connection, "connection", 1, "number of connection")
	flag.IntVar(&s.Stream, "stream", 1, "number of streams per connection")
	flag.IntVar(&s.Goroutine, "goroutine", 1, "number of goroutines per stream")
	flag.IntVar(&s.CPU, "cpu", 0, "set the GOMAXPROCS, use go default if 0")
	flag.IntVar(&s.Burst, "burst", 0, "burst a number of request, use with -async=true")
	flag.IntVar(&s.N, "N", 0, "number of request per goroutine")
	flag.BoolVar(&s.Send, "send", true, "perform send action")
	flag.BoolVar(&s.Recv, "recv", true, "perform recv action")
	flag.DurationVar(&s.Delay, "delay", 0, "wait delay time before send the next request")
	flag.DurationVar(&s.Tick, "tick", 2*time.Second, "interval between statistics")
	flag.StringVar(&s.Address, "server", "127.0.0.1:8804", "address of the target server")
	flag.BoolVar(&s.Async, "async", false, "send and recv in seperate goroutines")
	flag.StringVar(&s.CallType, "type", "auto", "set the call type:unary, stream or auto. default is auto")
	flag.StringVar(&s.InfluxDB, "influxdb", "", "writing stats to influxdb, specify the address in this option")
	flag.Usage = usage
	flag.Parse()

	s.Target = flag.Arg(0)
	if len(s.Target) == 0 {
		flag.Usage()
		return
	}
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		_ = <-c
		stats.histogram.Value().Print(os.Stdout)
		os.Exit(0)
	}()

	runtime.GOMAXPROCS(s.CPU)
	go func() {
		runtime.SetBlockProfileRate(1)
		log.Println(http.ListenAndServe(":6060", nil))
	}()

	if s.Burst > 0 {
		burst = make(chan int, s.Burst)
	}

	if len(s.InfluxDB) > 0 {
		c, err := db.NewHTTPClient(db.HTTPConfig{
			Addr: s.InfluxDB,
		})
		if err != nil {
			log.Fatalf("Error creating InfluxDB Client: %v", err.Error())
		}
		defer c.Close()
		q := db.NewQuery("CREATE DATABASE fperf", "", "")
		if response, err := c.Query(q); err == nil && response.Error() == nil {
			log.Println(response.Results)
		}
		influxdb = c
	}

	stats.latencies = make([]time.Duration, 0, 500000)
	histopt := hist.HistogramOptions{
		NumBuckets:         16,
		GrowthFactor:       1.8,
		SmallestBucketSize: 1000,
		MinValue:           10000,
	}
	stats.histogram = hist.NewHistogram(histopt)
	clients := createClients(s.Connection, s.Address)
	cli := clients[0]
	switch s.CallType {
	case "auto":
		switch cli.(type) {
		case client.StreamClient:
			streams := createStreams(s.Stream, clients)
			benchmarkStream(s.Goroutine, streams)
		case client.UnaryClient:
			benchmarkUnary(s.Goroutine, clients)
		}
	case "stream":
		streams := createStreams(s.Stream, clients)
		benchmarkStream(s.Goroutine, streams)
	case "unary":
		benchmarkUnary(s.Goroutine, clients)
	}
}
<commit_msg>Remove unused codes<commit_after>/*
fperf allows you to build your performace tools easily

Three steps to create your own testcase

1. Create the "NewClient" function

	package demo

	import (
		"fmt"
		"github.com/shafreeck/fperf/client"
		"time"
	)

	type DemoClient struct{}

	func NewDemoClient(flag *client.FlagSet) client.Client {
		return &DemoClient{}
	}

2. Implement the UnaryClient or StreamClient

	func (c *DemoClient) Dial(addr string) error {
		fmt.Println("Dial to", addr)
		return nil
	}

	func (c *DemoClient) Request() error {
		time.Sleep(100 * time.Millisecond)
		return nil
	}

3. Register to fperf

	func init() {
		client.Register("demo", NewDemoClient, "This is a demo client discription")
	}

Run the buildin testcase

http is a simple builtin testcase to benchmark http servers

	fperf -cpu 8 -connection 10 http http://example.com
*/
package main

import (
	"flag"
	"fmt"
	db "github.com/influxdata/influxdb/client/v2"
	"github.com/shafreeck/fperf/client"
	hist "github.com/shafreeck/fperf/stats"
	"golang.org/x/net/context"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"runtime"
	"sync"
	"syscall"
	"time"
)

type setting struct {
	Connection int
	Stream     int
	Goroutine  int
	CPU        int
	Burst      int
	N          int //number of requests
	Tick       time.Duration
	Address    string
	Send       bool
	Recv       bool
	Delay      time.Duration
	Async      bool
	Target     string
	CallType   string
	InfluxDB   string
}

type statistics struct {
	latencies []time.Duration
	histogram *hist.Histogram
}

type roundtrip struct {
	start time.Time
	end   time.Time
}

func createClients(n int, addr string) []client.Client {
	clients := make([]client.Client, n)
	for i := 0; i < n; i++ {
		cli := client.NewClient(s.Target)
		if cli == nil {
			log.Fatalf("Can not find client %q for benchmark\n", s.Target)
		}

		if err := cli.Dial(addr); err != nil {
			log.Fatalln(err)
		}
		clients[i] = cli
	}
	return clients
}
func createStreams(n int, clients []client.Client) []client.Stream {
	streams := make([]client.Stream, n*len(clients))
	for cur, cli := range clients {
		for i := 0; i < n; i++ {
			if cli, ok := cli.(client.StreamClient); ok {
				stream, err := cli.CreateStream(context.Background())
				if err != nil {
					log.Fatalf("StreamCall faile to create new stream, %v", err)
				}
				streams[cur*n+i] = stream
			} else {
				log.Fatalln(s.Target, " do not implement the client.StreamClient")
			}
		}
	}
	return streams
}

func benchmarkStream(n int, streams []client.Stream) {
	var wg sync.WaitGroup
	for _, stream := range streams {
		for i := 0; i < n; i++ {
			//Notice here. we must pass stream as a parameter because the varibale stream
			//would be changed after the goroutine created
			if s.Async {
				wg.Add(2)
				go func(stream client.Stream) { send(nil, stream); wg.Done() }(stream)
				go func(stream client.Stream) { recv(nil, stream); wg.Done() }(stream)
			} else {
				wg.Add(1)
				go func(stream client.Stream) { run(nil, stream); wg.Done() }(stream)
			}
		}
	}
	go statPrint()
	wg.Wait()
}
func benchmarkUnary(n int, clients []client.Client) {
	var wg sync.WaitGroup
	for _, cli := range clients {
		for i := 0; i < n; i++ {
			wg.Add(1)
			if cli, ok := cli.(client.UnaryClient); ok {
				go func(cli client.UnaryClient) { runUnary(nil, cli); wg.Done() }(cli)
			} else {
				log.Fatalln(s.Target, " does not implement the client.UnaryClient")
			}
		}
	}
	go statPrint()
	wg.Wait()
}

func runUnary(done <-chan int, cli client.UnaryClient) {
	for i := 0; s.N == 0 || i < s.N; i++ {
		//select {
		//case <-done:
		//	log.Println("run goroutine exit done")
		//	return
		//default:
		start := time.Now()
		if err := cli.Request(); err != nil {
			log.Println(err)
		}
		eplase := time.Since(start)
		stats.latencies = append(stats.latencies, eplase)
		stats.histogram.Add(int64(eplase))
		if s.Delay > 0 {
			time.Sleep(s.Delay)
		}
		//	}
	}
}
func run(done <-chan int, stream client.Stream) {
	for i := 0; s.N == 0 || i < s.N; i++ {
		select {
		case <-done:
			log.Println("run goroutine exit done")
			return
		default:
			start := time.Now()
			if s.Send {
				stream.DoSend()
			}
			if s.Recv {
				stream.DoRecv()
			}
			eplase := time.Since(start)
			stats.latencies = append(stats.latencies, eplase)
			stats.histogram.Add(int64(eplase))
			if s.Delay > 0 {
				time.Sleep(s.Delay)
			}
		}
	}
}

func send(done <-chan int, stream client.Stream) {
	timer := time.NewTimer(time.Second)
	for i := 0; s.N == 0 || i < s.N; i++ {
		select {
		case <-done:
			log.Println("send goroutine exit, done")
			return
		default:
			select {
			case rtts <- &roundtrip{start: time.Now()}:
				timer.Reset(time.Second)
			case <-timer.C:
				log.Println("blocked on send rtts")
			}

			if burst != nil {
				select {
				case burst <- 0:
					timer.Reset(time.Second)
				case <-timer.C:
					log.Println("blocked on send burst chan")
				}
			}

			stream.DoSend()
			if s.Delay > 0 {
				time.Sleep(s.Delay)
			}
		}
	}
}
func recv(done <-chan int, stream client.Stream) {
	timer := time.NewTimer(time.Second)
	for i := 0; s.N == 0 || i < s.N; i++ {
		select {
		case <-done:
			log.Println("recv goroutine exit, done")
			return
		default:
			if burst != nil {
				select {
				case <-burst:
					timer.Reset(time.Second)
				case <-timer.C:
					log.Println("blocked on recv burst chan")
				}
			}
			err := stream.DoRecv()
			if err != nil {
				log.Println("recv goroutine exit", err)
				return
			}
			select {
			case rtt := <-rtts:
				timer.Reset(time.Second)
				eplase := time.Since(rtt.start)
				stats.latencies = append(stats.latencies, eplase)
				stats.histogram.Add(int64(eplase))
			case <-timer.C:
				log.Println("blocked on recv rtts")
			}
			if s.Delay > 0 {
				time.Sleep(s.Delay)
			}
		}
	}
}

func statPrint() {
	tickc := time.Tick(s.Tick)
	var latencies []time.Duration
	total := int64(0)
	for {
		select {
		case <-tickc:
			latencies = stats.latencies
			stats.latencies = stats.latencies[:0]

			sum := time.Duration(0)
			for _, eplase := range latencies {
				total++
				sum += eplase
			}
			count := len(latencies)
			if count != 0 {
				log.Printf("latency %v qps %d total %v\n", sum/time.Duration(count), int64(float64(count)/float64(s.Tick)*float64(time.Second)), total)
				if influxdb != nil {
					bp, _ := db.NewBatchPoints(db.BatchPointsConfig{
						Database:  "fperf",
						Precision: "s",
					})
					tags := map[string]string{"latency": "latency", "qps": "qps"}
					fields := map[string]interface{}{
						"latency": float64(sum) / float64(count) / 1000.0,
						"qps":     int64(float64(count) / float64(s.Tick) * float64(time.Second)),
					}
					pt, err := db.NewPoint("benchmark", tags, fields, time.Now())
					if err != nil {
						log.Println("Error: ", err.Error())
					}
					bp.AddPoint(pt)

					// Write the batch
					err = influxdb.Write(bp)
					if err != nil {
						log.Println("Error: ", err.Error())
					}
				}
			} else {
				log.Printf("blocking...")
			}
		}
	}
}

var s setting
var stats statistics
var rtts = make(chan *roundtrip, 10*1024*1024)
var mutex sync.RWMutex
var burst chan int
var influxdb db.Client

func usage() {
	fmt.Printf("Usage: %v [options] <client>\noptions:\n", os.Args[0])
	flag.PrintDefaults()
	fmt.Println("clients:")
	for name, desc := range client.AllClients() {
		fmt.Printf(" %s", name)
		if len(desc) > 0 {
			fmt.Printf("\t: %s", desc)
		}
		fmt.Println()
	}
}

func main() {
	flag.IntVar(&s.Connection, "connection", 1, "number of connection")
	flag.IntVar(&s.Stream, "stream", 1, "number of streams per connection")
	flag.IntVar(&s.Goroutine, "goroutine", 1, "number of goroutines per stream")
	flag.IntVar(&s.CPU, "cpu", 0, "set the GOMAXPROCS, use go default if 0")
	flag.IntVar(&s.Burst, "burst", 0, "burst a number of request, use with -async=true")
	flag.IntVar(&s.N, "N", 0, "number of request per goroutine")
	flag.BoolVar(&s.Send, "send", true, "perform send action")
	flag.BoolVar(&s.Recv, "recv", true, "perform recv action")
	flag.DurationVar(&s.Delay, "delay", 0, "wait delay time before send the next request")
	flag.DurationVar(&s.Tick, "tick", 2*time.Second, "interval between statistics")
	flag.StringVar(&s.Address, "server", "127.0.0.1:8804", "address of the target server")
	flag.BoolVar(&s.Async, "async", false, "send and recv in seperate goroutines")
	flag.StringVar(&s.CallType, "type", "auto", "set the call type:unary, stream or auto. default is auto")
	flag.StringVar(&s.InfluxDB, "influxdb", "", "writing stats to influxdb, specify the address in this option")
	flag.Usage = usage
	flag.Parse()

	s.Target = flag.Arg(0)
	if len(s.Target) == 0 {
		flag.Usage()
		return
	}
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		_ = <-c
		stats.histogram.Value().Print(os.Stdout)
		os.Exit(0)
	}()

	runtime.GOMAXPROCS(s.CPU)
	go func() {
		runtime.SetBlockProfileRate(1)
		log.Println(http.ListenAndServe(":6060", nil))
	}()

	if s.Burst > 0 {
		burst = make(chan int, s.Burst)
	}

	if len(s.InfluxDB) > 0 {
		c, err := db.NewHTTPClient(db.HTTPConfig{
			Addr: s.InfluxDB,
		})
		if err != nil {
			log.Fatalf("Error creating InfluxDB Client: %v", err.Error())
		}
		defer c.Close()
		q := db.NewQuery("CREATE DATABASE fperf", "", "")
		if response, err := c.Query(q); err == nil && response.Error() == nil {
			log.Println(response.Results)
		}
		influxdb = c
	}

	stats.latencies = make([]time.Duration, 0, 500000)
	histopt := hist.HistogramOptions{
		NumBuckets:         16,
		GrowthFactor:       1.8,
		SmallestBucketSize: 1000,
		MinValue:           10000,
	}
	stats.histogram = hist.NewHistogram(histopt)
	clients := createClients(s.Connection, s.Address)
	cli := clients[0]
	switch s.CallType {
	case "auto":
		switch cli.(type) {
		case client.StreamClient:
			streams := createStreams(s.Stream, clients)
			benchmarkStream(s.Goroutine, streams)
		case client.UnaryClient:
			benchmarkUnary(s.Goroutine, clients)
		}
	case "stream":
		streams := createStreams(s.Stream, clients)
		benchmarkStream(s.Goroutine, streams)
	case "unary":
		benchmarkUnary(s.Goroutine, clients)
	}
}
<|endoftext|>


<commit_before>package frame

import (
	"github.com/as/drawcache"
	"github.com/as/frame/box"
	"github.com/as/frame/font"
	"image"
	"image/draw"
)

var (
	// Enables the UTF-8 experiment
	ForceUTF8Experiment = false
	// Enables the Elastic Tabstop experiement
	ForceElasticTabstopExperiment = false
)

// Frame is a write-only container for editable text
type Frame struct {
	box.Run
	Color
	Font         *font.Font
	b            *image.RGBA
	r, entire    image.Rectangle
	maxtab       int
	lastlinefull int

	p0 int64
	p1 int64

	tick      draw.Image
	tickback  draw.Image
	Ticked    bool
	tickscale int
	tickoff   bool
	maxlines  int
	modified  bool
	noredraw  bool
	op        draw.Op

	// Points to the font subpackage's StringN?BG or RuneN?BG functions
	stringBG  func (draw.Image, image.Point, image.Image, image.Point, *font.Font, []byte, image.Image, image.Point) int
	stringNBG func (draw.Image, image.Point, image.Image, image.Point, *font.Font, []byte) int
	newRulerFunc func(s []byte, ft *font.Font) box.Ruler

	drawcache.Drawer
	pts     [][2]image.Point
	Scroll  func(int)
	ir      *box.Run
	hexFont *font.Font
	hex     []draw.Image
}

func newRuneFrame(r image.Rectangle, ft *font.Font, b *image.RGBA, cols Color, runes ...bool) *Frame{
	spaceDx := ft.Measure(' ')
	f := &Frame{
		Font:   ft,
		maxtab: 400 * spaceDx,
		Color:  cols,
		Run:    box.NewRun(spaceDx, 5000, ft, box.NewRuneRuler),
		stringBG: font.RuneBG,
		stringNBG: font.RuneNBG,
		newRulerFunc: box.NewRuneRuler,
		op:     draw.Src,
	}
	f.setrects(r, b)
	f.inittick()
	run := box.NewRun(spaceDx, 5000, ft, box.NewRuneRuler)
	f.ir = &run
	f.Drawer = drawcache.New()
	return f
}

// New creates a new frame on b with bounds r. The image b is used
// as the frame's internal bitmap cache.
func New(r image.Rectangle, ft *font.Font, b *image.RGBA, cols Color, runes ...bool) *Frame {
	if (len(runes) > 0 && runes[0]) || ForceUTF8Experiment {
		return newRuneFrame(r,ft,b,cols)
	}
	spaceDx := ft.Measure(' ')
	f := &Frame{
		Font:   ft,
		maxtab: 4 * spaceDx,
		Color:  cols,
		Run:    box.NewRun(spaceDx, 5000, ft),
		stringBG: font.StringBG,
		stringNBG: font.StringNBG,
		newRulerFunc: box.NewByteRuler,
		op:     draw.Src,
	}
	f.setrects(r, b)
	f.inittick()
	run := box.NewRun(spaceDx, 5000, ft)
	f.ir = &run
	f.Drawer = drawcache.New()
	return f
}

func (f *Frame) RGBA() *image.RGBA {
	return f.b
}
func (f *Frame) Size() image.Point {
	r := f.RGBA().Bounds()
	return image.Pt(r.Dx(), r.Dy())
}

// Dirty returns true if the contents of the frame have changes since the last redraw
func (f *Frame) Dirty() bool {
	return f.modified
}

// SetDirty alters the frame's internal state
func (f *Frame) SetDirty(dirty bool) {
	f.modified = dirty
}

func (f *Frame) SetOp(op draw.Op) {
	f.op = op

}

// Close closes the frame
func (f *Frame) Close() error{
	return nil
}

// Reset resets the frame to display on image b with bounds r and font ft.
func (f *Frame) Reset(r image.Rectangle, b *image.RGBA, ft *font.Font) {
	f.r = r
	f.b = b
	f.SetFont(ft)
}

func (f *Frame) SetFont(ft *font.Font) {
	f.Font = ft
	f.Run.Reset(ft)
	f.Refresh()
}

// Bounds returns the frame's clipping rectangle
func (f *Frame) Bounds() image.Rectangle {
	return f.r.Bounds()
}

// Full returns true if the last line in the frame is full
func (f *Frame) Full() bool {
	return f.lastlinefull == 1
}

// Maxline returns the max number of wrapped lines fitting on the frame
func (f *Frame) MaxLine() int {
	return f.maxlines
}

// Line returns the number of wrapped lines currently in the frame
func (f *Frame) Line() int {
	return f.Nlines
}

// Len returns the number of bytes currently in the frame
func (f *Frame) Len() int64 {
	return f.Nchars
}

// Dot returns the range of the selected text
func (f *Frame) Dot() (p0, p1 int64) {
	return f.p0, f.p1
}

func (f *Frame) setrects(r image.Rectangle, b *image.RGBA) {
	f.b = b
	f.entire = r
	f.r = r
	f.r.Max.Y -= f.r.Dy() % f.Font.Dy()
	f.maxlines = f.r.Dy() / f.Font.Dy()
}

func (f *Frame) clear(freeall bool) {
	if f.Nbox != 0 {
		f.Run.Delete(0, f.Nbox-1)
	}
	if f.Box != nil {
		free(f.Box)
	}
	if freeall {
		// TODO: unnecessary
		freeimage(f.tick)
		freeimage(f.tickback)
		f.tick = nil
		f.tickback = nil
	}
	f.Box = nil
	f.Ticked = false
}

func free(i interface{}) {
}
func freeimage(i image.Image) {
}
<commit_msg>no need for 400<commit_after>package frame

import (
	"github.com/as/drawcache"
	"github.com/as/frame/box"
	"github.com/as/frame/font"
	"image"
	"image/draw"
)

var (
	// Enables the UTF-8 experiment
	ForceUTF8Experiment = false
	// Enables the Elastic Tabstop experiement
	ForceElasticTabstopExperiment = false
)

// Frame is a write-only container for editable text
type Frame struct {
	box.Run
	Color
	Font         *font.Font
	b            *image.RGBA
	r, entire    image.Rectangle
	maxtab       int
	lastlinefull int

	p0 int64
	p1 int64

	tick      draw.Image
	tickback  draw.Image
	Ticked    bool
	tickscale int
	tickoff   bool
	maxlines  int
	modified  bool
	noredraw  bool
	op        draw.Op

	// Points to the font subpackage's StringN?BG or RuneN?BG functions
	stringBG  func (draw.Image, image.Point, image.Image, image.Point, *font.Font, []byte, image.Image, image.Point) int
	stringNBG func (draw.Image, image.Point, image.Image, image.Point, *font.Font, []byte) int
	newRulerFunc func(s []byte, ft *font.Font) box.Ruler

	drawcache.Drawer
	pts     [][2]image.Point
	Scroll  func(int)
	ir      *box.Run
	hexFont *font.Font
	hex     []draw.Image
}

func newRuneFrame(r image.Rectangle, ft *font.Font, b *image.RGBA, cols Color, runes ...bool) *Frame{
	spaceDx := ft.Measure(' ')
	f := &Frame{
		Font:   ft,
		maxtab: 4 * spaceDx,
		Color:  cols,
		Run:    box.NewRun(spaceDx, 5000, ft, box.NewRuneRuler),
		stringBG: font.RuneBG,
		stringNBG: font.RuneNBG,
		newRulerFunc: box.NewRuneRuler,
		op:     draw.Src,
	}
	f.setrects(r, b)
	f.inittick()
	run := box.NewRun(spaceDx, 5000, ft, box.NewRuneRuler)
	f.ir = &run
	f.Drawer = drawcache.New()
	return f
}

// New creates a new frame on b with bounds r. The image b is used
// as the frame's internal bitmap cache.
func New(r image.Rectangle, ft *font.Font, b *image.RGBA, cols Color, runes ...bool) *Frame {
	if (len(runes) > 0 && runes[0]) || ForceUTF8Experiment {
		return newRuneFrame(r,ft,b,cols)
	}
	spaceDx := ft.Measure(' ')
	f := &Frame{
		Font:   ft,
		maxtab: 4 * spaceDx,
		Color:  cols,
		Run:    box.NewRun(spaceDx, 5000, ft),
		stringBG: font.StringBG,
		stringNBG: font.StringNBG,
		newRulerFunc: box.NewByteRuler,
		op:     draw.Src,
	}
	f.setrects(r, b)
	f.inittick()
	run := box.NewRun(spaceDx, 5000, ft)
	f.ir = &run
	f.Drawer = drawcache.New()
	return f
}

func (f *Frame) RGBA() *image.RGBA {
	return f.b
}
func (f *Frame) Size() image.Point {
	r := f.RGBA().Bounds()
	return image.Pt(r.Dx(), r.Dy())
}

// Dirty returns true if the contents of the frame have changes since the last redraw
func (f *Frame) Dirty() bool {
	return f.modified
}

// SetDirty alters the frame's internal state
func (f *Frame) SetDirty(dirty bool) {
	f.modified = dirty
}

func (f *Frame) SetOp(op draw.Op) {
	f.op = op

}

// Close closes the frame
func (f *Frame) Close() error{
	return nil
}

// Reset resets the frame to display on image b with bounds r and font ft.
func (f *Frame) Reset(r image.Rectangle, b *image.RGBA, ft *font.Font) {
	f.r = r
	f.b = b
	f.SetFont(ft)
}

func (f *Frame) SetFont(ft *font.Font) {
	f.Font = ft
	f.Run.Reset(ft)
	f.Refresh()
}

// Bounds returns the frame's clipping rectangle
func (f *Frame) Bounds() image.Rectangle {
	return f.r.Bounds()
}

// Full returns true if the last line in the frame is full
func (f *Frame) Full() bool {
	return f.lastlinefull == 1
}

// Maxline returns the max number of wrapped lines fitting on the frame
func (f *Frame) MaxLine() int {
	return f.maxlines
}

// Line returns the number of wrapped lines currently in the frame
func (f *Frame) Line() int {
	return f.Nlines
}

// Len returns the number of bytes currently in the frame
func (f *Frame) Len() int64 {
	return f.Nchars
}

// Dot returns the range of the selected text
func (f *Frame) Dot() (p0, p1 int64) {
	return f.p0, f.p1
}

func (f *Frame) setrects(r image.Rectangle, b *image.RGBA) {
	f.b = b
	f.entire = r
	f.r = r
	f.r.Max.Y -= f.r.Dy() % f.Font.Dy()
	f.maxlines = f.r.Dy() / f.Font.Dy()
}

func (f *Frame) clear(freeall bool) {
	if f.Nbox != 0 {
		f.Run.Delete(0, f.Nbox-1)
	}
	if f.Box != nil {
		free(f.Box)
	}
	if freeall {
		// TODO: unnecessary
		freeimage(f.tick)
		freeimage(f.tickback)
		f.tick = nil
		f.tickback = nil
	}
	f.Box = nil
	f.Ticked = false
}

func free(i interface{}) {
}
func freeimage(i image.Image) {
}
<|endoftext|>


<commit_before>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package piazza

import "fmt"

//----------------------------------------------------------

// Elasticsearch, at least, does it this way:
//  - perform the query, giving a huge result set
//  - sort the result set
//  - select out the page you want

// Constants indicating ascending (1,2,3) or descending (3,2,1) order.
type SortOrder string

const (
	SortOrderAscending  SortOrder = "asc"
	SortOrderDescending SortOrder = "desc"
)

type JsonPagination struct {
	Count   int       `json:"count"` // only used when writing output
	Page    int       `json:"page"`
	PerPage int       `json:"perPage"`
	SortBy  string    `json:"sortBy"`
	Order   SortOrder `json:"order"`
}

func (p *JsonPagination) StartIndex() int {
	return p.Page * p.PerPage
}

func (p *JsonPagination) EndIndex() int {
	return p.StartIndex() + p.PerPage
}

func NewJsonPagination(params *HttpQueryParams) (*JsonPagination, error) {

	jp := &JsonPagination{}

	perPage, err := params.GetPerPage(defaults().PerPage)
	if err != nil {
		return nil, err
	}
	if perPage != nil {
		jp.PerPage = *perPage
	}

	page, err := params.GetPage(defaults().Page)
	if err != nil {
		return nil, err
	}
	if page != nil {
		jp.Page = *page
	}

	sortBy, err := params.GetSortBy(defaults().SortBy)
	if err != nil {
		return nil, err
	}
	if sortBy != nil {
		jp.SortBy = *sortBy
	}

	order, err := params.GetSortOrder(defaults().Order)
	if err != nil {
		return nil, err
	}
	if order != nil {
		jp.Order = *order
	}

	return jp, nil
}

// TODO: probably want to create this once and reuse it
func defaults() *JsonPagination {
	return &JsonPagination{
		PerPage: 10,
		Page:    0,
		Order:   SortOrderDescending,
		SortBy:  "createdOn",
	}
}

func (format *JsonPagination) ToParamString() string {
	s := fmt.Sprintf("perPage=%d&page=%d&sortBy=%s&order=%s",
		format.PerPage, format.Page, format.SortBy, format.Order)
	return s
}
<commit_msg>quick kludge compilation fix<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package piazza

import "fmt"

//----------------------------------------------------------

// Elasticsearch, at least, does it this way:
//  - perform the query, giving a huge result set
//  - sort the result set
//  - select out the page you want

// Constants indicating ascending (1,2,3) or descending (3,2,1) order.
type SortOrder string

const (
	SortOrderAscending  SortOrder = "asc"
	SortOrderDescending SortOrder = "desc"
)

type JsonPagination struct {
	Count   int       `json:"count"` // only used when writing output
	Page    int       `json:"page"`
	PerPage int       `json:"perPage"`
	SortBy  string    `json:"sortBy"`
	Order   SortOrder `json:"order"`
}

func (p *JsonPagination) StartIndex() int {
	return p.Page * p.PerPage
}

func (p *JsonPagination) EndIndex() int {
	return p.StartIndex() + p.PerPage
}

func NewJsonPagination(params *HttpQueryParams) (*JsonPagination, error) {

	jp := &JsonPagination{}

	perPage, err := params.GetPerPage(&(defaults().PerPage))
	if err != nil {
		return nil, err
	}
	if perPage != nil {
		jp.PerPage = *perPage
	}

	page, err := params.GetPage(&(defaults().Page))
	if err != nil {
		return nil, err
	}
	if page != nil {
		jp.Page = *page
	}

	sortBy, err := params.GetSortBy(&(defaults().SortBy))
	if err != nil {
		return nil, err
	}
	if sortBy != nil {
		jp.SortBy = *sortBy
	}

	order, err := params.GetSortOrder(&(defaults().Order))
	if err != nil {
		return nil, err
	}
	if order != nil {
		jp.Order = *order
	}

	return jp, nil
}

// TODO: probably want to create this once and reuse it
func defaults() *JsonPagination {
	return &JsonPagination{
		PerPage: 10,
		Page:    0,
		Order:   SortOrderDescending,
		SortBy:  "createdOn",
	}
}

func (format *JsonPagination) ToParamString() string {
	s := fmt.Sprintf("perPage=%d&page=%d&sortBy=%s&order=%s",
		format.PerPage, format.Page, format.SortBy, format.Order)
	return s
}
<|endoftext|>


<commit_before>package g

import (
	"encoding/json"
	"github.com/toolkits/file"
	"log"
	"os"
	"sync"
)

type PluginConfig struct {
	Enabled bool   `json:"enabled"`
	Dir     string `json:"dir"`
	Git     string `json:"git"`
	LogDir  string `json:"logs"`
}

type HeartbeatConfig struct {
	Enabled  bool   `json:"enabled"`
	Addr     string `json:"addr"`
	Interval int    `json:"interval"`
	Timeout  int    `json:"timeout"`
}

type TransferConfig struct {
	Enabled  bool   `json:"enabled"`
	Addr     string `json:"addr"`
	Interval int    `json:"interval"`
	Timeout  int    `json:"timeout"`
}

type HttpConfig struct {
	Enabled  bool   `json:"enabled"`
	Listen   string `json:"listen"`
	Backdoor bool   `json:"backdoor"`
}

type CollectorConfig struct {
	IfacePrefix []string `json:"ifacePrefix"`
}

type GlobalConfig struct {
	Debug         bool             `json:"debug"`
	Hostname      string           `json:"hostname"`
	IP            string           `json:"ip"`
	Plugin        *PluginConfig    `json:"plugin"`
	Heartbeat     *HeartbeatConfig `json:"heartbeat"`
	Transfer      *TransferConfig  `json:"transfer"`
	Http          *HttpConfig      `json:"http"`
	Collector     *CollectorConfig `json:"collector"`
	IgnoreMetrics map[string]bool  `json:"ignore"`
}

var (
	ConfigFile string
	config     *GlobalConfig
	lock       = new(sync.RWMutex)
)

func Config() *GlobalConfig {
	lock.RLock()
	defer lock.RUnlock()
	return config
}

func Hostname() (string, error) {
	hostname := Config().Hostname
	if hostname != "" {
		return hostname, nil
	}

	hostname, err := os.Hostname()
	if err != nil {
		log.Println("ERROR: os.Hostname() fail", err)
	}
	return hostname, err
}

func IP() string {
	ip := Config().IP
	if ip != "" {
		// use ip in configuration
		return ip
	}

	if len(LocalIps) > 0 {
		ip = LocalIps[0]
	}

	return ip
}

func ParseConfig(cfg string) {
	if cfg == "" {
		log.Fatalln("use -c to specify configuration file")
	}

	if !file.IsExist(cfg) {
		log.Fatalln("config file:", cfg, "is not existent. maybe you need `mv cfg.example.json cfg.json`")
	}

	ConfigFile = cfg

	configContent, err := file.ToTrimString(cfg)
	if err != nil {
		log.Fatalln("read config file:", cfg, "fail:", err)
	}

	var c GlobalConfig
	err = json.Unmarshal([]byte(configContent), &c)
	if err != nil {
		log.Fatalln("parse config file:", cfg, "fail:", err)
	}

	lock.Lock()
	defer lock.Unlock()

	config = &c

	log.Println("read config file:", cfg, "successfully")
}
<commit_msg>[OWL-291] use short hostname<commit_after>package g

import (
	"encoding/json"
	"github.com/toolkits/file"
	"log"
	"os"
	"strings"
	"sync"
)

type PluginConfig struct {
	Enabled bool   `json:"enabled"`
	Dir     string `json:"dir"`
	Git     string `json:"git"`
	LogDir  string `json:"logs"`
}

type HeartbeatConfig struct {
	Enabled  bool   `json:"enabled"`
	Addr     string `json:"addr"`
	Interval int    `json:"interval"`
	Timeout  int    `json:"timeout"`
}

type TransferConfig struct {
	Enabled  bool   `json:"enabled"`
	Addr     string `json:"addr"`
	Interval int    `json:"interval"`
	Timeout  int    `json:"timeout"`
}

type HttpConfig struct {
	Enabled  bool   `json:"enabled"`
	Listen   string `json:"listen"`
	Backdoor bool   `json:"backdoor"`
}

type CollectorConfig struct {
	IfacePrefix []string `json:"ifacePrefix"`
}

type GlobalConfig struct {
	Debug         bool             `json:"debug"`
	Hostname      string           `json:"hostname"`
	IP            string           `json:"ip"`
	Plugin        *PluginConfig    `json:"plugin"`
	Heartbeat     *HeartbeatConfig `json:"heartbeat"`
	Transfer      *TransferConfig  `json:"transfer"`
	Http          *HttpConfig      `json:"http"`
	Collector     *CollectorConfig `json:"collector"`
	IgnoreMetrics map[string]bool  `json:"ignore"`
}

var (
	ConfigFile string
	config     *GlobalConfig
	lock       = new(sync.RWMutex)
)

func Config() *GlobalConfig {
	lock.RLock()
	defer lock.RUnlock()
	return config
}

func Hostname() (string, error) {
	hostname := Config().Hostname
	if hostname != "" {
		return hostname, nil
	}

	hostname, err := os.Hostname()
	if err != nil {
		log.Println("ERROR: os.Hostname() fail", err)
	}
	// hostname -s
	// -s, --short
	// Display the short host name. This is the host name cut at the first dot.
	hostname = strings.Split(hostname, ".")[0]
	return hostname, err
}

func IP() string {
	ip := Config().IP
	if ip != "" {
		// use ip in configuration
		return ip
	}

	if len(LocalIps) > 0 {
		ip = LocalIps[0]
	}

	return ip
}

func ParseConfig(cfg string) {
	if cfg == "" {
		log.Fatalln("use -c to specify configuration file")
	}

	if !file.IsExist(cfg) {
		log.Fatalln("config file:", cfg, "is not existent. maybe you need `mv cfg.example.json cfg.json`")
	}

	ConfigFile = cfg

	configContent, err := file.ToTrimString(cfg)
	if err != nil {
		log.Fatalln("read config file:", cfg, "fail:", err)
	}

	var c GlobalConfig
	err = json.Unmarshal([]byte(configContent), &c)
	if err != nil {
		log.Fatalln("parse config file:", cfg, "fail:", err)
	}

	lock.Lock()
	defer lock.Unlock()

	config = &c

	log.Println("read config file:", cfg, "successfully")
}
<|endoftext|>


<commit_before>package main

import (
  "log"
  "fmt"
  "os/exec"
  "strings"
  "net/http"
  "io/ioutil"
)

var URL = "https://%s/master/LICENSE"

type response struct{
  Dep string
  License string
  Link string
}

func getLicense(url string, dependency string, ch chan response) {
  resp, err := http.Get(url)
  if err != nil {
      panic(err)
  }
  defer resp.Body.Close()
  body, err := ioutil.ReadAll(resp.Body)
  if err != nil {
      panic(err)
  }
  license := getLicenseText(string(body))
  ch <- response{
    Dep: dependency,
    License: license,
    Link: url,
  }
}

func getLicenseText(data string) string {
  whole := strings.Split(data, "\n")
  return whole[0]
}

func main() {
  out, err := exec.Command("sh", "-c", `go list -f '{{ join .Imports "\n"}}' | grep github`).Output()
  if err != nil {
    log.Fatal(err)
  }
  deps := strings.Split(string(out), "\n")
  ch := make(chan response, len(deps)- 1)
  rawDeps :=  deps[:len(deps)-1]
  for _, rawDep := range rawDeps {
    dep := strings.Replace(rawDep, "github.com", "raw.githubusercontent.com", 1)
    dep = fmt.Sprintf(URL, dep)
    go getLicense(dep, rawDep, ch)
  }
  for i := 0; i < len(rawDeps); i++  {
    result := <- ch
    fmt.Printf("%v ===>: %v\n", result.Dep, result.License)
  }
}
<commit_msg>Change method of getting license to use github api<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os/exec"
	"strings"

	"github.com/gorilla/mux"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

// URL represents path a github repos license
var URL = "https://api.github.com/repos/%s/license"

type message struct {
	Dependency string
	License    string
	Link       string
}
type response struct {
	Html_URL string
	License  license
}
type license struct {
	Name string
}

func getLicense(url string, dependency string, ch chan message) {
	cleanURL := formatLink(url)
	url = fmt.Sprintf(URL, cleanURL)
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	cleanBody := &response{}
	json.Unmarshal([]byte(body), &cleanBody)

	ch <- message{
		Dependency: dependency,
		License:    cleanBody.License.Name,
		Link:       cleanBody.Html_URL,
	}
}

// formatLink returns just the repo name and owner in the format ":owner/:repo"
func formatLink(link string) string {
	strippedURL := strings.Split(link, "/")
	cleanURL := strings.Join(strippedURL[1:3], "/")
	return cleanURL
}

func main() {
	mux.NewRouter()
	out, err := exec.Command("sh", "-c", `go list -f '{{ join .Imports "\n"}}' | grep github`).Output()
	if err != nil {
		log.Fatal(err)
	}
	deps := strings.Split(string(out), "\n")
	rawDeps := deps[:len(deps)-1]
	ch := make(chan message, len(rawDeps)-1)
	for _, rawDep := range rawDeps {
		go getLicense(rawDep, rawDep, ch)
	}
	for i := 0; i < len(rawDeps); i++ {
		result := <-ch
		fmt.Printf("%v ===>: %v (%v)\n", result.Dependency, result.License, result.Link)
	}
}
<|endoftext|>


<commit_before>package util

import (
	"bytes"
	"encoding/json"
	"fmt"
	"os"

	"github.com/satori/go.uuid"
	"gopkg.in/resty.v0"
)

func (u SomaUtil) GetTeamIdByName(teamName string) uuid.UUID {
	url := u.ApiUrl
	url.Path = "/teams"

	var req somaproto.ProtoRequestTeam
	var err error
	req.Filter.TeamName = teamName

	resp, err := resty.New().
		SetRedirectPolicy(resty.FlexibleRedirectPolicy(3)).
		R().
		SetBody(req).
		Get(url.String())
	if err != nil {
		fmt.Fprintf(os.Stderr, err.Error())
		u.Log.Fatal(err)
	}

	u.CheckRestyResponse(resp)
	teamResult := u.DecodeProtoResultTeamFromResponse(resp)

	if teamName != teamResult.Teams[0].TeamName {
		u.Log.Fatal("Received result set for incorrect team")
	}
	return teamResult.Teams[0].TeamId
}

func (u SomaUtil) DecodeProtoResultTeamFromResponse(resp *resty.Response) *somaproto.ProtoResultTeam {
	decoder := json.NewDecoder(bytes.NewReader(resp.Body))
	var res somaproto.ProtoResultTeam
	err := decoder.Decode(&res)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error decoding server response body\n")
		u.Log.Printf("Error decoding server response body\n")
		u.Log.Fatal(err)
	}
	if res.Code > 299 {
		fmt.Fprintf(os.Stderr, "Request failed: %d - %s\n",
			res.Code, res.Status)
		for _, e := range res.Text {
			fmt.Fprintf(os.Stderr, "%s\n", e)
			u.Log.Printf("%s\n", e)
		}
		os.Exit(1)
	}
	return &res
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<commit_msg>Refactor + add TryGetTeamByUUIDOrName function<commit_after>package util

import (
	"bytes"
	"encoding/json"
	"fmt"

	"github.com/satori/go.uuid"
	"gopkg.in/resty.v0"
)

func (u SomaUtil) TryGetTeamByUUIDOrName(s string) uuid.UUID {
	id, err := uuid.FromString(s)
	if err != nil {
		// aborts on failure
		id = u.GetNodeIdByName(s)
	}
	return id
}

func (u SomaUtil) GetTeamIdByName(teamName string) uuid.UUID {
	url := u.ApiUrl
	url.Path = "/teams/"

	var req somaproto.ProtoRequestTeam
	req.Filter.TeamName = teamName

	resp := u.GetRequestWithBody(req, url.String())
	teamResult := u.DecodeProtoResultTeamFromResponse(resp)

	if teamName != teamResult.Teams[0].TeamName {
		u.Log.Fatal("Received result set for incorrect team")
	}
	return teamResult.Teams[0].TeamId
}

func (u SomaUtil) DecodeProtoResultTeamFromResponse(resp *resty.Response) *somaproto.ProtoResultTeam {
	decoder := json.NewDecoder(bytes.NewReader(resp.Body))
	var res somaproto.ProtoResultTeam
	err := decoder.Decode(&res)
	u.AbortOnError(err, "Error decoding server response body")
	if res.Code > 299 {
		s := fmt.Sprintf("Request failed: %d - %s", res.Code, res.Status)
		msgs := []string{s}
		msgs = append(msgs, res.Text...)
		u.Abort(msgs...)
	}
	return &res
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/TrevorSStone/goriot"
	"github.com/coopernurse/gorp"
)

type PlayedGame struct {
	SummonerId int64 `db:"summonerId"`
	GameId     int64 `db:"gameId"`
}

func hasSummonerAlreadyPlayedGame(summonerId int64, gameId int64, games []PlayedGame) (gameIsPlayed bool) {
	for _, game := range games {
		if game.SummonerId == summonerId && game.GameId == gameId {
			return true
		}
	}

	return false
}

// use list of summoners to download game data
func updateGames(summoners []int64, dbmap *gorp.DbMap) (gameCount int) {

	// get stored game ids for summoners
	var summonerGameIdQuery string = `
        SELECT gameId
        FROM summoner_games
        INNER JOIN game_info gi ON
            gi.id = gameId
        WHERE summonerId = %d
        ORDER by gi.date desc`
	var gameIdQuery string = "SELECT id FROM game_info"
	var gameIds []int64 = make([]int64, 1)
	_, err := dbmap.Select(&gameIds, gameIdQuery)
	checkErr(err, "Could not get game ids from database")

	// get most recent games for each summoner
	var playedGames []int64 = make([]int64, 1)
	var savedGames = make([]int64, 1)
	for _, summonerId := range summoners {
		fmt.Printf("\nChecking summoner: %d\n", summonerId)
		fmt.Printf("---\n")
		summonerGames, riotErr := goriot.RecentGameBySummoner(goriot.NA, summonerId)
		if riotErr != nil {
			panic(riotErr)
		}

		_, err := dbmap.Select(
			&playedGames,
			fmt.Sprintf(summonerGameIdQuery, summonerId))
		checkErr(err, "Could not find games for summoner")

		fmt.Printf("%d has %d games played\n", summonerId, len(playedGames))

		// save game if we don't already have it
		for _, game := range summonerGames {

			if existsInSlice(game.GameID, gameIds) == false {

				if existsInSlice(game.GameID, savedGames) == false {

					updateGameInfo(game, dbmap)

					// save game id to list to skip loading into
					// game_info, in the event it shows again
					savedGames = append(savedGames, game.GameID)
				}
			}
			if existsInSlice(game.GameID, playedGames) == false {
				fmt.Printf("%d hasn't played %d\n", summonerId, game.GameID)
				var stats goriot.GameStat = game.Statistics
				statId := updateSummonerStatistics(summonerId, stats, dbmap)

				updateSummonerGames(
					summonerId, game, statId, stats.Win, dbmap)
			}
		}

	}

	return len(savedGames)
}

func updateGameInfo(game goriot.Game, db *gorp.DbMap) {
	// save game to db
	var gameInfoQuery string = `
                            INSERT INTO game_info
                                (id, mode, type, subType, mapId, date)
                            VALUES
                                (?, ?, ?, ?, ?, FROM_UNIXTIME(?))`
	_, infoErr := db.Exec(
		gameInfoQuery,
		game.GameID,
		game.GameMode,
		game.GameType,
		game.SubType,
		game.MapID,
		game.CreateDate/1000)
	if infoErr != nil {
		panic(infoErr)
	}
}

func updateSummonerGames(
	summonerId int64,
	game goriot.Game,
	statId int64,
	wonGame bool,
	db *gorp.DbMap) {
	// save summoner_game
	var summonerGameQuery string = `
                        INSERT INTO summoner_games
                            (summonerId, gameId, championId, spellOne, spellTwo,
                             statId, won)
                        VALUES
                            (?,?,?,?,?,?,?)`
	_, sgErr := db.Exec(
		summonerGameQuery,
		summonerId,
		game.GameID,
		game.ChampionID,
		game.Spell1,
		game.Spell2,
		statId,
		wonGame)
	checkErr(sgErr, "Could not save summoner game info")
}

func updateSummonerStatistics(
	summonerId int64,
	stats goriot.GameStat,
	db *gorp.DbMap) (statId int64) {
	// save stats
	var statsQuery string = `
                        INSERT INTO summoner_stats
                            (assists, barracksKilled, championsKilled,
                             combatPlayerScore, consumablesPurchased,
                             damageDealtPlayer, doubleKills, firstBlood,
                             gold, goldEarned, goldSpent, item0, item1,
                             item2, item3, item4, item5, item6, itemsPurchased,
                             killingSprees, largestCriticalStrike,
                             largestKillingSpree, largestMultiKill,
                             legendaryItemsCreated, level, magicDamageDealtPlayer,
                             magicDamageDealtToChampions, magicDamageTaken,
                             minionsDenied, minionsKilled, neutralMinionsKilled,
                             neutralMinionsKilledEnemyJungle,
                             neutralMinionsKilledYourJungle, nexusKilled, nodeCapture,
                             nodeCaptureAssist, nodeNeutralize, nodeNeutralizeAssist,
                             numDeaths, numItemsBought, objectivePlayerScore, pentaKills,
                             physicalDamageDealtPlayer, physicalDamageDealtToChampions,
                             physicalDamageTaken, quadraKills, sightWardsBought,
                             spellOneCast, spellTwoCast, spellThreeCast, spellFourCast,
                             summonerSpellOneCast, summonerSpellTwoCast,
                             superMonsterKilled, team, teamObjective, timePlayed,
                             totalDamageDealt, totalDamageDealtToChampions,
                             totalDamageTaken, totalHeal, totalPlayerScore,
                             totalScoreRank, totalTimeCrowdControlDealt,
                             totalUnitsHealed, tripleKills, trueDamageDealtPlayer,
                             trueDamageDealtToChampions, trueDamageTaken, turretsKilled,
                             unrealKills, victoryPointTotal, visionWardsBought,
                             wardKilled, wardPlaced)
                        VALUES
                            (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
                             ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
                             ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
	statRes, statErr := db.Exec(
		statsQuery,
		stats.Assists,
		stats.BarracksKilled,
		stats.ChampionsKilled,
		stats.CombatPlayerScore,
		stats.ConsumablesPurchased,
		stats.DamageDealtPlayer,
		stats.DoubleKills,
		stats.FirstBlood,
		stats.Gold,
		stats.GoldEarned,
		stats.GoldSpent,
		stats.Item0,
		stats.Item1,
		stats.Item2,
		stats.Item3,
		stats.Item4,
		stats.Item5,
		stats.Item6,
		stats.ItemsPurchased,
		stats.KillingSprees,
		stats.LargestCriticalStrike,
		stats.LargestKillingSpree,
		stats.LargestMultiKill,
		stats.LegendaryItemsCreated,
		stats.Level,
		stats.MagicDamageDealtPlayer,
		stats.MagicDamageDealtToChampions,
		stats.MagicDamageTaken,
		stats.MinionsDenied,
		stats.MinionsKilled,
		stats.NeutralMinionsKilled,
		stats.NeutralMinionsKilledEnemyJungle,
		stats.NeutralMinionsKilledYourJungle,
		stats.NexusKilled,
		stats.NodeCapture,
		stats.NodeCaptureAssist,
		stats.NodeNeutralize,
		stats.NodeNeutralizeAssist,
		stats.NumDeaths,
		stats.NumItemsBought,
		stats.ObjectivePlayerScore,
		stats.PentaKills,
		stats.PhysicalDamageDealtPlayer,
		stats.PhysicalDamageDealtToChampions,
		stats.PhysicalDamageTaken,
		stats.QuadraKills,
		stats.SightWardsBought,
		stats.Spell1Cast,
		stats.Spell2Cast,
		stats.Spell3Cast,
		stats.Spell4Cast,
		stats.SummonSpell1Cast,
		stats.SummonSpell2Cast,
		stats.SuperMonsterKilled,
		stats.Team,
		stats.TeamObjective,
		stats.TimePlayed,
		stats.TotalDamageDealt,
		stats.TotalDamageDealtToChampions,
		stats.TotalDamageTaken,
		stats.TotalHeal,
		stats.TotalPlayerScore,
		stats.TotalScoreRank,
		stats.TotalTimeCrowdControlDealt,
		stats.TotalUnitsHealed,
		stats.TripleKills,
		stats.TrueDamageDealtPlayer,
		stats.TrueDamageDealtToChampions,
		stats.TrueDamageTaken,
		stats.TurretsKilled,
		stats.UnrealKills,
		stats.VictoryPointTotal,
		stats.VisionWardsBought,
		stats.WardKilled,
		stats.WardPlaced)
	checkErr(statErr, "Could not insert stats")

	statId, statIdErr := statRes.LastInsertId()
	checkErr(statIdErr, "Could not get last insterted id")

	return statId
}
<commit_msg>Fixed a bug that caused games to be missed by some summoners.<commit_after>package main

import (
	"fmt"
	"github.com/TrevorSStone/goriot"
	"github.com/coopernurse/gorp"
)

type PlayedGame struct {
	SummonerId int64 `db:"summonerId"`
	GameId     int64 `db:"gameId"`
}

func hasSummonerAlreadyPlayedGame(summonerId int64, gameId int64, games []PlayedGame) (gameIsPlayed bool) {
	for _, game := range games {
		if game.SummonerId == summonerId && game.GameId == gameId {
			return true
		}
	}

	return false
}

// use list of summoners to download game data
func updateGames(summoners []int64, dbmap *gorp.DbMap) (gameCount int) {

	// get stored game ids for summoners
	var summonerGameIdQuery string = `
        SELECT gameId
        FROM summoner_games
        INNER JOIN game_info gi ON
            gi.id = gameId
        WHERE summonerId = %d
        ORDER by gi.date desc`
	var gameIdQuery string = "SELECT id FROM game_info"
	var gameIds []int64 = make([]int64, 1)
	_, err := dbmap.Select(&gameIds, gameIdQuery)
	checkErr(err, "Could not get game ids from database")

	// get most recent games for each summoner
	var playedGames []int64
	var savedGames = make([]int64, 1)
	for _, summonerId := range summoners {

		playedGames = make([]int64, 1)
		summonerGames, riotErr := goriot.RecentGameBySummoner(goriot.NA, summonerId)
		if riotErr != nil {
			panic(riotErr)
		}

		_, err := dbmap.Select(
			&playedGames,
			fmt.Sprintf(summonerGameIdQuery, summonerId))
		checkErr(err, "Could not find games for summoner")

		// save game if we don't already have it
		for _, game := range summonerGames {

			if existsInSlice(game.GameID, gameIds) == false {

				if existsInSlice(game.GameID, savedGames) == false {

					updateGameInfo(game, dbmap)

					// save game id to list to skip loading into
					// game_info, in the event it shows again
					savedGames = append(savedGames, game.GameID)
				}
			}
			if existsInSlice(game.GameID, playedGames) == false {
				var stats goriot.GameStat = game.Statistics
				statId := updateSummonerStatistics(summonerId, stats, dbmap)

				updateSummonerGames(
					summonerId, game, statId, stats.Win, dbmap)
			} else {
				fmt.Printf("Already played %d\n", game.GameID)
			}
		}

	}

	return len(savedGames)
}

func updateGameInfo(game goriot.Game, db *gorp.DbMap) {
	// save game to db
	var gameInfoQuery string = `
                            INSERT INTO game_info
                                (id, mode, type, subType, mapId, date)
                            VALUES
                                (?, ?, ?, ?, ?, FROM_UNIXTIME(?))`
	_, infoErr := db.Exec(
		gameInfoQuery,
		game.GameID,
		game.GameMode,
		game.GameType,
		game.SubType,
		game.MapID,
		game.CreateDate/1000)
	if infoErr != nil {
		panic(infoErr)
	}
}

func updateSummonerGames(
	summonerId int64,
	game goriot.Game,
	statId int64,
	wonGame bool,
	db *gorp.DbMap) {
	// save summoner_game
	var summonerGameQuery string = `
                        INSERT INTO summoner_games
                            (summonerId, gameId, championId, spellOne, spellTwo,
                             statId, won)
                        VALUES
                            (?,?,?,?,?,?,?)`
	_, sgErr := db.Exec(
		summonerGameQuery,
		summonerId,
		game.GameID,
		game.ChampionID,
		game.Spell1,
		game.Spell2,
		statId,
		wonGame)
	checkErr(sgErr, "Could not save summoner game info")
}

func updateSummonerStatistics(
	summonerId int64,
	stats goriot.GameStat,
	db *gorp.DbMap) (statId int64) {
	// save stats
	var statsQuery string = `
                        INSERT INTO summoner_stats
                            (assists, barracksKilled, championsKilled,
                             combatPlayerScore, consumablesPurchased,
                             damageDealtPlayer, doubleKills, firstBlood,
                             gold, goldEarned, goldSpent, item0, item1,
                             item2, item3, item4, item5, item6, itemsPurchased,
                             killingSprees, largestCriticalStrike,
                             largestKillingSpree, largestMultiKill,
                             legendaryItemsCreated, level, magicDamageDealtPlayer,
                             magicDamageDealtToChampions, magicDamageTaken,
                             minionsDenied, minionsKilled, neutralMinionsKilled,
                             neutralMinionsKilledEnemyJungle,
                             neutralMinionsKilledYourJungle, nexusKilled, nodeCapture,
                             nodeCaptureAssist, nodeNeutralize, nodeNeutralizeAssist,
                             numDeaths, numItemsBought, objectivePlayerScore, pentaKills,
                             physicalDamageDealtPlayer, physicalDamageDealtToChampions,
                             physicalDamageTaken, quadraKills, sightWardsBought,
                             spellOneCast, spellTwoCast, spellThreeCast, spellFourCast,
                             summonerSpellOneCast, summonerSpellTwoCast,
                             superMonsterKilled, team, teamObjective, timePlayed,
                             totalDamageDealt, totalDamageDealtToChampions,
                             totalDamageTaken, totalHeal, totalPlayerScore,
                             totalScoreRank, totalTimeCrowdControlDealt,
                             totalUnitsHealed, tripleKills, trueDamageDealtPlayer,
                             trueDamageDealtToChampions, trueDamageTaken, turretsKilled,
                             unrealKills, victoryPointTotal, visionWardsBought,
                             wardKilled, wardPlaced)
                        VALUES
                            (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
                             ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
                             ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
	statRes, statErr := db.Exec(
		statsQuery,
		stats.Assists,
		stats.BarracksKilled,
		stats.ChampionsKilled,
		stats.CombatPlayerScore,
		stats.ConsumablesPurchased,
		stats.DamageDealtPlayer,
		stats.DoubleKills,
		stats.FirstBlood,
		stats.Gold,
		stats.GoldEarned,
		stats.GoldSpent,
		stats.Item0,
		stats.Item1,
		stats.Item2,
		stats.Item3,
		stats.Item4,
		stats.Item5,
		stats.Item6,
		stats.ItemsPurchased,
		stats.KillingSprees,
		stats.LargestCriticalStrike,
		stats.LargestKillingSpree,
		stats.LargestMultiKill,
		stats.LegendaryItemsCreated,
		stats.Level,
		stats.MagicDamageDealtPlayer,
		stats.MagicDamageDealtToChampions,
		stats.MagicDamageTaken,
		stats.MinionsDenied,
		stats.MinionsKilled,
		stats.NeutralMinionsKilled,
		stats.NeutralMinionsKilledEnemyJungle,
		stats.NeutralMinionsKilledYourJungle,
		stats.NexusKilled,
		stats.NodeCapture,
		stats.NodeCaptureAssist,
		stats.NodeNeutralize,
		stats.NodeNeutralizeAssist,
		stats.NumDeaths,
		stats.NumItemsBought,
		stats.ObjectivePlayerScore,
		stats.PentaKills,
		stats.PhysicalDamageDealtPlayer,
		stats.PhysicalDamageDealtToChampions,
		stats.PhysicalDamageTaken,
		stats.QuadraKills,
		stats.SightWardsBought,
		stats.Spell1Cast,
		stats.Spell2Cast,
		stats.Spell3Cast,
		stats.Spell4Cast,
		stats.SummonSpell1Cast,
		stats.SummonSpell2Cast,
		stats.SuperMonsterKilled,
		stats.Team,
		stats.TeamObjective,
		stats.TimePlayed,
		stats.TotalDamageDealt,
		stats.TotalDamageDealtToChampions,
		stats.TotalDamageTaken,
		stats.TotalHeal,
		stats.TotalPlayerScore,
		stats.TotalScoreRank,
		stats.TotalTimeCrowdControlDealt,
		stats.TotalUnitsHealed,
		stats.TripleKills,
		stats.TrueDamageDealtPlayer,
		stats.TrueDamageDealtToChampions,
		stats.TrueDamageTaken,
		stats.TurretsKilled,
		stats.UnrealKills,
		stats.VictoryPointTotal,
		stats.VisionWardsBought,
		stats.WardKilled,
		stats.WardPlaced)
	checkErr(statErr, "Could not insert stats")

	statId, statIdErr := statRes.LastInsertId()
	checkErr(statIdErr, "Could not get last insterted id")

	return statId
}
<|endoftext|>


<commit_before>package checkdisk

import (
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/jessevdk/go-flags"
	"github.com/mackerelio/checkers"
	gpud "github.com/shirou/gopsutil/disk"
)

var opts struct {
	Warning       *string   `short:"w" long:"warning" value-name:"N, N%" description:"Exit with WARNING status if less than N units or N% of disk are free"`
	Critical      *string   `short:"c" long:"critical" value-name:"N, N%" description:"Exit with CRITICAL status if less than N units or N% of disk are free"`
	InodeWarning  *string   `short:"W" long:"iwarning" value-name:"N%" description:"Exit with WARNING status if less than PERCENT of inode space is free"`
	InodeCritical *string   `short:"K" long:"icritical" value-name:"N%" description:"Exit with CRITICAL status if less than PERCENT of inode space is free"`
	Path          *[]string `short:"p" long:"path" value-name:"PATH" description:"Mount point or block device as emitted by the mount(8) command (may be repeated)"`
	Exclude       *[]string `short:"x" long:"exclude-device" value-name:"EXCLUDE PATH" description:"Ignore device (may be repeated; only works if -p unspecified)"`
	All           bool      `short:"A" long:"all" description:"Explicitly select all paths."`
	ExcludeType   *[]string `short:"X" long:"exclude-type" value-name:"TYPE" description:"Ignore all filesystems of indicated type (may be repeated)"`
	IncludeType   *[]string `short:"N" long:"include-type" value-name:"TYPE" description:"Check only filesystems of indicated type (may be repeated)"`
	Units         *string   `short:"u" long:"units" value-name:"STRING" description:"Choose bytes, kB, MB, GB, TB (default: MB)"`
}

const (
	b  = float64(1)
	kb = float64(1024) * b
	mb = float64(1024) * kb
	gb = float64(1024) * mb
	tb = float64(1024) * gb
)

type unit struct {
	Name string
	Size float64
}

func checkStatus(current checkers.Status, threshold string, units float64, disk *gpud.UsageStat, chkInode bool, status checkers.Status) (checkers.Status, error) {
	if strings.HasSuffix(threshold, "%") {
		v, err := strconv.ParseFloat(strings.TrimRight(threshold, "%"), 64)
		if err != nil {
			return checkers.UNKNOWN, err
		}

		freePct := float64(100) - disk.UsedPercent
		inodesFreePct := float64(100) - disk.InodesUsedPercent

		if chkInode && (disk.InodesTotal != 0 && v > inodesFreePct) {
			current = status
		}

		if !chkInode && (v > freePct || (disk.InodesTotal != 0 && v > inodesFreePct)) {
			current = status
		}
	} else {
		if chkInode {
			return checkers.UNKNOWN, errors.New("-W, -K value should be N%")
		}

		v, err := strconv.ParseFloat(threshold, 64)
		if err != nil {
			return checkers.UNKNOWN, err
		}

		free := float64(disk.Free) / units
		if v > free {
			current = status
		}
	}

	return current, nil
}

func genMessage(disk *gpud.UsageStat, u unit) string {
	all := float64(disk.Total) / u.Size
	used := float64(disk.Used) / u.Size
	free := float64(disk.Free) / u.Size
	freePct := float64(100) - disk.UsedPercent
	inodesFreePct := float64(100) - disk.InodesUsedPercent

	return fmt.Sprintf("Path: %v, All: %.2f %v, Used: %.2f %v, Free: %.2f %v, Free percentage: %.2f (inodes: %.2f)", disk.Path, all, u.Name, used, u.Name, free, u.Name, freePct, inodesFreePct)
}

// Do the plugin
func Do() {
	ckr := run(os.Args[1:])
	ckr.Name = "Disk"
	ckr.Exit()
}

func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	partitions, err := listPartitions()
	if err != nil {
		return checkers.Unknown(fmt.Sprintf("Failed to fetch partitions: %s", err))
	}

	if !opts.All {
		// Filtering partitions by Fstype
		if opts.IncludeType != nil {
			partitions = filterPartitionsByInclusion(partitions, *opts.IncludeType, fstypeOfPartition)
			if len(partitions) == 0 {
				return checkers.Unknown(fmt.Sprintf("Failed to fetch partitions: %s", errors.New("No device found for the specified *FsType*")))
			}
		}

		if opts.ExcludeType != nil {
			partitions = filterPartitionsByExclusion(partitions, *opts.ExcludeType, fstypeOfPartition)
		}

		// Filtering partions by Mountpoint
		if opts.Path != nil {
			if opts.Exclude != nil {
				return checkers.Unknown(fmt.Sprintf("Invalid arguments: %s", errors.New("-x does not work with -p")))
			}

			partitions = filterPartitionsByInclusion(partitions, *opts.Path, mountpointOfPartition)
			if len(partitions) == 0 {
				return checkers.Unknown(fmt.Sprintf("Failed to fetch partitions: %s", errors.New("No device found for the specified *Mountpoint*")))
			}
		}

		if opts.Path == nil && opts.Exclude != nil {
			partitions = filterPartitionsByExclusion(partitions, *opts.Exclude, mountpointOfPartition)
		}
	}

	if len(partitions) == 0 {
		return checkers.Unknown(fmt.Sprintf("Failed to fetch partitions: %s", errors.New("No device found")))
	}

	var disks []*gpud.UsageStat

	for _, partition := range partitions {
		disk, err := gpud.Usage(partition.Mountpoint)
		if err != nil {
			return checkers.Unknown(fmt.Sprintf("Failed to fetch disk usage: %s", err))
		}

		if disk.Total != 0 {
			disks = append(disks, disk)
		}
	}

	u := unit{"MB", mb}
	if opts.Units != nil {
		us := strings.ToLower(*opts.Units)
		if us == "bytes" {
			u = unit{us, b}
		} else if us == "kb" {
			u = unit{us, mb}
		} else if us == "gb" {
			u = unit{us, gb}
		} else if us == "tb" {
			u = unit{us, tb}
		} else {
			return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", errors.New("Invalid argument flag '-u, --units'")))
		}
	}

	checkSt := checkers.OK
	if opts.InodeCritical != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.InodeCritical, u.Size, disk, true, checkers.CRITICAL)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", err))
			}

			if checkSt == checkers.CRITICAL {
				break
			}
		}
	}

	if checkSt != checkers.CRITICAL && opts.Critical != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.Critical, u.Size, disk, false, checkers.CRITICAL)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", err))
			}

			if checkSt == checkers.CRITICAL {
				break
			}
		}
	}

	if checkSt != checkers.CRITICAL && opts.InodeWarning != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.InodeWarning, u.Size, disk, true, checkers.WARNING)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", err))
			}

			if checkSt == checkers.WARNING {
				break
			}
		}
	}

	if checkSt == checkers.OK && opts.Warning != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.Warning, u.Size, disk, false, checkers.WARNING)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", err))
			}

			if checkSt == checkers.WARNING {
				break
			}
		}
	}

	var msgs []string
	for _, disk := range disks {
		msg := genMessage(disk, u)
		msgs = append(msgs, msg)
	}
	msgss := strings.Join(msgs, ";\n")

	return checkers.NewChecker(checkSt, msgss)
}

// ref: mountlist.c in gnulib
// https://github.com/coreutils/gnulib/blob/a742bdb3/lib/mountlist.c#L168
func listPartitions() ([]gpud.PartitionStat, error) {
	allPartitions, err := gpud.Partitions(true)
	if err != nil {
		return nil, err
	}
	partitions := make([]gpud.PartitionStat, 0, len(allPartitions))
	for _, p := range allPartitions {
		switch p.Fstype {
		case "autofs",
			"proc",
			"subfs",
			"debugfs",
			"devpts",
			"fusectl",
			"mqueue",
			"rpc_pipefs",
			"sysfs",
			"devfs",
			"kernfs",
			"ignore":
			continue
		case "none":
			if !strings.Contains(p.Opts, "bind") {
				partitions = append(partitions, p)
			}
		default:
			partitions = append(partitions, p)
		}
	}

	return partitions, nil
}

func mountpointOfPartition(partition gpud.PartitionStat) string {
	return partition.Mountpoint
}

func fstypeOfPartition(partition gpud.PartitionStat) string {
	return partition.Fstype
}

func filterPartitionsByInclusion(partitions []gpud.PartitionStat, list []string, key func(_ gpud.PartitionStat) string) []gpud.PartitionStat {
	newPartitions := make([]gpud.PartitionStat, 0, len(partitions))
	for _, partition := range partitions {
		var ok = false
		for _, l := range list {
			if (l == key(partition)) {
				ok = true
				break
			}
		}
		if (ok) {
			newPartitions = append(newPartitions, partition)
		}
	}

	return newPartitions
}

func filterPartitionsByExclusion(partitions []gpud.PartitionStat, list []string, key func(_ gpud.PartitionStat) string) []gpud.PartitionStat {
	newPartitions := make([]gpud.PartitionStat, 0, len(partitions))
	for _, partition := range partitions {
		var ok = true
		for _, l := range list {
			if (l == key(partition)) {
				ok = false
				break
			}
		}
		if (ok) {
			newPartitions = append(newPartitions, partition)
		}
	}

	return newPartitions
}
<commit_msg>[check-disk] gofmt<commit_after>package checkdisk

import (
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/jessevdk/go-flags"
	"github.com/mackerelio/checkers"
	gpud "github.com/shirou/gopsutil/disk"
)

var opts struct {
	Warning       *string   `short:"w" long:"warning" value-name:"N, N%" description:"Exit with WARNING status if less than N units or N% of disk are free"`
	Critical      *string   `short:"c" long:"critical" value-name:"N, N%" description:"Exit with CRITICAL status if less than N units or N% of disk are free"`
	InodeWarning  *string   `short:"W" long:"iwarning" value-name:"N%" description:"Exit with WARNING status if less than PERCENT of inode space is free"`
	InodeCritical *string   `short:"K" long:"icritical" value-name:"N%" description:"Exit with CRITICAL status if less than PERCENT of inode space is free"`
	Path          *[]string `short:"p" long:"path" value-name:"PATH" description:"Mount point or block device as emitted by the mount(8) command (may be repeated)"`
	Exclude       *[]string `short:"x" long:"exclude-device" value-name:"EXCLUDE PATH" description:"Ignore device (may be repeated; only works if -p unspecified)"`
	All           bool      `short:"A" long:"all" description:"Explicitly select all paths."`
	ExcludeType   *[]string `short:"X" long:"exclude-type" value-name:"TYPE" description:"Ignore all filesystems of indicated type (may be repeated)"`
	IncludeType   *[]string `short:"N" long:"include-type" value-name:"TYPE" description:"Check only filesystems of indicated type (may be repeated)"`
	Units         *string   `short:"u" long:"units" value-name:"STRING" description:"Choose bytes, kB, MB, GB, TB (default: MB)"`
}

const (
	b  = float64(1)
	kb = float64(1024) * b
	mb = float64(1024) * kb
	gb = float64(1024) * mb
	tb = float64(1024) * gb
)

type unit struct {
	Name string
	Size float64
}

func checkStatus(current checkers.Status, threshold string, units float64, disk *gpud.UsageStat, chkInode bool, status checkers.Status) (checkers.Status, error) {
	if strings.HasSuffix(threshold, "%") {
		v, err := strconv.ParseFloat(strings.TrimRight(threshold, "%"), 64)
		if err != nil {
			return checkers.UNKNOWN, err
		}

		freePct := float64(100) - disk.UsedPercent
		inodesFreePct := float64(100) - disk.InodesUsedPercent

		if chkInode && (disk.InodesTotal != 0 && v > inodesFreePct) {
			current = status
		}

		if !chkInode && (v > freePct || (disk.InodesTotal != 0 && v > inodesFreePct)) {
			current = status
		}
	} else {
		if chkInode {
			return checkers.UNKNOWN, errors.New("-W, -K value should be N%")
		}

		v, err := strconv.ParseFloat(threshold, 64)
		if err != nil {
			return checkers.UNKNOWN, err
		}

		free := float64(disk.Free) / units
		if v > free {
			current = status
		}
	}

	return current, nil
}

func genMessage(disk *gpud.UsageStat, u unit) string {
	all := float64(disk.Total) / u.Size
	used := float64(disk.Used) / u.Size
	free := float64(disk.Free) / u.Size
	freePct := float64(100) - disk.UsedPercent
	inodesFreePct := float64(100) - disk.InodesUsedPercent

	return fmt.Sprintf("Path: %v, All: %.2f %v, Used: %.2f %v, Free: %.2f %v, Free percentage: %.2f (inodes: %.2f)", disk.Path, all, u.Name, used, u.Name, free, u.Name, freePct, inodesFreePct)
}

// Do the plugin
func Do() {
	ckr := run(os.Args[1:])
	ckr.Name = "Disk"
	ckr.Exit()
}

func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	partitions, err := listPartitions()
	if err != nil {
		return checkers.Unknown(fmt.Sprintf("Failed to fetch partitions: %s", err))
	}

	if !opts.All {
		// Filtering partitions by Fstype
		if opts.IncludeType != nil {
			partitions = filterPartitionsByInclusion(partitions, *opts.IncludeType, fstypeOfPartition)
			if len(partitions) == 0 {
				return checkers.Unknown(fmt.Sprintf("Failed to fetch partitions: %s", errors.New("No device found for the specified *FsType*")))
			}
		}

		if opts.ExcludeType != nil {
			partitions = filterPartitionsByExclusion(partitions, *opts.ExcludeType, fstypeOfPartition)
		}

		// Filtering partions by Mountpoint
		if opts.Path != nil {
			if opts.Exclude != nil {
				return checkers.Unknown(fmt.Sprintf("Invalid arguments: %s", errors.New("-x does not work with -p")))
			}

			partitions = filterPartitionsByInclusion(partitions, *opts.Path, mountpointOfPartition)
			if len(partitions) == 0 {
				return checkers.Unknown(fmt.Sprintf("Failed to fetch partitions: %s", errors.New("No device found for the specified *Mountpoint*")))
			}
		}

		if opts.Path == nil && opts.Exclude != nil {
			partitions = filterPartitionsByExclusion(partitions, *opts.Exclude, mountpointOfPartition)
		}
	}

	if len(partitions) == 0 {
		return checkers.Unknown(fmt.Sprintf("Failed to fetch partitions: %s", errors.New("No device found")))
	}

	var disks []*gpud.UsageStat

	for _, partition := range partitions {
		disk, err := gpud.Usage(partition.Mountpoint)
		if err != nil {
			return checkers.Unknown(fmt.Sprintf("Failed to fetch disk usage: %s", err))
		}

		if disk.Total != 0 {
			disks = append(disks, disk)
		}
	}

	u := unit{"MB", mb}
	if opts.Units != nil {
		us := strings.ToLower(*opts.Units)
		if us == "bytes" {
			u = unit{us, b}
		} else if us == "kb" {
			u = unit{us, mb}
		} else if us == "gb" {
			u = unit{us, gb}
		} else if us == "tb" {
			u = unit{us, tb}
		} else {
			return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", errors.New("Invalid argument flag '-u, --units'")))
		}
	}

	checkSt := checkers.OK
	if opts.InodeCritical != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.InodeCritical, u.Size, disk, true, checkers.CRITICAL)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", err))
			}

			if checkSt == checkers.CRITICAL {
				break
			}
		}
	}

	if checkSt != checkers.CRITICAL && opts.Critical != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.Critical, u.Size, disk, false, checkers.CRITICAL)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", err))
			}

			if checkSt == checkers.CRITICAL {
				break
			}
		}
	}

	if checkSt != checkers.CRITICAL && opts.InodeWarning != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.InodeWarning, u.Size, disk, true, checkers.WARNING)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", err))
			}

			if checkSt == checkers.WARNING {
				break
			}
		}
	}

	if checkSt == checkers.OK && opts.Warning != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.Warning, u.Size, disk, false, checkers.WARNING)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Failed to check disk status: %s", err))
			}

			if checkSt == checkers.WARNING {
				break
			}
		}
	}

	var msgs []string
	for _, disk := range disks {
		msg := genMessage(disk, u)
		msgs = append(msgs, msg)
	}
	msgss := strings.Join(msgs, ";\n")

	return checkers.NewChecker(checkSt, msgss)
}

// ref: mountlist.c in gnulib
// https://github.com/coreutils/gnulib/blob/a742bdb3/lib/mountlist.c#L168
func listPartitions() ([]gpud.PartitionStat, error) {
	allPartitions, err := gpud.Partitions(true)
	if err != nil {
		return nil, err
	}
	partitions := make([]gpud.PartitionStat, 0, len(allPartitions))
	for _, p := range allPartitions {
		switch p.Fstype {
		case "autofs",
			"proc",
			"subfs",
			"debugfs",
			"devpts",
			"fusectl",
			"mqueue",
			"rpc_pipefs",
			"sysfs",
			"devfs",
			"kernfs",
			"ignore":
			continue
		case "none":
			if !strings.Contains(p.Opts, "bind") {
				partitions = append(partitions, p)
			}
		default:
			partitions = append(partitions, p)
		}
	}

	return partitions, nil
}

func mountpointOfPartition(partition gpud.PartitionStat) string {
	return partition.Mountpoint
}

func fstypeOfPartition(partition gpud.PartitionStat) string {
	return partition.Fstype
}

func filterPartitionsByInclusion(partitions []gpud.PartitionStat, list []string, key func(_ gpud.PartitionStat) string) []gpud.PartitionStat {
	newPartitions := make([]gpud.PartitionStat, 0, len(partitions))
	for _, partition := range partitions {
		var ok = false
		for _, l := range list {
			if l == key(partition) {
				ok = true
				break
			}
		}
		if ok {
			newPartitions = append(newPartitions, partition)
		}
	}

	return newPartitions
}

func filterPartitionsByExclusion(partitions []gpud.PartitionStat, list []string, key func(_ gpud.PartitionStat) string) []gpud.PartitionStat {
	newPartitions := make([]gpud.PartitionStat, 0, len(partitions))
	for _, partition := range partitions {
		var ok = true
		for _, l := range list {
			if l == key(partition) {
				ok = false
				break
			}
		}
		if ok {
			newPartitions = append(newPartitions, partition)
		}
	}

	return newPartitions
}
<|endoftext|>


<commit_before>package crypto

import (
	"crypto/sha256"
	"encoding/base64"
)

var iv = []byte{0xe8, 0x30, 0x09, 0x4b, 0x97, 0x20, 0x5d, 0x2a}
var sigmaWords = []uint32{
	0x61707865,
	0x3320646e,
	0x79622d32,
	0x6b206574,
}

// SalsaStream is a Salsa20 cipher that implements CryptoStream interface
type SalsaStream struct {
	State        []uint32
	blockUsed    int
	block        []byte
	counterWords [2]uint32
	currentBlock []byte
}

// NewSalsaStream initialize a new SalsaStream interfaced with CryptoStream
func NewSalsaStream(key []byte) (*SalsaStream, error) {
	hash := sha256.Sum256(key)
	state := make([]uint32, 16)

	state[1] = u8to32little(hash[:], 0)
	state[2] = u8to32little(hash[:], 4)
	state[3] = u8to32little(hash[:], 8)
	state[4] = u8to32little(hash[:], 12)
	state[11] = u8to32little(hash[:], 16)
	state[12] = u8to32little(hash[:], 20)
	state[13] = u8to32little(hash[:], 24)
	state[14] = u8to32little(hash[:], 28)
	state[0] = sigmaWords[0]
	state[5] = sigmaWords[1]
	state[10] = sigmaWords[2]
	state[15] = sigmaWords[3]

	state[6] = u8to32little(iv, 0)
	state[7] = u8to32little(iv, 4)
	state[8] = uint32(0)
	state[9] = uint32(0)

	s := SalsaStream{
		State:        state,
		currentBlock: make([]byte, 0),
	}
	s.reset()
	return &s, nil
}

// Unpack returns the payload as unencrypted byte array
func (s *SalsaStream) Unpack(payload string) []byte {
	var result []byte

	data, _ := base64.StdEncoding.DecodeString(payload)

	salsaBytes := s.fetchBytes(len(data))

	for i := 0; i < len(data); i++ {
		result = append(result, salsaBytes[i]^data[i])
	}
	return result
}

// Pack returns the payload as encrypted string
func (s *SalsaStream) Pack(payload []byte) string {
	var data []byte

	salsaBytes := s.fetchBytes(len(payload))

	for i := 0; i < len(payload); i++ {
		data = append(data, salsaBytes[i]^payload[i])
	}

	lockedPassword := base64.StdEncoding.EncodeToString(data)
	return lockedPassword
}

func u8to32little(k []byte, i int) uint32 {
	return uint32(k[i]) |
		(uint32(k[i+1]) << 8) |
		(uint32(k[i+2]) << 16) |
		(uint32(k[i+3]) << 24)
}

func rotl32(x uint32, b uint) uint32 {
	return ((x << b) | (x >> (32 - b)))
}

func (s *SalsaStream) reset() {
	s.blockUsed = 64
	s.counterWords = [2]uint32{0, 0}
}

func (s *SalsaStream) incrementCounter() {
	s.counterWords[0] = (s.counterWords[0] + 1) & 0xffffffff
	if s.counterWords[0] == 0 {
		s.counterWords[1] = (s.counterWords[1] + 1) & 0xffffffff
	}
}

func (s *SalsaStream) fetchBytes(length int) []byte {
	for length > len(s.currentBlock) {
		s.currentBlock = append(s.currentBlock, s.getBytes(64)...)
	}

	data := s.currentBlock[0:length]
	s.currentBlock = s.currentBlock[length:]

	return data
}

func (s *SalsaStream) getBytes(length int) []byte {
	b := make([]byte, length)

	for i := 0; i < length; i++ {
		if s.blockUsed == 64 {
			s.generateBlock()
			s.incrementCounter()
			s.blockUsed = 0
		}
		b[i] = s.block[s.blockUsed]
		s.blockUsed++
	}

	return b
}

func (s *SalsaStream) generateBlock() {
	s.block = make([]byte, 64)

	x := make([]uint32, 16)
	copy(x, s.State)

	for i := 0; i < 10; i++ {
		x[4] = x[4] ^ rotl32(x[0]+x[12], 7)
		x[8] = x[8] ^ rotl32(x[4]+x[0], 9)
		x[12] = x[12] ^ rotl32(x[8]+x[4], 13)
		x[0] = x[0] ^ rotl32(x[12]+x[8], 18)

		x[9] = x[9] ^ rotl32(x[5]+x[1], 7)
		x[13] = x[13] ^ rotl32(x[9]+x[5], 9)
		x[1] = x[1] ^ rotl32(x[13]+x[9], 13)
		x[5] = x[5] ^ rotl32(x[1]+x[13], 18)

		x[14] = x[14] ^ rotl32(x[10]+x[6], 7)
		x[2] = x[2] ^ rotl32(x[14]+x[10], 9)
		x[6] = x[6] ^ rotl32(x[2]+x[14], 13)
		x[10] = x[10] ^ rotl32(x[6]+x[2], 18)

		x[3] = x[3] ^ rotl32(x[15]+x[11], 7)
		x[7] = x[7] ^ rotl32(x[3]+x[15], 9)
		x[11] = x[11] ^ rotl32(x[7]+x[3], 13)
		x[15] = x[15] ^ rotl32(x[11]+x[7], 18)

		x[1] = x[1] ^ rotl32(x[0]+x[3], 7)
		x[2] = x[2] ^ rotl32(x[1]+x[0], 9)
		x[3] = x[3] ^ rotl32(x[2]+x[1], 13)
		x[0] = x[0] ^ rotl32(x[3]+x[2], 18)

		x[6] = x[6] ^ rotl32(x[5]+x[4], 7)
		x[7] = x[7] ^ rotl32(x[6]+x[5], 9)
		x[4] = x[4] ^ rotl32(x[7]+x[6], 13)
		x[5] = x[5] ^ rotl32(x[4]+x[7], 18)

		x[11] = x[11] ^ rotl32(x[10]+x[9], 7)
		x[8] = x[8] ^ rotl32(x[11]+x[10], 9)
		x[9] = x[9] ^ rotl32(x[8]+x[11], 13)
		x[10] = x[10] ^ rotl32(x[9]+x[8], 18)

		x[12] = x[12] ^ rotl32(x[15]+x[14], 7)
		x[13] = x[13] ^ rotl32(x[12]+x[15], 9)
		x[14] = x[14] ^ rotl32(x[13]+x[12], 13)
		x[15] = x[15] ^ rotl32(x[14]+x[13], 18)
	}

	for i := 0; i < 16; i++ {
		x[i] += s.State[i]
	}

	for i := 0; i < 16; i++ {
		s.block[i<<2] = byte(x[i])
		s.block[(i<<2)+1] = byte(x[i] >> 8)
		s.block[(i<<2)+2] = byte(x[i] >> 16)
		s.block[(i<<2)+3] = byte(x[i] >> 24)
	}
	s.blockUsed = 0
	s.State[8]++
	if s.State[8] == 0 {
		s.State[9]++
	}
}
<commit_msg>Drop counter from SalsaStream<commit_after>package crypto

import (
	"crypto/sha256"
	"encoding/base64"
)

var iv = []byte{0xe8, 0x30, 0x09, 0x4b, 0x97, 0x20, 0x5d, 0x2a}
var sigmaWords = []uint32{
	0x61707865,
	0x3320646e,
	0x79622d32,
	0x6b206574,
}

// SalsaStream is a Salsa20 cipher that implements CryptoStream interface
type SalsaStream struct {
	State        []uint32
	blockUsed    int
	block        []byte
	currentBlock []byte
}

// NewSalsaStream initialize a new SalsaStream interfaced with CryptoStream
func NewSalsaStream(key []byte) (*SalsaStream, error) {
	hash := sha256.Sum256(key)
	state := make([]uint32, 16)

	state[1] = u8to32little(hash[:], 0)
	state[2] = u8to32little(hash[:], 4)
	state[3] = u8to32little(hash[:], 8)
	state[4] = u8to32little(hash[:], 12)
	state[11] = u8to32little(hash[:], 16)
	state[12] = u8to32little(hash[:], 20)
	state[13] = u8to32little(hash[:], 24)
	state[14] = u8to32little(hash[:], 28)
	state[0] = sigmaWords[0]
	state[5] = sigmaWords[1]
	state[10] = sigmaWords[2]
	state[15] = sigmaWords[3]

	state[6] = u8to32little(iv, 0)
	state[7] = u8to32little(iv, 4)
	state[8] = uint32(0)
	state[9] = uint32(0)

	s := SalsaStream{
		State:        state,
		blockUsed:    64, // Ensure a fresh block is generated, the first time bytes are needed
		currentBlock: make([]byte, 0),
	}
	return &s, nil
}

// Unpack returns the payload as unencrypted byte array
func (s *SalsaStream) Unpack(payload string) []byte {
	var result []byte

	data, _ := base64.StdEncoding.DecodeString(payload)

	salsaBytes := s.fetchBytes(len(data))

	for i := 0; i < len(data); i++ {
		result = append(result, salsaBytes[i]^data[i])
	}
	return result
}

// Pack returns the payload as encrypted string
func (s *SalsaStream) Pack(payload []byte) string {
	var data []byte

	salsaBytes := s.fetchBytes(len(payload))

	for i := 0; i < len(payload); i++ {
		data = append(data, salsaBytes[i]^payload[i])
	}

	lockedPassword := base64.StdEncoding.EncodeToString(data)
	return lockedPassword
}

func u8to32little(k []byte, i int) uint32 {
	return uint32(k[i]) |
		(uint32(k[i+1]) << 8) |
		(uint32(k[i+2]) << 16) |
		(uint32(k[i+3]) << 24)
}

func rotl32(x uint32, b uint) uint32 {
	return ((x << b) | (x >> (32 - b)))
}

func (s *SalsaStream) fetchBytes(length int) []byte {
	for length > len(s.currentBlock) {
		s.currentBlock = append(s.currentBlock, s.getBytes(64)...)
	}

	data := s.currentBlock[0:length]
	s.currentBlock = s.currentBlock[length:]

	return data
}

func (s *SalsaStream) getBytes(length int) []byte {
	b := make([]byte, length)

	for i := 0; i < length; i++ {
		if s.blockUsed == 64 {
			s.generateBlock()
			s.blockUsed = 0
		}
		b[i] = s.block[s.blockUsed]
		s.blockUsed++
	}

	return b
}

func (s *SalsaStream) generateBlock() {
	s.block = make([]byte, 64)

	x := make([]uint32, 16)
	copy(x, s.State)

	for i := 0; i < 10; i++ {
		x[4] = x[4] ^ rotl32(x[0]+x[12], 7)
		x[8] = x[8] ^ rotl32(x[4]+x[0], 9)
		x[12] = x[12] ^ rotl32(x[8]+x[4], 13)
		x[0] = x[0] ^ rotl32(x[12]+x[8], 18)

		x[9] = x[9] ^ rotl32(x[5]+x[1], 7)
		x[13] = x[13] ^ rotl32(x[9]+x[5], 9)
		x[1] = x[1] ^ rotl32(x[13]+x[9], 13)
		x[5] = x[5] ^ rotl32(x[1]+x[13], 18)

		x[14] = x[14] ^ rotl32(x[10]+x[6], 7)
		x[2] = x[2] ^ rotl32(x[14]+x[10], 9)
		x[6] = x[6] ^ rotl32(x[2]+x[14], 13)
		x[10] = x[10] ^ rotl32(x[6]+x[2], 18)

		x[3] = x[3] ^ rotl32(x[15]+x[11], 7)
		x[7] = x[7] ^ rotl32(x[3]+x[15], 9)
		x[11] = x[11] ^ rotl32(x[7]+x[3], 13)
		x[15] = x[15] ^ rotl32(x[11]+x[7], 18)

		x[1] = x[1] ^ rotl32(x[0]+x[3], 7)
		x[2] = x[2] ^ rotl32(x[1]+x[0], 9)
		x[3] = x[3] ^ rotl32(x[2]+x[1], 13)
		x[0] = x[0] ^ rotl32(x[3]+x[2], 18)

		x[6] = x[6] ^ rotl32(x[5]+x[4], 7)
		x[7] = x[7] ^ rotl32(x[6]+x[5], 9)
		x[4] = x[4] ^ rotl32(x[7]+x[6], 13)
		x[5] = x[5] ^ rotl32(x[4]+x[7], 18)

		x[11] = x[11] ^ rotl32(x[10]+x[9], 7)
		x[8] = x[8] ^ rotl32(x[11]+x[10], 9)
		x[9] = x[9] ^ rotl32(x[8]+x[11], 13)
		x[10] = x[10] ^ rotl32(x[9]+x[8], 18)

		x[12] = x[12] ^ rotl32(x[15]+x[14], 7)
		x[13] = x[13] ^ rotl32(x[12]+x[15], 9)
		x[14] = x[14] ^ rotl32(x[13]+x[12], 13)
		x[15] = x[15] ^ rotl32(x[14]+x[13], 18)
	}

	for i := 0; i < 16; i++ {
		x[i] += s.State[i]
	}

	for i := 0; i < 16; i++ {
		s.block[i<<2] = byte(x[i])
		s.block[(i<<2)+1] = byte(x[i] >> 8)
		s.block[(i<<2)+2] = byte(x[i] >> 16)
		s.block[(i<<2)+3] = byte(x[i] >> 24)
	}
	s.blockUsed = 0
	s.State[8]++
	if s.State[8] == 0 {
		s.State[9]++
	}
}
<|endoftext|>


<commit_before>package geoip

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
)

var baseURI = "https://freegeoip.net/json/"

// Location queries location information of an IP address. 'ip' can be a IPv4
// or IPv6 address. It is the users job to make sure 'ip' is a valid IP address.
func Location(ip string) (map[string]string, error) {
	uri := fmt.Sprintf("%s%s", baseURI, ip)
	body, err := performRequest(uri)
	if err != nil {
		return nil, err
	}
	data, err := extractJSON(body)
	if err != nil {
		return nil, err
	}
	m := make(map[string]string)
	for k, v := range data {
		if k == "latitude" || k == "longitude" || k == "metro_code" {
			m[k] = strconv.FormatFloat(v.(float64), 'f', -1, 64)
		} else {
			m[k] = v.(string)
		}
	}
	return m, nil
}

func performRequest(uri string) ([]byte, error) {
	res, err := http.Get(uri)
	if err != nil {
		log.Fatal(err)
	}
	body, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		return nil, err
	}
	if res.StatusCode != http.StatusOK {
		e := fmt.Sprintf("http %d from %s", res.StatusCode, baseURI)
		return nil, errors.New(e)
	}
	return body, nil
}

func extractJSON(jsonBlob []byte) (map[string]interface{}, error) {
	var j map[string]interface{}
	err := json.Unmarshal(jsonBlob, &j)
	if err != nil {
		return nil, err
	}
	return j, nil
}
<commit_msg>Export error variable outside package<commit_after>package geoip

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
)

var baseURI = "https://freegeoip.net/json/"

var ErrReq error

// Location queries location information of an IP address. 'ip' can be a IPv4
// or IPv6 address. It is the users job to make sure 'ip' is a valid IP address.
func Location(ip string) (map[string]string, error) {
	uri := fmt.Sprintf("%s%s", baseURI, ip)
	body, err := performRequest(uri)
	if err != nil {
		return nil, err
	}
	data, err := extractJSON(body)
	if err != nil {
		return nil, err
	}
	m := make(map[string]string)
	for k, v := range data {
		if k == "latitude" || k == "longitude" || k == "metro_code" {
			m[k] = strconv.FormatFloat(v.(float64), 'f', -1, 64)
		} else {
			m[k] = v.(string)
		}
	}
	return m, nil
}

func performRequest(uri string) ([]byte, error) {
	res, err := http.Get(uri)
	if err != nil {
		log.Fatal(err)
	}
	body, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		return nil, err
	}
	if res.StatusCode != http.StatusOK {
		e := fmt.Sprintf("http %d from %s", res.StatusCode, baseURI)
		ErrReq = errors.New(e)
		return nil, ErrReq
	}
	return body, nil
}

func extractJSON(jsonBlob []byte) (map[string]interface{}, error) {
	var j map[string]interface{}
	err := json.Unmarshal(jsonBlob, &j)
	if err != nil {
		return nil, err
	}
	return j, nil
}
<|endoftext|>