<commit_before>package engine

import (
	log "github.com/Sirupsen/logrus"
	"github.com/luizbafilho/fusis/infra"
	"github.com/luizbafilho/fusis/steps"
)

var store *StoreBolt
var cs *infra.CloudstackIaaS

func init() {
	var err error
	store, err = NewStore("fusis.db")
	if err != nil {
		panic(err)
	}
}

func GetServices() (*[]Service, error) {
	return store.GetServices()
}

func AddService(svc *Service) error {
	seq := steps.NewSequence(
		addServiceStore{svc},
		addServiceIpvs{svc},
	)

	if err := seq.Execute(); err != nil {
		return err
	}

	return nil
}

func GetService(id string) (*Service, error) {
	return store.GetService(id)
}

func DeleteService(id string) error {
	log.Infof("Deleting Service: %v", id)
	svc, err := store.GetService(id)
	if err != nil {
		return err
	}

	if err := IPVSDeleteService(svc.ToIpvsService()); err != nil {
		return err
	}

	if err := store.DeleteService(svc); err != nil {
		return err
	}

	return nil
}

func AddDestination(svc *Service, dst *Destination) error {
	log.Infof("Adding Destination: %v", dst.Name)
	if err := store.AddDestination(dst); err != nil {
		return err
	}

	if err := IPVSAddDestination(*svc.ToIpvsService(), *dst.ToIpvsDestination()); err != nil {
		return err
	}

	return nil
}

func DeleteDestination(id string) error {
	log.Infof("Deleting Destination: %v", id)
	dst, err := store.GetDestination(id)
	if err != nil {
		return err
	}

	svc, err := store.GetService(dst.ServiceId)
	if err != nil {
		return err
	}

	if err := store.DeleteDestination(dst); err != nil {
		return err
	}
	if err := IPVSDeleteDestination(*svc.ToIpvsService(), *dst.ToIpvsDestination()); err != nil {
		return err
	}

	return nil
}
<commit_msg>[engine] removing wrong import<commit_after>package engine

import (
	log "github.com/Sirupsen/logrus"
	"github.com/luizbafilho/fusis/steps"
)

var store *StoreBolt

func init() {
	var err error
	store, err = NewStore("fusis.db")
	if err != nil {
		panic(err)
	}
}

func GetServices() (*[]Service, error) {
	return store.GetServices()
}

func AddService(svc *Service) error {
	seq := steps.NewSequence(
		addServiceStore{svc},
		addServiceIpvs{svc},
	)

	if err := seq.Execute(); err != nil {
		return err
	}

	return nil
}

func GetService(id string) (*Service, error) {
	return store.GetService(id)
}

func DeleteService(id string) error {
	log.Infof("Deleting Service: %v", id)
	svc, err := store.GetService(id)
	if err != nil {
		return err
	}

	if err := IPVSDeleteService(svc.ToIpvsService()); err != nil {
		return err
	}

	if err := store.DeleteService(svc); err != nil {
		return err
	}

	return nil
}

func AddDestination(svc *Service, dst *Destination) error {
	log.Infof("Adding Destination: %v", dst.Name)
	if err := store.AddDestination(dst); err != nil {
		return err
	}

	if err := IPVSAddDestination(*svc.ToIpvsService(), *dst.ToIpvsDestination()); err != nil {
		return err
	}

	return nil
}

func DeleteDestination(id string) error {
	log.Infof("Deleting Destination: %v", id)
	dst, err := store.GetDestination(id)
	if err != nil {
		return err
	}

	svc, err := store.GetService(dst.ServiceId)
	if err != nil {
		return err
	}

	if err := store.DeleteDestination(dst); err != nil {
		return err
	}
	if err := IPVSDeleteDestination(*svc.ToIpvsService(), *dst.ToIpvsDestination()); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "log"
    "time"

    "periph.io/x/periph/conn/gpio"
    "periph.io/x/periph/host"
    "periph.io/x/periph/host/rpi"
)

func main() {
    // Load all the drivers:
    if _, err := host.Init(); err != nil {
        log.Fatal(err)
    }

    // Lookup a pin by its number:
    p20 := gpioreg.ByName("GPI20")
    if p20 == nil {
        log.Fatal("Failed to find GPI20")
    }

    fmt.Printf("%s: %s\n", p20, p20.Function())

    // Set it as input, with an internal pull down resistor:
    if err = p20.In(gpio.PullDown, gpio.BothEdges); err != nil {
        log.Fatal(err)
    }

    // Wait for edges as detected by the hardware, and print the value read:
    for {
        p20.WaitForEdge(-1)
        fmt.Printf("-> %s\n", p20.Read())
    }

    t := time.NewTicker(500 * time.Millisecond)
    for l := gpio.Low; ; l = !l {
        // Lookup a pin by its location on the board:
        if err := rpi.P1_40.Out(l); err != nil {
            log.Fatal(err)
        }
        <-t.C
    }
}

<commit_msg>udpate<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"time"

	"periph.io/x/periph/conn/gpio"
	"periph.io/x/periph/host"
	"periph.io/x/periph/host/rpi"

	log "github.com/sirupsen/logrus"
)

const toolVersion = "1.0.0"

// A Function that also returns an error
func jeffFunc() (string, error) {

	fmt.Println("opening gpio")

	host.Init()
	t := time.NewTicker(500 * time.Millisecond)
	for l := gpio.Low; ; l = !l {
		rpi.P1_33.Out(l)
		<-t.C
	}

	return "Everything worked great", nil
}

// Check your error
func checkErr(err error) {
	if err != nil {
		fmt.Printf("Error is %+v\n", err)
		log.Fatal("ERROR:", err)
	}
}

func init() {

	// SET LOG LEVEL
	// log.SetLevel(log.InfoLevel)
	log.SetLevel(log.TraceLevel)

	// SET FORMAT
	log.SetFormatter(&log.TextFormatter{})
	// log.SetFormatter(&log.JSONFormatter{})

	// SET OUTPUT (DEFAULT stderr)
	log.SetOutput(os.Stdout)

	// VERSION FLAG
	version := flag.Bool("v", false, "prints current version")
	// Parse the flags
	flag.Parse()

	// CHECK VERSION
	if *version {
		fmt.Println(toolVersion)
		os.Exit(0)
	}

}

func main() {

	log.Trace("Calling jeffFunc to get result")
	r, err := jeffFunc()
	checkErr(err)
	fmt.Println("Returned", r)

}

<|endoftext|>


<commit_before>package entity

import (
	"github.com/yofu/dxf/format"
)

// Spline represents LINE Entity.
type Spline struct {
	*entity
	Normal    []float64   // 210, 220, 230
	Flag      int         // 70
	Degree    int         // 71
	Knots     []float64 // 72, 40
	Controls  [][]float64 // 73, 10, 20, 30
	Fits      [][]float64 // 74, 11, 21, 31
	Tolerance []float64   // 42, 43, 44
}

// IsEntity is for Entity interface.
func (l *Spline) IsEntity() bool {
	return true
}

// NewSpline creates a new Spline.
func NewSpline() *Spline {
	l := &Spline{
		entity:    NewEntity(SPLINE),
		Normal:    []float64{0.0, 0.0, 1.0},
		Flag:      1064,
		Degree:    3,
		Knots:     nil,
		Controls:  nil,
		Fits:      nil,
		Tolerance: []float64{0.000000001, 0.0000000001, 0.0000000001},
	}
	return l
}

// Format writes data to formatter.
func (s *Spline) Format(f format.Formatter) {
	s.entity.Format(f)
	f.WriteString(100, "AcDbSpline")
	for i := 0; i < 3; i++ {
		f.WriteFloat(210+i*10, s.Normal[i])
	}
	f.WriteInt(70, s.Flag)
	f.WriteInt(71, s.Degree)
	f.WriteInt(72, len(s.Knots))
	f.WriteInt(73, len(s.Controls))
	f.WriteInt(74, len(s.Fits))
	for i := 0; i < 3; i++ {
		f.WriteFloat(42+i, s.Tolerance[i])
	}
	for _, k := range s.Knots {
		f.WriteFloat(40, k)
	}
	for _, c := range s.Controls {
		for i := 0; i < 3; i++ {
			f.WriteFloat((i+1)*10, c[i])
		}
	}
	for _, ft := range s.Fits {
		for i := 0; i < 3; i++ {
			f.WriteFloat((i+1)*10+1, ft[i])
		}
	}
}

// String outputs data using default formatter.
func (s *Spline) String() string {
	f := format.NewASCII()
	return s.FormatString(f)
}

// FormatString outputs data using given formatter.
func (s *Spline) FormatString(f format.Formatter) string {
	s.Format(f)
	return f.Output()
}

// func (s *Spline) BBox() ([]float64, []float64) {
// 	mins := make([]float64, 3)
// 	maxs := make([]float64, 3)
// 	for i := 0; i < 3; i++ {
// 		if l.Start[i] <= l.End[i] {
// 			mins[i] = l.Start[i]
// 			maxs[i] = l.End[i]
// 		} else {
// 			mins[i] = l.End[i]
// 			maxs[i] = l.Start[i]
// 		}
// 	}
// 	return mins, maxs
// }
<commit_msg>gofmt<commit_after>package entity

import (
	"github.com/yofu/dxf/format"
)

// Spline represents LINE Entity.
type Spline struct {
	*entity
	Normal    []float64   // 210, 220, 230
	Flag      int         // 70
	Degree    int         // 71
	Knots     []float64   // 72, 40
	Controls  [][]float64 // 73, 10, 20, 30
	Fits      [][]float64 // 74, 11, 21, 31
	Tolerance []float64   // 42, 43, 44
}

// IsEntity is for Entity interface.
func (l *Spline) IsEntity() bool {
	return true
}

// NewSpline creates a new Spline.
func NewSpline() *Spline {
	l := &Spline{
		entity:    NewEntity(SPLINE),
		Normal:    []float64{0.0, 0.0, 1.0},
		Flag:      1064,
		Degree:    3,
		Knots:     nil,
		Controls:  nil,
		Fits:      nil,
		Tolerance: []float64{0.000000001, 0.0000000001, 0.0000000001},
	}
	return l
}

// Format writes data to formatter.
func (s *Spline) Format(f format.Formatter) {
	s.entity.Format(f)
	f.WriteString(100, "AcDbSpline")
	for i := 0; i < 3; i++ {
		f.WriteFloat(210+i*10, s.Normal[i])
	}
	f.WriteInt(70, s.Flag)
	f.WriteInt(71, s.Degree)
	f.WriteInt(72, len(s.Knots))
	f.WriteInt(73, len(s.Controls))
	f.WriteInt(74, len(s.Fits))
	for i := 0; i < 3; i++ {
		f.WriteFloat(42+i, s.Tolerance[i])
	}
	for _, k := range s.Knots {
		f.WriteFloat(40, k)
	}
	for _, c := range s.Controls {
		for i := 0; i < 3; i++ {
			f.WriteFloat((i+1)*10, c[i])
		}
	}
	for _, ft := range s.Fits {
		for i := 0; i < 3; i++ {
			f.WriteFloat((i+1)*10+1, ft[i])
		}
	}
}

// String outputs data using default formatter.
func (s *Spline) String() string {
	f := format.NewASCII()
	return s.FormatString(f)
}

// FormatString outputs data using given formatter.
func (s *Spline) FormatString(f format.Formatter) string {
	s.Format(f)
	return f.Output()
}

// func (s *Spline) BBox() ([]float64, []float64) {
// 	mins := make([]float64, 3)
// 	maxs := make([]float64, 3)
// 	for i := 0; i < 3; i++ {
// 		if l.Start[i] <= l.End[i] {
// 			mins[i] = l.Start[i]
// 			maxs[i] = l.End[i]
// 		} else {
// 			mins[i] = l.End[i]
// 			maxs[i] = l.Start[i]
// 		}
// 	}
// 	return mins, maxs
// }
<|endoftext|>


<commit_before>package errors

import (
	"fmt"
	"sync"
)

//go:generate stringer -type=Priority

// Priority defines how an error should be threaded
type Priority int

// Priorities that can be used to create and list errors
const (
	Unknown Priority = iota
	Debug
	Info
	Notice
	Warning
	Error
	Critical
	Alert
	Emergency
)

// Config defines the error configuration, currently no configuration options
// are availible.
type Config struct {
}

// Err contains a single error
type Err struct {
	p   Priority
	msg string
}

// Priority returns the priority of this error
func (e Err) Priority() Priority {
	return e.p
}

// String returns the message of this error
func (e Err) Error() string {
	return e.msg
}

// Errors contains a list of Error
type Errors struct {
	err    []Err
	config *Config
	p      Priority
	m      sync.Mutex
}

// New creates an empty error container
func New(c *Config) *Errors {
	return &Errors{config: c}
}

// IsError returns true on one or more errors
func (e *Errors) IsError() bool {
	if len(e.err) > 0 {
		return true
	}
	return false
}

// Priority returns the priority of this error
func (e *Errors) Priority() Priority {
	return e.p
}

// List returns all errors of a given priority, if no priority is given all
// errors are returned.
func (e *Errors) List(p ...Priority) []Err {
	if len(p) == 0 {
		return e.err
	}

	// filter errors to given priorities
	var l []Err
	for _, e := range e.err {
		for _, priority := range p {
			if e.p == priority {
				l = append(l, e)
			}
		}
	}
	return l
}

// Append add all Errors to existing Errors
func (e *Errors) Append(err *Errors) error {
	if err == nil {
		return nil
	}

	e.m.Lock()

	// append Errors at the end of the current list
	e.err = append(e.err, err.err...)

	// set highest priority
	if err.p > e.p {
		e.p = err.p
	}

	e.m.Unlock()
	return nil
}

// Emerg log an error with severity Emergency
func (e *Errors) Emerg(format string, a ...interface{}) error {
	return e.add(Emergency, format, a)
}

// Alert log an error with severity Alert
func (e *Errors) Alert(format string, a ...interface{}) error {
	return e.add(Alert, format, a)
}

// Crit log an error with severity Critical
func (e *Errors) Crit(format string, a ...interface{}) error {
	return e.add(Critical, format, a)
}

// Err log an error with severity Error
func (e *Errors) Err(format string, a ...interface{}) error {
	return e.add(Error, format, a)
}

// Warning log an error with severity Warning
func (e *Errors) Warning(format string, a ...interface{}) error {
	return e.add(Warning, format, a)
}

// Notice log an error with severity Notice
func (e *Errors) Notice(format string, a ...interface{}) error {
	return e.add(Notice, format, a)
}

// Info log an error with severity Info
func (e *Errors) Info(format string, a ...interface{}) error {
	return e.add(Info, format, a)
}

// Debug log an error with severity Debug
func (e *Errors) Debug(format string, a ...interface{}) error {
	return e.add(Debug, format, a)
}

func (e *Errors) add(p Priority, format string, a []interface{}) error {
	// no error in request
	if len(format) == 0 && len(a) == 0 {
		return nil
	}

	e.m.Lock()

	msg := format
	if len(a) > 0 {
		msg = fmt.Sprintf(format, a)
	}

	// add this priority to the end of the list
	e.err = append(e.err, Err{
		p:   p,
		msg: msg,
	})

	// set highest priority in this list
	if p > e.p {
		e.p = p
	}

	e.m.Unlock()
	return nil
}
<commit_msg>Fix argument forwarding<commit_after>package errors

import (
	"fmt"
	"sync"
)

//go:generate stringer -type=Priority

// Priority defines how an error should be threaded
type Priority int

// Priorities that can be used to create and list errors
const (
	Unknown Priority = iota
	Debug
	Info
	Notice
	Warning
	Error
	Critical
	Alert
	Emergency
)

// Config defines the error configuration, currently no configuration options
// are availible.
type Config struct {
}

// Err contains a single error
type Err struct {
	p   Priority
	msg string
}

// Priority returns the priority of this error
func (e Err) Priority() Priority {
	return e.p
}

// String returns the message of this error
func (e Err) Error() string {
	return e.msg
}

// Errors contains a list of Error
type Errors struct {
	err    []Err
	config *Config
	p      Priority
	m      sync.Mutex
}

// New creates an empty error container
func New(c *Config) *Errors {
	return &Errors{config: c}
}

// IsError returns true on one or more errors
func (e *Errors) IsError() bool {
	if len(e.err) > 0 {
		return true
	}
	return false
}

// Priority returns the priority of this error
func (e *Errors) Priority() Priority {
	return e.p
}

// List returns all errors of a given priority, if no priority is given all
// errors are returned.
func (e *Errors) List(p ...Priority) []Err {
	if len(p) == 0 {
		return e.err
	}

	// filter errors to given priorities
	var l []Err
	for _, e := range e.err {
		for _, priority := range p {
			if e.p == priority {
				l = append(l, e)
			}
		}
	}
	return l
}

// Append add all Errors to existing Errors
func (e *Errors) Append(err *Errors) error {
	if err == nil {
		return nil
	}

	e.m.Lock()

	// append Errors at the end of the current list
	e.err = append(e.err, err.err...)

	// set highest priority
	if err.p > e.p {
		e.p = err.p
	}

	e.m.Unlock()
	return nil
}

// Emerg log an error with severity Emergency
func (e *Errors) Emerg(format string, a ...interface{}) error {
	return e.add(Emergency, format, a...)
}

// Alert log an error with severity Alert
func (e *Errors) Alert(format string, a ...interface{}) error {
	return e.add(Alert, format, a...)
}

// Crit log an error with severity Critical
func (e *Errors) Crit(format string, a ...interface{}) error {
	return e.add(Critical, format, a...)
}

// Err log an error with severity Error
func (e *Errors) Err(format string, a ...interface{}) error {
	return e.add(Error, format, a...)
}

// Warning log an error with severity Warning
func (e *Errors) Warning(format string, a ...interface{}) error {
	return e.add(Warning, format, a...)
}

// Notice log an error with severity Notice
func (e *Errors) Notice(format string, a ...interface{}) error {
	return e.add(Notice, format, a...)
}

// Info log an error with severity Info
func (e *Errors) Info(format string, a ...interface{}) error {
	return e.add(Info, format, a...)
}

// Debug log an error with severity Debug
func (e *Errors) Debug(format string, a ...interface{}) error {
	return e.add(Debug, format, a...)
}

func (e *Errors) add(p Priority, format string, a ...interface{}) error {
	// no error in request
	if len(format) == 0 && len(a) == 0 {
		return nil
	}

	e.m.Lock()

	msg := format
	if len(a) > 0 {
		msg = fmt.Sprintf(format, a...)
	}

	// add this priority to the end of the list
	e.err = append(e.err, Err{
		p:   p,
		msg: msg,
	})

	// set highest priority in this list
	if p > e.p {
		e.p = p
	}

	e.m.Unlock()
	return nil
}
<|endoftext|>


<commit_before>package shell

import (
	flag "../../appletflag"
	"../../common"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
)

func Main() {
	flag.Parse()
	call := flag.Args()
	var in *common.BufferedReader
	interactive := true
	if len(call) > 1 {
		call = call[0:1]
	}
	if len(call) == 1 {
		f, e := os.Open(call[0])
		if e != nil {
			log.Fatalf("Could not open input file %s: %s\n", call[1], e)
		}
		defer f.Close()
		in = common.NewBufferedReader(f)
		interactive = false
	} else {
		in = common.NewBufferedReader(os.Stdin)
	}

	var e error
	var line string
	for e == nil {
		if interactive {
			fmt.Print("> ")
		}
		line, e = in.ReadWholeLine()
		if e != nil {
			log.Fatalf("Could not read line: %s\n", e)
		}
		if isComment(line) {
			continue
		}
		params, ce := common.Parameterize(line)
		if ce != nil {
			common.DumpError(ce)
			continue
		}
		ce = execute(params)
		if ce != nil {
			common.DumpError(ce)
			continue
		}
	}
	return
}

func isComment(line string) bool {
	line = strings.TrimSpace(line)
	return strings.HasPrefix(line, "#")
}

func execute(cmd []string) error {
	if len(cmd) == 0 {
		return nil
	}
	if isBuiltIn(cmd[0]) {
		builtin := Builtins[cmd[0]]
		return builtin(cmd)
	} else {
		cmd := exec.Command(cmd[0], cmd[1:]...)
		cmd.Stdout = os.Stdout
		cmd.Stdin = os.Stdin
		cmd.Stderr = os.Stderr
		e := cmd.Run()
		return e
	}
	return nil
}

func isBuiltIn(cmd string) bool {
	_, ok := Builtins[cmd]
	return ok
}
<commit_msg>Expand environment variables in shell<commit_after>package shell

import (
	flag "../../appletflag"
	"../../common"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
)

func Main() {
	flag.Parse()
	call := flag.Args()
	var in *common.BufferedReader
	interactive := true
	if len(call) > 1 {
		call = call[0:1]
	}
	if len(call) == 1 {
		f, e := os.Open(call[0])
		if e != nil {
			log.Fatalf("Could not open input file %s: %s\n", call[1], e)
		}
		defer f.Close()
		in = common.NewBufferedReader(f)
		interactive = false
	} else {
		in = common.NewBufferedReader(os.Stdin)
	}

	var e error
	var line string
	for e == nil {
		if interactive {
			fmt.Print("> ")
		}
		line, e = in.ReadWholeLine()
		if e != nil {
			log.Fatalf("Could not read line: %s\n", e)
		}
		if isComment(line) {
			continue
		}
		params, ce := common.Parameterize(line)
		if ce != nil {
			common.DumpError(ce)
			continue
		}
		params = expandEnvs(params)
		ce = execute(params)
		if ce != nil {
			common.DumpError(ce)
			continue
		}
	}
	return
}

// Replace environment variables with the content
func expandEnvs(params []string) []string {
	for i, param := range params {
		if len(param) > 1 && strings.HasPrefix(param, "$") {
			params[i] = os.Getenv(param[1:])
		}
	}
	return params
}

func isComment(line string) bool {
	line = strings.TrimSpace(line)
	return strings.HasPrefix(line, "#")
}

func execute(cmd []string) error {
	if len(cmd) == 0 {
		return nil
	}
	if isBuiltIn(cmd[0]) {
		builtin := Builtins[cmd[0]]
		return builtin(cmd)
	} else {
		cmd := exec.Command(cmd[0], cmd[1:]...)
		cmd.Stdout = os.Stdout
		cmd.Stdin = os.Stdin
		cmd.Stderr = os.Stderr
		e := cmd.Run()
		return e
	}
	return nil
}

func isBuiltIn(cmd string) bool {
	_, ok := Builtins[cmd]
	return ok
}
<|endoftext|>


<commit_before>package apps

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"

	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	"github.com/cloudfoundry/cf-acceptance-tests/helpers"
)

var _ = Describe("Application Lifecycle", func() {
	var appName string

	BeforeEach(func() {
		appName = generator.RandomName()

		Expect(cf.Cf("push", appName, "-p", helpers.NewAssets().Dora).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))
	})

	AfterEach(func() {
		Expect(cf.Cf("delete", appName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})

	Describe("pushing", func() {
		It("makes the app reachable via its bound route", func() {
			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("Hi, I'm Dora!"))
		})
	})

	Describe("stopping", func() {
		BeforeEach(func() {
			Expect(cf.Cf("stop", appName).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})

		It("makes the app unreachable", func() {
			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("404"))
		})

		Describe("and then starting", func() {
			BeforeEach(func() {
				Expect(cf.Cf("start", appName).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			})

			It("makes the app reachable again", func() {
				Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("Hi, I'm Dora!"))
			})
		})
	})

	Describe("updating", func() {
		It("is reflected through another push", func() {
			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("Hi, I'm Dora!"))

			Expect(cf.Cf("push", appName, "-p", helpers.NewAssets().HelloWorld).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))

			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("Hello, world!"))
		})
	})

	Describe("deleting", func() {
		BeforeEach(func() {
			Expect(cf.Cf("delete", appName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})

		It("removes the application", func() {
			app := cf.Cf("app", appName).Wait(DEFAULT_TIMEOUT)
			Expect(app).To(Exit(1))
			Expect(app).To(Say("not found"))
		})

		It("makes the app unreachable", func() {
			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("404"))
		})
	})
})
<commit_msg>Acceptance tests for app usage event<commit_after>package apps

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"

	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	"github.com/cloudfoundry/cf-acceptance-tests/helpers"
)

type AppUsageEvent struct {
	Entity struct {
		AppName       string `json:"app_name"`
		State         string `json:"state"`
		BuildpackName string `json:"buildpack_name"`
		BuildpackGuid string `json:"buildpack_guid"`
	} `json:"entity"`
}

type AppUsageEvents struct {
	Resources []AppUsageEvent `struct:"resources"`
}

func lastAppUsageEvent(appName string, state string) (bool, AppUsageEvent) {
	var response AppUsageEvents
	cf.AsUser(context.AdminUserContext(), func() {
		cf.ApiRequest("GET", "/v2/app_usage_events?order-direction=desc&page=1", &response)
	})

	for _, event := range response.Resources {
		if event.Entity.AppName == appName && event.Entity.State == state {
			return true, event
		}
	}

	return false, AppUsageEvent{}
}

var _ = Describe("Application Lifecycle", func() {
	var appName string

	BeforeEach(func() {
		appName = generator.RandomName()

		Expect(cf.Cf("push", appName, "-p", helpers.NewAssets().Dora).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))
	})

	AfterEach(func() {
		Expect(cf.Cf("delete", appName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})

	Describe("pushing", func() {
		It("makes the app reachable via its bound route", func() {
			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("Hi, I'm Dora!"))
		})

		It("generates an app usage 'started' event", func() {
			found, _ := lastAppUsageEvent(appName, "STARTED")
			Expect(found).To(BeTrue())
		})

		It("generates an app usage 'buildpack_set' event", func() {
			found, matchingEvent := lastAppUsageEvent(appName, "BUILDPACK_SET")

			Expect(found).To(BeTrue())
			Expect(matchingEvent.Entity.BuildpackName).To(Equal("ruby_buildpack"))
			Expect(matchingEvent.Entity.BuildpackGuid).ToNot(BeZero())
		})
	})

	Describe("stopping", func() {
		BeforeEach(func() {
			Expect(cf.Cf("stop", appName).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})

		It("makes the app unreachable", func() {
			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("404"))
		})

		It("generates an app usage 'stopped' event", func() {
			found, _ := lastAppUsageEvent(appName, "STOPPED")
			Expect(found).To(BeTrue())
		})

		Describe("and then starting", func() {
			BeforeEach(func() {
				Expect(cf.Cf("start", appName).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			})

			It("makes the app reachable again", func() {
				Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("Hi, I'm Dora!"))
			})
		})
	})

	Describe("updating", func() {
		It("is reflected through another push", func() {
			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("Hi, I'm Dora!"))

			Expect(cf.Cf("push", appName, "-p", helpers.NewAssets().HelloWorld).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))

			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("Hello, world!"))
		})
	})

	Describe("deleting", func() {
		BeforeEach(func() {
			Expect(cf.Cf("delete", appName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})

		It("removes the application", func() {
			app := cf.Cf("app", appName).Wait(DEFAULT_TIMEOUT)
			Expect(app).To(Exit(1))
			Expect(app).To(Say("not found"))
		})

		It("makes the app unreachable", func() {
			Expect(helpers.CurlAppRoot(appName)).To(ContainSubstring("404"))
		})

		It("generates an app usage 'stopped' event", func() {
			found, _ := lastAppUsageEvent(appName, "STOPPED")
			Expect(found).To(BeTrue())
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strconv"
	"strings"

	"gonum.org/v1/plot"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/vg"

	"github.com/lucasb-eyer/go-colorful"
)

type job struct {
	caseNumber   int
	autoscaling  bool
	trainerCount int
}

type row struct {
	timestamp               int
	cpuUtil                 float64
	runningTrainerCount     int
	notExistJobCount        int
	pendingJobCount         int
	runningJobCount         int
	doneJobCount            int
	nginxCount              int
	jobRunningTrainerCounts []int
	jobCPUUtils             []float64
}

type jobCase []row

func parseJobCase(path string) (j jobCase) {
	b, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}

	idx := 0
	s := bufio.NewScanner(bytes.NewReader(b))
	ts := 0
	for s.Scan() {
		var r row
		ss := strings.Split(s.Text(), ",")
		r.timestamp, err = strconv.Atoi(ss[0])
		if err != nil {
			panic(err)
		}

		if r.timestamp < ts {
			continue
		}
		ts = r.timestamp

		r.cpuUtil, err = strconv.ParseFloat(ss[1], 64)
		if err != nil {
			panic(err)
		}

		r.runningTrainerCount, err = strconv.Atoi(ss[2])
		if err != nil {
			panic(err)
		}

		r.notExistJobCount, err = strconv.Atoi(ss[3])
		if err != nil {
			panic(err)
		}

		r.pendingJobCount, err = strconv.Atoi(ss[4])
		if err != nil {
			panic(err)
		}

		r.runningJobCount, err = strconv.Atoi(ss[5])
		if err != nil {
			panic(err)
		}

		r.doneJobCount, err = strconv.Atoi(ss[6])
		if err != nil {
			panic(err)
		}

		r.nginxCount, err = strconv.Atoi(ss[7])
		if err != nil {
			panic(err)
		}

		cur := 8
		remain := len(ss) - cur
		trainerCount := remain / 2
		if remain != trainerCount*2 {
			panic(fmt.Errorf("unrecognized row at %s:%d", path, idx))
		}

		r.jobRunningTrainerCounts = make([]int, trainerCount)
		r.jobCPUUtils = make([]float64, trainerCount)

		for i := range r.jobRunningTrainerCounts {
			c, err := strconv.ParseFloat(ss[cur], 64)
			if err != nil {
				panic(err)
			}
			r.jobRunningTrainerCounts[i] = int(c)

			cur++
		}

		for i := range r.jobCPUUtils {
			r.jobCPUUtils[i], err = strconv.ParseFloat(ss[cur], 64)
			if err != nil {
				panic(err)
			}

			cur++
		}

		j = append(j, r)
		idx++
	}

	return
}

func parseJob(path string) job {
	j := job{}
	s := strings.Split(path, "/")
	folder := s[len(s)-2]

	s = strings.Split(folder, "-")
	switch s[0] {
	case "case1":
		j.caseNumber = 1
	case "case2":
		j.caseNumber = 2
	default:
		panic(fmt.Errorf("could not recognize file path: %s", path))
	}

	switch s[2] {
	case "OFF":
		j.autoscaling = false
	case "ON":
		j.autoscaling = true
	default:
		panic(fmt.Errorf("could not recognize file path: %s", path))
	}

	count, err := strconv.Atoi(s[3])
	if err != nil {
		panic(err)
	}

	j.trainerCount = count
	return j
}

type present func(c jobCase) plotter.XYs

func casesToPoints(p present, c []jobCase) []plotter.XYs {
	r := make([]plotter.XYs, len(c))
	for i := range r {
		r[i] = p(c[i])
	}
	return r
}

func clusterUtil(c jobCase) plotter.XYs {
	r := make(plotter.XYs, len(c))
	for i, row := range c {
		r[i].X = float64(row.timestamp)
		r[i].Y = row.cpuUtil
	}

	return r
}

func pendingJobs(c jobCase) plotter.XYs {
	r := make(plotter.XYs, len(c))
	for i, row := range c {
		r[i].X = float64(row.timestamp)
		r[i].Y = float64(row.pendingJobCount)
	}

	return r
}

func nginxCount(c jobCase) plotter.XYs {
	r := make(plotter.XYs, len(c))
	for i, row := range c {
		r[i].X = float64(row.timestamp)
		r[i].Y = float64(row.nginxCount)
	}

	return r
}

func draw(p *plot.Plot, output string, caseOn, caseOff []jobCase, pre present) {
	pts := casesToPoints(pre, caseOn)
	for i := range pts {
		l, err := plotter.NewLine(pts[i])
		if err != nil {
			panic(err)
		}
		l.LineStyle.Width = vg.Points(1)
		l.LineStyle.Color = colorful.HappyColor()

		p.Add(l)
		p.Legend.Add(fmt.Sprintf("on-%d", i), l)
		if err != nil {
			panic(err)
		}
	}

	pts = casesToPoints(pre, caseOff)
	for i := range pts {
		l, err := plotter.NewLine(pts[i])
		if err != nil {
			panic(err)
		}
		l.LineStyle.Width = vg.Points(1)
		l.LineStyle.Color = colorful.WarmColor()
		l.LineStyle.Dashes = []vg.Length{vg.Points(5), vg.Points(5)}

		p.Add(l)
		p.Legend.Add(fmt.Sprintf("off-%d", i), l)
		if err != nil {
			panic(err)
		}
	}

	// Save the plot to a PNG file.
	if err := p.Save(8*vg.Inch, 4*vg.Inch, output); err != nil {
		panic(err)
	}
}

var (
	case1On  = job{caseNumber: 1, autoscaling: true, trainerCount: 20}
	case1Off = job{caseNumber: 1, autoscaling: false, trainerCount: 20}
	case2On  = job{caseNumber: 2, autoscaling: true, trainerCount: 6}
	case2Off = job{caseNumber: 2, autoscaling: false, trainerCount: 6}
)

func main() {
	pattern := flag.String("pattern", "", "input files")
	flag.Parse()

	matches, err := filepath.Glob(*pattern)
	if err != nil {
		panic(err)
	}

	if len(matches) == 0 {
		panic("no file matched from pattern")
	}

	cases := make(map[job][]jobCase)

	for _, path := range matches {
		j := parseJob(path)
		c := parseJobCase(path)
		cases[j] = append(cases[j], c)
	}

	p, err := plot.New()
	if err != nil {
		panic(err)
	}
	p.Title.Text = "Case 1 Cluster Utilization"
	p.X.Label.Text = "Timestamp"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "Utilization Percentage"
	p.Y.Min = 0
	p.Y.Max = 100
	p.Add(plotter.NewGrid())
	draw(p, "case1_util.png", cases[case1On], cases[case1Off], clusterUtil)

	p, err = plot.New()
	if err != nil {
		panic(err)
	}
	p.Title.Text = "Case 2 Cluster Utilization"
	p.X.Label.Text = "Timestamp"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "Utilization Percentage"
	p.Y.Min = 0
	p.Y.Max = 100
	p.Add(plotter.NewGrid())
	draw(p, "case2_util.png", cases[case2On], cases[case2Off], clusterUtil)

	p, err = plot.New()
	if err != nil {
		panic(err)
	}
	p.Title.Text = "Case 1 Pending Job Count"
	p.X.Label.Text = "Timestamp"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "Number of Pending Jobs"
	p.Y.Min = 0
	p.Y.Max = 16
	p.Add(plotter.NewGrid())
	draw(p, "case1_pending.png", cases[case1On], cases[case1Off], pendingJobs)

	p, err = plot.New()
	if err != nil {
		panic(err)
	}
	p.Title.Text = "Case 2 Pending Job Count"
	p.X.Label.Text = "Timestamp"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "Number of Pending Jobs"
	p.Y.Min = 0
	p.Y.Max = 4
	p.Add(plotter.NewGrid())
	draw(p, "case2_pending.png", cases[case2On], cases[case2Off], pendingJobs)
	p, err = plot.New()
	if err != nil {
		panic(err)
	}

	p.Title.Text = "Case 2 Nginx Count"
	p.X.Label.Text = "Timestamp"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "Number of Nginx Pods"
	p.Y.Min = 0
	p.Y.Max = 420
	p.Add(plotter.NewGrid())
	draw(p, "case2_nginx.png", cases[case2On], cases[case2Off], nginxCount)
}
<commit_msg>Update experiment plot texts<commit_after>package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strconv"
	"strings"

	"gonum.org/v1/plot"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/vg"

	"github.com/lucasb-eyer/go-colorful"
)

type job struct {
	caseNumber   int
	autoscaling  bool
	trainerCount int
}

type row struct {
	timestamp               int
	cpuUtil                 float64
	runningTrainerCount     int
	notExistJobCount        int
	pendingJobCount         int
	runningJobCount         int
	doneJobCount            int
	nginxCount              int
	jobRunningTrainerCounts []int
	jobCPUUtils             []float64
}

type jobCase []row

func parseJobCase(path string) (j jobCase) {
	b, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}

	idx := 0
	s := bufio.NewScanner(bytes.NewReader(b))
	ts := 0
	for s.Scan() {
		var r row
		ss := strings.Split(s.Text(), ",")
		r.timestamp, err = strconv.Atoi(ss[0])
		if err != nil {
			panic(err)
		}

		if r.timestamp < ts {
			continue
		}
		ts = r.timestamp

		r.cpuUtil, err = strconv.ParseFloat(ss[1], 64)
		if err != nil {
			panic(err)
		}

		r.runningTrainerCount, err = strconv.Atoi(ss[2])
		if err != nil {
			panic(err)
		}

		r.notExistJobCount, err = strconv.Atoi(ss[3])
		if err != nil {
			panic(err)
		}

		r.pendingJobCount, err = strconv.Atoi(ss[4])
		if err != nil {
			panic(err)
		}

		r.runningJobCount, err = strconv.Atoi(ss[5])
		if err != nil {
			panic(err)
		}

		r.doneJobCount, err = strconv.Atoi(ss[6])
		if err != nil {
			panic(err)
		}

		r.nginxCount, err = strconv.Atoi(ss[7])
		if err != nil {
			panic(err)
		}

		cur := 8
		remain := len(ss) - cur
		trainerCount := remain / 2
		if remain != trainerCount*2 {
			panic(fmt.Errorf("unrecognized row at %s:%d", path, idx))
		}

		r.jobRunningTrainerCounts = make([]int, trainerCount)
		r.jobCPUUtils = make([]float64, trainerCount)

		for i := range r.jobRunningTrainerCounts {
			c, err := strconv.ParseFloat(ss[cur], 64)
			if err != nil {
				panic(err)
			}
			r.jobRunningTrainerCounts[i] = int(c)

			cur++
		}

		for i := range r.jobCPUUtils {
			r.jobCPUUtils[i], err = strconv.ParseFloat(ss[cur], 64)
			if err != nil {
				panic(err)
			}

			cur++
		}

		j = append(j, r)
		idx++
	}

	return
}

func parseJob(path string) job {
	j := job{}
	s := strings.Split(path, "/")
	folder := s[len(s)-2]

	s = strings.Split(folder, "-")
	switch s[0] {
	case "case1":
		j.caseNumber = 1
	case "case2":
		j.caseNumber = 2
	default:
		panic(fmt.Errorf("could not recognize file path: %s", path))
	}

	switch s[2] {
	case "OFF":
		j.autoscaling = false
	case "ON":
		j.autoscaling = true
	default:
		panic(fmt.Errorf("could not recognize file path: %s", path))
	}

	count, err := strconv.Atoi(s[3])
	if err != nil {
		panic(err)
	}

	j.trainerCount = count
	return j
}

type present func(c jobCase) plotter.XYs

func casesToPoints(p present, c []jobCase) []plotter.XYs {
	r := make([]plotter.XYs, len(c))
	for i := range r {
		r[i] = p(c[i])
	}
	return r
}

func clusterUtil(c jobCase) plotter.XYs {
	r := make(plotter.XYs, len(c))
	for i, row := range c {
		r[i].X = float64(row.timestamp)
		r[i].Y = row.cpuUtil
	}

	return r
}

func pendingJobs(c jobCase) plotter.XYs {
	r := make(plotter.XYs, len(c))
	for i, row := range c {
		r[i].X = float64(row.timestamp)
		r[i].Y = float64(row.pendingJobCount)
	}

	return r
}

func nginxCount(c jobCase) plotter.XYs {
	r := make(plotter.XYs, len(c))
	for i, row := range c {
		r[i].X = float64(row.timestamp)
		r[i].Y = float64(row.nginxCount)
	}

	return r
}

func draw(p *plot.Plot, output string, caseOn, caseOff []jobCase, pre present) {
	pts := casesToPoints(pre, caseOn)
	for i := range pts {
		l, err := plotter.NewLine(pts[i])
		if err != nil {
			panic(err)
		}
		l.LineStyle.Width = vg.Points(1)
		l.LineStyle.Color = colorful.HappyColor()

		p.Add(l)
		p.Legend.Add(fmt.Sprintf("on-%d", i), l)
		if err != nil {
			panic(err)
		}
	}

	pts = casesToPoints(pre, caseOff)
	for i := range pts {
		l, err := plotter.NewLine(pts[i])
		if err != nil {
			panic(err)
		}
		l.LineStyle.Width = vg.Points(1)
		l.LineStyle.Color = colorful.WarmColor()
		l.LineStyle.Dashes = []vg.Length{vg.Points(5), vg.Points(5)}

		p.Add(l)
		p.Legend.Add(fmt.Sprintf("off-%d", i), l)
		if err != nil {
			panic(err)
		}
	}

	// Save the plot to a PNG file.
	if err := p.Save(8*vg.Inch, 4*vg.Inch, output); err != nil {
		panic(err)
	}
}

var (
	case1On  = job{caseNumber: 1, autoscaling: true, trainerCount: 20}
	case1Off = job{caseNumber: 1, autoscaling: false, trainerCount: 20}
	case2On  = job{caseNumber: 2, autoscaling: true, trainerCount: 6}
	case2Off = job{caseNumber: 2, autoscaling: false, trainerCount: 6}
)

func main() {
	pattern := flag.String("pattern", "", "input files")
	flag.Parse()

	matches, err := filepath.Glob(*pattern)
	if err != nil {
		panic(err)
	}

	if len(matches) == 0 {
		panic("no file matched from pattern")
	}

	cases := make(map[job][]jobCase)

	for _, path := range matches {
		j := parseJob(path)
		c := parseJobCase(path)
		cases[j] = append(cases[j], c)
	}

	p, err := plot.New()
	if err != nil {
		panic(err)
	}
	p.Title.Text = "Case 1 Cluster Utilization"
	p.X.Label.Text = "time (s)"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "CPU utilization (percentage)"
	p.Y.Min = 0
	p.Y.Max = 100
	p.Add(plotter.NewGrid())
	draw(p, "case1_util.png", cases[case1On], cases[case1Off], clusterUtil)

	p, err = plot.New()
	if err != nil {
		panic(err)
	}
	p.Title.Text = "Case 2 Cluster Utilization"
	p.X.Label.Text = "time (s)"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "CPU utilization (percentage)"
	p.Y.Min = 0
	p.Y.Max = 100
	p.Add(plotter.NewGrid())
	draw(p, "case2_util.png", cases[case2On], cases[case2Off], clusterUtil)

	p, err = plot.New()
	if err != nil {
		panic(err)
	}
	p.Title.Text = "Case 1 Number of Pending Jobs"
	p.X.Label.Text = "time (s)"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "number of pending jobs"
	p.Y.Min = 0
	p.Y.Max = 16
	p.Add(plotter.NewGrid())
	draw(p, "case1_pending.png", cases[case1On], cases[case1Off], pendingJobs)

	p, err = plot.New()
	if err != nil {
		panic(err)
	}
	p.Title.Text = "Case 2 Number of Pending Jobs"
	p.X.Label.Text = "time (s)"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "number of pending jobs"
	p.Y.Min = 0
	p.Y.Max = 4
	p.Add(plotter.NewGrid())
	draw(p, "case2_pending.png", cases[case2On], cases[case2Off], pendingJobs)
	p, err = plot.New()
	if err != nil {
		panic(err)
	}

	p.Title.Text = "Case 2 Number of Nginx Pods"
	p.X.Label.Text = "time (s)"
	p.X.Min = 0
	p.X.Max = 600
	p.Y.Label.Text = "number of nginx pods"
	p.Y.Min = 0
	p.Y.Max = 420
	p.Add(plotter.NewGrid())
	draw(p, "case2_nginx.png", cases[case2On], cases[case2Off], nginxCount)
}
<|endoftext|>


<commit_before>// Package smux is a multiplexing library for Golang.
//
// It relies on an underlying connection to provide reliability and ordering, such as TCP or KCP,
// and provides stream-oriented multiplexing over a single channel.
package smux

import (
	"errors"
	"fmt"
	"io"
	"math"
	"time"
)

// Config is used to tune the Smux session
type Config struct {
	// SMUX Protocol version
	Version int
	// KeepAliveInterval is how often to send a NOP command to the remote
	KeepAliveInterval time.Duration

	// KeepAliveTimeout is how long the session
	// will be closed if no data has arrived
	KeepAliveTimeout time.Duration

	// MaxFrameSize is used to control the maximum
	// frame size to sent to the remote
	MaxFrameSize int

	// MaxReceiveBuffer is used to control the maximum
	// number of data in the buffer pool
	MaxReceiveBuffer int

	// MaxStreamBuffer is used to control the maximum
	// number of data per stream
	MaxStreamBuffer int
}

// DefaultConfig is used to return a default configuration
func DefaultConfig() *Config {
	return &Config{
		Version:           1,
		KeepAliveInterval: 10 * time.Second,
		KeepAliveTimeout:  30 * time.Second,
		MaxFrameSize:      32768,
		MaxReceiveBuffer:  4194304,
		MaxStreamBuffer:   65536,
	}
}

// VerifyConfig is used to verify the sanity of configuration
func VerifyConfig(config *Config) error {
	if !(config.Version == 1 || config.Version == 2) {
		return errors.New("unsupported protocol version")
	}
	if config.KeepAliveInterval == 0 {
		return errors.New("keep-alive interval must be positive")
	}
	if config.KeepAliveTimeout < config.KeepAliveInterval {
		return fmt.Errorf("keep-alive timeout must be larger than keep-alive interval")
	}
	if config.MaxFrameSize <= 0 {
		return errors.New("max frame size must be positive")
	}
	if config.MaxFrameSize > 65535 {
		return errors.New("max frame size must not be larger than 65535")
	}
	if config.MaxReceiveBuffer <= 0 {
		return errors.New("max receive buffer must be positive")
	}
	if config.MaxStreamBuffer <= 0 {
		return errors.New("max stream buffer must be positive")
	}
	if config.MaxStreamBuffer > config.MaxReceiveBuffer {
		return errors.New("max stream buffer must not be larger than max receive buffer")
	}
	if config.MaxStreamBuffer > math.MaxInt32 {
		return errors.New("max stream buffer cannot be larger than 2147483647")
	}
	return nil
}

// Server is used to initialize a new server-side connection.
func Server(conn io.ReadWriteCloser, config *Config) (*Session, error) {
	if config == nil {
		config = DefaultConfig()
	}
	if err := VerifyConfig(config); err != nil {
		return nil, err
	}
	return newSession(config, conn, false), nil
}

// Client is used to initialize a new client-side connection.
func Client(conn io.ReadWriteCloser, config *Config) (*Session, error) {
	if config == nil {
		config = DefaultConfig()
	}

	if err := VerifyConfig(config); err != nil {
		return nil, err
	}
	return newSession(config, conn, true), nil
}
<commit_msg>add comments<commit_after>// Package smux is a multiplexing library for Golang.
//
// It relies on an underlying connection to provide reliability and ordering, such as TCP or KCP,
// and provides stream-oriented multiplexing over a single channel.
package smux

import (
	"errors"
	"fmt"
	"io"
	"math"
	"time"
)

// Config is used to tune the Smux session
type Config struct {
	// SMUX Protocol version, support 1,2
	Version int

	// KeepAliveInterval is how often to send a NOP command to the remote
	KeepAliveInterval time.Duration

	// KeepAliveTimeout is how long the session
	// will be closed if no data has arrived
	KeepAliveTimeout time.Duration

	// MaxFrameSize is used to control the maximum
	// frame size to sent to the remote
	MaxFrameSize int

	// MaxReceiveBuffer is used to control the maximum
	// number of data in the buffer pool
	MaxReceiveBuffer int

	// MaxStreamBuffer is used to control the maximum
	// number of data per stream
	MaxStreamBuffer int
}

// DefaultConfig is used to return a default configuration
func DefaultConfig() *Config {
	return &Config{
		Version:           1,
		KeepAliveInterval: 10 * time.Second,
		KeepAliveTimeout:  30 * time.Second,
		MaxFrameSize:      32768,
		MaxReceiveBuffer:  4194304,
		MaxStreamBuffer:   65536,
	}
}

// VerifyConfig is used to verify the sanity of configuration
func VerifyConfig(config *Config) error {
	if !(config.Version == 1 || config.Version == 2) {
		return errors.New("unsupported protocol version")
	}
	if config.KeepAliveInterval == 0 {
		return errors.New("keep-alive interval must be positive")
	}
	if config.KeepAliveTimeout < config.KeepAliveInterval {
		return fmt.Errorf("keep-alive timeout must be larger than keep-alive interval")
	}
	if config.MaxFrameSize <= 0 {
		return errors.New("max frame size must be positive")
	}
	if config.MaxFrameSize > 65535 {
		return errors.New("max frame size must not be larger than 65535")
	}
	if config.MaxReceiveBuffer <= 0 {
		return errors.New("max receive buffer must be positive")
	}
	if config.MaxStreamBuffer <= 0 {
		return errors.New("max stream buffer must be positive")
	}
	if config.MaxStreamBuffer > config.MaxReceiveBuffer {
		return errors.New("max stream buffer must not be larger than max receive buffer")
	}
	if config.MaxStreamBuffer > math.MaxInt32 {
		return errors.New("max stream buffer cannot be larger than 2147483647")
	}
	return nil
}

// Server is used to initialize a new server-side connection.
func Server(conn io.ReadWriteCloser, config *Config) (*Session, error) {
	if config == nil {
		config = DefaultConfig()
	}
	if err := VerifyConfig(config); err != nil {
		return nil, err
	}
	return newSession(config, conn, false), nil
}

// Client is used to initialize a new client-side connection.
func Client(conn io.ReadWriteCloser, config *Config) (*Session, error) {
	if config == nil {
		config = DefaultConfig()
	}

	if err := VerifyConfig(config); err != nil {
		return nil, err
	}
	return newSession(config, conn, true), nil
}
<|endoftext|>


<commit_before>/*-
 * Copyright 2015 Square 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 main

import (
	"crypto/tls"
	"io"
	"net"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/rcrowley/go-metrics"
)

type proxy struct {
	quit     int32
	listener net.Listener
	handlers *sync.WaitGroup
	dial     func() (net.Conn, error)
}

var (
	openCounter    = metrics.GetOrRegisterCounter("conn.open", metrics.DefaultRegistry)
	totalCounter   = metrics.GetOrRegisterCounter("accept.total", metrics.DefaultRegistry)
	successCounter = metrics.GetOrRegisterCounter("accept.success", metrics.DefaultRegistry)
	errorCounter   = metrics.GetOrRegisterCounter("accept.error", metrics.DefaultRegistry)
	timeoutCounter = metrics.GetOrRegisterCounter("accept.timeout", metrics.DefaultRegistry)
	connTimer      = metrics.GetOrRegisterTimer("conn.lifetime", metrics.DefaultRegistry)
)

// Accept incoming connections in server mode and spawn Go routines to handle them.
// The signal handler (serverSignalHandle) can close the listener socket and
// send true to the stopper channel. When that happens, we stop accepting new
// connections and wait for outstanding connections to end.
func (p *proxy) accept() {
	for {
		// Wait for new connection
		conn, err := p.listener.Accept()
		if err != nil {
			// Check if we're supposed to stop
			if atomic.LoadInt32(&p.quit) == 1 {
				return
			}

			errorCounter.Inc(1)
			continue
		}

		openCounter.Inc(1)
		totalCounter.Inc(1)

		go connTimer.Time(func() {
			defer conn.Close()
			defer openCounter.Dec(1)

			forceHandshake(conn)

			backend, err := p.dial()
			if err != nil {
				logger.Printf("%s", err)
				return
			}

			successCounter.Inc(1)
			p.handlers.Add(1)
			defer p.handlers.Done()
			fuse(conn, backend)
		})
	}
}

// Force handshake. Handshake usually happens on first read/write, but we
// want to force it to make sure we can control the timeout for it.
// Otherwise, unauthenticated clients would be able to open connections
// and leave them hanging forever. Going through the handshake verifies
// that clients have a valid client cert and are allowed to talk to us.
func forceHandshake(conn net.Conn) (err error) {
	if tlsConn, ok := conn.(*tls.Conn); ok {
		timer := time.AfterFunc(*timeoutDuration, func() {
			logger.Printf("timed out TLS handshake on %s", conn.RemoteAddr())
			conn.SetDeadline(time.Now())
			conn.Close()
			timeoutCounter.Inc(1)
		})

		err = tlsConn.Handshake()
		timer.Stop()

		if err != nil {
			logger.Printf("error on TLS handshake from %s: %s", conn.RemoteAddr(), err)
		}
	}
	return
}

// Fuse connections together
func fuse(client, backend net.Conn) {
	// Copy from client -> backend, and from backend -> client
	go func() { copyData(client, backend) }()
	copyData(backend, client)
}

// Copy data between two connections
func copyData(dst net.Conn, src net.Conn) {
	defer dst.Close()
	defer src.Close()
	defer logger.Printf("closed pipe: %s:%s <- %s:%s", dst.RemoteAddr().Network(), dst.RemoteAddr().String(), src.RemoteAddr().Network(), src.RemoteAddr().String())
	logger.Printf("opening pipe: %s:%s <- %s:%s", dst.RemoteAddr().Network(), dst.RemoteAddr().String(), src.RemoteAddr().Network(), src.RemoteAddr().String())

	_, err := io.Copy(dst, src)

	if err != nil {
		logger.Printf("%s", err)
	}
}

// Parse a string representing a TCP address or UNIX socket for our backend
// target. The input can be or the form "HOST:PORT" for TCP or "unix:PATH"
// for a UNIX socket.
func parseUnixOrTCPAddress(input string) (network, address, host string, err error) {
	if strings.HasPrefix(input, "unix:") {
		network = "unix"
		address = input[5:]
		return
	}

	host, _, err = net.SplitHostPort(input)
	if err != nil {
		return
	}

	var tcp *net.TCPAddr
	tcp, err = net.ResolveTCPAddr("tcp", input)
	if err != nil {
		return
	}

	network, address = "tcp", tcp.String()
	return
}
<commit_msg>Better handshake timeout logic (via SetDeadline)<commit_after>/*-
 * Copyright 2015 Square 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 main

import (
	"crypto/tls"
	"io"
	"net"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/rcrowley/go-metrics"
)

type proxy struct {
	quit     int32
	listener net.Listener
	handlers *sync.WaitGroup
	dial     func() (net.Conn, error)
}

var (
	openCounter    = metrics.GetOrRegisterCounter("conn.open", metrics.DefaultRegistry)
	totalCounter   = metrics.GetOrRegisterCounter("accept.total", metrics.DefaultRegistry)
	successCounter = metrics.GetOrRegisterCounter("accept.success", metrics.DefaultRegistry)
	errorCounter   = metrics.GetOrRegisterCounter("accept.error", metrics.DefaultRegistry)
	timeoutCounter = metrics.GetOrRegisterCounter("accept.timeout", metrics.DefaultRegistry)
	connTimer      = metrics.GetOrRegisterTimer("conn.lifetime", metrics.DefaultRegistry)
)

// Accept incoming connections in server mode and spawn Go routines to handle them.
// The signal handler (serverSignalHandle) can close the listener socket and
// send true to the stopper channel. When that happens, we stop accepting new
// connections and wait for outstanding connections to end.
func (p *proxy) accept() {
	for {
		// Wait for new connection
		conn, err := p.listener.Accept()
		if err != nil {
			// Check if we're supposed to stop
			if atomic.LoadInt32(&p.quit) == 1 {
				return
			}

			errorCounter.Inc(1)
			continue
		}

		openCounter.Inc(1)
		totalCounter.Inc(1)

		go connTimer.Time(func() {
			defer conn.Close()
			defer openCounter.Dec(1)

			err := forceHandshake(conn)
			if err != nil {
				logger.Printf("error on TLS handshake from %s: %s", conn.RemoteAddr(), err)
				return
			}

			backend, err := p.dial()
			if err != nil {
				logger.Printf("%s", err)
				return
			}

			successCounter.Inc(1)
			p.handlers.Add(1)
			defer p.handlers.Done()
			fuse(conn, backend)
		})
	}
}

// Force handshake. Handshake usually happens on first read/write, but we
// want to force it to make sure we can control the timeout for it.
// Otherwise, unauthenticated clients would be able to open connections
// and leave them hanging forever. Going through the handshake verifies
// that clients have a valid client cert and are allowed to talk to us.
func forceHandshake(conn net.Conn) (err error) {
	if tlsConn, ok := conn.(*tls.Conn); ok {
		// Set deadline to avoid blocking forever
		tlsConn.SetDeadline(time.Now().Add(*timeoutDuration))

		err = tlsConn.Handshake()
		if err == nil {
			// Success: clear deadline
			tlsConn.SetDeadline(time.Time{})
		}
		if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
			// If we timed out, increment timeout metric
			timeoutCounter.Inc(1)
		}
	}
	return
}

// Fuse connections together
func fuse(client, backend net.Conn) {
	// Copy from client -> backend, and from backend -> client
	go func() { copyData(client, backend) }()
	copyData(backend, client)
}

// Copy data between two connections
func copyData(dst net.Conn, src net.Conn) {
	defer dst.Close()
	defer src.Close()
	defer logger.Printf("closed pipe: %s:%s <- %s:%s", dst.RemoteAddr().Network(), dst.RemoteAddr().String(), src.RemoteAddr().Network(), src.RemoteAddr().String())
	logger.Printf("opening pipe: %s:%s <- %s:%s", dst.RemoteAddr().Network(), dst.RemoteAddr().String(), src.RemoteAddr().Network(), src.RemoteAddr().String())

	_, err := io.Copy(dst, src)

	if err != nil {
		logger.Printf("%s", err)
	}
}

// Parse a string representing a TCP address or UNIX socket for our backend
// target. The input can be or the form "HOST:PORT" for TCP or "unix:PATH"
// for a UNIX socket.
func parseUnixOrTCPAddress(input string) (network, address, host string, err error) {
	if strings.HasPrefix(input, "unix:") {
		network = "unix"
		address = input[5:]
		return
	}

	host, _, err = net.SplitHostPort(input)
	if err != nil {
		return
	}

	var tcp *net.TCPAddr
	tcp, err = net.ResolveTCPAddr("tcp", input)
	if err != nil {
		return
	}

	network, address = "tcp", tcp.String()
	return
}
<|endoftext|>


<commit_before>package nth

import "sort"

// Element finds the nth rank ordered element and ensures it is at the nth
// position.
func Element(data sort.Interface, n int) {
	if n < 0 || n >= data.Len() {
		return
	}
	sort.Sort(data)
}
<commit_msg>Implement quick select<commit_after>package nth

import "sort"

// Element finds the nth rank ordered element and ensures it is at the nth
// position.
func Element(data sort.Interface, n int) {
	l := data.Len()
	if n < 0 || n >= l {
		return
	}
	quickSelect(data, n, 0, l)
}

func quickSelect(data sort.Interface, n, a, b int) {
	pivot := a
	for i := a + 1; i < b; i++ {
		if data.Less(i, pivot) { // data[i] < data[pivot]
			// data[i] needs to be before data[pivot]
			data.Swap(pivot, i)
			pivot++
			data.Swap(pivot, i)
		}
	}
	if a+n < pivot {
		quickSelect(data, n, a, pivot)
	} else if pivot < a+n {
		quickSelect(data, a+n-pivot-1, pivot+1, b)
	}
}
<|endoftext|>


<commit_before>// A library to fetch Our Daily Bread online and parse it
package odb

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/saintfish/bible.go/bible"
	"github.com/saintfish/brave"
	"net/http"
	"regexp"
	"strings"
)

// The metadata of a odb page
type Post struct {
	Year, Month, Day int
	Url              string
	Title            string
	BibleVerse       string
	BibleVerseRef    bible.RefRangeList
	GoldenVerse      string
	Passages         []string
	Poem             []string
	Thought          string
}

// Language of odb website
type Language int

const (
	English Language = iota
	SimplifiedChinese
	TraditionalChinese
)

type param struct {
	domain                        string
	bibleBoxPrefix, bibleBoxSplit string
	refParser                     func(string) bible.RefRangeList
}

var languageParamMap = map[Language]param{
	English: param{
		domain:         "odb.org",
		bibleBoxPrefix: "Read: ",
		bibleBoxSplit:  " | Bible in a Year: ",
	},
	SimplifiedChinese: param{
		domain:         "simplified-odb.org",
		bibleBoxPrefix: "读经: ",
		bibleBoxSplit:  " | 全年读经: ",
		refParser:      parseChineseRef,
	},
	TraditionalChinese: param{
		domain:         "traditional-odb.org",
		bibleBoxPrefix: "讀經: ",
		bibleBoxSplit:  " | 全年讀經: ",
		refParser:      parseChineseRef,
	},
}

// Odb represents an odb website accessor
type Odb struct {
	param
	httpClient *http.Client
}

// Create an accessor to a odb website in a specific language
func NewOdb(l Language) *Odb {
	return &Odb{languageParamMap[l], &http.Client{}}
}

func NewOdbWithHttpClient(l Language, c *http.Client) *Odb {
	return &Odb{languageParamMap[l], c}
}

// Get a post in specific date
func (odb *Odb) GetPost(year, month, day int) (*Post, error) {
	calendarUrl := fmt.Sprintf("http://%s/%4d/%02d/%02d?calendar-redirect=true", odb.domain, year, month, day)
	q, err := fetch(odb.httpClient, calendarUrl)
	if err != nil {
		return nil, fmt.Errorf("error in crawl post page %s: #v", calendarUrl, err)
	}
	title := text(q.Find("h2.entry-title"))
	goldenVerse := text(q.Find(".verse-box"))
	bibleBox := text(q.Find(".passage-box"))
	bibleVerse := ""
	if strings.HasPrefix(bibleBox, odb.bibleBoxPrefix) {
		bibleVerse, _ = token(bibleBox[len(odb.bibleBoxPrefix):], odb.bibleBoxSplit)
	}
	passages := []string{}
	q.Find(".post-content > p").Each(func(_ int, s *goquery.Selection) {
		passages = append(passages, text(s))
	})
	poemText, _ := q.Find(".entry-content .poem-box").Html()
	poem := splitParagraphs(poemText)
	thought := text(q.Find(".entry-content .thought-box"))

	var bibleVerseRef bible.RefRangeList
	if odb.refParser != nil {
		bibleVerseRef = odb.refParser(bibleVerse)
	}

	p := &Post{
		Year:          year,
		Month:         month,
		Day:           day,
		Url:           q.Url.String(),
		Title:         title,
		BibleVerse:    bibleVerse,
		BibleVerseRef: bibleVerseRef,
		GoldenVerse:   goldenVerse,
		Passages:      passages,
		Poem:          poem,
		Thought:       thought,
	}
	return p, nil
}

func fetch(c *http.Client, url string) (*goquery.Document, error) {
	res, err := c.Get(url)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("Unsuccessful status code %d", res.StatusCode)
	}
	q, err := goquery.NewDocumentFromReader(res.Body)
	if err != nil {
		return nil, err
	}
	q.Url = res.Request.URL
	return q, nil
}

func text(q *goquery.Selection) string {
	return strings.Trim(q.Text(), "\u2029 \n\t")
}

func token(s, sep string) (token, remainder string) {
	split := strings.SplitN(s, sep, 2)
	if len(split) < 2 {
		return "", split[0]
	}
	return split[0], split[1]
}

var newLine = regexp.MustCompile("((\\s|\u2029)*<br\\s*/?>(\\s|\u2029)*)+")

func splitParagraphs(html string) []string {
	result := []string{}
	for _, s := range newLine.Split(html, -1) {
		if len(s) != 0 {
			result = append(result, s)
		}
	}
	return result
}

func parseChineseRef(verse string) bible.RefRangeList {
	refMatch, verseRef := brave.ParseChineseFull(verse)
	if !refMatch {
		return nil
	}
	return verseRef
}
<commit_msg>Fix verse parsing. Odb changed their translation.<commit_after>// A library to fetch Our Daily Bread online and parse it
package odb

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/saintfish/bible.go/bible"
	"github.com/saintfish/brave"
	"net/http"
	"regexp"
	"strings"
)

// The metadata of a odb page
type Post struct {
	Year, Month, Day int
	Url              string
	Title            string
	BibleVerse       string
	BibleVerseRef    bible.RefRangeList
	GoldenVerse      string
	Passages         []string
	Poem             []string
	Thought          string
}

// Language of odb website
type Language int

const (
	English Language = iota
	SimplifiedChinese
	TraditionalChinese
)

type param struct {
	domain                        string
	bibleBoxPrefix, bibleBoxSplit string
	refParser                     func(string) bible.RefRangeList
}

var languageParamMap = map[Language]param{
	English: param{
		domain:         "odb.org",
		bibleBoxPrefix: "Read: ",
		bibleBoxSplit:  " | Bible in a Year: ",
	},
	SimplifiedChinese: param{
		domain:         "simplified-odb.org",
		bibleBoxPrefix: "读经: ",
		bibleBoxSplit:  " | 全年读经进度: ",
		refParser:      parseChineseRef,
	},
	TraditionalChinese: param{
		domain:         "traditional-odb.org",
		bibleBoxPrefix: "讀經: ",
		bibleBoxSplit:  " | 全年讀經進度: ",
		refParser:      parseChineseRef,
	},
}

// Odb represents an odb website accessor
type Odb struct {
	param
	httpClient *http.Client
}

// Create an accessor to a odb website in a specific language
func NewOdb(l Language) *Odb {
	return &Odb{languageParamMap[l], &http.Client{}}
}

func NewOdbWithHttpClient(l Language, c *http.Client) *Odb {
	return &Odb{languageParamMap[l], c}
}

// Get a post in specific date
func (odb *Odb) GetPost(year, month, day int) (*Post, error) {
	calendarUrl := fmt.Sprintf("http://%s/%4d/%02d/%02d?calendar-redirect=true", odb.domain, year, month, day)
	q, err := fetch(odb.httpClient, calendarUrl)
	if err != nil {
		return nil, fmt.Errorf("error in crawl post page %s: #v", calendarUrl, err)
	}
	title := text(q.Find("h2.entry-title"))
	goldenVerse := text(q.Find(".verse-box"))
	bibleBox := text(q.Find(".passage-box"))
	bibleVerse := ""
	if strings.HasPrefix(bibleBox, odb.bibleBoxPrefix) {
		bibleVerse, _ = token(bibleBox[len(odb.bibleBoxPrefix):], odb.bibleBoxSplit)
		bibleVerse = strings.Trim(bibleVerse, "\u2029 \n\t")
	}
	passages := []string{}
	q.Find(".post-content > p").Each(func(_ int, s *goquery.Selection) {
		passages = append(passages, text(s))
	})
	poemText, _ := q.Find(".entry-content .poem-box").Html()
	poem := splitParagraphs(poemText)
	thought := text(q.Find(".entry-content .thought-box"))

	var bibleVerseRef bible.RefRangeList
	if odb.refParser != nil {
		bibleVerseRef = odb.refParser(bibleVerse)
	}

	p := &Post{
		Year:          year,
		Month:         month,
		Day:           day,
		Url:           q.Url.String(),
		Title:         title,
		BibleVerse:    bibleVerse,
		BibleVerseRef: bibleVerseRef,
		GoldenVerse:   goldenVerse,
		Passages:      passages,
		Poem:          poem,
		Thought:       thought,
	}
	return p, nil
}

func (odb *Odb) SetBibleVerse(p *Post, bibleVerse string) {
	p.BibleVerse = bibleVerse
	if odb.refParser != nil {
		p.BibleVerseRef = odb.refParser(bibleVerse)
	}
}

func fetch(c *http.Client, url string) (*goquery.Document, error) {
	res, err := c.Get(url)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("Unsuccessful status code %d", res.StatusCode)
	}
	q, err := goquery.NewDocumentFromReader(res.Body)
	if err != nil {
		return nil, err
	}
	q.Url = res.Request.URL
	return q, nil
}

func text(q *goquery.Selection) string {
	return strings.Trim(q.Text(), "\u2029 \n\t")
}

func token(s, sep string) (token, remainder string) {
	split := strings.SplitN(s, sep, 2)
	if len(split) < 2 {
		return "", split[0]
	}
	return split[0], split[1]
}

var newLine = regexp.MustCompile("((\\s|\u2029)*<br\\s*/?>(\\s|\u2029)*)+")

func splitParagraphs(html string) []string {
	result := []string{}
	for _, s := range newLine.Split(html, -1) {
		if len(s) != 0 {
			result = append(result, s)
		}
	}
	return result
}

func parseChineseRef(verse string) bible.RefRangeList {
	refMatch, verseRef := brave.ParseChineseFull(verse)
	if !refMatch {
		return nil
	}
	return verseRef
}
<|endoftext|>


<commit_before>// Copyright 2014 Vasco Costa. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package owm implements a wrapper for the OpenWeatherMap API.
//
// Read more about the OpenWeatherMap API here: http://openweathermap.org/api.
package owm

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

type weatherLine struct {
	Id          int
	Main        string
	Description string
	Icon        string
}

// Weather represents the current weather at a specific location.
//
// It is returned by the WeatherBy* methods of Client.
type Weather struct {
	Coord struct {
		Lat float64
		Lon float64
	}
	Sys struct {
		Type    int
		Id      int
		Country string
		Sunrise int
		Sunset  int
	}
	Weather []weatherLine
	Base    string
	Main    struct {
		Temp      float64
		Humidity  int
		TempMin   float64 `json:"temp_min"`
		TempMax   float64 `json:"temp_max"`
		Pressure  float64
		SeaLevel  float64 `json:"sea_level"`
		GrndLevel float64 `json:"grnd_level"`
	}
	Wind struct {
		Speed float64
		Deg   float64
		Gust  float64
	}
	Clouds struct {
		All int
	}
	Dt   int
	Id   int
	Name string
	Cod  int
}

type weatherSet struct {
	Cnt     int
	Weather []Weather `json:"list"`
}

// Forecast represents the weather forecast for a specific location.
//
// It is returned by the ForecastBy* methods of Client.
type Forecast struct {
	Cod  string
	City struct {
		Id    int
		Name  string
		Coord struct {
			Lon float64
			Lat float64
		}
		Country string
	}
	Cnt     int
	Weather []Weather `json:"list"`
}

// Client represents an OpenWeatherMap API client.
type Client struct {
	key     string
	baseURL string
}

// NewClient returns a new Client given an API key.
//
// Pass an empty string as the key argument to use the client without an API key.
func NewClient(key string) *Client {
	return &Client{key, "http://api.openweathermap.org/data/2.5/"}
}

func (c *Client) data(url string) (data []byte, err error) {
	res, err := http.Get(url)
	if err != nil {
		err = errors.New("owm: error while fetching weather data")
		return
	}
	data, err = ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		err = errors.New("owm: error while fetching weather data")
		return
	}
	return
}

func (c *Client) weather(url string) (w Weather, err error) {
	if c.key != "" {
		url += "&APPID=" + c.key
	}
	data, err := c.data(url)
	if err != nil || strings.Contains(string(data), `"cod":"404"`) {
		err = errors.New("owm: error while fetching weather data")
		return
	}
	err = json.Unmarshal(data, &w)
	if err != nil {
		err = errors.New("owm: error while decoding weather data")
		return
	}
	return
}

func (c *Client) weatherSet(url string) (ws weatherSet, err error) {
	if c.key != "" {
		url += "&APPID=" + c.key
	}
	data, err := c.data(url)
	if err != nil || strings.Contains(string(data), `"cod":"404"`) {
		err = errors.New("owm: error while fetching weather data")
		return
	}
	err = json.Unmarshal(data, &ws)
	if err != nil {
		err = errors.New("owm: error while decoding weather data")
		return
	}
	return
}

func (c *Client) forecast(url string) (f Forecast, err error) {
	if c.key != "" {
		url += "&APPID=" + c.key
	}
	data, err := c.data(url)
	if err != nil || strings.Contains(string(data), `"cod":"404"`) {
		err = errors.New("owm: error while fetching forecast data")
		return
	}
	err = json.Unmarshal(data, &f)
	if err != nil {
		err = errors.New("owm: error while decoding forecast data")
		return
	}
	return
}

// WeatherByName decodes the current weather of a location given the city name
// and units. It uses the corresponding web API URL to fetch JSON encoded data
// and returns a Weather with as much fields decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByName(name string, units string) (w Weather, err error) {
	w, err = c.weather(c.baseURL +
		"weather" +
		"?q=" + name +
		"&units=" + units)
	return
}

// WeatherById decodes the current weather of a location given the city id and
// units. It uses the corresponding web API URL to fetch JSON encoded data and
// returns a Weather with as much fields decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherById(id int, units string) (w Weather, err error) {
	w, err = c.weather(c.baseURL +
		"weather" +
		"?id=" + strconv.Itoa(id) +
		"&units=" + units)
	return
}

// WeatherByCoord decodes the current weather of a location given the city
// coordinates and units. It uses the corresponding web API URL to fetch JSON
// encoded data and returns a Weather with as much fields decoded as those
// available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByCoord(lat, lon float64, units string) (w Weather, err error) {
	w, err = c.weather(c.baseURL +
		"weather" +
		"?lat=" + strconv.FormatFloat(lat, 'f', 2, 64) +
		"&lon=" + strconv.FormatFloat(lon, 'f', 2, 64) +
		"&units=" + units)
	return
}

// WeatherByZone decodes the current weather of multiple locations given the
// zone coordinates, map zoom and units. It uses the corresponding web API URL
// to fetch JSON encoded data and returns a []Weather with as much fields
// decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByZone(lat1, lon1, lat2, lon2 float64, zoom int, units string) (w []Weather, err error) {
	ws, err := c.weatherSet(c.baseURL +
		"box/city" +
		"?bbox=" +
		strconv.FormatFloat(lat1, 'f', 2, 64) + "," +
		strconv.FormatFloat(lon1, 'f', 2, 64) + "," +
		strconv.FormatFloat(lat2, 'f', 2, 64) + "," +
		strconv.FormatFloat(lon2, 'f', 2, 64) + "," +
		strconv.Itoa(zoom) +
		"&units=" + units)
	w = ws.Weather
	return
}

// WeatherByRadius decodes the current weather of multiple locations given the
// center coordinates, radius and units. It uses the corresponding web API URL
// to fetch JSON encoded data and returns a []Weather with as much fields
// decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByRadius(lat, lon, radius float64, units string) (w []Weather, err error) {
	ws, err := c.weatherSet(c.baseURL +
		"find" +
		"?lat=" + strconv.FormatFloat(lat, 'f', 2, 64) + "," +
		"&lon=" + strconv.FormatFloat(lon, 'f', 2, 64) + "," +
		"&cnt=" + strconv.FormatFloat(radius, 'f', 2, 64) +
		"&units=" + units)
	w = ws.Weather
	return
}

// WeatherByIds decodes the current weather of multiple locations given the a
// slice of city ids and units. It uses the corresponding web API URL to fetch
// JSON encoded data and returns a []Weather with as much fields decoded fields
// as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByIds(id []int, units string) (w []Weather, err error) {
	var ids string
	for i := range id {
		ids += strconv.Itoa(id[i]) + ","
	}
	ws, err := c.weatherSet(c.baseURL +
		"group" +
		"?id=" + ids[:len(ids)-1] +
		"&units=" + units)
	w = ws.Weather
	return
}

// ForecastByName decodes the current forecast given the city name and the units.
func (c *Client) ForecastByName(name string, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast" +
		"?q=" + name +
		"&units=" + units)
	return
}

// ForecastById decodes the current forecast given the city id and the units.
func (c *Client) ForecastById(id int, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast" +
		"?id=" + strconv.Itoa(id) +
		"&units=" + units)
	return
}

// ForecastByCoord decodes the current forecast given the city coordinates and the units.
func (c *Client) ForecastByCoord(lat, lon float64, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast" +
		"?lat=" + strconv.FormatFloat(lat, 'f', 2, 64) +
		"&lon=" + strconv.FormatFloat(lon, 'f', 2, 64) +
		"&units=" + units)
	return
}

// DailyForecastByName decodes the daily forecast given the city name, number of days  and units.
func (c *Client) DailyForecastByName(name string, days int, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast/daily" +
		"?q=" + name +
		"&cnt=" + strconv.Itoa(days) +
		"&units=" + units)
	return
}

// DailyForecastById decodes the daily forecast given the city id, number of days and units.
func (c *Client) DailyForecastById(id, days int, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast/daily" +
		"?id=" + strconv.Itoa(id) +
		"&cnt=" + strconv.Itoa(days) +
		"&units=" + units)
	return
}

// DailyForecastByCoord decodes the daily forecast given the city coordinates, number of days and units.
func (c *Client) DailyForecastByCoord(lat, lon float64, days int, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast/daily" +
		"?lat=" + strconv.FormatFloat(lat, 'f', 2, 64) +
		"&lon=" + strconv.FormatFloat(lon, 'f', 2, 64) +
		"&cnt=" + strconv.Itoa(days) +
		"&units=" + units)
	return
}
<commit_msg>fixed comments<commit_after>// Copyright 2014 Vasco Costa. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package owm implements a wrapper for the OpenWeatherMap API.
//
// Read more about the OpenWeatherMap API here: http://openweathermap.org/api.
package owm

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

type weatherLine struct {
	Id          int
	Main        string
	Description string
	Icon        string
}

// Weather represents the current weather at a specific location.
//
// It is returned by the WeatherBy* methods of Client.
type Weather struct {
	Coord struct {
		Lat float64
		Lon float64
	}
	Sys struct {
		Type    int
		Id      int
		Country string
		Sunrise int
		Sunset  int
	}
	Weather []weatherLine
	Base    string
	Main    struct {
		Temp      float64
		Humidity  int
		TempMin   float64 `json:"temp_min"`
		TempMax   float64 `json:"temp_max"`
		Pressure  float64
		SeaLevel  float64 `json:"sea_level"`
		GrndLevel float64 `json:"grnd_level"`
	}
	Wind struct {
		Speed float64
		Deg   float64
		Gust  float64
	}
	Clouds struct {
		All int
	}
	Dt   int
	Id   int
	Name string
	Cod  int
}

type weatherSet struct {
	Cnt     int
	Weather []Weather `json:"list"`
}

// Forecast represents the weather forecast for a specific location.
//
// It is returned by the ForecastBy* methods of Client.
type Forecast struct {
	Cod  string
	City struct {
		Id    int
		Name  string
		Coord struct {
			Lon float64
			Lat float64
		}
		Country string
	}
	Cnt     int
	Weather []Weather `json:"list"`
}

// Client represents an OpenWeatherMap API client.
type Client struct {
	key     string
	baseURL string
}

// NewClient returns a new Client given an API key.
//
// Pass an empty string as the key argument to use the client without an API key.
func NewClient(key string) *Client {
	return &Client{key, "http://api.openweathermap.org/data/2.5/"}
}

func (c *Client) data(url string) (data []byte, err error) {
	res, err := http.Get(url)
	if err != nil {
		err = errors.New("owm: error while fetching weather data")
		return
	}
	data, err = ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		err = errors.New("owm: error while fetching weather data")
		return
	}
	return
}

func (c *Client) weather(url string) (w Weather, err error) {
	if c.key != "" {
		url += "&APPID=" + c.key
	}
	data, err := c.data(url)
	if err != nil || strings.Contains(string(data), `"cod":"404"`) {
		err = errors.New("owm: error while fetching weather data")
		return
	}
	err = json.Unmarshal(data, &w)
	if err != nil {
		err = errors.New("owm: error while decoding weather data")
		return
	}
	return
}

func (c *Client) weatherSet(url string) (ws weatherSet, err error) {
	if c.key != "" {
		url += "&APPID=" + c.key
	}
	data, err := c.data(url)
	if err != nil || strings.Contains(string(data), `"cod":"404"`) {
		err = errors.New("owm: error while fetching weather data")
		return
	}
	err = json.Unmarshal(data, &ws)
	if err != nil {
		err = errors.New("owm: error while decoding weather data")
		return
	}
	return
}

func (c *Client) forecast(url string) (f Forecast, err error) {
	if c.key != "" {
		url += "&APPID=" + c.key
	}
	data, err := c.data(url)
	if err != nil || strings.Contains(string(data), `"cod":"404"`) {
		err = errors.New("owm: error while fetching forecast data")
		return
	}
	err = json.Unmarshal(data, &f)
	if err != nil {
		err = errors.New("owm: error while decoding forecast data")
		return
	}
	return
}

// WeatherByName decodes the current weather of a location given the city name
// and units. It uses the corresponding web API URL to fetch JSON encoded data
// and returns a Weather with as much fields decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByName(name string, units string) (w Weather, err error) {
	w, err = c.weather(c.baseURL +
		"weather" +
		"?q=" + name +
		"&units=" + units)
	return
}

// WeatherById decodes the current weather of a location given the city id and
// units. It uses the corresponding web API URL to fetch JSON encoded data and
// returns a Weather with as much fields decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherById(id int, units string) (w Weather, err error) {
	w, err = c.weather(c.baseURL +
		"weather" +
		"?id=" + strconv.Itoa(id) +
		"&units=" + units)
	return
}

// WeatherByCoord decodes the current weather of a location given the city
// coordinates and units. It uses the corresponding web API URL to fetch JSON
// encoded data and returns a Weather with as much fields decoded as those
// available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByCoord(lat, lon float64, units string) (w Weather, err error) {
	w, err = c.weather(c.baseURL +
		"weather" +
		"?lat=" + strconv.FormatFloat(lat, 'f', 2, 64) +
		"&lon=" + strconv.FormatFloat(lon, 'f', 2, 64) +
		"&units=" + units)
	return
}

// WeatherByZone decodes the current weather of multiple locations given the
// zone coordinates, map zoom and units. It uses the corresponding web API URL
// to fetch JSON encoded data and returns a []Weather with as much fields
// decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByZone(lat1, lon1, lat2, lon2 float64, zoom int, units string) (w []Weather, err error) {
	ws, err := c.weatherSet(c.baseURL +
		"box/city" +
		"?bbox=" +
		strconv.FormatFloat(lat1, 'f', 2, 64) + "," +
		strconv.FormatFloat(lon1, 'f', 2, 64) + "," +
		strconv.FormatFloat(lat2, 'f', 2, 64) + "," +
		strconv.FormatFloat(lon2, 'f', 2, 64) + "," +
		strconv.Itoa(zoom) +
		"&units=" + units)
	w = ws.Weather
	return
}

// WeatherByRadius decodes the current weather of multiple locations given the
// center coordinates, radius and units. It uses the corresponding web API URL
// to fetch JSON encoded data and returns a []Weather with as much fields
// decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByRadius(lat, lon, radius float64, units string) (w []Weather, err error) {
	ws, err := c.weatherSet(c.baseURL +
		"find" +
		"?lat=" + strconv.FormatFloat(lat, 'f', 2, 64) + "," +
		"&lon=" + strconv.FormatFloat(lon, 'f', 2, 64) + "," +
		"&cnt=" + strconv.FormatFloat(radius, 'f', 2, 64) +
		"&units=" + units)
	w = ws.Weather
	return
}

// WeatherByIds decodes the current weather of multiple locations given the a
// slice of city ids and units. It uses the corresponding web API URL to fetch
// JSON encoded data and returns a []Weather with as much fields decoded fields
// as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) WeatherByIds(id []int, units string) (w []Weather, err error) {
	var ids string
	for i := range id {
		ids += strconv.Itoa(id[i]) + ","
	}
	ws, err := c.weatherSet(c.baseURL +
		"group" +
		"?id=" + ids[:len(ids)-1] +
		"&units=" + units)
	w = ws.Weather
	return
}

// ForecastByName decodes the current forecast of a location given the city name
// and units. It uses the corresponding web API URL to fetch JSON encoded data
// and returns a Forecast with as much fields decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) ForecastByName(name string, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast" +
		"?q=" + name +
		"&units=" + units)
	return
}

// ForecastById decodes the current forecast of a location given the city id
// and units. It uses the corresponding web API URL to fetch JSON encoded data
// and returns a Forecast with as much fields decoded as those available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) ForecastById(id int, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast" +
		"?id=" + strconv.Itoa(id) +
		"&units=" + units)
	return
}

// ForecastByCoord decodes the current forecast of a location given the city
// coordinates and units. It uses the corresponding web API URL to fetch JSON
// encoded data and returns a Forecast with as much fields decoded as those
// available.
//
// An error is returned if there is a problem while fetching weather data from
// the web API or decoding the weather data.
func (c *Client) ForecastByCoord(lat, lon float64, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast" +
		"?lat=" + strconv.FormatFloat(lat, 'f', 2, 64) +
		"&lon=" + strconv.FormatFloat(lon, 'f', 2, 64) +
		"&units=" + units)
	return
}

// DailyForecastByName decodes the daily forecast given the city name, number of days  and units.
func (c *Client) DailyForecastByName(name string, days int, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast/daily" +
		"?q=" + name +
		"&cnt=" + strconv.Itoa(days) +
		"&units=" + units)
	return
}

// DailyForecastById decodes the daily forecast given the city id, number of days and units.
func (c *Client) DailyForecastById(id, days int, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast/daily" +
		"?id=" + strconv.Itoa(id) +
		"&cnt=" + strconv.Itoa(days) +
		"&units=" + units)
	return
}

// DailyForecastByCoord decodes the daily forecast given the city coordinates, number of days and units.
func (c *Client) DailyForecastByCoord(lat, lon float64, days int, units string) (f Forecast, err error) {
	f, err = c.forecast(c.baseURL +
		"forecast/daily" +
		"?lat=" + strconv.FormatFloat(lat, 'f', 2, 64) +
		"&lon=" + strconv.FormatFloat(lon, 'f', 2, 64) +
		"&cnt=" + strconv.Itoa(days) +
		"&units=" + units)
	return
}
<|endoftext|>


<commit_before>package leftpad

// PadLeft takes the inputs string src and returns a new string with len length
// padded by the string padding
func PadLeft(src, padding string, length int) string {
	for {
		src = padding + src
		if len(src) > length-1 {
			return src[0:length]
		}
	}
}
<commit_msg>Cleaning up the docs<commit_after>package leftpad

// PadLeft takes the input string src and returns a string of length 'length'
// padded by the string padding
func PadLeft(src, padding string, length int) string {
	for {
		src = padding + src
		if len(src) > length-1 {
			return src[0:length]
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	"github.com/codegangsta/cli"
	"github.com/missinglink/pbf/command"
)

func main() {
	app := cli.NewApp()
	app.Name = "pbf"
	app.Usage = "utilities for parsing OpenStreetMap PBF files and extracting geographic data"
	app.Commands = []cli.Command{
		{
			Name:   "stats",
			Usage:  "pbf statistics",
			Flags:  []cli.Flag{cli.IntFlag{Name: "interval, i", Usage: "write stats every i milliseconds"}},
			Action: command.Stats,
		},
		{
			Name:   "json",
			Usage:  "convert to overpass json format, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action: command.JSON,
		},
		{
			Name:   "xml",
			Usage:  "convert to osm xml format, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action: command.XML,
		},
		{
			Name:   "opl",
			Usage:  "convert to opl, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action: command.OPL,
		},
		{
			Name:        "nquad",
			Usage:       "convert to nquad, optionally using bitmask to filter elements",
			Description: "the output can be imported in to dgraph using the dgraphloader utility",
			Flags:       []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action:      command.Nquad,
		},
		{
			Name:        "cypher",
			Usage:       "convert to cypher format used by the neo4j graph database, optionally using bitmask to filter elements",
			Description: "the output can be piped directly in to neo4j: `cmd | neo4j-shell -file -`",
			Flags:       []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action:      command.Cypher,
		},
		{
			Name:   "sqlite3",
			Usage:  "import elements in to sqlite3 database, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only import element ids in bitmask"}},
			Action: command.Sqlite3,
		},
		{
			Name:   "leveldb",
			Usage:  "import elements in to leveldb database, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only import element ids in bitmask"}},
			Action: command.LevelDB,
		},
		{
			Name:  "pelias",
			Usage: "convert to overpass pelias format, compulsorily using bitmask to filter elements",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"},
				cli.StringFlag{Name: "leveldb, l", Usage: "location of leveldb tmp dir"},
			},
			Action: command.Pelias,
		},
		{
			Name:  "genmask",
			Usage: "generate a bitmask file by specifying feature tags to match",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "config, c", Usage: "read features from config"},
				cli.BoolFlag{Name: "indexing, i", Usage: "also write PBF index file"},
			},
			Action: command.BitmaskCustom,
		},
		{
			Name:   "genmask-boundaries",
			Usage:  "generate a bitmask file containing only elements referenced by a boundary:administrative relation",
			Action: command.BitmaskBoundaries,
		},
		{
			Name:   "genmask-super-relations",
			Usage:  "generate a bitmask file containing only relations which have at least one another relation as a member",
			Action: command.BitmaskSuperRelations,
		},
		{
			Name:   "bitmask-stats",
			Usage:  "output statistics for a bitmask file",
			Action: command.BitmaskStats,
		},
		{
			Name:  "store-noderefs",
			Usage: "store all node refs in leveldb for records matching bitmask",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "bitmask, m", Usage: "only store refs in bitmask"},
				cli.StringFlag{Name: "leveldb, l", Usage: "location of leveldb tmp dir"},
			},
			Action: command.StoreNodeRefs,
		},
		{
			Name:   "boundaries",
			Usage:  "write geojson osm boundary files using a leveldb database as source",
			Action: command.BoundaryExporter,
		},
		{
			Name:   "xroads",
			Usage:  "compute street intersections",
			Action: command.Crossroads,
		},
		{
			Name:   "streets",
			Usage:  "compute a graph of street",
			Action: command.StreetGraph,
		},
		{
			Name:   "noderefs",
			Usage:  "count the number of times a nodeid is referenced in file",
			Action: command.NodeRefs,
		},
		{
			Name:   "index",
			Usage:  "index a pbf file and write index to disk",
			Action: command.PbfIndex,
		},
		{
			Name:   "index-info",
			Usage:  "display a visual representation of the index file",
			Action: command.PbfIndexInfo,
		},
		// {
		// 	Name:   "find",
		// 	Usage:  "random access to pbf",
		// 	Flags:  []cli.Flag{cli.BoolFlag{Name: "recurse, r", Usage: "output child elements recursively"}},
		// 	Action: command.RandomAccess,
		// },
	}

	app.Run(os.Args)
}
<commit_msg>cli: clean up --help<commit_after>package main

import (
	"os"

	"github.com/codegangsta/cli"
	"github.com/missinglink/pbf/command"
)

func main() {
	app := cli.NewApp()
	app.Name = "pbf"
	app.Usage = "utilities for parsing OpenStreetMap PBF files and extracting geographic data"
	app.Commands = []cli.Command{
		{
			Name:   "stats",
			Usage:  "pbf statistics",
			Flags:  []cli.Flag{cli.IntFlag{Name: "interval, i", Usage: "write stats every i milliseconds"}},
			Action: command.Stats,
		},
		{
			Name:   "json",
			Usage:  "convert to overpass json format, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action: command.JSON,
		},
		{
			Name:   "xml",
			Usage:  "convert to osm xml format, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action: command.XML,
		},
		{
			Name:   "opl",
			Usage:  "convert to opl, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action: command.OPL,
		},
		{
			Name:        "nquad",
			Usage:       "convert to nquad, optionally using bitmask to filter elements",
			Description: "the output can be imported in to dgraph using the dgraphloader utility",
			Flags:       []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action:      command.Nquad,
		},
		{
			Name:        "cypher",
			Usage:       "convert to cypher format used by the neo4j graph database, optionally using bitmask to filter elements",
			Description: "the output can be piped directly in to neo4j: `cmd | neo4j-shell -file -`",
			Flags:       []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"}},
			Action:      command.Cypher,
		},
		{
			Name:   "sqlite3",
			Usage:  "import elements in to sqlite3 database, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only import element ids in bitmask"}},
			Action: command.Sqlite3,
		},
		{
			Name:   "leveldb",
			Usage:  "import elements in to leveldb database, optionally using bitmask to filter elements",
			Flags:  []cli.Flag{cli.StringFlag{Name: "bitmask, m", Usage: "only import element ids in bitmask"}},
			Action: command.LevelDB,
		},
		{
			Name:  "pelias",
			Usage: "convert to overpass pelias format, compulsorily using bitmask to filter elements",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "bitmask, m", Usage: "only output element ids in bitmask"},
			},
			Action: command.Pelias,
		},
		{
			Name:  "genmask",
			Usage: "generate a bitmask file by specifying feature tags to match",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "config, c", Usage: "read features from config"},
				cli.BoolFlag{Name: "indexing, i", Usage: "also write PBF index file"},
			},
			Action: command.BitmaskCustom,
		},
		{
			Name:   "genmask-boundaries",
			Usage:  "generate a bitmask file containing only elements referenced by a boundary:administrative relation",
			Action: command.BitmaskBoundaries,
		},
		{
			Name:   "genmask-super-relations",
			Usage:  "generate a bitmask file containing only relations which have at least one another relation as a member",
			Action: command.BitmaskSuperRelations,
		},
		{
			Name:   "bitmask-stats",
			Usage:  "output statistics for a bitmask file",
			Action: command.BitmaskStats,
		},
		{
			Name:  "store-noderefs",
			Usage: "store all node refs in leveldb for records matching bitmask",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "bitmask, m", Usage: "only store refs in bitmask"},
				cli.StringFlag{Name: "leveldb, l", Usage: "location of leveldb tmp dir"},
			},
			Action: command.StoreNodeRefs,
		},
		{
			Name:   "boundaries",
			Usage:  "write geojson osm boundary files using a leveldb database as source",
			Action: command.BoundaryExporter,
		},
		{
			Name:   "xroads",
			Usage:  "compute street intersections",
			Action: command.Crossroads,
		},
		{
			Name:   "streets",
			Usage:  "compute a graph of street",
			Action: command.StreetGraph,
		},
		{
			Name:   "noderefs",
			Usage:  "count the number of times a nodeid is referenced in file",
			Action: command.NodeRefs,
		},
		{
			Name:   "index",
			Usage:  "index a pbf file and write index to disk",
			Action: command.PbfIndex,
		},
		{
			Name:   "index-info",
			Usage:  "display a visual representation of the index file",
			Action: command.PbfIndexInfo,
		},
		// {
		// 	Name:   "find",
		// 	Usage:  "random access to pbf",
		// 	Flags:  []cli.Flag{cli.BoolFlag{Name: "recurse, r", Usage: "output child elements recursively"}},
		// 	Action: command.RandomAccess,
		// },
	}

	app.Run(os.Args)
}
<|endoftext|>