<commit_before>package analytics

//
// dependencies
//

import "github.com/jehiah/go-strftime"
import "github.com/nu7hatch/gouuid"
import . "encoding/json"
import "net/http"
import "bytes"
import "time"
import "log"

//
// Library version
//

const Version = "0.0.1"

//
// Default API end-point
//

const api = "https://api.segment.io"

//
// Segment.io client
//

type client struct {
	debug      bool
	key        string
	url        string
	flushAt    int
	flushAfter time.Duration
	buffer     []*interface{}
}

//
// Message context library
//

type contextLibrary struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

//
// Message context
//

type context struct {
	Library contextLibrary `json:"library"`
}

//
// Identify message
//

type identify struct {
	Action    string      `json:"action"`
	Traits    interface{} `json:"trailts"`
	Timestamp string      `json:"timestamp"`
}

//
// Alias message
//

type alias struct {
	Action     string `json:"action"`
	PreviousId string `json:"previousId"`
	Timestamp  string `json:"timestamp"`
}

//
// Track message
//

type track struct {
	Action     string      `json:"action"`
	Event      string      `json:"event"`
	Properties interface{} `json:"properties"`
	Timestamp  string      `json:"timestamp"`
}

//
// Group message
//

type group struct {
	Action    string      `json:"action"`
	GroupId   string      `json:"groupId"`
	Traits    interface{} `json:"trailts"`
	Timestamp string      `json:"timestamp"`
}

//
// Page message
//

type page struct {
	Action     string      `json:"action"`
	Category   string      `json:"category"`
	Name       string      `json:"name"`
	Properties interface{} `json:"properties"`
	Timestamp  string      `json:"timestamp"`
}

//
// Batch message
//

type batch struct {
	Context   context        `json:"context"`
	RequestId string         `json:"requestId"`
	Messages  []*interface{} `json:"batch"`
}

//
// Return a new Segment.io client
// with the given write key.
//

func Client(key string) *client {
	return &client{
		key:        key,
		url:        api,
		flushAt:    500,
		flushAfter: 10 * time.Second,
		buffer:     make([]*interface{}, 0),
	}
}

//
// Set buffer max.
//

func (c *client) FlushAt(n int) {
	c.flushAt = n
}

//
// Set buffer flush interal.
//

func (c *client) FlushAfter(interval time.Duration) {
	c.flushAfter = interval
}

//
// Enable debug mode.
//

func (c *client) Debug() {
	c.debug = true
}

//
// Set target url
//

func (c *client) URL(url string) {
	c.url = url
}

//
// Return formatted timestamp.
//

func timestamp() string {
	return strftime.Format("%Y-%m-%dT%H:%M:%S%z", time.Now())
}

// Return a batch message primed
// with context properties
//

func createBatch(msgs []*interface{}) (*batch, error) {
	uid, err := uuid.NewV4()

	if err != nil {
		return nil, err
	}

	batch := &batch{
		RequestId: uid.String(),
		Messages:  msgs,
		Context: context{
			Library: contextLibrary{
				Name:    "analytics-go",
				Version: Version,
			},
		},
	}

	return batch, nil
}

//
// Flush the buffered messages.
//

func (c *client) flush() error {
	b, err := createBatch(c.buffer)

	if err != nil {
		return err
	}

	j, err := Marshal(b)

	if err != nil {
		return err
	}

	c.buffer = nil

	client := &http.Client{}
	req, err := http.NewRequest("POST", c.url+"/v1/batch", bytes.NewBuffer(j))

	if err != nil {
		return err
	}

	req.Header.Add("User-Agent", "analytics-go (version: "+Version+")")
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Content-Length", string(len(j)))
	req.SetBasicAuth(c.key, "")

	res, err := client.Do(req)

	if res != nil {
		// TODO: how the fuck do you ignore res ^
	}

	return err
}

//
// Buffer the given message and flush
// when the buffer exceeds .flushAt.
//

func (c *client) bufferMessage(msg interface{}) error {
	c.buffer = append(c.buffer, &msg)

	if c.debug {
		log.Printf("buffer (%d/%d) %v", len(c.buffer), c.flushAt, msg)
	}

	if len(c.buffer) >= c.flushAt {
		log.Printf("flushing %d messages", len(c.buffer))
		return c.flush()
	}

	return nil
}

//
// Buffer an alias message
//

func (c *client) Alias(previousId string) error {
	return c.bufferMessage(&alias{"Alias", previousId, timestamp()})
}

//
// Buffer a page message
//

func (c *client) Page(name string, category string, properties interface{}) error {
	return c.bufferMessage(&page{"Page", name, category, properties, timestamp()})
}

//
// Buffer a screen message
//

func (c *client) Screen(name string, category string, properties interface{}) error {
	return c.bufferMessage(&page{"Screen", name, category, properties, timestamp()})
}

//
// Buffer a group message
//

func (c *client) Group(id string, traits interface{}) error {
	return c.bufferMessage(&group{"Group", id, traits, timestamp()})
}

//
// Buffer an identify message
//

func (c *client) Identify(traits interface{}) error {
	return c.bufferMessage(&identify{"Identify", traits, timestamp()})
}

//
// Buffer a track message
//

func (c *client) Track(event string, properties interface{}) error {
	return c.bufferMessage(&track{"Track", event, properties, timestamp()})
}
<commit_msg>refactor<commit_after>package analytics

//
// dependencies
//

import "github.com/jehiah/go-strftime"
import "github.com/nu7hatch/gouuid"
import . "encoding/json"
import "net/http"
import "bytes"
import "time"
import "log"

//
// Library version
//

const Version = "0.0.1"

//
// Default API end-point
//

const api = "https://api.segment.io"

//
// Segment.io client
//

type client struct {
	debug      bool
	key        string
	url        string
	flushAt    int
	flushAfter time.Duration
	buffer     []*interface{}
}

//
// Message context library
//

type contextLibrary struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

//
// Message context
//

type context struct {
	Library contextLibrary `json:"library"`
}

//
// Identify message
//

type identify struct {
	Action    string      `json:"action"`
	Traits    interface{} `json:"trailts"`
	Timestamp string      `json:"timestamp"`
}

//
// Alias message
//

type alias struct {
	Action     string `json:"action"`
	PreviousId string `json:"previousId"`
	Timestamp  string `json:"timestamp"`
}

//
// Track message
//

type track struct {
	Action     string      `json:"action"`
	Event      string      `json:"event"`
	Properties interface{} `json:"properties"`
	Timestamp  string      `json:"timestamp"`
}

//
// Group message
//

type group struct {
	Action    string      `json:"action"`
	GroupId   string      `json:"groupId"`
	Traits    interface{} `json:"trailts"`
	Timestamp string      `json:"timestamp"`
}

//
// Page message
//

type page struct {
	Action     string      `json:"action"`
	Category   string      `json:"category"`
	Name       string      `json:"name"`
	Properties interface{} `json:"properties"`
	Timestamp  string      `json:"timestamp"`
}

//
// Batch message
//

type batch struct {
	Context   context        `json:"context"`
	RequestId string         `json:"requestId"`
	Messages  []*interface{} `json:"batch"`
}

//
// Return a new Segment.io client
// with the given write key.
//

func Client(key string) *client {
	return &client{
		key:        key,
		url:        api,
		flushAt:    500,
		flushAfter: 10 * time.Second,
		buffer:     make([]*interface{}, 0),
	}
}

//
// Set buffer max.
//

func (c *client) FlushAt(n int) {
	c.flushAt = n
}

//
// Set buffer flush interal.
//

func (c *client) FlushAfter(interval time.Duration) {
	c.flushAfter = interval
}

//
// Enable debug mode.
//

func (c *client) Debug() {
	c.debug = true
}

//
// Set target url
//

func (c *client) URL(url string) {
	c.url = url
}

//
// Return formatted timestamp.
//

func timestamp() string {
	return strftime.Format("%Y-%m-%dT%H:%M:%S%z", time.Now())
}

// Return a batch message primed
// with context properties
//

func createBatch(msgs []*interface{}) (*batch, error) {
	uid, err := uuid.NewV4()

	if err != nil {
		return nil, err
	}

	batch := &batch{
		RequestId: uid.String(),
		Messages:  msgs,
		Context: context{
			Library: contextLibrary{
				Name:    "analytics-go",
				Version: Version,
			},
		},
	}

	return batch, nil
}

//
// Flush the buffered messages.
//

func (c *client) flush() error {
	b, err := createBatch(c.buffer)

	if err != nil {
		return err
	}

	json, err := Marshal(b)

	if err != nil {
		return err
	}

	c.buffer = nil

	client := &http.Client{}
	req, err := http.NewRequest("POST", c.url+"/v1/batch", bytes.NewBuffer(json))

	if err != nil {
		return err
	}

	req.Header.Add("User-Agent", "analytics-go (version: "+Version+")")
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Content-Length", string(len(json)))
	req.SetBasicAuth(c.key, "")

	res, err := client.Do(req)

	if res != nil {
		// TODO: how the fuck do you ignore res ^
	}

	return err
}

//
// Buffer the given message and flush
// when the buffer exceeds .flushAt.
//

func (c *client) bufferMessage(msg interface{}) error {
	c.buffer = append(c.buffer, &msg)

	if c.debug {
		log.Printf("buffer (%d/%d) %v", len(c.buffer), c.flushAt, msg)
	}

	if len(c.buffer) >= c.flushAt {
		log.Printf("flushing %d messages", len(c.buffer))
		return c.flush()
	}

	return nil
}

//
// Buffer an alias message
//

func (c *client) Alias(previousId string) error {
	return c.bufferMessage(&alias{"Alias", previousId, timestamp()})
}

//
// Buffer a page message
//

func (c *client) Page(name string, category string, properties interface{}) error {
	return c.bufferMessage(&page{"Page", name, category, properties, timestamp()})
}

//
// Buffer a screen message
//

func (c *client) Screen(name string, category string, properties interface{}) error {
	return c.bufferMessage(&page{"Screen", name, category, properties, timestamp()})
}

//
// Buffer a group message
//

func (c *client) Group(id string, traits interface{}) error {
	return c.bufferMessage(&group{"Group", id, traits, timestamp()})
}

//
// Buffer an identify message
//

func (c *client) Identify(traits interface{}) error {
	return c.bufferMessage(&identify{"Identify", traits, timestamp()})
}

//
// Buffer a track message
//

func (c *client) Track(event string, properties interface{}) error {
	return c.bufferMessage(&track{"Track", event, properties, timestamp()})
}
<|endoftext|>


<commit_before>package shell

import (
	"errors"
	"os"
	"os/exec"
)

func signalProcess(cmd *exec.Command, sig os.Signal) error {
	if cmd.Process != nil {
		return errors.New("Process doesn't exist yet")
	}
	return cmd.Process.Signal(sig)
}
<commit_msg>Fix typo in windows signal<commit_after>package shell

import (
	"errors"
	"os"
	"os/exec"
)

func signalProcess(cmd *exec.Cmd, sig os.Signal) error {
	if cmd.Process != nil {
		return errors.New("Process doesn't exist yet")
	}
	return cmd.Process.Signal(sig)
}
<|endoftext|>


<commit_before>package vm

import (
	"encoding/json"
	"fmt"
	"math"
	"reflect"
	"strconv"
	"strings"
	"time"
)

var (
	//ReflectNilValue   = reflect.ValueOf((*interface{})(nil))
	//ReflectTrueValue  = reflect.ValueOf(true)
	//ReflectFalseValue = reflect.ValueOf(false)

	// our DataTypes we support, a limited sub-set of go
	floatRv   = reflect.ValueOf(float64(1.2))
	int64Rv   = reflect.ValueOf(int64(1))
	int32Rv   = reflect.ValueOf(int32(1))
	stringRv  = reflect.ValueOf("hello")
	stringsRv = reflect.ValueOf([]string{"hello"})
	boolRv    = reflect.ValueOf(true)
	mapIntRv  = reflect.ValueOf(map[string]int64{"hello": int64(1)})
	timeRv    = reflect.ValueOf(time.Time{})
	nilRv     = reflect.ValueOf(nil)

	RV_ZERO     = reflect.Value{}
	nilStruct   *emptyStruct
	EmptyStruct = struct{}{}

	BoolValueTrue    = NewBoolValue(true)
	BoolValueFalse   = NewBoolValue(false)
	NumberNaNValue   = NewNumberValue(math.NaN())
	EmptyStringValue = NewStringValue("")
	EmptyMapIntValue = NewMapIntValue(make(map[string]int64))
	NilStructValue   = NewStructValue(nilStruct)
	TimeZeroValue    = NewTimeValue(time.Time{})
	ErrValue         = NewErrorValue("")

	_ Value = (StringValue)(EmptyStringValue)
)

type emptyStruct struct{}

type Value interface {
	// Is this a nil?  or empty string?
	Nil() bool
	// Is this an error, or unable to evaluate from Vm?
	Err() bool
	Value() interface{}
	Rv() reflect.Value
	ToString() string
	//CanCoerce(rv reflect.Value) bool
}
type NumericValue interface {
	Float() float64
	Int() int64
}

type NumberValue struct {
	v  float64
	rv reflect.Value
}

func NewNumberValue(v float64) NumberValue {
	return NumberValue{v: v, rv: reflect.ValueOf(v)}
}

func (m NumberValue) Nil() bool                         { return false }
func (m NumberValue) Err() bool                         { return false }
func (m NumberValue) Rv() reflect.Value                 { return m.rv }
func (m NumberValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(int64Rv, toRv) }
func (m NumberValue) Value() interface{}                { return m.v }
func (m NumberValue) MarshalJSON() ([]byte, error)      { return marshalFloat(float64(m.v)) }
func (m NumberValue) ToString() string                  { return strconv.FormatFloat(float64(m.v), 'f', -1, 64) }
func (m NumberValue) Float() float64                    { return m.v }
func (m NumberValue) Int() int64                        { return int64(m.v) }

type IntValue struct {
	v  int64
	rv reflect.Value
}

func NewIntValue(v int64) IntValue {
	return IntValue{v: v, rv: reflect.ValueOf(v)}
}

func (m IntValue) Nil() bool                         { return false }
func (m IntValue) Err() bool                         { return false }
func (m IntValue) Rv() reflect.Value                 { return m.rv }
func (m IntValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(int64Rv, toRv) }
func (m IntValue) Value() interface{}                { return m.v }
func (m IntValue) MarshalJSON() ([]byte, error)      { return marshalFloat(float64(m.v)) }
func (m IntValue) NumberValue() NumberValue          { return NewNumberValue(float64(m.v)) }
func (m IntValue) ToString() string                  { return strconv.FormatInt(m.v, 10) }
func (m IntValue) Float() float64                    { return float64(m.v) }
func (m IntValue) Int() int64                        { return m.v }

type BoolValue struct {
	v  bool
	rv reflect.Value
}

func NewBoolValue(v bool) BoolValue {
	return BoolValue{v: v, rv: reflect.ValueOf(v)}
}

func (m BoolValue) Nil() bool                         { return false }
func (m BoolValue) Err() bool                         { return false }
func (m BoolValue) Rv() reflect.Value                 { return m.rv }
func (m BoolValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(boolRv, toRv) }
func (m BoolValue) Value() interface{}                { return m.v }
func (m BoolValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m BoolValue) ToString() string                  { return strconv.FormatBool(m.v) }

type StringValue struct {
	v  string
	rv reflect.Value
}

func NewStringValue(v string) StringValue {
	return StringValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StringValue) Nil() bool                          { return len(m.v) == 0 }
func (m StringValue) Err() bool                          { return false }
func (m StringValue) Rv() reflect.Value                  { return m.rv }
func (m StringValue) CanCoerce(input reflect.Value) bool { return CanCoerce(stringRv, input) }
func (m StringValue) Value() interface{}                 { return m.v }
func (m StringValue) MarshalJSON() ([]byte, error)       { return json.Marshal(m.v) }
func (m StringValue) NumberValue() NumberValue           { return NewNumberValue(ToFloat64(m.Rv())) }
func (m StringValue) ToString() string                   { return m.v }

func (m StringValue) IntValue() IntValue {
	iv, _ := ToInt64(m.Rv())
	return NewIntValue(iv)
}

type StringsValue struct {
	v  []string
	rv reflect.Value
}

func NewStringsValue(v []string) StringsValue {
	return StringsValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StringsValue) Nil() bool                           { return len(m.v) == 0 }
func (m StringsValue) Err() bool                           { return false }
func (m StringsValue) Rv() reflect.Value                   { return m.rv }
func (m StringsValue) CanCoerce(boolRv reflect.Value) bool { return CanCoerce(stringRv, boolRv) }
func (m StringsValue) Value() interface{}                  { return m.v }
func (m StringsValue) Append(sv string)                    { m.v = append(m.v, sv) }
func (m StringsValue) MarshalJSON() ([]byte, error)        { return json.Marshal(m.v) }
func (m StringsValue) NumberValue() NumberValue {
	if len(m.v) == 1 {
		if fv, err := strconv.ParseFloat(m.v[0], 64); err == nil {
			return NewNumberValue(fv)
		}
	}

	return NumberNaNValue
}
func (m StringsValue) IntValue() IntValue {
	// Im not confident this is valid?   array first element?
	iv, _ := ToInt64(m.Rv())
	return NewIntValue(iv)
}
func (m StringsValue) ToString() string  { return strings.Join(m.v, ",") }
func (m StringsValue) Strings() []string { return m.v }
func (m StringsValue) Set() map[string]struct{} {
	setvals := make(map[string]struct{})
	for _, sv := range m.v {
		// Are we sure about this ToLower?
		setvals[strings.ToLower(sv)] = EmptyStruct
	}
	return setvals
}

type MapIntValue struct {
	v  map[string]int64
	rv reflect.Value
}

func NewMapIntValue(v map[string]int64) MapIntValue {
	return MapIntValue{v: v, rv: reflect.ValueOf(v)}
}

func (m MapIntValue) Nil() bool                         { return len(m.v) == 0 }
func (m MapIntValue) Err() bool                         { return false }
func (m MapIntValue) Rv() reflect.Value                 { return m.rv }
func (m MapIntValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(mapIntRv, toRv) }
func (m MapIntValue) Value() interface{}                { return m.v }
func (m MapIntValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m MapIntValue) ToString() string                  { return fmt.Sprintf("%v", m.v) }
func (m MapIntValue) MapInt() map[string]int64          { return m.v }

type StructValue struct {
	v  interface{}
	rv reflect.Value
}

func NewStructValue(v interface{}) StructValue {
	return StructValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StructValue) Nil() bool                         { return false }
func (m StructValue) Err() bool                         { return false }
func (m StructValue) Rv() reflect.Value                 { return m.rv }
func (m StructValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m StructValue) Value() interface{}                { return m.v }
func (m StructValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m StructValue) ToString() string                  { return fmt.Sprintf("%v", m.v) }

type TimeValue struct {
	t  time.Time
	rv reflect.Value
}

func NewTimeValue(t time.Time) TimeValue {
	return TimeValue{t: t, rv: reflect.ValueOf(t)}
}

func (m TimeValue) Nil() bool                         { return m.t.IsZero() }
func (m TimeValue) Err() bool                         { return false }
func (m TimeValue) Rv() reflect.Value                 { return m.rv }
func (m TimeValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(timeRv, toRv) }
func (m TimeValue) Value() interface{}                { return m.t }
func (m TimeValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.t) }
func (m TimeValue) ToString() string                  { return m.t.Format(time.RFC3339) }
func (m TimeValue) Time() time.Time                   { return m.t }

type ErrorValue struct {
	v  string
	rv reflect.Value
}

func NewErrorValue(v string) ErrorValue {
	return ErrorValue{v: v, rv: reflect.ValueOf(v)}
}

func (m ErrorValue) Nil() bool                         { return false }
func (m ErrorValue) Err() bool                         { return true }
func (m ErrorValue) Rv() reflect.Value                 { return m.rv }
func (m ErrorValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m ErrorValue) Value() interface{}                { return m.v }
func (m ErrorValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m ErrorValue) ToString() string                  { return "" }

type NilValue struct{}

func NewNilValue() NilValue {
	return NilValue{}
}

func (m NilValue) Nil() bool                         { return true }
func (m NilValue) Err() bool                         { return false }
func (m NilValue) Rv() reflect.Value                 { return nilRv }
func (m NilValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m NilValue) Value() interface{}                { return nil }
func (m NilValue) MarshalJSON() ([]byte, error)      { return nil, nil }
func (m NilValue) ToString() string                  { return "" }
<commit_msg>bug on append<commit_after>package vm

import (
	"encoding/json"
	"fmt"
	"math"
	"reflect"
	"strconv"
	"strings"
	"time"
)

var (
	//ReflectNilValue   = reflect.ValueOf((*interface{})(nil))
	//ReflectTrueValue  = reflect.ValueOf(true)
	//ReflectFalseValue = reflect.ValueOf(false)

	// our DataTypes we support, a limited sub-set of go
	floatRv   = reflect.ValueOf(float64(1.2))
	int64Rv   = reflect.ValueOf(int64(1))
	int32Rv   = reflect.ValueOf(int32(1))
	stringRv  = reflect.ValueOf("hello")
	stringsRv = reflect.ValueOf([]string{"hello"})
	boolRv    = reflect.ValueOf(true)
	mapIntRv  = reflect.ValueOf(map[string]int64{"hello": int64(1)})
	timeRv    = reflect.ValueOf(time.Time{})
	nilRv     = reflect.ValueOf(nil)

	RV_ZERO     = reflect.Value{}
	nilStruct   *emptyStruct
	EmptyStruct = struct{}{}

	BoolValueTrue     = NewBoolValue(true)
	BoolValueFalse    = NewBoolValue(false)
	NumberNaNValue    = NewNumberValue(math.NaN())
	EmptyStringValue  = NewStringValue("")
	EmptyStringsValue = NewStringsValue(nil)
	EmptyMapIntValue  = NewMapIntValue(make(map[string]int64))
	NilStructValue    = NewStructValue(nilStruct)
	TimeZeroValue     = NewTimeValue(time.Time{})
	ErrValue          = NewErrorValue("")

	_ Value = (StringValue)(EmptyStringValue)
)

type emptyStruct struct{}

type Value interface {
	// Is this a nil?  or empty string?
	Nil() bool
	// Is this an error, or unable to evaluate from Vm?
	Err() bool
	Value() interface{}
	Rv() reflect.Value
	ToString() string
	//CanCoerce(rv reflect.Value) bool
}
type NumericValue interface {
	Float() float64
	Int() int64
}

type NumberValue struct {
	v  float64
	rv reflect.Value
}

func NewNumberValue(v float64) NumberValue {
	return NumberValue{v: v, rv: reflect.ValueOf(v)}
}

func (m NumberValue) Nil() bool                         { return false }
func (m NumberValue) Err() bool                         { return false }
func (m NumberValue) Rv() reflect.Value                 { return m.rv }
func (m NumberValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(int64Rv, toRv) }
func (m NumberValue) Value() interface{}                { return m.v }
func (m NumberValue) MarshalJSON() ([]byte, error)      { return marshalFloat(float64(m.v)) }
func (m NumberValue) ToString() string                  { return strconv.FormatFloat(float64(m.v), 'f', -1, 64) }
func (m NumberValue) Float() float64                    { return m.v }
func (m NumberValue) Int() int64                        { return int64(m.v) }

type IntValue struct {
	v  int64
	rv reflect.Value
}

func NewIntValue(v int64) IntValue {
	return IntValue{v: v, rv: reflect.ValueOf(v)}
}

func (m IntValue) Nil() bool                         { return false }
func (m IntValue) Err() bool                         { return false }
func (m IntValue) Rv() reflect.Value                 { return m.rv }
func (m IntValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(int64Rv, toRv) }
func (m IntValue) Value() interface{}                { return m.v }
func (m IntValue) MarshalJSON() ([]byte, error)      { return marshalFloat(float64(m.v)) }
func (m IntValue) NumberValue() NumberValue          { return NewNumberValue(float64(m.v)) }
func (m IntValue) ToString() string                  { return strconv.FormatInt(m.v, 10) }
func (m IntValue) Float() float64                    { return float64(m.v) }
func (m IntValue) Int() int64                        { return m.v }

type BoolValue struct {
	v  bool
	rv reflect.Value
}

func NewBoolValue(v bool) BoolValue {
	return BoolValue{v: v, rv: reflect.ValueOf(v)}
}

func (m BoolValue) Nil() bool                         { return false }
func (m BoolValue) Err() bool                         { return false }
func (m BoolValue) Rv() reflect.Value                 { return m.rv }
func (m BoolValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(boolRv, toRv) }
func (m BoolValue) Value() interface{}                { return m.v }
func (m BoolValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m BoolValue) ToString() string                  { return strconv.FormatBool(m.v) }

type StringValue struct {
	v  string
	rv reflect.Value
}

func NewStringValue(v string) StringValue {
	return StringValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StringValue) Nil() bool                          { return len(m.v) == 0 }
func (m StringValue) Err() bool                          { return false }
func (m StringValue) Rv() reflect.Value                  { return m.rv }
func (m StringValue) CanCoerce(input reflect.Value) bool { return CanCoerce(stringRv, input) }
func (m StringValue) Value() interface{}                 { return m.v }
func (m StringValue) MarshalJSON() ([]byte, error)       { return json.Marshal(m.v) }
func (m StringValue) NumberValue() NumberValue           { return NewNumberValue(ToFloat64(m.Rv())) }
func (m StringValue) ToString() string                   { return m.v }

func (m StringValue) IntValue() IntValue {
	iv, _ := ToInt64(m.Rv())
	return NewIntValue(iv)
}

type StringsValue struct {
	v  []string
	rv reflect.Value
}

func NewStringsValue(v []string) StringsValue {
	return StringsValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StringsValue) Nil() bool                           { return len(m.v) == 0 }
func (m StringsValue) Err() bool                           { return false }
func (m StringsValue) Rv() reflect.Value                   { return m.rv }
func (m StringsValue) CanCoerce(boolRv reflect.Value) bool { return CanCoerce(stringRv, boolRv) }
func (m StringsValue) Value() interface{}                  { return m.v }
func (m *StringsValue) Append(sv string)                   { m.v = append(m.v, sv) }
func (m StringsValue) MarshalJSON() ([]byte, error)        { return json.Marshal(m.v) }
func (m StringsValue) Len() int                            { return len(m.v) }
func (m StringsValue) NumberValue() NumberValue {
	if len(m.v) == 1 {
		if fv, err := strconv.ParseFloat(m.v[0], 64); err == nil {
			return NewNumberValue(fv)
		}
	}

	return NumberNaNValue
}
func (m StringsValue) IntValue() IntValue {
	// Im not confident this is valid?   array first element?
	iv, _ := ToInt64(m.Rv())
	return NewIntValue(iv)
}
func (m StringsValue) ToString() string  { return strings.Join(m.v, ",") }
func (m StringsValue) Strings() []string { return m.v }
func (m StringsValue) Set() map[string]struct{} {
	setvals := make(map[string]struct{})
	for _, sv := range m.v {
		// Are we sure about this ToLower?
		setvals[strings.ToLower(sv)] = EmptyStruct
	}
	return setvals
}

type MapIntValue struct {
	v  map[string]int64
	rv reflect.Value
}

func NewMapIntValue(v map[string]int64) MapIntValue {
	return MapIntValue{v: v, rv: reflect.ValueOf(v)}
}

func (m MapIntValue) Nil() bool                         { return len(m.v) == 0 }
func (m MapIntValue) Err() bool                         { return false }
func (m MapIntValue) Rv() reflect.Value                 { return m.rv }
func (m MapIntValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(mapIntRv, toRv) }
func (m MapIntValue) Value() interface{}                { return m.v }
func (m MapIntValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m MapIntValue) ToString() string                  { return fmt.Sprintf("%v", m.v) }
func (m MapIntValue) MapInt() map[string]int64          { return m.v }

type StructValue struct {
	v  interface{}
	rv reflect.Value
}

func NewStructValue(v interface{}) StructValue {
	return StructValue{v: v, rv: reflect.ValueOf(v)}
}

func (m StructValue) Nil() bool                         { return false }
func (m StructValue) Err() bool                         { return false }
func (m StructValue) Rv() reflect.Value                 { return m.rv }
func (m StructValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m StructValue) Value() interface{}                { return m.v }
func (m StructValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m StructValue) ToString() string                  { return fmt.Sprintf("%v", m.v) }

type TimeValue struct {
	t  time.Time
	rv reflect.Value
}

func NewTimeValue(t time.Time) TimeValue {
	return TimeValue{t: t, rv: reflect.ValueOf(t)}
}

func (m TimeValue) Nil() bool                         { return m.t.IsZero() }
func (m TimeValue) Err() bool                         { return false }
func (m TimeValue) Rv() reflect.Value                 { return m.rv }
func (m TimeValue) CanCoerce(toRv reflect.Value) bool { return CanCoerce(timeRv, toRv) }
func (m TimeValue) Value() interface{}                { return m.t }
func (m TimeValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.t) }
func (m TimeValue) ToString() string                  { return m.t.Format(time.RFC3339) }
func (m TimeValue) Time() time.Time                   { return m.t }

type ErrorValue struct {
	v  string
	rv reflect.Value
}

func NewErrorValue(v string) ErrorValue {
	return ErrorValue{v: v, rv: reflect.ValueOf(v)}
}

func (m ErrorValue) Nil() bool                         { return false }
func (m ErrorValue) Err() bool                         { return true }
func (m ErrorValue) Rv() reflect.Value                 { return m.rv }
func (m ErrorValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m ErrorValue) Value() interface{}                { return m.v }
func (m ErrorValue) MarshalJSON() ([]byte, error)      { return json.Marshal(m.v) }
func (m ErrorValue) ToString() string                  { return "" }

type NilValue struct{}

func NewNilValue() NilValue {
	return NilValue{}
}

func (m NilValue) Nil() bool                         { return true }
func (m NilValue) Err() bool                         { return false }
func (m NilValue) Rv() reflect.Value                 { return nilRv }
func (m NilValue) CanCoerce(toRv reflect.Value) bool { return false }
func (m NilValue) Value() interface{}                { return nil }
func (m NilValue) MarshalJSON() ([]byte, error)      { return nil, nil }
func (m NilValue) ToString() string                  { return "" }
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"net/http"
	"strings"
)

type WebCheck struct {
	Url    string `yaml:"url"`
	Status int    `yaml:"status"`
	Format string `yaml:"format"`
}

func init() {
	// TODO: Make sure SSL verification works. This is just a workaround.
	cfg := &tls.Config{InsecureSkipVerify: true}

	http.DefaultClient.Transport = &http.Transport{
		TLSClientConfig: cfg,
	}
}

func ParseWebCheck(data map[string]interface{}) WebCheck {
	check := WebCheck{}

	if data["url"] != nil {
		check.Url = data["url"].(string)
	}

	if data["status"] != nil {
		check.Status = data["status"].(int)
	} else {
		check.Status = 200
	}

	if data["format"] != nil {
		check.Format = data["format"].(string)
	} else {
		check.Format = "html"
	}

	return check
}

func (check WebCheck) Name() string {
	return "WEB"
}

func (check WebCheck) Perform() error {
	log.Printf(
		"Performing WEB check for url=%v status=%v format=%v\n",
		check.Url, check.Status, check.Format,
	)

	if check.Url == "" {
		return fmt.Errorf("URL should not be empty")
	}

	resp, err := http.Get(check.Url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != check.Status {
		return fmt.Errorf(
			"Expected HTTP status %v for %v, got: %v",
			check.Status, check.Url, resp.StatusCode,
		)
	}

	contentType := resp.Header.Get("Content-Type")
	if !strings.Contains(contentType, check.Format) {
		return fmt.Errorf(
			"Expected HTTP format '%v' for %v to include '%v'",
			contentType, check.Url, check.Format,
		)
	}

	return nil
}
<commit_msg>Set default http timeout to 10s<commit_after>package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"
)

type WebCheck struct {
	Url    string `yaml:"url"`
	Status int    `yaml:"status"`
	Format string `yaml:"format"`
}

func init() {
	// TODO: Make sure SSL verification works. This is just a workaround.
	cfg := &tls.Config{InsecureSkipVerify: true}

	http.DefaultClient.Transport = &http.Transport{
		TLSClientConfig: cfg,
	}

	http.DefaultClient.Timeout = time.Second * 10
}

func ParseWebCheck(data map[string]interface{}) WebCheck {
	check := WebCheck{}

	if data["url"] != nil {
		check.Url = data["url"].(string)
	}

	if data["status"] != nil {
		check.Status = data["status"].(int)
	} else {
		check.Status = 200
	}

	if data["format"] != nil {
		check.Format = data["format"].(string)
	} else {
		check.Format = "html"
	}

	return check
}

func (check WebCheck) Name() string {
	return "WEB"
}

func (check WebCheck) Perform() error {
	log.Printf(
		"Performing WEB check for url=%v status=%v format=%v\n",
		check.Url, check.Status, check.Format,
	)

	if check.Url == "" {
		return fmt.Errorf("URL should not be empty")
	}

	resp, err := http.Get(check.Url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != check.Status {
		return fmt.Errorf(
			"Expected HTTP status %v for %v, got: %v",
			check.Status, check.Url, resp.StatusCode,
		)
	}

	contentType := resp.Header.Get("Content-Type")
	if !strings.Contains(contentType, check.Format) {
		return fmt.Errorf(
			"Expected HTTP format '%v' for %v to include '%v'",
			contentType, check.Url, check.Format,
		)
	}

	return nil
}
<|endoftext|>


<commit_before>package todolist

import (
	"fmt"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"

	"github.com/fatih/color"
)

type Formatter struct {
	GroupedTodos *GroupedTodos
	Writer       *tabwriter.Writer
}

func NewFormatter(todos *GroupedTodos) *Formatter {
	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 0, 8, 0, '\t', 0)
	formatter := &Formatter{GroupedTodos: todos, Writer: w}
	return formatter
}

func (f *Formatter) Print() {
	cyan := color.New(color.FgCyan).SprintFunc()

	var keys []string
	for key, _ := range f.GroupedTodos.Groups {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	for _, key := range keys {
		fmt.Fprintf(f.Writer, "\n   \t%s\n", cyan(key))
		for _, todo := range f.GroupedTodos.Groups[key] {
			f.printTodo(todo)
		}
	}
	f.Writer.Flush()
}

func (f *Formatter) printTodo(todo *Todo) {
	yellow := color.New(color.FgYellow).SprintFunc()
	fmt.Fprintf(f.Writer, "     \t%s\t%s\t%s\t%s\t\n",
		yellow(strconv.Itoa(todo.Id)),
		f.formatCompleted(todo.Completed),
		f.formatDue(todo.Due),
		f.formatSubject(todo.Subject))
}

func (f *Formatter) formatDue(due string) string {
	blue := color.New(color.FgBlue).SprintFunc()
	red := color.New(color.FgRed).SprintFunc()

	if due == "" {
		return blue(" ")
	}
	dueTime, err := time.Parse("2006-01-02", due)

	if err != nil {
		panic(err)
	}

	if isToday(dueTime) {
		return blue("today")
	} else if isTomorrow(dueTime) {
		return blue("tomorrow")
	} else if isPastDue(dueTime) {
		return red(dueTime.Format("Mon Jan 2"))
	} else {
		return blue(dueTime.Format("Mon Jan 2"))
	}
}

func isToday(t time.Time) bool {
	nowYear, nowMonth, nowDay := time.Now().Date()
	timeYear, timeMonth, timeDay := t.Date()
	return nowYear == timeYear &&
		nowMonth == timeMonth &&
		nowDay == timeDay
}

func isTomorrow(t time.Time) bool {
	nowYear, nowMonth, nowDay := time.Now().AddDate(0, 0, 1).Date()
	timeYear, timeMonth, timeDay := t.Date()
	return nowYear == timeYear &&
		nowMonth == timeMonth &&
		nowDay == timeDay
}

func isPastDue(t time.Time) bool {
	return time.Now().After(t)
}

func (f *Formatter) formatSubject(subject string) string {
	red := color.New(color.FgRed).SprintFunc()
	magenta := color.New(color.FgMagenta).SprintFunc()

	splitted := strings.Split(subject, " ")
	projectRegex, _ := regexp.Compile(`\+\w+`)
	contextRegex, _ := regexp.Compile(`\@\w+`)

	coloredWords := []string{}

	for _, word := range splitted {
		if projectRegex.MatchString(word) {
			coloredWords = append(coloredWords, magenta(word))
		} else if contextRegex.MatchString(word) {
			coloredWords = append(coloredWords, red(word))
		} else {
			coloredWords = append(coloredWords, word)
		}
	}
	return strings.Join(coloredWords, " ")

}

func (f *Formatter) formatCompleted(completed bool) string {
	if completed {
		return "[x]"
	} else {
		return "[ ]"
	}
}
<commit_msg>Remove large amounts of whitespace at beginning, to save space<commit_after>package todolist

import (
	"fmt"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"

	"github.com/fatih/color"
)

type Formatter struct {
	GroupedTodos *GroupedTodos
	Writer       *tabwriter.Writer
}

func NewFormatter(todos *GroupedTodos) *Formatter {
	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 0, 8, 0, '\t', 0)
	formatter := &Formatter{GroupedTodos: todos, Writer: w}
	return formatter
}

func (f *Formatter) Print() {
	cyan := color.New(color.FgCyan).SprintFunc()

	var keys []string
	for key, _ := range f.GroupedTodos.Groups {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	for _, key := range keys {
		fmt.Fprintf(f.Writer, "\n %s\n", cyan(key))
		for _, todo := range f.GroupedTodos.Groups[key] {
			f.printTodo(todo)
		}
	}
	f.Writer.Flush()
}

func (f *Formatter) printTodo(todo *Todo) {
	yellow := color.New(color.FgYellow).SprintFunc()
	fmt.Fprintf(f.Writer, " %s\t%s\t%s\t%s\t\n",
		yellow(strconv.Itoa(todo.Id)),
		f.formatCompleted(todo.Completed),
		f.formatDue(todo.Due),
		f.formatSubject(todo.Subject))
}

func (f *Formatter) formatDue(due string) string {
	blue := color.New(color.FgBlue).SprintFunc()
	red := color.New(color.FgRed).SprintFunc()

	if due == "" {
		return blue(" ")
	}
	dueTime, err := time.Parse("2006-01-02", due)

	if err != nil {
		panic(err)
	}

	if isToday(dueTime) {
		return blue("today")
	} else if isTomorrow(dueTime) {
		return blue("tomorrow")
	} else if isPastDue(dueTime) {
		return red(dueTime.Format("Mon Jan 2"))
	} else {
		return blue(dueTime.Format("Mon Jan 2"))
	}
}

func isToday(t time.Time) bool {
	nowYear, nowMonth, nowDay := time.Now().Date()
	timeYear, timeMonth, timeDay := t.Date()
	return nowYear == timeYear &&
		nowMonth == timeMonth &&
		nowDay == timeDay
}

func isTomorrow(t time.Time) bool {
	nowYear, nowMonth, nowDay := time.Now().AddDate(0, 0, 1).Date()
	timeYear, timeMonth, timeDay := t.Date()
	return nowYear == timeYear &&
		nowMonth == timeMonth &&
		nowDay == timeDay
}

func isPastDue(t time.Time) bool {
	return time.Now().After(t)
}

func (f *Formatter) formatSubject(subject string) string {
	red := color.New(color.FgRed).SprintFunc()
	magenta := color.New(color.FgMagenta).SprintFunc()

	splitted := strings.Split(subject, " ")
	projectRegex, _ := regexp.Compile(`\+\w+`)
	contextRegex, _ := regexp.Compile(`\@\w+`)

	coloredWords := []string{}

	for _, word := range splitted {
		if projectRegex.MatchString(word) {
			coloredWords = append(coloredWords, magenta(word))
		} else if contextRegex.MatchString(word) {
			coloredWords = append(coloredWords, red(word))
		} else {
			coloredWords = append(coloredWords, word)
		}
	}
	return strings.Join(coloredWords, " ")

}

func (f *Formatter) formatCompleted(completed bool) string {
	if completed {
		return "[x]"
	} else {
		return "[ ]"
	}
}
<|endoftext|>


<commit_before>package todolist

import (
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"

	"github.com/fatih/color"
)

type Formatter struct {
	GroupedTodos *GroupedTodos
	Writer       *tabwriter.Writer
}

func NewFormatter(todos *GroupedTodos) *Formatter {
	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 0, 8, 0, '\t', 0)
	formatter := &Formatter{GroupedTodos: todos, Writer: w}
	return formatter
}

func (f *Formatter) Print() {
	cyan := color.New(color.FgCyan).SprintFunc()

	for key, todos := range f.GroupedTodos.Groups {
		fmt.Fprintf(f.Writer, "\n   \t%s\n", cyan(key))
		for _, todo := range todos {
			f.printTodo(todo)
		}

	}
	f.Writer.Flush()
}

func (f *Formatter) printTodo(todo *Todo) {
	yellow := color.New(color.FgYellow).SprintFunc()
	fmt.Fprintf(f.Writer, "     \t%s\t%s\t%s\t%s\t\n",
		yellow(strconv.Itoa(todo.Id)),
		f.formatCompleted(todo.Completed),
		f.formatDue(todo.Due),
		f.formatSubject(todo.Subject))
}

func (f *Formatter) formatDue(due string) string {
	if due == "" {
		return ""
	}
	dueTime, err := time.Parse("2006-01-02", due)

	if err != nil {
		panic(err)
	}

	blue := color.New(color.FgBlue).SprintFunc()
	red := color.New(color.FgRed).SprintFunc()

	if isToday(dueTime) {
		return blue("today")
	} else if isTomorrow(dueTime) {
		return blue("tomorrow")
	} else if isPastDue(dueTime) {
		return red(dueTime.Format("Mon Jan 2"))
	} else {
		return blue(dueTime.Format("Mon Jan 2"))
	}
}

func isToday(t time.Time) bool {
	nowYear, nowMonth, nowDay := time.Now().Date()
	timeYear, timeMonth, timeDay := t.Date()
	return nowYear == timeYear &&
		nowMonth == timeMonth &&
		nowDay == timeDay
}

func isTomorrow(t time.Time) bool {
	nowYear, nowMonth, nowDay := time.Now().AddDate(0, 0, 1).Date()
	timeYear, timeMonth, timeDay := t.Date()
	return nowYear == timeYear &&
		nowMonth == timeMonth &&
		nowDay == timeDay
}

func isPastDue(t time.Time) bool {
	return time.Now().After(t)
}

func (f *Formatter) formatSubject(subject string) string {
	red := color.New(color.FgRed).SprintFunc()
	magenta := color.New(color.FgMagenta).SprintFunc()

	splitted := strings.Split(subject, " ")
	projectRegex, _ := regexp.Compile(`\+\w+`)
	contextRegex, _ := regexp.Compile(`\@\w+`)

	coloredWords := []string{}

	for _, word := range splitted {
		if projectRegex.MatchString(word) {
			coloredWords = append(coloredWords, magenta(word))
		} else if contextRegex.MatchString(word) {
			coloredWords = append(coloredWords, red(word))
		} else {
			coloredWords = append(coloredWords, word)
		}
	}
	return strings.Join(coloredWords, " ")

}

func (f *Formatter) formatCompleted(completed bool) string {
	if completed {
		return "[x]"
	} else {
		return "[ ]"
	}
}
<commit_msg>alpha-sort groups<commit_after>package todolist

import (
	"fmt"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"

	"github.com/fatih/color"
)

type Formatter struct {
	GroupedTodos *GroupedTodos
	Writer       *tabwriter.Writer
}

func NewFormatter(todos *GroupedTodos) *Formatter {
	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 0, 8, 0, '\t', 0)
	formatter := &Formatter{GroupedTodos: todos, Writer: w}
	return formatter
}

func (f *Formatter) Print() {
	cyan := color.New(color.FgCyan).SprintFunc()

	var keys []string
	for key, _ := range f.GroupedTodos.Groups {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	for _, key := range keys {
		fmt.Fprintf(f.Writer, "\n   \t%s\n", cyan(key))
		for _, todo := range f.GroupedTodos.Groups[key] {
			f.printTodo(todo)
		}
	}
	f.Writer.Flush()
}

func (f *Formatter) printTodo(todo *Todo) {
	yellow := color.New(color.FgYellow).SprintFunc()
	fmt.Fprintf(f.Writer, "     \t%s\t%s\t%s\t%s\t\n",
		yellow(strconv.Itoa(todo.Id)),
		f.formatCompleted(todo.Completed),
		f.formatDue(todo.Due),
		f.formatSubject(todo.Subject))
}

func (f *Formatter) formatDue(due string) string {
	if due == "" {
		return ""
	}
	dueTime, err := time.Parse("2006-01-02", due)

	if err != nil {
		panic(err)
	}

	blue := color.New(color.FgBlue).SprintFunc()
	red := color.New(color.FgRed).SprintFunc()

	if isToday(dueTime) {
		return blue("today")
	} else if isTomorrow(dueTime) {
		return blue("tomorrow")
	} else if isPastDue(dueTime) {
		return red(dueTime.Format("Mon Jan 2"))
	} else {
		return blue(dueTime.Format("Mon Jan 2"))
	}
}

func isToday(t time.Time) bool {
	nowYear, nowMonth, nowDay := time.Now().Date()
	timeYear, timeMonth, timeDay := t.Date()
	return nowYear == timeYear &&
		nowMonth == timeMonth &&
		nowDay == timeDay
}

func isTomorrow(t time.Time) bool {
	nowYear, nowMonth, nowDay := time.Now().AddDate(0, 0, 1).Date()
	timeYear, timeMonth, timeDay := t.Date()
	return nowYear == timeYear &&
		nowMonth == timeMonth &&
		nowDay == timeDay
}

func isPastDue(t time.Time) bool {
	return time.Now().After(t)
}

func (f *Formatter) formatSubject(subject string) string {
	red := color.New(color.FgRed).SprintFunc()
	magenta := color.New(color.FgMagenta).SprintFunc()

	splitted := strings.Split(subject, " ")
	projectRegex, _ := regexp.Compile(`\+\w+`)
	contextRegex, _ := regexp.Compile(`\@\w+`)

	coloredWords := []string{}

	for _, word := range splitted {
		if projectRegex.MatchString(word) {
			coloredWords = append(coloredWords, magenta(word))
		} else if contextRegex.MatchString(word) {
			coloredWords = append(coloredWords, red(word))
		} else {
			coloredWords = append(coloredWords, word)
		}
	}
	return strings.Join(coloredWords, " ")

}

func (f *Formatter) formatCompleted(completed bool) string {
	if completed {
		return "[x]"
	} else {
		return "[ ]"
	}
}
<|endoftext|>


<commit_before>package k8s_test

import (
	"bufio"
	"bytes"
	"encoding/json"
	"github.com/caarlos0/env"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"regexp"
	"strconv"
	"testing"

	. "github.com/concourse/concourse/topgun"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func TestK8s(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "K8s Suite")
}

type environment struct {
	ChartsDir            string `env:"CHARTS_DIR,required"`
	ConcourseChartDir    string `env:"CONCOURSE_CHART_DIR"`
	ConcourseImageDigest string `env:"CONCOURSE_IMAGE_DIGEST"`
	ConcourseImageName   string `env:"CONCOURSE_IMAGE_NAME,required"`
	ConcourseImageTag    string `env:"CONCOURSE_IMAGE_TAG"`
	FlyPath              string `env:"FLY_PATH"`
}

var (
	Environment environment
	fly         Fly
)

var _ = SynchronizedBeforeSuite(func() []byte {
	var parsedEnv environment

	err := env.Parse(&parsedEnv)
	Expect(err).ToNot(HaveOccurred())

	if parsedEnv.FlyPath == "" {
		parsedEnv.FlyPath = BuildBinary()
	}

	if parsedEnv.ConcourseChartDir == "" {
		parsedEnv.ConcourseChartDir = path.Join(parsedEnv.ChartsDir, "stable/concourse")
	}

	By("Checking if kubectl has a context set")
	Wait(Start(nil, "kubectl", "config", "current-context"))

	By("Installing tiller in the k8s cluster")
	Wait(Start(nil, "helm", "init", "--wait"))

	By("Updating the dependencies of the Concourse chart locally")
	Wait(Start(nil, "helm", "dependency", "update", parsedEnv.ConcourseChartDir))

	envBytes, err := json.Marshal(parsedEnv)
	Expect(err).ToNot(HaveOccurred())

	return envBytes
}, func(data []byte) {
	err := json.Unmarshal(data, &Environment)
	Expect(err).ToNot(HaveOccurred())
})

var _ = BeforeEach(func() {
	tmp, err := ioutil.TempDir("", "topgun-tmp")
	Expect(err).ToNot(HaveOccurred())

	fly = Fly{
		Bin:    Environment.FlyPath,
		Target: "concourse-topgun-k8s-" + strconv.Itoa(GinkgoParallelNode()),
		Home:   filepath.Join(tmp, "fly-home-"+strconv.Itoa(GinkgoParallelNode())),
	}

	err = os.Mkdir(fly.Home, 0755)
	Expect(err).ToNot(HaveOccurred())
})

type pod struct {
	Status struct {
		Phase  string `json:"phase"`
		HostIp string `json:"hostIP"`
		Ip     string `json:"podIP"`
	} `json:"status"`
	Metadata struct {
		Name string `json:"name"`
	} `json:"metadata"`
}

type podListResponse struct {
	Items []pod `json:"items"`
}

func helmDeploy(releaseName, chartDir string, args ...string) {
	helmArgs := []string{
		"upgrade",
		"--install",
		"--force",
		"--wait",
		"--namespace", releaseName,
	}

	helmArgs = append(helmArgs, args...)
	helmArgs = append(helmArgs, releaseName, chartDir)

	Wait(Start(nil, "helm", helmArgs...))
}

func deployConcourseChart(releaseName string, args ...string) {
	helmArgs := []string{
		"--set=concourse.web.kubernetes.keepNamespaces=false",
		"--set=concourse.web.livenessProbe.initialDelaySeconds=3s",
		"--set=image=" + Environment.ConcourseImageName,
		"--set=imageTag=" + Environment.ConcourseImageTag}

	if Environment.ConcourseImageDigest != "" {
		helmArgs = append(helmArgs, "--set=imageDigest="+Environment.ConcourseImageDigest)
	}

	helmArgs = append(helmArgs, args...)

	helmDeploy(releaseName, Environment.ConcourseChartDir, args...)
}

func helmDestroy(releaseName string) {
	helmArgs := []string{
		"delete",
		"--purge",
		releaseName,
	}

	Wait(Start(nil, "helm", helmArgs...))
}

func getPods(namespace string, flags ...string) []pod {
	var (
		pods podListResponse
		args = append([]string{"get", "pods",
			"--namespace=" + namespace,
			"--output=json",
			"--no-headers"}, flags...)
		session = Start(nil, "kubectl", args...)
	)

	Wait(session)

	err := json.Unmarshal(session.Out.Contents(), &pods)
	Expect(err).ToNot(HaveOccurred())

	return pods.Items
}

func getPodsNames(pods []pod) []string {
	var names []string

	for _, pod := range pods {
		names = append(names, pod.Metadata.Name)
	}

	return names
}

func deletePods(namespace string, flags ...string) []string {
	var (
		podNames []string
		args     = append([]string{"delete", "pod",
			"--namespace=" + namespace,
		}, flags...)
		session = Start(nil, "kubectl", args...)
	)

	Wait(session)

	scanner := bufio.NewScanner(bytes.NewBuffer(session.Out.Contents()))
	for scanner.Scan() {
		podNames = append(podNames, scanner.Text())
	}

	return podNames
}

func startPortForwarding(namespace, service, port string) (*gexec.Session, string) {
	session := Start(nil, "kubectl", "port-forward", "--namespace="+namespace, "service/"+service, ":"+port)
	Eventually(session.Out).Should(gbytes.Say("Forwarding"))

	address := regexp.MustCompile(`127\.0\.0\.1:[0-9]+`).
		FindStringSubmatch(string(session.Out.Contents()))

	Expect(address).NotTo(BeEmpty())

	return session, "http://" + address[0]
}

func getRunningWorkers(workers []Worker) (running []Worker) {
	for _, w := range workers {
		if w.State == "running" {
			running = append(running, w)
		}
	}
	return
}
<commit_msg>topgun: makes use of default helm args in k8s<commit_after>package k8s_test

import (
	"bufio"
	"bytes"
	"encoding/json"
	"github.com/caarlos0/env"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"regexp"
	"strconv"
	"testing"

	. "github.com/concourse/concourse/topgun"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func TestK8s(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "K8s Suite")
}

type environment struct {
	ChartsDir            string `env:"CHARTS_DIR,required"`
	ConcourseChartDir    string `env:"CONCOURSE_CHART_DIR"`
	ConcourseImageDigest string `env:"CONCOURSE_IMAGE_DIGEST"`
	ConcourseImageName   string `env:"CONCOURSE_IMAGE_NAME,required"`
	ConcourseImageTag    string `env:"CONCOURSE_IMAGE_TAG"`
	FlyPath              string `env:"FLY_PATH"`
}

var (
	Environment environment
	fly         Fly
)

var _ = SynchronizedBeforeSuite(func() []byte {
	var parsedEnv environment

	err := env.Parse(&parsedEnv)
	Expect(err).ToNot(HaveOccurred())

	if parsedEnv.FlyPath == "" {
		parsedEnv.FlyPath = BuildBinary()
	}

	if parsedEnv.ConcourseChartDir == "" {
		parsedEnv.ConcourseChartDir = path.Join(parsedEnv.ChartsDir, "stable/concourse")
	}

	By("Checking if kubectl has a context set")
	Wait(Start(nil, "kubectl", "config", "current-context"))

	By("Installing tiller in the k8s cluster")
	Wait(Start(nil, "helm", "init", "--wait"))

	By("Updating the dependencies of the Concourse chart locally")
	Wait(Start(nil, "helm", "dependency", "update", parsedEnv.ConcourseChartDir))

	envBytes, err := json.Marshal(parsedEnv)
	Expect(err).ToNot(HaveOccurred())

	return envBytes
}, func(data []byte) {
	err := json.Unmarshal(data, &Environment)
	Expect(err).ToNot(HaveOccurred())
})

var _ = BeforeEach(func() {
	tmp, err := ioutil.TempDir("", "topgun-tmp")
	Expect(err).ToNot(HaveOccurred())

	fly = Fly{
		Bin:    Environment.FlyPath,
		Target: "concourse-topgun-k8s-" + strconv.Itoa(GinkgoParallelNode()),
		Home:   filepath.Join(tmp, "fly-home-"+strconv.Itoa(GinkgoParallelNode())),
	}

	err = os.Mkdir(fly.Home, 0755)
	Expect(err).ToNot(HaveOccurred())
})

type pod struct {
	Status struct {
		Phase  string `json:"phase"`
		HostIp string `json:"hostIP"`
		Ip     string `json:"podIP"`
	} `json:"status"`
	Metadata struct {
		Name string `json:"name"`
	} `json:"metadata"`
}

type podListResponse struct {
	Items []pod `json:"items"`
}

func helmDeploy(releaseName, chartDir string, args ...string) {
	helmArgs := []string{
		"upgrade",
		"--install",
		"--force",
		"--wait",
		"--namespace", releaseName,
	}

	helmArgs = append(helmArgs, args...)
	helmArgs = append(helmArgs, releaseName, chartDir)

	Wait(Start(nil, "helm", helmArgs...))
}

func deployConcourseChart(releaseName string, args ...string) {
	helmArgs := []string{
		"--set=postgresql.persistence.enabled=false",
		"--set=concourse.web.kubernetes.keepNamespaces=false",
		"--set=concourse.web.livenessProbe.initialDelaySeconds=1s",
		"--set=concourse.web.livenessProbe.periodSeconds=3s",
		"--set=concourse.web.livenessProbe.failureThreshold=30",
		"--set=concourse.web.readinessProbe.initialDelaySeconds=1s",
		"--set=concourse.web.readinessProbe.periodSeconds=3s",
		"--set=concourse.web.readinessProbe.failureThreshold=30",
		"--set=image=" + Environment.ConcourseImageName,
		"--set=imageTag=" + Environment.ConcourseImageTag}

	if Environment.ConcourseImageDigest != "" {
		helmArgs = append(helmArgs, "--set=imageDigest="+Environment.ConcourseImageDigest)
	}

	helmArgs = append(helmArgs, args...)
	helmDeploy(releaseName, Environment.ConcourseChartDir, helmArgs...)
}

func helmDestroy(releaseName string) {
	helmArgs := []string{
		"delete",
		"--purge",
		releaseName,
	}

	Wait(Start(nil, "helm", helmArgs...))
}

func getPods(namespace string, flags ...string) []pod {
	var (
		pods podListResponse
		args = append([]string{"get", "pods",
			"--namespace=" + namespace,
			"--output=json",
			"--no-headers"}, flags...)
		session = Start(nil, "kubectl", args...)
	)

	Wait(session)

	err := json.Unmarshal(session.Out.Contents(), &pods)
	Expect(err).ToNot(HaveOccurred())

	return pods.Items
}

func getPodsNames(pods []pod) []string {
	var names []string

	for _, pod := range pods {
		names = append(names, pod.Metadata.Name)
	}

	return names
}

func deletePods(namespace string, flags ...string) []string {
	var (
		podNames []string
		args     = append([]string{"delete", "pod",
			"--namespace=" + namespace,
		}, flags...)
		session = Start(nil, "kubectl", args...)
	)

	Wait(session)

	scanner := bufio.NewScanner(bytes.NewBuffer(session.Out.Contents()))
	for scanner.Scan() {
		podNames = append(podNames, scanner.Text())
	}

	return podNames
}

func startPortForwarding(namespace, service, port string) (*gexec.Session, string) {
	session := Start(nil, "kubectl", "port-forward", "--namespace="+namespace, "service/"+service, ":"+port)
	Eventually(session.Out).Should(gbytes.Say("Forwarding"))

	address := regexp.MustCompile(`127\.0\.0\.1:[0-9]+`).
		FindStringSubmatch(string(session.Out.Contents()))

	Expect(address).NotTo(BeEmpty())

	return session, "http://" + address[0]
}

func getRunningWorkers(workers []Worker) (running []Worker) {
	for _, w := range workers {
		if w.State == "running" {
			running = append(running, w)
		}
	}
	return
}
<|endoftext|>


<commit_before>package aiff

import (
	"io"

	"github.com/mattetti/audio"
)

type Clip struct {
	r          io.ReadSeeker
	size       int64
	channels   int
	bitDepth   int
	sampleRate int64
}

func (c *Clip) Read(p []byte) (n int, err error) {
	return
}

func (c *Clip) Seek(offset int64, whence int) (int64, error) {
	return 0, nil
}

func (c *Clip) FrameInfo() audio.FrameInfo {
	return audio.FrameInfo{
		Channels:   c.channels,
		BitDepth:   c.bitDepth,
		SampleRate: c.sampleRate,
	}
}

func (c *Clip) Size() int64 {
	return c.size
}
<commit_msg>aiff: remove unused file<commit_after><|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package controllers

import (
	"fmt"

	"github.com/ernestio/api-gateway/controllers/builds"
	"github.com/ernestio/api-gateway/controllers/envs"
	h "github.com/ernestio/api-gateway/helpers"
	"github.com/labstack/echo"
)

// ActionHandler : handles different actions that can be triggered on an env
func ActionHandler(c echo.Context) error {
	au := AuthenticatedUser(c)

	action, err := mapAction(c)
	if err != nil {
		return h.Respond(c, 400, []byte(err.Error()))
	}

	st, b := h.IsAuthorized(&au, "envs/"+action.Type)
	if st != 200 {
		return h.Respond(c, st, b)
	}

	fmt.Println(h.Licensed())

	switch action.Type {
	case "import":
		st, b = builds.Import(au, envName(c), action)
	case "reset":
		st, b = envs.Reset(au, envName(c), action)
	case "sync":
		st, b = envs.Sync(au, envName(c), action)
	case "resolve":
		st, b = envs.Resolve(au, envName(c), action)
	case "review":
		st, b = builds.Review(au, envName(c), action)
	default:
		return h.Respond(c, 400, []byte("unsupported action"))
	}

	return h.Respond(c, st, b)
}
<commit_msg>removing logging<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package controllers

import (
	"github.com/ernestio/api-gateway/controllers/builds"
	"github.com/ernestio/api-gateway/controllers/envs"
	h "github.com/ernestio/api-gateway/helpers"
	"github.com/labstack/echo"
)

// ActionHandler : handles different actions that can be triggered on an env
func ActionHandler(c echo.Context) error {
	au := AuthenticatedUser(c)

	action, err := mapAction(c)
	if err != nil {
		return h.Respond(c, 400, []byte(err.Error()))
	}

	st, b := h.IsAuthorized(&au, "envs/"+action.Type)
	if st != 200 {
		return h.Respond(c, st, b)
	}

	switch action.Type {
	case "import":
		st, b = builds.Import(au, envName(c), action)
	case "reset":
		st, b = envs.Reset(au, envName(c), action)
	case "sync":
		st, b = envs.Sync(au, envName(c), action)
	case "resolve":
		st, b = envs.Resolve(au, envName(c), action)
	case "review":
		st, b = builds.Review(au, envName(c), action)
	default:
		return h.Respond(c, 400, []byte("unsupported action"))
	}

	return h.Respond(c, st, b)
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"regexp"

	"github.com/mvdan/gibot/site/gitlab"
)

const listenAddr = ":9990"

func webhookListen() {
	for _, repo := range repos {
		listenRepo(repo)
	}

	log.Fatal(http.ListenAndServe(listenAddr, nil))
}

func listenRepo(repo *gitlab.Repo) {
	path := fmt.Sprintf("/webhooks/gitlab/%s", repo.Name)
	http.HandleFunc(path, gitlabHandler(repo.Name))
	log.Printf("Receiving webhooks for %s on %s%s", repo.Name, listenAddr, path)
}

func toInt(v interface{}) int {
	i, ok := v.(float64)
	if !ok {
		return 0
	}
	return int(i)
}

func toStr(v interface{}) string {
	s, ok := v.(string)
	if !ok {
		return ""
	}
	return s
}

func toSlice(v interface{}) []interface{} {
	l, ok := v.([]interface{})
	if !ok {
		return []interface{}{}
	}
	return l
}

func toMap(v interface{}) map[string]interface{} {
	m, ok := v.(map[string]interface{})
	if !ok {
		return map[string]interface{}{}
	}
	return m
}

func gitlabHandler(reponame string) func(http.ResponseWriter, *http.Request) {
	repo, e := repos[reponame]
	if !e {
		panic("unknown repo")
	}
	return func(w http.ResponseWriter, r *http.Request) {
		decoder := json.NewDecoder(r.Body)
		m := make(map[string]interface{})
		if err := decoder.Decode(&m); err != nil {
			log.Printf("Error decoding webhook data: %v", err)
		}
		kind := toStr(m["object_kind"])
		switch kind {
		case "push":
			onPush(repo, m)
		case "issue":
			onIssue(repo, m)
		case "merge_request":
			onMergeRequest(repo, m)
		default:
			log.Printf("Webhook event we don't handle: %s", kind)
			return
		}
	}
}

var headBranch = regexp.MustCompile(`^refs/heads/(.*)$`)

func getBranch(ref string) string {
	if s := headBranch.FindStringSubmatch(ref); s != nil {
		return s[1]
	}
	log.Printf("Unknown branch ref format: %s", ref)
	return ""
}

func onPush(r *gitlab.Repo, m map[string]interface{}) {
	userId := toInt(m["user_id"])
	user, err := r.GetUser(userId)
	if err != nil {
		log.Printf("Unknown user: %v", err)
	}
	username := user.Username
	count := toInt(m["total_commits_count"])
	var howMany string
	if count > 1 {
		howMany = fmt.Sprintf("%d commits", count)
	} else {
		howMany = fmt.Sprintf("%d commit", count)
	}
	branch := getBranch(toStr(m["ref"]))
	if branch == "" {
		return
	}
	before := toStr(m["before"])
	after := toStr(m["after"])
	url := r.CompareURL(before, after)
	message := fmt.Sprintf("%s pushed %s to %s - %s", username, howMany, branch, url)
	sendNoticeToAll(r.Name, message)
}

func onIssue(r *gitlab.Repo, m map[string]interface{}) {
	user := toMap(m["user"])
	username := toStr(user["username"])
	attrs := toMap(m["object_attributes"])
	iid := toInt(attrs["iid"])
	title := gitlab.ShortTitle(toStr(attrs["title"]))
	url := toStr(attrs["url"])
	action := toStr(attrs["action"])
	var message string
	switch action {
	case "open":
		message = fmt.Sprintf("%s opened #%d: %s - %s", username, iid, title, url)
	case "close":
		message = fmt.Sprintf("%s closed #%d: %s - %s", username, iid, title, url)
	case "reopen":
		message = fmt.Sprintf("%s reopened #%d: %s - %s", username, iid, title, url)
	default:
		log.Printf("Issue action we don't handle: %s", action)
		return
	}
	sendNoticeToAll(r.Name, message)
}

func onMergeRequest(r *gitlab.Repo, m map[string]interface{}) {
	user := toMap(m["user"])
	username := toStr(user["username"])
	attrs := toMap(m["object_attributes"])
	iid := toInt(attrs["iid"])
	title := gitlab.ShortTitle(toStr(attrs["title"]))
	url := toStr(attrs["url"])
	action := toStr(attrs["action"])
	var message string
	switch action {
	case "open":
		message = fmt.Sprintf("%s opened !%d: %s - %s", username, iid, title, url)
	case "close":
		message = fmt.Sprintf("%s closed !%d: %s - %s", username, iid, title, url)
	case "reopen":
		message = fmt.Sprintf("%s reopened !%d: %s - %s", username, iid, title, url)
	default:
		log.Printf("Merge Request action we don't handle: %s", action)
		return
	}
	sendNoticeToAll(r.Name, message)
}
<commit_msg>Add missing returns<commit_after>// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"regexp"

	"github.com/mvdan/gibot/site/gitlab"
)

const listenAddr = ":9990"

func webhookListen() {
	for _, repo := range repos {
		listenRepo(repo)
	}

	log.Fatal(http.ListenAndServe(listenAddr, nil))
}

func listenRepo(repo *gitlab.Repo) {
	path := fmt.Sprintf("/webhooks/gitlab/%s", repo.Name)
	http.HandleFunc(path, gitlabHandler(repo.Name))
	log.Printf("Receiving webhooks for %s on %s%s", repo.Name, listenAddr, path)
}

func toInt(v interface{}) int {
	i, ok := v.(float64)
	if !ok {
		return 0
	}
	return int(i)
}

func toStr(v interface{}) string {
	s, ok := v.(string)
	if !ok {
		return ""
	}
	return s
}

func toSlice(v interface{}) []interface{} {
	l, ok := v.([]interface{})
	if !ok {
		return []interface{}{}
	}
	return l
}

func toMap(v interface{}) map[string]interface{} {
	m, ok := v.(map[string]interface{})
	if !ok {
		return map[string]interface{}{}
	}
	return m
}

func gitlabHandler(reponame string) func(http.ResponseWriter, *http.Request) {
	repo, e := repos[reponame]
	if !e {
		panic("unknown repo")
	}
	return func(w http.ResponseWriter, r *http.Request) {
		decoder := json.NewDecoder(r.Body)
		m := make(map[string]interface{})
		if err := decoder.Decode(&m); err != nil {
			log.Printf("Error decoding webhook data: %v", err)
			return
		}
		kind := toStr(m["object_kind"])
		switch kind {
		case "push":
			onPush(repo, m)
		case "issue":
			onIssue(repo, m)
		case "merge_request":
			onMergeRequest(repo, m)
		default:
			log.Printf("Webhook event we don't handle: %s", kind)
			return
		}
	}
}

var headBranch = regexp.MustCompile(`^refs/heads/(.*)$`)

func getBranch(ref string) string {
	if s := headBranch.FindStringSubmatch(ref); s != nil {
		return s[1]
	}
	log.Printf("Unknown branch ref format: %s", ref)
	return ""
}

func onPush(r *gitlab.Repo, m map[string]interface{}) {
	userId := toInt(m["user_id"])
	user, err := r.GetUser(userId)
	if err != nil {
		log.Printf("Unknown user: %v", err)
		return
	}
	username := user.Username
	count := toInt(m["total_commits_count"])
	var howMany string
	if count > 1 {
		howMany = fmt.Sprintf("%d commits", count)
	} else {
		howMany = fmt.Sprintf("%d commit", count)
	}
	branch := getBranch(toStr(m["ref"]))
	if branch == "" {
		return
	}
	before := toStr(m["before"])
	after := toStr(m["after"])
	url := r.CompareURL(before, after)
	message := fmt.Sprintf("%s pushed %s to %s - %s", username, howMany, branch, url)
	sendNoticeToAll(r.Name, message)
}

func onIssue(r *gitlab.Repo, m map[string]interface{}) {
	user := toMap(m["user"])
	username := toStr(user["username"])
	attrs := toMap(m["object_attributes"])
	iid := toInt(attrs["iid"])
	title := gitlab.ShortTitle(toStr(attrs["title"]))
	url := toStr(attrs["url"])
	action := toStr(attrs["action"])
	var message string
	switch action {
	case "open":
		message = fmt.Sprintf("%s opened #%d: %s - %s", username, iid, title, url)
	case "close":
		message = fmt.Sprintf("%s closed #%d: %s - %s", username, iid, title, url)
	case "reopen":
		message = fmt.Sprintf("%s reopened #%d: %s - %s", username, iid, title, url)
	default:
		log.Printf("Issue action we don't handle: %s", action)
		return
	}
	sendNoticeToAll(r.Name, message)
}

func onMergeRequest(r *gitlab.Repo, m map[string]interface{}) {
	user := toMap(m["user"])
	username := toStr(user["username"])
	attrs := toMap(m["object_attributes"])
	iid := toInt(attrs["iid"])
	title := gitlab.ShortTitle(toStr(attrs["title"]))
	url := toStr(attrs["url"])
	action := toStr(attrs["action"])
	var message string
	switch action {
	case "open":
		message = fmt.Sprintf("%s opened !%d: %s - %s", username, iid, title, url)
	case "close":
		message = fmt.Sprintf("%s closed !%d: %s - %s", username, iid, title, url)
	case "reopen":
		message = fmt.Sprintf("%s reopened !%d: %s - %s", username, iid, title, url)
	default:
		log.Printf("Merge Request action we don't handle: %s", action)
		return
	}
	sendNoticeToAll(r.Name, message)
}
<|endoftext|>


<commit_before>package controllers

import (
	"encoding/json"
	"io"
	"io/ioutil"
	"net/http"

	"github.com/alphagov/publishing-api/errornotifier"
	"github.com/alphagov/publishing-api/urlarbiter"
	"github.com/gorilla/mux"
	"gopkg.in/unrolled/render.v1"
)

var renderer = render.New(render.Options{})

type ContentStoreRequest struct {
	PublishingApp string `json:"publishing_app"`
}

type ErrorResponse struct {
	Message string `json:"message"`
}

func NewErrorResponse(message string, err error) *ErrorResponse {
	return &ErrorResponse{
		Message: message + ": " + err.Error(),
	}
}

func handleURLArbiterResponse(urlArbiterResponse urlarbiter.URLArbiterResponse, err error,
	w http.ResponseWriter, r *http.Request, errbitNotifier errornotifier.Notifier) {

	if err != nil {
		switch err {
		case urlarbiter.ConflictPathAlreadyReserved:
			renderer.JSON(w, http.StatusConflict, urlArbiterResponse)
		case urlarbiter.UnprocessableEntity:
			renderer.JSON(w, 422, urlArbiterResponse)
		default:
			message := "Unexpected error whilst registering with url-arbiter"
			renderer.JSON(w, http.StatusInternalServerError, NewErrorResponse(message, err))
		}
	}
}

func handleContentStoreResponse(resp *http.Response, err error, w http.ResponseWriter,
	r *http.Request, errbitNotifier errornotifier.Notifier) {

	if resp != nil {
		defer resp.Body.Close()
	}

	if w != nil {
		if err != nil {
			renderer.JSON(w, http.StatusInternalServerError, NewErrorResponse("Unexpected error in request to content-store", err))
			return
		}

		w.Header().Set("Content-Type", resp.Header.Get("Content-Type"))
		w.WriteHeader(resp.StatusCode)
		io.Copy(w, resp.Body)
	}
}

func extractBasePath(r *http.Request) string {
	urlParameters := mux.Vars(r)
	return urlParameters["base_path"]
}

func readRequest(w http.ResponseWriter, r *http.Request, errbitNotifier errornotifier.Notifier) ([]byte, *ContentStoreRequest) {
	requestBody, err := ioutil.ReadAll(r.Body)
	if err != nil {
		renderer.JSON(w, http.StatusInternalServerError, NewErrorResponse("Unexpected error in reading your request body", err))
		return nil, nil
	}

	var contentStoreRequest *ContentStoreRequest
	if err := json.Unmarshal(requestBody, &contentStoreRequest); err != nil {
		switch err.(type) {
		case *json.SyntaxError:
			renderer.JSON(w, http.StatusBadRequest, NewErrorResponse("Invalid JSON in request body", err))
		default:
			renderer.JSON(w, http.StatusInternalServerError, NewErrorResponse("Unexpected error unmarshalling your request body to JSON", err))
		}
		return nil, nil
	}

	return requestBody, contentStoreRequest
}
<commit_msg>Notify errbit on internal server errors<commit_after>package controllers

import (
	"encoding/json"
	"io"
	"io/ioutil"
	"net/http"

	"github.com/alphagov/publishing-api/errornotifier"
	"github.com/alphagov/publishing-api/urlarbiter"
	"github.com/gorilla/mux"
	"gopkg.in/unrolled/render.v1"
)

var renderer = render.New(render.Options{})

type ContentStoreRequest struct {
	PublishingApp string `json:"publishing_app"`
}

type ErrorResponse struct {
	Message string `json:"message"`
}

func NewErrorResponse(message string, err error) *ErrorResponse {
	return &ErrorResponse{
		Message: message + ": " + err.Error(),
	}
}

func handleURLArbiterResponse(urlArbiterResponse urlarbiter.URLArbiterResponse, err error,
	w http.ResponseWriter, r *http.Request, errbitNotifier errornotifier.Notifier) {

	if err != nil {
		switch err {
		case urlarbiter.ConflictPathAlreadyReserved:
			renderer.JSON(w, http.StatusConflict, urlArbiterResponse)
		case urlarbiter.UnprocessableEntity:
			renderer.JSON(w, 422, urlArbiterResponse)
		default:
			message := "Unexpected error whilst registering with url-arbiter"
			renderer.JSON(w, http.StatusInternalServerError, NewErrorResponse(message, err))
			if errbitNotifier != nil {
				errbitNotifier.Notify(err, r)
			}
		}
	}
}

func handleContentStoreResponse(resp *http.Response, err error, w http.ResponseWriter,
	r *http.Request, errbitNotifier errornotifier.Notifier) {

	if resp != nil {
		defer resp.Body.Close()
	}

	if w != nil {
		if err != nil {
			renderer.JSON(w, http.StatusInternalServerError, NewErrorResponse("Unexpected error in request to content-store", err))
			if errbitNotifier != nil {
				errbitNotifier.Notify(err, r)
			}
			return
		}

		w.Header().Set("Content-Type", resp.Header.Get("Content-Type"))
		w.WriteHeader(resp.StatusCode)
		io.Copy(w, resp.Body)
	}
}

func extractBasePath(r *http.Request) string {
	urlParameters := mux.Vars(r)
	return urlParameters["base_path"]
}

func readRequest(w http.ResponseWriter, r *http.Request, errbitNotifier errornotifier.Notifier) ([]byte, *ContentStoreRequest) {
	requestBody, err := ioutil.ReadAll(r.Body)
	if err != nil {
		renderer.JSON(w, http.StatusInternalServerError, NewErrorResponse("Unexpected error in reading your request body", err))
		if errbitNotifier != nil {
			errbitNotifier.Notify(err, r)
		}
		return nil, nil
	}

	var contentStoreRequest *ContentStoreRequest
	if err := json.Unmarshal(requestBody, &contentStoreRequest); err != nil {
		switch err.(type) {
		case *json.SyntaxError:
			renderer.JSON(w, http.StatusBadRequest, NewErrorResponse("Invalid JSON in request body", err))
		default:
			renderer.JSON(w, http.StatusInternalServerError, NewErrorResponse("Unexpected error unmarshalling your request body to JSON", err))
			if errbitNotifier != nil {
				errbitNotifier.Notify(err, r)
			}
		}
		return nil, nil
	}

	return requestBody, contentStoreRequest
}
<|endoftext|>


<commit_before>// +build windows

package plugin

import (
	"golang.org/x/sys/windows/svc/eventlog"

	log "github.com/sirupsen/logrus"
)

type logData eventLogHook

// eventLogHook allows logrus to log to Windows EventLog
type eventLogHook struct {
	elog *eventlog.Log
	src  string
}

func (p *plug) deinitLogger() error {
	if err := eventLogHook(p.e).Close(); err != nil {
		return err
	}

	return p.closeLogFile()
}

// initLogger creates a logger with an EventLog hook (requires admin privileges)
func (p *plug) initLogger() error {
	if err := eventlog.InstallAsEventCreate(p.params.Name,
		eventlog.Error|eventlog.Warning|eventlog.Info); err != nil {

		return err
	}

	el, err := eventlog.Open(p.params.Name)
	if err != nil {
		return err
	}

	lh := eventLogHook{
		elog: el,
		src:  p.params.Name,
	}

	p.e = logData(lh)

	p.l = log.New()
	p.l.Hooks.Add(lh)

	return p.openLogFile("") // no default
}

// Close closes the logger and uninstalls the source
func (h eventLogHook) Close() error {
	if err := h.elog.Close(); err != nil {
		return err
	}

	return eventlog.Remove(h.src)
}

// Fire logs an entry to the EventLog.
func (h eventLogHook) Fire(entry *log.Entry) error {
	message, err := entry.String()
	if err != nil {
		return err
	}

	switch entry.Level {
	case log.PanicLevel:
		fallthrough
	case log.FatalLevel:
		fallthrough
	case log.ErrorLevel:
		return h.elog.Error(1, message)

	case log.WarnLevel:
		return h.elog.Warning(10, message)

	case log.InfoLevel:
		fallthrough
	case log.DebugLevel:
		return h.elog.Info(100, message)

	default:
		panic("unsupported level in hooks")
	}
}

// Levels returns the supported logging levels.
func (eventLogHook) Levels() []log.Level {
	return log.AllLevels
}
<commit_msg>Fixes<commit_after>// +build windows

package plugin

import (
	"golang.org/x/sys/windows/svc/eventlog"

	log "github.com/sirupsen/logrus"
)

type logData eventLogHook

// eventLogHook allows logrus to log to Windows EventLog
type eventLogHook struct {
	elog *eventlog.Log
	src  string
}

func (p *plug) deinitLogger() error {
	if err := eventLogHook(p.e).Close(); err != nil {
		return err
	}

	return p.closeLogFile()
}

// initLogger creates a logger with an EventLog hook (requires admin privileges)
func (p *plug) initLogger() error {
	if err := eventlog.InstallAsEventCreate(p.params.Name,
		eventlog.Error|eventlog.Warning|eventlog.Info); err != nil {

		return err
	}

	el, err := eventlog.Open(p.params.Name)
	if err != nil {
		return err
	}

	lh := eventLogHook{
		elog: el,
		src:  p.params.Name,
	}

	p.e = logData(lh)

	p.l = log.New()
	p.l.Hooks.Add(lh)

	return p.openLogFile("") // no default
}

// Close closes the logger and uninstalls the source
func (h eventLogHook) Close() error {
	if err := h.elog.Close(); err != nil {
		return err
	}

	h.elog = nil

	return eventlog.Remove(h.src)
}

// Fire logs an entry to the EventLog.
func (h eventLogHook) Fire(entry *log.Entry) error {
	if h.elog == nil {
		return nil
	}

	message, err := entry.String()
	if err != nil {
		return err
	}

	switch entry.Level {
	case log.PanicLevel:
		fallthrough
	case log.FatalLevel:
		fallthrough
	case log.ErrorLevel:
		return h.elog.Error(1, message)

	case log.WarnLevel:
		return h.elog.Warning(10, message)

	case log.InfoLevel:
		fallthrough
	case log.DebugLevel:
		return h.elog.Info(100, message)

	default:
		panic("unsupported level in hooks")
	}
}

// Levels returns the supported logging levels.
func (eventLogHook) Levels() []log.Level {
	return log.AllLevels
}
<|endoftext|>


<commit_before>package utils

import (
	"fmt"
	"labix.org/v2/mgo/bson"
	"net"
	"regexp"
	"strconv"
)

type action struct {
	key  string
	text string
	data bson.ObjectId
}

type Menu struct {
	Actions []action
	Title   string
	Prompt  string
}

func NewMenu(text string) Menu {
	var menu Menu
	menu.Title = text
	menu.Prompt = "> "
	return menu
}

func (self *Menu) AddAction(key string, text string) {
	self.Actions = append(self.Actions, action{key: key, text: text})
}

func (self *Menu) AddActionData(key int, text string, data bson.ObjectId) {
	keyStr := strconv.Itoa(key)
	self.Actions = append(self.Actions, action{key: keyStr, text: text, data: data})
}

func (self *Menu) getAction(key string) action {
	for _, action := range self.Actions {
		if action.key == key {
			return action
		}
	}
	return action{}
}

func (self *Menu) HasAction(key string) bool {
	action := self.getAction(key)
	return action.key != ""
}

func (self *Menu) Exec(conn net.Conn, cm ColorMode) (string, bson.ObjectId) {
	for {
		self.Print(conn, cm)
		input := GetUserInput(conn, Colorize(cm, ColorWhite, self.Prompt))

		if input == "" {
			return "", ""
		}

		action := self.getAction(input)
		if action.key != "" {
			return action.key, action.data
		}
	}

	panic("Unexpected code path")
	return "", ""
}

func (self *Menu) Print(conn net.Conn, cm ColorMode) {
	border := Colorize(cm, ColorWhite, "-=-=-")
	title := Colorize(cm, ColorBlue, self.Title)
	WriteLine(conn, fmt.Sprintf("%s %s %s", border, title, border))

	for _, action := range self.Actions {
		regex := regexp.MustCompile("^\\[([^\\]]*)\\](.*)")
		matches := regex.FindStringSubmatch(action.text)

		actionText := action.text

		if len(matches) == 3 {
			actionText = Colorize(cm, ColorDarkBlue, "[") +
				Colorize(cm, ColorBlue, matches[1]) +
				Colorize(cm, ColorDarkBlue, "]") +
				Colorize(cm, ColorWhite, matches[2])
		}

		WriteLine(conn, "  "+actionText)
	}
}

// vim: nocindent
<commit_msg>Slightly more flexible interface for Exec and Print functions<commit_after>package utils

import (
	"fmt"
	"io"
	"labix.org/v2/mgo/bson"
	"regexp"
	"strconv"
)

type action struct {
	key  string
	text string
	data bson.ObjectId
}

type Menu struct {
	Actions []action
	Title   string
	Prompt  string
}

func NewMenu(text string) Menu {
	var menu Menu
	menu.Title = text
	menu.Prompt = "> "
	return menu
}

func (self *Menu) AddAction(key string, text string) {
	self.Actions = append(self.Actions, action{key: key, text: text})
}

func (self *Menu) AddActionData(key int, text string, data bson.ObjectId) {
	keyStr := strconv.Itoa(key)
	self.Actions = append(self.Actions, action{key: keyStr, text: text, data: data})
}

func (self *Menu) getAction(key string) action {
	for _, action := range self.Actions {
		if action.key == key {
			return action
		}
	}
	return action{}
}

func (self *Menu) HasAction(key string) bool {
	action := self.getAction(key)
	return action.key != ""
}

func (self *Menu) Exec(conn io.ReadWriter, cm ColorMode) (string, bson.ObjectId) {
	for {
		self.Print(conn, cm)
		input := GetUserInput(conn, Colorize(cm, ColorWhite, self.Prompt))

		if input == "" {
			return "", ""
		}

		action := self.getAction(input)
		if action.key != "" {
			return action.key, action.data
		}
	}

	panic("Unexpected code path")
	return "", ""
}

func (self *Menu) Print(conn io.Writer, cm ColorMode) {
	border := Colorize(cm, ColorWhite, "-=-=-")
	title := Colorize(cm, ColorBlue, self.Title)
	WriteLine(conn, fmt.Sprintf("%s %s %s", border, title, border))

	for _, action := range self.Actions {
		regex := regexp.MustCompile("^\\[([^\\]]*)\\](.*)")
		matches := regex.FindStringSubmatch(action.text)

		actionText := action.text

		if len(matches) == 3 {
			actionText = Colorize(cm, ColorDarkBlue, "[") +
				Colorize(cm, ColorBlue, matches[1]) +
				Colorize(cm, ColorDarkBlue, "]") +
				Colorize(cm, ColorWhite, matches[2])
		}

		WriteLine(conn, "  "+actionText)
	}
}

// vim: nocindent
<|endoftext|>


<commit_before>// Package utils provides zmq connection pool
package utils

import (
	"container/list"
	"fmt"
	"sync"
	"time"

	zmq "github.com/pebbe/zmq4"
)

type Pool struct {
	// Stack of idleConn with most recently used at the front.
	pool list.List

	// mu protects fields defined below.
	mu     sync.Mutex
	cond   *sync.Cond
	closed bool

	// 获取新连接的方法
	New func() (*zmq.Socket, error)

	Max int

	Wait bool //当连接池满的时候是否等待

	Life time.Duration
}

type PooledSocket struct {
	Soc    *zmq.Socket
	expire time.Time
	undone bool //未完成
	inUse  bool
	pool   *Pool
	ele    *list.Element //在list中位置
}

/* {{{ func NewPool(newFn func() (Conn, error), maxIdle int) *Pool
 * NewPool creates a new pool. This function is deprecated. Applications should
 * initialize the Pool fields directly as shown in example.
 */
func NewPool(newFn func() (*zmq.Socket, error), max int, life time.Duration) *Pool {
	return &Pool{New: newFn, Max: max, Life: life}
}

/* }}} */

/* {{{ func (p *Pool) Close()
 *
 */
func (p *Pool) Close() {
	p.mu.Lock()
	defer p.mu.Unlock()
	for e := p.pool.Front(); e != nil; e = e.Next() {
		e.Value.(*PooledSocket).Soc.Close()
	}
	p.pool.Init() // clear
	p.closed = true
	if p.cond != nil { //唤醒所有等待者
		p.cond.Broadcast()
	}
}

/* }}} */

/* {{{ func (p *Pool) Get() *Socket
 *
 */
func (p *Pool) Get() (*PooledSocket, error) {
	p.mu.Lock()
	defer p.mu.Unlock()

	if p.closed {
		return nil, fmt.Errorf("pool closed")
	}

	for { //不get到誓不罢休
		// Get pooled item.
		if e := p.pool.Front(); e != nil { //如果存在未使用的item,第一个肯定是
			ps := e.Value.(*PooledSocket)
			if !ps.inUse {
				ps.inUse = true
				p.pool.MoveToBack(e) //移到最后
				return ps, nil
			}
		}

		if p.Max <= 0 || p.pool.Len() < p.Max { //池子无限制或者还没满
			// create new.
			if soc, err := p.New(); err != nil { //无法新建
				return nil, err
			} else {
				ps := &PooledSocket{
					Soc:    soc,
					expire: time.Now().Add(p.Life),
					inUse:  true,
					pool:   p,
				}
				ps.ele = p.pool.PushBack(ps)
				return ps, nil
			}
		}

		if !p.Wait { //不等就结束
			return nil, fmt.Errorf("Pool full at %d", p.Max)
		}

		//等待被唤醒
		if p.cond == nil {
			p.cond = sync.NewCond(&p.mu)
		}
		p.cond.Wait()
	}
}

/* }}} */

/* {{{ func (ps *PooledSocket) Close()
 *
 */
func (ps *PooledSocket) Close() {
	p := ps.pool
	p.mu.Lock()
	defer p.mu.Unlock()
	if ps.undone == true {
		//指示需要销毁
		ps.Soc.Close()
		p.pool.Remove(ps.ele)
	} else {
		ps.inUse = false
		ps.expire = time.Now().Add(p.Life) //过期时间延长
		p.pool.MoveToFront(ps.ele)         //放到最前
	}
	if p.cond != nil { //唤醒一个, 如果有的话
		p.cond.Signal()
	}
}

/* }}} */

/* {{{ func (ps *PooledSocket) Do(timeout time.Duration, msg ...interface{}) (reply []string, err error)
 *
 */
func (ps *PooledSocket) Do(timeout time.Duration, msg ...interface{}) (reply []string, err error) {
	p := ps.pool
	p.mu.Lock()
	defer p.mu.Unlock()

	soc := ps.Soc
	poller := zmq.NewPoller()
	poller.Add(soc, zmq.POLLIN)

	// send
	if _, err := soc.SendMessage(msg...); err != nil {
		ps.undone = true
		return nil, err
	}

	// recv
	if sockets, err := poller.Poll(timeout); err != nil {
		ps.undone = true
		return nil, err
	} else if len(sockets) == 1 {
		return soc.RecvMessage(zmq.DONTWAIT)
	} else {
		ps.undone = true
		return nil, fmt.Errorf("time out!")
	}

	return
}

/* }}} */
<commit_msg>check pool full issue<commit_after>// Package utils provides zmq connection pool
package utils

import (
	"container/list"
	"fmt"
	"sync"
	"time"

	zmq "github.com/pebbe/zmq4"
)

type Pool struct {
	// Stack of idleConn with most recently used at the front.
	pool list.List

	// mu protects fields defined below.
	mu     sync.Mutex
	cond   *sync.Cond
	closed bool

	// logger
	logger PoolLogger
	prefix string

	// 获取新连接的方法
	New func() (*zmq.Socket, error)

	Max int

	Wait bool //当连接池满的时候是否等待

	Life time.Duration
}

type PoolLogger interface {
	Printf(format string, v ...interface{})
}

type PooledSocket struct {
	Soc    *zmq.Socket
	expire time.Time
	undone bool //未完成
	inUse  bool
	pool   *Pool
	ele    *list.Element //在list中位置
}

/* {{{ func NewPool(newFn func() (*zmq.Socket, error), ext ...interface{}) *Pool
 * NewPool creates a new pool. This function is deprecated. Applications should
 * initialize the Pool fields directly as shown in example.
 */
//func NewPool(newFn func() (*zmq.Socket, error), max int, life time.Duration) *Pool {
func NewPool(newFn func() (*zmq.Socket, error), ext ...interface{}) *Pool {
	var Max int = 100
	var Life time.Duration = 60 * time.Second
	var Logger PoolLogger
	var Prefix string

	if len(ext) > 0 {
		if max, ok := ext[0].(int); ok {
			Max = max
		}
	}
	if len(ext) > 1 {
		if life, ok := ext[1].(time.Duration); ok {
			Life = life
		}
	}
	if len(ext) > 2 {
		if logger, ok := ext[2].(PoolLogger); ok {
			Logger = logger
			Prefix = "[OgoPool]"
		}
	}
	return &Pool{New: newFn, Max: Max, Life: Life, logger: Logger, prefix: Prefix}
}

/* }}} */

/* {{{ func (p *Pool) Debug(format string, v ...interface{})
 *
 */
func (p *Pool) Debug(format string, v ...interface{}) {
	if p.logger == nil {
		return
	}
	p.logger.Printf(p.prefix+" "+format, v...)
}

/* }}} */

/* {{{ func (p *Pool) Close()
 *
 */
func (p *Pool) Close() {
	p.mu.Lock()
	defer p.mu.Unlock()
	for e := p.pool.Front(); e != nil; e = e.Next() {
		e.Value.(*PooledSocket).Soc.Close()
	}
	p.pool.Init() // clear
	p.closed = true
	if p.cond != nil { //唤醒所有等待者
		p.cond.Broadcast()
	}
}

/* }}} */

/* {{{ func (p *Pool) Get() *Socket
 *
 */
func (p *Pool) Get() (*PooledSocket, error) {
	p.mu.Lock()
	defer p.mu.Unlock()

	if p.closed {
		return nil, fmt.Errorf("pool closed")
	}

	for { //不get到誓不罢休
		// Get pooled item.
		//if e := p.pool.Front(); e != nil { //如果存在未使用的item,第一个肯定是
		//	ps := e.Value.(*PooledSocket)
		//	if !ps.inUse {
		//		ps.inUse = true
		//		p.pool.MoveToBack(e) //移到最后
		//		return ps, nil
		//	}
		//}
		depth := 0
		for e := p.pool.Front(); e != nil; e = e.Next() {
			depth++
			ps := e.Value.(*PooledSocket)
			if !ps.inUse {
				ps.inUse = true
				p.pool.MoveToBack(e) //移到最后
				p.Debug("find depth: %d, pool len: %d", depth, p.pool.Len())
				return ps, nil
			}
		}

		if p.Max <= 0 || p.pool.Len() < p.Max { //池子无限制或者还没满
			// create new.
			if soc, err := p.New(); err != nil { //无法新建
				return nil, err
			} else {
				ps := &PooledSocket{
					Soc:    soc,
					expire: time.Now().Add(p.Life),
					inUse:  true,
					pool:   p,
				}
				ps.ele = p.pool.PushBack(ps)
				return ps, nil
			}
		}

		if !p.Wait { //不等就结束
			return nil, fmt.Errorf("Pool full at %d", p.Max)
		}

		//等待被唤醒
		if p.cond == nil {
			p.cond = sync.NewCond(&p.mu)
		}
		p.cond.Wait()
	}
}

/* }}} */

/* {{{ func (ps *PooledSocket) Close()
 *
 */
func (ps *PooledSocket) Close() {
	p := ps.pool
	p.mu.Lock()
	defer p.mu.Unlock()
	if ps.undone == true {
		//指示需要销毁
		ps.Soc.Close()
		p.pool.Remove(ps.ele)
	} else {
		ps.inUse = false
		ps.expire = time.Now().Add(p.Life) //过期时间延长
		p.pool.MoveToFront(ps.ele)         //放到最前
	}
	if p.cond != nil { //唤醒一个, 如果有的话
		p.cond.Signal()
	}
}

/* }}} */

/* {{{ func (ps *PooledSocket) Do(timeout time.Duration, msg ...interface{}) (reply []string, err error)
 *
 */
func (ps *PooledSocket) Do(timeout time.Duration, msg ...interface{}) (reply []string, err error) {
	p := ps.pool
	p.mu.Lock()
	defer p.mu.Unlock()

	soc := ps.Soc
	poller := zmq.NewPoller()
	poller.Add(soc, zmq.POLLIN)

	// send
	if _, err := soc.SendMessage(msg...); err != nil {
		ps.undone = true
		return nil, err
	}

	// recv
	if sockets, err := poller.Poll(timeout); err != nil {
		ps.undone = true
		return nil, err
	} else if len(sockets) == 1 {
		return soc.RecvMessage(zmq.DONTWAIT)
	} else {
		ps.undone = true
		return nil, fmt.Errorf("time out!")
	}

	return
}

/* }}} */
<|endoftext|>


<commit_before>package utils

import (
	"database/sql"

	e "github.com/techjanitor/pram-post/errors"
)

// user struct
type User struct {
	Id        uint   `json:"id"`
	Name      string `json:"name"`
	Group     uint   `json:"group"`
	Confirmed bool   `json:"-"`
	Locked    bool   `json:"-"`
	Banned    bool   `json:"-"`
}

// get the user info from id
func (u *User) Info() (err error) {

	// this needs an id
	if u.Id == 0 {
		return e.ErrInvalidParam
	}

	err = db.QueryRow("SELECT usergroup_id,user_name,user_confirmed,user_locked,user_banned FROM users WHERE user_id = ?", u.Id).Scan(&u.Group, &u.Name, &u.Confirmed, &u.Locked, &u.Banned)
	if err == sql.ErrNoRows {
		return e.ErrNotFound
	} else if err != nil {
		return
	}

	return

}
<commit_msg>add email to user struct<commit_after>package utils

import (
	"database/sql"

	e "github.com/techjanitor/pram-post/errors"
)

// user struct
type User struct {
	Id        uint   `json:"id"`
	Name      string `json:"name"`
	Email     string `json:"email"`
	Group     uint   `json:"group"`
	Confirmed bool   `json:"-"`
	Locked    bool   `json:"-"`
	Banned    bool   `json:"-"`
}

// get the user info from id
func (u *User) Info() (err error) {

	// this needs an id
	if u.Id == 0 {
		return e.ErrInvalidParam
	}

	err = db.QueryRow("SELECT usergroup_id,user_name,user_email,user_confirmed,user_locked,user_banned FROM users WHERE user_id = ?", u.Id).Scan(&u.Group, &u.Name, &u.Email, &u.Confirmed, &u.Locked, &u.Banned)
	if err == sql.ErrNoRows {
		return e.ErrNotFound
	} else if err != nil {
		return
	}

	return

}
<|endoftext|>


<commit_before>// Copyright 2016-2021 The Libsacloud Authors
//
// 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 libsacloud

// Version バージョン
const Version = "2.18.0"
<commit_msg>Bump to v2.18.1<commit_after>// Copyright 2016-2021 The Libsacloud Authors
//
// 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 libsacloud

// Version バージョン
const Version = "2.18.1"
<|endoftext|>