<commit_before>package main

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"time"
)

//Config Get config info from extra config.json file.
type Config struct {
	Concurrency          int      `json:"concurrency"`
	Timeout              int      `json:"timeout"`
	HandshakeTimeout     int      `json:"handshake_timeout"`
	Delay                int      `json:"delay"`
	OrgNames             []string `json:"organization"`
	GwsDomains           []string `json:"gws"`
	GvsDomains           []string `json:"gvs"`
	SortOkIP             bool     `json:"sort_tmpokfile"`
	CheckLastOkIP        bool     `json:"check_last_okip"`
	CheckBandwidth       bool     `json:"check_bandwidth"`
	SortBandwidth        bool     `json:"sort_bandwidth"`
	BandwidthConcurrency int      `json:"bandwidth_concurrency"`
	BandwidthTimeout     int      `json:"bandwidth_timeout"`
	Write2Goproxy        bool     `json:"write_to_goproxy"`
	GoproxyPath          string   `json:"goproxy_path"`
}

const (
	configFileName   string = "config.json"
	certFileName     string = "cacert.pem"
	googleIPFileName string = "googleip.txt"
	tmpOkIPFileName  string = "ip_tmpok.txt"
	tmpErrIPFileName string = "ip_tmperr.txt"
	tmpNoIPFileName  string = "ip_tmpno.txt"
	jsonIPFileName   string = "ip.txt"
)

var config Config
var curDir string
var separator string
var certPool *x509.CertPool
var tlsConfig *tls.Config
var dialer net.Dialer

func init() {
	parseConfig()
	loadCertPem()
	createFile()
	tlsConfig = &tls.Config{
		RootCAs:            certPool,
		InsecureSkipVerify: true,
	}
}

func main() {

	flag.Set("logtostderr", "true")
	flag.Parse()

	var lastOkIPs []string
	if config.CheckLastOkIP {
		tmpLastOkIPs := getLastOkIP()
		for _, ip := range tmpLastOkIPs {
			lastOkIPs = append(lastOkIPs, ip.Address)
		}
	}

	ips := append(lastOkIPs, getGoogleIP()...)

	fmt.Printf("load last checked ip ok, count: %d,\nload extra ip ok, line: %d, count: %d\n\n", len(lastOkIPs), len(getGoogleIPRange()), len(ips))
	time.Sleep(10 * 1000)

	jobs := make(chan string, config.Concurrency)
	done := make(chan bool, config.Concurrency)

	//check all goole ip begin
	t0 := time.Now()
	go func() {
		for _, ip := range ips {
			jobs <- ip
		}
		close(jobs)
	}()
	for ip := range jobs {
		done <- true
		go checkIP(ip, done)
	}
	for i := 0; i < cap(done); i++ {
		done <- true
	}
	//check all goole ip end

	if config.CheckBandwidth {

		jobs := make(chan IP, config.BandwidthConcurrency)
		done := make(chan bool, config.BandwidthConcurrency)

		ips := getLastOkIP()
		_, err := os.Create(tmpOkIPFileName)
		checkErr(fmt.Sprintf("create file %s error: ", tmpOkIPFileName), err, Error)
		// t2 := time.Now()
		go func() {
			for _, ip := range ips {
				jobs <- ip
			}
			close(jobs)
		}()
		for ip := range jobs {
			done <- true
			go checkBandwidth(ip, done)
		}
		for i := 0; i < cap(done); i++ {
			done <- true
		}
		// t3 := time.Now()
		// cost := int(t3.Sub(t2).Seconds())
	}
	gws, gvs, gpips := writeJSONIP2File()
	t1 := time.Now()
	cost := int(t1.Sub(t0).Seconds())
	fmt.Printf("\ntime: %ds, ok ip count: %d(gws: %d, gvs: %d)\n\n", cost, gws+gvs, gws, gvs)
	if config.Write2Goproxy {
		file := filepath.Join(config.GoproxyPath, "gae.user.json")
		if isFileExist(file) {
			writeIP2Goproxy(file, gpips)
		} else if isFileExist(filepath.Join(config.GoproxyPath, "gae.user.json")) {
			writeIP2Goproxy(file, gpips)
		} else {
			fmt.Println("directory: ", config.GoproxyPath, " not found.")
		}
	}
	fmt.Println("\npress 'Enter' to continue...")
	fmt.Scanln()
}

//Parse config file
func parseConfig() {
	conf, err := ioutil.ReadFile(configFileName)
	checkErr("read config file error: ", err, Error)
	err = json.Unmarshal(conf, &config)
	checkErr("parse config file error: ", err, Error)
}

//Load cacert.pem
func loadCertPem() {
	certpem, err := ioutil.ReadFile(certFileName)
	checkErr(fmt.Sprintf("read pem file %s error: ", certFileName), err, Error)
	certPool = x509.NewCertPool()
	if !certPool.AppendCertsFromPEM(certpem) {
		checkErr(fmt.Sprintf("load pem file %s error: ", certFileName), errors.New("load pem file error"), Error)
	}
}

func checkIP(ip string, done chan bool) {
	defer func() {
		<-done
	}()
	var checkedip IP
	checkedip.Address = ip
	checkedip.Bandwidth = -1
	checkedip.CountryName = "-"
	dialer = net.Dialer{
		Timeout:   time.Millisecond * time.Duration(config.Timeout),
		KeepAlive: 0,
		DualStack: false,
	}

	conn, err := dialer.Dial("tcp", net.JoinHostPort(ip, "443"))
	if err != nil {
		checkErr(fmt.Sprintf("%s dial error: ", ip), err, Debug)
		appendIP2File(checkedip, tmpErrIPFileName)
		return
	}
	defer conn.Close()

	t0 := time.Now()
	tlsClient := tls.Client(conn, tlsConfig)
	tlsClient.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(config.HandshakeTimeout)))
	err = tlsClient.Handshake()

	if err != nil {
		checkErr(fmt.Sprintf("%s handshake error: ", ip), err, Debug)
		appendIP2File(checkedip, tmpErrIPFileName)
		return
	}
	defer tlsClient.Close()
	t1 := time.Now()

	if tlsClient.ConnectionState().PeerCertificates == nil {
		checkErr(fmt.Sprintf("%s peer certificates error: ", ip), errors.New("peer certificates is nil"), Debug)
		appendIP2File(checkedip, tmpNoIPFileName)
		return
	}

	checkedip.Delay = int(t1.Sub(t0).Seconds() * 1000)

	peerCertSubject := tlsClient.ConnectionState().PeerCertificates[0].Subject
	checkedip.CommonName = peerCertSubject.CommonName
	orgNames := peerCertSubject.Organization
	if len(peerCertSubject.Organization) > 0 {
		checkedip.OrgName = orgNames[0]
	}
	countryNames := peerCertSubject.Country
	if len(countryNames) > 0 {
		checkedip.CountryName = countryNames[0]
	}

	for _, org := range config.OrgNames {
		if org == checkedip.OrgName {
			var flag0, flag1 bool
			for _, gws := range config.GwsDomains {
				if gws == checkedip.CommonName {
					checkedip.ServerName = "gws"
					appendIP2File(checkedip, tmpOkIPFileName)
					flag0 = true
					break
				}
			}
			if !flag0 {
				for _, gvs := range config.GvsDomains {
					if gvs == checkedip.CommonName {
						checkedip.ServerName = "gvs"
						appendIP2File(checkedip, tmpOkIPFileName)
						flag1 = true
						break
					}
				}
			}
			if !flag0 && !flag1 {
				appendIP2File(checkedip, tmpNoIPFileName)
			}
		} else {
			appendIP2File(checkedip, tmpNoIPFileName)
		}
	}
	checkErr(fmt.Sprintf("%s: %s %s %s %dms", checkedip.Address, checkedip.CommonName, checkedip.ServerName, checkedip.CountryName,
		checkedip.Delay), errors.New(""), Info)
}

//append ip to related file
func appendIP2File(checkedip IP, filename string) {
	f, err := os.OpenFile(filename, os.O_APPEND, os.ModeAppend)
	checkErr(fmt.Sprintf("open file %s error: ", filename), err, Error)
	defer f.Close()

	_, err = f.WriteString(fmt.Sprintf("%s %dms %s %s %s %dKB/s\n", checkedip.Address, checkedip.Delay, checkedip.CommonName, checkedip.ServerName, checkedip.CountryName, checkedip.Bandwidth))
	checkErr(fmt.Sprintf("append ip to file %s error: ", filename), err, Error)
	f.Close()
}

//Create files if they donnot exist, or truncate them.
func createFile() {
	if !isFileExist(tmpOkIPFileName) {
		_, err := os.Create(tmpOkIPFileName)
		checkErr(fmt.Sprintf("create file %s error: ", tmpOkIPFileName), err, Error)
	}
	if !isFileExist(tmpNoIPFileName) {
		_, err := os.Create(tmpNoIPFileName)
		checkErr(fmt.Sprintf("create file %s error: ", tmpNoIPFileName), err, Error)
	}
	if !isFileExist(tmpErrIPFileName) {
		_, err := os.Create(tmpErrIPFileName)
		checkErr(fmt.Sprintf("create file %s error: ", tmpErrIPFileName), err, Error)
	}
}

/**
writeJSONIP2File: sorting ip, ridding duplicate ip, generating json ip and
bar-separated ip
*/
func writeJSONIP2File() (gws, gvs int, gpips string) {
	okIPs := getLastOkIP()
	if config.SortOkIP {
		sort.Sort(ByDelay{IPs(okIPs)})
	}
	err := os.Truncate(tmpOkIPFileName, 0)
	checkErr(fmt.Sprintf("truncate file %s error: ", tmpOkIPFileName), err, Error)
	var gaipbuf, gpipbuf bytes.Buffer
	for _, ip := range okIPs {
		if ip.ServerName == "gws" {
			gws++
		}
		if ip.ServerName == "gvs" {
			gvs++
		}
		appendIP2File(ip, tmpOkIPFileName)

		if ip.Delay <= config.Delay {
			gaipbuf.WriteString(ip.Address)
			gaipbuf.WriteString("|")
			gpipbuf.WriteString("\"")
			gpipbuf.WriteString(ip.Address)
			gpipbuf.WriteString("\",")
		}
	}
	gaips := gaipbuf.String()
	gpips = gpipbuf.String()

	if len(gaips) > 0 {
		gaips = gaips[:len(gaips)-1]
	}
	if len(gpips) > 0 {
		gpips = gpips[:len(gpips)-1]
	}
	err = ioutil.WriteFile(jsonIPFileName, []byte(gaips+"\n"+gpips), 0755)
	checkErr(fmt.Sprintf("write ip to file %s error: ", jsonIPFileName), err, Error)

	return gws, gvs, gpips
}

//writeIP2Goproxy: write json ip to gae.user.json or gae.json
func writeIP2Goproxy(file, jsonips string) {
	data, err := ioutil.ReadFile(file)
	checkErr(fmt.Sprintf("read file %s error: ", file), err, Error)
	content := string(data)
	if n := strings.Index(content, "HostMap"); n > -1 {
		tmp := content[n:]
		tmp = tmp[strings.Index(tmp, "[")+1 : strings.Index(tmp, "]")]
		content = strings.Replace(content, tmp, "\r\n\t\t\t"+jsonips+"\r\n\t\t\t", -1)
		err := ioutil.WriteFile(file, []byte(content), 0777)
		checkErr(fmt.Sprintf("write ip to file %s error: ", file), err, Error)
		fmt.Println("write ip to .json file successfully.")
	}
}
func checkBandwidth(ip IP, done chan bool) {
	defer func() {
		<-done
	}()
	ip.Bandwidth = -1
	if ip.ServerName == "gvs" {
		appendIP2File(ip, tmpOkIPFileName)
		checkErr(fmt.Sprintf("%s %s %s NaN", ip.Address, ip.CommonName, ip.ServerName), errors.New("gvs skipped"), Info)
		return
	}
	conn, err := dialer.Dial("tcp", net.JoinHostPort(ip.Address, "443"))
	if err != nil {
		appendIP2File(ip, tmpOkIPFileName)
		checkErr(fmt.Sprintf("%s dial error: ", ip.Address), err, Info)
		return
	}
	defer conn.Close()

	tlsClient := tls.Client(conn, tlsConfig)
	tlsClient.SetDeadline(time.Now().Add(time.Minute * 5))
	_, err = tlsClient.Write([]byte("GET /storage/v1/b/google-code-archive/o/v2%2Fcode.google.com%2Fgogo-tester%2Fwiki%2F1m.wiki?alt=media HTTP/1.1\r\nHost: www.googleapis.com\r\nConnection: close\r\n\r\n"))
	if err != nil {
		appendIP2File(ip, tmpOkIPFileName)
		checkErr(fmt.Sprintf("%s tls write data error: ", ip.Address), err, Info)
		return
	}
	defer tlsClient.Close()

	buf := make([]byte, 0, 4096)
	tmp := make([]byte, 1024)
	t0 := time.Now()
	for {
		n, err := tlsClient.Read(tmp)
		if err != nil {
			if err != io.EOF {
				fmt.Println("read error:", err)
			}
			break
		}
		buf = append(buf, tmp[:n]...)
	}
	t1 := time.Now()

	ip.Bandwidth = int(float64(len(buf)) / 1024 / t1.Sub(t0).Seconds())
	appendIP2File(ip, tmpOkIPFileName)
	checkErr(fmt.Sprintf("%s %s %s %dKB/s", ip.Address, ip.CommonName, ip.ServerName, ip.Bandwidth), errors.New(""), Info)
}
<commit_msg>sleep 5 second<commit_after>package main

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"time"
)

//Config Get config info from extra config.json file.
type Config struct {
	Concurrency          int      `json:"concurrency"`
	Timeout              int      `json:"timeout"`
	HandshakeTimeout     int      `json:"handshake_timeout"`
	Delay                int      `json:"delay"`
	OrgNames             []string `json:"organization"`
	GwsDomains           []string `json:"gws"`
	GvsDomains           []string `json:"gvs"`
	SortOkIP             bool     `json:"sort_tmpokfile"`
	CheckLastOkIP        bool     `json:"check_last_okip"`
	CheckBandwidth       bool     `json:"check_bandwidth"`
	SortBandwidth        bool     `json:"sort_bandwidth"`
	BandwidthConcurrency int      `json:"bandwidth_concurrency"`
	BandwidthTimeout     int      `json:"bandwidth_timeout"`
	Write2Goproxy        bool     `json:"write_to_goproxy"`
	GoproxyPath          string   `json:"goproxy_path"`
}

const (
	configFileName   string = "config.json"
	certFileName     string = "cacert.pem"
	googleIPFileName string = "googleip.txt"
	tmpOkIPFileName  string = "ip_tmpok.txt"
	tmpErrIPFileName string = "ip_tmperr.txt"
	tmpNoIPFileName  string = "ip_tmpno.txt"
	jsonIPFileName   string = "ip.txt"
)

var config Config
var curDir string
var separator string
var certPool *x509.CertPool
var tlsConfig *tls.Config
var dialer net.Dialer

func init() {
	fmt.Println("initial...")
	parseConfig()
	loadCertPem()
	createFile()
	tlsConfig = &tls.Config{
		RootCAs:            certPool,
		InsecureSkipVerify: true,
	}
}

func main() {

	flag.Set("logtostderr", "true")
	flag.Parse()

	var lastOkIPs []string
	if config.CheckLastOkIP {
		tmpLastOkIPs := getLastOkIP()
		for _, ip := range tmpLastOkIPs {
			lastOkIPs = append(lastOkIPs, ip.Address)
		}
	}

	ips := append(lastOkIPs, getGoogleIP()...)

	fmt.Printf("load last checked ip ok, count: %d,\nload extra ip ok, line: %d, count: %d\n\n", len(lastOkIPs), len(getGoogleIPRange()), len(ips))
	time.Sleep(5 * time.Second)

	jobs := make(chan string, config.Concurrency)
	done := make(chan bool, config.Concurrency)

	//check all goole ip begin
	t0 := time.Now()
	go func() {
		for _, ip := range ips {
			jobs <- ip
		}
		close(jobs)
	}()
	for ip := range jobs {
		done <- true
		go checkIP(ip, done)
	}
	for i := 0; i < cap(done); i++ {
		done <- true
	}
	//check all goole ip end

	if config.CheckBandwidth {

		jobs := make(chan IP, config.BandwidthConcurrency)
		done := make(chan bool, config.BandwidthConcurrency)

		ips := getLastOkIP()
		_, err := os.Create(tmpOkIPFileName)
		checkErr(fmt.Sprintf("create file %s error: ", tmpOkIPFileName), err, Error)
		// t2 := time.Now()
		go func() {
			for _, ip := range ips {
				jobs <- ip
			}
			close(jobs)
		}()
		for ip := range jobs {
			done <- true
			go checkBandwidth(ip, done)
		}
		for i := 0; i < cap(done); i++ {
			done <- true
		}
		// t3 := time.Now()
		// cost := int(t3.Sub(t2).Seconds())
	}
	gws, gvs, gpips := writeJSONIP2File()
	t1 := time.Now()
	cost := int(t1.Sub(t0).Seconds())
	fmt.Printf("\ntime: %ds, ok ip count: %d(gws: %d, gvs: %d)\n\n", cost, gws+gvs, gws, gvs)
	if config.Write2Goproxy {
		file := filepath.Join(config.GoproxyPath, "gae.user.json")
		if isFileExist(file) {
			writeIP2Goproxy(file, gpips)
		} else if isFileExist(filepath.Join(config.GoproxyPath, "gae.user.json")) {
			writeIP2Goproxy(file, gpips)
		} else {
			fmt.Println("directory: ", config.GoproxyPath, " not found.")
		}
	}
	fmt.Println("\npress 'Enter' to continue...")
	fmt.Scanln()
}

//Parse config file
func parseConfig() {
	conf, err := ioutil.ReadFile(configFileName)
	checkErr("read config file error: ", err, Error)
	err = json.Unmarshal(conf, &config)
	checkErr("parse config file error: ", err, Error)
}

//Load cacert.pem
func loadCertPem() {
	certpem, err := ioutil.ReadFile(certFileName)
	checkErr(fmt.Sprintf("read pem file %s error: ", certFileName), err, Error)
	certPool = x509.NewCertPool()
	if !certPool.AppendCertsFromPEM(certpem) {
		checkErr(fmt.Sprintf("load pem file %s error: ", certFileName), errors.New("load pem file error"), Error)
	}
}

func checkIP(ip string, done chan bool) {
	defer func() {
		<-done
	}()
	var checkedip IP
	checkedip.Address = ip
	checkedip.Bandwidth = -1
	checkedip.CountryName = "-"
	dialer = net.Dialer{
		Timeout:   time.Millisecond * time.Duration(config.Timeout),
		KeepAlive: 0,
		DualStack: false,
	}

	conn, err := dialer.Dial("tcp", net.JoinHostPort(ip, "443"))
	if err != nil {
		checkErr(fmt.Sprintf("%s dial error: ", ip), err, Debug)
		appendIP2File(checkedip, tmpErrIPFileName)
		return
	}
	defer conn.Close()

	t0 := time.Now()
	tlsClient := tls.Client(conn, tlsConfig)
	tlsClient.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(config.HandshakeTimeout)))
	err = tlsClient.Handshake()

	if err != nil {
		checkErr(fmt.Sprintf("%s handshake error: ", ip), err, Debug)
		appendIP2File(checkedip, tmpErrIPFileName)
		return
	}
	defer tlsClient.Close()
	t1 := time.Now()

	if tlsClient.ConnectionState().PeerCertificates == nil {
		checkErr(fmt.Sprintf("%s peer certificates error: ", ip), errors.New("peer certificates is nil"), Debug)
		appendIP2File(checkedip, tmpNoIPFileName)
		return
	}

	checkedip.Delay = int(t1.Sub(t0).Seconds() * 1000)

	peerCertSubject := tlsClient.ConnectionState().PeerCertificates[0].Subject
	checkedip.CommonName = peerCertSubject.CommonName
	orgNames := peerCertSubject.Organization
	if len(peerCertSubject.Organization) > 0 {
		checkedip.OrgName = orgNames[0]
	}
	countryNames := peerCertSubject.Country
	if len(countryNames) > 0 {
		checkedip.CountryName = countryNames[0]
	}

	for _, org := range config.OrgNames {
		if org == checkedip.OrgName {
			var flag0, flag1 bool
			for _, gws := range config.GwsDomains {
				if gws == checkedip.CommonName {
					checkedip.ServerName = "gws"
					appendIP2File(checkedip, tmpOkIPFileName)
					flag0 = true
					break
				}
			}
			if !flag0 {
				for _, gvs := range config.GvsDomains {
					if gvs == checkedip.CommonName {
						checkedip.ServerName = "gvs"
						appendIP2File(checkedip, tmpOkIPFileName)
						flag1 = true
						break
					}
				}
			}
			if !flag0 && !flag1 {
				appendIP2File(checkedip, tmpNoIPFileName)
			}
		} else {
			appendIP2File(checkedip, tmpNoIPFileName)
		}
	}
	checkErr(fmt.Sprintf("%s: %s %s %s %dms", checkedip.Address, checkedip.CommonName, checkedip.ServerName, checkedip.CountryName,
		checkedip.Delay), errors.New(""), Info)
}

//append ip to related file
func appendIP2File(checkedip IP, filename string) {
	f, err := os.OpenFile(filename, os.O_APPEND, os.ModeAppend)
	checkErr(fmt.Sprintf("open file %s error: ", filename), err, Error)
	defer f.Close()

	_, err = f.WriteString(fmt.Sprintf("%s %dms %s %s %s %dKB/s\n", checkedip.Address, checkedip.Delay, checkedip.CommonName, checkedip.ServerName, checkedip.CountryName, checkedip.Bandwidth))
	checkErr(fmt.Sprintf("append ip to file %s error: ", filename), err, Error)
	f.Close()
}

//Create files if they donnot exist, or truncate them.
func createFile() {
	if !isFileExist(tmpOkIPFileName) {
		_, err := os.Create(tmpOkIPFileName)
		checkErr(fmt.Sprintf("create file %s error: ", tmpOkIPFileName), err, Error)
	}
	if !isFileExist(tmpNoIPFileName) {
		_, err := os.Create(tmpNoIPFileName)
		checkErr(fmt.Sprintf("create file %s error: ", tmpNoIPFileName), err, Error)
	}
	if !isFileExist(tmpErrIPFileName) {
		_, err := os.Create(tmpErrIPFileName)
		checkErr(fmt.Sprintf("create file %s error: ", tmpErrIPFileName), err, Error)
	}
}

/**
writeJSONIP2File: sorting ip, ridding duplicate ip, generating json ip and
bar-separated ip
*/
func writeJSONIP2File() (gws, gvs int, gpips string) {
	okIPs := getLastOkIP()
	if config.SortOkIP {
		sort.Sort(ByDelay{IPs(okIPs)})
	}
	err := os.Truncate(tmpOkIPFileName, 0)
	checkErr(fmt.Sprintf("truncate file %s error: ", tmpOkIPFileName), err, Error)
	var gaipbuf, gpipbuf bytes.Buffer
	for _, ip := range okIPs {
		if ip.ServerName == "gws" {
			gws++
		}
		if ip.ServerName == "gvs" {
			gvs++
		}
		appendIP2File(ip, tmpOkIPFileName)

		if ip.Delay <= config.Delay {
			gaipbuf.WriteString(ip.Address)
			gaipbuf.WriteString("|")
			gpipbuf.WriteString("\"")
			gpipbuf.WriteString(ip.Address)
			gpipbuf.WriteString("\",")
		}
	}
	gaips := gaipbuf.String()
	gpips = gpipbuf.String()

	if len(gaips) > 0 {
		gaips = gaips[:len(gaips)-1]
	}
	if len(gpips) > 0 {
		gpips = gpips[:len(gpips)-1]
	}
	err = ioutil.WriteFile(jsonIPFileName, []byte(gaips+"\n"+gpips), 0755)
	checkErr(fmt.Sprintf("write ip to file %s error: ", jsonIPFileName), err, Error)

	return gws, gvs, gpips
}

//writeIP2Goproxy: write json ip to gae.user.json or gae.json
func writeIP2Goproxy(file, jsonips string) {
	data, err := ioutil.ReadFile(file)
	checkErr(fmt.Sprintf("read file %s error: ", file), err, Error)
	content := string(data)
	if n := strings.Index(content, "HostMap"); n > -1 {
		tmp := content[n:]
		tmp = tmp[strings.Index(tmp, "[")+1 : strings.Index(tmp, "]")]
		content = strings.Replace(content, tmp, "\r\n\t\t\t"+jsonips+"\r\n\t\t\t", -1)
		err := ioutil.WriteFile(file, []byte(content), 0777)
		checkErr(fmt.Sprintf("write ip to file %s error: ", file), err, Error)
		fmt.Println("write ip to .json file successfully.")
	}
}
func checkBandwidth(ip IP, done chan bool) {
	defer func() {
		<-done
	}()
	ip.Bandwidth = -1
	if ip.ServerName == "gvs" {
		appendIP2File(ip, tmpOkIPFileName)
		checkErr(fmt.Sprintf("%s %s %s NaN", ip.Address, ip.CommonName, ip.ServerName), errors.New("gvs skipped"), Info)
		return
	}
	conn, err := dialer.Dial("tcp", net.JoinHostPort(ip.Address, "443"))
	if err != nil {
		appendIP2File(ip, tmpOkIPFileName)
		checkErr(fmt.Sprintf("%s dial error: ", ip.Address), err, Info)
		return
	}
	defer conn.Close()

	tlsClient := tls.Client(conn, tlsConfig)
	tlsClient.SetDeadline(time.Now().Add(time.Minute * 5))
	_, err = tlsClient.Write([]byte("GET /storage/v1/b/google-code-archive/o/v2%2Fcode.google.com%2Fgogo-tester%2Fwiki%2F1m.wiki?alt=media HTTP/1.1\r\nHost: www.googleapis.com\r\nConnection: close\r\n\r\n"))
	if err != nil {
		appendIP2File(ip, tmpOkIPFileName)
		checkErr(fmt.Sprintf("%s tls write data error: ", ip.Address), err, Info)
		return
	}
	defer tlsClient.Close()

	buf := make([]byte, 0, 4096)
	tmp := make([]byte, 1024)
	t0 := time.Now()
	for {
		n, err := tlsClient.Read(tmp)
		if err != nil {
			if err != io.EOF {
				fmt.Println("read error:", err)
			}
			break
		}
		buf = append(buf, tmp[:n]...)
	}
	t1 := time.Now()

	ip.Bandwidth = int(float64(len(buf)) / 1024 / t1.Sub(t0).Seconds())
	appendIP2File(ip, tmpOkIPFileName)
	checkErr(fmt.Sprintf("%s %s %s %dKB/s", ip.Address, ip.CommonName, ip.ServerName, ip.Bandwidth), errors.New(""), Info)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/elwinar/rambler/log"
	"github.com/urfave/cli"
)

var service *Service
var logger *log.Logger

// VERSION holds the version of rambler as defined at compile time.
var VERSION string

func main() {
	var app = cli.NewApp()

	app.Name = "rambler"
	app.Usage = "Migrate all the things!"
	app.Version = VERSION
	app.Authors = []cli.Author{
		{
			Name:  "Romain Baugue",
			Email: "romain.baugue@elwinar.com",
		},
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "configuration, c",
			Usage: "path to the configuration file",
		},
		cli.StringFlag{
			Name:  "environment, e",
			Value: "default",
			Usage: "set the working environment",
		},
		cli.BoolFlag{
			Name:  "debug",
			Usage: "display debug messages",
		},
	}

	app.Before = Bootstrap

	app.Commands = []cli.Command{
		{
			Name:  "apply",
			Usage: "apply the next migration",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "all, a",
					Usage: "Apply all migrations",
				},
			},
			Action: Apply,
		},
		{
			Name:  "reverse",
			Usage: "reverse the last migration",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "all, a",
					Usage: "Reverse all migrations",
				},
			},
			Action: Reverse,
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
<commit_msg>Set the missing default value for configuration<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/elwinar/rambler/log"
	"github.com/urfave/cli"
)

var service *Service
var logger *log.Logger

// VERSION holds the version of rambler as defined at compile time.
var VERSION string

func main() {
	var app = cli.NewApp()

	app.Name = "rambler"
	app.Usage = "Migrate all the things!"
	app.Version = VERSION
	app.Authors = []cli.Author{
		{
			Name:  "Romain Baugue",
			Email: "romain.baugue@elwinar.com",
		},
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "configuration, c",
			Value: "rambler.json",
			Usage: "path to the configuration file",
		},
		cli.StringFlag{
			Name:  "environment, e",
			Value: "default",
			Usage: "set the working environment",
		},
		cli.BoolFlag{
			Name:  "debug",
			Usage: "display debug messages",
		},
	}

	app.Before = Bootstrap

	app.Commands = []cli.Command{
		{
			Name:  "apply",
			Usage: "apply the next migration",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "all, a",
					Usage: "Apply all migrations",
				},
			},
			Action: Apply,
		},
		{
			Name:  "reverse",
			Usage: "reverse the last migration",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "all, a",
					Usage: "Reverse all migrations",
				},
			},
			Action: Reverse,
		},
	}

	err := app.Run(os.Args)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"time"

	"github.com/prometheus/client_golang/prometheus"
)

func main() {
	fs := flag.NewFlagSet("mesos-exporter", flag.ExitOnError)
	addr := fs.String("addr", ":9110", "Address to listen on")
	name := fs.String("name", "master.mesos.", "Master leader DNS name")
	timeout := fs.Duration("timeout", 5*time.Second, "Master polling timeout")

	fs.Parse(os.Args[1:])

	c := newCollector(*name, *timeout)
	if err := prometheus.Register(c); err != nil {
		log.Fatal(err)
	}

	http.Handle("/metrics", prometheus.Handler())
	if err := http.ListenAndServe(*addr, nil); err != nil {
		log.Fatal(err)
	}
}

type collector struct {
	*http.Client
	name    string
	metrics map[*prometheus.GaugeVec]func(*slave, prometheus.Gauge)
}

func newCollector(name string, timeout time.Duration) *collector {
	labels := []string{"slave"}
	return &collector{
		Client: &http.Client{Timeout: timeout},
		name:   name,
		metrics: map[*prometheus.GaugeVec]func(*slave, prometheus.Gauge){
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Total slave CPUs (fractional)",
				Name:      "cpus",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Total.CPUs) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Used slave CPUs (fractional)",
				Name:      "cpus_used",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Used.CPUs) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Unreserved slave CPUs (fractional)",
				Name:      "cpus_unreserved",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Unreserved.CPUs) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Total slave memory in MB",
				Name:      "mem",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Total.Mem) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Used slave memory in MB",
				Name:      "mem_used",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Used.Mem) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Unreserved slave memory in MB",
				Name:      "mem_unreserved",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Unreserved.Mem) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Total slave disk in MB",
				Name:      "disk",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Total.Disk) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Used slave disk in MB",
				Name:      "disk_used",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Used.Disk) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Unreserved slave disk in MB",
				Name:      "disk_unreserved",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Unreserved.Disk) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Total slave ports",
				Name:      "ports",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(float64(s.Total.Ports.size())) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Used slave ports",
				Name:      "ports_used",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(float64(s.Used.Ports.size())) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Unreserved slave ports",
				Name:      "ports_unreserved",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(float64(s.Unreserved.Ports.size())) },
		},
	}
}

func (c *collector) Collect(ch chan<- prometheus.Metric) {
	masters, err := net.LookupHost(c.name)
	if err != nil || len(masters) == 0 {
		log.Printf("failed to DNS lookup %s: %s", c.name, err)
		return
	}

	req := &http.Request{
		Method: "GET",
		URL:    &url.URL{Scheme: "http", Host: masters[0], Path: "/state.json"},
	}

	res, err := c.Do(req)
	if err != nil {
		log.Print(err)
		return
	}
	defer res.Body.Close()

	var s state
	if err := json.NewDecoder(res.Body).Decode(&s); err != nil {
		log.Print(err)
		return
	}

	for _, slave := range s.Slaves {
		for metric, set := range c.metrics {
			m := metric.WithLabelValues(slave.PID)
			set(&slave, m)
			ch <- m
		}
	}
}

func (c *collector) Describe(ch chan<- *prometheus.Desc) {
	for metric := range c.metrics {
		metric.Describe(ch)
	}
}

type ranges [][2]uint64

func (rs ranges) UnmarshalJSON(data []byte) error {
	if len(data) <= 2 {
		return nil
	} else if data[0] != '[' || data[len(data)-1] != ']' {
		return fmt.Errorf("failed to parse port range %q", data)
	}

	var rng [2]uint64
	for _, r := range bytes.Split(data[1:len(data)-1], []byte(",")) {
		if err := json.Unmarshal(r, &rng); err != nil {
			return err
		}
		rs = append(rs, rng)
	}

	return nil
}

func (rs ranges) size() uint64 {
	var sz uint64
	for i := range rs {
		sz += 1 + (rs[i][1] - rs[i][0])
	}
	return sz
}

type resources struct {
	CPUs  float64 `json:"cpus"`
	Disk  float64 `json:"disk"`
	Mem   float64 `json:"mem"`
	Ports ranges  `json:"ports"`
}

type slave struct {
	PID        string    `json:"pid"`
	Used       resources `json:"user_resources"`
	Unreserved resources `json:"unreserved_resources"`
	Total      resources `json:"resources"`
}

type state struct {
	Slaves []slave `json:"slaves"`
}
<commit_msg>Parameterize Master port<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"time"

	"github.com/prometheus/client_golang/prometheus"
)

func main() {
	fs := flag.NewFlagSet("mesos-exporter", flag.ExitOnError)
	addr := fs.String("addr", ":9110", "Address to listen on")
	port := fs.Int("port", 5050, "Master port")
	name := fs.String("name", "master.mesos.", "Master leader DNS name")
	timeout := fs.Duration("timeout", 5*time.Second, "Master polling timeout")

	fs.Parse(os.Args[1:])

	c := newCollector(*name, *port, *timeout)
	if err := prometheus.Register(c); err != nil {
		log.Fatal(err)
	}

	http.Handle("/metrics", prometheus.Handler())
	if err := http.ListenAndServe(*addr, nil); err != nil {
		log.Fatal(err)
	}
}

type collector struct {
	*http.Client
	name    string
	port    int
	metrics map[*prometheus.GaugeVec]func(*slave, prometheus.Gauge)
}

func newCollector(name string, port int, timeout time.Duration) *collector {
	labels := []string{"slave"}
	return &collector{
		Client: &http.Client{Timeout: timeout},
		name:   name,
		port:   port,
		metrics: map[*prometheus.GaugeVec]func(*slave, prometheus.Gauge){
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Total slave CPUs (fractional)",
				Name:      "cpus",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Total.CPUs) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Used slave CPUs (fractional)",
				Name:      "cpus_used",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Used.CPUs) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Unreserved slave CPUs (fractional)",
				Name:      "cpus_unreserved",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Unreserved.CPUs) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Total slave memory in MB",
				Name:      "mem",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Total.Mem) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Used slave memory in MB",
				Name:      "mem_used",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Used.Mem) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Unreserved slave memory in MB",
				Name:      "mem_unreserved",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Unreserved.Mem) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Total slave disk in MB",
				Name:      "disk",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Total.Disk) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Used slave disk in MB",
				Name:      "disk_used",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Used.Disk) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Unreserved slave disk in MB",
				Name:      "disk_unreserved",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(s.Unreserved.Disk) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Total slave ports",
				Name:      "ports",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(float64(s.Total.Ports.size())) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Used slave ports",
				Name:      "ports_used",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(float64(s.Used.Ports.size())) },
			prometheus.NewGaugeVec(prometheus.GaugeOpts{
				Help:      "Unreserved slave ports",
				Name:      "ports_unreserved",
				Namespace: "mesos",
				Subsystem: "slave",
			}, labels): func(s *slave, g prometheus.Gauge) { g.Set(float64(s.Unreserved.Ports.size())) },
		},
	}
}

func (c *collector) Collect(ch chan<- prometheus.Metric) {
	masters, err := net.LookupHost(c.name)
	if err != nil || len(masters) == 0 {
		log.Printf("failed to DNS lookup %s: %s", c.name, err)
		return
	}

	req := &http.Request{
		Method: "GET",
		URL: &url.URL{
			Scheme: "http",
			Host:   net.JoinHostPort(masters[0], strconv.Itoa(c.port)),
			Path:   "/state.json",
		},
	}

	res, err := c.Do(req)
	if err != nil {
		log.Print(err)
		return
	}
	defer res.Body.Close()

	var s state
	if err := json.NewDecoder(res.Body).Decode(&s); err != nil {
		log.Print(err)
		return
	}

	for _, slave := range s.Slaves {
		for metric, set := range c.metrics {
			m := metric.WithLabelValues(slave.PID)
			set(&slave, m)
			ch <- m
		}
	}
}

func (c *collector) Describe(ch chan<- *prometheus.Desc) {
	for metric := range c.metrics {
		metric.Describe(ch)
	}
}

type ranges [][2]uint64

func (rs ranges) UnmarshalJSON(data []byte) error {
	if len(data) <= 2 {
		return nil
	} else if data[0] != '[' || data[len(data)-1] != ']' {
		return fmt.Errorf("failed to parse port range %q", data)
	}

	var rng [2]uint64
	for _, r := range bytes.Split(data[1:len(data)-1], []byte(",")) {
		if err := json.Unmarshal(r, &rng); err != nil {
			return err
		}
		rs = append(rs, rng)
	}

	return nil
}

func (rs ranges) size() uint64 {
	var sz uint64
	for i := range rs {
		sz += 1 + (rs[i][1] - rs[i][0])
	}
	return sz
}

type resources struct {
	CPUs  float64 `json:"cpus"`
	Disk  float64 `json:"disk"`
	Mem   float64 `json:"mem"`
	Ports ranges  `json:"ports"`
}

type slave struct {
	PID        string    `json:"pid"`
	Used       resources `json:"user_resources"`
	Unreserved resources `json:"unreserved_resources"`
	Total      resources `json:"resources"`
}

type state struct {
	Slaves []slave `json:"slaves"`
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
	"os"
	"strings"
)

type source struct {
	myToken *oauth2.Token
}

func (t source) Token() (*oauth2.Token, error) {
	return t.myToken, nil
}

func main() {
	if len(os.Args) != 2 {
		fmt.Printf("missing github access token as avg 1\n")
		return
	}

	var NoContext oauth2.Context = nil
	src := source{
		myToken: &oauth2.Token{AccessToken: os.Args[1]},
	}

	client := oauth2.NewClient(NoContext, src)
	ghClient := github.NewClient(client)
	owner := "docker-library"
	repository := "official-images"

	err := labelPullsInRepo(ghClient, owner, repository, "all", "library/")
	if err != nil {
		fmt.Printf("%v", err)
		return
	}

	return
}

func labelPullsInRepo(ghClient *github.Client, owner string, repository string, state string, filePrefix string) error {
	options := &github.PullRequestListOptions{
		State: state,
	}

	pulls, _, err := ghClient.PullRequests.List(owner, repository, options)
	if err != nil {
		return err
	}

	for _, pr := range pulls {
		commitFiles, _, err := ghClient.PullRequests.ListFiles(owner, repository, *pr.Number, nil)
		if err != nil {
			fmt.Printf("%v", err)
			continue
		}

		labels := []string{}
		for _, commitFile := range commitFiles {
			if strings.HasPrefix(*commitFile.Filename, filePrefix) {
				labels = append(labels, *commitFile.Filename)
			}
		}
		fmt.Printf("%d: %v\n", *pr.Number, labels)

		// add labels
		labelObjs, _, err := ghClient.Issues.AddLabelsToIssue(owner, repository, *pr.Number, labels)
		if err != nil {
			fmt.Printf("%v", err)
			continue
		}
		fmt.Printf("%v\n", labelObjs)
	}

	return nil
}
<commit_msg>Loop over pages<commit_after>package main

import (
	"fmt"
	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
	"os"
	"strings"
)

type source struct {
	myToken *oauth2.Token
}

func (t source) Token() (*oauth2.Token, error) {
	return t.myToken, nil
}

func main() {
	if len(os.Args) != 2 {
		fmt.Printf("missing github access token as avg 1\n")
		return
	}

	var NoContext oauth2.Context = nil
	src := source{
		myToken: &oauth2.Token{AccessToken: os.Args[1]},
	}

	client := oauth2.NewClient(NoContext, src)
	ghClient := github.NewClient(client)
	owner := "docker-library"
	repository := "official-images"

	err := labelPullsInRepo(ghClient, owner, repository, "all", "library/")
	if err != nil {
		fmt.Printf("%v", err)
		return
	}

	return
}

func labelPullsInRepo(ghClient *github.Client, owner string, repository string, state string, filePrefix string) error {
	options := &github.PullRequestListOptions{
		State: state,
		ListOptions: github.ListOptions{
			PerPage: 100,
		},
	}

	for {
		pulls, resp, err := ghClient.PullRequests.List(owner, repository, options)
		if err != nil {
			return err
		}

		for _, pr := range pulls {
			commitFiles, _, err := ghClient.PullRequests.ListFiles(owner, repository, *pr.Number, nil)
			if err != nil {
				fmt.Printf("%v", err)
				continue
			}

			labels := []string{}
			for _, commitFile := range commitFiles {
				if strings.HasPrefix(*commitFile.Filename, filePrefix) {
					labels = append(labels, *commitFile.Filename)
				}
			}
			fmt.Printf("%d: %v\n", *pr.Number, labels)

			// add labels
			labelObjs, _, err := ghClient.Issues.AddLabelsToIssue(owner, repository, *pr.Number, labels)
			if err != nil {
				fmt.Printf("%v", err)
				continue
			}
			fmt.Printf("%v\n", labelObjs)
		}

		if resp.NextPage == 0 {
			break
		}
		options.ListOptions.Page = resp.NextPage
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"path/filepath"
	"strings"

	"os"
	"os/signal"
	"syscall"
	"time"
)

var (
	listen   string
	quotaDir string
	users    string
	timeout  time.Duration

	startTime      = time.Now()
	lastReloadTime = time.Now()

	version     bool
	gitRevision string = "HEAD"
	buildStamp  string = "unknown"
)

func loadQuotaFiles(quotaDir string) error {
	log.Printf("Loading configuration files from [%s]\n", quotaDir)

	glob := fmt.Sprintf("%s%c%s", quotaDir, filepath.Separator, "*.xml")
	files, _ := filepath.Glob(glob)
	if len(files) == 0 {
		return fmt.Errorf("no quota XML files found in [%s] - exiting", quotaDir)
	}

	for _, file := range files {
		loadQuotaFile(file)
	}
	return nil
}

func loadQuotaFile(file string) {
	fileName := filepath.Base(file)
	quotaName := strings.TrimSuffix(fileName, filepath.Ext(fileName))
	var browsers Browsers
	err := readConfig(file, &browsers)
	if err != nil {
		log.Printf("Failed to load configuration from [%s]: %v", fileName, err)
		return
	}
	updateQuota(quotaName, browsers)
	log.Printf("Loaded configuration from [%s]:\n%v\n", file, browsers)
}

func updateQuota(quotaName string, browsers Browsers) {
	confLock.Lock()
	defer confLock.Unlock()
	quota[quotaName] = browsers
	routes = appendRoutes(routes, &browsers)
	lastReloadTime = time.Now()
}

func showVersion() {
	fmt.Printf("Git Revision: %s\n", gitRevision)
	fmt.Printf("UTC Build Time: %s\n", buildStamp)
}

func init() {
	flag.StringVar(&listen, "listen", ":4444", "host and port to listen to")
	flag.StringVar(&quotaDir, "quotaDir", "quota", "quota directory")
	flag.StringVar(&users, "users", ".htpasswd", "htpasswd auth file path")
	flag.DurationVar(&timeout, "timeout", 300*time.Second, "session creation timeout in time.Duration format, e.g. 300s or 500ms")
	flag.BoolVar(&version, "version", false, "show version and exit")
	flag.Parse()
	if version {
		showVersion()
		os.Exit(0)
	}
	log.Printf("Users file is [%s]\n", users)
	if err := loadQuotaFiles(quotaDir); err != nil {
		log.Fatalf("%v\n", err)
	}
	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGHUP)
	go func() {
		for {
			<-sig
			loadQuotaFiles(quotaDir)
		}
	}()
}

func main() {
    log.Fatal(http.ListenAndServe(listen, mux()))
}
<commit_msg>Add graceful shutdown<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"path/filepath"
	"strings"

	"context"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var (
	listen         string
	quotaDir       string
	users          string
	timeout        time.Duration
	gracefulPeriod time.Duration

	startTime      = time.Now()
	lastReloadTime = time.Now()

	version     bool
	gitRevision string = "HEAD"
	buildStamp  string = "unknown"
)

func loadQuotaFiles(quotaDir string) error {
	log.Printf("Loading configuration files from [%s]\n", quotaDir)

	glob := fmt.Sprintf("%s%c%s", quotaDir, filepath.Separator, "*.xml")
	files, _ := filepath.Glob(glob)
	if len(files) == 0 {
		return fmt.Errorf("no quota XML files found in [%s] - exiting", quotaDir)
	}

	for _, file := range files {
		loadQuotaFile(file)
	}
	return nil
}

func loadQuotaFile(file string) {
	fileName := filepath.Base(file)
	quotaName := strings.TrimSuffix(fileName, filepath.Ext(fileName))
	var browsers Browsers
	err := readConfig(file, &browsers)
	if err != nil {
		log.Printf("Failed to load configuration from [%s]: %v", fileName, err)
		return
	}
	updateQuota(quotaName, browsers)
	log.Printf("Loaded configuration from [%s]:\n%v\n", file, browsers)
}

func updateQuota(quotaName string, browsers Browsers) {
	confLock.Lock()
	defer confLock.Unlock()
	quota[quotaName] = browsers
	routes = appendRoutes(routes, &browsers)
	lastReloadTime = time.Now()
}

func showVersion() {
	fmt.Printf("Git Revision: %s\n", gitRevision)
	fmt.Printf("UTC Build Time: %s\n", buildStamp)
}

func init() {
	flag.StringVar(&listen, "listen", ":4444", "host and port to listen to")
	flag.StringVar(&quotaDir, "quotaDir", "quota", "quota directory")
	flag.StringVar(&users, "users", ".htpasswd", "htpasswd auth file path")
	flag.DurationVar(&timeout, "timeout", 300*time.Second, "session creation timeout in time.Duration format, e.g. 300s or 500ms")
	flag.DurationVar(&gracefulPeriod, "graceful-period", 300*time.Second, "graceful shutdown period in time.Duration format, e.g. 300s or 500ms")
	flag.BoolVar(&version, "version", false, "show version and exit")
	flag.Parse()
	if version {
		showVersion()
		os.Exit(0)
	}
	log.Printf("Users file is [%s]\n", users)
	if err := loadQuotaFiles(quotaDir); err != nil {
		log.Fatalf("%v\n", err)
	}
	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGHUP)
	go func() {
		for {
			<-sig
			loadQuotaFiles(quotaDir)
		}
	}()
}

func main() {
	stop := make(chan os.Signal)
	signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)

	server := &http.Server{
		Addr:    listen,
		Handler: mux(),
	}
	go server.ListenAndServe()

	<-stop

	ctx, cancel := context.WithTimeout(context.Background(), gracefulPeriod)
	defer cancel()
	if err := server.Shutdown(ctx); err != nil {
		log.Fatalf("graceful shutdown: %v\n", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"math/rand"
	"net"
	"os"
	"regexp"
	"strings"
	"time"

	"github.com/codegangsta/cli"
	"github.com/miekg/dns"
)

const (
	Version = "0.0.4"
)

var (
	root  string
	debug bool
	fool  bool
)

func rrsearch(ns string, q string, t uint16) *dns.Msg {
	c := new(dns.Client)
	m := new(dns.Msg)
	m.SetQuestion(dns.Fqdn(q), t)

	if debug {
		log.Printf("NS %v,Question %v\n", ns, q)
	}
	r, _, err := c.Exchange(m, net.JoinHostPort(ns, "53"))
	if debug {
		log.Printf("NS %v,Response %v\n", ns, r.String())
	}
	if err != nil {
		fmt.Println(err.Error())
		panic("rrsearch Error")
	}
	return r
}

func splitRR(rr dns.RR) []string {
	if debug {
		log.Printf("RR %v\n", rr.String())
	}
	rrary := strings.SplitN(rr.String(), "\t", 5)
	return rrary
}

func setNS(rrs []string, r *dns.Msg, qns string) (string, string) {
	if debug {
		log.Printf("RRS %v,DNS Message %v Qns %v\n", rrs, r.String(), qns)
	}

	var ns string
	typ := "A"

	if strings.Contains(rrs[4], rrs[0]) || strings.Compare(qns, root) == 0 || fool {
		for _, rr := range r.Extra {
			rrss := splitRR(rr)
			if strings.Compare(rrss[3], "AAAA") == 0 {
				continue
			}
			if strings.Compare(rrss[0], rrs[4]) == 0 {
				ns = rrss[4]
				typ = rrss[3]
				break
			}
			ns = rrs[4]
		}
	} else {
		ns = rrs[4]
	}
	return ns, typ
}

func noRecRsolve(dst, ns string) string {
	rand.Seed(time.Now().UnixNano())
	for {
		r := rrsearch(ns, dst, dns.TypeA)
		if len(r.Answer) == 0 {
			rrs := splitRR(r.Ns[rand.Intn(len(r.Ns))])
			nss, typ := setNS(rrs, r, ns)
			for strings.Compare(typ, "AAAA") == 0 {
				if debug {
					log.Printf("Type %v\n", typ)
				}
				rrs := splitRR(r.Ns[rand.Intn(len(r.Ns))])
				nss, typ = setNS(rrs, r, ns)
			}
			fmt.Println(ns + "=>")
			fmt.Printf("\t%s -> %s\n",
				rrs[0],
				rrs[4],
			)
			if strings.Compare(rrs[0], ".") == 0 {
				fmt.Println("Domain Name Not found")
				os.Exit(1)
			}
			ns = nss
		} else {
			fmt.Println("Answer : " + ns + "=>")
			var ip string
			for _, ans := range r.Answer {
				anss := splitRR(ans)
				fmt.Printf("\t%s -> %s\n",
					dst,
					anss[4],
				)
				ip = anss[4]
			}
			return ip
		}
	}
}

func recRsolve(dst, ns string, n int) string {
	var tab string
	for i := 0; i < n; i++ {
		tab = tab + "\t"
	}
	rand.Seed(time.Now().UnixNano())
	for {
		checkNS, _ := regexp.MatchString("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$", ns)
		if checkNS == false {
			if debug {
				log.Printf("NS %v,Root %v\n", ns, root)
			}
			ns = recRsolve(ns, root, n+1)
			if debug {
				log.Printf("NS %v,Root %v\n", ns, root)
			}
		}
		r := rrsearch(ns, dst, dns.TypeA)
		if len(r.Answer) == 0 {
			rrs := splitRR(r.Ns[rand.Intn(len(r.Ns))])
			nss, typ := setNS(rrs, r, ns)

			for strings.Compare(typ, "AAAA") == 0 {
				rrs := splitRR(r.Ns[rand.Intn(len(r.Ns))])
				nss, typ = setNS(rrs, r, ns)
				if debug {
					log.Printf("Type %v\n", typ)
				}
			}
			fmt.Println(tab + ns + "=>")
			fmt.Printf(tab+"\t%s -> %s\n",
				rrs[0],
				rrs[4],
			)
			if strings.Compare(rrs[0], ".") == 0 {
				fmt.Printf("Domain Name Not found NameServer %v Question %v\n", ns, dst)
				os.Exit(1)
			}

			ns = nss
		} else {
			fmt.Println(tab + "Answer : " + ns + "=>")
			var ip string
			for _, ans := range r.Answer {
				anss := splitRR(ans)
				fmt.Printf(tab+"\t%s -> %s\n",
					dst,
					anss[4],
				)
				ip = anss[4]
			}
			return ip
		}
	}
}

func main() {
	app := cli.NewApp()
	app.Usage = "It is a tool to see Iterative Search of the DNS is how to."
	app.Version = Version

	app.Commands = []cli.Command{
		{
			Name:    "rec",
			Aliases: []string{"r"},
			Usage:   "Iterative Search",
			Action: func(c *cli.Context) {
				if debug {
					log.SetFlags(log.Llongfile)
				}
				recRsolve(c.Args().First(), root, 0)
			},
		},
		{
			Name:    "norec",
			Aliases: []string{"n"},
			Usage:   "No Iterative Search",
			Action: func(c *cli.Context) {
				if debug {
					log.SetFlags(log.Llongfile)
				}
				noRecRsolve(c.Args().First(), root)
			},
		},
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "root",
			Value:       "202.12.27.33",
			Usage:       "Root DNS Server's IP address",
			Destination: &root,
		},
		cli.BoolFlag{
			Name:        "debug",
			Usage:       "Debug Option for Developer",
			EnvVar:      "false",
			Destination: &debug,
		},
		cli.BoolFlag{
			Name:        "fool",
			Usage:       "Believe something like flue record",
			EnvVar:      "false",
			Destination: &fool,
		},
	}
	err := app.Run(os.Args)
	if err != nil {
		panic(err)
	}
}
<commit_msg>-foolフラフを使用した時のバグを修uu正<commit_after>package main

import (
	"fmt"
	"log"
	"math/rand"
	"net"
	"os"
	"regexp"
	"strings"
	"time"

	"github.com/codegangsta/cli"
	"github.com/miekg/dns"
)

const (
	Version = "0.0.4"
)

var (
	root  string
	debug bool
	fool  bool
)

func rrsearch(ns string, q string, t uint16) *dns.Msg {
	c := new(dns.Client)
	m := new(dns.Msg)
	m.SetQuestion(dns.Fqdn(q), t)

	if debug {
		log.Printf("NS %v,Question %v\n", ns, q)
	}
	r, _, err := c.Exchange(m, net.JoinHostPort(ns, "53"))
	if debug {
		log.Printf("NS %v,Response %v\n", ns, r.String())
	}
	if err != nil {
		fmt.Println(err.Error())
		panic("rrsearch Error")
	}
	return r
}

func splitRR(rr dns.RR) []string {
	if debug {
		log.Printf("RR %v\n", rr.String())
	}
	rrary := strings.SplitN(rr.String(), "\t", 5)
	return rrary
}

func setNS(rrs []string, r *dns.Msg, qns string) (string, string) {
	if debug {
		log.Printf("RRS %v,DNS Message %v Qns %v\n", rrs, r.String(), qns)
	}

	var ns string
	typ := "A"

	if strings.Contains(rrs[4], rrs[0]) || strings.Compare(qns, root) == 0 || fool {
		for _, rr := range r.Extra {
			rrss := splitRR(rr)
			if strings.Compare(rrss[3], "AAAA") == 0 {
				continue
			}
			if strings.Compare(rrss[0], rrs[4]) == 0 {
				ns = rrss[4]
				typ = rrss[3]
				break
			}
		}
	} else {
		ns = rrs[4]
	}

	if strings.Compare(ns, "") == 0 {
		ns = rrs[4]
	}
	return ns, typ
}

func noRecRsolve(dst, ns string) string {
	rand.Seed(time.Now().UnixNano())
	for {
		r := rrsearch(ns, dst, dns.TypeA)
		if len(r.Answer) == 0 {
			rrs := splitRR(r.Ns[rand.Intn(len(r.Ns))])
			nss, typ := setNS(rrs, r, ns)
			for strings.Compare(typ, "AAAA") == 0 {
				if debug {
					log.Printf("Type %v\n", typ)
				}
				rrs := splitRR(r.Ns[rand.Intn(len(r.Ns))])
				nss, typ = setNS(rrs, r, ns)
			}
			fmt.Println(ns + "=>")
			fmt.Printf("\t%s -> %s\n",
				rrs[0],
				rrs[4],
			)
			if strings.Compare(rrs[0], ".") == 0 {
				fmt.Println("Domain Name Not found")
				os.Exit(1)
			}
			ns = nss
		} else {
			fmt.Println("Answer : " + ns + "=>")
			var ip string
			for _, ans := range r.Answer {
				anss := splitRR(ans)
				fmt.Printf("\t%s -> %s\n",
					dst,
					anss[4],
				)
				ip = anss[4]
			}
			return ip
		}
	}
}

func recRsolve(dst, ns string, n int) string {
	var tab string
	for i := 0; i < n; i++ {
		tab = tab + "\t"
	}
	rand.Seed(time.Now().UnixNano())
	for {
		checkNS, _ := regexp.MatchString("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$", ns)
		if checkNS == false {
			if debug {
				log.Printf("NS %v,Root %v\n", ns, root)
			}
			ns = recRsolve(ns, root, n+1)
			if debug {
				log.Printf("NS %v,Root %v\n", ns, root)
			}
		}
		r := rrsearch(ns, dst, dns.TypeA)
		if len(r.Answer) == 0 {
			rrs := splitRR(r.Ns[rand.Intn(len(r.Ns))])
			nss, typ := setNS(rrs, r, ns)

			for strings.Compare(typ, "AAAA") == 0 {
				rrs := splitRR(r.Ns[rand.Intn(len(r.Ns))])
				nss, typ = setNS(rrs, r, ns)
				if debug {
					log.Printf("Type %v\n", typ)
				}
			}
			fmt.Println(tab + ns + "=>")
			fmt.Printf(tab+"\t%s -> %s\n",
				rrs[0],
				rrs[4],
			)
			if strings.Compare(rrs[0], ".") == 0 {
				fmt.Printf("Domain Name Not found NameServer %v Question %v\n", ns, dst)
				os.Exit(1)
			}

			ns = nss
		} else {
			fmt.Println(tab + "Answer : " + ns + "=>")
			var ip string
			for _, ans := range r.Answer {
				anss := splitRR(ans)
				fmt.Printf(tab+"\t%s -> %s\n",
					dst,
					anss[4],
				)
				ip = anss[4]
			}
			return ip
		}
	}
}

func main() {
	app := cli.NewApp()
	app.Usage = "It is a tool to see Iterative Search of the DNS is how to."
	app.Version = Version

	app.Commands = []cli.Command{
		{
			Name:    "rec",
			Aliases: []string{"r"},
			Usage:   "Iterative Search",
			Action: func(c *cli.Context) {
				if debug {
					log.SetFlags(log.Llongfile)
				}
				recRsolve(c.Args().First(), root, 0)
			},
		},
		{
			Name:    "norec",
			Aliases: []string{"n"},
			Usage:   "No Iterative Search",
			Action: func(c *cli.Context) {
				if debug {
					log.SetFlags(log.Llongfile)
				}
				noRecRsolve(c.Args().First(), root)
			},
		},
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "root",
			Value:       "202.12.27.33",
			Usage:       "Root DNS Server's IP address",
			Destination: &root,
		},
		cli.BoolFlag{
			Name:        "debug",
			Usage:       "Debug Option for Developer",
			EnvVar:      "false",
			Destination: &debug,
		},
		cli.BoolFlag{
			Name:        "fool",
			Usage:       "Believe something like flue record",
			EnvVar:      "false",
			Destination: &fool,
		},
	}
	err := app.Run(os.Args)
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"strings"
)

// func main() {

// 	// `os.Args` provides access to raw command-line
// 	// arguments. Note that the first value in this slice
// 	// is the path to the program, and `os.Args[1:]`
// 	// holds the arguments to the program.
// 	argsWithProg := os.Args
// 	argsWithoutProg := os.Args[1:]

// 	// You can get individual args with normal indexing.
// 	arg := os.Args[1]

// 	fmt.Println(argsWithProg)
// 	fmt.Println(argsWithoutProg)
// 	fmt.Println(arg)
// }
func check(e error) {
	if e != nil {
		panic(e)
	}
}
func createDir(path string){
	if _, err := os.Stat(path); os.IsNotExist(err) {
		os.Mkdir(path,0777)

	}
}

func writeToFile(path string,content string) {
	f,err := os.Create(path)
	check(err)
	f.WriteString(content)
	 f.Close()
}
func getStringFromBindata(path string) string  {
	data, err := Asset(path)
	check(err)
	return string(data[:])
}
func main() {
	const packageTamplateName string = "nameOfThePackage"
	const functionTemplateName string = "Function"
	path := os.Args[1]
	createDir(path)
	createDir(path + "/src")
	createDir(path+"/src/main")
	createDir(path+"/src/main/kotlin")

	kotlinFunction := getStringFromBindata("data/Function.kt")
	var functionName string = strings.Title(path) +"Handler"
	var packageName string = "main"

	kotlinFunction = strings.Replace(kotlinFunction,functionTemplateName,functionName, 1)
	kotlinFunction = strings.Replace(kotlinFunction,packageTamplateName,packageName, 1)

	functionJson := getStringFromBindata("data/function.json")
	functionJson = strings.Replace(functionJson,packageTamplateName,packageName, 2)
	functionJson = strings.Replace(functionJson,functionTemplateName,functionName, 2)

	writeToFile(path + "/build.gradle", getStringFromBindata("data/build.gradle"))
	writeToFile(path + "/src/main/kotlin/" + functionName + ".kt", kotlinFunction)
	writeToFile(path + "/function.json",functionJson)

}
<commit_msg>commets<commit_after>package main

import (
	"os"
	"strings"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}
func createDir(path string){
	if _, err := os.Stat(path); os.IsNotExist(err) {
		os.Mkdir(path,0777)

	}
}

func writeToFile(path string,content string) {
	f,err := os.Create(path)
	check(err)
	f.WriteString(content)
	 f.Close()
}
func getStringFromBindata(path string) string  {
	data, err := Asset(path)
	check(err)
	return string(data[:])
}
func main() {
	const packageTamplateName string = "nameOfThePackage"
	const functionTemplateName string = "Function"
	path := os.Args[1]
	createDir(path)
	createDir(path + "/src")
	createDir(path+"/src/main")
	createDir(path+"/src/main/kotlin")

	kotlinFunction := getStringFromBindata("data/Function.kt")
	var functionName string = strings.Title(path) +"Handler"
	var packageName string = "main"

	kotlinFunction = strings.Replace(kotlinFunction,functionTemplateName,functionName, 1)
	kotlinFunction = strings.Replace(kotlinFunction,packageTamplateName,packageName, 1)

	functionJson := getStringFromBindata("data/function.json")
	functionJson = strings.Replace(functionJson,packageTamplateName,packageName, 2)
	functionJson = strings.Replace(functionJson,functionTemplateName,functionName, 2)

	writeToFile(path + "/build.gradle", getStringFromBindata("data/build.gradle"))
	writeToFile(path + "/src/main/kotlin/" + functionName + ".kt", kotlinFunction)
	writeToFile(path + "/function.json",functionJson)

}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"github.com/gorilla/mux"
	_ "github.com/mattn/go-sqlite3"
	"html"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"time"
)

var dbHandle *sql.DB
var templates = template.Must(template.ParseFiles("index.html"))
var debugLogger *log.Logger

type Record struct {
	Records          []Records `json: "records"`
	QueryRecordCount int       `json: "queryRecordCount"`
	TotalRecordCount int       `json: "totalRecordCount"`
}

type Records struct {
	Id     string `json: "id"`
	Name   string `json: "name"`
	Hash   string `json: "hash"`
	Magnet string `json: "magnet"`
}

func getDBHandle() *sql.DB {
	db, err := sql.Open("sqlite3", "./nyaa.db")
	checkErr(err)
	return db
}

func checkErr(err error) {
	if err != nil {
		debugLogger.Println("   " + err.Error())
		os.Exit(1)
	}
}

func apiHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents LIMIT 50 offset ?", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + "&tr=udp://tracker.openbittorrent.com"
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: magnet}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 50
	b.TotalRecordCount = 1473098
	rows.Close()
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
func singleapiHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	id := vars["id"]
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents where torrent_id = ?", html.EscapeString(id))
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + "&tr=udp://tracker.openbittorrent.com"
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: magnet}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 1
	b.TotalRecordCount = 1473098
	rows.Close()
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	param1 := r.URL.Query().Get("q")
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents where torrent_name LIKE ? LIMIT 50 offset ?", "%"+html.EscapeString(param1)+"%", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + "&tr=udp://tracker.openbittorrent.com"
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: magnet}

		b.Records = append(b.Records, res)

	}
	rows.Close()

	err = templates.ExecuteTemplate(w, "index.html", &b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents LIMIT 50 offset ?", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + "&tr=udp://tracker.openbittorrent.com"
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: magnet}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 50
	b.TotalRecordCount = 1473098
	rows.Close()
	err = templates.ExecuteTemplate(w, "index.html", &b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}

func main() {

	dbHandle = getDBHandle()
	router := mux.NewRouter()

	// Routes,
	router.HandleFunc("/", rootHandler)
	router.HandleFunc("/page/{page}", rootHandler)
	router.HandleFunc("/search", searchHandler)
	router.HandleFunc("/search/{page}", searchHandler)
	router.HandleFunc("/api/{page}", apiHandler).Methods("GET")
	router.HandleFunc("/api/torrent/{id}", singleapiHandler).Methods("GET")
	// Set up server,
	srv := &http.Server{
		Handler:      router,
		Addr:         "localhost:9999",
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}

	err := srv.ListenAndServe()
	checkErr(err)
}
<commit_msg>introduce order by<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"github.com/gorilla/mux"
	_ "github.com/mattn/go-sqlite3"
	"html"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"time"
)

var dbHandle *sql.DB
var templates = template.Must(template.ParseFiles("index.html"))
var debugLogger *log.Logger

type Record struct {
	Records          []Records `json: "records"`
	QueryRecordCount int       `json: "queryRecordCount"`
	TotalRecordCount int       `json: "totalRecordCount"`
}

type Records struct {
	Id     string `json: "id"`
	Name   string `json: "name"`
	Hash   string `json: "hash"`
	Magnet string `json: "magnet"`
}

func getDBHandle() *sql.DB {
	db, err := sql.Open("sqlite3", "./nyaa.db")
	checkErr(err)
	return db
}

func checkErr(err error) {
	if err != nil {
		debugLogger.Println("   " + err.Error())
		os.Exit(1)
	}
}

func apiHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT 50 offset ?", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + "&tr=udp://tracker.openbittorrent.com"
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: magnet}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 50
	b.TotalRecordCount = 1473098
	rows.Close()
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
func singleapiHandler(w http.ResponseWriter, r *http.Request) {

	vars := mux.Vars(r)
	id := vars["id"]
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents where torrent_id = ? ORDER BY torrent_id DESC", html.EscapeString(id))
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + "&tr=udp://tracker.openbittorrent.com"
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: magnet}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 1
	b.TotalRecordCount = 1473098
	rows.Close()
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	param1 := r.URL.Query().Get("q")
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents where torrent_name LIKE ? ORDER BY torrent_id DESC LIMIT 50 offset ?", "%"+html.EscapeString(param1)+"%", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "magnet:?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + "&tr=udp://tracker.openbittorrent.com"
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: magnet}

		b.Records = append(b.Records, res)

	}
	rows.Close()

	err = templates.ExecuteTemplate(w, "index.html", &b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	b := Record{Records: []Records{}}
	rows, err := dbHandle.Query("select torrent_id, torrent_name, torrent_hash from torrents ORDER BY torrent_id DESC LIMIT 50 offset ?", 50*pagenum-1)
	for rows.Next() {
		var id, name, hash, magnet string
		rows.Scan(&id, &name, &hash)
		magnet = "?xt=urn:btih:" + hash + "&dn=" + url.QueryEscape(name) + "&tr=udp://tracker.openbittorrent.com"
		res := Records{
			Id:     id,
			Name:   name,
			Hash:   hash,
			Magnet: magnet}

		b.Records = append(b.Records, res)

	}
	b.QueryRecordCount = 50
	b.TotalRecordCount = 1473098
	rows.Close()
	err = templates.ExecuteTemplate(w, "index.html", &b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}

func main() {

	dbHandle = getDBHandle()
	router := mux.NewRouter()

	// Routes,
	router.HandleFunc("/", rootHandler)
	router.HandleFunc("/page/{page}", rootHandler)
	router.HandleFunc("/search", searchHandler)
	router.HandleFunc("/search/{page}", searchHandler)
	router.HandleFunc("/api/{page}", apiHandler).Methods("GET")
	router.HandleFunc("/api/torrent/{id}", singleapiHandler).Methods("GET")
	// Set up server,
	srv := &http.Server{
		Handler:      router,
		Addr:         "localhost:9999",
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}

	err := srv.ListenAndServe()
	checkErr(err)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
)

//MB глобальная переменная, которая содержит объект Менеджер ботов
var MB *ManagerBots
//MW глобальная переменная, которая содержит объект Менеджер веб-интерфейса
var MW *ManagerWeb

func main() {
	var err error

	MB, err = newManagerBots()
	if err != nil {
		log.Println(err)
	}

	MW, err = newManagerWeb()
	if err != nil {
		log.Println(err)
	}
	MW.Start()
	fmt.Println(MB, MW)

	var response string
	fmt.Println("Press Enter")
	_, _ = fmt.Scanln(&response)
	fmt.Println("Exit.")
}
<commit_msg>При закрытии программы закрыть базу данных.<commit_after>package main

import (
	"fmt"
	"log"
)

//MB глобальная переменная, которая содержит объект Менеджер ботов
var MB *ManagerBots
//MW глобальная переменная, которая содержит объект Менеджер веб-интерфейса
var MW *ManagerWeb

func main() {
	var err error

	MB, err = newManagerBots()
	if err != nil {
		log.Println(err)
	}
	defer MB.db.Close()

	MW, err = newManagerWeb()
	if err != nil {
		log.Println(err)
	}
	MW.Start()
	fmt.Println(MB, MW)

	var response string
	fmt.Println("Press Enter")
	_, _ = fmt.Scanln(&response)
	fmt.Println("Exit.")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strconv"
	"sync"
	"time"

	"github.com/gizak/termui"
)

const (
	calcInterval      = 2
	renderingInterval = 250 * time.Millisecond
)

var (
	mu                 sync.Mutex
	gcCounter, stwTime int
	gcPercent          *termui.Gauge
	gcRate             *termui.Par
	liveHeap, goalHeap *termui.LineChart
	wallTime, cpuTime  *termui.BarChart
)

func render() {
	ticker := time.NewTicker(renderingInterval)

	for range ticker.C {
		termui.Render(termui.Body)
	}
}

func updateSummary() {
	ticker := time.NewTicker(calcInterval * time.Second)

	for range ticker.C {
		go func() {
			mu.Lock()
			defer mu.Unlock()

			gcRate.Text = strconv.Itoa(gcCounter / calcInterval)
			gcPercent.Percent = 100 * stwTime / calcInterval / 1e6

			gcCounter = 0
			stwTime = 0
		}()
	}
}

func updateCharts(data gcInfo) {
	liveHeap.Data = append(liveHeap.Data[1:], data.size.live)
	goalHeap.Data = append(goalHeap.Data[1:], data.size.goal)

	wallTime.Data = []int{
		data.wallTime.sweepTermination,
		data.wallTime.markAndSwap,
		data.wallTime.markTermination,
	}
	cpuTime.Data = []int{
		data.cpuTime.sweepTermination,
		data.cpuTime.markAndSwap,
		data.cpuTime.markTermination,
	}

	mu.Lock()
	gcCounter++
	stwTime += data.wallTime.sweepTermination
	stwTime += data.wallTime.markTermination
	mu.Unlock()
}

func sendEvents() {
	for data := range readStdin() {
		termui.SendCustomEvt("/feed", data)
	}
}

func initWidgets() {
	gcPercent = newGauge("Percentage of Time Spent in STW GC")
	gcRate = newPar("GC Events per Second")

	liveHeap = newLineChart("Live heap size, MB")
	goalHeap = newLineChart("Goal heap size, MB")

	phases := []string{
		"STW Sweep Termination",
		"Concurrent Mark & Swap",
		"STW Mark Termination",
	}
	wallTime = newBarChart("Wall-clock time, us", phases)
	cpuTime = newBarChart("CPU time, us", phases)
}

func buildLayout() {
	initWidgets()

	termui.Body.AddRows(
		termui.NewRow(
			termui.NewCol(10, 0, gcPercent),
			termui.NewCol(2, 0, gcRate)),
		termui.NewRow(
			termui.NewCol(12, 0, liveHeap)),
		termui.NewRow(
			termui.NewCol(12, 0, goalHeap)),
		termui.NewRow(
			termui.NewCol(6, 0, wallTime),
			termui.NewCol(6, 0, cpuTime)))

	termui.Body.Align()
}

// assignHandlers breaks UI loop on any keystroke and also connects UI
// components to events from standard input.
func assignHandlers() {
	termui.Handle("/sys/kbd", func(termui.Event) {
		termui.StopLoop()
	})

	termui.Handle("/feed", func(e termui.Event) {
		if data, ok := e.Data.(gcInfo); ok {
			updateCharts(data)
		}
	})
}

// detectPipe interrupts execution if there is nothing to read from standard
// input.
func detectPipe() {
	fi, err := os.Stdin.Stat()
	if err != nil {
		panic(err)
	}
	if fi.Mode() & os.ModeCharDevice != 0 {
		fmt.Println("Data pipe is required")
		os.Exit(1)
	}
}

func main() {
	detectPipe()

	if err := termui.Init(); err != nil {
		panic(err)
	}
	defer termui.Close()

	buildLayout()
	assignHandlers()

	go render()
	go sendEvents()
	go updateSummary()

	termui.Loop()
}
<commit_msg>Calculate realtime metrics every 5 seconds<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"
	"sync"
	"time"

	"github.com/gizak/termui"
)

const (
	calcInterval      = 5
	renderingInterval = 250 * time.Millisecond
)

var (
	mu                 sync.Mutex
	gcCounter, stwTime int
	gcPercent          *termui.Gauge
	gcRate             *termui.Par
	liveHeap, goalHeap *termui.LineChart
	wallTime, cpuTime  *termui.BarChart
)

func render() {
	ticker := time.NewTicker(renderingInterval)

	for range ticker.C {
		termui.Render(termui.Body)
	}
}

func updateSummary() {
	ticker := time.NewTicker(calcInterval * time.Second)

	for range ticker.C {
		go func() {
			mu.Lock()
			defer mu.Unlock()

			gcRate.Text = strconv.Itoa(gcCounter / calcInterval)
			gcPercent.Percent = 100 * stwTime / calcInterval / 1e6

			gcCounter = 0
			stwTime = 0
		}()
	}
}

func updateCharts(data gcInfo) {
	liveHeap.Data = append(liveHeap.Data[1:], data.size.live)
	goalHeap.Data = append(goalHeap.Data[1:], data.size.goal)

	wallTime.Data = []int{
		data.wallTime.sweepTermination,
		data.wallTime.markAndSwap,
		data.wallTime.markTermination,
	}
	cpuTime.Data = []int{
		data.cpuTime.sweepTermination,
		data.cpuTime.markAndSwap,
		data.cpuTime.markTermination,
	}

	mu.Lock()
	gcCounter++
	stwTime += data.wallTime.sweepTermination
	stwTime += data.wallTime.markTermination
	mu.Unlock()
}

func sendEvents() {
	for data := range readStdin() {
		termui.SendCustomEvt("/feed", data)
	}
}

func initWidgets() {
	gcPercent = newGauge("Percentage of Time Spent in STW GC")
	gcRate = newPar("GC Events per Second")

	liveHeap = newLineChart("Live heap size, MB")
	goalHeap = newLineChart("Goal heap size, MB")

	phases := []string{
		"STW Sweep Termination",
		"Concurrent Mark & Swap",
		"STW Mark Termination",
	}
	wallTime = newBarChart("Wall-clock time, us", phases)
	cpuTime = newBarChart("CPU time, us", phases)
}

func buildLayout() {
	initWidgets()

	termui.Body.AddRows(
		termui.NewRow(
			termui.NewCol(10, 0, gcPercent),
			termui.NewCol(2, 0, gcRate)),
		termui.NewRow(
			termui.NewCol(12, 0, liveHeap)),
		termui.NewRow(
			termui.NewCol(12, 0, goalHeap)),
		termui.NewRow(
			termui.NewCol(6, 0, wallTime),
			termui.NewCol(6, 0, cpuTime)))

	termui.Body.Align()
}

// assignHandlers breaks UI loop on any keystroke and also connects UI
// components to events from standard input.
func assignHandlers() {
	termui.Handle("/sys/kbd", func(termui.Event) {
		termui.StopLoop()
	})

	termui.Handle("/feed", func(e termui.Event) {
		if data, ok := e.Data.(gcInfo); ok {
			updateCharts(data)
		}
	})
}

// detectPipe interrupts execution if there is nothing to read from standard
// input.
func detectPipe() {
	fi, err := os.Stdin.Stat()
	if err != nil {
		panic(err)
	}
	if fi.Mode() & os.ModeCharDevice != 0 {
		fmt.Println("Data pipe is required")
		os.Exit(1)
	}
}

func main() {
	detectPipe()

	if err := termui.Init(); err != nil {
		panic(err)
	}
	defer termui.Close()

	buildLayout()
	assignHandlers()

	go render()
	go sendEvents()
	go updateSummary()

	termui.Loop()
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/rand"
	"fmt"
	"io"
	"io/ioutil"

	"golang.org/x/crypto/nacl/box"

	kingpin "gopkg.in/alecthomas/kingpin.v1"
)

var (
	pubFile        string
	secFile        string
	plaintextFile  string
	ciphertextFile string
)

func readKeyFile(path string) *[32]byte {
	var ret [32]byte
	c, err := ioutil.ReadFile(path)
	kingpin.FatalIfError(err, fmt.Sprintf("Reading key file %q", path))
	if len(c) != 32 {
		kingpin.Fatalf("Invalid key file %q (wrong size)", path)
	}
	copy(ret[:], c)
	return &ret
}

func main() {
	keys := func(cmd *kingpin.CmdClause) {
		cmd.Arg("pubkey", "Public key file.").Required().StringVar(&pubFile)
		cmd.Arg("seckey", "Secret key file.").Required().StringVar(&secFile)
	}

	cmd := kingpin.Command("genkey", "Generate a key pair and write them to the given files.")
	keys(cmd)

	cmd = kingpin.Command("encrypt", "Encrypt a file FROM seckey (you) TO pubkey (peer)")
	keys(cmd)
	cmd.Arg("input-file", "The file to encrypt.").Required().ExistingFileVar(&plaintextFile)
	cmd.Arg("output-file", "Destination path for the encrypted content.").Required().StringVar(&ciphertextFile)

	cmd = kingpin.Command("decrypt", "Decrypt a file FROM pubkey (peer) TO seckey (you)")
	keys(cmd)
	cmd.Arg("input-file", "The file to decrypt.").Required().ExistingFileVar(&plaintextFile)
	cmd.Arg("output-file", "Destination path for the decrypted content.").Required().StringVar(&ciphertextFile)

	switch kingpin.Parse() {
	case "genkey":
		pub, sec, err := box.GenerateKey(rand.Reader)
		kingpin.FatalIfError(err, "Error generating keypair")
		kingpin.FatalIfError(ioutil.WriteFile(pubFile, pub[:], 0644), "Writing public key")
		kingpin.FatalIfError(ioutil.WriteFile(secFile, sec[:], 0600), "Writing secret key")

	case "encrypt":
		pub := readKeyFile(pubFile)
		sec := readKeyFile(secFile)
		plain, err := ioutil.ReadFile(plaintextFile)
		kingpin.FatalIfError(err, "Reading plaintext file")
		var nonce [24]byte
		_, err = io.ReadFull(rand.Reader, nonce[:])
		kingpin.FatalIfError(err, "Reading randomness")
		cipher := box.Seal(nonce[:], plain, &nonce, pub, sec)
		kingpin.FatalIfError(ioutil.WriteFile(ciphertextFile, cipher, 0644), "Writing ciphertext")

	case "decrypt":
		pub := readKeyFile(pubFile)
		sec := readKeyFile(secFile)
		nonceAndCipher, err := ioutil.ReadFile(ciphertextFile)
		kingpin.FatalIfError(err, "Reading ciphertext file")
		var nonce [24]byte
		copy(nonce[:], nonceAndCipher)
		plain, ok := box.Open(nil, nonceAndCipher[24:], &nonce, pub, sec)
		if !ok {
			kingpin.Fatalf("Decryption of %q failed (wrong keys?)", ciphertextFile)
		}
		kingpin.FatalIfError(ioutil.WriteFile(plaintextFile, plain, 0600), "Writing plaintext")
	}
}
<commit_msg>Defend against argument inversion on the commandline.<commit_after>package main

import (
	"crypto/rand"
	"fmt"
	"io"
	"io/ioutil"

	"golang.org/x/crypto/nacl/box"

	kingpin "gopkg.in/alecthomas/kingpin.v1"
)

var (
	pubFile        string
	secFile        string
	plaintextFile  string
	ciphertextFile string
)

type keyType byte

func (k keyType) String() string {
	switch k {
	case 'P':
		return "public"
	case 'S':
		return "secret"
	default:
		return "unknown"
	}
}

const (
	keyPub keyType = 'P'
	keySec         = 'S'
)

func readKeyFile(path string, kt keyType) *[32]byte {
	var ret [32]byte
	c, err := ioutil.ReadFile(path)
	kingpin.FatalIfError(err, fmt.Sprintf("Reading key file %q", path))
	if len(c) != 33 {
		kingpin.Fatalf("Invalid key file %q (wrong size)", path)
	}
	at := keyType(c[32])
	if at != kt {
		kingpin.Fatalf("Wrong key type in %q: wanted %q, but got %q (did you switch the public and private key files on the commandline?)", path, kt, at)
	}
	copy(ret[:], c)
	return &ret
}

func main() {
	keys := func(cmd *kingpin.CmdClause) {
		cmd.Arg("pubkey", "Public key file.").Required().StringVar(&pubFile)
		cmd.Arg("seckey", "Secret key file.").Required().StringVar(&secFile)
	}

	cmd := kingpin.Command("genkey", "Generate a key pair and write them to the given files.")
	keys(cmd)

	cmd = kingpin.Command("encrypt", "Encrypt a file FROM seckey (you) TO pubkey (peer)")
	keys(cmd)
	cmd.Arg("input-file", "The file to encrypt.").Required().ExistingFileVar(&plaintextFile)
	cmd.Arg("output-file", "Destination path for the encrypted content.").Required().StringVar(&ciphertextFile)

	cmd = kingpin.Command("decrypt", "Decrypt a file FROM pubkey (peer) TO seckey (you)")
	keys(cmd)
	cmd.Arg("input-file", "The file to decrypt.").Required().ExistingFileVar(&plaintextFile)
	cmd.Arg("output-file", "Destination path for the decrypted content.").Required().StringVar(&ciphertextFile)

	switch kingpin.Parse() {
	case "genkey":
		pub, sec, err := box.GenerateKey(rand.Reader)
		kingpin.FatalIfError(err, "Error generating keypair")
		kingpin.FatalIfError(ioutil.WriteFile(pubFile, append(pub[:], byte(keyPub)), 0644), "Writing public key")
		kingpin.FatalIfError(ioutil.WriteFile(secFile, append(sec[:], byte(keySec)), 0600), "Writing secret key")

	case "encrypt":
		pub := readKeyFile(pubFile, keyPub)
		sec := readKeyFile(secFile, keySec)
		plain, err := ioutil.ReadFile(plaintextFile)
		kingpin.FatalIfError(err, "Reading plaintext file")
		var nonce [24]byte
		_, err = io.ReadFull(rand.Reader, nonce[:])
		kingpin.FatalIfError(err, "Reading randomness")
		cipher := box.Seal(nonce[:], plain, &nonce, pub, sec)
		kingpin.FatalIfError(ioutil.WriteFile(ciphertextFile, cipher, 0644), "Writing ciphertext")

	case "decrypt":
		pub := readKeyFile(pubFile, keyPub)
		sec := readKeyFile(secFile, keySec)
		nonceAndCipher, err := ioutil.ReadFile(ciphertextFile)
		kingpin.FatalIfError(err, "Reading ciphertext file")
		var nonce [24]byte
		copy(nonce[:], nonceAndCipher)
		plain, ok := box.Open(nil, nonceAndCipher[24:], &nonce, pub, sec)
		if !ok {
			kingpin.Fatalf("Decryption of %q failed (wrong keys?)", ciphertextFile)
		}
		kingpin.FatalIfError(ioutil.WriteFile(plaintextFile, plain, 0600), "Writing plaintext")
	}
}
<|endoftext|>


<commit_before>// Package main provides ...
package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/user"
	"path"
	"runtime"
)

func fetchPages() {
	gitDir := getGitDir()
	cmd := exec.Command("git", "clone", "https://github.com/tldr-pages/tldr", gitDir)
	err := cmd.Run()
	if err != nil {
		log.Fatal("ERROR: Can't fetch tldr repository")
	}
}

func getHomeDirectory() string {
	usr, err := user.Current()
	if err != nil {
		log.Fatal("ERROR: " + err.Error())
	}
	if usr.HomeDir == "" {
		log.Fatal("ERROR: Can't load user's home folder path")
	}

	return usr.HomeDir
}

func getCacheDir() string {
	homeDir := getHomeDirectory()
	return path.Join(homeDir, ".cache", "tldr-go")
}

func getPagesDir() string {
	cacheDir := getCacheDir()
	return path.Join(cacheDir, "pages")
}

func getGitDir() string {
	cacheDir := getCacheDir()
	return path.Join(cacheDir, "tldr-git")
}

func createCacheDir() {
	cacheDir := getCacheDir()
	os.MkdirAll(cacheDir, 0755)
}

func copyPages() {
	gitDir := getGitDir()
	pagesDir := getPagesDir()
	err := os.Rename(path.Join(gitDir, "pages"), pagesDir)
	if err != nil {
		log.Fatal("ERROR: " + err.Error())
	}
}

func removeCacheDir() {
	cacheDir := getCacheDir()
	os.RemoveAll(cacheDir)
}

func setup() {
	createCacheDir()
	fetchPages()
	copyPages()
}

func update() {
	removeCacheDir()
	setup()
}

func getCurrentSystem() string {
	os := runtime.GOOS
	switch os {
	case "darwin":
		os = "osx"
	}

	return os
}

func getFoldersToSearch() []string {
	currentSystem := getCurrentSystem()
	return []string{currentSystem, "common"}
}

func main() {
	pagesDir := getPagesDir()
	if _, err := os.Stat(pagesDir); os.IsNotExist(err) {
		update()
	}

	args := os.Args[1:]
	currentSystem := getCurrentSystem()

	for index, folder := range []string{currentSystem, "common"} {
		systemDir := path.Join(pagesDir, folder)
		file := systemDir + "/" + args[0] + ".md"
		if _, err := os.Stat(file); os.IsNotExist(err) {
			if index == 2 {
				log.Fatal("ERROR: no page found for " + args[0])
			}
		}
	}

	fmt.Println("Hello world!")
}
<commit_msg>fix: correct index of condition<commit_after>// Package main provides ...
package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/user"
	"path"
	"runtime"
)

func fetchPages() {
	gitDir := getGitDir()
	cmd := exec.Command("git", "clone", "https://github.com/tldr-pages/tldr", gitDir)
	err := cmd.Run()
	if err != nil {
		log.Fatal("ERROR: Can't fetch tldr repository")
	}
}

func getHomeDirectory() string {
	usr, err := user.Current()
	if err != nil {
		log.Fatal("ERROR: " + err.Error())
	}
	if usr.HomeDir == "" {
		log.Fatal("ERROR: Can't load user's home folder path")
	}

	return usr.HomeDir
}

func getCacheDir() string {
	homeDir := getHomeDirectory()
	return path.Join(homeDir, ".cache", "tldr-go")
}

func getPagesDir() string {
	cacheDir := getCacheDir()
	return path.Join(cacheDir, "pages")
}

func getGitDir() string {
	cacheDir := getCacheDir()
	return path.Join(cacheDir, "tldr-git")
}

func createCacheDir() {
	cacheDir := getCacheDir()
	os.MkdirAll(cacheDir, 0755)
}

func copyPages() {
	gitDir := getGitDir()
	pagesDir := getPagesDir()
	err := os.Rename(path.Join(gitDir, "pages"), pagesDir)
	if err != nil {
		log.Fatal("ERROR: " + err.Error())
	}
}

func removeCacheDir() {
	cacheDir := getCacheDir()
	os.RemoveAll(cacheDir)
}

func setup() {
	createCacheDir()
	fetchPages()
	copyPages()
}

func update() {
	removeCacheDir()
	setup()
}

func getCurrentSystem() string {
	os := runtime.GOOS
	switch os {
	case "darwin":
		os = "osx"
	}

	return os
}

func getFoldersToSearch() []string {
	currentSystem := getCurrentSystem()
	return []string{currentSystem, "common"}
}

func main() {
	pagesDir := getPagesDir()
	if _, err := os.Stat(pagesDir); os.IsNotExist(err) {
		update()
	}

	args := os.Args[1:]
	currentSystem := getCurrentSystem()

	for index, folder := range []string{currentSystem, "common"} {
		systemDir := path.Join(pagesDir, folder)
		file := systemDir + "/" + args[0] + ".md"
		if _, err := os.Stat(file); os.IsNotExist(err) {
			if index == 1 {
				log.Fatal("ERROR: no page found for " + args[0])
			}
		}
	}

	fmt.Println("Hello world!")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"net/http"
	"sort"
	"sync"
	"time"
)

var (
	version   = "0.1.0"
	github    = "https://github.com/ekalinin/awsping"
	useragent = fmt.Sprintf("AwsPing/%s (+%s)", version, github)
)

var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func mkRandoString(n int) string {
	b := make([]rune, n)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

// AWSRegion description of the AWS EC2 region
type AWSRegion struct {
	Name    string
	Code    string
	Latency time.Duration
	Error   error
}

// CheckLatency fills internal field Latency
func (r *AWSRegion) CheckLatency(wg *sync.WaitGroup) {
	url := fmt.Sprintf("http://dynamodb.%s.amazonaws.com/ping?x=%s",
		r.Code, mkRandoString(13))
	client := &http.Client{}

	req, err := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", useragent)

	start := time.Now()
	resp, err := client.Do(req)
	r.Latency = time.Since(start)

	r.Error = err
	resp.Body.Close()

	wg.Done()
}

// AWSRegions slice of the AWSRegion
type AWSRegions []AWSRegion

func (rs AWSRegions) Len() int {
	return len(rs)
}

func (rs AWSRegions) Less(i, j int) bool {
	return rs[i].Latency < rs[j].Latency
}

func (rs AWSRegions) Swap(i, j int) {
	rs[i], rs[j] = rs[j], rs[i]
}

func main() {
	regions := AWSRegions{
		{Name: "US-East (Virginia)", Code: "us-east-1"},
		{Name: "US-West (California)", Code: "us-west-1"},
		{Name: "US-West (Oregon)", Code: "us-west-2"},
		{Name: "Asia Pacific (Mumbai)", Code: "ap-south-1"},
		{Name: "Asia Pacific (Seoul)", Code: "ap-northeast-2"},
		{Name: "Asia Pacific (Singapore)", Code: "ap-southeast-1"},
		{Name: "Asia Pacific (Sydney)", Code: "ap-southeast-2"},
		{Name: "Asia Pacific (Tokyo)", Code: "ap-northeast-1"},
		{Name: "Europe (Ireland)", Code: "eu-west-1"},
		{Name: "Europe (Frankfurt)", Code: "eu-central-1"},
		{Name: "South America (São Paulo)", Code: "sa-east-1"},
		//{Name: "China (Beijing)", Code: "cn-north-1"},
	}
	var wg sync.WaitGroup
	wg.Add(len(regions))

	for i := range regions {
		go regions[i].CheckLatency(&wg)
	}

	wg.Wait()

	sort.Sort(regions)

	outFmt := "|%5v|%-30s|%20s|%20v|\n"
	fmt.Printf(outFmt, "", "Region", "Latency", "Error")
	for i, r := range regions {
		ms := fmt.Sprintf("%.2f ms", float64(r.Latency.Nanoseconds())/1000/1000)
		fmt.Printf(outFmt, i, r.Name, ms, r.Error)
	}
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<commit_msg>prettified the output<commit_after>package main

import (
	"fmt"
	"math/rand"
	"net/http"
	"sort"
	"sync"
	"time"
)

var (
	version   = "0.1.0"
	github    = "https://github.com/ekalinin/awsping"
	useragent = fmt.Sprintf("AwsPing/%s (+%s)", version, github)
)

var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func mkRandoString(n int) string {
	b := make([]rune, n)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

// AWSRegion description of the AWS EC2 region
type AWSRegion struct {
	Name    string
	Code    string
	Latency time.Duration
	Error   error
}

// CheckLatency fills internal field Latency
func (r *AWSRegion) CheckLatency(wg *sync.WaitGroup) {
	url := fmt.Sprintf("http://dynamodb.%s.amazonaws.com/ping?x=%s",
		r.Code, mkRandoString(13))
	client := &http.Client{}

	req, err := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", useragent)

	start := time.Now()
	resp, err := client.Do(req)
	r.Latency = time.Since(start)

	r.Error = err
	resp.Body.Close()

	wg.Done()
}

// AWSRegions slice of the AWSRegion
type AWSRegions []AWSRegion

func (rs AWSRegions) Len() int {
	return len(rs)
}

func (rs AWSRegions) Less(i, j int) bool {
	return rs[i].Latency < rs[j].Latency
}

func (rs AWSRegions) Swap(i, j int) {
	rs[i], rs[j] = rs[j], rs[i]
}

func main() {
	regions := AWSRegions{
		{Name: "US-East (Virginia)", Code: "us-east-1"},
		{Name: "US-West (California)", Code: "us-west-1"},
		{Name: "US-West (Oregon)", Code: "us-west-2"},
		{Name: "Asia Pacific (Mumbai)", Code: "ap-south-1"},
		{Name: "Asia Pacific (Seoul)", Code: "ap-northeast-2"},
		{Name: "Asia Pacific (Singapore)", Code: "ap-southeast-1"},
		{Name: "Asia Pacific (Sydney)", Code: "ap-southeast-2"},
		{Name: "Asia Pacific (Tokyo)", Code: "ap-northeast-1"},
		{Name: "Europe (Ireland)", Code: "eu-west-1"},
		{Name: "Europe (Frankfurt)", Code: "eu-central-1"},
		{Name: "South America (São Paulo)", Code: "sa-east-1"},
		//{Name: "China (Beijing)", Code: "cn-north-1"},
	}
	var wg sync.WaitGroup
	wg.Add(len(regions))

	for i := range regions {
		go regions[i].CheckLatency(&wg)
	}

	wg.Wait()

	sort.Sort(regions)

	outFmt := "%5v %-30s %20s\n"
	fmt.Printf(outFmt, "", "Region", "Latency")
	for i, r := range regions {
		ms := fmt.Sprintf("%.2f ms", float64(r.Latency.Nanoseconds())/1000/1000)
		fmt.Printf(outFmt, i, r.Name, ms)
	}
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<|endoftext|>