<commit_before>package main

import (
	"crypto/tls"
	"errors"
	"fmt"
	"github.com/orchardup/orchard/cli"
	"github.com/orchardup/orchard/github.com/docopt/docopt.go"
	"github.com/orchardup/orchard/proxy"
	"github.com/orchardup/orchard/tlsconfig"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"os/signal"
	"path"
	"strings"
	"syscall"
	"text/tabwriter"
)

func main() {
	usage := `Orchard.

Usage:
  orchard hosts
  orchard hosts create NAME
  orchard hosts rm NAME
  orchard [options] docker [COMMAND...]
  orchard [options] proxy

Options:
  -h --help               Show this screen.
  --version               Show version.
  -H NAME, --host=NAME    Name of host to connect to (instead of 'default')`

	args, err := docopt.Parse(usage, nil, true, "Orchard 2.0.0", true)
	if err != nil {
		fmt.Println("Error parsing arguments: %s\n", err)
		return
	}

	if args["hosts"] == true {
		if err := Hosts(args); err != nil {
			fmt.Println(err)
		}
	} else if args["docker"] == true || args["proxy"] == true {
		hostName := "default"
		if args["--host"] != nil {
			hostName = args["--host"].(string)
		}

		dirname, err := ioutil.TempDir("/tmp", "orchard-")
		if err != nil {
			fmt.Printf("Error creating temporary directory: %s\n", err)
			return
		}
		defer os.RemoveAll(dirname)
		socketPath := path.Join(dirname, "orchard.sock")

		p, err := MakeProxy(socketPath, hostName)
		if err != nil {
			fmt.Printf("Error starting proxy: %v\n", err)
			return
		}

		go p.Start()
		defer p.Stop()

		if err := <-p.ErrorChannel; err != nil {
			fmt.Printf("Error starting proxy: %v\n", err)
			return
		}

		if args["docker"] == true {
			err := CallDocker(args["COMMAND"].([]string), []string{"DOCKER_HOST=unix://" + socketPath})
			if err != nil {
				fmt.Println(err)
			}
		} else {
			fmt.Println("Started proxy at unix://" + socketPath)

			c := make(chan os.Signal)
			signal.Notify(c, syscall.SIGINT, syscall.SIGKILL)
			<-c

			fmt.Println("\nStopping proxy")
		}
	}
}

func MakeProxy(socketPath string, hostName string) (*proxy.Proxy, error) {
	httpClient, err := authenticator.Authenticate()
	if err != nil {
		return nil, err
	}

	host, err := httpClient.GetHost(hostName)
	if err != nil {
		return nil, err
	}
	destination := host.IPv4_Address + ":4243"

	fmt.Printf("Connecting to %s...\n", destination)

	certData, err := ioutil.ReadFile("client-cert.pem")
	if err != nil {
		return nil, err
	}
	keyData, err := ioutil.ReadFile("client-key.pem")
	if err != nil {
		return nil, err
	}

	config, err := tlsconfig.GetTLSConfig(certData, keyData)
	if err != nil {
		return nil, err
	}

	return proxy.New(
		func() (net.Listener, error) { return net.Listen("unix", socketPath) },
		func() (net.Conn, error) { return tls.Dial("tcp", destination, config) },
	), nil
}

func CallDocker(args []string, env []string) error {
	dockerPath := GetDockerPath()
	if dockerPath == "" {
		return errors.New("Can't find `docker` executable in $PATH.\nYou might need to install it: http://docs.docker.io/en/latest/installation/#installation-list")
	}

	cmd := exec.Command(dockerPath, args...)
	cmd.Env = env
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

func GetDockerPath() string {
	for _, dir := range strings.Split(os.Getenv("PATH"), ":") {
		dockerPath := path.Join(dir, "docker")
		_, err := os.Stat(dockerPath)
		if err == nil {
			return dockerPath
		}
	}
	return ""
}

func Hosts(args map[string]interface{}) error {
	httpClient, err := authenticator.Authenticate()
	if err != nil {
		fmt.Printf("Error authenticating:\n%s\n", err)
	}

	if args["create"] == true {
		host, err := httpClient.CreateHost(args["NAME"].(string))
		if err != nil {
			return err
		}
		fmt.Printf("Created %s with IP address %s\n", host.Name, host.IPv4_Address)
	} else if args["rm"] == true {
		err := httpClient.DeleteHost(args["NAME"].(string))
		if err != nil {
			return err
		}
		fmt.Printf("Removed %s\n", args["NAME"].(string))
	} else {
		hosts, err := httpClient.GetHosts()
		if err != nil {
			return err
		}

		writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
		fmt.Fprintln(writer, "NAME\tIP")
		for _, host := range hosts {
			fmt.Fprintf(writer, "%s\t%s\n", host.Name, host.IPv4_Address)
		}
		writer.Flush()
	}

	return nil
}
<commit_msg>Extract docker/proxy command into function<commit_after>package main

import (
	"crypto/tls"
	"errors"
	"fmt"
	"github.com/orchardup/orchard/cli"
	"github.com/orchardup/orchard/github.com/docopt/docopt.go"
	"github.com/orchardup/orchard/proxy"
	"github.com/orchardup/orchard/tlsconfig"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"os/signal"
	"path"
	"strings"
	"syscall"
	"text/tabwriter"
)

func main() {
	usage := `Orchard.

Usage:
  orchard hosts
  orchard hosts create NAME
  orchard hosts rm NAME
  orchard [options] docker [COMMAND...]
  orchard [options] proxy

Options:
  -h --help               Show this screen.
  --version               Show version.
  -H NAME, --host=NAME    Name of host to connect to (instead of 'default')`

	args, err := docopt.Parse(usage, nil, true, "Orchard 2.0.0", true)
	if err != nil {
		fmt.Println("Error parsing arguments: %s\n", err)
		return
	}

	if args["hosts"] == true {
		if err := Hosts(args); err != nil {
			fmt.Println(err)
		}
	} else if args["docker"] == true || args["proxy"] == true {
		if err := Docker(args); err != nil {
			fmt.Println(err)
		}
	}
}

func Docker(args map[string]interface{}) error {
	hostName := "default"
	if args["--host"] != nil {
		hostName = args["--host"].(string)
	}

	dirname, err := ioutil.TempDir("/tmp", "orchard-")
	if err != nil {
		return fmt.Errorf("Error creating temporary directory: %s\n", err)
	}
	defer os.RemoveAll(dirname)
	socketPath := path.Join(dirname, "orchard.sock")

	p, err := MakeProxy(socketPath, hostName)
	if err != nil {
		return fmt.Errorf("Error starting proxy: %v\n", err)
	}

	go p.Start()
	defer p.Stop()

	if err := <-p.ErrorChannel; err != nil {
		return fmt.Errorf("Error starting proxy: %v\n", err)
	}

	if args["docker"] == true {
		err := CallDocker(args["COMMAND"].([]string), []string{"DOCKER_HOST=unix://" + socketPath})
		if err != nil {
			fmt.Println(err)
		}
	} else {
		fmt.Println("Started proxy at unix://" + socketPath)

		c := make(chan os.Signal)
		signal.Notify(c, syscall.SIGINT, syscall.SIGKILL)
		<-c

		fmt.Println("\nStopping proxy")
	}

	return nil
}

func MakeProxy(socketPath string, hostName string) (*proxy.Proxy, error) {
	httpClient, err := authenticator.Authenticate()
	if err != nil {
		return nil, err
	}

	host, err := httpClient.GetHost(hostName)
	if err != nil {
		return nil, err
	}
	destination := host.IPv4_Address + ":4243"

	fmt.Printf("Connecting to %s...\n", destination)

	certData, err := ioutil.ReadFile("client-cert.pem")
	if err != nil {
		return nil, err
	}
	keyData, err := ioutil.ReadFile("client-key.pem")
	if err != nil {
		return nil, err
	}

	config, err := tlsconfig.GetTLSConfig(certData, keyData)
	if err != nil {
		return nil, err
	}

	return proxy.New(
		func() (net.Listener, error) { return net.Listen("unix", socketPath) },
		func() (net.Conn, error) { return tls.Dial("tcp", destination, config) },
	), nil
}

func CallDocker(args []string, env []string) error {
	dockerPath := GetDockerPath()
	if dockerPath == "" {
		return errors.New("Can't find `docker` executable in $PATH.\nYou might need to install it: http://docs.docker.io/en/latest/installation/#installation-list")
	}

	cmd := exec.Command(dockerPath, args...)
	cmd.Env = env
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

func GetDockerPath() string {
	for _, dir := range strings.Split(os.Getenv("PATH"), ":") {
		dockerPath := path.Join(dir, "docker")
		_, err := os.Stat(dockerPath)
		if err == nil {
			return dockerPath
		}
	}
	return ""
}

func Hosts(args map[string]interface{}) error {
	httpClient, err := authenticator.Authenticate()
	if err != nil {
		fmt.Printf("Error authenticating:\n%s\n", err)
	}

	if args["create"] == true {
		host, err := httpClient.CreateHost(args["NAME"].(string))
		if err != nil {
			return err
		}
		fmt.Printf("Created %s with IP address %s\n", host.Name, host.IPv4_Address)
	} else if args["rm"] == true {
		err := httpClient.DeleteHost(args["NAME"].(string))
		if err != nil {
			return err
		}
		fmt.Printf("Removed %s\n", args["NAME"].(string))
	} else {
		hosts, err := httpClient.GetHosts()
		if err != nil {
			return err
		}

		writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
		fmt.Fprintln(writer, "NAME\tIP")
		for _, host := range hosts {
			fmt.Fprintf(writer, "%s\t%s\n", host.Name, host.IPv4_Address)
		}
		writer.Flush()
	}

	return nil
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

		 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"errors"
	"fmt"
	"strconv"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

var viktor = "viktor"
var furqan = "furqan"
var seller = "viktor"
var buyer = "furqan"

var store = "store_index"
var bought = "bought_index"

type Product struct {
	Id string `json:"id"`
	Name string `json:"name"`
	Price int `json:"price"`
	Quantity int `json:"quantity"`
}

// ============================================================================================================================
// Main
// ============================================================================================================================
func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}
	var err error

	err = stub.PutState(viktor, []byte(strconv.Itoa(100)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(furqan, []byte(strconv.Itoa(100)))
	if err != nil {
		return nil, err
	}

	var shopIndex []string
	var boughtIndex []string

	chair := `{"id":"001", "name": "chair", "price": 50, "quantity": 5}`
	err = stub.PutState("001", []byte(chair))
	shopIndex = append(shopIndex, "001")

	phone := `{"id":"002", "name": "phone", "price": 99, "quantity": 15}`
	err = stub.PutState("002", []byte(phone))
	shopIndex = append(shopIndex, "002")

	shopAsBytes, _ := json.Marshal(shopIndex)
	err = stub.PutState(store, shopAsBytes)
	boughtAsBytes, _ := json.Marshal(boughtIndex)
	err = stub.PutState(bought, boughtAsBytes)

	return nil, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" {													//initialize the chaincode state, used as reset
		return t.Init(stub, "init", args)
	} else if function == "write" {
		var sender, receiver string
		var err error

		if len(args) != 3 {
			return nil, errors.New("Incorrect number of arguments. Expecting 3. name of the sender, receiver and value to transfer")
		}

		sender = args[0] //rename for funsies
		receiver = args[1]
		amount, err := strconv.Atoi(args[2])

		senderValue, err := stub.GetState(sender)
		receiverValue, err := stub.GetState(receiver)
		senderInt, err := strconv.Atoi(string(senderValue[:]))
		receiverInt, err := strconv.Atoi(string(receiverValue[:]))

		if err != nil {
			return nil, err
		}

		err = stub.PutState(sender, []byte(strconv.Itoa(senderInt - amount)))
		err = stub.PutState(receiver, []byte(strconv.Itoa(receiverInt + amount)))

		if err != nil {
			return nil, err
		}
		return nil, nil
	} else if function == "trade" {

		if len(args) != 2 {
			return nil, errors.New("Incorrect number of arguments. Expecting 2. Product id and quantity")
		}
	}
	fmt.Println("invoke did not find func: " + function)					//error

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	var key, jsonResp string

	// Handle different functions
	if function == "read" {
		if len(args) != 1 {
			return nil, errors.New("Incorrect number of arguments. Expecting name of the user to query")
		}								//read a variable
		key = args[0]
		valAsbytes, err := stub.GetState(key)
		if err != nil {
			jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
			return nil, errors.New(jsonResp)
		}
		return valAsbytes, nil
	} else if function == "list" {
		if len(args) != 1 {
			return nil, errors.New("Incorrect number of arguments. Expecting name of the user to query")
		}
		key = args[0]
		if (key == buyer) {
			valAsbytes, err := stub.GetState(bought)
			if err != nil {
				jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
				return nil, errors.New(jsonResp)
			}
			var response []string
			var products []string
			json.Unmarshal(valAsbytes, &products)
			for _, product := range products {
				response = append(response, product)
			}
			responseAsBytes, _ := json.Marshal(response)
			return responseAsBytes, nil
		} else if (key == seller) {
			valAsbytes, err := stub.GetState(store)
			if err != nil {
				jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
				return nil, errors.New(jsonResp)
			}
			return valAsbytes, nil
		}
	}
	fmt.Println("query did not find func: " + function)						//error

	return nil, errors.New("Received unknown function query: " + function)
}
<commit_msg>list unmarshalled3<commit_after>/*
Copyright IBM Corp 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

		 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"errors"
	"fmt"
	"strconv"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

var viktor = "viktor"
var furqan = "furqan"
var seller = "viktor"
var buyer = "furqan"

var store = "store_index"
var bought = "bought_index"

type Product struct {
	Id string `json:"id"`
	Name string `json:"name"`
	Price int `json:"price"`
	Quantity int `json:"quantity"`
}

// ============================================================================================================================
// Main
// ============================================================================================================================
func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}
	var err error

	err = stub.PutState(viktor, []byte(strconv.Itoa(100)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(furqan, []byte(strconv.Itoa(100)))
	if err != nil {
		return nil, err
	}

	var shopIndex []string
	var boughtIndex []string

	chair := `{"id":"001", "name": "chair", "price": 50, "quantity": 5}`
	err = stub.PutState("001", []byte(chair))
	shopIndex = append(shopIndex, "001")

	phone := `{"id":"002", "name": "phone", "price": 99, "quantity": 15}`
	err = stub.PutState("002", []byte(phone))
	shopIndex = append(shopIndex, "002")

	shopAsBytes, _ := json.Marshal(shopIndex)
	err = stub.PutState(store, shopAsBytes)
	boughtAsBytes, _ := json.Marshal(boughtIndex)
	err = stub.PutState(bought, boughtAsBytes)

	return nil, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" {													//initialize the chaincode state, used as reset
		return t.Init(stub, "init", args)
	} else if function == "write" {
		var sender, receiver string
		var err error

		if len(args) != 3 {
			return nil, errors.New("Incorrect number of arguments. Expecting 3. name of the sender, receiver and value to transfer")
		}

		sender = args[0] //rename for funsies
		receiver = args[1]
		amount, err := strconv.Atoi(args[2])

		senderValue, err := stub.GetState(sender)
		receiverValue, err := stub.GetState(receiver)
		senderInt, err := strconv.Atoi(string(senderValue[:]))
		receiverInt, err := strconv.Atoi(string(receiverValue[:]))

		if err != nil {
			return nil, err
		}

		err = stub.PutState(sender, []byte(strconv.Itoa(senderInt - amount)))
		err = stub.PutState(receiver, []byte(strconv.Itoa(receiverInt + amount)))

		if err != nil {
			return nil, err
		}
		return nil, nil
	} else if function == "trade" {

		if len(args) != 2 {
			return nil, errors.New("Incorrect number of arguments. Expecting 2. Product id and quantity")
		}
	}
	fmt.Println("invoke did not find func: " + function)					//error

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	var key, jsonResp string

	// Handle different functions
	if function == "read" {
		if len(args) != 1 {
			return nil, errors.New("Incorrect number of arguments. Expecting name of the user to query")
		}								//read a variable
		key = args[0]
		valAsbytes, err := stub.GetState(key)
		if err != nil {
			jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
			return nil, errors.New(jsonResp)
		}
		return valAsbytes, nil
	} else if function == "list" {
		if len(args) != 1 {
			return nil, errors.New("Incorrect number of arguments. Expecting name of the user to query")
		}
		key = args[0]
		if (key == buyer) {
			valAsbytes, err := stub.GetState(bought)
			if err != nil {
				jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
				return nil, errors.New(jsonResp)
			}
			var response []string
			var products []string
			json.Unmarshal(valAsbytes, &products)
			for _, product := range products {
				response = append(response, product)
			}
			responseAsBytes, _ := json.Marshal(response)
			return responseAsBytes, nil
		} else if (key == seller) {
			valAsbytes, err := stub.GetState(store)
			if err != nil {
				jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
				return nil, errors.New(jsonResp)
			}
			var response []string
			var products []string
			json.Unmarshal(valAsbytes, &products)
			for _, product := range products {
				response = append(response, product)
			}
			responseAsBytes, _ := json.Marshal(response)
			return responseAsBytes, nil
		}
	}
	fmt.Println("query did not find func: " + function)						//error

	return nil, errors.New("Received unknown function query: " + function)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"time"

	govix "github.com/hooklift/govix"
	"github.com/satori/go.uuid"
	"gopkg.in/unrolled/render.v1"
)

var (
	Port    string
	r       *render.Render
	Version string
)

func init() {
	Port = os.Getenv("PORT")
	if Port == "" {
		Port = "12345"
	}

	r = render.New(render.Options{
		IndentJSON: true,
	})
}

func Log(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL)
		handler.ServeHTTP(w, r)
	})
}

func main() {
	http.HandleFunc("/vms", VMHandler)

	address := ":" + Port

	log.Printf("OSX Builder %s about to listen on %s", Version, address)
	err := http.ListenAndServe(address, Log(http.DefaultServeMux))
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

type BuilderError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Trace   string `json:"trace"`
}

func VMHandler(w http.ResponseWriter, req *http.Request) {
	var err error
	var vms []string
	var vminfo *VM

	switch req.Method {
	case "POST":
		var params LaunchVMParams
		body, err := ioutil.ReadAll(req.Body)
		if err != nil {
			//TODO(c4milo): Wrap error in BuilderError
			r.JSON(w, http.StatusBadRequest, err.Error())
			return
		}

		err = json.Unmarshal(body, params)
		if err != nil {
			//TODO(c4milo): Wrap error in BuilderError
			r.JSON(w, http.StatusUnsupportedMediaType, err.Error())
			return
		}

		vminfo, err = LaunchVM(params)
	case "DELETE":
		params := DestroyVMParams{
			ID: path.Base(req.URL.Path),
		}
		err = DestroyVM(params)
	case "GET":
		params := ListVMsParams{
			Status: req.URL.Query().Get("status"),
		}
		vms, err = ListVMs(params)
	default:
		r.JSON(w, http.StatusMethodNotAllowed, nil)
		return
	}

	if err != nil {
		switch err {
		default:
			r.JSON(w, http.StatusInternalServerError, err.Error())
		}
	}

	if vminfo != nil {
		r.JSON(w, http.StatusCreated, vminfo)
		return
	}

	if vms != nil {
		r.JSON(w, http.StatusOK, vms)
		return
	}

	r.JSON(w, http.StatusNotFound, nil)
}

type LaunchVMParams struct {
	CPUs             uint              `json:"cpus"`
	Memory           string            `json:"memory"`
	NetType          govix.NetworkType `json:"network_type"`
	OSImage          Image             `json:"image"`
	BootstrapScript  string            `json:"bootstrap_script"`
	ToolsInitTimeout time.Duration     `json:"tools_init_timeout"`
	LaunchGUI        bool              `json:"launch_gui"`
	CallbackURL      string            `json:"callback_url"`
}

func LaunchVM(params LaunchVMParams) (*VM, error) {
	name := uuid.NewV4()

	vm := &VM{
		Provider:         string(govix.VMWARE_WORKSTATION),
		VerifySSL:        false,
		Name:             name.String(),
		Image:            params.OSImage,
		CPUs:             params.CPUs,
		Memory:           params.Memory,
		UpgradeVHardware: false,
		ToolsInitTimeout: params.ToolsInitTimeout,
		LaunchGUI:        params.LaunchGUI,
	}

	id, err := vm.Create()
	if err != nil {
		return nil, err

	}

	if vm.IPAddress == "" {
		vm.Refresh(id)
	}

	return vm, nil
}

type DestroyVMParams struct {
	ID string
}

func DestroyVM(params DestroyVMParams) error {
	vm := VM{
		Provider:  string(govix.VMWARE_WORKSTATION),
		VerifySSL: false,
	}

	return vm.Destroy(params.ID)
}

type ListVMsParams struct {
	Status string
}

func ListVMs(params ListVMsParams) ([]string, error) {
	vm := VM{
		Provider:  string(govix.VMWARE_WORKSTATION),
		VerifySSL: false,
	}

	host, err := vm.client()
	if err != nil {
		return nil, err
	}
	defer host.Disconnect()

	return host.FindItems(govix.FIND_RUNNING_VMS)
}
<commit_msg>Adds negroni and httprouter as MUX<commit_after>package main

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"

	"github.com/codegangsta/negroni"
	govix "github.com/hooklift/govix"
	"github.com/julienschmidt/httprouter"
	"github.com/meatballhat/negroni-logrus"
	"github.com/satori/go.uuid"
	"github.com/stretchr/graceful"
	"gopkg.in/unrolled/render.v1"
)

var (
	Port    string
	r       *render.Render
	Version string
)

func init() {
	Port = os.Getenv("PORT")
	if Port == "" {
		Port = "12345"
	}

	r = render.New(render.Options{
		IndentJSON: true,
	})
}

func main() {
	router := httprouter.New()

	router.POST("/vms", LaunchVM)
	router.DELETE("/vms/:id", DestroyVM)
	router.GET("/vms", ListVMs)
	router.GET("/vms/:id", GetVM)

	n := negroni.Classic()
	n.Use(negronilogrus.NewMiddleware())
	n.UseHandler(router)

	address := ":" + Port

	log.Printf("OSX Builder %s about to listen on %s", Version, address)

	graceful.Run(address, 10*time.Second, n)
}

type BuilderError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Trace   string `json:"trace"`
}

type LaunchVMParams struct {
	CPUs             uint              `json:"cpus"`
	Memory           string            `json:"memory"`
	NetType          govix.NetworkType `json:"network_type"`
	OSImage          Image             `json:"image"`
	BootstrapScript  string            `json:"bootstrap_script"`
	ToolsInitTimeout time.Duration     `json:"tools_init_timeout"`
	LaunchGUI        bool              `json:"launch_gui"`
	CallbackURL      string            `json:"callback_url"`
}

func LaunchVM(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	var params LaunchVMParams
	body, err := ioutil.ReadAll(req.Body)
	if err != nil {
		//TODO(c4milo): Wrap error in BuilderError
		r.JSON(w, http.StatusBadRequest, err.Error())
		return
	}

	err = json.Unmarshal(body, &params)
	if err != nil {
		//TODO(c4milo): Wrap error in BuilderError
		r.JSON(w, http.StatusUnsupportedMediaType, err.Error())
		return
	}

	name := uuid.NewV4()

	vm := &VM{
		provider:         string(govix.VMWARE_WORKSTATION),
		verifySSL:        false,
		Name:             name.String(),
		Image:            params.OSImage,
		CPUs:             params.CPUs,
		Memory:           params.Memory,
		upgradeVHardware: false,
		ToolsInitTimeout: params.ToolsInitTimeout,
		LaunchGUI:        params.LaunchGUI,
	}

	nic := &govix.NetworkAdapter{
		ConnType: params.NetType,
	}

	vm.vNetworkAdapters = make([]*govix.NetworkAdapter, 0, 1)
	vm.vNetworkAdapters = append(vm.vNetworkAdapters, nic)

	id, err := vm.Create()
	if err != nil {
		r.JSON(w, http.StatusInternalServerError, err.Error())
		return
	}

	if vm.IPAddress == "" {
		vm.Refresh(id)
	}

	r.JSON(w, http.StatusCreated, vm)
}

type DestroyVMParams struct {
	ID string
}

func DestroyVM(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
	params := DestroyVMParams{
		ID: ps.ByName("id"),
	}

	vm := VM{
		provider:  string(govix.VMWARE_WORKSTATION),
		verifySSL: false,
	}

	err := vm.Destroy(params.ID)
	if err != nil {
		r.JSON(w, http.StatusInternalServerError, err.Error())
		return
	}

	r.JSON(w, http.StatusNoContent, nil)
}

type ListVMsParams struct {
	Status string
}

func ListVMs(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	// params := ListVMsParams{
	// 	Status: req.URL.Query().Get("status"),
	// }

	vm := VM{
		provider:  string(govix.VMWARE_WORKSTATION),
		verifySSL: false,
	}

	host, err := vm.client()
	if err != nil {
		r.JSON(w, http.StatusInternalServerError, err.Error())
		return
	}
	defer host.Disconnect()

	ids, err := host.FindItems(govix.FIND_RUNNING_VMS)
	if err != nil {
		r.JSON(w, http.StatusInternalServerError, err.Error())
		return
	}

	r.JSON(w, http.StatusOK, ids)
}

func GetVM(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
	id := ps.ByName("id")

	r.JSON(w, http.StatusOK, id)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"
)

const (
	keyCtrlC     = 3
	keyCtrlD     = 4
	keyCtrlN     = 14
	keyCtrlP     = 16
	keyCtrlU     = 21
	keyCtrlW     = 23
	keyEnter     = '\r'
	keyNL        = '\n'
	keyEscape    = 27
	keyUp        = 38
	keyDown      = 40
	keyBackspace = 127
)

var (
	SaveCursorPosition     = []byte{keyEscape, '[', 's'}
	RestoreCursorPosition  = []byte{keyEscape, '[', 'u'}
	EraseDisplayFromCursor = []byte{keyEscape, '[', 'J'}
	ReverseColor           = []byte{keyEscape, '[', '7', 'm'}
	ResetColor             = []byte{keyEscape, '[', '0', 'm'}
	ShowCursor             = []byte{keyEscape, '[', '?', '2', '5', 'h'}
)

type TTY struct {
	*os.File
}

func OpenTTY() (*TTY, error) {
	file, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
	if err != nil {
		return nil, err
	}
	return &TTY{file}, nil
}

type steps struct {
	Up    int
	Down  int
	Left  int
	Right int
}

func (tty *TTY) moveCursor(step steps) {
	count := step.Down + step.Up + step.Left + step.Right
	movement := make([]byte, 3*(count))
	m := movement
	for i := 0; i < step.Up; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'A'
		m = m[3:]
	}
	for i := 0; i < step.Down; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'B'
		m = m[3:]
	}
	for i := 0; i < step.Left; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'D'
		m = m[3:]
	}
	for i := 0; i < step.Right; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'C'
		m = m[3:]
	}

	tty.Write(movement)
}

func (tty *TTY) ShowCursor() {
	tty.Write(ShowCursor)
}

func (tty *TTY) SaveCursorPosition() {
	tty.Write(SaveCursorPosition)
}

func (tty *TTY) RestoreCursorPosition() {
	tty.Write(RestoreCursorPosition)
}

func (tty *TTY) EraseDisplayFromCursor() {
	tty.Write(EraseDisplayFromCursor)
}

// XXX: The renderer work is still spread across the file.
type Renderer struct {
	tty     *TTY
	width   int
	height  int
	visible int
}

func (r *Renderer) PrepareForTerminalVim() {
	// start from the bottom of the screen
	r.tty.moveCursor(steps{
		Left: r.width,
		Down: r.height,
	})
}

func (r *Renderer) focusWritingPoint(view *PickerView) {
	r.tty.RestoreCursorPosition()
	r.tty.moveCursor(steps{
		Right: len(view.input),
	})
}

func cutAt(str string, width int) string {
	if len(str) > width {
		return str[:width]
	}
	return str
}

func TTYReverse(str string) string {
	return string(ReverseColor) + str + string(ResetColor)
}

func (r *Renderer) renderPickerView(view *PickerView) {
	view.input = cutAt(view.input, r.width)
	for i := range view.lines {
		view.lines[i] = cutAt(view.lines[i], r.width)
	}
	view.lines[view.selected] = TTYReverse(view.lines[view.selected])

	r.tty.WriteString(view.input + "\n" + strings.Join(view.lines, "\n"))
}

func (r *Renderer) renderFirstFrame(view *PickerView) {
	r.renderPickerView(view)

	// going width time to the left is more than necessary but it works in all
	// situations and is simpler
	r.tty.moveCursor(steps{
		Up:   r.visible,
		Left: r.width,
	})

	// We already rendered the first view but that was to find the right
	// point so now we can save it erase the display from the point to the
	// end of the terminal and then re-render the picker.
	r.tty.SaveCursorPosition()
	r.tty.EraseDisplayFromCursor()
	r.renderPickerView(view)

	r.focusWritingPoint(view)
	r.tty.ShowCursor()
}

func (r *Renderer) Start(channel chan *PickerView) {
	// we special case the first picker to render since we have to save a
	// position for later uses
	r.renderFirstFrame(<-channel)

	for view := range channel {
		r.tty.RestoreCursorPosition()
		r.tty.EraseDisplayFromCursor()

		r.renderPickerView(view)
		r.focusWritingPoint(view)
	}
}

func maxf(a, b float32) float32 {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

var (
	visible int
	vim     bool
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.IntVar(&visible, "v", 20, "Number of visible candidates")
	flag.BoolVar(&vim, "vim", false, "Print at bottom of screen")
	flag.Parse()

	tty, err := OpenTTY()
	if err != nil {
		panic(err)
	}

	old, err := tty.MakeRaw()
	if err != nil {
		panic(err)
	}
	defer tty.Restore(old)

	width, height, err := tty.GetSize()
	if err != nil {
		panic(err)
	}

	if height < visible {
		visible = height
	}

	renderChan := make(chan *PickerView)
	renderer := &Renderer{
		tty:     tty,
		height:  height,
		width:   width,
		visible: visible,
	}

	if vim {
		renderer.PrepareForTerminalVim()
	}
	go renderer.Start(renderChan)

	picker := NewPicker("> ", visible, os.Stdin, renderChan)

	input := make(chan rune)
	go func() {
		reader := bufio.NewReader(tty)
		for {
			r, _, err := reader.ReadRune()
			if err != nil || r == keyEscape || r == keyCtrlC {
				tty.RestoreCursorPosition()
				os.Exit(1)
			}
			input <- r
		}
	}()

	for r := range input {
		switch r {
		case keyEnter, keyNL:
			tty.RestoreCursorPosition()
			selected, err := picker.Selected()
			if err != nil {
				os.Exit(1)
			}
			fmt.Println(selected)
			return
		case keyCtrlU, keyCtrlW:
			picker.Clear()
		case keyCtrlN, keyDown:
			picker.Down()
		case keyCtrlP, keyUp:
			picker.Up()
		case keyBackspace:
			picker.Back()
		default:
			picker.More(r)
		}
	}
}
<commit_msg>Hide cursor while rendering. Delete dead code<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"
)

const (
	keyCtrlC     = 3
	keyCtrlD     = 4
	keyCtrlN     = 14
	keyCtrlP     = 16
	keyCtrlU     = 21
	keyCtrlW     = 23
	keyEnter     = '\r'
	keyNL        = '\n'
	keyEscape    = 27
	keyUp        = 38
	keyDown      = 40
	keyBackspace = 127
)

var (
	SaveCursorPosition     = []byte{keyEscape, '[', 's'}
	RestoreCursorPosition  = []byte{keyEscape, '[', 'u'}
	EraseDisplayFromCursor = []byte{keyEscape, '[', 'J'}
	ReverseColor           = []byte{keyEscape, '[', '7', 'm'}
	ResetColor             = []byte{keyEscape, '[', '0', 'm'}
	HideCursor             = []byte{keyEscape, '[', '?', '2', '5', 'l'}
	ShowCursor             = []byte{keyEscape, '[', '?', '2', '5', 'h'}
)

type TTY struct {
	*os.File
}

func OpenTTY() (*TTY, error) {
	file, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
	if err != nil {
		return nil, err
	}
	return &TTY{file}, nil
}

type steps struct {
	Up    int
	Down  int
	Left  int
	Right int
}

func (tty *TTY) moveCursor(step steps) {
	count := step.Down + step.Up + step.Left + step.Right
	movement := make([]byte, 3*(count))
	m := movement
	for i := 0; i < step.Up; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'A'
		m = m[3:]
	}
	for i := 0; i < step.Down; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'B'
		m = m[3:]
	}
	for i := 0; i < step.Left; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'D'
		m = m[3:]
	}
	for i := 0; i < step.Right; i++ {
		m[0] = keyEscape
		m[1] = '['
		m[2] = 'C'
		m = m[3:]
	}

	tty.Write(movement)
}

func (tty *TTY) HideCursor() {
	tty.Write(HideCursor)
}

func (tty *TTY) ShowCursor() {
	tty.Write(ShowCursor)
}

func (tty *TTY) SaveCursorPosition() {
	tty.Write(SaveCursorPosition)
}

func (tty *TTY) RestoreCursorPosition() {
	tty.Write(RestoreCursorPosition)
}

func (tty *TTY) EraseDisplayFromCursor() {
	tty.Write(EraseDisplayFromCursor)
}

// XXX: The renderer work is still spread across the file.
type Renderer struct {
	tty     *TTY
	width   int
	height  int
	visible int
}

func (r *Renderer) PrepareForTerminalVim() {
	// start from the bottom of the screen
	r.tty.moveCursor(steps{
		Left: r.width,
		Down: r.height,
	})
}

func (r *Renderer) focusWritingPoint(view *PickerView) {
	r.tty.RestoreCursorPosition()
	r.tty.moveCursor(steps{
		Right: len(view.input),
	})
}

func cutAt(str string, width int) string {
	if len(str) > width {
		return str[:width]
	}
	return str
}

func TTYReverse(str string) string {
	return string(ReverseColor) + str + string(ResetColor)
}

func (r *Renderer) renderPickerView(view *PickerView) {
	view.input = cutAt(view.input, r.width)
	for i := range view.lines {
		view.lines[i] = cutAt(view.lines[i], r.width)
	}
	view.lines[view.selected] = TTYReverse(view.lines[view.selected])

	r.tty.WriteString(view.input + "\n" + strings.Join(view.lines, "\n"))
}

func (r *Renderer) renderFirstFrame(view *PickerView) {
	r.tty.HideCursor()
	r.renderPickerView(view)

	// going width time to the left is more than necessary but it works in all
	// situations and is simpler
	r.tty.moveCursor(steps{
		Up:   r.visible,
		Left: r.width,
	})

	// We already rendered the first view but that was to find the right
	// point so now we can save it erase the display from the point to the
	// end of the terminal and then re-render the picker.
	r.tty.SaveCursorPosition()
	r.tty.EraseDisplayFromCursor()
	r.renderPickerView(view)

	r.focusWritingPoint(view)
	r.tty.ShowCursor()
}

func (r *Renderer) Start(channel chan *PickerView) {
	// we special case the first picker to render since we have to save a
	// position for later uses
	r.renderFirstFrame(<-channel)

	for view := range channel {
		r.tty.HideCursor()
		r.tty.RestoreCursorPosition()
		r.tty.EraseDisplayFromCursor()

		r.renderPickerView(view)
		r.focusWritingPoint(view)
		r.tty.ShowCursor()
	}
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

var (
	visible int
	vim     bool
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.IntVar(&visible, "v", 20, "Number of visible candidates")
	flag.BoolVar(&vim, "vim", false, "Print at bottom of screen")
	flag.Parse()

	tty, err := OpenTTY()
	if err != nil {
		panic(err)
	}

	old, err := tty.MakeRaw()
	if err != nil {
		panic(err)
	}
	defer tty.Restore(old)

	width, height, err := tty.GetSize()
	if err != nil {
		panic(err)
	}

	if height < visible {
		visible = height
	}

	renderChan := make(chan *PickerView)
	renderer := &Renderer{
		tty:     tty,
		height:  height,
		width:   width,
		visible: visible,
	}

	if vim {
		renderer.PrepareForTerminalVim()
	}
	go renderer.Start(renderChan)

	picker := NewPicker("> ", visible, os.Stdin, renderChan)

	input := make(chan rune)
	go func() {
		reader := bufio.NewReader(tty)
		for {
			r, _, err := reader.ReadRune()
			if err != nil || r == keyEscape || r == keyCtrlC {
				tty.RestoreCursorPosition()
				os.Exit(1)
			}
			input <- r
		}
	}()

	for r := range input {
		switch r {
		case keyEnter, keyNL:
			tty.RestoreCursorPosition()
			selected, err := picker.Selected()
			if err != nil {
				os.Exit(1)
			}
			fmt.Println(selected)
			return
		case keyCtrlU, keyCtrlW:
			picker.Clear()
		case keyCtrlN, keyDown:
			picker.Down()
		case keyCtrlP, keyUp:
			picker.Up()
		case keyBackspace:
			picker.Back()
		default:
			picker.More(r)
		}
	}
}
<|endoftext|>


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

package state_test

import (
	"github.com/jacobsa/comeback/state"
	. "github.com/jacobsa/ogletest"
	"testing"
)

func TestStringSet(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type StringSetTest struct {
	set state.StringSet
}

func init() { RegisterTestSuite(&StringSetTest{}) }

func (t *StringSetTest) SetUp(i *TestInfo) {
	t.set = state.NewStringSet()
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *StringSetTest) DoesFoo() {
	ExpectEq("TODO", "")
}
<commit_msg>Added test names.<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package state_test

import (
	"github.com/jacobsa/comeback/state"
	. "github.com/jacobsa/ogletest"
	"testing"
)

func TestStringSet(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

type StringSetTest struct {
	set state.StringSet
}

func init() { RegisterTestSuite(&StringSetTest{}) }

func (t *StringSetTest) SetUp(i *TestInfo) {
	t.set = state.NewStringSet()
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *StringSetTest) EmptySet() {
	ExpectEq("TODO", "")
}

func (t *StringSetTest) SomeElements() {
	ExpectEq("TODO", "")
}

func (t *StringSetTest) AddTwice() {
	ExpectEq("TODO", "")
}

func (t *StringSetTest) EncodingRoundTrip() {
	ExpectEq("TODO", "")
}
<|endoftext|>


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

package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"strings"

	"github.com/briandowns/logcolor/renderers"
)

var textChan = make(chan string)         // channel to pass log lines for processing
var formattedChan = make(chan string)    // channel to pass formatted text back
var signalChan = make(chan os.Signal, 1) // channel to catch ctrl-c
var stopChan = make(chan struct{})       // channel to kill the process thread

// TODO: replace code below with strings.Contains() and strings.Replace()
func processLine(log renderers.Log) {
	for {
		select {
		case t := <-textChan:
			brokenLine := strings.Split(t, " ")
			for i, s := range brokenLine {
				switch {
				case log.ExistsInBadLines(s):
					var formatted string
					brokenLine[i] = renderers.ColorBad(s)
					formattedChan <- strings.Join(brokenLine, " ")
				case log.ExistsInWarnWords(s):
					brokenLine[i] = renderers.ColorBad(s)
					formattedChan <- strings.Join(brokenLine, " ")
				case log.ExistsInGoodWords(s):
					brokenLine[i] = renderers.ColorBad(s)
					formattedChan <- strings.Join(brokenLine, " ")
				default:
					formattedChan <- s
				}
			}
		case <-stopChan:
			return
		}
	}
}

// Pointers to hold the contents of the flag args.
var (
	templateFlag = flag.String("t", "", "template to use for log parsing")
)

const USAGE = `Usage: logcolor -t template [-h]`

func main() {
	flag.Parse()

	signal.Notify(signalChan, os.Interrupt)
	// setup go routine to catch a ctrl-c
	go func() {
		for range signalChan {
			stopChan <- struct{}{} // clean up
			os.Exit(1)
		}
	}()

	if len(*templateFlag) != 1 {
		fmt.Println(USAGE)
		os.Exit(1)
	}

	var log renderers.Log
	switch *templateFlag {
	case "http":
		h := &renderers.HTTP{}
		log = renderers.Log(h)
	case "ftp":
		f := &renderers.FTP{}
		log = renderers.Log(f)
	case "sip":
		s := &renderers.SIP{}
		log = renderers.Log(s)
	case "mysql":
		m := &renderers.MySQL{}
		log = renderers.Log(m)
	case "rsync":
		r := &renderers.Rsync{}
		log = renderers.Log(r)
	case "postgresql":
		p := &renderers.Postgresql{}
		log = renderers.Log(p)
	case "openstack":
		o := &renderers.Openstack{}
		log = renderers.Log(o)
	}

	go processLine(log)

	for {
		reader := bufio.NewReader(os.Stdin)
		text, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("unable to read line")
			os.Exit(1)
		}
		textChan <- text
	}
	os.Exit(0)
}
<commit_msg>removed unused import<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"strings"
)

var textChan = make(chan string)         // channel to pass log lines for processing
var formattedChan = make(chan string)    // channel to pass formatted text back
var signalChan = make(chan os.Signal, 1) // channel to catch ctrl-c
var stopChan = make(chan struct{})       // channel to kill the process thread

// TODO: replace code below with strings.Contains() and strings.Replace()
func processLine(log renderers.Log) {
	for {
		select {
		case t := <-textChan:
			brokenLine := strings.Split(t, " ")
			for i, s := range brokenLine {
				switch {
				case log.ExistsInBadLines(s):
					var formatted string
					brokenLine[i] = renderers.ColorBad(s)
					formattedChan <- strings.Join(brokenLine, " ")
				case log.ExistsInWarnWords(s):
					brokenLine[i] = renderers.ColorBad(s)
					formattedChan <- strings.Join(brokenLine, " ")
				case log.ExistsInGoodWords(s):
					brokenLine[i] = renderers.ColorBad(s)
					formattedChan <- strings.Join(brokenLine, " ")
				default:
					formattedChan <- s
				}
			}
		case <-stopChan:
			return
		}
	}
}

// Pointers to hold the contents of the flag args.
var (
	templateFlag = flag.String("t", "", "template to use for log parsing")
)

const USAGE = `Usage: logcolor -t template [-h]`

func main() {
	flag.Parse()

	signal.Notify(signalChan, os.Interrupt)
	// setup go routine to catch a ctrl-c
	go func() {
		for range signalChan {
			stopChan <- struct{}{} // clean up
			os.Exit(1)
		}
	}()

	if len(*templateFlag) != 1 {
		fmt.Println(USAGE)
		os.Exit(1)
	}

	var log renderers.Log
	switch *templateFlag {
	case "http":
		h := &renderers.HTTP{}
		log = renderers.Log(h)
	case "ftp":
		f := &renderers.FTP{}
		log = renderers.Log(f)
	case "sip":
		s := &renderers.SIP{}
		log = renderers.Log(s)
	case "mysql":
		m := &renderers.MySQL{}
		log = renderers.Log(m)
	case "rsync":
		r := &renderers.Rsync{}
		log = renderers.Log(r)
	case "postgresql":
		p := &renderers.Postgresql{}
		log = renderers.Log(p)
	case "openstack":
		o := &renderers.Openstack{}
		log = renderers.Log(o)
	}

	go processLine(log)

	for {
		reader := bufio.NewReader(os.Stdin)
		text, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("unable to read line")
			os.Exit(1)
		}
		textChan <- text
	}
	os.Exit(0)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io"
	"os"

	"github.com/hansrodtang/runcom/backends"
	"github.com/hansrodtang/runcom/core"
	"github.com/hansrodtang/runcom/plugins"
	// Backend
	_ "github.com/hansrodtang/runcom/backends/directory"
	// Plugins
	_ "github.com/hansrodtang/runcom/plugins/dotfiles"
	_ "github.com/hansrodtang/runcom/plugins/packages/homebrew"
	_ "github.com/hansrodtang/runcom/plugins/scripts"
	// Other dependencies
	"github.com/hansrodtang/viper"
	"github.com/spf13/cobra"
	"golang.org/x/crypto/ssh/terminal"
)

const defaultBackend = "directory"

func main() {
	viper.SetDefault("backend", defaultBackend)

	var mainCmd = &cobra.Command{
		Use:   core.BinaryName,
		Short: core.Name + " is a simple and flexible configuration manager",
		Long: `A Simple and Flexible Configuration Manager..
Complete documentation is available at http:/runcom.github.io`,
	}

	mainCmd.PersistentFlags().String("backend", defaultBackend, "Storage backend to use for saving configuration")
	viper.BindPFlag("backend", mainCmd.PersistentFlags().Lookup("backend"))

	print := core.NewPrinter(core.BinaryName)

	backendErr := backends.Select(viper.GetString("backend"))
	if backendErr != nil {
		answer := print.Ask("Backend '"+viper.GetString("backend")+"' not found. Use default? ["+defaultBackend+"]", true)
		if !answer {
			fmt.Println("No storage backend chosen. Exiting")
			os.Exit(0)
		}
		backendErr = backends.Select(defaultBackend)
		if backendErr != nil {
			panic("Could not load default backend.")
		}

	}

	plugs := plugins.GetAll()

	for _, plugin := range plugs {
		mainCmd.AddCommand(plugin.Command)
	}

	mainCmd.AddCommand(
		core.ConnectCommand,
		core.PushCommand,
		core.GetCommand,
		core.UnpackCommand,
		core.PackCommand)

	if !terminal.IsTerminal(int(os.Stdout.Fd())) {
		var test io.Writer
		test = bufio.NewWriter(test)
		mainCmd.SetOutput(test)
	}

	mainCmd.Execute()
}
<commit_msg>Checking if this fixes the AppVeyor build.<commit_after>package main

import (
	"bufio"
	"fmt"
	"io"
	"os"

	"github.com/hansrodtang/runcom/backends"
	"github.com/hansrodtang/runcom/core"
	"github.com/hansrodtang/runcom/plugins"
	// Backend
	_ "github.com/hansrodtang/runcom/backends/directory"
	_ "github.com/hansrodtang/runcom/backends/git"
	// Plugins
	_ "github.com/hansrodtang/runcom/plugins/dotfiles"
	_ "github.com/hansrodtang/runcom/plugins/packages/homebrew"
	_ "github.com/hansrodtang/runcom/plugins/scripts"
	// Other dependencies
	"github.com/hansrodtang/viper"
	"github.com/spf13/cobra"
	"golang.org/x/crypto/ssh/terminal"
)

const defaultBackend = "directory"

func main() {
	viper.SetDefault("backend", defaultBackend)

	var mainCmd = &cobra.Command{
		Use:   core.BinaryName,
		Short: core.Name + " is a simple and flexible configuration manager",
		Long: `A Simple and Flexible Configuration Manager..
Complete documentation is available at http:/runcom.github.io`,
	}

	mainCmd.PersistentFlags().String("backend", defaultBackend, "Storage backend to use for saving configuration")
	viper.BindPFlag("backend", mainCmd.PersistentFlags().Lookup("backend"))

	print := core.NewPrinter(core.BinaryName)

	backendErr := backends.Select(viper.GetString("backend"))
	if backendErr != nil {
		answer := print.Ask("Backend '"+viper.GetString("backend")+"' not found. Use default? ["+defaultBackend+"]", true)
		if !answer {
			fmt.Println("No storage backend chosen. Exiting")
			os.Exit(0)
		}
		backendErr = backends.Select(defaultBackend)
		if backendErr != nil {
			panic("Could not load default backend.")
		}

	}

	plugs := plugins.GetAll()

	for _, plugin := range plugs {
		mainCmd.AddCommand(plugin.Command)
	}

	mainCmd.AddCommand(
		core.ConnectCommand,
		core.PushCommand,
		core.GetCommand,
		core.UnpackCommand,
		core.PackCommand)

	if !terminal.IsTerminal(int(os.Stdout.Fd())) {
		var test io.Writer
		test = bufio.NewWriter(test)
		mainCmd.SetOutput(test)
	}

	mainCmd.Execute()
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"strings"
)

func main() {
	if len(os.Args) < 2 || os.Args[1][0] != '/' {
		printUsage()
		return
	}

	startPoint := os.Args[1]
	storage, err := extendScanWays(startPoint)
	if err != nil {
		panic(err)
	}
	plan := extendPlan(storage)
	extendPrint(plan)

	if len(os.Args) > 2 && os.Args[2] == "--do" {
		if extendDo(plan) {
			fmt.Println("NEED REBOOT AND START ME ONCE AGAIN.")
		} else {
			fmt.Println("OK")
		}
	}
}

func printUsage() {
	fmt.Printf(`Usage: %v <start_point> [--do]
start_point - path to block device or file system to extend
--do - do extending. Without it - print extend plan only.
`, os.Args[0])
}

func cmd(cmd string, args ...string) (stdout, errout string, err error) {
	bufStd := &bytes.Buffer{}
	bufErr := &bytes.Buffer{}
	command := exec.Command(cmd, args...)
	command.Stdout = bufStd
	command.Stderr = bufErr
	err = command.Run()
	return bufStd.String(), bufErr.String(), err
}

/*
execute command with args and return slice of strings.TrimSpace(line). Empty lines removed.
Возвращает stdout команды, разделенный на строки. У каждой строки пустые символы в начале/конце обрезаны, пустые строки
удалены. stderr и код ответа не учитываются
*/
func cmdTrimLines(command string, args ...string) []string {
	res, _, _ := cmd(command, args...)
	lines := make([]string, 0)
	for _, line := range strings.Split(res, "\n") {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		} else {
			lines = append(lines, line)
		}
	}
	return lines
}
<commit_msg>fix usage<commit_after>package main

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"strings"
)

func main() {
	if len(os.Args) < 2 || os.Args[1][0] != '/' {
		printUsage()
		return
	}

	startPoint := os.Args[1]
	storage, err := extendScanWays(startPoint)
	if err != nil {
		panic(err)
	}
	plan := extendPlan(storage)
	extendPrint(plan)

	if len(os.Args) > 2 && os.Args[2] == "--do" {
		if extendDo(plan) {
			fmt.Println("NEED REBOOT AND START ME ONCE AGAIN.")
		} else {
			fmt.Println("OK")
		}
	}
}

func printUsage() {
	fmt.Printf(`Usage: %v <start_point> [--do]
start_point - path to block device or file system to extend
--do - do extending. Without it - print extend plan only.

The program print to stdout:
OK - if extended compele.
NEED REBOOT AND START ME ONCE AGAIN. - if need reboot and run command with same parameters
`, os.Args[0])
}

func cmd(cmd string, args ...string) (stdout, errout string, err error) {
	bufStd := &bytes.Buffer{}
	bufErr := &bytes.Buffer{}
	command := exec.Command(cmd, args...)
	command.Stdout = bufStd
	command.Stderr = bufErr
	err = command.Run()
	return bufStd.String(), bufErr.String(), err
}

/*
execute command with args and return slice of strings.TrimSpace(line). Empty lines removed.
Возвращает stdout команды, разделенный на строки. У каждой строки пустые символы в начале/конце обрезаны, пустые строки
удалены. stderr и код ответа не учитываются
*/
func cmdTrimLines(command string, args ...string) []string {
	res, _, _ := cmd(command, args...)
	lines := make([]string, 0)
	for _, line := range strings.Split(res, "\n") {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		} else {
			lines = append(lines, line)
		}
	}
	return lines
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"compress/gzip"
	"encoding/json"
	"flag"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"regexp"
	"strings"
	"text/template"
)

const (
	MaxErrors     = 3
	MaxPages      = 1
	MinReputation = 400
	APIKeyPath    = "./_secret/api.key"
	ApiURL        = "https://api.stackexchange.com/2.2/users?page="
	CQuery        = "pagesize=100&order=desc&sort=reputation&site=stackoverflow"
)

type SOUsers struct {
	Items []struct {
		BadgeCounts struct {
			Bronze int `json:"bronze"`
			Silver int `json:"silver"`
			Gold   int `json:"gold"`
		} `json:"badge_counts"`
		AccountID               int    `json:"account_id"`
		IsEmployee              bool   `json:"is_employee"`
		LastModifiedDate        int    `json:"last_modified_date"`
		LastAccessDate          int    `json:"last_access_date"`
		Age                     int    `json:"age,omitempty"`
		ReputationChangeYear    int    `json:"reputation_change_year"`
		ReputationChangeQuarter int    `json:"reputation_change_quarter"`
		ReputationChangeMonth   int    `json:"reputation_change_month"`
		ReputationChangeWeek    int    `json:"reputation_change_week"`
		ReputationChangeDay     int    `json:"reputation_change_day"`
		Reputation              int    `json:"reputation"`
		CreationDate            int    `json:"creation_date"`
		UserType                string `json:"user_type"`
		UserID                  int    `json:"user_id"`
		AcceptRate              int    `json:"accept_rate,omitempty"`
		Location                string `json:"location,omitempty"`
		WebsiteURL              string `json:"website_url,omitempty"`
		Link                    string `json:"link"`
		ProfileImage            string `json:"profile_image"`
		DisplayName             string `json:"display_name"`
	} `json:"items"`
	HasMore        bool `json:"has_more"`
	QuotaMax       int  `json:"quota_max"`
	QuotaRemaining int  `json:"quota_remaining"`
}

type SOUserRank struct {
	Rank         int    `json:"rank"`
	AccountID    int    `json:"account_id"`
	DisplayName  string `json:"display_name"`
	Reputation   int    `json:"reputation"`
	Location     string `json:"location,omitempty"`
	WebsiteURL   string `json:"website_url,omitempty"`
	Link         string `json:"link"`
	ProfileImage string `json:"profile_image"`
}

type Ranks []SOUserRank

var (
	Trace    *log.Logger
	Info     *log.Logger
	Warning  *log.Logger
	Error    *log.Logger
	location = flag.String("location", "spain", "location")
	jsonfile = flag.String("json", "", "json sample file")
	jsonrsp  = flag.String("jsonrsp", "", "json response file")
	mdrsp    = flag.String("mdrsp", "", "markdown response file")
	limit    = flag.Int("limit", 20, "max number of records")
)

func Init(
	traceHandle io.Writer,
	infoHandle io.Writer,
	warningHandle io.Writer,
	errorHandle io.Writer) {

	Trace = log.New(traceHandle,
		"TRACE: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Info = log.New(infoHandle,
		"INFO: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Warning = log.New(warningHandle,
		"WARN: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Error = log.New(errorHandle,
		"ERROR: ",
		log.Ldate|log.Ltime|log.Lshortfile)

}

func Decode(r io.Reader) (users *SOUsers, err error) {

	users = new(SOUsers)
	return users, json.NewDecoder(r).Decode(users)
}

func StreamHTTP(page int, key string) (users *SOUsers, err error) {

	var reader io.ReadCloser

	url := fmt.Sprintf("%s%d&%s%s", ApiURL, page, CQuery, key)
	Trace.Println(url)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		Trace.Println(err)
		return users, err
	}

	req.Header.Set("Accept-Encoding", "gzip")

	response, err := http.DefaultClient.Do(req)
	if err != nil {
		Trace.Println(err)
		return users, err
	}
	defer response.Body.Close()

	switch response.Header.Get("Content-Encoding") {
	case "gzip":
		reader, err = gzip.NewReader(response.Body)
		if err != nil {
			Trace.Println(err)
			return users, err
		}
		defer reader.Close()
	default:
		reader = response.Body
	}
	return Decode(reader)
}

func StreamFile(jsonfile string) (users *SOUsers, err error) {
	reader, err := os.Open(jsonfile)
	defer reader.Close()

	return Decode(reader)
}

func GetUserInfo(users *SOUsers, location *regexp.Regexp, counter *int, limit int, ranks *Ranks) (rep bool) {

	for _, user := range users.Items {
		if user.Reputation < MinReputation {
			return false
		}
		if location.MatchString(user.Location) {
			*counter += 1
			if *counter == 1 {
				fmt.Printf("%4s %-30s %6s %-30s\n", "Rank", "Name", "Rep", "Location")
			}

			if *counter > limit && limit != 0 {
				return false
			}
			s := SOUserRank{Rank: *counter,
				AccountID:    user.AccountID,
				DisplayName:  user.DisplayName,
				Reputation:   user.Reputation,
				Location:     user.Location,
				WebsiteURL:   user.WebsiteURL,
				Link:         user.Link,
				ProfileImage: user.ProfileImage}

			*ranks = append(*ranks, s)

			fmt.Printf("%4d %-30s %6d %-30s %s\n", *counter, html.UnescapeString(user.DisplayName),
				user.Reputation, html.UnescapeString(user.Location), user.WebsiteURL)

		}
	}
	return true
}

func DumpJson(path *string, ranks *Ranks) {
	Trace.Printf("Writing to: %s\n", *path)
	jsonenc, _ := json.MarshalIndent(*ranks, "", " ")
	f, err := os.Create(*path)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	w := bufio.NewWriter(f)
	n4, err := w.WriteString(string(jsonenc))
	if err != nil {
		panic(err)
	}
	Trace.Printf("Wrote %d bytes to %s\n", n4, *path)

	w.Flush()
}

func DumpMarkdown(path *string, ranks Ranks) {
	head := "Rank|Name|Rep|Location|Web|Avatar\n----|----|---|--------|---|------\n"

	userfmt := "{{.Rank}}|[{{.DisplayName}}]({{.Link}})|{{.Reputation}}|{{.Location}}|{{.WebsiteURL}}|![Avatar]({{.ProfileImage}})\n"

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

	defer f.Close()
	w := bufio.NewWriter(f)
	n4, err := w.WriteString(head)
	if err != nil {
		panic(err)
	}
	w.Flush()

	tmpl, _ := template.New("test").Parse(userfmt)
	for _, userRank := range ranks {
		_ = tmpl.Execute(f, userRank)
	}
	Trace.Printf("Wrote %d bytes to %s\n", n4, *path)
	w.Flush()
}

func GetKey() (key string, err error) {
	_, err = os.Stat(APIKeyPath)

	if err != nil {
		return "", fmt.Errorf("Can't find API key: %s", APIKeyPath)
	}

	strkey, err := ioutil.ReadFile(APIKeyPath)
	if err != nil {
		return "", fmt.Errorf("Can't load API key: %s", err)
	}

	return fmt.Sprintf("&key=%s", strings.TrimRight(string(strkey)[:], "\n")), nil
}

func main() {
	flag.Parse()

	Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
	Trace.Println("location: ", *location)
	Trace.Println("json: ", *jsonfile)
	Trace.Println("jsontest: ", *jsonfile)
	Trace.Println("jsonrsp: ", *jsonrsp)
	Trace.Println("mdrsp: ", *mdrsp)
	Trace.Println("limit: ", *limit)

	re := regexp.MustCompile(fmt.Sprintf("(?i)%s", *location))

	stop := false
	streamErrors := 0
	currentPage := 1
	counter := 0

	var users *SOUsers
	var ranks Ranks

	for {
		if *jsonfile == "" {
			key, err := GetKey()
			if err != nil {
				Warning.Println(err)
			}
			users, err = StreamHTTP(currentPage, key)
			if err != nil || len(users.Items) == 0 {

				Warning.Println("Can't stream data.")
				streamErrors += 1
				if streamErrors >= MaxErrors {
					Error.Println("Max retry number reached")
					os.Exit(5)
				}
				continue
			}
		} else {
			var err error
			users, err = StreamFile(*jsonfile)
			if err != nil {
				Error.Println("Can't decode json file.")
				os.Exit(5)
			}
			stop = true
		}

		repLimit := GetUserInfo(users, re, &counter, *limit, &ranks)
		if !repLimit {
			break
		}

		currentPage += 1
		if (currentPage >= MaxPages && MaxPages != 0) || !users.HasMore || stop {
			break
		}
	}

	if counter == 0 {
		Warning.Println("No results found.")
		os.Exit(0)
	}

	if *mdrsp != "" {
		DumpMarkdown(mdrsp, ranks)
	}

	if *jsonrsp != "" {
		DumpJson(jsonrsp, &ranks)
	}
	Trace.Printf("%d users found.\n", counter)
}
<commit_msg>terminal output flag<commit_after>package main

import (
	"bufio"
	"compress/gzip"
	"encoding/json"
	"flag"
	"fmt"
	"html"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"regexp"
	"strings"
	"text/template"
)

const (
	MaxErrors     = 3
	MaxPages      = 1
	MinReputation = 400
	APIKeyPath    = "./_secret/api.key"
	ApiURL        = "https://api.stackexchange.com/2.2/users?page="
	CQuery        = "pagesize=100&order=desc&sort=reputation&site=stackoverflow"
)

type SOUsers struct {
	Items []struct {
		BadgeCounts struct {
			Bronze int `json:"bronze"`
			Silver int `json:"silver"`
			Gold   int `json:"gold"`
		} `json:"badge_counts"`
		AccountID               int    `json:"account_id"`
		IsEmployee              bool   `json:"is_employee"`
		LastModifiedDate        int    `json:"last_modified_date"`
		LastAccessDate          int    `json:"last_access_date"`
		Age                     int    `json:"age,omitempty"`
		ReputationChangeYear    int    `json:"reputation_change_year"`
		ReputationChangeQuarter int    `json:"reputation_change_quarter"`
		ReputationChangeMonth   int    `json:"reputation_change_month"`
		ReputationChangeWeek    int    `json:"reputation_change_week"`
		ReputationChangeDay     int    `json:"reputation_change_day"`
		Reputation              int    `json:"reputation"`
		CreationDate            int    `json:"creation_date"`
		UserType                string `json:"user_type"`
		UserID                  int    `json:"user_id"`
		AcceptRate              int    `json:"accept_rate,omitempty"`
		Location                string `json:"location,omitempty"`
		WebsiteURL              string `json:"website_url,omitempty"`
		Link                    string `json:"link"`
		ProfileImage            string `json:"profile_image"`
		DisplayName             string `json:"display_name"`
	} `json:"items"`
	HasMore        bool `json:"has_more"`
	QuotaMax       int  `json:"quota_max"`
	QuotaRemaining int  `json:"quota_remaining"`
}

type SOUserRank struct {
	Rank         int    `json:"rank"`
	AccountID    int    `json:"account_id"`
	DisplayName  string `json:"display_name"`
	Reputation   int    `json:"reputation"`
	Location     string `json:"location,omitempty"`
	WebsiteURL   string `json:"website_url,omitempty"`
	Link         string `json:"link"`
	ProfileImage string `json:"profile_image"`
}

type Ranks []SOUserRank

var (
	Trace    *log.Logger
	Info     *log.Logger
	Warning  *log.Logger
	Error    *log.Logger
	location = flag.String("location", "spain", "location")
	jsonfile = flag.String("json", "", "json sample file")
	jsonrsp  = flag.String("jsonrsp", "", "json response file")
	mdrsp    = flag.String("mdrsp", "", "markdown response file")
	limit    = flag.Int("limit", 20, "max number of records")
	term     = flag.Bool("term", false, "print output in terminal")
)

func Init(
	traceHandle io.Writer,
	infoHandle io.Writer,
	warningHandle io.Writer,
	errorHandle io.Writer) {

	Trace = log.New(traceHandle,
		"TRACE: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Info = log.New(infoHandle,
		"INFO: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Warning = log.New(warningHandle,
		"WARN: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Error = log.New(errorHandle,
		"ERROR: ",
		log.Ldate|log.Ltime|log.Lshortfile)

}

func Decode(r io.Reader) (users *SOUsers, err error) {

	users = new(SOUsers)
	return users, json.NewDecoder(r).Decode(users)
}

func StreamHTTP(page int, key string) (users *SOUsers, err error) {

	var reader io.ReadCloser

	url := fmt.Sprintf("%s%d&%s%s", ApiURL, page, CQuery, key)
	Trace.Println(url)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		Trace.Println(err)
		return users, err
	}

	req.Header.Set("Accept-Encoding", "gzip")

	response, err := http.DefaultClient.Do(req)
	if err != nil {
		Trace.Println(err)
		return users, err
	}
	defer response.Body.Close()

	switch response.Header.Get("Content-Encoding") {
	case "gzip":
		reader, err = gzip.NewReader(response.Body)
		if err != nil {
			Trace.Println(err)
			return users, err
		}
		defer reader.Close()
	default:
		reader = response.Body
	}
	return Decode(reader)
}

func StreamFile(jsonfile string) (users *SOUsers, err error) {
	reader, err := os.Open(jsonfile)
	defer reader.Close()

	return Decode(reader)
}

func GetUserInfo(users *SOUsers, location *regexp.Regexp, counter *int, limit int, ranks *Ranks, term bool) (rep bool) {

	for _, user := range users.Items {
		if user.Reputation < MinReputation {
			return false
		}
		if location.MatchString(user.Location) {
			*counter += 1
			if *counter == 1 && term {
				fmt.Printf("%4s %-30s %6s %s\n", "Rank", "Name", "Rep", "Location")
			}

			if *counter > limit && limit != 0 {
				return false
			}
			s := SOUserRank{Rank: *counter,
				AccountID:    user.AccountID,
				DisplayName:  user.DisplayName,
				Reputation:   user.Reputation,
				Location:     user.Location,
				WebsiteURL:   user.WebsiteURL,
				Link:         user.Link,
				ProfileImage: user.ProfileImage}

			*ranks = append(*ranks, s)

			if term {
				fmt.Printf("%4d %-30s %6d %s\n", *counter, html.UnescapeString(user.DisplayName),
					user.Reputation, html.UnescapeString(user.Location))
			}

		}
	}
	return true
}

func DumpJson(path *string, ranks *Ranks) {
	Trace.Printf("Writing to: %s\n", *path)
	jsonenc, _ := json.MarshalIndent(*ranks, "", " ")
	f, err := os.Create(*path)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	w := bufio.NewWriter(f)
	n4, err := w.WriteString(string(jsonenc))
	if err != nil {
		panic(err)
	}
	Trace.Printf("Wrote %d bytes to %s\n", n4, *path)

	w.Flush()
}

func DumpMarkdown(path *string, ranks Ranks) {
	head := "Rank|Name|Rep|Location|Web|Avatar\n----|----|---|--------|---|------\n"

	userfmt := "{{.Rank}}|[{{.DisplayName}}]({{.Link}})|{{.Reputation}}|{{.Location}}|{{.WebsiteURL}}|![Avatar]({{.ProfileImage}})\n"

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

	defer f.Close()
	w := bufio.NewWriter(f)
	n4, err := w.WriteString(head)
	if err != nil {
		panic(err)
	}
	w.Flush()

	tmpl, _ := template.New("test").Parse(userfmt)
	for _, userRank := range ranks {
		_ = tmpl.Execute(f, userRank)
	}
	Trace.Printf("Wrote %d bytes to %s\n", n4, *path)
	w.Flush()
}

func GetKey() (key string, err error) {
	_, err = os.Stat(APIKeyPath)

	if err != nil {
		return "", fmt.Errorf("Can't find API key: %s", APIKeyPath)
	}

	strkey, err := ioutil.ReadFile(APIKeyPath)
	if err != nil {
		return "", fmt.Errorf("Can't load API key: %s", err)
	}

	return fmt.Sprintf("&key=%s", strings.TrimRight(string(strkey)[:], "\n")), nil
}

func main() {
	flag.Parse()

	Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
	Trace.Println("location: ", *location)
	Trace.Println("json: ", *jsonfile)
	Trace.Println("jsontest: ", *jsonfile)
	Trace.Println("jsonrsp: ", *jsonrsp)
	Trace.Println("mdrsp: ", *mdrsp)
	Trace.Println("limit: ", *limit)
	Trace.Println("term: ", *term)

	re := regexp.MustCompile(fmt.Sprintf("(?i)%s", *location))

	stop := false
	streamErrors := 0
	currentPage := 1
	counter := 0

	var users *SOUsers
	var ranks Ranks

	for {
		if *jsonfile == "" {
			key, err := GetKey()
			if err != nil {
				Warning.Println(err)
			}
			users, err = StreamHTTP(currentPage, key)
			if err != nil || len(users.Items) == 0 {

				Warning.Println("Can't stream data.")
				streamErrors += 1
				if streamErrors >= MaxErrors {
					Error.Println("Max retry number reached")
					os.Exit(5)
				}
				continue
			}
		} else {
			var err error
			users, err = StreamFile(*jsonfile)
			if err != nil {
				Error.Println("Can't decode json file.")
				os.Exit(5)
			}
			stop = true
		}

		repLimit := GetUserInfo(users, re, &counter, *limit, &ranks, *term)
		if !repLimit {
			break
		}

		currentPage += 1
		if (currentPage >= MaxPages && MaxPages != 0) || !users.HasMore || stop {
			break
		}
	}

	if counter == 0 {
		Warning.Println("No results found.")
		os.Exit(0)
	}

	if *mdrsp != "" {
		DumpMarkdown(mdrsp, ranks)
	}

	if *jsonrsp != "" {
		DumpJson(jsonrsp, &ranks)
	}
	Trace.Printf("%d users found.\n", counter)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"

	"github.com/jingweno/ccat/Godeps/_workspace/src/github.com/mattn/go-colorable"
	"github.com/jingweno/ccat/Godeps/_workspace/src/github.com/spf13/cobra"
)

const (
	readFromStdin = "-"
)

type ccatCmd struct {
	BG          string
	Color       string
	ColorValues mapValue
}

func (c *ccatCmd) Run(cmd *cobra.Command, args []string) {
	var colorDefs ColorDefs
	if c.BG == "dark" {
		colorDefs = DarkColorDefs
	} else {
		colorDefs = LightColorDefs
	}

	for k, v := range c.ColorValues {
		ok := colorDefs.Set(k, v)
		if !ok {
			log.Fatal(fmt.Errorf("unknown color value: %s", k))
		}
	}

	var printer CCatPrinter
	if c.Color == "always" {
		printer = ColorPrinter{colorDefs}
	} else if c.Color == "never" {
		printer = PlainTextPrinter{}
	} else {
		printer = AutoColorPrinter{colorDefs}
	}

	// if there's no args, read from stdin
	if len(args) == 0 {
		args = []string{readFromStdin}
	}

	stdout := colorable.NewColorableStdout()
	for _, arg := range args {
		err := CCat(arg, printer, stdout)
		if err != nil {
			log.Fatal(err)
		}
	}
}

func main() {
	ccatCmd := &ccatCmd{
		ColorValues: make(mapValue),
	}
	rootCmd := &cobra.Command{
		Use:  "ccat [OPTION]... [FILE]...",
		Long: "Colorize FILE(s), or standard input, to standard output.",
		Example: `$ ccat FILE1 FILE2 ...
  $ ccat --bg=dark FILE1 FILE2 ... # dark background
  $ ccat # read from standard input
  $ curl https://raw.githubusercontent.com/jingweno/ccat/master/main.go | ccat`,
		Run: ccatCmd.Run,
	}

	usageTempl := `{{ $cmd := . }}
Usage:
  {{.UseLine}}

Flags:
{{.LocalFlags.FlagUsages}}
Using color is auto both by default and with --color=auto. With --color=auto,
ccat emits color codes only when standard output is connected to a terminal.

Examples:
  {{ .Example }}`
	rootCmd.SetUsageTemplate(usageTempl)

	rootCmd.PersistentFlags().StringVarP(&ccatCmd.BG, "bg", "", "light", `set to "light" or "dark" depending on the terminal's background`)
	rootCmd.PersistentFlags().StringVarP(&ccatCmd.Color, "color", "C", "auto", `colorize the output; value can be "never", "always" or "auto"`)
	rootCmd.PersistentFlags().VarP(&ccatCmd.ColorValues, "color-val", "G", `set color value`)

	rootCmd.Execute()
}
<commit_msg>Rename color-val to color-code and add help description<commit_after>package main

import (
	"fmt"
	"log"

	"github.com/jingweno/ccat/Godeps/_workspace/src/github.com/mattn/go-colorable"
	"github.com/jingweno/ccat/Godeps/_workspace/src/github.com/spf13/cobra"
)

const (
	readFromStdin = "-"
)

type ccatCmd struct {
	BG         string
	Color      string
	ColorCodes mapValue
}

func (c *ccatCmd) Run(cmd *cobra.Command, args []string) {
	var colorDefs ColorDefs
	if c.BG == "dark" {
		colorDefs = DarkColorDefs
	} else {
		colorDefs = LightColorDefs
	}

	for k, v := range c.ColorCodes {
		ok := colorDefs.Set(k, v)
		if !ok {
			log.Fatal(fmt.Errorf("unknown color code: %s", k))
		}
	}

	var printer CCatPrinter
	if c.Color == "always" {
		printer = ColorPrinter{colorDefs}
	} else if c.Color == "never" {
		printer = PlainTextPrinter{}
	} else {
		printer = AutoColorPrinter{colorDefs}
	}

	// if there's no args, read from stdin
	if len(args) == 0 {
		args = []string{readFromStdin}
	}

	stdout := colorable.NewColorableStdout()
	for _, arg := range args {
		err := CCat(arg, printer, stdout)
		if err != nil {
			log.Fatal(err)
		}
	}
}

func main() {
	ccatCmd := &ccatCmd{
		ColorCodes: make(mapValue),
	}
	rootCmd := &cobra.Command{
		Use:  "ccat [OPTION]... [FILE]...",
		Long: "Colorize FILE(s), or standard input, to standard output.",
		Example: `$ ccat FILE1 FILE2 ...
  $ ccat --bg=dark FILE1 FILE2 ... # dark background
  $ ccat --color-code String="_darkblue_" --color-code Plaintext="darkred" FILE # set color codes
  $ ccat # read from standard input
  $ curl https://raw.githubusercontent.com/jingweno/ccat/master/main.go | ccat`,
		Run: ccatCmd.Run,
	}

	usageTempl := `{{ $cmd := . }}
Usage:
  {{.UseLine}}

Flags:
{{.LocalFlags.FlagUsages}}
Using color is auto both by default and with --color=auto. With --color=auto,
ccat emits color codes only when standard output is connected to a terminal.
Color codes can be changed with --color-code KEY=VALUE.

Examples:
  {{ .Example }}`
	rootCmd.SetUsageTemplate(usageTempl)

	rootCmd.PersistentFlags().StringVarP(&ccatCmd.BG, "bg", "", "light", `set to "light" or "dark" depending on the terminal's background`)
	rootCmd.PersistentFlags().StringVarP(&ccatCmd.Color, "color", "C", "auto", `colorize the output; value can be "never", "always" or "auto"`)
	rootCmd.PersistentFlags().VarP(&ccatCmd.ColorCodes, "color-code", "G", `set color codes`)

	rootCmd.Execute()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"code.google.com/p/bencode-go"
)

type Files struct {
	Length int
	Path []string
}

type Info struct {
	Name string
	Length int
	Files []Files
	Pieces string
	PieceLength int "piece length"
}

type Metainfo struct {
	Info Info
	Announce string
	AnnounceList [][]string "announce-list"
}

func main() {
	if len(os.Args) != 2 {
		log.Fatalf("Usage: %s: torrent\n", os.Args[0])
        }
	torrent := os.Args[1]

	file, err := os.Open(torrent)
	if err != nil {
		log.Fatal(err)
	}

	var m Metainfo

	err = bencode.Unmarshal(file, &m)
	if err != nil {
		log.Fatal(err)
	}

	if (m.Info.Length != 0) {
		fmt.Println(m.Info.Length)
	}
}
<commit_msg>Add tags, detect single or multi-file mode, marshal info struct to bencoded message and print<commit_after>package main

import (
//	"crypto/sha1"
	"fmt"
	"log"
	"os"
	"code.google.com/p/bencode-go"
)

type Files struct {
	Length int "length"
	Path []string "path"
}

type Info struct {
	Name string "name"
	Length int "length"
//	Files []Files "files"
	Pieces string "pieces"
	PieceLength int "piece length"
}

type Metainfo struct {
	Info Info "info"
	Announce string "announce"
	AnnounceList [][]string "announce-list"
}

func main() {
	var m Metainfo

	if len(os.Args) != 2 {
		log.Fatalf("Usage: %s: torrent\n", os.Args[0])
        }
	torrent := os.Args[1]

	file, err := os.Open(torrent)
	if err != nil {
		log.Fatal(err)
	}

	err = bencode.Unmarshal(file, &m)
	if err != nil {
		log.Fatal(err)
	}

	if (m.Info.Length != 0) {
		log.Println("Single File Mode")
		fmt.Println(m.Info.Length)
	} else {
		log.Fatal("Multiple File Mode not implemented")
	}

	err = bencode.Marshal(os.Stdout, m.Info)
	if err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"

	"github.com/zenazn/goji"
)

const (
	tmpPrefix         = "chequer_image"
	resultPrefix      = "tesseract_result"
	tesseractLanguage = "mcr"
)

func main() {
	serviceGojiRoutes()
}

func serviceGojiRoutes() {
	goji.Post("/cheque", PostCheque)
	goji.Serve()
}

type ChequeRequest struct {
	ImageURL string `json:"image_url"`
}

func PostCheque(w http.ResponseWriter, r *http.Request) {
	multiReader, err := r.MultipartReader()
	var chequeResult *ChequeResult
	if err != nil {
		chequeResult, err = processNonMultipartChequeRequest(r)
	} else {
		chequeResult, err = processMultipartChequeRequest(multiReader)
	}

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

	w.Header().Set("Content-Type", "application/json")
	responseData, err := json.Marshal(chequeResult)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(responseData)
}

func processNonMultipartChequeRequest(r *http.Request) (*ChequeResult, error) {
	decoder := json.NewDecoder(r.Body)
	var chequeRequest ChequeRequest
	decodeErr := decoder.Decode(&chequeRequest)

	if decodeErr != nil {
		return nil, decodeErr
	}

	httpResponse, err := http.Get(chequeRequest.ImageURL)
	if err != nil {
		return nil, err
	}
	defer httpResponse.Body.Close()

	tmpFile, err := ioutil.TempFile(os.TempDir(), tmpPrefix)
	if err != nil {
		return nil, err
	}
	defer tmpFile.Close()

	_, err = io.Copy(tmpFile, httpResponse.Body)
	return ProcessCheque(tmpFile)
}

func processMultipartChequeRequest(multiReader *multipart.Reader) (*ChequeResult, error) {
	var chequeResult *ChequeResult
	partCount := 0

	for {
		part, partErr := multiReader.NextPart()
		partCount++

		if partErr == io.EOF {
			return chequeResult, nil
		} else if partCount > 1 {
			return chequeResult, fmt.Errorf("Multiple parts found. Currently we " +
				"only support a single part.")
		} else if partErr != nil {
			return chequeResult, partErr
		} else {
			p, err := ioutil.ReadAll(part)
			if err != nil {
				return chequeResult, err
			}

			tmpFile, err := ioutil.TempFile(os.TempDir(), tmpPrefix)
			if err != nil {
				return nil, err
			}
			tmpFile.Close()

			ioutil.WriteFile(tmpFile.Name(), p, 0644)
			chequeResult, err = ProcessCheque(tmpFile)
		}
	}

	// This should never be called
	return nil, fmt.Errorf("Unable to find any multipart parts.")
}

func ProcessCheque(img *os.File) (*ChequeResult, error) {
	outFile, err := ioutil.TempFile(os.TempDir(), resultPrefix)
	if err != nil {
		return nil, err
	}

	options := []string{
		img.Name(),
		outFile.Name(),
		"-l",
		tesseractLanguage,
	}

	err = outFile.Close()
	if err != nil {
		return nil, err
	}

	cmd := exec.Command("tesseract", options...)
	output, err := cmd.CombinedOutput()
	if err != nil {
		log.Printf("Error calling tesseract: %v\n%s", err, output)
		return nil, err
	}

	outFile, err = os.Open(outFile.Name() + ".txt")
	if err != nil {
		return nil, err
	}

	return ProcessTesseractOutput(outFile)
}

func ProcessTesseractOutput(outFile *os.File) (*ChequeResult, error) {
	scanner := bufio.NewScanner(outFile)
	var micrLine string
	for scanner.Scan() {
		line := scanner.Text()
		if strings.Contains(line, "@") {
			micrLine = line
		}
	}

	result := ChequeResult{
		Account: findAccountNumber(micrLine),
		Routing: findRoutingNumber(micrLine),
	}
	log.Println(result)
	return &result, nil
}

func findAccountNumber(micrLine string) string {
	re := regexp.MustCompile("@(\\d+)@")
	match := re.FindStringSubmatch(micrLine)

	if len(match) > 0 {
		return match[1]
	}

	return ""
}

func findRoutingNumber(micrLine string) string {
	re := regexp.MustCompile("\\[([\\d-]+)\\[?")
	match := re.FindStringSubmatch(micrLine)

	if len(match) > 0 {
		return match[1]
	}

	return ""
}

type ChequeResult struct {
	Account string `json:"account"`
	Routing string `json:"routing"`
}
<commit_msg>Use multiple regexes.<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"

	"github.com/zenazn/goji"
)

const (
	tmpPrefix         = "chequer_image"
	resultPrefix      = "tesseract_result"
	tesseractLanguage = "mcr"
)

func main() {
	serviceGojiRoutes()
}

func serviceGojiRoutes() {
	goji.Post("/cheque", PostCheque)
	goji.Serve()
}

type ChequeRequest struct {
	ImageURL string `json:"image_url"`
}

func PostCheque(w http.ResponseWriter, r *http.Request) {
	multiReader, err := r.MultipartReader()
	var chequeResult *ChequeResult
	if err != nil {
		chequeResult, err = processNonMultipartChequeRequest(r)
	} else {
		chequeResult, err = processMultipartChequeRequest(multiReader)
	}

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

	w.Header().Set("Content-Type", "application/json")
	responseData, err := json.Marshal(chequeResult)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(responseData)
}

func processNonMultipartChequeRequest(r *http.Request) (*ChequeResult, error) {
	decoder := json.NewDecoder(r.Body)
	var chequeRequest ChequeRequest
	decodeErr := decoder.Decode(&chequeRequest)

	if decodeErr != nil {
		return nil, decodeErr
	}

	httpResponse, err := http.Get(chequeRequest.ImageURL)
	if err != nil {
		return nil, err
	}
	defer httpResponse.Body.Close()

	tmpFile, err := ioutil.TempFile(os.TempDir(), tmpPrefix)
	if err != nil {
		return nil, err
	}
	defer tmpFile.Close()

	_, err = io.Copy(tmpFile, httpResponse.Body)
	return ProcessCheque(tmpFile)
}

func processMultipartChequeRequest(multiReader *multipart.Reader) (*ChequeResult, error) {
	var chequeResult *ChequeResult
	partCount := 0

	for {
		part, partErr := multiReader.NextPart()
		partCount++

		if partErr == io.EOF {
			return chequeResult, nil
		} else if partCount > 1 {
			return chequeResult, fmt.Errorf("Multiple parts found. Currently we " +
				"only support a single part.")
		} else if partErr != nil {
			return chequeResult, partErr
		} else {
			p, err := ioutil.ReadAll(part)
			if err != nil {
				return chequeResult, err
			}

			tmpFile, err := ioutil.TempFile(os.TempDir(), tmpPrefix)
			if err != nil {
				return nil, err
			}
			tmpFile.Close()

			ioutil.WriteFile(tmpFile.Name(), p, 0644)
			chequeResult, err = ProcessCheque(tmpFile)
		}
	}

	// This should never be called
	return nil, fmt.Errorf("Unable to find any multipart parts.")
}

func ProcessCheque(img *os.File) (*ChequeResult, error) {
	outFile, err := ioutil.TempFile(os.TempDir(), resultPrefix)
	if err != nil {
		return nil, err
	}

	options := []string{
		img.Name(),
		outFile.Name(),
		"-l",
		tesseractLanguage,
	}

	err = outFile.Close()
	if err != nil {
		return nil, err
	}

	cmd := exec.Command("tesseract", options...)
	output, err := cmd.CombinedOutput()
	if err != nil {
		log.Printf("Error calling tesseract: %v\n%s", err, output)
		return nil, err
	}

	outFile, err = os.Open(outFile.Name() + ".txt")
	if err != nil {
		return nil, err
	}

	return ProcessTesseractOutput(outFile)
}

func ProcessTesseractOutput(outFile *os.File) (*ChequeResult, error) {
	scanner := bufio.NewScanner(outFile)
	var micrLine string
	for scanner.Scan() {
		line := scanner.Text()
		if strings.Contains(line, "@") {
			micrLine = line
		}
	}

	log.Println(micrLine)
	result := ChequeResult{
		Account: findAccountNumber(micrLine),
		Routing: findRoutingNumber(micrLine),
	}
	log.Println(result)
	return &result, nil
}

func findAccountNumber(micrLine string) string {
	regexes := []string{
		"@(\\d+)@?",
		"@?(\\d+)@",
	}
	for _, regexStr := range regexes {
		re := regexp.MustCompile(regexStr)
		match := re.FindStringSubmatch(micrLine)

		if len(match) > 0 {
			return match[1]
		}
	}

	return ""
}

func findRoutingNumber(micrLine string) string {
	regexes := []string{
		"\\[([\\d-]+)\\[?",
		"\\[?([\\d-]+)\\[",
	}
	for _, regexStr := range regexes {
		re := regexp.MustCompile(regexStr)
		match := re.FindStringSubmatch(micrLine)

		if len(match) > 0 {
			return match[1]
		}
	}

	return ""
}

type ChequeResult struct {
	Account string `json:"account"`
	Routing string `json:"routing"`
}
<|endoftext|>


<commit_before>package main

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

	yaml "gopkg.in/yaml.v2"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatchevents"
	"github.com/aws/aws-sdk-go/service/lambda"
)

// Version of the maekawa
var Version = "0.3.0"

func main() {
	var (
		apply, dryrun                           bool
		file, awsRegion                         string
		err                                     error
		sess                                    *session.Session
		cweRulesBeforeApply, cweRulesAfterApply *cloudwatchevents.ListRulesOutput
	)

	flag.BoolVar(&apply, "apply", false, "apply to CloudWatch Events")
	flag.BoolVar(&dryrun, "dry-run", false, "dry-run")
	flag.StringVar(&file, "file", "config.yml", "file path to setting yaml")
	flag.StringVar(&file, "f", "config.yml", "file path to setting yaml (shorthand)")
	flag.StringVar(&awsRegion, "region", os.Getenv("AWS_REGION"), "aws region")
	flag.Parse()

	sess, err = session.NewSession(
		&aws.Config{
			Region: aws.String(awsRegion),
		},
	)
	if err != nil {
		fmt.Println("Session error\n", err)
		os.Exit(1)
	}

	cweClient := cloudwatchevents.New(sess)
	lambdaClient := lambda.New(sess)

	cweRulesBeforeApply, err = cweClient.ListRules(nil)
	if err != nil {
		fmt.Println("API error\n", err)
		os.Exit(1)
	}

	describedRules := Rules{}
	err = loadYaml(file, &describedRules)
	if err != nil {
		fmt.Println("File error\n", err)
		os.Exit(1)
	}

	describedRules.Rules = AssociateRules(cweRulesBeforeApply.Rules, describedRules.Rules)
	for i, rule := range describedRules.Rules {
		t, _ := fetchActualTargetsByRule(cweClient, rule)
		describedRules.Rules[i].Targets = AssociateTargets(t, describedRules.Rules[i].Targets)
	}
	CheckIsNeedUpdateOrDelete(describedRules.Rules)
	displayWhatWillChange(describedRules.Rules)

	if apply && !dryrun {
		err = updateCloudWatchEvents(cweClient, describedRules.Rules)
		if err != nil {
			fmt.Println("API error\n", err)
			os.Exit(1)
		}

		err = removePermissonFromLambda(lambdaClient, describedRules.Rules)
		if err != nil {
			fmt.Println("API error\n", err)
			os.Exit(1)
		}

		// Grant permission to invoke lambda function from CloudWatch Events
		cweRulesAfterApply, err = cweClient.ListRules(nil)
		describedRules.Rules = AssociateRules(cweRulesAfterApply.Rules, describedRules.Rules)
		for i, rule := range describedRules.Rules {
			t, _ := fetchActualTargetsByRule(cweClient, rule)
			describedRules.Rules[i].Targets = AssociateTargets(t, describedRules.Rules[i].Targets)
		}

		err = addPermissionToLambdaFromCloudWatchEvents(lambdaClient, describedRules.Rules)
		if err != nil {
			fmt.Println("Grant permission error\n", err)
		}
	}
}

func loadYaml(file string, r *Rules) error {

	buf, err := ioutil.ReadFile(file)
	if err != nil {
		return err
	}

	err = yaml.Unmarshal(buf, &r)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Add command option for print self version to stdout<commit_after>package main

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

	yaml "gopkg.in/yaml.v2"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatchevents"
	"github.com/aws/aws-sdk-go/service/lambda"
)

// Version of the maekawa
var Version = "0.3.0"

func main() {
	var (
		apply, dryrun, version                  bool
		file, awsRegion                         string
		err                                     error
		sess                                    *session.Session
		cweRulesBeforeApply, cweRulesAfterApply *cloudwatchevents.ListRulesOutput
	)

	flag.BoolVar(&apply, "apply", false, "apply to CloudWatch Events")
	flag.BoolVar(&dryrun, "dry-run", false, "dry-run")
	flag.BoolVar(&version, "version", false, "show maekawa version")
	flag.BoolVar(&version, "v", false, "show maekawa version (shorthand)")
	flag.StringVar(&file, "file", "config.yml", "file path to setting yaml")
	flag.StringVar(&file, "f", "config.yml", "file path to setting yaml (shorthand)")
	flag.StringVar(&awsRegion, "region", os.Getenv("AWS_REGION"), "aws region")
	flag.Parse()

	if version {
		fmt.Printf("maekawa version %s\n", Version)
		os.Exit(0)
	}

	sess, err = session.NewSession(
		&aws.Config{
			Region: aws.String(awsRegion),
		},
	)
	if err != nil {
		fmt.Println("Session error\n", err)
		os.Exit(1)
	}

	cweClient := cloudwatchevents.New(sess)
	lambdaClient := lambda.New(sess)

	cweRulesBeforeApply, err = cweClient.ListRules(nil)
	if err != nil {
		fmt.Println("API error\n", err)
		os.Exit(1)
	}

	describedRules := Rules{}
	err = loadYaml(file, &describedRules)
	if err != nil {
		fmt.Println("File error\n", err)
		os.Exit(1)
	}

	describedRules.Rules = AssociateRules(cweRulesBeforeApply.Rules, describedRules.Rules)
	for i, rule := range describedRules.Rules {
		t, _ := fetchActualTargetsByRule(cweClient, rule)
		describedRules.Rules[i].Targets = AssociateTargets(t, describedRules.Rules[i].Targets)
	}
	CheckIsNeedUpdateOrDelete(describedRules.Rules)
	displayWhatWillChange(describedRules.Rules)

	if apply && !dryrun {
		err = updateCloudWatchEvents(cweClient, describedRules.Rules)
		if err != nil {
			fmt.Println("API error\n", err)
			os.Exit(1)
		}

		err = removePermissonFromLambda(lambdaClient, describedRules.Rules)
		if err != nil {
			fmt.Println("API error\n", err)
			os.Exit(1)
		}

		// Grant permission to invoke lambda function from CloudWatch Events
		cweRulesAfterApply, err = cweClient.ListRules(nil)
		describedRules.Rules = AssociateRules(cweRulesAfterApply.Rules, describedRules.Rules)
		for i, rule := range describedRules.Rules {
			t, _ := fetchActualTargetsByRule(cweClient, rule)
			describedRules.Rules[i].Targets = AssociateTargets(t, describedRules.Rules[i].Targets)
		}

		err = addPermissionToLambdaFromCloudWatchEvents(lambdaClient, describedRules.Rules)
		if err != nil {
			fmt.Println("Grant permission error\n", err)
		}
	}
}

func loadYaml(file string, r *Rules) error {

	buf, err := ioutil.ReadFile(file)
	if err != nil {
		return err
	}

	err = yaml.Unmarshal(buf, &r)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


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

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

const (
	illuminancePath   = "/sys/bus/iio/devices/iio:device0/in_illuminance_raw"
	backlightMaxPath  = "/sys/class/backlight/intel_backlight/max_brightness"
	backlightCurrPath = "/sys/class/backlight/intel_backlight/brightness"
)

func sysfileReadInt(f string) (int, error) {
	file, err := os.Open(f)
	if err != nil {
		return -1, err
	}
	defer file.Close()
	buf, err := ioutil.ReadAll(file)
	if err != nil {
		return -1, err
	}
	text := strings.TrimSpace(string(buf))
	return strconv.Atoi(text)
}

func sysfileWriteInt(name string, n int) error {
	buf := fmt.Sprintf("%d\n", n)
	return ioutil.WriteFile(name, []byte(buf), 0644)
}

type poller struct {
	max, min int
	ratio    int
	dryrun   bool
	wait     time.Duration
}

func (p *poller) poll() {
	maxIn := p.ratio * 100
	blMin := p.max / 50 // TODO: This is quite a magic number
	for {
		blight, err := sysfileReadInt(backlightCurrPath)
		if err != nil {
			log.Fatal("cannot get backlight value: ", err)
		}
		inlight, err := sysfileReadInt(illuminancePath)
		if err != nil {
			log.Fatal("cannot get ambient light value: ", err)
		}
		inlightPercent := inlight * 100 / maxIn
		if inlightPercent > 100 {
			inlightPercent = 100
		}
		nblight := inlightPercent*p.max/100 + p.min
		if nblight > p.max {
			nblight = p.max
		}
		diff := nblight - blight
		if diff < 0 {
			diff = -diff
		}
		if diff >= blMin {
			if !p.dryrun {
				if err := sysfileWriteInt(backlightCurrPath, nblight); err != nil {
					log.Fatal("cannot set backlight: ", err)
				}
			} else {
				log.Printf("change backlight to %d%%; illuminance = %d, backlight = %d (was %d)", inlightPercent, inlight, nblight, blight)
			}
		}
		time.Sleep(p.wait)
	}
}

func main() {
	max, err := sysfileReadInt(backlightMaxPath)
	if err != nil {
		log.Fatal("cannot get backlight max value: ", err)
	}
	p := poller{
		min:    65,
		max:    max,
		ratio:  30,    // lux = 1%
		dryrun: false, // TODO
		wait:   1 * time.Second,
	}
	flag.IntVar(&p.min, "min", p.min, "Minimum value `N` for backlight")
	flag.IntVar(&p.max, "max", p.max, "Maximum value `N` for backlight (autodetected)")
	flag.IntVar(&p.ratio, "ratio", p.ratio, "Ratio `R` of light change: number of lux for a 1% change in backlight")
	flag.BoolVar(&p.dryrun, "dryrun", p.dryrun, "Do not set backlight, only print what would happen")
	flag.DurationVar(&p.wait, "wait", p.wait, "Duration `T` between checks for changed light conditions")
	flag.Parse()
	p.poll()
}
<commit_msg>Improve defaults and add debug flag<commit_after>// Copyright 2015 Giulio Iotti. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

const (
	illuminancePath   = "/sys/bus/iio/devices/iio:device0/in_illuminance_raw"
	backlightMaxPath  = "/sys/class/backlight/intel_backlight/max_brightness"
	backlightCurrPath = "/sys/class/backlight/intel_backlight/brightness"
)

func sysfileReadInt(f string) (int, error) {
	file, err := os.Open(f)
	if err != nil {
		return -1, err
	}
	defer file.Close()
	buf, err := ioutil.ReadAll(file)
	if err != nil {
		return -1, err
	}
	text := strings.TrimSpace(string(buf))
	return strconv.Atoi(text)
}

func sysfileWriteInt(name string, n int) error {
	buf := fmt.Sprintf("%d\n", n)
	return ioutil.WriteFile(name, []byte(buf), 0644)
}

type poller struct {
	max, min int
	sens     int
	ratio    int
	dryrun   bool
	debug    bool
	wait     time.Duration
}

func (p *poller) poll() {
	maxIn := p.ratio * 100
	blMin := p.sens * p.max / 100
	for {
		blight, err := sysfileReadInt(backlightCurrPath)
		if err != nil {
			log.Fatal("cannot get backlight value: ", err)
		}
		inlight, err := sysfileReadInt(illuminancePath)
		if err != nil {
			log.Fatal("cannot get ambient light value: ", err)
		}
		inlightPercent := inlight * 100 / maxIn
		if inlightPercent > 100 {
			inlightPercent = 100
		}
		nblight := inlightPercent*p.max/100 + p.min
		if nblight > p.max {
			nblight = p.max
		}
		diff := nblight - blight
		if diff < 0 {
			diff = -diff
		}
		if p.debug {
			log.Printf("light = %d (%d%%), back-light = %d, set %d (diff %d, min %d)", inlight, inlightPercent, blight, nblight, diff, blMin)
		}
		// Set backlight if there is more than the minimum change thresold to adjust. Or if we are below min (level was never set.)
		if diff >= blMin || blight < p.min {
			if !p.dryrun {
				if err := sysfileWriteInt(backlightCurrPath, nblight); err != nil {
					log.Fatal("cannot set backlight: ", err)
				}
			} else {
				log.Printf("change backlight to %d%%; illuminance = %d, backlight = %d (was %d)", inlightPercent, inlight, nblight, blight)
			}
		}
		time.Sleep(p.wait)
	}
}

func main() {
	max, err := sysfileReadInt(backlightMaxPath)
	if err != nil {
		log.Fatal("cannot get backlight max value: ", err)
	}
	p := poller{
		min:    75,  // backlight min N
		max:    max, // backlight max N
		sens:   2,   // sensitivity %
		ratio:  60,  // lux = 1%
		dryrun: false,
		debug:  false,
		wait:   2 * time.Second,
	}
	flag.IntVar(&p.min, "min", p.min, "Minimum value `N` for backlight")
	flag.IntVar(&p.max, "max", p.max, "Maximum value `N` for backlight (autodetected)")
	flag.IntVar(&p.sens, "sensitivity", p.sens, "Minimum amount `S` in percent of backlight change to perform")
	flag.IntVar(&p.ratio, "ratio", p.ratio, "Ratio `R` of light change: number of lux for a 1% change in backlight")
	flag.BoolVar(&p.dryrun, "dryrun", p.dryrun, "Do not set backlight, only print what would happen")
	flag.BoolVar(&p.debug, "debug", p.debug, "Print values read from sensors every wait duration")
	flag.DurationVar(&p.wait, "wait", p.wait, "Duration `T` between checks for changed light conditions")
	flag.Parse()
	p.poll()
}
<|endoftext|>