<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"sync"
	"text/tabwriter"

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

	"github.com/docker/machine/drivers"
	_ "github.com/docker/machine/drivers/azure"
	_ "github.com/docker/machine/drivers/digitalocean"
	_ "github.com/docker/machine/drivers/none"
	_ "github.com/docker/machine/drivers/virtualbox"
	"github.com/docker/machine/state"
)

type HostListItem struct {
	Name       string
	Active     bool
	DriverName string
	State      state.State
	URL        string
}

type HostListItemByName []HostListItem

func (h HostListItemByName) Len() int {
	return len(h)
}

func (h HostListItemByName) Swap(i, j int) {
	h[i], h[j] = h[j], h[i]
}

func (h HostListItemByName) Less(i, j int) bool {
	return strings.ToLower(h[i].Name) < strings.ToLower(h[j].Name)
}

func BeforeHandler(c *cli.Context) error {
	if c.Bool("debug") {
		os.Setenv("DEBUG", "1")
		initLogging(log.DebugLevel)
	}

	return nil
}

var Commands = []cli.Command{
	{
		Name:  "active",
		Usage: "Get or set the active machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			store := NewStore()

			if name == "" {
				host, err := store.GetActive()
				if err != nil {
					log.Errorf("error finding active host")
				}
				if host != nil {
					fmt.Println(host.Name)
				}
			} else if name != "" {
				host, err := store.Load(name)
				if err != nil {
					log.Errorln(err)
					log.Errorf("error loading new active host")
					os.Exit(1)
				}

				if err := store.SetActive(host); err != nil {
					log.Errorf("error setting new active host")
					os.Exit(1)
				}
			} else {
				cli.ShowCommandHelp(c, "active")
			}
		},
	},
	{
		Flags: append(
			drivers.GetCreateFlags(),
			cli.StringFlag{
				Name: "driver, d",
				Usage: fmt.Sprintf(
					"Driver to create machine with. Available drivers: %s",
					strings.Join(drivers.GetDriverNames(), ", "),
				),
				Value: "none",
			},
		),
		Name:  "create",
		Usage: "Create a machine",
		Action: func(c *cli.Context) {
			driver := c.String("driver")
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "create")
				os.Exit(1)
			}

			keyExists, err := drivers.PublicKeyExists()
			if err != nil {
				log.Errorf("error")
				os.Exit(1)
			}

			if !keyExists {
				log.Errorf("error key doesn't exist")
				os.Exit(1)
			}

			store := NewStore()

			host, err := store.Create(name, driver, c)
			if err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}
			if err := store.SetActive(host); err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}

			log.Infof("%q has been created and is now the active machine. To point Docker at this machine, run: export DOCKER_HOST=$(machine url) DOCKER_AUTH=identity", name)
		},
	},
	{
		Name:  "inspect",
		Usage: "Inspect information about a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "inspect")
				os.Exit(1)
			}

			store := NewStore()
			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error loading data")
				os.Exit(1)
			}

			prettyJson, err := json.MarshalIndent(host, "", "    ")
			if err != nil {
				log.Error("error with json")
				os.Exit(1)
			}

			fmt.Println(string(prettyJson))
		},
	},
	{
		Name:  "ip",
		Usage: "Get the IP address of a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "ip")
				os.Exit(1)
			}

			var (
				err   error
				host  *Host
				store = NewStore()
			)

			if name != "" {
				host, err = store.Load(name)
				if err != nil {
					log.Errorf("error unable to load data")
					os.Exit(1)
				}
			} else {
				host, err = store.GetActive()
				if err != nil {
					log.Errorf("error")
					os.Exit(1)
				}
				if host == nil {
					os.Exit(1)
				}
			}

			ip, err := host.Driver.GetIP()
			if err != nil {
				log.Errorf("error unable to get IP")
				os.Exit(1)
			}

			fmt.Println(ip)
		},
	},
	{
		Name:  "kill",
		Usage: "Kill a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "kill")
				os.Exit(1)
			}

			store := NewStore()

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load data")
				os.Exit(1)
			}

			host.Driver.Kill()
		},
	},
	{
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "quiet, q",
				Usage: "Enable quiet mode",
			},
		},
		Name:  "ls",
		Usage: "List machines",
		Action: func(c *cli.Context) {
			quiet := c.Bool("quiet")
			store := NewStore()

			hostList, err := store.List()
			if err != nil {
				log.Errorf("error unable to list hosts")
				os.Exit(1)
			}

			w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)

			if !quiet {
				fmt.Fprintln(w, "NAME\tACTIVE\tDRIVER\tSTATE\tURL")
			}

			wg := sync.WaitGroup{}

			for _, host := range hostList {
				host := host
				if quiet {
					fmt.Fprintf(w, "%s\n", host.Name)
				} else {
					wg.Add(1)
					go func() {
						currentState, err := host.Driver.GetState()
						if err != nil {
							log.Errorf("error getting state for host %s: %s", host.Name, err)
						}

						url, err := host.GetURL()
						if err != nil {
							if err == drivers.ErrHostIsNotRunning {
								url = ""
							} else {
								log.Errorf("error getting URL for host %s: %s", host.Name, err)
							}
						}

						isActive, err := store.IsActive(&host)
						if err != nil {
							log.Errorf("error determining whether host %q is active: %s",
								host.Name, err)
						}

						activeString := ""
						if isActive {
							activeString = "*"
						}

						fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
							host.Name, activeString, host.Driver.DriverName(), currentState, url)
						wg.Done()
					}()
				}
			}

			wg.Wait()
			w.Flush()
		},
	},
	{
		Name:  "restart",
		Usage: "Restart a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			if name == "" {
				cli.ShowCommandHelp(c, "restart")
				os.Exit(1)
			}

			store := NewStore()

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load data")
				os.Exit(1)
			}

			host.Driver.Restart()
		},
	},
	{
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "force, f",
				Usage: "Remove local configuration even if machine cannot be removed",
			},
		},
		Name:  "rm",
		Usage: "Remove a machine",
		Action: func(c *cli.Context) {
			if len(c.Args()) == 0 {
				cli.ShowCommandHelp(c, "rm")
				os.Exit(1)
			}

			force := c.Bool("force")

			isError := false

			store := NewStore()
			for _, host := range c.Args() {
				if err := store.Remove(host, force); err != nil {
					log.Errorf("Error removing machine %s: %s", host, err)
					isError = true
				}
			}
			if isError {
				log.Errorf("There was an error removing a machine. To force remove it, pass the -f option. Warning: this might leave it running on the provider.")
			}
		},
	},
	{
		Name:  "ssh",
		Usage: "Log into or run a command on a machine with SSH",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "ssh")
				os.Exit(1)
			}

			i := 1
			for i < len(os.Args) && os.Args[i-1] != name {
				i++
			}

			store := NewStore()

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}

			sshCmd, err := host.Driver.GetSSHCommand(os.Args[i:]...)
			if err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}

			sshCmd.Stdin = os.Stdin
			sshCmd.Stdout = os.Stdout
			sshCmd.Stderr = os.Stderr
			if err := sshCmd.Run(); err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}
		},
	},
	{
		Name:  "start",
		Usage: "Start a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			store := NewStore()

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load data")
				os.Exit(1)
			}

			host.Start()
		},
	},
	{
		Name:  "stop",
		Usage: "Stop a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			if name == "" {
				cli.ShowCommandHelp(c, "stop")
				os.Exit(1)
			}

			store := NewStore()

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load data")
				os.Exit(1)
			}

			host.Stop()
		},
	},
	{
		Name:  "upgrade",
		Usage: "Upgrade a machine to the latest version of Docker",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			if name == "" {
				cli.ShowCommandHelp(c, "upgrade")
				os.Exit(1)
			}

			store := NewStore()
			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load host")
				os.Exit(1)
			}

			host.Driver.Upgrade()
		},
	},
	{
		Name:  "url",
		Usage: "Get the URL of a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "url")
				os.Exit(1)
			}

			var (
				err   error
				host  *Host
				store = NewStore()
			)

			if name != "" {
				host, err = store.Load(name)
				if err != nil {
					log.Errorf("error unable to load data")
					os.Exit(1)
				}
			} else {
				host, err = store.GetActive()
				if err != nil {
					log.Errorf("error unable to get active host")
					os.Exit(1)
				}
				if host == nil {
					os.Exit(1)
				}
			}

			url, err := host.GetURL()
			if err != nil {
				log.Errorf("error unable to get url for host")
				os.Exit(1)
			}

			fmt.Println(url)
		},
	},
}
<commit_msg>makes the name optional for stop/start/ssh/upgrade<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"sync"
	"text/tabwriter"

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

	"github.com/docker/machine/drivers"
	_ "github.com/docker/machine/drivers/azure"
	_ "github.com/docker/machine/drivers/digitalocean"
	_ "github.com/docker/machine/drivers/none"
	_ "github.com/docker/machine/drivers/virtualbox"
	"github.com/docker/machine/state"
)

type HostListItem struct {
	Name       string
	Active     bool
	DriverName string
	State      state.State
	URL        string
}

type HostListItemByName []HostListItem

func (h HostListItemByName) Len() int {
	return len(h)
}

func (h HostListItemByName) Swap(i, j int) {
	h[i], h[j] = h[j], h[i]
}

func (h HostListItemByName) Less(i, j int) bool {
	return strings.ToLower(h[i].Name) < strings.ToLower(h[j].Name)
}

func BeforeHandler(c *cli.Context) error {
	// if c.Bool("debug") {
	// 	os.Setenv("DEBUG", "1")
	// 	initLogging(log.DebugLevel)
	// }

	return nil
}

var Commands = []cli.Command{
	{
		Name:  "active",
		Usage: "Get or set the active machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			store := NewStore()

			if name == "" {
				host, err := store.GetActive()
				if err != nil {
					log.Errorf("error finding active host")
				}
				if host != nil {
					fmt.Println(host.Name)
				}
			} else if name != "" {
				host, err := store.Load(name)
				if err != nil {
					log.Errorln(err)
					log.Errorf("error loading new active host")
					os.Exit(1)
				}

				if err := store.SetActive(host); err != nil {
					log.Errorf("error setting new active host")
					os.Exit(1)
				}
			} else {
				cli.ShowCommandHelp(c, "active")
			}
		},
	},
	{
		Flags: append(
			drivers.GetCreateFlags(),
			cli.StringFlag{
				Name: "driver, d",
				Usage: fmt.Sprintf(
					"Driver to create machine with. Available drivers: %s",
					strings.Join(drivers.GetDriverNames(), ", "),
				),
				Value: "none",
			},
		),
		Name:  "create",
		Usage: "Create a machine",
		Action: func(c *cli.Context) {
			driver := c.String("driver")
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "create")
				os.Exit(1)
			}

			keyExists, err := drivers.PublicKeyExists()
			if err != nil {
				log.Errorf("error")
				os.Exit(1)
			}

			if !keyExists {
				log.Errorf("error key doesn't exist")
				os.Exit(1)
			}

			store := NewStore()

			fmt.Printf("%#v", c.String("url"))

			host, err := store.Create(name, driver, c)
			if err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}
			if err := store.SetActive(host); err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}

			log.Infof("%q has been created and is now the active machine. To point Docker at this machine, run: export DOCKER_HOST=$(machine url) DOCKER_AUTH=identity", name)
		},
	},
	{
		Name:  "inspect",
		Usage: "Inspect information about a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "inspect")
				os.Exit(1)
			}

			store := NewStore()
			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error loading data")
				os.Exit(1)
			}

			prettyJson, err := json.MarshalIndent(host, "", "    ")
			if err != nil {
				log.Error("error with json")
				os.Exit(1)
			}

			fmt.Println(string(prettyJson))
		},
	},
	{
		Name:  "ip",
		Usage: "Get the IP address of a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "ip")
				os.Exit(1)
			}

			var (
				err   error
				host  *Host
				store = NewStore()
			)

			if name != "" {
				host, err = store.Load(name)
				if err != nil {
					log.Errorf("error unable to load data")
					os.Exit(1)
				}
			} else {
				host, err = store.GetActive()
				if err != nil {
					log.Errorf("error")
					os.Exit(1)
				}
				if host == nil {
					os.Exit(1)
				}
			}

			ip, err := host.Driver.GetIP()
			if err != nil {
				log.Errorf("error unable to get IP")
				os.Exit(1)
			}

			fmt.Println(ip)
		},
	},
	{
		Name:  "kill",
		Usage: "Kill a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "kill")
				os.Exit(1)
			}

			store := NewStore()

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load data")
				os.Exit(1)
			}

			host.Driver.Kill()
		},
	},
	{
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "quiet, q",
				Usage: "Enable quiet mode",
			},
		},
		Name:  "ls",
		Usage: "List machines",
		Action: func(c *cli.Context) {
			quiet := c.Bool("quiet")
			store := NewStore()

			hostList, err := store.List()
			if err != nil {
				log.Errorf("error unable to list hosts")
				os.Exit(1)
			}

			w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)

			if !quiet {
				fmt.Fprintln(w, "NAME\tACTIVE\tDRIVER\tSTATE\tURL")
			}

			wg := sync.WaitGroup{}

			for _, host := range hostList {
				host := host
				if quiet {
					fmt.Fprintf(w, "%s\n", host.Name)
				} else {
					wg.Add(1)
					go func() {
						currentState, err := host.Driver.GetState()
						if err != nil {
							log.Errorf("error getting state for host %s: %s", host.Name, err)
						}

						url, err := host.GetURL()
						if err != nil {
							if err == drivers.ErrHostIsNotRunning {
								url = ""
							} else {
								log.Errorf("error getting URL for host %s: %s", host.Name, err)
							}
						}

						isActive, err := store.IsActive(&host)
						if err != nil {
							log.Errorf("error determining whether host %q is active: %s",
								host.Name, err)
						}

						activeString := ""
						if isActive {
							activeString = "*"
						}

						fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
							host.Name, activeString, host.Driver.DriverName(), currentState, url)
						wg.Done()
					}()
				}
			}

			wg.Wait()
			w.Flush()
		},
	},
	{
		Name:  "restart",
		Usage: "Restart a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			if name == "" {
				cli.ShowCommandHelp(c, "restart")
				os.Exit(1)
			}

			store := NewStore()

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load data")
				os.Exit(1)
			}

			host.Driver.Restart()
		},
	},
	{
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "force, f",
				Usage: "Remove local configuration even if machine cannot be removed",
			},
		},
		Name:  "rm",
		Usage: "Remove a machine",
		Action: func(c *cli.Context) {
			if len(c.Args()) == 0 {
				cli.ShowCommandHelp(c, "rm")
				os.Exit(1)
			}

			force := c.Bool("force")

			isError := false

			store := NewStore()
			for _, host := range c.Args() {
				if err := store.Remove(host, force); err != nil {
					log.Errorf("Error removing machine %s: %s", host, err)
					isError = true
				}
			}
			if isError {
				log.Errorf("There was an error removing a machine. To force remove it, pass the -f option. Warning: this might leave it running on the provider.")
			}
		},
	},
	{
		Name:  "ssh",
		Usage: "Log into or run a command on a machine with SSH",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			store := NewStore()

			if name == "" {
				host, err := store.GetActive()
				if err != nil {
					log.Errorf("error unable to get active host")
					os.Exit(1)
				}

				name = host.Name
			}

			i := 1
			for i < len(os.Args) && os.Args[i-1] != name {
				i++
			}

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}

			sshCmd, err := host.Driver.GetSSHCommand(os.Args[i:]...)
			if err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}

			sshCmd.Stdin = os.Stdin
			sshCmd.Stdout = os.Stdout
			sshCmd.Stderr = os.Stderr
			if err := sshCmd.Run(); err != nil {
				log.Errorf("%s", err)
				os.Exit(1)
			}
		},
	},
	{
		Name:  "start",
		Usage: "Start a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			store := NewStore()

			if name == "" {
				host, err := store.GetActive()
				if err != nil {
					log.Errorf("error unable to get active host")
					os.Exit(1)
				}

				name = host.Name
			}

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load data")
				os.Exit(1)
			}

			host.Start()
		},
	},
	{
		Name:  "stop",
		Usage: "Stop a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			store := NewStore()

			if name == "" {
				host, err := store.GetActive()
				if err != nil {
					log.Errorf("error unable to get active host")
					os.Exit(1)
				}

				name = host.Name
			}

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load data")
				os.Exit(1)
			}

			host.Stop()
		},
	},
	{
		Name:  "upgrade",
		Usage: "Upgrade a machine to the latest version of Docker",
		Action: func(c *cli.Context) {
			name := c.Args().First()
			store := NewStore()

			if name == "" {
				host, err := store.GetActive()
				if err != nil {
					log.Errorf("error unable to get active host")
					os.Exit(1)
				}

				name = host.Name
			}

			host, err := store.Load(name)
			if err != nil {
				log.Errorf("error unable to load host")
				os.Exit(1)
			}

			host.Driver.Upgrade()
		},
	},
	{
		Name:  "url",
		Usage: "Get the URL of a machine",
		Action: func(c *cli.Context) {
			name := c.Args().First()

			if name == "" {
				cli.ShowCommandHelp(c, "url")
				os.Exit(1)
			}

			var (
				err   error
				host  *Host
				store = NewStore()
			)

			if name != "" {
				host, err = store.Load(name)
				if err != nil {
					log.Errorf("error unable to load data")
					os.Exit(1)
				}
			} else {
				host, err = store.GetActive()
				if err != nil {
					log.Errorf("error unable to get active host")
					os.Exit(1)
				}
				if host == nil {
					os.Exit(1)
				}
			}

			url, err := host.GetURL()
			if err != nil {
				log.Errorf("error unable to get url for host")
				os.Exit(1)
			}

			fmt.Println(url)
		},
	},
}
<|endoftext|>


<commit_before>package shareit

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"io"
	"io/ioutil"
	"net/http"
	"path/filepath"
	//	"strconv"
	"errors"
	"github.com/scritch007/shareit/browse"
	"github.com/scritch007/shareit/share_link"
	"github.com/scritch007/shareit/types"
	"os"
	"strconv"
	"strings"
	"time"
)

//ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)
//CommandHandler is used to keep information about issued commands
type CommandHandler struct {
	config    *types.Configuration
	shareLink *share_link.ShareLinkHandler
	browser   *browse.BrowseHandler
}

func (c *CommandHandler) save(command *types.Command) error {
	return c.config.Db.SaveCommand(command)
}

// CommandHandler constructor
func NewCommandHandler(config *types.Configuration) (c *CommandHandler) {
	c = new(CommandHandler)
	c.config = config
	c.shareLink = share_link.NewShareLinkHandler(config)
	c.browser = browse.NewBrowseHandler(config)
	return c
}

func (c *CommandHandler) getHandler(command *types.Command) types.CommandHandler {
	if strings.Contains(string(command.Name), "browser.") {
		return c.browser
	} else if strings.Contains(string(command.Name), share_link.COMMAND_PREFIX) {
		return c.shareLink
	} else {
		return nil
	}
}

//Handle Request on /commands
//Only GET and POST request are available
func (c *CommandHandler) Commands(w http.ResponseWriter, r *http.Request) {
	user, err := c.config.Auth.GetAuthenticatedUser(w, r)
	if nil != err {
		http.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	if "GET" == r.Method {
		// We want to list the commands that have been already answered
		var userName *string = nil
		if nil != user {
			userName = &user.Id
		}
		commands, _, err := c.config.Db.ListCommands(userName, 0, -1, nil)
		if nil != err {
			errMessage := fmt.Sprintf("Invalid Input: %s", err)
			types.LOG_ERROR.Println(errMessage)
			http.Error(w, errMessage, http.StatusInternalServerError)
			return
		}
		b, _ := json.Marshal(commands)
		io.WriteString(w, string(b))
		return
	}
	// Extract the POST body
	command := new(types.Command)

	input, err := ioutil.ReadAll(r.Body)
	if nil != err {
		errMessage := fmt.Sprintf("1 Failed with error code: %s", err)
		types.LOG_ERROR.Println(errMessage)
		http.Error(w, errMessage, http.StatusBadRequest)
		return
	}
	err = json.Unmarshal(input, command)
	if nil != user {
		command.User = &user.Id //Store current user
	} else {
		command.User = nil
	}
	if nil != err {
		//TODO Set erro Code
	}
	channel := make(chan types.EnumCommandHandlerStatus)
	command.State.Progress = 0
	command.State.ErrorCode = 0
	command.State.Status = types.COMMAND_STATUS_IN_PROGRESS
	err = c.save(command)
	if nil != err {
		http.Error(w, "Couldn't save this command", http.StatusInternalServerError)
		return
	}

	handler := c.getHandler(command)
	if nil == handler {
		http.Error(w, "Unknown Request Type", http.StatusBadRequest)
	}
	commandContext := types.CommandContext{command, user, r}
	hErr := handler.Handle(&commandContext, channel)

	if nil != err {
		http.Error(w, hErr.Err.Error(), hErr.Status)
		return
	}
	timeout := time.Duration(command.Timeout)
	if 0 == timeout {
		timeout = 5
	}
	//timer := time.NewTimer(1)
	timer := time.NewTimer(timeout * time.Second)

	select {
	case a := <-channel:
		types.LOG_DEBUG.Println("Got answer from command")
		timer.Stop()
		if types.EnumCommandHandlerDone == a {
			command.State.Status = types.COMMAND_STATUS_DONE
			command.State.Progress = 100
		} else if types.EnumCommandHandlerError == a {
			command.State.Status = types.COMMAND_STATUS_ERROR
			command.State.Progress = 100
		}
		c.save(command)
	case <-timer.C:
		types.LOG_DEBUG.Println("Timer just elapsed")
		go func() {
			//Wait for the command to end
			a := <-channel
			if types.EnumCommandHandlerDone == a {
				command.State.Status = types.COMMAND_STATUS_DONE
				command.State.Progress = 100
			} else if types.EnumCommandHandlerError == a {
				command.State.Status = types.COMMAND_STATUS_ERROR
				command.State.Progress = 100
			}
			c.save(command)
		}()
	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	b, _ := json.Marshal(command)
	io.WriteString(w, string(b))
}

//This is extracted from the net/http/fs.go file
type httpRange struct {
	start, length int64
}

func parseRange(ra string, size int64) (*httpRange, error) {
	ra = strings.TrimSpace(ra)
	if ra == "" {
		return nil, errors.New("invalid range 1")
	}
	if !strings.HasPrefix(ra, "bytes") {
		return nil, errors.New("invalid range 1.1")
	}
	ra = ra[6:]
	i := strings.Index(ra, "-")
	if i < 0 {
		return nil, errors.New("invalid range 2")
	}
	start, endAndSize := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:])

	i = strings.Index(endAndSize, "/")

	end, rSizeStr := strings.TrimSpace(endAndSize[:i]), strings.TrimSpace(endAndSize[i+1:])

	value, err := strconv.ParseInt(rSizeStr, 10, 64)
	if err != nil {
		return nil, errors.New("invalid range 2.5")
	}
	rSize := value

	if rSize != size {
		return nil, errors.New("Invalid range 3")
	}

	var r httpRange
	value, err = strconv.ParseInt(start, 10, 64)
	if err != nil || value > size || value < 0 {
		return nil, errors.New("invalid range 4")
	}
	r.start = value
	value, err = strconv.ParseInt(end, 10, 64)
	if err != nil || r.start > value {
		return nil, errors.New("invalid range 5")
	}
	if value >= size {
		value = size - 1
	}
	r.length = value - r.start + 1
	return &r, nil
}

func (c *CommandHandler) Command(w http.ResponseWriter, r *http.Request) {
	user, err := c.config.Auth.GetAuthenticatedUser(w, r)
	if nil != err {
		http.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}
	vars := mux.Vars(r)
	ref := vars["command_id"]
	command, err := c.config.Db.GetCommand(ref)
	if nil != command.User && (nil == user || *command.User != user.Id) {
		http.Error(w, "You are trying to access some resources that do not belong to you", http.StatusUnauthorized)
		return
	}
	if nil != err {
		http.Error(w, fmt.Sprintf("Couldn't get this command ref %s", ref), http.StatusBadRequest)
		return
	}
	if "GET" == r.Method {
		b, _ := json.Marshal(command)
		io.WriteString(w, string(b))
	} else if "PUT" == r.Method {

		if 100 == command.State.Progress {
			http.Error(w, "Command already completed", http.StatusUnauthorized)
			return
		}
		input, err := ioutil.ReadAll(r.Body)
		types.LOG_DEBUG.Println("Received ", len(input), "bytes")
		if nil != err {
			errMessage := fmt.Sprintf("1 Failed with error code: %s", err)
			types.LOG_ERROR.Println(errMessage)
			http.Error(w, errMessage, http.StatusBadRequest)
			return
		}
		h := c.getHandler(command)
		commandContext := types.CommandContext{command, user, r}
		uploadPath, size, hErr := h.GetUploadPath(&commandContext)

		if nil != hErr {
			errMessage := fmt.Sprintf("Failed to get upload path with error code: %s", hErr.Err)
			types.LOG_ERROR.Println(errMessage)
			http.Error(w, errMessage, hErr.Status)
			return
		}
		rangeHeader := r.Header.Get("Content-Range")

		if _, err := os.Stat(*uploadPath); err != nil {
			if os.IsNotExist(err) {
				fo, err := os.Create(*uploadPath)
				if nil != err {
					errMessage := fmt.Sprintf("Couldn't create File with error %s", err)
					http.Error(w, errMessage, http.StatusInternalServerError)
					return
				}
				fo.Close()
			} else {
				errMessage := fmt.Sprintf("Couldn't read stat with error %s", err)
				types.LOG_ERROR.Println(errMessage)
				http.Error(w, errMessage, http.StatusInternalServerError)
				return
			}
		}
		var offset int64 = 0
		if 0 != len(rangeHeader) {
			rangeValue, err := parseRange(rangeHeader, size)
			if nil != err {
				errMessage := fmt.Sprintf("Incorrect Range header %s", err.Error())
				types.LOG_ERROR.Println(errMessage)
				http.Error(w, errMessage, http.StatusBadRequest)
				return
			}
			if size < rangeValue.start {
				errMessage := fmt.Sprintf("Couldn't seek to requested offset %d", rangeValue.start)
				types.LOG_ERROR.Println(errMessage)
				http.Error(w, errMessage, http.StatusBadRequest)
				return
			}

			offset = rangeValue.start
		}
		f, err := os.OpenFile(*uploadPath, os.O_RDWR, os.ModePerm)
		if nil != err {
			errMessage := fmt.Sprintf("Failed to open file with error %s", err)
			types.LOG_ERROR.Println(errMessage)
			http.Error(w, errMessage, http.StatusInternalServerError)
			return
		}
		defer f.Close()
		f.Seek(offset, os.SEEK_SET)
		io.WriteString(f, string(input))
		command.State.Progress = int((offset + int64(len(input))) * 100 / size)
		if 100 == command.State.Progress {
			command.State.Status = types.COMMAND_STATUS_DONE
		}
	}
}

func (c *CommandHandler) Download(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	file := vars["file"]

	link, err := c.config.Db.GetDownloadLink(file)
	//Get the realpath depending on the configuration and the sharelink or direct download
	if nil == err {
		types.LOG_DEBUG.Println("Serving file ", *link.RealPath)
		w.Header().Set("Content-Disposition", "attachment; filename="+filepath.Base(*link.RealPath))
		http.ServeFile(w, r, *link.RealPath)
	} else {
		http.Error(w, "Download link is unavailable. Try renewing link", http.StatusNotFound)
	}
}
<commit_msg>Allow downloading folder as a zipped file.<commit_after>package shareit

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"io"
	"io/ioutil"
	"net/http"
	"path/filepath"
	//	"strconv"
	"errors"
	"github.com/scritch007/shareit/browse"
	"github.com/scritch007/shareit/share_link"
	"github.com/scritch007/shareit/types"
	"os"
	"strconv"
	"strings"
	"time"
	"archive/zip"
)

//ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)
//CommandHandler is used to keep information about issued commands
type CommandHandler struct {
	config    *types.Configuration
	shareLink *share_link.ShareLinkHandler
	browser   *browse.BrowseHandler
}

func (c *CommandHandler) save(command *types.Command) error {
	return c.config.Db.SaveCommand(command)
}

// CommandHandler constructor
func NewCommandHandler(config *types.Configuration) (c *CommandHandler) {
	c = new(CommandHandler)
	c.config = config
	c.shareLink = share_link.NewShareLinkHandler(config)
	c.browser = browse.NewBrowseHandler(config)
	return c
}

func (c *CommandHandler) getHandler(command *types.Command) types.CommandHandler {
	if strings.Contains(string(command.Name), "browser.") {
		return c.browser
	} else if strings.Contains(string(command.Name), share_link.COMMAND_PREFIX) {
		return c.shareLink
	} else {
		return nil
	}
}

//Handle Request on /commands
//Only GET and POST request are available
func (c *CommandHandler) Commands(w http.ResponseWriter, r *http.Request) {
	user, err := c.config.Auth.GetAuthenticatedUser(w, r)
	if nil != err {
		http.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	if "GET" == r.Method {
		// We want to list the commands that have been already answered
		var userName *string = nil
		if nil != user {
			userName = &user.Id
		}
		commands, _, err := c.config.Db.ListCommands(userName, 0, -1, nil)
		if nil != err {
			errMessage := fmt.Sprintf("Invalid Input: %s", err)
			types.LOG_ERROR.Println(errMessage)
			http.Error(w, errMessage, http.StatusInternalServerError)
			return
		}
		b, _ := json.Marshal(commands)
		io.WriteString(w, string(b))
		return
	}
	// Extract the POST body
	command := new(types.Command)

	input, err := ioutil.ReadAll(r.Body)
	if nil != err {
		errMessage := fmt.Sprintf("1 Failed with error code: %s", err)
		types.LOG_ERROR.Println(errMessage)
		http.Error(w, errMessage, http.StatusBadRequest)
		return
	}
	err = json.Unmarshal(input, command)
	if nil != user {
		command.User = &user.Id //Store current user
	} else {
		command.User = nil
	}
	if nil != err {
		//TODO Set erro Code
	}
	channel := make(chan types.EnumCommandHandlerStatus)
	command.State.Progress = 0
	command.State.ErrorCode = 0
	command.State.Status = types.COMMAND_STATUS_IN_PROGRESS
	err = c.save(command)
	if nil != err {
		http.Error(w, "Couldn't save this command", http.StatusInternalServerError)
		return
	}

	handler := c.getHandler(command)
	if nil == handler {
		http.Error(w, "Unknown Request Type", http.StatusBadRequest)
	}
	commandContext := types.CommandContext{command, user, r}
	hErr := handler.Handle(&commandContext, channel)

	if nil != err {
		http.Error(w, hErr.Err.Error(), hErr.Status)
		return
	}
	timeout := time.Duration(command.Timeout)
	if 0 == timeout {
		timeout = 5
	}
	//timer := time.NewTimer(1)
	timer := time.NewTimer(timeout * time.Second)

	select {
	case a := <-channel:
		types.LOG_DEBUG.Println("Got answer from command")
		timer.Stop()
		if types.EnumCommandHandlerDone == a {
			command.State.Status = types.COMMAND_STATUS_DONE
			command.State.Progress = 100
		} else if types.EnumCommandHandlerError == a {
			command.State.Status = types.COMMAND_STATUS_ERROR
			command.State.Progress = 100
		}
		c.save(command)
	case <-timer.C:
		types.LOG_DEBUG.Println("Timer just elapsed")
		go func() {
			//Wait for the command to end
			a := <-channel
			if types.EnumCommandHandlerDone == a {
				command.State.Status = types.COMMAND_STATUS_DONE
				command.State.Progress = 100
			} else if types.EnumCommandHandlerError == a {
				command.State.Status = types.COMMAND_STATUS_ERROR
				command.State.Progress = 100
			}
			c.save(command)
		}()
	}
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	b, _ := json.Marshal(command)
	io.WriteString(w, string(b))
}

//This is extracted from the net/http/fs.go file
type httpRange struct {
	start, length int64
}

func parseRange(ra string, size int64) (*httpRange, error) {
	ra = strings.TrimSpace(ra)
	if ra == "" {
		return nil, errors.New("invalid range 1")
	}
	if !strings.HasPrefix(ra, "bytes") {
		return nil, errors.New("invalid range 1.1")
	}
	ra = ra[6:]
	i := strings.Index(ra, "-")
	if i < 0 {
		return nil, errors.New("invalid range 2")
	}
	start, endAndSize := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:])

	i = strings.Index(endAndSize, "/")

	end, rSizeStr := strings.TrimSpace(endAndSize[:i]), strings.TrimSpace(endAndSize[i+1:])

	value, err := strconv.ParseInt(rSizeStr, 10, 64)
	if err != nil {
		return nil, errors.New("invalid range 2.5")
	}
	rSize := value

	if rSize != size {
		return nil, errors.New("Invalid range 3")
	}

	var r httpRange
	value, err = strconv.ParseInt(start, 10, 64)
	if err != nil || value > size || value < 0 {
		return nil, errors.New("invalid range 4")
	}
	r.start = value
	value, err = strconv.ParseInt(end, 10, 64)
	if err != nil || r.start > value {
		return nil, errors.New("invalid range 5")
	}
	if value >= size {
		value = size - 1
	}
	r.length = value - r.start + 1
	return &r, nil
}

func (c *CommandHandler) Command(w http.ResponseWriter, r *http.Request) {
	user, err := c.config.Auth.GetAuthenticatedUser(w, r)
	if nil != err {
		http.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}
	vars := mux.Vars(r)
	ref := vars["command_id"]
	command, err := c.config.Db.GetCommand(ref)
	if nil != command.User && (nil == user || *command.User != user.Id) {
		http.Error(w, "You are trying to access some resources that do not belong to you", http.StatusUnauthorized)
		return
	}
	if nil != err {
		http.Error(w, fmt.Sprintf("Couldn't get this command ref %s", ref), http.StatusBadRequest)
		return
	}
	if "GET" == r.Method {
		b, _ := json.Marshal(command)
		io.WriteString(w, string(b))
	} else if "PUT" == r.Method {

		if 100 == command.State.Progress {
			http.Error(w, "Command already completed", http.StatusUnauthorized)
			return
		}
		input, err := ioutil.ReadAll(r.Body)
		types.LOG_DEBUG.Println("Received ", len(input), "bytes")
		if nil != err {
			errMessage := fmt.Sprintf("1 Failed with error code: %s", err)
			types.LOG_ERROR.Println(errMessage)
			http.Error(w, errMessage, http.StatusBadRequest)
			return
		}
		h := c.getHandler(command)
		commandContext := types.CommandContext{command, user, r}
		uploadPath, size, hErr := h.GetUploadPath(&commandContext)

		if nil != hErr {
			errMessage := fmt.Sprintf("Failed to get upload path with error code: %s", hErr.Err)
			types.LOG_ERROR.Println(errMessage)
			http.Error(w, errMessage, hErr.Status)
			return
		}
		rangeHeader := r.Header.Get("Content-Range")

		if _, err := os.Stat(*uploadPath); err != nil {
			if os.IsNotExist(err) {
				fo, err := os.Create(*uploadPath)
				if nil != err {
					errMessage := fmt.Sprintf("Couldn't create File with error %s", err)
					http.Error(w, errMessage, http.StatusInternalServerError)
					return
				}
				fo.Close()
			} else {
				errMessage := fmt.Sprintf("Couldn't read stat with error %s", err)
				types.LOG_ERROR.Println(errMessage)
				http.Error(w, errMessage, http.StatusInternalServerError)
				return
			}
		}
		var offset int64 = 0
		if 0 != len(rangeHeader) {
			rangeValue, err := parseRange(rangeHeader, size)
			if nil != err {
				errMessage := fmt.Sprintf("Incorrect Range header %s", err.Error())
				types.LOG_ERROR.Println(errMessage)
				http.Error(w, errMessage, http.StatusBadRequest)
				return
			}
			if size < rangeValue.start {
				errMessage := fmt.Sprintf("Couldn't seek to requested offset %d", rangeValue.start)
				types.LOG_ERROR.Println(errMessage)
				http.Error(w, errMessage, http.StatusBadRequest)
				return
			}

			offset = rangeValue.start
		}
		f, err := os.OpenFile(*uploadPath, os.O_RDWR, os.ModePerm)
		if nil != err {
			errMessage := fmt.Sprintf("Failed to open file with error %s", err)
			types.LOG_ERROR.Println(errMessage)
			http.Error(w, errMessage, http.StatusInternalServerError)
			return
		}
		defer f.Close()
		f.Seek(offset, os.SEEK_SET)
		io.WriteString(f, string(input))
		command.State.Progress = int((offset + int64(len(input))) * 100 / size)
		if 100 == command.State.Progress {
			command.State.Status = types.COMMAND_STATUS_DONE
		}
	}
}

func (c *CommandHandler) Download(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	file := vars["file"]

	link, err := c.config.Db.GetDownloadLink(file)
	//Get the realpath depending on the configuration and the sharelink or direct download
	if nil == err {
		types.LOG_DEBUG.Println("Serving file ", *link.RealPath)
		fileInfo, err := os.Lstat(*link.RealPath)
		if nil != err{
			http.Error(w, "Download link doesn't point to a valid path", http.StatusNotFound)
			return
		}
		if fileInfo.IsDir(){
			zipFileName := fileInfo.Name() + ".zip"
			w.Header().Set("Content-Type", "application/zip")
			w.Header().Set("Content-Disposition", `attachment; filename="`+zipFileName+`"`)
			zw := zip.NewWriter(w)
			defer zw.Close()
			// Walk directory.
			filepath.Walk(*link.RealPath, func(path string, info os.FileInfo, err error) error {
				if info.IsDir() {
					return nil
				}
				// Remove base path, convert to forward slash.
				zipPath := path[len(*link.RealPath):]
				zipPath = strings.TrimLeft(strings.Replace(zipPath, `\`, "/", -1), `/`)
				ze, err := zw.Create(zipPath)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Cannot create zip entry <%s>: %s\n", zipPath, err)
					return err
				}
				file, err := os.Open(path)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Cannot open file <%s>: %s\n", path, err)
					return err
				}
				defer file.Close()
				io.Copy(ze, file)
				return nil
			})

		}else{
			w.Header().Set("Content-Disposition", "attachment; filename="+filepath.Base(*link.RealPath))
			http.ServeFile(w, r, *link.RealPath)
		}

	} else {
		http.Error(w, "Download link is unavailable. Try renewing link", http.StatusNotFound)
	}
}
<|endoftext|>


<commit_before>// Copyright 2017 The go-hep Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package fmom

import (
	"fmt"
	"math"
)

// Equal returns true if p1==p2
func Equal(p1, p2 P4) bool {
	return p4equal(p1, p2, 1e-14)
}

func p4equal(p1, p2 P4, epsilon float64) bool {
	if cmpeq(p1.E(), p2.E(), epsilon) &&
		cmpeq(p1.Px(), p2.Px(), epsilon) &&
		cmpeq(p1.Py(), p2.Py(), epsilon) &&
		cmpeq(p1.Pz(), p2.Pz(), epsilon) {
		return true
	}
	return false
}

func cmpeq(x, y, epsilon float64) bool {
	if x == y {
		return true
	}

	return math.Abs(x-y) < epsilon
}

// Add returns the sum p1+p2.
func Add(p1, p2 P4) P4 {
	// FIXME(sbinet):
	// dispatch most efficient/less-lossy addition
	// based on type(dst) (and, optionally, type(src))
	var sum P4
	switch p1 := p1.(type) {

	case *PxPyPzE:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		sum = &p

	case *EEtaPhiM:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		var pp EEtaPhiM
		pp.Set(&p)
		sum = &pp

	case *EtEtaPhiM:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		var pp EtEtaPhiM
		pp.Set(&p)
		sum = &pp

	case *PtEtaPhiM:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		var pp PtEtaPhiM
		pp.Set(&p)
		sum = &pp

	case *IPtCotThPhiM:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		var pp IPtCotThPhiM
		pp.Set(&p)
		sum = &pp

	default:
		panic(fmt.Errorf("fmom: invalid P4 concrete value: %#v", p1))
	}
	return sum
}

// IAdd adds src into dst, and returns dst
func IAdd(dst, src P4) P4 {
	// FIXME(sbinet):
	// dispatch most efficient/less-lossy addition
	// based on type(dst) (and, optionally, type(src))
	var sum P4
	var p4 *PxPyPzE = nil
	switch p1 := dst.(type) {

	case *PxPyPzE:
		p4 = p1
		sum = dst

	case *EEtaPhiM:
		p := NewPxPyPzE(p1.Px(), p1.Py(), p1.Pz(), p1.E())
		p4 = &p
		sum = dst

	case *EtEtaPhiM:
		p := NewPxPyPzE(p1.Px(), p1.Py(), p1.Pz(), p1.E())
		p4 = &p
		sum = dst

	case *PtEtaPhiM:
		p := NewPxPyPzE(p1.Px(), p1.Py(), p1.Pz(), p1.E())
		p4 = &p
		sum = dst

	case *IPtCotThPhiM:
		p := NewPxPyPzE(p1.Px(), p1.Py(), p1.Pz(), p1.E())
		p4 = &p
		sum = dst

	default:
		panic(fmt.Errorf("fmom: invalid P4 concrete value: %#v", dst))
	}
	p4[0] += src.Px()
	p4[1] += src.Py()
	p4[2] += src.Pz()
	p4[3] += src.E()
	sum.Set(p4)
	return sum
}

// Scale returns a*p
func Scale(a float64, p P4) P4 {
	// FIXME(sbinet):
	// dispatch most efficient/less-lossy operation
	// based on type(dst) (and, optionally, type(src))
	var out P4
	switch p := p.(type) {

	case *PxPyPzE:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		out = &dst

	case *EEtaPhiM:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		var pp EEtaPhiM
		pp.Set(&dst)
		out = &pp

	case *EtEtaPhiM:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		var pp EtEtaPhiM
		pp.Set(&dst)
		out = &pp

	case *PtEtaPhiM:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		var pp PtEtaPhiM
		pp.Set(&dst)
		out = &pp

	case *IPtCotThPhiM:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		var pp IPtCotThPhiM
		pp.Set(&dst)
		out = &pp

	default:
		panic(fmt.Errorf("fmom: invalid P4 concrete value: %#v", p))
	}

	return out
}
<commit_msg>fmom: implement InvMass<commit_after>// Copyright 2017 The go-hep Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package fmom

import (
	"fmt"
	"math"
)

// Equal returns true if p1==p2
func Equal(p1, p2 P4) bool {
	return p4equal(p1, p2, 1e-14)
}

func p4equal(p1, p2 P4, epsilon float64) bool {
	if cmpeq(p1.E(), p2.E(), epsilon) &&
		cmpeq(p1.Px(), p2.Px(), epsilon) &&
		cmpeq(p1.Py(), p2.Py(), epsilon) &&
		cmpeq(p1.Pz(), p2.Pz(), epsilon) {
		return true
	}
	return false
}

func cmpeq(x, y, epsilon float64) bool {
	if x == y {
		return true
	}

	return math.Abs(x-y) < epsilon
}

// Add returns the sum p1+p2.
func Add(p1, p2 P4) P4 {
	// FIXME(sbinet):
	// dispatch most efficient/less-lossy addition
	// based on type(dst) (and, optionally, type(src))
	var sum P4
	switch p1 := p1.(type) {

	case *PxPyPzE:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		sum = &p

	case *EEtaPhiM:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		var pp EEtaPhiM
		pp.Set(&p)
		sum = &pp

	case *EtEtaPhiM:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		var pp EtEtaPhiM
		pp.Set(&p)
		sum = &pp

	case *PtEtaPhiM:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		var pp PtEtaPhiM
		pp.Set(&p)
		sum = &pp

	case *IPtCotThPhiM:
		p := NewPxPyPzE(p1.Px()+p2.Px(), p1.Py()+p2.Py(), p1.Pz()+p2.Pz(), p1.E()+p2.E())
		var pp IPtCotThPhiM
		pp.Set(&p)
		sum = &pp

	default:
		panic(fmt.Errorf("fmom: invalid P4 concrete value: %#v", p1))
	}
	return sum
}

// IAdd adds src into dst, and returns dst
func IAdd(dst, src P4) P4 {
	// FIXME(sbinet):
	// dispatch most efficient/less-lossy addition
	// based on type(dst) (and, optionally, type(src))
	var sum P4
	var p4 *PxPyPzE = nil
	switch p1 := dst.(type) {

	case *PxPyPzE:
		p4 = p1
		sum = dst

	case *EEtaPhiM:
		p := NewPxPyPzE(p1.Px(), p1.Py(), p1.Pz(), p1.E())
		p4 = &p
		sum = dst

	case *EtEtaPhiM:
		p := NewPxPyPzE(p1.Px(), p1.Py(), p1.Pz(), p1.E())
		p4 = &p
		sum = dst

	case *PtEtaPhiM:
		p := NewPxPyPzE(p1.Px(), p1.Py(), p1.Pz(), p1.E())
		p4 = &p
		sum = dst

	case *IPtCotThPhiM:
		p := NewPxPyPzE(p1.Px(), p1.Py(), p1.Pz(), p1.E())
		p4 = &p
		sum = dst

	default:
		panic(fmt.Errorf("fmom: invalid P4 concrete value: %#v", dst))
	}
	p4[0] += src.Px()
	p4[1] += src.Py()
	p4[2] += src.Pz()
	p4[3] += src.E()
	sum.Set(p4)
	return sum
}

// Scale returns a*p
func Scale(a float64, p P4) P4 {
	// FIXME(sbinet):
	// dispatch most efficient/less-lossy operation
	// based on type(dst) (and, optionally, type(src))
	var out P4
	switch p := p.(type) {

	case *PxPyPzE:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		out = &dst

	case *EEtaPhiM:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		var pp EEtaPhiM
		pp.Set(&dst)
		out = &pp

	case *EtEtaPhiM:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		var pp EtEtaPhiM
		pp.Set(&dst)
		out = &pp

	case *PtEtaPhiM:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		var pp PtEtaPhiM
		pp.Set(&dst)
		out = &pp

	case *IPtCotThPhiM:
		dst := NewPxPyPzE(a*p.Px(), a*p.Py(), a*p.Pz(), a*p.E())
		var pp IPtCotThPhiM
		pp.Set(&dst)
		out = &pp

	default:
		panic(fmt.Errorf("fmom: invalid P4 concrete value: %#v", p))
	}

	return out
}

// InvMass computes the invariant mass of two incoming 4-vectors p1 and p2.
func InvMass(p1, p2 P4) float64 {
	p := Add(p1, p2)
	return p.M()
}
<|endoftext|>


<commit_before>package dalga

import (
	"encoding/json"
	"errors"
	"net/http"
	"net/url"
	"strconv"

	"github.com/cenkalti/dalga/dalga/Godeps/_workspace/src/github.com/bmizerany/pat"
)

func (d *Dalga) serveHTTP() error {
	const path = "/jobs/:jobPath/:jobBody"
	m := pat.New()
	m.Get(path, handler(d.handleGet))
	m.Put(path, handler(d.handleSchedule))
	m.Post(path, handler(d.handleTrigger))
	m.Del(path, handler(d.handleCancel))
	m.Get("/status", http.HandlerFunc(d.handleStatus))
	return http.Serve(d.listener, m)
}

func handler(f func(w http.ResponseWriter, r *http.Request, jobPath, body string)) http.HandlerFunc {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		debug("http:", r.Method, r.RequestURI)
		var err error

		jobPath := r.URL.Query().Get(":jobPath")
		if jobPath == "" {
			http.Error(w, "empty routing key", http.StatusBadRequest)
			return
		}
		jobPath, err = url.QueryUnescape(jobPath)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		jobBody := r.URL.Query().Get(":jobBody")
		if jobBody == "" {
			http.Error(w, "empty job", http.StatusBadRequest)
			return
		}
		jobBody, err = url.QueryUnescape(jobBody)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		f(w, r, jobPath, jobBody)
	})
}

func getInterval(r *http.Request) (uint32, error) {
	s := r.FormValue("interval")
	if s == "" {
		return 0, errors.New("empty interval")
	}
	i64, err := strconv.ParseUint(s, 10, 32)
	if err != nil {
		return 0, errors.New("cannot parse interval")
	}
	return uint32(i64), nil
}

func (d *Dalga) handleGet(w http.ResponseWriter, r *http.Request, path, body string) {
	job, err := d.Jobs.Get(path, body)
	if err == ErrNotExist {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	data, err := json.Marshal(job)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(data)
}

func (d *Dalga) handleSchedule(w http.ResponseWriter, r *http.Request, path, body string) {
	interval, err := getInterval(r)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	oneOff := r.FormValue("one-off") != ""
	if !oneOff && interval == 0 {
		http.Error(w, "interval can't be 0 for periodic jobs", http.StatusBadRequest)
		return
	}
	job, err := d.Jobs.Schedule(path, body, interval, oneOff)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	data, err := json.Marshal(job)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	w.Write(data)
}

func (d *Dalga) handleTrigger(w http.ResponseWriter, r *http.Request, path, body string) {
	job, err := d.Jobs.Trigger(path, body)
	if err == ErrNotExist {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	data, err := json.Marshal(job)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(data)
}

func (d *Dalga) handleCancel(w http.ResponseWriter, r *http.Request, path, body string) {
	err := d.Jobs.Cancel(path, body)
	if err == ErrNotExist {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusNoContent)
}

func (d *Dalga) handleStatus(w http.ResponseWriter, r *http.Request) {
	count, err := d.Jobs.Total()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	m := map[string]interface{}{
		"running_jobs": d.Jobs.Running(),
		"total_jobs":   count,
	}
	data, err := json.Marshal(m)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(data)
}
<commit_msg>validate one-off param<commit_after>package dalga

import (
	"encoding/json"
	"errors"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	"github.com/cenkalti/dalga/dalga/Godeps/_workspace/src/github.com/bmizerany/pat"
)

func (d *Dalga) serveHTTP() error {
	const path = "/jobs/:jobPath/:jobBody"
	m := pat.New()
	m.Get(path, handler(d.handleGet))
	m.Put(path, handler(d.handleSchedule))
	m.Post(path, handler(d.handleTrigger))
	m.Del(path, handler(d.handleCancel))
	m.Get("/status", http.HandlerFunc(d.handleStatus))
	return http.Serve(d.listener, m)
}

func handler(f func(w http.ResponseWriter, r *http.Request, jobPath, body string)) http.HandlerFunc {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		debug("http:", r.Method, r.RequestURI)
		var err error

		jobPath := r.URL.Query().Get(":jobPath")
		if jobPath == "" {
			http.Error(w, "empty routing key", http.StatusBadRequest)
			return
		}
		jobPath, err = url.QueryUnescape(jobPath)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		jobBody := r.URL.Query().Get(":jobBody")
		if jobBody == "" {
			http.Error(w, "empty job", http.StatusBadRequest)
			return
		}
		jobBody, err = url.QueryUnescape(jobBody)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		f(w, r, jobPath, jobBody)
	})
}

func getInterval(r *http.Request) (uint32, error) {
	s := r.FormValue("interval")
	if s == "" {
		return 0, errors.New("empty interval")
	}
	i64, err := strconv.ParseUint(s, 10, 32)
	if err != nil {
		return 0, errors.New("cannot parse interval")
	}
	return uint32(i64), nil
}

func (d *Dalga) handleGet(w http.ResponseWriter, r *http.Request, path, body string) {
	job, err := d.Jobs.Get(path, body)
	if err == ErrNotExist {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	data, err := json.Marshal(job)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(data)
}

func (d *Dalga) handleSchedule(w http.ResponseWriter, r *http.Request, path, body string) {
	interval, err := getInterval(r)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	var oneOff bool
	switch strings.ToLower(r.FormValue("one-off")) {
	case "1", "true", "yes", "on":
		oneOff = true
	case "0", "false", "no", "off", "":
		oneOff = false
	default:
		http.Error(w, "invalid one-off param", http.StatusBadRequest)
		return
	}
	if !oneOff && interval == 0 {
		http.Error(w, "interval can't be 0 for periodic jobs", http.StatusBadRequest)
		return
	}
	job, err := d.Jobs.Schedule(path, body, interval, oneOff)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	data, err := json.Marshal(job)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	w.Write(data)
}

func (d *Dalga) handleTrigger(w http.ResponseWriter, r *http.Request, path, body string) {
	job, err := d.Jobs.Trigger(path, body)
	if err == ErrNotExist {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	data, err := json.Marshal(job)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(data)
}

func (d *Dalga) handleCancel(w http.ResponseWriter, r *http.Request, path, body string) {
	err := d.Jobs.Cancel(path, body)
	if err == ErrNotExist {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusNoContent)
}

func (d *Dalga) handleStatus(w http.ResponseWriter, r *http.Request) {
	count, err := d.Jobs.Total()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	m := map[string]interface{}{
		"running_jobs": d.Jobs.Running(),
		"total_jobs":   count,
	}
	data, err := json.Marshal(m)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(data)
}
<|endoftext|>


<commit_before>// testrestcliant
package main

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

	"github.com/jmcvetta/napping"
	"bytes"
)

type Configuration struct {
	LogFilePath string
	Interval    int
	DebugMode   bool
	TraceMode   bool
	LogStashUrl string
	LgLogin     string // logstash login
	LgPassword  string // logstash password
	NatsUrls    []string
}
type NatsNodeTopInfo struct {
	Varz  Varz
	Connz Connz
}
type Cluster struct {
	Addr         string
	Cluster_port int
}
type Varz struct {
	Server_id         string
	Host              string
	Addr              string
	Http_host         string
	Cluster           Cluster
	Start             string
	Now               time.Time
	Uptime            string
	Mem               float32
	Cpu               float32
	Connections       int
	Total_connections int
	Routes            int
	Remotes           int
	In_msgs           int
	Out_msgs          int
	In_bytes          int
	Out_bytes         int
	In_msgs_sec       int
	Out_msgs_sec      int
	In_bytes_sec      int
	Out_bytes_sec     int
	Slow_consumers    int
	Subscriptions     int
}
type Connection struct {
	Сid           int
	Ip            string
	Port          int
	Start         string
	Last_activity string
	Uptime        string
	Pending_bytes int
	In_msgs       int
	Out_msgs      int
	In_bytes      int
	Out_bytes     int
}
type Connz struct {
	Now             string
	Num_connections int
	Total           int
	Offset          int
	Limit           int
	Connections     []Connection
}
type PrevInOutValues struct {
	In_msgs   int
	Out_msgs  int
	In_bytes  int
	Out_bytes int

	Now       time.Time
}
type InOutPerSec struct {
	In_msgs_sec   int
	Out_msgs_sec  int
	In_bytes_sec  int
	Out_bytes_sec int
}

var prev_vals map[string]*PrevInOutValues = make(map[string]*PrevInOutValues)

func main() {

	config := Configuration{}

	configPathCL := flag.String("c", "", "path to config file")
	logFilePathCL := flag.String("l", "", "path to log file")
	isDebugCL := flag.Bool("d", false, "DEBUG mode")
	isTraceCL := flag.Bool("t", false, "TRACE mode")

	setFlag(flag.CommandLine)
	flag.Parse()

	config = readConfig(*configPathCL)

	isDebug := config.DebugMode
	isTrace := config.DebugMode

	if *isDebugCL {
		isDebug = *isDebugCL
	}

	if *isTraceCL {
		isTrace = *isTraceCL
	}

	setLogOutput(config, *logFilePathCL)

	httpClient := http.Client{}
	httpClient.Timeout = time.Duration(300) * time.Millisecond
	sessionToNats := napping.Session{Client: &httpClient}
	sessionToLogstash := napping.Session{Userinfo: url.UserPassword(config.LgLogin, config.LgPassword)}

	e := HttpError{}

	log.Printf("NATS-ELK forwarder started\n")
	log.Printf("Interval of requests: %d ms\n", config.Interval)

	for true {
		for _, url := range config.NatsUrls {

			varz := Varz{}
			connzs := Connz{}
			natsNodeTopInfo := NatsNodeTopInfo{}

			varzUrl := url + "/varz"
			connzUrl := url + "/connz"

			varzResponse, err := sessionToNats.Get(varzUrl, nil, &varz, &e)

			if err != nil && isDebug {
				log.Printf("%v\n", err)
				continue
			}

			connzResponse, err := sessionToNats.Get(connzUrl, nil, &connzs, &e)

			if err != nil && isDebug {
				log.Printf("%v\n", err)
				continue
			}

			if varzResponse.Status() == 200 && connzResponse.Status() == 200 {

				if isDebug {
					log.Printf("Get data from nats node (%v) - Success\n", url)
				}

				perSecValues := getPerSecValues(url, varz)

				varz.In_bytes_sec = perSecValues.In_bytes_sec
				varz.Out_bytes_sec = perSecValues.Out_bytes_sec
				varz.In_msgs_sec = perSecValues.In_msgs_sec
				varz.Out_msgs_sec = perSecValues.Out_msgs_sec

				varz.Mem = varz.Mem / 1024 / 1024 // to MB
				natsNodeTopInfo.Varz = varz
				natsNodeTopInfo.Connz = connzs

				if isTrace {
					printPrettyJson(natsNodeTopInfo)
				}

				logstashResponse, err := sessionToLogstash.Post(config.LogStashUrl, natsNodeTopInfo, nil, &e)

				if err != nil && isDebug {
					log.Printf("Sending to logstash -> Error: ")
					log.Printf("%v\n", err)
				}
				if logstashResponse.Status() == 200 && isDebug {
					log.Printf("Sending to logstash (%v): Success\n", config.LogStashUrl)
				}
			}
		}
		time.Sleep(time.Duration(config.Interval) * time.Millisecond)
	}
}
func getPerSecValues(url string, varz Varz) InOutPerSec {
	inOutPerSec := InOutPerSec{}

	if prev_vals[url] == nil {

		prev_vals[url] = &PrevInOutValues{}

		prev_vals[url].In_bytes = varz.In_bytes
		prev_vals[url].Out_bytes = varz.Out_bytes
		prev_vals[url].In_msgs = varz.In_msgs
		prev_vals[url].Out_msgs = varz.Out_msgs
		prev_vals[url].Now = varz.Now

		return InOutPerSec{}
	}

	// calculate
	in_bytes_delta := varz.In_bytes - prev_vals[url].In_bytes
	out_bytes_delta := varz.Out_bytes - prev_vals[url].Out_bytes

	in_msgs_delta := varz.In_msgs - prev_vals[url].In_msgs
	out_msgs_delta := varz.Out_msgs - prev_vals[url].Out_msgs

	sec := varz.Now.Second() - prev_vals[url].Now.Second()

	inOutPerSec.In_bytes_sec = in_bytes_delta / sec
	inOutPerSec.Out_bytes_sec = out_bytes_delta / sec
	inOutPerSec.In_msgs_sec = in_msgs_delta / sec
	inOutPerSec.Out_msgs_sec = out_msgs_delta / sec

	// save prev.values
	prev_vals[url].In_bytes = varz.In_bytes
	prev_vals[url].Out_bytes = varz.Out_bytes
	prev_vals[url].In_msgs = varz.In_msgs
	prev_vals[url].Out_msgs = varz.Out_msgs
	prev_vals[url].Now = varz.Now

	// return result
	return inOutPerSec
}
func readConfig(filepath string) Configuration {

	file, _ := os.Open(filepath)
	decoder := json.NewDecoder(file)
	configuration := Configuration{}
	err := decoder.Decode(&configuration)

	if err != nil {
		log.Println("error:", err)
	}

	return configuration
}

type HttpError struct {
	Message string
	Errors  []struct {
		Resource string
		Field    string
		Code     string
	}
}

func setFlag(flag *flag.FlagSet) {
	flag.Usage = func() {
		showHelp()
	}
}
func showHelp() {
	fmt.Println(`
Usage: CLI Template [OPTIONS]
Options:
    -c, --config     Path to config file.
    -l, --log        Path to log file.
    -d, --debug      DEBUG mode.
    -t, --trace      TRACE mode.
    -h, --help       prints this help info.
    `)
}
func setLogOutput(config Configuration, logFilePathCL string) {

	if len(config.LogFilePath) > 0 || len(logFilePathCL) > 0 {

		logFilePath := ""

		if len(config.LogFilePath) > 0 {
			logFilePath = config.LogFilePath
		}
		if len(logFilePathCL) > 0 {
			logFilePath = logFilePathCL
		}

		file, err := os.OpenFile(logFilePath, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)

		if err != nil {
			log.Fatalf("error opening file: %v", err)
		}

		log.SetOutput(file)
	}
}
func printPrettyJson(info NatsNodeTopInfo){
	var prettyJSON bytes.Buffer

	body, err := json.Marshal(info)

	if err != nil {
		log.Println(err)
		return
	}

	error := json.Indent(&prettyJSON, body, "", "\t")
	if error != nil {
		log.Println("JSON parse error: ", error)
		return
	}

	log.Println(string(prettyJSON.Bytes()))
}
<commit_msg>fixed trace bug<commit_after>package main

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

	"github.com/jmcvetta/napping"
	"bytes"
)

type Configuration struct {
	LogFilePath string
	Interval    int
	DebugMode   bool
	TraceMode   bool
	LogStashUrl string
	LgLogin     string // logstash login
	LgPassword  string // logstash password
	NatsUrls    []string
}
type NatsNodeTopInfo struct {
	Varz  Varz
	Connz Connz
}
type Cluster struct {
	Addr         string
	Cluster_port int
}
type Varz struct {
	Server_id         string
	Host              string
	Addr              string
	Http_host         string
	Cluster           Cluster
	Start             string
	Now               time.Time
	Uptime            string
	Mem               float32
	Cpu               float32
	Connections       int
	Total_connections int
	Routes            int
	Remotes           int
	In_msgs           int
	Out_msgs          int
	In_bytes          int
	Out_bytes         int
	In_msgs_sec       int
	Out_msgs_sec      int
	In_bytes_sec      int
	Out_bytes_sec     int
	Slow_consumers    int
	Subscriptions     int
}
type Connection struct {
	Сid           int
	Ip            string
	Port          int
	Start         string
	Last_activity string
	Uptime        string
	Pending_bytes int
	In_msgs       int
	Out_msgs      int
	In_bytes      int
	Out_bytes     int
}
type Connz struct {
	Now             string
	Num_connections int
	Total           int
	Offset          int
	Limit           int
	Connections     []Connection
}
type PrevInOutValues struct {
	In_msgs   int
	Out_msgs  int
	In_bytes  int
	Out_bytes int

	Now       time.Time
}
type InOutPerSec struct {
	In_msgs_sec   int
	Out_msgs_sec  int
	In_bytes_sec  int
	Out_bytes_sec int
}

var prev_vals map[string]*PrevInOutValues = make(map[string]*PrevInOutValues)

func main() {

	config := Configuration{}

	configPathCL := flag.String("c", "", "path to config file")
	logFilePathCL := flag.String("l", "", "path to log file")
	isDebugCL := flag.Bool("d", false, "DEBUG mode")
	isTraceCL := flag.Bool("t", false, "TRACE mode")

	setFlag(flag.CommandLine)
	flag.Parse()

	config = readConfig(*configPathCL)

	isDebug := config.DebugMode
	isTrace := config.TraceMode

	if *isDebugCL {
		isDebug = *isDebugCL
	}

	if *isTraceCL {
		isTrace = *isTraceCL
	}

	setLogOutput(config, *logFilePathCL)

	httpClient := http.Client{}
	httpClient.Timeout = time.Duration(300) * time.Millisecond
	sessionToNats := napping.Session{Client: &httpClient}
	sessionToLogstash := napping.Session{Userinfo: url.UserPassword(config.LgLogin, config.LgPassword)}

	e := HttpError{}

	log.Printf("NATS-ELK forwarder started\n")
	log.Printf("Interval of requests: %d ms\n", config.Interval)

	for true {

		for _, url := range config.NatsUrls {

			varz := Varz{}
			connzs := Connz{}
			natsNodeTopInfo := NatsNodeTopInfo{}

			varzUrl := url + "/varz"
			connzUrl := url + "/connz"

			varzResponse, err := sessionToNats.Get(varzUrl, nil, &varz, &e)

			if err != nil && isDebug {
				log.Printf("%v\n", err)
				continue
			}

			connzResponse, err := sessionToNats.Get(connzUrl, nil, &connzs, &e)

			if err != nil && isDebug {
				log.Printf("%v\n", err)
				continue
			}

			if varzResponse.Status() == 200 && connzResponse.Status() == 200 {

				if isDebug {
					log.Printf("Get data from nats node (%v) - Success\n", url)
				}

				perSecValues := getPerSecValues(url, varz)

				varz.In_bytes_sec = perSecValues.In_bytes_sec
				varz.Out_bytes_sec = perSecValues.Out_bytes_sec
				varz.In_msgs_sec = perSecValues.In_msgs_sec
				varz.Out_msgs_sec = perSecValues.Out_msgs_sec

				varz.Mem = varz.Mem / 1024 / 1024 // to MB
				natsNodeTopInfo.Varz = varz
				natsNodeTopInfo.Connz = connzs

				if isTrace {
					printPrettyJson(natsNodeTopInfo)
				}

				logstashResponse, err := sessionToLogstash.Post(config.LogStashUrl, natsNodeTopInfo, nil, &e)

				if err != nil && isDebug {
					log.Printf("Sending to logstash -> Error: ")
					log.Printf("%v\n", err)
				}
				if logstashResponse.Status() == 200 && isDebug {
					log.Printf("Sending to logstash (%v): Success\n", config.LogStashUrl)
				}
			}
		}
		time.Sleep(time.Duration(config.Interval) * time.Millisecond)
	}
}
func getPerSecValues(url string, varz Varz) InOutPerSec {
	inOutPerSec := InOutPerSec{}

	if prev_vals[url] == nil {

		prev_vals[url] = &PrevInOutValues{}

		prev_vals[url].In_bytes = varz.In_bytes
		prev_vals[url].Out_bytes = varz.Out_bytes
		prev_vals[url].In_msgs = varz.In_msgs
		prev_vals[url].Out_msgs = varz.Out_msgs
		prev_vals[url].Now = varz.Now

		return InOutPerSec{}
	}

	// calculate
	in_bytes_delta := varz.In_bytes - prev_vals[url].In_bytes
	out_bytes_delta := varz.Out_bytes - prev_vals[url].Out_bytes

	in_msgs_delta := varz.In_msgs - prev_vals[url].In_msgs
	out_msgs_delta := varz.Out_msgs - prev_vals[url].Out_msgs

	sec := varz.Now.Second() - prev_vals[url].Now.Second()

	inOutPerSec.In_bytes_sec = in_bytes_delta / sec
	inOutPerSec.Out_bytes_sec = out_bytes_delta / sec
	inOutPerSec.In_msgs_sec = in_msgs_delta / sec
	inOutPerSec.Out_msgs_sec = out_msgs_delta / sec

	// save prev.values
	prev_vals[url].In_bytes = varz.In_bytes
	prev_vals[url].Out_bytes = varz.Out_bytes
	prev_vals[url].In_msgs = varz.In_msgs
	prev_vals[url].Out_msgs = varz.Out_msgs
	prev_vals[url].Now = varz.Now

	// return result
	return inOutPerSec
}
func readConfig(filepath string) Configuration {

	file, _ := os.Open(filepath)
	decoder := json.NewDecoder(file)
	configuration := Configuration{}
	err := decoder.Decode(&configuration)

	if err != nil {
		log.Println("error:", err)
	}

	return configuration
}

type HttpError struct {
	Message string
	Errors  []struct {
		Resource string
		Field    string
		Code     string
	}
}

func setFlag(flag *flag.FlagSet) {
	flag.Usage = func() {
		showHelp()
	}
}
func showHelp() {
	fmt.Println(`
Usage: CLI Template [OPTIONS]
Options:
    -c, --config     Path to config file.
    -l, --log        Path to log file.
    -d, --debug      DEBUG mode.
    -t, --trace      TRACE mode.
    -h, --help       prints this help info.
    `)
}
func setLogOutput(config Configuration, logFilePathCL string) {

	if len(config.LogFilePath) > 0 || len(logFilePathCL) > 0 {

		logFilePath := ""

		if len(config.LogFilePath) > 0 {
			logFilePath = config.LogFilePath
		}
		if len(logFilePathCL) > 0 {
			logFilePath = logFilePathCL
		}

		file, err := os.OpenFile(logFilePath, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)

		if err != nil {
			log.Fatalf("error opening file: %v", err)
		}

		log.SetOutput(file)
	}
}
func printPrettyJson(info NatsNodeTopInfo){
	var prettyJSON bytes.Buffer

	body, err := json.Marshal(info)

	if err != nil {
		log.Println(err)
		return
	}

	error := json.Indent(&prettyJSON, body, "", "\t")
	if error != nil {
		log.Println("JSON parse error: ", error)
		return
	}

	log.Println(string(prettyJSON.Bytes()))
}
<|endoftext|>


<commit_before>package punter

import (
	"fmt"

	"github.com/juju/loggo"
	"github.com/streadway/amqp"
)

var (
	log = loggo.GetLogger("punter")
)

// MsgHander function which is supplied to handle delivers.
type MsgHander func(deliveries <-chan amqp.Delivery, done chan error)

// Consumer holds state for the AMQP consumer
type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
	tag     string
	done    chan error
	count   int
}

// Config is the settings for the consumer
type Config struct {
	AmqpURI      string
	Exchange     string
	ExchangeType string
	QueueName    string
	Key          string
	MessageTTL   int32 // How long to retain messages in the queue
	Durable      bool  // Queue durable?
}

// NewConsumer create and configure a new consumer, this also triggers a connection to AMQP server
func NewConsumer(config *Config, ctag string, msgHandler MsgHander) (*Consumer, error) {

	c := &Consumer{
		conn:    nil,
		channel: nil,
		tag:     ctag,
		done:    make(chan error),
	}

	var err error

	log.Infof("dialing %q", config.AmqpURI)
	c.conn, err = amqp.Dial(config.AmqpURI)
	if err != nil {
		return nil, fmt.Errorf("Dial: %s", err)
	}

	go func() {
		log.Infof("closing: %s", <-c.conn.NotifyClose(make(chan *amqp.Error)))
	}()

	log.Infof("got Connection, getting Channel")
	c.channel, err = c.conn.Channel()
	if err != nil {
		return nil, fmt.Errorf("Channel: %s", err)
	}

	log.Infof("got Channel, declaring Exchange (%q)", config.Exchange)
	if err = c.channel.ExchangeDeclare(
		config.Exchange,     // name of the exchange
		config.ExchangeType, // type
		config.Durable,      // durable
		false,               // delete when complete
		false,               // internal
		false,               // noWait
		nil,                 // arguments
	); err != nil {
		return nil, fmt.Errorf("Exchange Declare: %s", err)
	}
	qargs := amqp.Table{}

	// if the value is set then configure the argument
	if config.MessageTTL > 0 {
		qargs["x-message-ttl"] = config.MessageTTL
	}

	log.Infof("declared Exchange, declaring Queue %q", config.QueueName)
	queue, err := c.channel.QueueDeclare(
		config.QueueName, // name of the queue
		true,             // durable
		false,            // delete when usused
		false,            // exclusive
		false,            // noWait
		qargs,            // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Declare: %s", err)
	}

	log.Infof("declared Queue (%q %d messages, %d consumers), binding to Exchange (key %q)",
		queue.Name, queue.Messages, queue.Consumers, config.Key)

	args := amqp.Table{}
	// TODO make this configurable.
	args["x-expires"] = int32(30000) // 30 second

	if err = c.channel.QueueBind(
		queue.Name,      // name of the queue
		config.Key,      // bindingKey
		config.Exchange, // sourceExchange
		false,           // noWait
		args,            // arguments
	); err != nil {
		return nil, fmt.Errorf("Queue Bind: %s", err)
	}

	log.Infof("Queue bound to Exchange, starting Consume (consumer tag %q)", c.tag)
	deliveries, err := c.channel.Consume(
		queue.Name, // name
		c.tag,      // consumerTag,
		false,      // noAck
		false,      // exclusive
		false,      // noLocal
		false,      // noWait
		nil,        // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Consume: %s", err)
	}

	go msgHandler(deliveries, c.done)

	return c, nil
}

// Shutdown enables cleanup of AMQP connection
func (c *Consumer) Shutdown() error {
	// will close() the deliveries channel
	if err := c.channel.Cancel(c.tag, true); err != nil {
		return fmt.Errorf("Consumer cancel failed: %s", err)
	}

	if err := c.conn.Close(); err != nil {
		return fmt.Errorf("AMQP connection close error: %s", err)
	}

	defer log.Infof("AMQP shutdown OK")

	// wait for handle() to exit
	return <-c.done
}
<commit_msg>Sort out exchange arguments, corrected durable setting in the wrong thing.<commit_after>package punter

import (
	"fmt"

	"github.com/juju/loggo"
	"github.com/streadway/amqp"
)

var (
	log = loggo.GetLogger("punter")
)

// MsgHander function which is supplied to handle delivers.
type MsgHander func(deliveries <-chan amqp.Delivery, done chan error)

// Consumer holds state for the AMQP consumer
type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
	tag     string
	done    chan error
	count   int
}

// Config is the settings for the consumer
type Config struct {
	AmqpURI      string
	Exchange     string
	ExchangeType string
	QueueName    string
	Key          string
	MessageTTL   int32 // How long to retain messages in the queue
	Durable      bool  // Queue durable?
}

// NewConsumer create and configure a new consumer, this also triggers a connection to AMQP server
func NewConsumer(config *Config, ctag string, msgHandler MsgHander) (*Consumer, error) {

	c := &Consumer{
		conn:    nil,
		channel: nil,
		tag:     ctag,
		done:    make(chan error),
	}

	var err error

	log.Infof("dialing %q", config.AmqpURI)
	c.conn, err = amqp.Dial(config.AmqpURI)
	if err != nil {
		return nil, fmt.Errorf("Dial: %s", err)
	}

	go func() {
		log.Infof("closing: %s", <-c.conn.NotifyClose(make(chan *amqp.Error)))
	}()

	log.Infof("got Connection, getting Channel")
	c.channel, err = c.conn.Channel()
	if err != nil {
		return nil, fmt.Errorf("Channel: %s", err)
	}

	log.Infof("got Channel, declaring Exchange (%q)", config.Exchange)
	if err = c.channel.ExchangeDeclare(
		config.Exchange,     // name of the exchange
		config.ExchangeType, // type
		true,                // durable
		false,               // delete when complete
		false,               // internal
		false,               // noWait
		nil,                 // arguments
	); err != nil {
		return nil, fmt.Errorf("Exchange Declare: %s", err)
	}
	qargs := amqp.Table{}

	// if the value is set then configure the argument
	if config.MessageTTL > 0 {
		qargs["x-message-ttl"] = config.MessageTTL
	}

	log.Infof("declared Exchange, declaring Queue %q", config.QueueName)
	queue, err := c.channel.QueueDeclare(
		config.QueueName, // name of the queue
		config.Durable,   // durable
		false,            // delete when usused
		false,            // exclusive
		false,            // noWait
		qargs,            // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Declare: %s", err)
	}

	log.Infof("declared Queue (%q %d messages, %d consumers), binding to Exchange (key %q)",
		queue.Name, queue.Messages, queue.Consumers, config.Key)

	args := amqp.Table{}
	// TODO make this configurable.
	args["x-expires"] = int32(30000) // 30 second

	if err = c.channel.QueueBind(
		queue.Name,      // name of the queue
		config.Key,      // bindingKey
		config.Exchange, // sourceExchange
		false,           // noWait
		args,            // arguments
	); err != nil {
		return nil, fmt.Errorf("Queue Bind: %s", err)
	}

	log.Infof("Queue bound to Exchange, starting Consume (consumer tag %q)", c.tag)
	deliveries, err := c.channel.Consume(
		queue.Name, // name
		c.tag,      // consumerTag,
		false,      // noAck
		false,      // exclusive
		false,      // noLocal
		false,      // noWait
		nil,        // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Consume: %s", err)
	}

	go msgHandler(deliveries, c.done)

	return c, nil
}

// Shutdown enables cleanup of AMQP connection
func (c *Consumer) Shutdown() error {
	// will close() the deliveries channel
	if err := c.channel.Cancel(c.tag, true); err != nil {
		return fmt.Errorf("Consumer cancel failed: %s", err)
	}

	if err := c.conn.Close(); err != nil {
		return fmt.Errorf("AMQP connection close error: %s", err)
	}

	defer log.Infof("AMQP shutdown OK")

	// wait for handle() to exit
	return <-c.done
}
<|endoftext|>


<commit_before>package newrelic

import (
	"encoding/json"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/neocortical/newrelic/model"
)

const (
	// DefaultPollInterval is the recommended poll interval for NewRelic plugins
	DefaultPollInterval = time.Minute
)

const (
	agentVersion = "0.0.1"
	apiEndpoint  = "https://platform-api.newrelic.com/platform/v1/metrics"
)

// Client encapsulates a NewRelic plugin client and all the plugins it reports
type Client struct {
	License      string
	PollInterval time.Duration
	Plugins      []*Plugin

	// HTTPClient is exposed to allow users to configure proxies, etc.
	HTTPClient *http.Client

	agent        model.Agent
	lastPollTime time.Time
	url          string
}

// AddPlugin appends a plugin to a clients list of plugins. A plugin is a "component"
// in the API call and can be configured (with a unique GUID) in the NewRelic UI.
func (c *Client) AddPlugin(p *Plugin) {
	c.Plugins = append(c.Plugins, p)
}

// New creates a new Client with the given license
func New(license string) *Client {
	result := &Client{
		License:      license,
		PollInterval: DefaultPollInterval,
		HTTPClient:   &http.Client{},
		url:          apiEndpoint,
	}

	result.agent.Version = agentVersion
	result.agent.PID = os.Getpid()
	var err error
	if result.agent.Host, err = os.Hostname(); err != nil {
		panic(err)
	}

	return result
}

func (c *Client) doSend(t time.Time) {
	request, err := c.generateRequest(t)
	if err != nil {
		Log(LogError, "ERROR: encountered error(s) creating request data: %v", err)
	}
	c.lastPollTime = t

	responseCode := doPost(request, c.url, c.License, c.HTTPClient)
	switch responseCode {
	case http.StatusOK:
		c.clearState()
	case http.StatusBadRequest:
		logResponseError(responseCode)
	case http.StatusForbidden:
		logResponseError(responseCode)
	case http.StatusNotFound:
		logResponseError(responseCode)
	case http.StatusMethodNotAllowed:
		// won't happen
		logResponseError(responseCode)
	case http.StatusRequestEntityTooLarge:
		// TODO: detect and split large responses
		logResponseError(responseCode)
	case http.StatusInternalServerError:
		logResponseError(responseCode)
	case http.StatusServiceUnavailable, http.StatusGatewayTimeout:
		logResponseError(responseCode)
	case http.StatusTeapot:
		Log(LogError, "Server is a teapot!")
	}
}

func (c *Client) clearState() {
	for _, p := range c.Plugins {
		p.clearState()
	}
}

// Run starts the NewRelic client asynchronously. Do not alter the configuration
// of plugins after starting the client, as this creates race conditions.
func (c *Client) Run() {
	Log(LogInfo, "Starting NewRelic plugin client...")
	go c.run()
}

func (c *Client) run() {
	ticks := time.Tick(time.Duration(c.PollInterval))
	for t := range ticks {
		c.doSend(t)
	}
}

func doPost(request model.Request, url, license string, client *http.Client) int {
	var jsonBytes []byte
	var err error
	if LogLevel <= LogDebug {
		jsonBytes, err = json.MarshalIndent(request, "", "   ")
	} else {
		jsonBytes, err = json.Marshal(request)
	}
	if err != nil {
		Log(LogError, "error encoding json request: %v", err)
		return http.StatusBadRequest
	}

	Log(LogDebug, "Posting request:\n%s", string(jsonBytes))

	httpRequest, err := http.NewRequest("POST", url, strings.NewReader(string(jsonBytes)))
	if err != nil {
		Log(LogError, "error creating request: %v", err)
		return http.StatusBadRequest
	}

	httpRequest.Header.Set("X-License-Key", license)
	httpRequest.Header.Set("Content-Type", "application/json")
	httpRequest.Header.Set("Accept", "application/json")

	httpResponse, err := client.Do(httpRequest)
	if err != nil {
		Log(LogError, "error posting request: %v", err)
		return http.StatusServiceUnavailable
	}
	defer httpResponse.Body.Close()
	return httpResponse.StatusCode
}

func logResponseError(responseCode int) {
	Log(LogError, "ERROR: newrelic encountered %d response", responseCode)
}

func (c *Client) generateRequest(t time.Time) (request model.Request, err CompositeError) {
	request.Agent = c.agent

	var duration time.Duration
	if c.lastPollTime.IsZero() {
		duration = c.PollInterval
	} else {
		duration = t.Sub(c.lastPollTime)
	}

	for _, p := range c.Plugins {
		pluginSnapshot, cerr := p.generatePluginSnapshot(duration)

		// we are tolerant of request generation errors and should be able to recover
		if cerr != nil {
			err = err.Accumulate(cerr)
		}
		request.Plugins = append(request.Plugins, pluginSnapshot)
	}

	return request, err
}
<commit_msg>fast timeout for calls to NewRelic API<commit_after>package newrelic

import (
	"encoding/json"
	"net"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/neocortical/newrelic/model"
)

const (
	// DefaultPollInterval is the recommended poll interval for NewRelic plugins
	DefaultPollInterval = time.Minute
)

const (
	agentVersion = "0.0.1"
	apiEndpoint  = "https://platform-api.newrelic.com/platform/v1/metrics"
)

var netTransport = &http.Transport{
	Dial: (&net.Dialer{
		Timeout:   5 * time.Second,
		KeepAlive: 5 * time.Second,
	}).Dial,
	TLSHandshakeTimeout: 5 * time.Second,
}

var netClient = &http.Client{
	Timeout:   time.Second * 5,
	Transport: netTransport,
}

// Client encapsulates a NewRelic plugin client and all the plugins it reports
type Client struct {
	License      string
	PollInterval time.Duration
	Plugins      []*Plugin

	// HTTPClient is exposed to allow users to configure proxies, etc.
	HTTPClient *http.Client

	agent        model.Agent
	lastPollTime time.Time
	url          string
}

// AddPlugin appends a plugin to a clients list of plugins. A plugin is a "component"
// in the API call and can be configured (with a unique GUID) in the NewRelic UI.
func (c *Client) AddPlugin(p *Plugin) {
	c.Plugins = append(c.Plugins, p)
}

// New creates a new Client with the given license
func New(license string) *Client {
	result := &Client{
		License:      license,
		PollInterval: DefaultPollInterval,
		HTTPClient:   netClient,
		url:          apiEndpoint,
	}

	result.agent.Version = agentVersion
	result.agent.PID = os.Getpid()
	var err error
	if result.agent.Host, err = os.Hostname(); err != nil {
		panic(err)
	}

	return result
}

func (c *Client) doSend(t time.Time) {
	request, err := c.generateRequest(t)
	if err != nil {
		Log(LogError, "ERROR: encountered error(s) creating request data: %v", err)
	}
	c.lastPollTime = t

	responseCode := doPost(request, c.url, c.License, c.HTTPClient)
	switch responseCode {
	case http.StatusOK:
		c.clearState()
	case http.StatusBadRequest:
		logResponseError(responseCode)
	case http.StatusForbidden:
		logResponseError(responseCode)
	case http.StatusNotFound:
		logResponseError(responseCode)
	case http.StatusMethodNotAllowed:
		// won't happen
		logResponseError(responseCode)
	case http.StatusRequestEntityTooLarge:
		// TODO: detect and split large responses
		logResponseError(responseCode)
	case http.StatusInternalServerError:
		logResponseError(responseCode)
	case http.StatusServiceUnavailable, http.StatusGatewayTimeout:
		logResponseError(responseCode)
	case http.StatusTeapot:
		Log(LogError, "Server is a teapot!")
	}
}

func (c *Client) clearState() {
	for _, p := range c.Plugins {
		p.clearState()
	}
}

// Run starts the NewRelic client asynchronously. Do not alter the configuration
// of plugins after starting the client, as this creates race conditions.
func (c *Client) Run() {
	Log(LogInfo, "Starting NewRelic plugin client...")
	go c.run()
}

func (c *Client) run() {
	ticks := time.Tick(time.Duration(c.PollInterval))
	for t := range ticks {
		c.doSend(t)
	}
}

func doPost(request model.Request, url, license string, client *http.Client) int {
	var jsonBytes []byte
	var err error
	if LogLevel <= LogDebug {
		jsonBytes, err = json.MarshalIndent(request, "", "   ")
	} else {
		jsonBytes, err = json.Marshal(request)
	}
	if err != nil {
		Log(LogError, "error encoding json request: %v", err)
		return http.StatusBadRequest
	}

	Log(LogDebug, "Posting request:\n%s", string(jsonBytes))

	httpRequest, err := http.NewRequest("POST", url, strings.NewReader(string(jsonBytes)))
	if err != nil {
		Log(LogError, "error creating request: %v", err)
		return http.StatusBadRequest
	}

	httpRequest.Header.Set("X-License-Key", license)
	httpRequest.Header.Set("Content-Type", "application/json")
	httpRequest.Header.Set("Accept", "application/json")

	httpResponse, err := client.Do(httpRequest)
	if err != nil {
		Log(LogError, "error posting request: %v", err)
		return http.StatusServiceUnavailable
	}
	defer httpResponse.Body.Close()
	return httpResponse.StatusCode
}

func logResponseError(responseCode int) {
	Log(LogError, "ERROR: newrelic encountered %d response", responseCode)
}

func (c *Client) generateRequest(t time.Time) (request model.Request, err CompositeError) {
	request.Agent = c.agent

	var duration time.Duration
	if c.lastPollTime.IsZero() {
		duration = c.PollInterval
	} else {
		duration = t.Sub(c.lastPollTime)
	}

	for _, p := range c.Plugins {
		pluginSnapshot, cerr := p.generatePluginSnapshot(duration)

		// we are tolerant of request generation errors and should be able to recover
		if cerr != nil {
			err = err.Accumulate(cerr)
		}
		request.Plugins = append(request.Plugins, pluginSnapshot)
	}

	return request, err
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"

	"github.com/mitchellh/packer/builder/digitalocean"
	"github.com/mitchellh/packer/packer"
)

type DigitalOcean struct {
	ClientID string
	ApiKey   string
}

func (d *DigitalOcean) Build(path string) error {
	log.Printf("Digitalocean: Reading template: %s", path)
	template, err := packer.ParseTemplateFile(path, nil)
	if err != nil {
		return fmt.Errorf("Failed to parse template: %s", err)
	}

	fmt.Printf("template %#v\n", template)

	if len(template.BuildNames()) != 1 {
		return fmt.Errorf("Failed to find build in the template: %v", template.BuildNames())
	}

	buildName := template.BuildNames()[0]
	if buildName != "digitalocean" {
		return fmt.Errorf("Build name is different than 'digitalocean': %v", buildName)
	}

	builder := digitalocean.Builder{}
	fmt.Printf("builder %+v\n", builder)

	s, err := builder.Prepare(template.Builders["digitalocean"].RawConfig)
	if err != nil {
		return err
	}

	fmt.Printf("s %+v\n", s)

	// log.Println("Digitalocean: Preparing environment")
	// envConfig := packer.DefaultEnvironmentConfig()
	// env, err := packer.NewEnvironment(envConfig)
	// if err != nil {
	// 	return err
	// }
	//
	// components := &packer.ComponentFinder{
	// 	Builder:       env.Builder,
	// 	Hook:          env.Hook,
	// 	PostProcessor: env.PostProcessor,
	// 	Provisioner:   env.Provisioner,
	// }

	// log.Println("Digitalocean: Creating build interface")
	// build, err := template.Build(buildName, components)
	// if err != nil {
	// 	return err
	// }

	return nil
}

func (d *DigitalOcean) Provision() error {
	return nil
}

func (d *DigitalOcean) Start() error   { return nil }
func (d *DigitalOcean) Stop() error    { return nil }
func (d *DigitalOcean) Restart() error { return nil }
func (d *DigitalOcean) Destroy() error { return nil }
<commit_msg>kloud: still reverse enginnering packer<commit_after>package main

import (
	"errors"
	"fmt"
	"log"

	"github.com/mitchellh/packer/builder/digitalocean"
	"github.com/mitchellh/packer/packer"
	"github.com/mitchellh/packer/provisioner/file"
	"github.com/mitchellh/packer/provisioner/shell"
)

type DigitalOcean struct {
	ClientID string
	ApiKey   string
}

func (d *DigitalOcean) Build(path string) error {
	log.Printf("Digitalocean: Reading template: %s", path)

	userVars := map[string]string{
		"klient_deb":     "klient_0.0.1_amd64.deb",
		"klient_keyname": "kite.key",
		"klient_keydir":  "/opt/kite/klient/key",
	}

	template, err := packer.ParseTemplateFile(path, userVars)
	if err != nil {
		return fmt.Errorf("Failed to parse template: %s", err)
	}

	if len(template.Builders) != 1 {
		return fmt.Errorf("Failed to find build in the template: %v", template.BuildNames())
	}

	if _, ok := template.Builders["digitalocean"]; !ok {
		return errors.New("Build 'digitalocean' does not exist")
	}

	components := &packer.ComponentFinder{
		Builder:     builderFunc,
		Provisioner: provisionerFunc,
	}

	build, err := template.Build("digitalocean", components)
	if err != nil {
		return err
	}

	_, err = build.Prepare()
	if err != nil {
		return err
	}

	return nil
}

func builderFunc(name string) (packer.Builder, error) {
	switch name {
	case "digitalocean":
		return &digitalocean.Builder{}, nil
	}

	return nil, errors.New("no suitable build found")
}

func provisionerFunc(name string) (packer.Provisioner, error) {
	switch name {
	case "file":
		return &file.Provisioner{}, nil
	case "shell":
		return &shell.Provisioner{}, nil
	}

	return nil, errors.New("no suitable provisioner found")
}

func (d *DigitalOcean) Provision() error {
	return nil
}

func (d *DigitalOcean) Start() error   { return nil }
func (d *DigitalOcean) Stop() error    { return nil }
func (d *DigitalOcean) Restart() error { return nil }
func (d *DigitalOcean) Destroy() error { return nil }

func deleteLater() {
	// _, err = build.Run()
	// if err != nil {
	// 	return err
	// }

	// log.Println("Digitalocean: Creating build interface")
	// build, err := template.Build(buildName, components)
	// if err != nil {
	// 	return err
	// }

	// for _, b := range template.Builders {
	// 	fmt.Printf("b.Type %+v\n", b.Type)
	// }
	//
	// variables := make(map[string]string)
	// for k, v := range template.Variables {
	// 	fmt.Printf("v %+v\n", v)
	// 	variables[k] = v.Value
	// }
	//
	// if len(template.BuildNames()) != 1 {
	// 	return fmt.Errorf("Failed to find build in the template: %v", template.BuildNames())
	// }
	//
	// buildName := template.BuildNames()[0]
	// if buildName != "digitalocean" {
	// 	return fmt.Errorf("Build name is different than 'digitalocean': %v", buildName)
	// }
	//
	// builder := digitalocean.Builder{}
	//
	// packerConfig := map[string]interface{}{
	// 	packer.BuildNameConfigKey:     b.name,
	// 	packer.BuilderTypeConfigKey:   template.Builders["digitalocan"].Type
	// 	packer.UserVariablesConfigKey: variables,
	// }
	//
	// // Prepare the builder
	// _, err = builder.Prepare(template.Builders["digitalocean"].RawConfig, packerConfig)
	// if err != nil {
	// 	return err
	// }
	//
	// for _, p := range template.Provisioners {
	// 	fmt.Printf("p.Type %+v\n", p.Type)
	//
	// 	switch p.Type {
	// 	case "file":
	// 		f := file.Provisioner{}
	// 		if err := f.Prepare(p.RawConfig); err != nil {
	// 			return err
	// 		}
	// 	case "shell":
	// 		s := shell.Provisioner{}
	// 		if err := s.Prepare(p.RawConfig); err != nil {
	// 			return err
	// 		}
	// 	}
	//
	// }
}
<|endoftext|>


<commit_before>package models

import "time"

type ChannelMessage struct {
	// unique identifier of the channel message
	Id int64

	// Body of the mesage
	Body string

	// type of the message
	Type string

	// Creator of the channel message
	AccountId int64

	// Creation date of the message
	CreatedAt time.Time

	// Modification date of the message
	UpdatedAt time.Time
	m         Model
}

func (c *ChannelMessage) GetId() int64 {
	return c.Id
}

func (c *ChannelMessage) TableName() string {
	return "channel_message"
}

func (c *ChannelMessage) Self() Modellable {
	return c
}

const (
	ChannelMessage_TYPE_POST  = "post"
	ChannelMessage_TYPE_JOIN  = "join"
	ChannelMessage_TYPE_LEAVE = "leave"
	ChannelMessage_TYPE_CHAT  = "chat"
)

func NewChannelMessage() *ChannelMessage {
	return &ChannelMessage{}
}

func (c *ChannelMessage) Fetch() error {
	return c.m.Fetch(c)
}

func (c *ChannelMessage) Update() error {
	// only update body
	return c.m.UpdatePartial(c,
		map[string]interface{}{
			"body": c.Body,
		},
	)
}

func (c *ChannelMessage) Create() error {
	return c.m.Create(c)
}

func (c *ChannelMessage) Delete() error {
	return c.m.Delete(c)
}

func (c *ChannelMessage) FetchByIds(ids []int64) ([]ChannelMessage, error) {
	var messages []ChannelMessage

	if len(ids) == 0 {
		return messages, nil
	}

	if err := c.m.FetchByIds(c, &messages, ids); err != nil {
		return nil, err
	}
	return messages, nil
}
<commit_msg>Social: implement FetchRelatives function<commit_after>package models

import (
	"errors"
	"time"
)

type ChannelMessage struct {
	// unique identifier of the channel message
	Id int64

	// Body of the mesage
	Body string

	// type of the message
	Type string

	// Creator of the channel message
	AccountId int64

	// Creation date of the message
	CreatedAt time.Time

	// Modification date of the message
	UpdatedAt time.Time
	m         Model
}

func (c *ChannelMessage) GetId() int64 {
	return c.Id
}

func (c *ChannelMessage) TableName() string {
	return "channel_message"
}

func (c *ChannelMessage) Self() Modellable {
	return c
}

const (
	ChannelMessage_TYPE_POST  = "post"
	ChannelMessage_TYPE_JOIN  = "join"
	ChannelMessage_TYPE_LEAVE = "leave"
	ChannelMessage_TYPE_CHAT  = "chat"
)

func NewChannelMessage() *ChannelMessage {
	return &ChannelMessage{}
}

func (c *ChannelMessage) Fetch() error {
	return c.m.Fetch(c)
}

func (c *ChannelMessage) Update() error {
	// only update body
	return c.m.UpdatePartial(c,
		map[string]interface{}{
			"body": c.Body,
		},
	)
}

func (c *ChannelMessage) Create() error {
	return c.m.Create(c)
}

func (c *ChannelMessage) Delete() error {
	return c.m.Delete(c)
}

func (c *ChannelMessage) FetchByIds(ids []int64) ([]ChannelMessage, error) {
	var messages []ChannelMessage

	if len(ids) == 0 {
		return messages, nil
	}

	if err := c.m.FetchByIds(c, &messages, ids); err != nil {
		return nil, err
	}
	return messages, nil
}

func (c *ChannelMessage) FetchRelatives() (*ChannelMessageContainer, error) {
	if c.Id == 0 {
		return nil, errors.New("Channel message id is not set")
	}
	container := NewChannelMessageContainer()
	container.Message = c

	i := NewInteraction()
	i.MessageId = c.Id

	interactions, err := i.List("like")
	if err != nil {
		return nil, err
	}

	interactionContainer := NewInteractionContainer()
	interactionContainer.Actors = interactions
	// check this from database
	interactionContainer.IsInteracted = true

	if container.Interactions == nil {
		container.Interactions = make(map[string]*InteractionContainer)
	}
	if _, ok := container.Interactions["like"]; !ok {
		container.Interactions["like"] = NewInteractionContainer()
	}
	container.Interactions["like"] = interactionContainer
	return container, nil
}
<|endoftext|>