<commit_before>package websocket

import (
	"errors"
	"runtime"

	"github.com/gopherjs/gopherjs/js"
	"honnef.co/go/js/dom"
	"honnef.co/go/js/util"
)

// ReadyState represents the state that a WebSocket is in. For more information
// about the available states, see
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Ready_state_constants
type ReadyState uint16

// Ready state constants from
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Ready_state_constants
const (
	Connecting ReadyState = 0 // The connection is not yet open.
	Open                  = 1 // The connection is open and ready to communicate.
	Closing               = 2 // The connection is in the process of closing.
	Closed                = 3 // The connection is closed or couldn't be opened.
)

// ErrSocketClosed is returned when an operation is attempted on a
// closed socket.
var ErrSocketClosed = errors.New("the socket has been closed")

type receiveItem struct {
	Error error
	Event *dom.MessageEvent
}

// WebSocket is a convenience wrapper around the browser's WebSocket
// implementation. For more information, see
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
type WebSocket struct {
	js.Object
	util.EventTarget

	// See https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Attributes
	// for information about these attributes.
	BinaryType     string     `js:"binaryType"`
	BufferedAmount uint32     `js:"bufferedAmount"`
	Extensions     string     `js:"extensions"`
	Protocol       string     `js:"protocol"`
	ReadyState     ReadyState `js:"readyState"`
	URL            string     `js:"url"`

	ch     chan *receiveItem
	openCh chan *js.Error
}

// New creates a new WebSocket. It blocks until the connection opens or throws
// an error.
func New(url string) (*WebSocket, error) {
	object := js.Global.Get("WebSocket").New(url)

	ws := &WebSocket{
		Object:      object,
		EventTarget: util.EventTarget{Object: object},
		ch:          make(chan *receiveItem),
		openCh:      make(chan *js.Error),
	}
	ws.init()

	// Wait for the WebSocket to open or error. See: onOpen & onClose.
	err, ok := <-ws.openCh
	if ok && err != nil {
		ws.Close() // Just in case the connection was open for some reason?
		return nil, err
	}

	return ws, nil
}

func (ws *WebSocket) init() {
	// Some browsers don't support Blobs. On top of that, []byte is converted to
	// Int8Array, which is handled similarly to ArrayBuffer.
	ws.BinaryType = "arraybuffer"

	// Add all of the event handlers.
	ws.EventTarget.AddEventListener("open", false, ws.onOpen)
	ws.EventTarget.AddEventListener("close", false, ws.onClose)
	ws.EventTarget.AddEventListener("error", false, ws.onError)
	ws.EventTarget.AddEventListener("message", false, ws.onMessage)
}

func (ws *WebSocket) onOpen(event js.Object) {
	close(ws.openCh)
}

func (ws *WebSocket) onClose(event js.Object) {
	if wasClean := event.Get("wasClean").Bool(); !wasClean {
		go func() {
			defer func() {
				// This feels extremely hacky, but I can't think of a better way
				// to do it. openCh is closed before the end of New(), but this
				// is one of the paths that can close it. The other is in
				// WebSocket.onOpen.
				e := recover()
				if e == nil {
					return
				}
				if e, ok := e.(runtime.Error); ok && e.Error() == "runtime error: send on closed channel" {
					return
				}
				panic(e)
			}()

			// If the close wasn't clean, we need to inform the openCh. This
			// allows New to return an error.
			ws.openCh <- &js.Error{Object: event}
			close(ws.openCh)
		}()
	}
	close(ws.ch)
}

func (ws *WebSocket) onError(event js.Object) {
	// TODO: Don't send to ws.ch when this is a connection error.
	// onError is called when a connection fails. Such errors shouldn't be sent
	// to ws.ch.
	go func() {
		// This allows Receive to return an error. It seems that many
		// WebSocket.send errors are handled this way.
		ws.ch <- &receiveItem{
			Event: nil,
			Error: &js.Error{Object: event},
		}
	}()
}

func (ws *WebSocket) onMessage(event js.Object) {
	go func() {
		ws.ch <- &receiveItem{
			Event: dom.WrapEvent(event).(*dom.MessageEvent),
			Error: nil,
		}
	}()
}

// SendRaw sends a message on the WebSocket. The data argument can be a string
// or a js.Object containing an ArrayBuffer.
//
// The helper functions SendString and SendBinary should be preferred to this.
func (ws *WebSocket) SendRaw(data interface{}) (err error) {
	defer func() {
		e := recover()
		if e == nil {
			return
		}
		if jsErr, ok := e.(*js.Error); ok && jsErr != nil {
			err = jsErr
		} else {
			panic(e)
		}
	}()
	ws.Object.Call("send", data)
	return nil
}

// SendString sends a string on the WebSocket. This is a helper method that
// calls SendRaw.
func (ws *WebSocket) SendString(data string) error {
	return ws.SendRaw(data)
}

// Write sends binary data on the WebSocket.
//
// Note: There are cases where the browser will throw an exception if it
// believes that the data passed to this function may be UTF-8.
func (ws *WebSocket) Write(p []byte) (int, error) {
	// We use Write to conform with the io.Writer interface.
	err := ws.SendRaw(p)
	if err != nil {
		return 0, err
	}
	return len(p), nil
}

// Receive receives one message from the WebSocket. It blocks until the message
// is received.
func (ws *WebSocket) Receive() (*dom.MessageEvent, error) {
	item, ok := <-ws.ch
	if !ok { // The channel has been closed
		return nil, ErrSocketClosed
	}
	return item.Event, item.Error
}

// Close closes the underlying WebSocket and cleans up any resources associated
// with the helper.
func (ws *WebSocket) Close() (err error) {
	defer func() {
		e := recover()
		if e == nil {
			return
		}
		if jsErr, ok := e.(*js.Error); ok && jsErr != nil {
			err = jsErr
		} else {
			panic(e)
		}
	}()
	ws.Object.Call("close")
	return nil
}
<commit_msg>Add ReadyState.String()<commit_after>package websocket

import (
	"errors"
	"runtime"

	"github.com/gopherjs/gopherjs/js"
	"honnef.co/go/js/dom"
	"honnef.co/go/js/util"
)

// ReadyState represents the state that a WebSocket is in. For more information
// about the available states, see
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Ready_state_constants
type ReadyState uint16

func (rs ReadyState) String() string {
	switch rs {
	case Connecting:
		return "Connecting"
	case Open:
		return "Open"
	case Closing:
		return "Closing"
	case Closed:
		return "Closed"
	default:
		return "Unknown"
	}
}

// Ready state constants from
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Ready_state_constants
const (
	Connecting ReadyState = 0 // The connection is not yet open.
	Open                  = 1 // The connection is open and ready to communicate.
	Closing               = 2 // The connection is in the process of closing.
	Closed                = 3 // The connection is closed or couldn't be opened.
)

// ErrSocketClosed is returned when an operation is attempted on a
// closed socket.
var ErrSocketClosed = errors.New("the socket has been closed")

type receiveItem struct {
	Error error
	Event *dom.MessageEvent
}

// WebSocket is a convenience wrapper around the browser's WebSocket
// implementation. For more information, see
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
type WebSocket struct {
	js.Object
	util.EventTarget

	// See https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Attributes
	// for information about these attributes.
	BinaryType     string     `js:"binaryType"`
	BufferedAmount uint32     `js:"bufferedAmount"`
	Extensions     string     `js:"extensions"`
	Protocol       string     `js:"protocol"`
	ReadyState     ReadyState `js:"readyState"`
	URL            string     `js:"url"`

	ch     chan *receiveItem
	openCh chan *js.Error
}

// New creates a new WebSocket. It blocks until the connection opens or throws
// an error.
func New(url string) (*WebSocket, error) {
	object := js.Global.Get("WebSocket").New(url)

	ws := &WebSocket{
		Object:      object,
		EventTarget: util.EventTarget{Object: object},
		ch:          make(chan *receiveItem),
		openCh:      make(chan *js.Error),
	}
	ws.init()

	// Wait for the WebSocket to open or error. See: onOpen & onClose.
	err, ok := <-ws.openCh
	if ok && err != nil {
		ws.Close() // Just in case the connection was open for some reason?
		return nil, err
	}

	return ws, nil
}

func (ws *WebSocket) init() {
	// Some browsers don't support Blobs. On top of that, []byte is converted to
	// Int8Array, which is handled similarly to ArrayBuffer.
	ws.BinaryType = "arraybuffer"

	// Add all of the event handlers.
	ws.EventTarget.AddEventListener("open", false, ws.onOpen)
	ws.EventTarget.AddEventListener("close", false, ws.onClose)
	ws.EventTarget.AddEventListener("error", false, ws.onError)
	ws.EventTarget.AddEventListener("message", false, ws.onMessage)
}

func (ws *WebSocket) onOpen(event js.Object) {
	close(ws.openCh)
}

func (ws *WebSocket) onClose(event js.Object) {
	if wasClean := event.Get("wasClean").Bool(); !wasClean {
		go func() {
			defer func() {
				// This feels extremely hacky, but I can't think of a better way
				// to do it. openCh is closed before the end of New(), but this
				// is one of the paths that can close it. The other is in
				// WebSocket.onOpen.
				e := recover()
				if e == nil {
					return
				}
				if e, ok := e.(runtime.Error); ok && e.Error() == "runtime error: send on closed channel" {
					return
				}
				panic(e)
			}()

			// If the close wasn't clean, we need to inform the openCh. This
			// allows New to return an error.
			ws.openCh <- &js.Error{Object: event}
			close(ws.openCh)
		}()
	}
	close(ws.ch)
}

func (ws *WebSocket) onError(event js.Object) {
	// TODO: Don't send to ws.ch when this is a connection error.
	// onError is called when a connection fails. Such errors shouldn't be sent
	// to ws.ch.
	go func() {
		// This allows Receive to return an error. It seems that many
		// WebSocket.send errors are handled this way.
		ws.ch <- &receiveItem{
			Event: nil,
			Error: &js.Error{Object: event},
		}
	}()
}

func (ws *WebSocket) onMessage(event js.Object) {
	go func() {
		ws.ch <- &receiveItem{
			Event: dom.WrapEvent(event).(*dom.MessageEvent),
			Error: nil,
		}
	}()
}

// SendRaw sends a message on the WebSocket. The data argument can be a string
// or a js.Object containing an ArrayBuffer.
//
// The helper functions SendString and SendBinary should be preferred to this.
func (ws *WebSocket) SendRaw(data interface{}) (err error) {
	defer func() {
		e := recover()
		if e == nil {
			return
		}
		if jsErr, ok := e.(*js.Error); ok && jsErr != nil {
			err = jsErr
		} else {
			panic(e)
		}
	}()
	ws.Object.Call("send", data)
	return nil
}

// SendString sends a string on the WebSocket. This is a helper method that
// calls SendRaw.
func (ws *WebSocket) SendString(data string) error {
	return ws.SendRaw(data)
}

// Write sends binary data on the WebSocket.
//
// Note: There are cases where the browser will throw an exception if it
// believes that the data passed to this function may be UTF-8.
func (ws *WebSocket) Write(p []byte) (int, error) {
	// We use Write to conform with the io.Writer interface.
	err := ws.SendRaw(p)
	if err != nil {
		return 0, err
	}
	return len(p), nil
}

// Receive receives one message from the WebSocket. It blocks until the message
// is received.
func (ws *WebSocket) Receive() (*dom.MessageEvent, error) {
	item, ok := <-ws.ch
	if !ok { // The channel has been closed
		return nil, ErrSocketClosed
	}
	return item.Event, item.Error
}

// Close closes the underlying WebSocket and cleans up any resources associated
// with the helper.
func (ws *WebSocket) Close() (err error) {
	defer func() {
		e := recover()
		if e == nil {
			return
		}
		if jsErr, ok := e.(*js.Error); ok && jsErr != nil {
			err = jsErr
		} else {
			panic(e)
		}
	}()
	ws.Object.Call("close")
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Florian Orben. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// prettybenchmarks: format go benchmarks into tables
//
// Usage: Pipe your benchmark results into "pb"
//    go test -bench=. [-benchmem] | pb
package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/apcera/termtables"
)

var (
	byWhitespace = regexp.MustCompile(`\s+`)
	byRuns       = regexp.MustCompile(`-\d+$`)
	byIterations = regexp.MustCompile(`(?i:)(Benchmark_?)`)
)

type (
	benchmark struct {
		info    *benchmarkInfo
		results *results
	}
	benchmarkInfo struct {
		hasFnIterations bool
		benchmemUsed    bool
		suggestedTiming string
	}
	results map[string][]*result
	result  struct {
		Name         string
		FnIterations int
		Runs         int
		Speed        float64
		Bps          int
		Aps          int
	}
)

type sortByFnIterations []*result

func (b sortByFnIterations) Len() int           { return len(b) }
func (b sortByFnIterations) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
func (b sortByFnIterations) Less(i, j int) bool { return b[i].FnIterations < b[j].FnIterations }

var (
	lines  [][]byte
	table  *termtables.Table
	bench  *benchmark
	timing string
)

func init() {
	setTiming()
}

func main() {

	reader := bufio.NewReader(os.Stdin)
	quit := make(chan bool)
	go loading(quit)

	for {
		text, err := reader.ReadBytes('\n')
		if err != nil {
			if err != io.EOF {
				panic(err)
			}
			break
		}
		lines = append(lines, text)
	}
	close(quit)

	bench = newBenchmark(lines)

	table = termtables.CreateTable()
	addTableHeader(table)
	addTableBody(table)

	fmt.Print("\r \n")
	fmt.Println(table.Render())
	fmt.Println(footer())
}

func newBenchmark(l [][]byte) *benchmark {
	results := newResults(l)
	return &benchmark{
		info:    newBenchmarkInfo(results),
		results: results,
	}
}

func newResults(l [][]byte) *results {
	benchMap := make(results)

	for _, l := range l[1 : len(l)-1] {
		bl := newResult(l)
		if bl != nil {
			if _, ok := benchMap[bl.Name]; !ok {
				benchMap[bl.Name] = make([]*result, 0)
			}
			benchMap[bl.Name] = append(benchMap[bl.Name], bl)
		}
	}

	for _, r := range benchMap {
		sort.Sort(sortByFnIterations(r))
	}

	return &benchMap
}

func newResult(b []byte) *result {
	var (
		name   string
		fnIter int
		bps    int
		aps    int
		err    error
		iter   int
		speed  float64
	)

	s := string(b)
	parts := byWhitespace.Split(s, -1)
	nameRuns := byRuns.ReplaceAllString(parts[0], "")
	nameIterations := byIterations.ReplaceAllString(nameRuns, "")
	lastIndex := strings.LastIndex(nameIterations, "_")

	if lastIndex > -1 {
		name = nameIterations[:lastIndex]
		fnIter, _ = strconv.Atoi(nameIterations[lastIndex+1:])
	} else {
		name = nameIterations
		fnIter = -1
	}

	//just print the line if it doesn't have the correct format
	if len(parts) < 4 {
		fmt.Println(s)
		return nil
	}

	iter, err = strconv.Atoi(parts[1])
	if err != nil {
		iter = -1
	}
	speed, err = strconv.ParseFloat(parts[2], 64)
	if err != nil {
		speed = -1
	}

	if len(parts) > 5 {
		bps, err = strconv.Atoi(parts[4])
		if err != nil {
			bps = -1
		}
		aps, err = strconv.Atoi(parts[6])
		if err != nil {
			aps = -1
		}
	} else {

		//without benchmem
		bps = -1
		aps = -1
	}

	return &result{
		Name:         name,
		FnIterations: fnIter,
		Runs:         iter,
		Speed:        speed,
		Bps:          bps,
		Aps:          aps,
	}
}

func newBenchmarkInfo(r *results) *benchmarkInfo {
	var (
		slowest         float64
		hasFnIterations bool
		benchmemUsed    bool
	)

	for _, bl := range *r {
		for _, l := range bl {

			if l.FnIterations > -1 {
				hasFnIterations = true
			}

			if l.Aps > -1 && l.Bps > -1 {
				benchmemUsed = true
			}

			if slowest < l.Speed {
				slowest = l.Speed
			}
		}
	}

	if timing == "" {
		switch {
		case slowest <= 1e3:
			timing = "ns"
		case slowest > 1e3 && slowest <= 1e6:
			timing = "µs"
		case slowest > 1e6 && slowest <= 1e9:
			timing = "ms"
		case slowest > 1e9:
			timing = "s"
		}
	}

	switch timing {
	case "ns":
		//ns is default, dont't do anything
	case "µs":
		updateSpeedVals(r, float64(1e3))
	case "ms":
		updateSpeedVals(r, float64(1e6))
	case "s":
		updateSpeedVals(r, float64(1e9))
	}

	return &benchmarkInfo{hasFnIterations, benchmemUsed, timing}
}

func updateSpeedVals(r *results, f float64) {
	for _, bl := range *r {
		for _, l := range bl {
			l.Speed = l.Speed / f
		}
	}
}

func footer() string {

	lastLine := bytes.Replace(
		bytes.TrimSpace(lines[len(lines)-1]),
		[]byte{9},
		[]byte{32, 32, 32, 32, 32},
		-1,
	)
	footer := make([]byte, 0, len(lastLine)*2+1)

	footer = append(
		footer,
		lastLine...,
	)

	footer = append(footer, byte(10))
	footer = append(footer, byte(43))
	for i := 0; i < len(lastLine)-2; i++ {
		footer = append(footer, byte(45))
	}
	footer = append(footer, byte(43))

	return bold(string(footer))
}

func addTableHeader(t *termtables.Table) {
	if bench.info.benchmemUsed {
		if bench.info.hasFnIterations {
			t.AddHeaders(bold("Name"), bold("Iterations"), bold("Runs"), bold(bench.info.suggestedTiming+"/op"), bold("B/op"), bold("allocations/op"), "")
		} else {
			t.AddHeaders(bold("Name"), bold("Runs"), bold(bench.info.suggestedTiming+"/op"), bold("B/op"), bold("allocations/op"), "")
		}
	} else {
		if bench.info.hasFnIterations {
			t.AddHeaders(bold("Name"), bold("Iterations"), bold("Runs"), bold(bench.info.suggestedTiming+"/op"), "")
		} else {
			t.AddHeaders(bold("Name"), bold("Runs"), bold(bench.info.suggestedTiming+"/op"), "")
		}
	}
}

func addTableBody(t *termtables.Table) {
	i := len(*bench.results)
	sorted := make([]string, 0, i)
	for name := range *bench.results {
		sorted = append(sorted, name)
	}
	sort.Sort(sort.StringSlice(sorted))

	for _, benchName := range sorted {
		results := (*bench.results)[benchName]

		for j, b := range results {
			var name string
			if j == 0 {
				name = bold(b.Name)
			}

			if bench.info.benchmemUsed {
				if bench.info.hasFnIterations {
					fnIterations := strconv.Itoa(b.FnIterations)

					if fnIterations == "-1" {
						fnIterations = ""
					}

					t.AddRow(name, fnIterations, b.Runs, b.Speed, b.Bps, b.Aps, "⬅")
				} else {
					t.AddRow(name, b.Runs, b.Speed, b.Bps, b.Aps, "⬅")
				}
			} else {
				if bench.info.hasFnIterations {
					fnIterations := strconv.Itoa(b.FnIterations)

					if fnIterations == "-1" {
						fnIterations = ""
					}

					t.AddRow(name, fnIterations, b.Runs, b.Speed, "⬅")
				} else {
					t.AddRow(name, b.Runs, b.Speed, "⬅")
				}
			}
		}

		i--
		if i > 0 {
			t.AddSeparator()
		}
	}

	t.SetAlign(termtables.AlignLeft, 1)
	t.SetAlign(termtables.AlignRight, 2)
	t.SetAlign(termtables.AlignRight, 3)
	t.SetAlign(termtables.AlignRight, 4)
	t.SetAlign(termtables.AlignRight, 5)
	t.SetAlign(termtables.AlignRight, 6)
}

func setTiming() {
	flag.Parse()
	args := flag.Args()

	if len(args) > 0 {
		if lowerArg := strings.ToLower(args[0]); lowerArg == "ns" || lowerArg == "us" || lowerArg == "µs" || lowerArg == "ms" || lowerArg == "s" {
			if lowerArg == "us" {
				lowerArg = "µs"
			}
			timing = lowerArg
		}
	}
}

func loading(q chan bool) {
	states := []string{"|", "/", "-", "\\", "|", "/", "–", "\\"}
	current := 0

	for {
		select {
		case <-time.Tick(150 * time.Millisecond):
			fmt.Printf("\r%s", states[current])
			if current == len(states)-1 {
				current = 0
			} else {
				current++
			}
		case <-q:
			break
		}
	}
}

func bold(s string) string {
	return fmt.Sprintf("\033[1m%s\033[0m", s)
}
<commit_msg>update package header comment to reflect last changes<commit_after>// Copyright 2015 Florian Orben. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// prettybenchmarks: format go benchmarks into tables
//
// Usage: Pipe your benchmark results into "pb"
//    go test -bench=. [-benchmem] | pb [ns/µs/ms/s]
package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/apcera/termtables"
)

var (
	byWhitespace = regexp.MustCompile(`\s+`)
	byRuns       = regexp.MustCompile(`-\d+$`)
	byIterations = regexp.MustCompile(`(?i:)(Benchmark_?)`)
)

type (
	benchmark struct {
		info    *benchmarkInfo
		results *results
	}
	benchmarkInfo struct {
		hasFnIterations bool
		benchmemUsed    bool
		suggestedTiming string
	}
	results map[string][]*result
	result  struct {
		Name         string
		FnIterations int
		Runs         int
		Speed        float64
		Bps          int
		Aps          int
	}
)

type sortByFnIterations []*result

func (b sortByFnIterations) Len() int           { return len(b) }
func (b sortByFnIterations) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
func (b sortByFnIterations) Less(i, j int) bool { return b[i].FnIterations < b[j].FnIterations }

var (
	lines  [][]byte
	table  *termtables.Table
	bench  *benchmark
	timing string
)

func init() {
	setTiming()
}

func main() {

	reader := bufio.NewReader(os.Stdin)
	quit := make(chan bool)
	go loading(quit)

	for {
		text, err := reader.ReadBytes('\n')
		if err != nil {
			if err != io.EOF {
				panic(err)
			}
			break
		}
		lines = append(lines, text)
	}
	close(quit)

	bench = newBenchmark(lines)

	table = termtables.CreateTable()
	addTableHeader(table)
	addTableBody(table)

	fmt.Print("\r \n")
	fmt.Println(table.Render())
	fmt.Println(footer())
}

func newBenchmark(l [][]byte) *benchmark {
	results := newResults(l)
	return &benchmark{
		info:    newBenchmarkInfo(results),
		results: results,
	}
}

func newResults(l [][]byte) *results {
	benchMap := make(results)

	for _, l := range l[1 : len(l)-1] {
		bl := newResult(l)
		if bl != nil {
			if _, ok := benchMap[bl.Name]; !ok {
				benchMap[bl.Name] = make([]*result, 0)
			}
			benchMap[bl.Name] = append(benchMap[bl.Name], bl)
		}
	}

	for _, r := range benchMap {
		sort.Sort(sortByFnIterations(r))
	}

	return &benchMap
}

func newResult(b []byte) *result {
	var (
		name   string
		fnIter int
		bps    int
		aps    int
		err    error
		iter   int
		speed  float64
	)

	s := string(b)
	parts := byWhitespace.Split(s, -1)
	nameRuns := byRuns.ReplaceAllString(parts[0], "")
	nameIterations := byIterations.ReplaceAllString(nameRuns, "")
	lastIndex := strings.LastIndex(nameIterations, "_")

	if lastIndex > -1 {
		name = nameIterations[:lastIndex]
		fnIter, _ = strconv.Atoi(nameIterations[lastIndex+1:])
	} else {
		name = nameIterations
		fnIter = -1
	}

	//just print the line if it doesn't have the correct format
	if len(parts) < 4 {
		fmt.Println(s)
		return nil
	}

	iter, err = strconv.Atoi(parts[1])
	if err != nil {
		iter = -1
	}
	speed, err = strconv.ParseFloat(parts[2], 64)
	if err != nil {
		speed = -1
	}

	if len(parts) > 5 {
		bps, err = strconv.Atoi(parts[4])
		if err != nil {
			bps = -1
		}
		aps, err = strconv.Atoi(parts[6])
		if err != nil {
			aps = -1
		}
	} else {

		//without benchmem
		bps = -1
		aps = -1
	}

	return &result{
		Name:         name,
		FnIterations: fnIter,
		Runs:         iter,
		Speed:        speed,
		Bps:          bps,
		Aps:          aps,
	}
}

func newBenchmarkInfo(r *results) *benchmarkInfo {
	var (
		slowest         float64
		hasFnIterations bool
		benchmemUsed    bool
	)

	for _, bl := range *r {
		for _, l := range bl {

			if l.FnIterations > -1 {
				hasFnIterations = true
			}

			if l.Aps > -1 && l.Bps > -1 {
				benchmemUsed = true
			}

			if slowest < l.Speed {
				slowest = l.Speed
			}
		}
	}

	if timing == "" {
		switch {
		case slowest <= 1e3:
			timing = "ns"
		case slowest > 1e3 && slowest <= 1e6:
			timing = "µs"
		case slowest > 1e6 && slowest <= 1e9:
			timing = "ms"
		case slowest > 1e9:
			timing = "s"
		}
	}

	switch timing {
	case "ns":
		//ns is default, dont't do anything
	case "µs":
		updateSpeedVals(r, float64(1e3))
	case "ms":
		updateSpeedVals(r, float64(1e6))
	case "s":
		updateSpeedVals(r, float64(1e9))
	}

	return &benchmarkInfo{hasFnIterations, benchmemUsed, timing}
}

func updateSpeedVals(r *results, f float64) {
	for _, bl := range *r {
		for _, l := range bl {
			l.Speed = l.Speed / f
		}
	}
}

func footer() string {

	lastLine := bytes.Replace(
		bytes.TrimSpace(lines[len(lines)-1]),
		[]byte{9},
		[]byte{32, 32, 32, 32, 32},
		-1,
	)
	footer := make([]byte, 0, len(lastLine)*2+1)

	footer = append(
		footer,
		lastLine...,
	)

	footer = append(footer, byte(10))
	footer = append(footer, byte(43))
	for i := 0; i < len(lastLine)-2; i++ {
		footer = append(footer, byte(45))
	}
	footer = append(footer, byte(43))

	return bold(string(footer))
}

func addTableHeader(t *termtables.Table) {
	if bench.info.benchmemUsed {
		if bench.info.hasFnIterations {
			t.AddHeaders(bold("Name"), bold("Iterations"), bold("Runs"), bold(bench.info.suggestedTiming+"/op"), bold("B/op"), bold("allocations/op"), "")
		} else {
			t.AddHeaders(bold("Name"), bold("Runs"), bold(bench.info.suggestedTiming+"/op"), bold("B/op"), bold("allocations/op"), "")
		}
	} else {
		if bench.info.hasFnIterations {
			t.AddHeaders(bold("Name"), bold("Iterations"), bold("Runs"), bold(bench.info.suggestedTiming+"/op"), "")
		} else {
			t.AddHeaders(bold("Name"), bold("Runs"), bold(bench.info.suggestedTiming+"/op"), "")
		}
	}
}

func addTableBody(t *termtables.Table) {
	i := len(*bench.results)
	sorted := make([]string, 0, i)
	for name := range *bench.results {
		sorted = append(sorted, name)
	}
	sort.Sort(sort.StringSlice(sorted))

	for _, benchName := range sorted {
		results := (*bench.results)[benchName]

		for j, b := range results {
			var name string
			if j == 0 {
				name = bold(b.Name)
			}

			if bench.info.benchmemUsed {
				if bench.info.hasFnIterations {
					fnIterations := strconv.Itoa(b.FnIterations)

					if fnIterations == "-1" {
						fnIterations = ""
					}

					t.AddRow(name, fnIterations, b.Runs, b.Speed, b.Bps, b.Aps, "⬅")
				} else {
					t.AddRow(name, b.Runs, b.Speed, b.Bps, b.Aps, "⬅")
				}
			} else {
				if bench.info.hasFnIterations {
					fnIterations := strconv.Itoa(b.FnIterations)

					if fnIterations == "-1" {
						fnIterations = ""
					}

					t.AddRow(name, fnIterations, b.Runs, b.Speed, "⬅")
				} else {
					t.AddRow(name, b.Runs, b.Speed, "⬅")
				}
			}
		}

		i--
		if i > 0 {
			t.AddSeparator()
		}
	}

	t.SetAlign(termtables.AlignLeft, 1)
	t.SetAlign(termtables.AlignRight, 2)
	t.SetAlign(termtables.AlignRight, 3)
	t.SetAlign(termtables.AlignRight, 4)
	t.SetAlign(termtables.AlignRight, 5)
	t.SetAlign(termtables.AlignRight, 6)
}

func setTiming() {
	flag.Parse()
	args := flag.Args()

	if len(args) > 0 {
		if lowerArg := strings.ToLower(args[0]); lowerArg == "ns" || lowerArg == "us" || lowerArg == "µs" || lowerArg == "ms" || lowerArg == "s" {
			if lowerArg == "us" {
				lowerArg = "µs"
			}
			timing = lowerArg
		}
	}
}

func loading(q chan bool) {
	states := []string{"|", "/", "-", "\\", "|", "/", "–", "\\"}
	current := 0

	for {
		select {
		case <-time.Tick(150 * time.Millisecond):
			fmt.Printf("\r%s", states[current])
			if current == len(states)-1 {
				current = 0
			} else {
				current++
			}
		case <-q:
			break
		}
	}
}

func bold(s string) string {
	return fmt.Sprintf("\033[1m%s\033[0m", s)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"

	"github.com/czerwonk/ovirt_api"
	"github.com/czerwonk/ovirt_exporter/host"
	"github.com/czerwonk/ovirt_exporter/storagedomain"
	"github.com/czerwonk/ovirt_exporter/vm"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/log"
)

const version string = "0.6.0"

var (
	showVersion     = flag.Bool("version", false, "Print version information.")
	listenAddress   = flag.String("web.listen-address", ":9325", "Address on which to expose metrics and web interface.")
	metricsPath     = flag.String("web.telemetry-path", "/metrics", "Path under which to expose metrics.")
	apiUrl          = flag.String("api.url", "https://localhost/ovirt-engine/api/", "API REST Endpoint")
	apiUser         = flag.String("api.username", "user@internal", "API username")
	apiPass         = flag.String("api.password", "", "API password")
	apiInsecureCert = flag.Bool("api.insecure-cert", false, "Skip verification for untrusted SSL/TLS certificates")
	withSnapshots   = flag.Bool("with-snapshots", true, "Collect snapshot metrics (can be time consuming in some cases)")
)

func init() {
	flag.Usage = func() {
		fmt.Println("Usage: ovirt_exporter [ ... ]\n\nParameters:")
		fmt.Println()
		flag.PrintDefaults()
	}
}

func main() {
	flag.Parse()

	if *showVersion {
		printVersion()
		os.Exit(0)
	}

	startServer()
}

func printVersion() {
	fmt.Println("ovirt_exporter")
	fmt.Printf("Version: %s\n", version)
	fmt.Println("Author(s): Daniel Czerwonk")
	fmt.Println("Metric exporter for oVirt engine")
}

func startServer() {
	log.Infof("Start"+
		"deing oVirt exporter (Version: %s)\n", version)
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
			<title>oVirt Exporter (Version ` + version + `)</title>

oVirt Exporter

<a href="` + *metricsPath + `">Metrics

More information:

github.com/czerwonk/ovirt_exporter

			`))
	})
	http.HandleFunc(*metricsPath, handleMetricsRequest)

	log.Infof("Listening for %s on %s\n", *metricsPath, *listenAddress)
	log.Fatal(http.ListenAndServe(*listenAddress, nil))
}

func handleMetricsRequest(w http.ResponseWriter, r *http.Request) {
	client, err := ovirt_api.NewClient(*apiUrl, *apiUser, *apiPass, *apiInsecureCert, &PromLogger{})
	if err != nil {
		log.Error(err)
		return
	}

	defer client.Close()

	reg := prometheus.NewRegistry()
	reg.MustRegister(vm.NewCollector(client, *withSnapshots))
	reg.MustRegister(host.NewCollector(client))
	reg.MustRegister(storagedomain.NewCollector(client))

	promhttp.HandlerFor(reg, promhttp.HandlerOpts{
		ErrorLog:      log.NewErrorLogger(),
		ErrorHandling: promhttp.ContinueOnError}).ServeHTTP(w, r)
}
<commit_msg>increased version<commit_after>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"

	"github.com/czerwonk/ovirt_api"
	"github.com/czerwonk/ovirt_exporter/host"
	"github.com/czerwonk/ovirt_exporter/storagedomain"
	"github.com/czerwonk/ovirt_exporter/vm"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/log"
)

const version string = "0.7.0"

var (
	showVersion     = flag.Bool("version", false, "Print version information.")
	listenAddress   = flag.String("web.listen-address", ":9325", "Address on which to expose metrics and web interface.")
	metricsPath     = flag.String("web.telemetry-path", "/metrics", "Path under which to expose metrics.")
	apiUrl          = flag.String("api.url", "https://localhost/ovirt-engine/api/", "API REST Endpoint")
	apiUser         = flag.String("api.username", "user@internal", "API username")
	apiPass         = flag.String("api.password", "", "API password")
	apiInsecureCert = flag.Bool("api.insecure-cert", false, "Skip verification for untrusted SSL/TLS certificates")
	withSnapshots   = flag.Bool("with-snapshots", true, "Collect snapshot metrics (can be time consuming in some cases)")
)

func init() {
	flag.Usage = func() {
		fmt.Println("Usage: ovirt_exporter [ ... ]\n\nParameters:")
		fmt.Println()
		flag.PrintDefaults()
	}
}

func main() {
	flag.Parse()

	if *showVersion {
		printVersion()
		os.Exit(0)
	}

	startServer()
}

func printVersion() {
	fmt.Println("ovirt_exporter")
	fmt.Printf("Version: %s\n", version)
	fmt.Println("Author(s): Daniel Czerwonk")
	fmt.Println("Metric exporter for oVirt engine")
}

func startServer() {
	log.Infof("Start"+
		"deing oVirt exporter (Version: %s)\n", version)
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
			<title>oVirt Exporter (Version ` + version + `)</title>

oVirt Exporter

<a href="` + *metricsPath + `">Metrics

More information:

github.com/czerwonk/ovirt_exporter

			`))
	})
	http.HandleFunc(*metricsPath, handleMetricsRequest)

	log.Infof("Listening for %s on %s\n", *metricsPath, *listenAddress)
	log.Fatal(http.ListenAndServe(*listenAddress, nil))
}

func handleMetricsRequest(w http.ResponseWriter, r *http.Request) {
	client, err := ovirt_api.NewClient(*apiUrl, *apiUser, *apiPass, *apiInsecureCert, &PromLogger{})
	if err != nil {
		log.Error(err)
		return
	}

	defer client.Close()

	reg := prometheus.NewRegistry()
	reg.MustRegister(vm.NewCollector(client, *withSnapshots))
	reg.MustRegister(host.NewCollector(client))
	reg.MustRegister(storagedomain.NewCollector(client))

	promhttp.HandlerFor(reg, promhttp.HandlerOpts{
		ErrorLog:      log.NewErrorLogger(),
		ErrorHandling: promhttp.ContinueOnError}).ServeHTTP(w, r)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"strings"
	"text/template"
)

const (
	templatesExtension = ".tpl"
	templatesFolder    = ".plates"
)

type plate struct {
	srcPath string
	outPath string
}

func newPlate(srcPath, outPath string) *plate {
	return &plate{
		srcPath: srcPath,
		outPath: outPath,
	}
}

func (p *plate) setup() {
	os.MkdirAll(p.srcPath, 0777)
}

func (p *plate) buildTemplatePath(name string) string {
	filename := fmt.Sprintf("%s%s", name, templatesExtension)
	return path.Join(p.srcPath, filename)
}

func (p *plate) buildOutPath(filepath string) string {
	return path.Join(p.outPath, filepath)
}

func (p *plate) templateFuncs(args ...string) template.FuncMap {
	return template.FuncMap{
		"args": func(i int) string {
			if i >= len(args) {
				fmt.Printf("The current template requires Args[%d].\n", i)
				fmt.Printf("Current Args are:\n")
				for index, arg := range args {
					fmt.Printf("  %d: %s\n", index, arg)
				}
				os.Exit(1)
			}

			return args[i]
		},
	}
}

func (p *plate) openTemplate(name string, args ...string) (*template.Template, error) {
	t := template.New("")
	t.Funcs(p.templateFuncs(args...))

	f, err := os.Open(p.buildTemplatePath(name))
	if err != nil {
		return t, err
	}
	defer f.Close()

	content, err := ioutil.ReadAll(f)
	if err != nil {
		return t, err
	}

	return t.Parse(string(content))
}

func (p *plate) availableTemplates() []string {
	pattern := path.Join(p.srcPath, fmt.Sprintf("*%s", templatesExtension))
	paths, err := filepath.Glob(pattern)
	if err != nil {
		log.Fatal(err)
	}

	var names []string

	for _, path := range paths {
		name, err := filepath.Rel(p.srcPath, path)
		if err != nil {
			log.Fatal(err)
		}

		names = append(names, name[0:len(name)-len(templatesExtension)])
	}

	return names
}

func (p *plate) execute(name string, args ...string) error {
	t, err := p.openTemplate(name, args...)
	if err != nil {
		return err
	}

	for _, tpl := range t.Templates() {
		name := tpl.Name()
		if name != "" {
			path := p.buildOutPath(name)
			dir := filepath.Dir(path)
			err := os.MkdirAll(dir, 0777)
			if err != nil {
				return err
			}

			f, err := os.Create(path)
			if err != nil {
				return err
			}

			buf := bytes.NewBuffer([]byte{})
			err = tpl.Execute(buf, nil)
			if err != nil {
				return err
			}

			tplContent := strings.TrimSpace(buf.String())
			io.WriteString(f, tplContent)
		}
	}

	return nil
}

func chooseTemplate(p *plate) string {
	templates := p.availableTemplates()
	if len(templates) < 1 {
		log.Fatalf("No templates available in %s", p.srcPath)
	}
	fmt.Printf("Available templates:\n\n")
	for i, path := range templates {
		fmt.Printf("  %d - %v\n", i+1, path)
	}

	fmt.Printf("\nChoose your template [1-%d]: ", len(templates))

	var i int
	fmt.Scanf("%d", &i)

	if i < 1 || i > len(templates) {
		return chooseTemplate(p)
	}

	return templates[i-1]
}

func main() {
	var tplName string

	flag.StringVar(&tplName, "t", "", "template name")
	flag.Parse()

	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}

	templatesPath := path.Join(usr.HomeDir, templatesFolder)

	args := os.Args

	if len(args) < 2 {
		fmt.Printf("Usage:\n  %s PROJECT_PATH\n", args[0])
		os.Exit(1)
	}

	p := newPlate(templatesPath, args[1])
	p.setup()
	name := chooseTemplate(p)
	err = p.execute(name, args...)
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>added ask func<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"strings"
	"text/template"
)

const (
	templatesExtension = ".tpl"
	templatesFolder    = ".plates"
)

type plate struct {
	srcPath string
	outPath string
}

func newPlate(srcPath, outPath string) *plate {
	return &plate{
		srcPath: srcPath,
		outPath: outPath,
	}
}

func (p *plate) setup() {
	os.MkdirAll(p.srcPath, 0777)
}

func (p *plate) buildTemplatePath(name string) string {
	filename := fmt.Sprintf("%s%s", name, templatesExtension)
	return path.Join(p.srcPath, filename)
}

func (p *plate) buildOutPath(filepath string) string {
	return path.Join(p.outPath, filepath)
}

func (p *plate) ask(name string) string {
	var val string
	fmt.Printf("> %s: ", name)
	fmt.Scanf("%s", &val)
	if val == "" {
		return p.ask(name)
	}

	return val
}

func (p *plate) templateFuncs(args ...string) template.FuncMap {
	vars := make(map[string]string)

	return template.FuncMap{
		"args": func(i int) string {
			if i >= len(args) {
				fmt.Printf("The current template requires Args[%d].\n", i)
				fmt.Printf("Current Args are:\n")
				for index, arg := range args {
					fmt.Printf("  %d: %s\n", index, arg)
				}
				os.Exit(1)
			}

			return args[i]
		},

		"var": func(name string) string {
			if val, ok := vars[name]; ok {
				return val
			}

			val := p.ask(name)
			vars[name] = val

			return val
		},
	}
}

func (p *plate) openTemplate(name string, args ...string) (*template.Template, error) {
	t := template.New("")
	t.Funcs(p.templateFuncs(args...))

	f, err := os.Open(p.buildTemplatePath(name))
	if err != nil {
		return t, err
	}
	defer f.Close()

	content, err := ioutil.ReadAll(f)
	if err != nil {
		return t, err
	}

	return t.Parse(string(content))
}

func (p *plate) availableTemplates() []string {
	pattern := path.Join(p.srcPath, fmt.Sprintf("*%s", templatesExtension))
	paths, err := filepath.Glob(pattern)
	if err != nil {
		log.Fatal(err)
	}

	var names []string

	for _, path := range paths {
		name, err := filepath.Rel(p.srcPath, path)
		if err != nil {
			log.Fatal(err)
		}

		names = append(names, name[0:len(name)-len(templatesExtension)])
	}

	return names
}

func (p *plate) execute(name string, args ...string) error {
	t, err := p.openTemplate(name, args...)
	if err != nil {
		return err
	}

	for _, tpl := range t.Templates() {
		name := tpl.Name()
		if name != "" {
			path := p.buildOutPath(name)
			dir := filepath.Dir(path)
			err := os.MkdirAll(dir, 0777)
			if err != nil {
				return err
			}

			f, err := os.Create(path)
			if err != nil {
				return err
			}

			buf := bytes.NewBuffer([]byte{})
			err = tpl.Execute(buf, nil)
			if err != nil {
				return err
			}

			tplContent := strings.TrimSpace(buf.String())
			io.WriteString(f, tplContent)
		}
	}

	return nil
}

func chooseTemplate(p *plate) string {
	templates := p.availableTemplates()
	if len(templates) < 1 {
		log.Fatalf("No templates available in %s", p.srcPath)
	}
	fmt.Printf("Available templates:\n\n")
	for i, path := range templates {
		fmt.Printf("  %d - %v\n", i+1, path)
	}

	fmt.Printf("\nChoose your template [1-%d]: ", len(templates))

	var i int
	fmt.Scanf("%d", &i)

	if i < 1 || i > len(templates) {
		return chooseTemplate(p)
	}

	return templates[i-1]
}

func main() {
	var tplName string

	flag.StringVar(&tplName, "t", "", "template name")
	flag.Parse()

	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}

	templatesPath := path.Join(usr.HomeDir, templatesFolder)

	args := os.Args

	if len(args) < 2 {
		fmt.Printf("Usage:\n  %s PROJECT_PATH\n", args[0])
		os.Exit(1)
	}

	p := newPlate(templatesPath, args[1])
	p.setup()
	name := chooseTemplate(p)
	err = p.execute(name, args...)
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/disiqueira/tindergo"
)

func main() {
	token := flag.String("token", "", "Your Facebook Token.")

	flag.Parse()

	if *token == "" {
		fmt.Println("You must provide a valid Facebook Token.")
		os.Exit(2)
	}

	t := tindergo.New()

	err := t.Authenticate(*token)
	checkError(err)

	profile, err := t.Profile()
	checkError(err)

	fmt.Println("You:")
	fmt.Println("Name: " + profile.Name)
	fmt.Println("")

	allRecs := make(map[string]tindergo.RecsCoreUser)

	countRecs := make(map[string]int)

	for j := 0; j <= 3; j++ {
		recs, err := t.RecsCore()
		checkError(err)

		for _, elem := range recs {
			_, exist := allRecs[elem.ID]
			if exist {
				countRecs[elem.ID] = countRecs[elem.ID] + 1
			} else {
				countRecs[elem.ID] = 1
				allRecs[elem.ID] = elem
			}
		}
	}

	for i, e := range allRecs {
		if countRecs[i] > 2 {
			fmt.Println(e.Name, float64((countRecs[i]*100)/4), "%")
		}
	}
}

// checkError Panic application if has an error returned.
func checkError(err error) {
	if err != nil {
		panic(err)
	}
}
<commit_msg>Changin output style<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/disiqueira/tindergo"
)

func main() {
	token := flag.String("token", "", "Your Facebook Token.")

	flag.Parse()

	if *token == "" {
		fmt.Println("You must provide a valid Facebook Token.")
		os.Exit(2)
	}

	t := tindergo.New()

	err := t.Authenticate(*token)
	checkError(err)

	profile, err := t.Profile()
	checkError(err)

	fmt.Println("You:")
	fmt.Println("Name: " + profile.Name)
	fmt.Println("")

	allRecs := make(map[string]tindergo.RecsCoreUser)

	countRecs := make(map[string]int)

	for j := 0; j <= 3; j++ {
		recs, err := t.RecsCore()
		checkError(err)

		for _, elem := range recs {
			_, exist := allRecs[elem.ID]
			if exist {
				countRecs[elem.ID] = countRecs[elem.ID] + 1
			} else {
				countRecs[elem.ID] = 1
				allRecs[elem.ID] = elem
			}
		}
	}

	fmt.Printf("|%40s|%70s|\n", "Your Matches", "Accuracy")
	fmt.Printf("|%40s|%70s|\n", "", "")
	for i, e := range allRecs {
		if countRecs[i] > 2 {
			fmt.Println(e.Name, float64((countRecs[i]*100)/4), "%")
		}
	}
}

// checkError Panic application if has an error returned.
func checkError(err error) {
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"syscall"
	"time"

	zipkin "github.com/openzipkin/zipkin-go-opentracing"

	"github.com/fsnotify/fsnotify"
	redigo "github.com/garyburd/redigo/redis"
	"github.com/go-kit/kit/endpoint"
	"github.com/go-kit/kit/log"
	stdopentracing "github.com/opentracing/opentracing-go"
	"github.com/pkg/errors"
	"github.com/pressly/chi"
	"github.com/solher/styx/account"
	"github.com/solher/styx/config"
	"github.com/solher/styx/helpers"
	"github.com/solher/styx/memory"
	"github.com/solher/styx/redis"
)

const (
	defaultHTTPAddr     = ":3000"
	defaultGRPCAddr     = ":8082"
	defaultAppdashAddr  = ""
	defaultZipkinAddr   = ""
	defaultConfigFile   = "./config.yml"
	defaultRedisAddr    = "redis:6379"
	defaultRedisMaxConn = 16
)

func main() {
	var (
		httpAddrEnv     = envString("HTTP_ADDR", defaultHTTPAddr)
		grpcAddrEnv     = envString("GRPC_ADDR", defaultGRPCAddr)
		zipkinAddrEnv   = envString("ZIPKIN_ADDR", defaultZipkinAddr)
		configFileEnv   = envString("CONFIG_FILE", defaultConfigFile)
		redisAddrEnv    = envString("REDIS_ADDR", defaultRedisAddr)
		redisMaxConnEnv = envInt("REDIS_MAX_CONN", defaultRedisMaxConn)

		httpAddr     = flag.String("httpAddr", httpAddrEnv, "HTTP listen address")
		_            = flag.String("grpcAddr", grpcAddrEnv, "gRPC (HTTP) listen address")
		zipkinAddr   = flag.String("zipkinAddr", zipkinAddrEnv, "Enable Zipkin tracing via server host:port")
		configFile   = flag.String("configFile", configFileEnv, "Config file location")
		redisAddr    = flag.String("redisAddr", redisAddrEnv, "Redis server address")
		redisMaxConn = flag.Int("redisMaxConn", redisMaxConnEnv, "Max simultaneous connections to Redis")
	)
	flag.Parse()

	exitCode := 0
	defer func() {
		os.Exit(exitCode)
	}()

	// Logging domain.
	var logger log.Logger
	{
		logger = log.NewLogfmtLogger(os.Stderr)
		logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC)
		logger = log.NewContext(logger).With("caller", log.DefaultCaller)
	}

	// Tracing domain.
	var tracer stdopentracing.Tracer
	{
		if *zipkinAddr != "" {
			logger := log.NewContext(logger).With("tracer", "Zipkin")
			logger.Log("msg", "sending trace to "+*zipkinAddr)
			collector, err := zipkin.NewScribeCollector(
				*zipkinAddr,
				3*time.Second,
				zipkin.ScribeLogger(logger),
			)
			if err != nil {
				logger.Log("err", errors.Wrap(err, "could create the Zipkin collector"))
				exitCode = 1
				return
			}
			tracer, err = zipkin.NewTracer(zipkin.NewRecorder(collector, false, "localhost:80", "styx"))
			if err != nil {
				logger.Log("err", errors.Wrap(err, "could not create the Zipkin tracer"))
				exitCode = 1
				return
			}
		} else {
			logger := log.NewContext(logger).With("tracer", "none")
			logger.Log("msg", "tracing disabled")
			tracer = stdopentracing.GlobalTracer() // no-op
		}
	}

	// Databases.
	redisPool := &redigo.Pool{
		Dial: func() (redigo.Conn, error) {
			return redigo.Dial("tcp", *redisAddr)
		},
		TestOnBorrow: func(c redigo.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
		MaxIdle: *redisMaxConn,
	}
	defer redisPool.Close()

	// Business domain.
	policyRepo := memory.NewPolicyRepository()
	resourceRepo := memory.NewResourceRepository()

	var accountService account.Service
	{
		sessionRepo := redis.NewSessionRepository(redisPool)
		accountService = account.NewService(sessionRepo)
	}

	// Endpoint domain.
	var createSessionEndpoint endpoint.Endpoint
	{
		createSessionEndpoint = account.MakeCreateSessionEndpoint(accountService)
		createSessionEndpoint = helpers.EndpointTracingMiddleware(createSessionEndpoint)
	}
	var findSessionByTokenEndpoint endpoint.Endpoint
	{
		findSessionByTokenEndpoint = account.MakeFindSessionByTokenEndpoint(accountService)
		findSessionByTokenEndpoint = helpers.EndpointTracingMiddleware(findSessionByTokenEndpoint)

	}
	var deleteSessionByTokenEndpoint endpoint.Endpoint
	{
		deleteSessionByTokenEndpoint = account.MakeDeleteSessionByTokenEndpoint(accountService)
		deleteSessionByTokenEndpoint = helpers.EndpointTracingMiddleware(deleteSessionByTokenEndpoint)

	}
	var deleteSessionsByOwnerTokenEndpoint endpoint.Endpoint
	{
		deleteSessionsByOwnerTokenEndpoint = account.MakeDeleteSessionsByOwnerTokenEndpoint(accountService)
		deleteSessionsByOwnerTokenEndpoint = helpers.EndpointTracingMiddleware(deleteSessionsByOwnerTokenEndpoint)
	}

	accountEndpoints := account.Endpoints{
		CreateSessionEndpoint:              createSessionEndpoint,
		FindSessionByTokenEndpoint:         findSessionByTokenEndpoint,
		DeleteSessionByTokenEndpoint:       deleteSessionByTokenEndpoint,
		DeleteSessionsByOwnerTokenEndpoint: deleteSessionsByOwnerTokenEndpoint,
	}

	// Mechanical domain.
	ctx := context.Background()
	errc := make(chan error)

	// Transport domain.
	accountHandler := account.MakeHTTPHandler(ctx, accountEndpoints, tracer, logger)

	r := chi.NewRouter()
	r.Mount("/account", accountHandler)

	conn, err := net.Listen("tcp", *httpAddr)
	if err != nil {
		logger.Log("err", errors.Wrap(err, "could not create a TCP connection"))
		exitCode = 1
		return
	}
	defer conn.Close()
	logger.Log("msg", "listening on "+*httpAddr+" (HTTP)")
	go func() {
		if err := http.Serve(conn, r); err != nil {
			errc <- errors.Wrap(err, "the http server returned an error")
			return
		}
	}()

	// Config watcher.
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		logger.Log("err", errors.Wrap(err, "could not create file watcher"))
		exitCode = 1
		return
	}
	defer watcher.Close()
	if err := watcher.Add(*configFile); err != nil {
		logger.Log("err", errors.Wrap(err, "could not add the config file to the watcher"))
		exitCode = 1
		return
	}
	logger.Log("msg", "watching config file at "+*configFile)
	go func() {
		for {
			select {
			case event := <-watcher.Events:
				if event.Op&fsnotify.Write == fsnotify.Write {
					file, err := ioutil.ReadFile(*configFile)
					if err != nil {
						logger.Log("err", errors.Wrap(err, "could not read the config file"))
						continue
					}
					config, err := config.FromFile(file)
					if err != nil {
						logger.Log("err", err)
						continue
					}
					if err := memory.SetPolicies(policyRepo, config.Policies); err != nil {
						logger.Log("err", err)
						continue
					}
					if err := memory.SetResources(resourceRepo, config.Resources); err != nil {
						logger.Log("err", err)
						continue
					}
					logger.Log("msg", "config successfully loaded")
				}
			}
		}
	}()
	watcher.Events <- fsnotify.Event{Op: fsnotify.Write} // Triggering manually conf file loading

	// Interrupt handler.
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		logger.Log(
			"signal", fmt.Sprintf("%s", <-c),
			"msg", "gracefully shutting down",
		)
		errc <- nil
	}()

	if err := <-errc; err != nil {
		logger.Log("err", err)
		exitCode = 1
	}
}

func envString(env, fallback string) string {
	e := os.Getenv(env)
	if e == "" {
		return fallback
	}
	return e
}

func envInt(env string, fallback int) int {
	e := os.Getenv(env)
	i, err := strconv.Atoi(e)
	if e == "" || err != nil {
		return fallback
	}
	return i
}
<commit_msg>Healthz endpoint added<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"syscall"
	"time"

	zipkin "github.com/openzipkin/zipkin-go-opentracing"

	"github.com/fsnotify/fsnotify"
	redigo "github.com/garyburd/redigo/redis"
	"github.com/go-kit/kit/endpoint"
	"github.com/go-kit/kit/log"
	stdopentracing "github.com/opentracing/opentracing-go"
	"github.com/pkg/errors"
	"github.com/pressly/chi"
	"github.com/solher/styx/account"
	"github.com/solher/styx/config"
	"github.com/solher/styx/helpers"
	"github.com/solher/styx/memory"
	"github.com/solher/styx/redis"
)

const (
	defaultHTTPAddr     = ":3000"
	defaultGRPCAddr     = ":8082"
	defaultAppdashAddr  = ""
	defaultZipkinAddr   = ""
	defaultConfigFile   = "./config.yml"
	defaultRedisAddr    = "redis:6379"
	defaultRedisMaxConn = 16
)

func main() {
	var (
		httpAddrEnv     = envString("HTTP_ADDR", defaultHTTPAddr)
		grpcAddrEnv     = envString("GRPC_ADDR", defaultGRPCAddr)
		zipkinAddrEnv   = envString("ZIPKIN_ADDR", defaultZipkinAddr)
		configFileEnv   = envString("CONFIG_FILE", defaultConfigFile)
		redisAddrEnv    = envString("REDIS_ADDR", defaultRedisAddr)
		redisMaxConnEnv = envInt("REDIS_MAX_CONN", defaultRedisMaxConn)

		httpAddr     = flag.String("httpAddr", httpAddrEnv, "HTTP listen address")
		_            = flag.String("grpcAddr", grpcAddrEnv, "gRPC (HTTP) listen address")
		zipkinAddr   = flag.String("zipkinAddr", zipkinAddrEnv, "Enable Zipkin tracing via server host:port")
		configFile   = flag.String("configFile", configFileEnv, "Config file location")
		redisAddr    = flag.String("redisAddr", redisAddrEnv, "Redis server address")
		redisMaxConn = flag.Int("redisMaxConn", redisMaxConnEnv, "Max simultaneous connections to Redis")
	)
	flag.Parse()

	exitCode := 0
	defer func() {
		os.Exit(exitCode)
	}()

	// Logging domain.
	var logger log.Logger
	{
		logger = log.NewLogfmtLogger(os.Stderr)
		logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC)
		logger = log.NewContext(logger).With("caller", log.DefaultCaller)
	}

	// Tracing domain.
	var tracer stdopentracing.Tracer
	{
		if *zipkinAddr != "" {
			logger := log.NewContext(logger).With("tracer", "Zipkin")
			logger.Log("msg", "sending trace to "+*zipkinAddr)
			collector, err := zipkin.NewScribeCollector(
				*zipkinAddr,
				3*time.Second,
				zipkin.ScribeLogger(logger),
			)
			if err != nil {
				logger.Log("err", errors.Wrap(err, "could create the Zipkin collector"))
				exitCode = 1
				return
			}
			tracer, err = zipkin.NewTracer(zipkin.NewRecorder(collector, false, "localhost:80", "styx"))
			if err != nil {
				logger.Log("err", errors.Wrap(err, "could not create the Zipkin tracer"))
				exitCode = 1
				return
			}
		} else {
			logger := log.NewContext(logger).With("tracer", "none")
			logger.Log("msg", "tracing disabled")
			tracer = stdopentracing.GlobalTracer() // no-op
		}
	}

	// Databases.
	redisPool := &redigo.Pool{
		Dial: func() (redigo.Conn, error) {
			return redigo.Dial("tcp", *redisAddr)
		},
		TestOnBorrow: func(c redigo.Conn, t time.Time) error {
			_, err := c.Do("PING")
			return err
		},
		MaxIdle: *redisMaxConn,
	}
	defer redisPool.Close()

	// Business domain.
	policyRepo := memory.NewPolicyRepository()
	resourceRepo := memory.NewResourceRepository()

	var accountService account.Service
	{
		sessionRepo := redis.NewSessionRepository(redisPool)
		accountService = account.NewService(sessionRepo)
	}

	// Endpoint domain.
	var createSessionEndpoint endpoint.Endpoint
	{
		createSessionEndpoint = account.MakeCreateSessionEndpoint(accountService)
		createSessionEndpoint = helpers.EndpointTracingMiddleware(createSessionEndpoint)
	}
	var findSessionByTokenEndpoint endpoint.Endpoint
	{
		findSessionByTokenEndpoint = account.MakeFindSessionByTokenEndpoint(accountService)
		findSessionByTokenEndpoint = helpers.EndpointTracingMiddleware(findSessionByTokenEndpoint)

	}
	var deleteSessionByTokenEndpoint endpoint.Endpoint
	{
		deleteSessionByTokenEndpoint = account.MakeDeleteSessionByTokenEndpoint(accountService)
		deleteSessionByTokenEndpoint = helpers.EndpointTracingMiddleware(deleteSessionByTokenEndpoint)

	}
	var deleteSessionsByOwnerTokenEndpoint endpoint.Endpoint
	{
		deleteSessionsByOwnerTokenEndpoint = account.MakeDeleteSessionsByOwnerTokenEndpoint(accountService)
		deleteSessionsByOwnerTokenEndpoint = helpers.EndpointTracingMiddleware(deleteSessionsByOwnerTokenEndpoint)
	}

	accountEndpoints := account.Endpoints{
		CreateSessionEndpoint:              createSessionEndpoint,
		FindSessionByTokenEndpoint:         findSessionByTokenEndpoint,
		DeleteSessionByTokenEndpoint:       deleteSessionByTokenEndpoint,
		DeleteSessionsByOwnerTokenEndpoint: deleteSessionsByOwnerTokenEndpoint,
	}

	// Mechanical domain.
	ctx := context.Background()
	errc := make(chan error)

	// Transport domain.
	accountHandler := account.MakeHTTPHandler(ctx, accountEndpoints, tracer, logger)

	r := chi.NewRouter()
	r.Get("/healthz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })
	r.Mount("/account", accountHandler)

	conn, err := net.Listen("tcp", *httpAddr)
	if err != nil {
		logger.Log("err", errors.Wrap(err, "could not create a TCP connection"))
		exitCode = 1
		return
	}
	defer conn.Close()
	logger.Log("msg", "listening on "+*httpAddr+" (HTTP)")
	go func() {
		if err := http.Serve(conn, r); err != nil {
			errc <- errors.Wrap(err, "the http server returned an error")
			return
		}
	}()

	// Config watcher.
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		logger.Log("err", errors.Wrap(err, "could not create file watcher"))
		exitCode = 1
		return
	}
	defer watcher.Close()
	if err := watcher.Add(*configFile); err != nil {
		logger.Log("err", errors.Wrap(err, "could not add the config file to the watcher"))
		exitCode = 1
		return
	}
	logger.Log("msg", "watching config file at "+*configFile)
	go func() {
		for {
			select {
			case event := <-watcher.Events:
				if event.Op&fsnotify.Write == fsnotify.Write {
					file, err := ioutil.ReadFile(*configFile)
					if err != nil {
						logger.Log("err", errors.Wrap(err, "could not read the config file"))
						continue
					}
					config, err := config.FromFile(file)
					if err != nil {
						logger.Log("err", err)
						continue
					}
					if err := memory.SetPolicies(policyRepo, config.Policies); err != nil {
						logger.Log("err", err)
						continue
					}
					if err := memory.SetResources(resourceRepo, config.Resources); err != nil {
						logger.Log("err", err)
						continue
					}
					logger.Log("msg", "config successfully loaded")
				}
			}
		}
	}()
	watcher.Events <- fsnotify.Event{Op: fsnotify.Write} // Triggering manually conf file loading

	// Interrupt handler.
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		logger.Log(
			"signal", fmt.Sprintf("%s", <-c),
			"msg", "gracefully shutting down",
		)
		errc <- nil
	}()

	if err := <-errc; err != nil {
		logger.Log("err", err)
		exitCode = 1
	}
}

func envString(env, fallback string) string {
	e := os.Getenv(env)
	if e == "" {
		return fallback
	}
	return e
}

func envInt(env string, fallback int) int {
	e := os.Getenv(env)
	i, err := strconv.Atoi(e)
	if e == "" || err != nil {
		return fallback
	}
	return i
}
<|endoftext|>


<commit_before>package main

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

	"./model"
	"github.com/rs/cors"
	"goji.io"
	"goji.io/pat"
	"golang.org/x/net/context"
	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

func main() {
	//trying to connect to mongo
	db, err := mgo.Dial("localhost:27017")
	if err != nil {
		//something happens when dialing
		log.Fatal("Cannot dial mongo", err)
	}
	//clear when we're done
	defer db.Close()
	ensureIndex(db)
	//initiate new multiplexer
	mux := goji.NewMux()
	//register all handler for each end point
	mux.HandleFuncC(pat.Get("/swits/:switId"), getSwit(db))
	mux.HandleFuncC(pat.Get("/swits"), getAllSwits(db))
	mux.HandleFuncC(pat.Post("/swits"), createSwit(db))
	mux.HandleFuncC(pat.Post("/users"), addUser(db))
	mux.HandleFuncC(pat.Get("/users/:uid"), getUser(db))
	//to allow cross origin
	handler := cors.Default().Handler(mux)
	//finally, listen and serve in designated host and port
	http.ListenAndServe(":3001", handler)
}

func ensureIndex(s *mgo.Session) {
	session := s.Copy()
	defer session.Close()

	c := session.DB("swit_app").C("users")

	index := mgo.Index{
		Key:        []string{"uid"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}
	err := c.EnsureIndex(index)
	if err != nil {
		log.Fatal(err)
	}
}

func addUser(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get the body request
		var user model.User
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&user)
		if err != nil {
			fmt.Println("Incorrect body of request")
			return
		}
		c := session.DB("swit_app").C("users")
		//add new user to database
		err = c.Insert(user)
		if err != nil {
			if mgo.IsDup(err) {
				//check if it's duplicate, if so return something to notify
				ResponseSimpleMessage("User is exist", false, w)
				return
			}
			//failed to Insert
			fmt.Println("Failed to insert a new user")
			log.Fatal(err)
		}

		ResponseSimpleMessage("Successfully added a new user", true, w)
	}
}

func getUser(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get query param
		uid := pat.Param(ctx, "uid")
		//get collection of users
		c := session.DB("swit_app").C("users")
		//prepare the model
		var user model.User
		//fetch the user in db
		err := c.Find(bson.M{"uid": uid}).One(&user)
		if err != nil {
			//failed to Insert
			fmt.Printf("Unable to search user with uid: %s", uid)
			log.Fatal(err)
		}
		//toJson
		respBody, _ := json.Marshal(user)
		ResponseWithJSON(w, respBody, http.StatusOK)
	}
}

func createSwit(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get the body request
		var swit model.Swit
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&swit)
		if err != nil {
			fmt.Println("Incorrect body of request")
			return
		}

		//should be now
		swit.Time = time.Now()
		swit.SwitId = bson.NewObjectIdWithTime(swit.Time)
		//TODO: should get the user id from req too
		swit.UserId = bson.NewObjectId()
		fmt.Println("incoming swit: ", swit)

		c := session.DB("swit_app").C("swits")
		//insert the new swit and catch error
		err = c.Insert(swit)
		if err != nil {
			//failed to Insert
			fmt.Println("Failed to insert a new book")
			log.Fatal(err)
		}
		resBody := SimpleResponse{"Successfully added a new book", true}
		fmt.Println("res body content: ", resBody)
		//toJson
		json, _ := json.Marshal(resBody)
		//write a response back
		ResponseWithJSON(w, json, http.StatusOK)
	}
}

func getAllSwits(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//prepare for the response
		var swits []*model.Swit
		//catch them all and if there is an error
		err := session.DB("swit_app").C("swits").Find(nil).All(&swits)
		if err != nil {
			//let's get panic instead
			panic(err)
		}
		// _ as blank identifier,the function returns multiple values, but we don't care
		switsJSON, _ := json.Marshal(swits)
		//write a response
		ResponseWithJSON(w, switsJSON, http.StatusOK)
	}
}

func getSwit(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get query param out of the http request
		switID := pat.Param(ctx, "switId")
		fmt.Printf("swit id is %s \n", switID)
		//get swits collection
		c := session.DB("swit_app").C("swits")
		var swit model.Swit
		//convert to object id
		oid := bson.ObjectIdHex(switID)
		err := c.Find(bson.M{"switId": oid}).One(&swit)
		if err != nil {
			panic(err)
		}

		fmt.Printf("the swit object is : %s \n", swit)
		//toJson
		respBody, _ := json.Marshal(swit)
		ResponseWithJSON(w, respBody, http.StatusOK)
	}
}

func ResponseSimpleMessage(message string, success bool, w http.ResponseWriter) {
	resBody := SimpleResponse{message, success}
	fmt.Println("res body content: ", resBody)
	//toJson
	json, _ := json.Marshal(resBody)
	//write a response back
	ResponseWithJSON(w, json, http.StatusOK)
}

func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {
	fmt.Println("Response Body : ", string(json))
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.WriteHeader(code)
	w.Write(json)
}

type SimpleResponse struct {
	Message string `json:"message"`
	Success bool   `json:"success"`
}
<commit_msg>Remove fatal() from error handling<commit_after>package main

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

	"./model"
	"github.com/rs/cors"
	"goji.io"
	"goji.io/pat"
	"golang.org/x/net/context"
	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

func main() {
	//trying to connect to mongo
	db, err := mgo.Dial("localhost:27017")
	if err != nil {
		//something happens when dialing
		log.Fatal("Cannot dial mongo", err)
	}
	//clear when we're done
	defer db.Close()
	ensureIndex(db)
	//initiate new multiplexer
	mux := goji.NewMux()
	//register all handler for each end point
	mux.HandleFuncC(pat.Get("/swits/:switId"), getSwit(db))
	mux.HandleFuncC(pat.Get("/swits"), getAllSwits(db))
	mux.HandleFuncC(pat.Post("/swits"), createSwit(db))
	mux.HandleFuncC(pat.Post("/users"), addUser(db))
	mux.HandleFuncC(pat.Get("/users/:uid"), getUser(db))
	//to allow cross origin
	handler := cors.Default().Handler(mux)
	//finally, listen and serve in designated host and port
	http.ListenAndServe(":3001", handler)
}

func ensureIndex(s *mgo.Session) {
	session := s.Copy()
	defer session.Close()

	c := session.DB("swit_app").C("users")

	index := mgo.Index{
		Key:        []string{"uid"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}
	err := c.EnsureIndex(index)
	if err != nil {
		log.Fatal(err)
	}
}

func addUser(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get the body request
		var user model.User
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&user)
		if err != nil {
			fmt.Println("Incorrect body of request")
			return
		}
		c := session.DB("swit_app").C("users")
		//add new user to database
		err = c.Insert(user)
		if err != nil {
			if mgo.IsDup(err) {
				//check if it's duplicate, if so return something to notify
				ResponseSimpleMessage("User is exist", false, w)
				return
			}
			//failed to Insert
			fmt.Println("Failed to insert a new user")
			ResponseSimpleMessage("Failed to insert a new user", false, w)
			return
		}

		ResponseSimpleMessage("Successfully added a new user", true, w)
	}
}

func getUser(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//get query param
		uid := pat.Param(ctx, "uid")
		if len(uid) <= 0 {
			fmt.Println("Empty uid")
			ResponseSimpleMessage("No uid", false, w)
			return
		}
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get collection of users
		c := session.DB("swit_app").C("users")
		//prepare the model
		var user model.User
		//fetch the user in db
		err := c.Find(bson.M{"uid": uid}).One(&user)
		if err != nil {
			//failed to Insert
			fmt.Printf("Unable to search user with uid: %s", uid)
			ResponseSimpleMessage("Unable to find the user", false, w)
		}
		//toJson
		respBody, _ := json.Marshal(user)
		ResponseWithJSON(w, respBody, http.StatusOK)
	}
}

func createSwit(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get the body request
		var swit model.Swit
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&swit)
		if err != nil {
			fmt.Println("Incorrect body of request")
			return
		}

		//should be now
		swit.Time = time.Now()
		swit.SwitId = bson.NewObjectIdWithTime(swit.Time)
		//TODO: should get the user id from req too
		swit.UserId = bson.NewObjectId()
		fmt.Println("incoming swit: ", swit)

		c := session.DB("swit_app").C("swits")
		//insert the new swit and catch error
		err = c.Insert(swit)
		if err != nil {
			//failed to Insert
			fmt.Println("Failed to insert a new swit")
			ResponseSimpleMessage("Failed to insert a new swit", false, w)
		}
		resBody := SimpleResponse{"Successfully added a new swit", true}
		fmt.Println("res body content: ", resBody)
		//toJson
		json, _ := json.Marshal(resBody)
		//write a response back
		ResponseWithJSON(w, json, http.StatusOK)
	}
}

func getAllSwits(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//prepare for the response
		var swits []*model.Swit
		//catch them all and if there is an error
		err := session.DB("swit_app").C("swits").Find(nil).All(&swits)
		if err != nil {
			//let's get panic instead
			panic(err)
		}
		// _ as blank identifier,the function returns multiple values, but we don't care
		switsJSON, _ := json.Marshal(swits)
		//write a response
		ResponseWithJSON(w, switsJSON, http.StatusOK)
	}
}

func getSwit(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get query param out of the http request
		switID := pat.Param(ctx, "switId")
		fmt.Printf("swit id is %s \n", switID)
		//get swits collection
		c := session.DB("swit_app").C("swits")
		var swit model.Swit
		//convert to object id
		oid := bson.ObjectIdHex(switID)
		err := c.Find(bson.M{"switId": oid}).One(&swit)
		if err != nil {
			panic(err)
		}

		fmt.Printf("the swit object is : %s \n", swit)
		//toJson
		respBody, _ := json.Marshal(swit)
		ResponseWithJSON(w, respBody, http.StatusOK)
	}
}

func ResponseSimpleMessage(message string, success bool, w http.ResponseWriter) {
	resBody := SimpleResponse{message, success}
	fmt.Println("res body content: ", resBody)
	//toJson
	json, _ := json.Marshal(resBody)
	//write a response back
	ResponseWithJSON(w, json, http.StatusOK)
}

func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {
	fmt.Println("Response Body : ", string(json))
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.WriteHeader(code)
	w.Write(json)
}

type SimpleResponse struct {
	Message string `json:"message"`
	Success bool   `json:"success"`
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
)

var (
	ivy = flag.String("ivy", "ivy", "the path to ivy")
)

func main() {
	flag.Usage = usage
	flag.Parse()
}

func usage() {
	fmt.Fprintf(os.Stderr, "Usage: pike [flags]\n")
	fmt.Fprintf(os.Stderr, "Flags:\n")
	flag.PrintDefaults()
	os.Exit(2)
}
<commit_msg>Implement the main functionality<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"os/exec"

	"github.com/peterh/liner"
)

var (
	path = flag.String("ivy", "ivy", "the path to ivy")
)

func main() {
	flag.Usage = usage
	flag.Parse()

	reader, writer := io.Pipe()

	liner := liner.NewLiner()
	liner.SetCtrlCAborts(true)
	defer liner.Close()

	cmd := exec.Command(*path)
	cmd.Stdin, cmd.Stdout, cmd.Stderr = reader, os.Stdout, os.Stderr
	cmd.Start()

	for {
		if line, err := liner.Prompt(""); err == nil {
			liner.AppendHistory(line)
			fmt.Fprintln(writer, line)
		} else {
			break
		}
	}
}

func usage() {
	fmt.Fprintf(os.Stderr, "Usage: pike [flags]\n")
	fmt.Fprintf(os.Stderr, "Flags:\n")
	flag.PrintDefaults()
	os.Exit(2)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

var (
	key    []byte
	logger = logrus.New()
)

func inputFile(context *cli.Context) (*os.File, error) {
	if context.GlobalBool("stdin") {
		return os.Stdin, nil
	}
	in, err := os.Open(context.Args().Get(0))
	if err != nil {
		return nil, err
	}
	return in, nil
}

func stdoutArgIndex(context *cli.Context) int {
	if !context.GlobalBool("stdin") {
		return 1
	}
	return 0
}

func outputFile(context *cli.Context) (*os.File, error) {
	if context.GlobalBool("stdout") {
		return os.Stdout, nil
	}
	out, err := os.Create(context.Args().Get(stdoutArgIndex(context)))
	if err != nil {
		return nil, err
	}
	return out, nil
}

func do(context *cli.Context, key []byte, a Action) error {
	in, err := inputFile(context)
	if err != nil {
		return err
	}
	defer in.Close()

	out, err := outputFile(context)
	if err != nil {
		return err
	}
	defer out.Close()
	p, err := newProcessor(in, out, key, a)
	if err != nil {
		return err
	}
	return p.Run()
}

func getAction(context *cli.Context) Action {
	switch {
	case context.GlobalBool("encrypt"):
		return Encrypt
	case context.GlobalBool("decrypt"):
		return Decrypt
	}
	return 0
}

func main() {
	app := cli.NewApp()
	app.Name = "crypt"
	app.Version = "1"
	app.Author = "@crosbymichael"
	app.Usage = "encrypt and decrypt files easily"
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "key", Usage: "key to use for the encryption algo"},
		cli.BoolFlag{Name: "encrypt,e", Usage: "encrypt a file"},
		cli.BoolFlag{Name: "decrypt,d", Usage: "decrypt a file"},
		cli.BoolFlag{Name: "stdin,i", Usage: "accept input for STDIN"},
		cli.BoolFlag{Name: "stdout,o", Usage: "return output to STDOUT"},
	}
	app.Before = func(context *cli.Context) error {
		if !context.GlobalBool("encrypt") && !context.GlobalBool("decrypt") {
			app.Action = nil
			return nil
		}
		if context.GlobalBool("stdin") && context.GlobalString("key") == "" {
			return fmt.Errorf("--key must be supplied when receiving input via STDIN")
		}
		key = getKey(context)
		if len(key) == 0 {
			return fmt.Errorf("no key provided via --key or STDIN")
		}
		return nil
	}
	app.Action = func(context *cli.Context) {
		a := getAction(context)
		if err := do(context, key, a); err != nil {
			logger.Fatal(err)
		}
	}
	if err := app.Run(os.Args); err != nil {
		logger.Fatal(err)
	}
}
<commit_msg>Update app version to alpha<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

var (
	key    []byte
	logger = logrus.New()
)

func inputFile(context *cli.Context) (*os.File, error) {
	if context.GlobalBool("stdin") {
		return os.Stdin, nil
	}
	in, err := os.Open(context.Args().Get(0))
	if err != nil {
		return nil, err
	}
	return in, nil
}

func stdoutArgIndex(context *cli.Context) int {
	if !context.GlobalBool("stdin") {
		return 1
	}
	return 0
}

func outputFile(context *cli.Context) (*os.File, error) {
	if context.GlobalBool("stdout") {
		return os.Stdout, nil
	}
	out, err := os.Create(context.Args().Get(stdoutArgIndex(context)))
	if err != nil {
		return nil, err
	}
	return out, nil
}

func do(context *cli.Context, key []byte, a Action) error {
	in, err := inputFile(context)
	if err != nil {
		return err
	}
	defer in.Close()

	out, err := outputFile(context)
	if err != nil {
		return err
	}
	defer out.Close()
	p, err := newProcessor(in, out, key, a)
	if err != nil {
		return err
	}
	return p.Run()
}

func getAction(context *cli.Context) Action {
	switch {
	case context.GlobalBool("encrypt"):
		return Encrypt
	case context.GlobalBool("decrypt"):
		return Decrypt
	}
	return 0
}

func main() {
	app := cli.NewApp()
	app.Name = "crypt"
	app.Version = "alpha"
	app.Author = "@crosbymichael"
	app.Usage = `
encrypt and decrypt files easily

NOTE!: While the version is alpha things may break between commits.
Do not expect compatibility between builds until the version goes to 1.
`

	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "key", Usage: "key to use for the encryption algo"},
		cli.BoolFlag{Name: "encrypt,e", Usage: "encrypt a file"},
		cli.BoolFlag{Name: "decrypt,d", Usage: "decrypt a file"},
		cli.BoolFlag{Name: "stdin,i", Usage: "accept input for STDIN"},
		cli.BoolFlag{Name: "stdout,o", Usage: "return output to STDOUT"},
	}
	app.Before = func(context *cli.Context) error {
		if !context.GlobalBool("encrypt") && !context.GlobalBool("decrypt") {
			return nil
		}
		app.Action = func(context *cli.Context) {
			a := getAction(context)
			if err := do(context, key, a); err != nil {
				logger.Fatal(err)
			}
		}
		if context.GlobalBool("stdin") && context.GlobalString("key") == "" {
			return fmt.Errorf("--key must be supplied when receiving input via STDIN")
		}
		key = getKey(context)
		if len(key) == 0 {
			return fmt.Errorf("no key provided via --key or STDIN")
		}
		return nil
	}
	if err := app.Run(os.Args); err != nil {
		logger.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/dimfeld/httptreemux"
	"github.com/kabukky/httpscerts"
	"github.com/kabukky/journey/configuration"
	"github.com/kabukky/journey/database"
	"github.com/kabukky/journey/filenames"
	"github.com/kabukky/journey/flags"
	"github.com/kabukky/journey/plugins"
	"github.com/kabukky/journey/server"
	"github.com/kabukky/journey/templates"
	"log"
	"net/http"
	"os"
	"runtime"
)

func httpsRedirect(w http.ResponseWriter, r *http.Request, _ map[string]string) {
	http.Redirect(w, r, configuration.Config.HttpsUrl+r.RequestURI, http.StatusMovedPermanently)
	return
}

func checkHttpsCertificates() {
	// Check https certificates. If they are not available generate temporary ones for testing.
	err := httpscerts.Check(filenames.HttpsCertFilename, filenames.HttpsKeyFilename)
	if err != nil {
		log.Println("Warning: couldn't load https certs. Generating new ones. Replace " + filenames.HttpsCertFilename + " and " + filenames.HttpsKeyFilename + " with your own certificates as soon as possible!")
		err := httpscerts.Generate(filenames.HttpsCertFilename, filenames.HttpsKeyFilename, configuration.Config.HttpsUrl)
		if err != nil {
			log.Fatal("Error: Couldn't create https certificates.")
			return
		}
	}
}

func main() {
	// Setup
	var err error

	// GOMAXPROCS - Maybe not needed
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Write log to file if Journey is not in dev mode
	if !flags.IsInDevMode {
		logFile, err := os.OpenFile(filenames.LogFilename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			log.Fatal("Error: Couldn't open log file: " + err.Error())
		}
		defer logFile.Close()
		//log.SetOutput(logFile)
	}

	// Configuration is read from config.json by loading the configuration package

	// Database
	err = database.Initialize()
	if err != nil {
		log.Fatal("Error: Couldn't initialize database: " + err.Error())
		return
	}

	// Templates
	err = templates.Generate()
	if err != nil {
		log.Fatal("Error: Couldn't compile templates: " + err.Error())
		return
	}

	// Plugins
	err = plugins.Load()
	if err == nil {
		// Close LuaPool at the end
		defer plugins.LuaPool.Shutdown()
		log.Println("Plugins loaded.")
	}

	// HTTP(S) Server
	// Determine the kind of https support (as set in the config.json)
	switch configuration.Config.HttpsUsage {
	case "AdminOnly":
		checkHttpsCertificates()
		httpRouter := httptreemux.New()
		httpsRouter := httptreemux.New()
		// Blog as http
		server.InitializeBlog(httpRouter)
		// Blog as https
		server.InitializeBlog(httpsRouter)
		// Admin as https and http redirect
		// Add redirection to http router
		httpRouter.GET("/admin/*path", httpsRedirect)
		// Add routes to https router
		server.InitializeAdmin(httpsRouter)
		// Start https server
		log.Println("Starting https server on port " + configuration.Config.HttpsHostAndPort + "...")
		go http.ListenAndServeTLS(configuration.Config.HttpsHostAndPort, filenames.HttpsCertFilename, filenames.HttpsKeyFilename, httpsRouter)
		// Start http server
		log.Println("Starting http server on port " + configuration.Config.HttpHostAndPort + "...")
		http.ListenAndServe(configuration.Config.HttpHostAndPort, httpRouter)
	case "All":
		checkHttpsCertificates()
		httpsRouter := httptreemux.New()
		httpRouter := httptreemux.New()
		// Blog as https
		server.InitializeBlog(httpsRouter)
		// Admin as https
		server.InitializeAdmin(httpsRouter)
		// Add redirection to http router
		httpRouter.GET("/", httpsRedirect)
		httpRouter.GET("/*path", httpsRedirect)
		// Start https server
		log.Println("Starting https server on port " + configuration.Config.HttpsHostAndPort + "...")
		go http.ListenAndServeTLS(configuration.Config.HttpsHostAndPort, filenames.HttpsCertFilename, filenames.HttpsKeyFilename, httpsRouter)
		// Start http server
		log.Println("Starting http server on port " + configuration.Config.HttpHostAndPort + "...")
		http.ListenAndServe(configuration.Config.HttpHostAndPort, httpRouter)
	default: // This is configuration.HttpsUsage == "None"
		httpRouter := httptreemux.New()
		// Blog as http
		server.InitializeBlog(httpRouter)
		// Admin as http
		server.InitializeAdmin(httpRouter)
		// Start http server
		log.Println("Starting server without HTTPS support. Please enable HTTPS in " + filenames.ConfigFilename + " to improve security.")
		log.Println("Starting http server on port " + configuration.Config.HttpHostAndPort + "...")
		http.ListenAndServe(configuration.Config.HttpHostAndPort, httpRouter)
	}
}
<commit_msg>Uncommented logging to file.<commit_after>package main

import (
	"github.com/dimfeld/httptreemux"
	"github.com/kabukky/httpscerts"
	"github.com/kabukky/journey/configuration"
	"github.com/kabukky/journey/database"
	"github.com/kabukky/journey/filenames"
	"github.com/kabukky/journey/flags"
	"github.com/kabukky/journey/plugins"
	"github.com/kabukky/journey/server"
	"github.com/kabukky/journey/templates"
	"log"
	"net/http"
	"os"
	"runtime"
)

func httpsRedirect(w http.ResponseWriter, r *http.Request, _ map[string]string) {
	http.Redirect(w, r, configuration.Config.HttpsUrl+r.RequestURI, http.StatusMovedPermanently)
	return
}

func checkHttpsCertificates() {
	// Check https certificates. If they are not available generate temporary ones for testing.
	err := httpscerts.Check(filenames.HttpsCertFilename, filenames.HttpsKeyFilename)
	if err != nil {
		log.Println("Warning: couldn't load https certs. Generating new ones. Replace " + filenames.HttpsCertFilename + " and " + filenames.HttpsKeyFilename + " with your own certificates as soon as possible!")
		err := httpscerts.Generate(filenames.HttpsCertFilename, filenames.HttpsKeyFilename, configuration.Config.HttpsUrl)
		if err != nil {
			log.Fatal("Error: Couldn't create https certificates.")
			return
		}
	}
}

func main() {
	// Setup
	var err error

	// GOMAXPROCS - Maybe not needed
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Write log to file if Journey is not in dev mode
	if !flags.IsInDevMode {
		logFile, err := os.OpenFile(filenames.LogFilename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			log.Fatal("Error: Couldn't open log file: " + err.Error())
		}
		defer logFile.Close()
		log.SetOutput(logFile)
	}

	// Configuration is read from config.json by loading the configuration package

	// Database
	err = database.Initialize()
	if err != nil {
		log.Fatal("Error: Couldn't initialize database: " + err.Error())
		return
	}

	// Templates
	err = templates.Generate()
	if err != nil {
		log.Fatal("Error: Couldn't compile templates: " + err.Error())
		return
	}

	// Plugins
	err = plugins.Load()
	if err == nil {
		// Close LuaPool at the end
		defer plugins.LuaPool.Shutdown()
		log.Println("Plugins loaded.")
	}

	// HTTP(S) Server
	// Determine the kind of https support (as set in the config.json)
	switch configuration.Config.HttpsUsage {
	case "AdminOnly":
		checkHttpsCertificates()
		httpRouter := httptreemux.New()
		httpsRouter := httptreemux.New()
		// Blog as http
		server.InitializeBlog(httpRouter)
		// Blog as https
		server.InitializeBlog(httpsRouter)
		// Admin as https and http redirect
		// Add redirection to http router
		httpRouter.GET("/admin/*path", httpsRedirect)
		// Add routes to https router
		server.InitializeAdmin(httpsRouter)
		// Start https server
		log.Println("Starting https server on port " + configuration.Config.HttpsHostAndPort + "...")
		go http.ListenAndServeTLS(configuration.Config.HttpsHostAndPort, filenames.HttpsCertFilename, filenames.HttpsKeyFilename, httpsRouter)
		// Start http server
		log.Println("Starting http server on port " + configuration.Config.HttpHostAndPort + "...")
		http.ListenAndServe(configuration.Config.HttpHostAndPort, httpRouter)
	case "All":
		checkHttpsCertificates()
		httpsRouter := httptreemux.New()
		httpRouter := httptreemux.New()
		// Blog as https
		server.InitializeBlog(httpsRouter)
		// Admin as https
		server.InitializeAdmin(httpsRouter)
		// Add redirection to http router
		httpRouter.GET("/", httpsRedirect)
		httpRouter.GET("/*path", httpsRedirect)
		// Start https server
		log.Println("Starting https server on port " + configuration.Config.HttpsHostAndPort + "...")
		go http.ListenAndServeTLS(configuration.Config.HttpsHostAndPort, filenames.HttpsCertFilename, filenames.HttpsKeyFilename, httpsRouter)
		// Start http server
		log.Println("Starting http server on port " + configuration.Config.HttpHostAndPort + "...")
		http.ListenAndServe(configuration.Config.HttpHostAndPort, httpRouter)
	default: // This is configuration.HttpsUsage == "None"
		httpRouter := httptreemux.New()
		// Blog as http
		server.InitializeBlog(httpRouter)
		// Admin as http
		server.InitializeAdmin(httpRouter)
		// Start http server
		log.Println("Starting server without HTTPS support. Please enable HTTPS in " + filenames.ConfigFilename + " to improve security.")
		log.Println("Starting http server on port " + configuration.Config.HttpHostAndPort + "...")
		http.ListenAndServe(configuration.Config.HttpHostAndPort, httpRouter)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"flag"
	"log"
	"log/syslog"
	"net/smtp"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/dghubble/go-twitter/twitter"
	"github.com/dghubble/oauth1"
	_ "github.com/go-sql-driver/mysql"
	"github.com/johansundell/cocapi"
)

var db *sql.DB
var mysqlUser, mysqlPass, mysqlDb, mysqlHost string
var queryInsertUpdateMember = `INSERT INTO members (tag, name, created, last_updated, active) VALUES (?, ?, null, null, 1) ON DUPLICATE KEY UPDATE member_id=LAST_INSERT_ID(member_id), last_updated = NOW(), active = 1`
var consumerKey, consumerSecret, accessToken, accessSecret string

func init() {

	mysqlDb = "cocsniffer"
	mysqlHost = os.Getenv("MYSQL_COC_HOST")
	mysqlUser = os.Getenv("MYSQL_USER")
	mysqlPass = os.Getenv("MYSQL_PASS")

	consumerKey = os.Getenv("TWITTER_CONSKEY")
	consumerSecret = os.Getenv("TWITTER_CONSSEC")
	accessToken = os.Getenv("TWITTER_ACCTOK")
	accessSecret = os.Getenv("TWITTER_ACCSEC")
}

func main() {
	useSyslog := flag.Bool("syslog", false, "Use syslog")
	flag.Parse()
	if *useSyslog {
		logwriter, e := syslog.New(syslog.LOG_NOTICE, "cocsniffer")
		if e == nil {
			log.SetOutput(logwriter)
		}
	}
	db, _ = sql.Open("mysql", mysqlUser+":"+mysqlPass+"@tcp("+mysqlHost+":3306)/"+mysqlDb)
	defer db.Close()

	getMembersData()
	ticker := time.NewTicker(5 * time.Minute)
	quit := make(chan struct{})
	go func() {
		for {
			select {
			case <-ticker.C:
				getMembersData()
			case <-quit:
				ticker.Stop()
				return
			}
		}
	}()

	config := oauth1.NewConfig(consumerKey, consumerSecret)
	token := oauth1.NewToken(accessToken, accessSecret)
	// OAuth1 http.Client will automatically authorize Requests
	httpClient := config.Client(oauth1.NoContext, token)

	// Twitter client
	client := twitter.NewClient(httpClient)

	// Convenience Demux demultiplexed stream messages
	demux := twitter.NewSwitchDemux()
	demux.Tweet = func(tweet *twitter.Tweet) {
		if tweet.User.ID == 730400376 || tweet.User.ID == 250293507 {
			log.Println("found one", tweet.Text)
			log.Println(tweet.User.ScreenName)
			if strings.Contains(strings.ToLower(tweet.Text), strings.ToLower("Maintenance")) {
				sendEmail("johan@pixpro.net", "johan@sundell.com", "COC alert", tweet.Text)
				log.Println("Email sent:", tweet.Text)
			}
		}

	}
	demux.DM = func(dm *twitter.DirectMessage) {
		//fmt.Println(dm.SenderID)
	}
	demux.Event = func(event *twitter.Event) {
		//fmt.Printf("%#v\n", event)
	}

	log.Println("Starting Stream...")

	// FILTER
	filterParams := &twitter.StreamFilterParams{
		Follow: []string{"730400376", "240359880", "250293507"},
		//Track:         []string{"Maintenance", "Maintenance.", "sudde"},
		StallWarnings: twitter.Bool(true),
	}

	stream, err := client.Streams.Filter(filterParams)
	if err != nil {
		log.Fatal(err)
	}

	// Receive messages until stopped or stream quits
	go demux.HandleChan(stream.Messages)

	// Wait for SIGINT and SIGTERM (HIT CTRL-C)
	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
	log.Println(<-ch)

	close(quit)
	stream.Stop()
	log.Println("Bye ;)")
}

func getMembersData() {
	members, err := cocapi.GetMemberInfo()
	if err != nil {
		reportError(err)
	}

	var ids = make([]string, 0)
	for _, m := range members.Items {
		if result, err := db.Exec(queryInsertUpdateMember, m.Tag, m.Name); err != nil {
			log.Println(err)
		} else {
			if id, err := result.LastInsertId(); err != nil {
				log.Println(err)
			} else {
				ids = append(ids, strconv.Itoa(int(id)))
			}
		}
	}
	db.Exec("UPDATE members SET active = 0 WHERE member_id NOT IN (" + strings.Join(ids, ", ") + ")")
	log.Println("done members func")
}

func reportError(err error) {
	log.Println("Fatal error:", err)
	os.Exit(0)
}

func sendEmail(to, from, subject, message string) bool {
	body := "To: " + to + "\r\nSubject: " + subject + "\r\n\r\n" + message
	if err := smtp.SendMail("127.0.0.1:25", nil, from, []string{to}, []byte(body)); err != nil {
		log.Println(err)
		return false
	}
	return true
}
<commit_msg>Setting time<commit_after>package main

import (
	"database/sql"
	"flag"
	"log"
	"log/syslog"
	"net/smtp"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/dghubble/go-twitter/twitter"
	"github.com/dghubble/oauth1"
	_ "github.com/go-sql-driver/mysql"
	"github.com/johansundell/cocapi"
)

var db *sql.DB
var mysqlUser, mysqlPass, mysqlDb, mysqlHost string
var queryInsertUpdateMember = `INSERT INTO members (tag, name, created, last_updated, active) VALUES (?, ?, null, null, 1) ON DUPLICATE KEY UPDATE member_id=LAST_INSERT_ID(member_id), last_updated = NOW(), active = 1`
var consumerKey, consumerSecret, accessToken, accessSecret string

func init() {

	mysqlDb = "cocsniffer"
	mysqlHost = os.Getenv("MYSQL_COC_HOST")
	mysqlUser = os.Getenv("MYSQL_USER")
	mysqlPass = os.Getenv("MYSQL_PASS")

	consumerKey = os.Getenv("TWITTER_CONSKEY")
	consumerSecret = os.Getenv("TWITTER_CONSSEC")
	accessToken = os.Getenv("TWITTER_ACCTOK")
	accessSecret = os.Getenv("TWITTER_ACCSEC")
}

func main() {
	useSyslog := flag.Bool("syslog", false, "Use syslog")
	flag.Parse()
	if *useSyslog {
		logwriter, e := syslog.New(syslog.LOG_NOTICE, "cocsniffer")
		if e == nil {
			log.SetOutput(logwriter)
		}
	}
	db, _ = sql.Open("mysql", mysqlUser+":"+mysqlPass+"@tcp("+mysqlHost+":3306)/"+mysqlDb)
	defer db.Close()

	getMembersData()
	ticker := time.NewTicker(1 * time.Minute)
	quit := make(chan struct{})
	go func() {
		for {
			select {
			case <-ticker.C:
				getMembersData()
			case <-quit:
				ticker.Stop()
				return
			}
		}
	}()

	config := oauth1.NewConfig(consumerKey, consumerSecret)
	token := oauth1.NewToken(accessToken, accessSecret)
	// OAuth1 http.Client will automatically authorize Requests
	httpClient := config.Client(oauth1.NoContext, token)

	// Twitter client
	client := twitter.NewClient(httpClient)

	// Convenience Demux demultiplexed stream messages
	demux := twitter.NewSwitchDemux()
	demux.Tweet = func(tweet *twitter.Tweet) {
		if tweet.User.ID == 730400376 || tweet.User.ID == 250293507 {
			log.Println("found one", tweet.Text)
			log.Println(tweet.User.ScreenName)
			if strings.Contains(strings.ToLower(tweet.Text), strings.ToLower("Maintenance")) {
				sendEmail("johan@pixpro.net", "johan@sundell.com", "COC alert", tweet.Text)
				log.Println("Email sent:", tweet.Text)
			}
		}

	}
	demux.DM = func(dm *twitter.DirectMessage) {
		//fmt.Println(dm.SenderID)
	}
	demux.Event = func(event *twitter.Event) {
		//fmt.Printf("%#v\n", event)
	}

	log.Println("Starting Stream...")

	// FILTER
	filterParams := &twitter.StreamFilterParams{
		Follow: []string{"730400376", "240359880", "250293507"},
		//Track:         []string{"Maintenance", "Maintenance.", "sudde"},
		StallWarnings: twitter.Bool(true),
	}

	stream, err := client.Streams.Filter(filterParams)
	if err != nil {
		log.Fatal(err)
	}

	// Receive messages until stopped or stream quits
	go demux.HandleChan(stream.Messages)

	// Wait for SIGINT and SIGTERM (HIT CTRL-C)
	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
	log.Println(<-ch)

	close(quit)
	stream.Stop()
	log.Println("Bye ;)")
}

func getMembersData() {
	members, err := cocapi.GetMemberInfo()
	if err != nil {
		reportError(err)
	}

	var ids = make([]string, 0)
	for _, m := range members.Items {
		if result, err := db.Exec(queryInsertUpdateMember, m.Tag, m.Name); err != nil {
			log.Println(err)
		} else {
			if id, err := result.LastInsertId(); err != nil {
				log.Println(err)
			} else {
				ids = append(ids, strconv.Itoa(int(id)))
			}
		}
	}
	db.Exec("UPDATE members SET active = 0 WHERE member_id NOT IN (" + strings.Join(ids, ", ") + ")")
	log.Println("done members func")
}

func reportError(err error) {
	log.Println("Fatal error:", err)
	os.Exit(0)
}

func sendEmail(to, from, subject, message string) bool {
	body := "To: " + to + "\r\nSubject: " + subject + "\r\n\r\n" + message
	if err := smtp.SendMail("127.0.0.1:25", nil, from, []string{to}, []byte(body)); err != nil {
		log.Println(err)
		return false
	}
	return true
}
<|endoftext|>