<commit_before>package main

import "encoding/json"
import "flag"
import "fmt"
import "os"
import "path/filepath"
import "sort"
import "strconv"
import "strings"
import "text/tabwriter"

import "github.com/appc/spec/schema"
import "github.com/appc/spec/schema/types"
import "github.com/juju/errors"

import "./jetpack"
import "./run"

var Host *jetpack.Host

func die(err error) {
	if err != nil {
		fmt.Fprintln(os.Stderr, errors.ErrorStack(err))
		os.Exit(1)
	}
}

func show(obj ...interface{}) {
	die(Show("", obj...))
}

func subcommand(def string, args []string) (string, []string) {
	if len(args) == 0 {
		return def, args
	}
	return args[0], args[1:]
}

func image(name string) *jetpack.Image {
	img, err := Host.FindImage(name)
	if err == jetpack.ErrNotFound {
		die(errors.Errorf("No such image: %#v", name))
	}
	die(err)
	return img
}

func getRuntimeApp(name string) (*schema.RuntimeApp, error) {
	if img, err := Host.FindImage(name); err != nil {
		return nil, err
	} else {
		rta := img.RuntimeApp()
		return &rta, nil
	}
}

func main() {
	configPath := jetpack.DefaultConfigPath
	help := false

	if cfg := os.Getenv("JETPACK_CONF"); cfg != "" {
		configPath = cfg
	}

	flag.StringVar(&configPath, "config", configPath, "Configuration file")
	flag.BoolVar(&help, "h", false, "Show help")
	flag.BoolVar(&help, "help", false, "Show help")

	flag.Parse()
	args := flag.Args()

	if help || len(args) == 0 || args[0] == "help" {
		fmt.Fprintf(os.Stderr, `Usage: %s [OPTIONS] COMMAND...
Options:
  -config=PATH  Configuration file (%s)
  -help, -h     Display this help screen
Commands:
  help                                    Display this help screen
  init                                    Initialize host
  info                                    Show global information
  test                                    Run integration tests
  image list [QUERY]                      List images
  image import ARCHIVE [MANIFEST]         Import image from an archive
  image IMAGE build [OPTIONS] COMMAND...  Build new image from an existing one
                    -dir=.                Location on build directory on host
                    -cp=PATH...           Copy additional files from host
  image IMAGE show                        Display image details
  image IMAGE export [PATH]               Export image to an AMI file
                                          Output to stdout if no PATH given
  image IMAGE destroy                     Destroy image
  pod list                                List pods
  pod create [FLAGS] IMAGE [IMAGE FLAGS] [IMAGE [IMAGE FLAGS] ...]
                                          Create new pod from image
             -help                        Show detailed help
  pod POD show                            Display pod details
  pod POD run [APP]                       Run pod's application
  pod POD console [APP]                   Open console inside the pod
  pod POD ps|top|killall [OPTIONS...]
                                          Manage pod's processes
  pod POD kill                            Kill running pod
  pod POD destroy                         Destroy pod
Needs Explanation:
  ARCHIVE, MANIFEST  May be filesystem paths or URLs.
            cp=PATH  This option can be given multiple times
              QUERY  Is an expression that looks like this:
                      - NAME[,LABEL=VALUE[,LABEL=VALUE[,...]]]
                      - NAME:VERSION (alias for NAME:version=VERSION)
              IMAGE  Can be:
                      - an UUID (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX),
                      - a checksum (sha512-...), or
                      - a QUERY (which can't be ambiguous).
          POD  Has to be an UUID for now
Helpful Aliases:
  i|img ... -- image ...
  p ... -- pod ...
  image, images -- image list
  pod, pods -- pod list
  image build|show|export|destroy IMAGE ... -- image IMAGE build|show|... ...
`,
			filepath.Base(os.Args[0]), configPath)
		return
	}

	command := args[0]
	args = args[1:]

	if host, err := jetpack.NewHost(configPath); err != nil {
		die(err)
	} else {
		Host = host
	}

	if command == "init" {
		// Init is special: it doesn't need an initialized host
		die(Host.Initialize())
		show(Host)
		return
	}

	if Host.Dataset == nil {
		die(errors.New("Host is not initialized"))
	}

	switch command {
	case "info":
		show(Host)
	case "test":
		die(run.Command(filepath.Join(jetpack.LibexecPath, "test.integration"),
			append(args, "dataset="+Host.Dataset.Name)...).Run())
	case "images":
		command = "image"
		args = append([]string{"list"}, args...)
		fallthrough
	case "image", "img", "i":
		switch command, args := subcommand("list", args); command {
		case "import":
			var archive, manifest string
			switch len(args) {
			case 2:
				manifest = args[1]
				fallthrough
			case 1:
				archive = args[0]
			default:
				die(errors.New("Usage: import ARCHIVE_URI [MANIFEST_URI]"))
			}
			image, err := Host.ImportImage(archive, manifest)
			die(err)
			show(image)
		case "list":
			var machineFriendly, showHash, idOnly bool
			fl := flag.NewFlagSet("image list", flag.ExitOnError)
			fl.BoolVar(&machineFriendly, "H", false, "Machine-friendly output")
			fl.BoolVar(&showHash, "hash", false, "Show image hash instead of UUID")
			fl.BoolVar(&idOnly, "q", false, "Show only ID")
			fl.Parse(args)

			images := Host.Images()

			if idOnly {
				for _, img := range images {
					if showHash {
						fmt.Println(img.Hash)
					} else {
						fmt.Println(img.UUID)
					}
				}
			} else if len(images) == 0 {
				if !machineFriendly {
					show("No images")
				}
			} else {
				lines := make([]string, len(images))
				for i, img := range images {
					labels := make([]string, len(img.Manifest.Labels))
					for j, label := range img.Manifest.Labels {
						labels[j] = fmt.Sprintf("%v=%#v", label.Name, label.Value)
					}
					sort.Strings(labels)
					first := img.UUID.String()
					if showHash {
						first = img.Hash.String()
					}
					lines[i] = fmt.Sprintf("%v\t%v\t%v",
						first,
						img.Manifest.Name,
						strings.Join(labels, ","))
				}
				sort.Strings(lines)
				output := strings.Join(lines, "\n")

				if machineFriendly {
					fmt.Println(output)
				} else {
					first := "UUID"
					if showHash {
						first = "HASH"
					}
					w := tabwriter.NewWriter(os.Stdout, 2, 8, 2, ' ', 0)
					fmt.Fprintf(w, "%v\tNAME\tLABELS\n%v\n", first, output)
					die(w.Flush())
				}
			}
		case "build", "show", "export", "destroy":
			// be nice to people who prefer to type UUID after command
			command, args[0] = args[0], command
			fallthrough
		default:
			img := image(command)

			switch command, args := subcommand("show", args); command {
			case "build":
				var copyFiles sliceFlag
				var buildDir string

				fs := flag.NewFlagSet("build", flag.ExitOnError)
				fs.Var(&copyFiles, "cp", "")
				fs.StringVar(&buildDir, "dir", ".", "")
				die(fs.Parse(args))

				newImage, err := img.Build(buildDir, copyFiles, fs.Args())
				die(err)
				show(newImage)
			case "show":
				show(img)
			case "export":
				path := "-"
				if len(args) > 0 {
					path = args[0]
				}
				if hash, err := img.SaveAMI(path, 0644); err != nil {
					die(err)
				} else {
					fmt.Fprintln(os.Stderr, hash)
				}
			case "destroy":
				die(img.Destroy())
			default:
				die(errors.Errorf("Unknown command %#v", command))
			}
		}
	case "pods":
		command = "pod"
		args = append([]string{"list"}, args...)
		fallthrough
	case "pod", "p":
		switch command, args := subcommand("list", args); command {
		case "create":
			var dryRun, doRun, doDestroy bool
			fl := flag.NewFlagSet("jetpack pod create", flag.ContinueOnError)
			fl.BoolVar(&dryRun, "n", false, "Dry run (don't actually create pod, just show manifest)")
			fl.BoolVar(&doRun, "run", false, "Run pod immediately")
			fl.BoolVar(&doDestroy, "destroy", false, "Destroy pod after running (meaningless without -run)")

			if pm, err := ConstructPod(args, fl, getRuntimeApp); err == flag.ErrHelp {
				// It's all right. Help has been shown.
			} else if err != nil {
				panic(err)
			} else if dryRun {
				if jb, err := json.MarshalIndent(pm, "", "  "); err != nil {
					panic(err)
				} else {
					fmt.Println(string(jb))
				}
			} else {
				pod, err := Host.CreatePod(pm)
				die(err)
				if doRun {
					if len(pod.Manifest.Apps) > 1 {
						die(errors.New("Pod has multiple apps, cannot run"))
					}
					err := pod.RunApp(pod.Manifest.Apps[0].Name)
					if doDestroy {
						err1 := pod.Destroy()
						if err == nil {
							err = err1
						}
					}
					die(err)
				} else {
					show(pod)
				}
			}
		case "list":
			var machineFriendly, idOnly bool
			fl := flag.NewFlagSet("pod list", flag.ExitOnError)
			fl.BoolVar(&machineFriendly, "H", false, "Machine-friendly output")
			fl.BoolVar(&idOnly, "q", false, "Show only ID")
			fl.Parse(args)

			pods := Host.Pods()

			if idOnly {
				for _, pod := range pods {
					fmt.Println(pod.UUID)
				}
			} else if len(pods) == 0 {
				if !machineFriendly {
					show("No pods")
				}
			} else {
				lines := make([]string, len(pods))
				for i, pod := range pods {
					apps := make([]string, len(pod.Manifest.Apps))
					for j, app := range pod.Manifest.Apps {
						apps[j] = app.Name.String()
					}
					ipAddress, _ := pod.Manifest.Annotations.Get("ip-address")
					lines[i] = fmt.Sprintf("%v\t%v\t%v\t%v",
						pod.UUID,
						pod.Status().String(),
						ipAddress,
						strings.Join(apps, " "))
				}
				sort.Strings(lines)
				output := strings.Join(lines, "\n")

				if machineFriendly {
					fmt.Println(output)
				} else {
					w := tabwriter.NewWriter(os.Stdout, 2, 8, 2, ' ', 0)
					fmt.Fprintf(w, "UUID\tSTATUS\tIP\tAPPS\n%v\n", output)
					die(w.Flush())
				}
			}
		case "show", "run", "ps", "top", "killall", "kill", "destroy":
			// be nice to people who prefer to type UUID after command
			command, args[0] = args[0], command
			fallthrough
		default:
			pod, err := Host.FindPod(command)
			if err == jetpack.ErrNotFound {
				die(errors.Errorf("No such pod: %#v", command))
			}
			die(err)
			switch command, args := subcommand("show", args); command {
			case "show":
				show(pod)
			case "run":
				switch len(args) {
				case 0:
					if len(pod.Manifest.Apps) > 1 {
						die(errors.New("Pod has multiple apps, you need to specify one"))
					}
					die(pod.RunApp(pod.Manifest.Apps[0].Name))
				case 1:
					die(pod.RunApp(types.ACName(args[0])))
				default:
					die(errors.New("Command `run' takes at most one argument"))
				}
			case "console":
				switch len(args) {
				case 0:
					if len(pod.Manifest.Apps) > 1 {
						die(errors.New("Pod has multiple apps, you need to specify one"))
					}
					die(pod.Console(pod.Manifest.Apps[0].Name, "root"))
				case 1:
					die(pod.Console(types.ACName(args[0]), "root"))
				default:
					die(errors.New("Command `console' takes at most one argument"))
				}
			case "ps", "top", "killall":
				jid := pod.Jid()
				if jid == 0 {
					die(errors.New("Pod is not running"))
				}

				flag := "-J"
				if command == "killall" {
					flag = "-j"
				}

				die(run.Command(command, append([]string{flag, strconv.Itoa(jid)}, args...)...).Run())
			case "kill":
				die(pod.Kill())
			case "destroy":
				die(pod.Destroy())
			default:
				die(errors.Errorf("Unknown command %#v", command))
			}
		}
	default:
		die(errors.Errorf("Unknown command %#v", command))
	}
}
<commit_msg>jetpack pod create -saveid<commit_after>package main

import "encoding/json"
import "flag"
import "fmt"
import "io/ioutil"
import "os"
import "path/filepath"
import "sort"
import "strconv"
import "strings"
import "text/tabwriter"

import "github.com/appc/spec/schema"
import "github.com/appc/spec/schema/types"
import "github.com/juju/errors"

import "./jetpack"
import "./run"

var Host *jetpack.Host

func die(err error) {
	if err != nil {
		fmt.Fprintln(os.Stderr, errors.ErrorStack(err))
		os.Exit(1)
	}
}

func show(obj ...interface{}) {
	die(Show("", obj...))
}

func subcommand(def string, args []string) (string, []string) {
	if len(args) == 0 {
		return def, args
	}
	return args[0], args[1:]
}

func image(name string) *jetpack.Image {
	img, err := Host.FindImage(name)
	if err == jetpack.ErrNotFound {
		die(errors.Errorf("No such image: %#v", name))
	}
	die(err)
	return img
}

func getRuntimeApp(name string) (*schema.RuntimeApp, error) {
	if img, err := Host.FindImage(name); err != nil {
		return nil, err
	} else {
		rta := img.RuntimeApp()
		return &rta, nil
	}
}

func main() {
	configPath := jetpack.DefaultConfigPath
	help := false

	if cfg := os.Getenv("JETPACK_CONF"); cfg != "" {
		configPath = cfg
	}

	flag.StringVar(&configPath, "config", configPath, "Configuration file")
	flag.BoolVar(&help, "h", false, "Show help")
	flag.BoolVar(&help, "help", false, "Show help")

	flag.Parse()
	args := flag.Args()

	if help || len(args) == 0 || args[0] == "help" {
		fmt.Fprintf(os.Stderr, `Usage: %s [OPTIONS] COMMAND...
Options:
  -config=PATH  Configuration file (%s)
  -help, -h     Display this help screen
Commands:
  help                                    Display this help screen
  init                                    Initialize host
  info                                    Show global information
  test                                    Run integration tests
  image list [QUERY]                      List images
  image import ARCHIVE [MANIFEST]         Import image from an archive
  image IMAGE build [OPTIONS] COMMAND...  Build new image from an existing one
                    -dir=.                Location on build directory on host
                    -cp=PATH...           Copy additional files from host
  image IMAGE show                        Display image details
  image IMAGE export [PATH]               Export image to an AMI file
                                          Output to stdout if no PATH given
  image IMAGE destroy                     Destroy image
  pod list                                List pods
  pod create [FLAGS] IMAGE [IMAGE FLAGS] [IMAGE [IMAGE FLAGS] ...]
                                          Create new pod from image
             -help                        Show detailed help
  pod POD show                            Display pod details
  pod POD run [APP]                       Run pod's application
  pod POD console [APP]                   Open console inside the pod
  pod POD ps|top|killall [OPTIONS...]
                                          Manage pod's processes
  pod POD kill                            Kill running pod
  pod POD destroy                         Destroy pod
Needs Explanation:
  ARCHIVE, MANIFEST  May be filesystem paths or URLs.
            cp=PATH  This option can be given multiple times
              QUERY  Is an expression that looks like this:
                      - NAME[,LABEL=VALUE[,LABEL=VALUE[,...]]]
                      - NAME:VERSION (alias for NAME:version=VERSION)
              IMAGE  Can be:
                      - an UUID (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX),
                      - a checksum (sha512-...), or
                      - a QUERY (which can't be ambiguous).
          POD  Has to be an UUID for now
Helpful Aliases:
  i|img ... -- image ...
  p ... -- pod ...
  image, images -- image list
  pod, pods -- pod list
  image build|show|export|destroy IMAGE ... -- image IMAGE build|show|... ...
`,
			filepath.Base(os.Args[0]), configPath)
		return
	}

	command := args[0]
	args = args[1:]

	if host, err := jetpack.NewHost(configPath); err != nil {
		die(err)
	} else {
		Host = host
	}

	if command == "init" {
		// Init is special: it doesn't need an initialized host
		die(Host.Initialize())
		show(Host)
		return
	}

	if Host.Dataset == nil {
		die(errors.New("Host is not initialized"))
	}

	switch command {
	case "info":
		show(Host)
	case "test":
		die(run.Command(filepath.Join(jetpack.LibexecPath, "test.integration"),
			append(args, "dataset="+Host.Dataset.Name)...).Run())
	case "images":
		command = "image"
		args = append([]string{"list"}, args...)
		fallthrough
	case "image", "img", "i":
		switch command, args := subcommand("list", args); command {
		case "import":
			var archive, manifest string
			switch len(args) {
			case 2:
				manifest = args[1]
				fallthrough
			case 1:
				archive = args[0]
			default:
				die(errors.New("Usage: import ARCHIVE_URI [MANIFEST_URI]"))
			}
			image, err := Host.ImportImage(archive, manifest)
			die(err)
			show(image)
		case "list":
			var machineFriendly, showHash, idOnly bool
			fl := flag.NewFlagSet("image list", flag.ExitOnError)
			fl.BoolVar(&machineFriendly, "H", false, "Machine-friendly output")
			fl.BoolVar(&showHash, "hash", false, "Show image hash instead of UUID")
			fl.BoolVar(&idOnly, "q", false, "Show only ID")
			fl.Parse(args)

			images := Host.Images()

			if idOnly {
				for _, img := range images {
					if showHash {
						fmt.Println(img.Hash)
					} else {
						fmt.Println(img.UUID)
					}
				}
			} else if len(images) == 0 {
				if !machineFriendly {
					show("No images")
				}
			} else {
				lines := make([]string, len(images))
				for i, img := range images {
					labels := make([]string, len(img.Manifest.Labels))
					for j, label := range img.Manifest.Labels {
						labels[j] = fmt.Sprintf("%v=%#v", label.Name, label.Value)
					}
					sort.Strings(labels)
					first := img.UUID.String()
					if showHash {
						first = img.Hash.String()
					}
					lines[i] = fmt.Sprintf("%v\t%v\t%v",
						first,
						img.Manifest.Name,
						strings.Join(labels, ","))
				}
				sort.Strings(lines)
				output := strings.Join(lines, "\n")

				if machineFriendly {
					fmt.Println(output)
				} else {
					first := "UUID"
					if showHash {
						first = "HASH"
					}
					w := tabwriter.NewWriter(os.Stdout, 2, 8, 2, ' ', 0)
					fmt.Fprintf(w, "%v\tNAME\tLABELS\n%v\n", first, output)
					die(w.Flush())
				}
			}
		case "build", "show", "export", "destroy":
			// be nice to people who prefer to type UUID after command
			command, args[0] = args[0], command
			fallthrough
		default:
			img := image(command)

			switch command, args := subcommand("show", args); command {
			case "build":
				var copyFiles sliceFlag
				var buildDir string

				fs := flag.NewFlagSet("build", flag.ExitOnError)
				fs.Var(&copyFiles, "cp", "")
				fs.StringVar(&buildDir, "dir", ".", "")
				die(fs.Parse(args))

				newImage, err := img.Build(buildDir, copyFiles, fs.Args())
				die(err)
				show(newImage)
			case "show":
				show(img)
			case "export":
				path := "-"
				if len(args) > 0 {
					path = args[0]
				}
				if hash, err := img.SaveAMI(path, 0644); err != nil {
					die(err)
				} else {
					fmt.Fprintln(os.Stderr, hash)
				}
			case "destroy":
				die(img.Destroy())
			default:
				die(errors.Errorf("Unknown command %#v", command))
			}
		}
	case "pods":
		command = "pod"
		args = append([]string{"list"}, args...)
		fallthrough
	case "pod", "p":
		switch command, args := subcommand("list", args); command {
		case "create":
			var dryRun, doRun, doDestroy bool
			var saveId string
			fl := flag.NewFlagSet("jetpack pod create", flag.ContinueOnError)
			fl.BoolVar(&dryRun, "n", false, "Dry run (don't actually create pod, just show manifest)")
			fl.BoolVar(&doRun, "run", false, "Run pod immediately")
			fl.BoolVar(&doDestroy, "destroy", false, "Destroy pod after running (meaningless without -run)")
			fl.StringVar(&saveId, "saveid", "", "Save pod UUID to file")

			if pm, err := ConstructPod(args, fl, getRuntimeApp); err == flag.ErrHelp {
				// It's all right. Help has been shown.
			} else if err != nil {
				panic(err)
			} else if dryRun {
				if jb, err := json.MarshalIndent(pm, "", "  "); err != nil {
					panic(err)
				} else {
					fmt.Println(string(jb))
				}
			} else {
				pod, err := Host.CreatePod(pm)
				die(err)
				if saveId != "" {
					die(ioutil.WriteFile(saveId, []byte(pod.UUID.String()), 0644))
				}
				if doRun {
					if len(pod.Manifest.Apps) > 1 {
						die(errors.New("Pod has multiple apps, cannot run"))
					}
					err := pod.RunApp(pod.Manifest.Apps[0].Name)
					if doDestroy {
						err1 := pod.Destroy()
						if err == nil {
							err = err1
						}
					}
					die(err)
				} else {
					show(pod)
				}
			}
		case "list":
			var machineFriendly, idOnly bool
			fl := flag.NewFlagSet("pod list", flag.ExitOnError)
			fl.BoolVar(&machineFriendly, "H", false, "Machine-friendly output")
			fl.BoolVar(&idOnly, "q", false, "Show only ID")
			fl.Parse(args)

			pods := Host.Pods()

			if idOnly {
				for _, pod := range pods {
					fmt.Println(pod.UUID)
				}
			} else if len(pods) == 0 {
				if !machineFriendly {
					show("No pods")
				}
			} else {
				lines := make([]string, len(pods))
				for i, pod := range pods {
					apps := make([]string, len(pod.Manifest.Apps))
					for j, app := range pod.Manifest.Apps {
						apps[j] = app.Name.String()
					}
					ipAddress, _ := pod.Manifest.Annotations.Get("ip-address")
					lines[i] = fmt.Sprintf("%v\t%v\t%v\t%v",
						pod.UUID,
						pod.Status().String(),
						ipAddress,
						strings.Join(apps, " "))
				}
				sort.Strings(lines)
				output := strings.Join(lines, "\n")

				if machineFriendly {
					fmt.Println(output)
				} else {
					w := tabwriter.NewWriter(os.Stdout, 2, 8, 2, ' ', 0)
					fmt.Fprintf(w, "UUID\tSTATUS\tIP\tAPPS\n%v\n", output)
					die(w.Flush())
				}
			}
		case "show", "run", "ps", "top", "killall", "kill", "destroy":
			// be nice to people who prefer to type UUID after command
			command, args[0] = args[0], command
			fallthrough
		default:
			pod, err := Host.FindPod(command)
			if err == jetpack.ErrNotFound {
				die(errors.Errorf("No such pod: %#v", command))
			}
			die(err)
			switch command, args := subcommand("show", args); command {
			case "show":
				show(pod)
			case "run":
				switch len(args) {
				case 0:
					if len(pod.Manifest.Apps) > 1 {
						die(errors.New("Pod has multiple apps, you need to specify one"))
					}
					die(pod.RunApp(pod.Manifest.Apps[0].Name))
				case 1:
					die(pod.RunApp(types.ACName(args[0])))
				default:
					die(errors.New("Command `run' takes at most one argument"))
				}
			case "console":
				switch len(args) {
				case 0:
					if len(pod.Manifest.Apps) > 1 {
						die(errors.New("Pod has multiple apps, you need to specify one"))
					}
					die(pod.Console(pod.Manifest.Apps[0].Name, "root"))
				case 1:
					die(pod.Console(types.ACName(args[0]), "root"))
				default:
					die(errors.New("Command `console' takes at most one argument"))
				}
			case "ps", "top", "killall":
				jid := pod.Jid()
				if jid == 0 {
					die(errors.New("Pod is not running"))
				}

				flag := "-J"
				if command == "killall" {
					flag = "-j"
				}

				die(run.Command(command, append([]string{flag, strconv.Itoa(jid)}, args...)...).Run())
			case "kill":
				die(pod.Kill())
			case "destroy":
				die(pod.Destroy())
			default:
				die(errors.Errorf("Unknown command %#v", command))
			}
		}
	default:
		die(errors.Errorf("Unknown command %#v", command))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/mitchellh/packer/packer/plugin"
)

const version = "0.1.0"

func main() {
	server, err := plugin.Server()
	if err != nil {
		panic(err)
	}
	server.RegisterPostProcessor(&PostProcessor{})
	server.Serve()
}
<commit_msg>bump version to 0.1.1<commit_after>package main

import (
	"github.com/mitchellh/packer/packer/plugin"
)

const version = "0.1.1"

func main() {
	server, err := plugin.Server()
	if err != nil {
		panic(err)
	}
	server.RegisterPostProcessor(&PostProcessor{})
	server.Serve()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/codegangsta/cli"
	"os"
	"time"
)

func main() {
	app := cli.NewApp()
	app.Name = "tad"
	app.Usage = "print the date and time"
	app.Action = func(c *cli.Context) {
		const layout = "Jan 2, 2006 at 3:04pm (MST)"
		t := time.Now()
		fmt.Println(t.Format(layout))
	}
	app.Run(os.Args)
}
<commit_msg>Update the name to dat<commit_after>package main

import (
	"fmt"
	"github.com/codegangsta/cli"
	"os"
	"time"
)

func main() {
	app := cli.NewApp()
	app.Name = "dat"
	app.Usage = "print the date and time"
	app.Action = func(c *cli.Context) {
		const layout = "Jan 2, 2006 at 3:04pm (MST)"
		t := time.Now()
		fmt.Println(t.Format(layout))
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/matsumana/flink_exporter/exporter"
	"github.com/prometheus/client_golang/prometheus"
	"gopkg.in/urfave/cli.v2"
	"net/http"
	"os"
)

const (
	version   = "0.1.1"
	endpoint  = "/metrics"
	namespace = "flink"
)

type appOpts struct {
	Name    string
	Version string
	Flags   []cli.Flag
}

func main() {
	opts := &appOpts{
		Name:    "flink_exporter",
		Version: version,
	}
	opts.Flags = []cli.Flag{
		&cli.StringFlag{
			Name:  "log-level",
			Usage: "Set Logging level",
			Value: "info",
		},
		&cli.IntFlag{
			Name:  "port",
			Usage: "The port number used to expose metrics via http",
			Value: 9160,
		},
		&cli.StringFlag{
			Name:  "flink-job-manager-url",
			Usage: "flink job manager url",
			Value: "http://localhost:8081/",
		},
	}
	log.Debugf("opts = %v", opts)

	err := newApp(opts).Run(os.Args)
	if err != nil {
		os.Exit(1)
	}
}

func newApp(opts *appOpts) *cli.App {
	return &cli.App{
		Name:    opts.Name,
		Version: opts.Version,
		Usage:   "Prometheus exporter for Apache Flink",
		Flags:   opts.Flags,
		Action:  action,
	}
}

func action(c *cli.Context) error {

	setupLogging(c)

	flinkJobManagerUrl := c.String("flink-job-manager-url")

	// register exporter
	exporter := exporter.NewExporter(flinkJobManagerUrl, namespace)
	prometheus.MustRegister(exporter)

	// http listen and serve
	port := c.Int("port")
	log.Debugf("port = %v", port)

	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Add("Location", endpoint)
		w.WriteHeader(http.StatusMovedPermanently)
	})
	http.Handle(endpoint, prometheus.Handler())
	if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil {
		log.Fatal(err)
	}

	return nil
}

func setupLogging(c *cli.Context) {
	log.SetFormatter(&log.TextFormatter{
		FullTimestamp: true,
	})
	levelString := c.String("log-level")
	level, err := log.ParseLevel(levelString)
	if err != nil {
		log.Fatalf("could not set log level to '%s';err:<%s>", levelString, err)
	}
	log.SetLevel(level)
}
<commit_msg>bump version to 0.2.0<commit_after>package main

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/matsumana/flink_exporter/exporter"
	"github.com/prometheus/client_golang/prometheus"
	"gopkg.in/urfave/cli.v2"
	"net/http"
	"os"
)

const (
	version   = "0.2.0"
	endpoint  = "/metrics"
	namespace = "flink"
)

type appOpts struct {
	Name    string
	Version string
	Flags   []cli.Flag
}

func main() {
	opts := &appOpts{
		Name:    "flink_exporter",
		Version: version,
	}
	opts.Flags = []cli.Flag{
		&cli.StringFlag{
			Name:  "log-level",
			Usage: "Set Logging level",
			Value: "info",
		},
		&cli.IntFlag{
			Name:  "port",
			Usage: "The port number used to expose metrics via http",
			Value: 9160,
		},
		&cli.StringFlag{
			Name:  "flink-job-manager-url",
			Usage: "flink job manager url",
			Value: "http://localhost:8081/",
		},
	}
	log.Debugf("opts = %v", opts)

	err := newApp(opts).Run(os.Args)
	if err != nil {
		os.Exit(1)
	}
}

func newApp(opts *appOpts) *cli.App {
	return &cli.App{
		Name:    opts.Name,
		Version: opts.Version,
		Usage:   "Prometheus exporter for Apache Flink",
		Flags:   opts.Flags,
		Action:  action,
	}
}

func action(c *cli.Context) error {

	setupLogging(c)

	flinkJobManagerUrl := c.String("flink-job-manager-url")

	// register exporter
	exporter := exporter.NewExporter(flinkJobManagerUrl, namespace)
	prometheus.MustRegister(exporter)

	// http listen and serve
	port := c.Int("port")
	log.Debugf("port = %v", port)

	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Add("Location", endpoint)
		w.WriteHeader(http.StatusMovedPermanently)
	})
	http.Handle(endpoint, prometheus.Handler())
	if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil {
		log.Fatal(err)
	}

	return nil
}

func setupLogging(c *cli.Context) {
	log.SetFormatter(&log.TextFormatter{
		FullTimestamp: true,
	})
	levelString := c.String("log-level")
	level, err := log.ParseLevel(levelString)
	if err != nil {
		log.Fatalf("could not set log level to '%s';err:<%s>", levelString, err)
	}
	log.SetLevel(level)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strconv"

	"time"

	"strings"

	"syscall"

	"os/signal"

	"runtime"

	"github.com/claudetech/loggo"
	. "github.com/claudetech/loggo/default"
	"github.com/dweidenfeld/plexdrive/chunk"
	"github.com/dweidenfeld/plexdrive/config"
	"github.com/dweidenfeld/plexdrive/drive"
	"github.com/dweidenfeld/plexdrive/mount"
	flag "github.com/ogier/pflag"
	"golang.org/x/sys/unix"
)

func main() {
	// get the users home dir
	user, err := user.Current()
	if nil != err {
		panic(fmt.Sprintf("Could not read users homedir %v\n", err))
	}

	// parse the command line arguments
	argLogLevel := flag.IntP("verbosity", "v", 0, "Set the log level (0 = error, 1 = warn, 2 = info, 3 = debug, 4 = trace)")
	argRootNodeID := flag.String("root-node-id", "root", "The ID of the root node to mount (use this for only mount a sub directory)")
	argConfigPath := flag.StringP("config", "c", filepath.Join(user.HomeDir, ".plexdrive"), "The path to the configuration directory")
	argCacheFile := flag.String("cache-file", filepath.Join(user.HomeDir, ".plexdrive", "cache.bolt"), "Path the the cache file")
	argChunkSize := flag.String("chunk-size", "10M", "The size of each chunk that is downloaded (units: B, K, M, G)")
	argChunkLoadThreads := flag.Int("chunk-load-threads", runtime.NumCPU()/2, "The number of threads to use for downloading chunks")
	argChunkCheckThreads := flag.Int("chunk-check-threads", runtime.NumCPU()/2, "The number of threads to use for checking chunk existence")
	argChunkLoadAhead := flag.Int("chunk-load-ahead", runtime.NumCPU()-1, "The number of chunks that should be read ahead")
	argMaxChunks := flag.Int("max-chunks", runtime.NumCPU()*2, "The maximum number of chunks to be stored on disk")
	argRefreshInterval := flag.Duration("refresh-interval", 1*time.Minute, "The time to wait till checking for changes")
	argMountOptions := flag.StringP("fuse-options", "o", "", "Fuse mount options (e.g. -fuse-options allow_other,...)")
	argVersion := flag.Bool("version", false, "Displays program's version information")
	argUID := flag.Int64("uid", -1, "Set the mounts UID (-1 = default permissions)")
	argGID := flag.Int64("gid", -1, "Set the mounts GID (-1 = default permissions)")
	argUmask := flag.Uint32("umask", 0, "Override the default file permissions")
	// argDownloadSpeedLimit := flag.String("speed-limit", "", "This value limits the download speed, e.g. 5M = 5MB/s per chunk (units: B, K, M, G)")
	flag.Parse()

	// display version information
	if *argVersion {
		fmt.Println("%VERSION%")
		return
	}

	argCommand := flag.Arg(0)

	if argCommand == "mount" {
		// check if mountpoint is specified
		argMountPoint := flag.Arg(1)
		if "" == argMountPoint {
			flag.Usage()
			fmt.Println()
			panic(fmt.Errorf("Mountpoint not specified"))
		}

		// calculate uid / gid
		uid := uint32(unix.Geteuid())
		gid := uint32(unix.Getegid())
		if *argUID > -1 {
			uid = uint32(*argUID)
		}
		if *argGID > -1 {
			gid = uint32(*argGID)
		}

		// parse filemode
		umask := os.FileMode(*argUmask)

		// parse the mount options
		var mountOptions []string
		if "" != *argMountOptions {
			mountOptions = strings.Split(*argMountOptions, ",")
		}

		// initialize the logger with the specific log level
		var logLevel loggo.Level
		switch *argLogLevel {
		case 0:
			logLevel = loggo.Error
		case 1:
			logLevel = loggo.Warning
		case 2:
			logLevel = loggo.Info
		case 3:
			logLevel = loggo.Debug
		case 4:
			logLevel = loggo.Trace
		default:
			logLevel = loggo.Warning
		}
		Log.SetLevel(logLevel)

		// debug all given parameters
		Log.Debugf("verbosity            : %v", logLevel)
		Log.Debugf("root-node-id         : %v", *argRootNodeID)
		Log.Debugf("config               : %v", *argConfigPath)
		Log.Debugf("cache-file           : %v", *argCacheFile)
		Log.Debugf("chunk-size           : %v", *argChunkSize)
		Log.Debugf("chunk-load-threads   : %v", *argChunkLoadThreads)
		Log.Debugf("chunk-check-threads  : %v", *argChunkCheckThreads)
		Log.Debugf("chunk-load-ahead     : %v", *argChunkLoadAhead)
		Log.Debugf("max-chunks           : %v", *argMaxChunks)
		Log.Debugf("refresh-interval     : %v", *argRefreshInterval)
		Log.Debugf("fuse-options         : %v", *argMountOptions)
		Log.Debugf("UID                  : %v", uid)
		Log.Debugf("GID                  : %v", gid)
		Log.Debugf("umask                : %v", umask)
		// Log.Debugf("speed-limit          : %v", *argDownloadSpeedLimit)
		// version missing here

		// create all directories
		if err := os.MkdirAll(*argConfigPath, 0766); nil != err {
			Log.Errorf("Could not create configuration directory")
			Log.Debugf("%v", err)
			os.Exit(1)
		}
		if err := os.MkdirAll(filepath.Dir(*argCacheFile), 0766); nil != err {
			Log.Errorf("Could not create cache file directory")
			Log.Debugf("%v", err)
			os.Exit(1)
		}

		// set the global buffer configuration
		chunkSize, err := parseSizeArg(*argChunkSize)
		if nil != err {
			Log.Errorf("%v", err)
			os.Exit(2)
		}

		// read the configuration
		configPath := filepath.Join(*argConfigPath, "config.json")
		cfg, err := config.Read(configPath)
		if nil != err {
			cfg, err = config.Create(configPath)
			if nil != err {
				Log.Errorf("Could not read configuration")
				Log.Debugf("%v", err)
				os.Exit(3)
			}
		}

		cache, err := drive.NewCache(*argCacheFile, *argConfigPath, *argLogLevel > 3)
		if nil != err {
			Log.Errorf("%v", err)
			os.Exit(4)
		}
		defer cache.Close()

		client, err := drive.NewClient(cfg, cache, *argRefreshInterval, *argRootNodeID)
		if nil != err {
			Log.Errorf("%v", err)
			os.Exit(4)
		}

		chunkManager, err := chunk.NewManager(
			chunkSize,
			*argChunkLoadAhead,
			*argChunkCheckThreads,
			*argChunkLoadThreads,
			client,
			*argMaxChunks)
		if nil != err {
			Log.Errorf("%v", err)
			os.Exit(4)
		}

		// check os signals like SIGINT/TERM
		checkOsSignals(argMountPoint)
		if err := mount.Mount(client, chunkManager, argMountPoint, mountOptions, uid, gid, umask); nil != err {
			Log.Debugf("%v", err)
			os.Exit(5)
		}
	} else {
		Log.Errorf("Command %v not found", argCommand)
	}
}

func checkOsSignals(mountpoint string) {
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGINT)

	go func() {
		for sig := range signals {
			if sig == syscall.SIGINT {
				if err := mount.Unmount(mountpoint, false); nil != err {
					Log.Warningf("%v", err)
				}
			}
		}
	}()
}

func parseSizeArg(input string) (int64, error) {
	if "" == input {
		return 0, nil
	}

	suffix := input[len(input)-1]
	suffixLen := 1
	var multiplier float64
	switch suffix {
	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.':
		suffixLen = 0
	case 'b', 'B':
		multiplier = 1
	case 'k', 'K':
		multiplier = 1024
	case 'm', 'M':
		multiplier = 1024 * 1024
	case 'g', 'G':
		multiplier = 1024 * 1024 * 1024
	default:
		return 0, fmt.Errorf("Invalid unit %v for %v", suffix, input)
	}
	input = input[:len(input)-suffixLen]
	value, err := strconv.ParseFloat(input, 64)
	if nil != err {
		Log.Debugf("%v", err)
		return 0, fmt.Errorf("Could not parse numeric value %v", input)
	}
	if value < 0 {
		return 0, fmt.Errorf("Numeric value must not be negative %v", input)
	}
	value *= multiplier
	return int64(value), nil
}
<commit_msg>Fix option parsing to work with 1 CPU core<commit_after>package main

import (
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strconv"

	"time"

	"strings"

	"syscall"

	"os/signal"

	"runtime"

	"github.com/claudetech/loggo"
	. "github.com/claudetech/loggo/default"
	"github.com/dweidenfeld/plexdrive/chunk"
	"github.com/dweidenfeld/plexdrive/config"
	"github.com/dweidenfeld/plexdrive/drive"
	"github.com/dweidenfeld/plexdrive/mount"
	flag "github.com/ogier/pflag"
	"golang.org/x/sys/unix"
)

func main() {
	// get the users home dir
	user, err := user.Current()
	if nil != err {
		panic(fmt.Sprintf("Could not read users homedir %v\n", err))
	}

	// parse the command line arguments
	argLogLevel := flag.IntP("verbosity", "v", 0, "Set the log level (0 = error, 1 = warn, 2 = info, 3 = debug, 4 = trace)")
	argRootNodeID := flag.String("root-node-id", "root", "The ID of the root node to mount (use this for only mount a sub directory)")
	argConfigPath := flag.StringP("config", "c", filepath.Join(user.HomeDir, ".plexdrive"), "The path to the configuration directory")
	argCacheFile := flag.String("cache-file", filepath.Join(user.HomeDir, ".plexdrive", "cache.bolt"), "Path the the cache file")
	argChunkSize := flag.String("chunk-size", "10M", "The size of each chunk that is downloaded (units: B, K, M, G)")
	argChunkLoadThreads := flag.Int("chunk-load-threads", max(runtime.NumCPU()/2, 1), "The number of threads to use for downloading chunks")
	argChunkCheckThreads := flag.Int("chunk-check-threads", max(runtime.NumCPU()/2, 1), "The number of threads to use for checking chunk existence")
	argChunkLoadAhead := flag.Int("chunk-load-ahead", max(runtime.NumCPU()-1, 1), "The number of chunks that should be read ahead")
	argMaxChunks := flag.Int("max-chunks", runtime.NumCPU()*2, "The maximum number of chunks to be stored on disk")
	argRefreshInterval := flag.Duration("refresh-interval", 1*time.Minute, "The time to wait till checking for changes")
	argMountOptions := flag.StringP("fuse-options", "o", "", "Fuse mount options (e.g. -fuse-options allow_other,...)")
	argVersion := flag.Bool("version", false, "Displays program's version information")
	argUID := flag.Int64("uid", -1, "Set the mounts UID (-1 = default permissions)")
	argGID := flag.Int64("gid", -1, "Set the mounts GID (-1 = default permissions)")
	argUmask := flag.Uint32("umask", 0, "Override the default file permissions")
	// argDownloadSpeedLimit := flag.String("speed-limit", "", "This value limits the download speed, e.g. 5M = 5MB/s per chunk (units: B, K, M, G)")
	flag.Parse()

	// display version information
	if *argVersion {
		fmt.Println("%VERSION%")
		return
	}

	argCommand := flag.Arg(0)

	if argCommand == "mount" {
		// check if mountpoint is specified
		argMountPoint := flag.Arg(1)
		if "" == argMountPoint {
			flag.Usage()
			fmt.Println()
			panic(fmt.Errorf("Mountpoint not specified"))
		}

		// calculate uid / gid
		uid := uint32(unix.Geteuid())
		gid := uint32(unix.Getegid())
		if *argUID > -1 {
			uid = uint32(*argUID)
		}
		if *argGID > -1 {
			gid = uint32(*argGID)
		}

		// parse filemode
		umask := os.FileMode(*argUmask)

		// parse the mount options
		var mountOptions []string
		if "" != *argMountOptions {
			mountOptions = strings.Split(*argMountOptions, ",")
		}

		// initialize the logger with the specific log level
		var logLevel loggo.Level
		switch *argLogLevel {
		case 0:
			logLevel = loggo.Error
		case 1:
			logLevel = loggo.Warning
		case 2:
			logLevel = loggo.Info
		case 3:
			logLevel = loggo.Debug
		case 4:
			logLevel = loggo.Trace
		default:
			logLevel = loggo.Warning
		}
		Log.SetLevel(logLevel)

		// debug all given parameters
		Log.Debugf("verbosity            : %v", logLevel)
		Log.Debugf("root-node-id         : %v", *argRootNodeID)
		Log.Debugf("config               : %v", *argConfigPath)
		Log.Debugf("cache-file           : %v", *argCacheFile)
		Log.Debugf("chunk-size           : %v", *argChunkSize)
		Log.Debugf("chunk-load-threads   : %v", *argChunkLoadThreads)
		Log.Debugf("chunk-check-threads  : %v", *argChunkCheckThreads)
		Log.Debugf("chunk-load-ahead     : %v", *argChunkLoadAhead)
		Log.Debugf("max-chunks           : %v", *argMaxChunks)
		Log.Debugf("refresh-interval     : %v", *argRefreshInterval)
		Log.Debugf("fuse-options         : %v", *argMountOptions)
		Log.Debugf("UID                  : %v", uid)
		Log.Debugf("GID                  : %v", gid)
		Log.Debugf("umask                : %v", umask)
		// Log.Debugf("speed-limit          : %v", *argDownloadSpeedLimit)
		// version missing here

		// create all directories
		if err := os.MkdirAll(*argConfigPath, 0766); nil != err {
			Log.Errorf("Could not create configuration directory")
			Log.Debugf("%v", err)
			os.Exit(1)
		}
		if err := os.MkdirAll(filepath.Dir(*argCacheFile), 0766); nil != err {
			Log.Errorf("Could not create cache file directory")
			Log.Debugf("%v", err)
			os.Exit(1)
		}

		// set the global buffer configuration
		chunkSize, err := parseSizeArg(*argChunkSize)
		if nil != err {
			Log.Errorf("%v", err)
			os.Exit(2)
		}

		// read the configuration
		configPath := filepath.Join(*argConfigPath, "config.json")
		cfg, err := config.Read(configPath)
		if nil != err {
			cfg, err = config.Create(configPath)
			if nil != err {
				Log.Errorf("Could not read configuration")
				Log.Debugf("%v", err)
				os.Exit(3)
			}
		}

		cache, err := drive.NewCache(*argCacheFile, *argConfigPath, *argLogLevel > 3)
		if nil != err {
			Log.Errorf("%v", err)
			os.Exit(4)
		}
		defer cache.Close()

		client, err := drive.NewClient(cfg, cache, *argRefreshInterval, *argRootNodeID)
		if nil != err {
			Log.Errorf("%v", err)
			os.Exit(4)
		}

		chunkManager, err := chunk.NewManager(
			chunkSize,
			*argChunkLoadAhead,
			*argChunkCheckThreads,
			*argChunkLoadThreads,
			client,
			*argMaxChunks)
		if nil != err {
			Log.Errorf("%v", err)
			os.Exit(4)
		}

		// check os signals like SIGINT/TERM
		checkOsSignals(argMountPoint)
		if err := mount.Mount(client, chunkManager, argMountPoint, mountOptions, uid, gid, umask); nil != err {
			Log.Debugf("%v", err)
			os.Exit(5)
		}
	} else {
		Log.Errorf("Command %v not found", argCommand)
	}
}

func checkOsSignals(mountpoint string) {
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGINT)

	go func() {
		for sig := range signals {
			if sig == syscall.SIGINT {
				if err := mount.Unmount(mountpoint, false); nil != err {
					Log.Warningf("%v", err)
				}
			}
		}
	}()
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func parseSizeArg(input string) (int64, error) {
	if "" == input {
		return 0, nil
	}

	suffix := input[len(input)-1]
	suffixLen := 1
	var multiplier float64
	switch suffix {
	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.':
		suffixLen = 0
	case 'b', 'B':
		multiplier = 1
	case 'k', 'K':
		multiplier = 1024
	case 'm', 'M':
		multiplier = 1024 * 1024
	case 'g', 'G':
		multiplier = 1024 * 1024 * 1024
	default:
		return 0, fmt.Errorf("Invalid unit %v for %v", suffix, input)
	}
	input = input[:len(input)-suffixLen]
	value, err := strconv.ParseFloat(input, 64)
	if nil != err {
		Log.Debugf("%v", err)
		return 0, fmt.Errorf("Could not parse numeric value %v", input)
	}
	if value < 0 {
		return 0, fmt.Errorf("Numeric value must not be negative %v", input)
	}
	value *= multiplier
	return int64(value), nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/csv"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"github.com/knq/dburl"
	"github.com/labkode/cernboxshareinfo/models"
	"github.com/labkode/cernboxshareinfo/proto"
	"github.com/syndtr/goleveldb/leveldb"
)

var sqlFile string
var phonebookBinary string
var phonebookdb string
var mysqlhost string
var mysqlusername string
var mysqlpassword string
var mysqldatabase string
var mysqlport int

func main() {
	flag.StringVar(&sqlFile, "sqlfile", "shares.sql", "file containing the mysql oc_shares dump")
	flag.StringVar(&phonebookBinary, "phonebookbinary", "/usr/bin/phonebook", "the phonebook binary")
	flag.StringVar(&phonebookdb, "phonebookdb", "phonebook.db", "phonebook cache db file")
	flag.StringVar(&mysqlhost, "mysqlhost", "localhost", "mysql hostname")
	flag.StringVar(&mysqlusername, "mysqlusername", "admin", "mysql username")
	flag.StringVar(&mysqlpassword, "mysqlpassword", "admin", "mysql password")
	flag.StringVar(&mysqldatabase, "mysqldatabase", "mydb", "mysql database")
	flag.IntVar(&mysqlport, "mysqlport", 3306, "mysql port")
	flag.Parse()

	fmt.Printf("Loading shares from: %s\n", sqlFile)
	fmt.Printf("PhoneBook Application: %s\n", phonebookBinary)

	handle, err := os.Open(sqlFile)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	defer handle.Close()

	r := csv.NewReader(handle)
	r.Comma = '\t'

	shareInfos := []*proto.ShareInfo{}
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(os.Stderr, err)
		} else {

			/*
			*
			* These are the attributes from the MySQL oc_share dump:
			*
			* id: unique identifier of the share
			* share_type: the type of the share: 0 is internal, 1 is group and 3 is by link
			* share_with: the receiver of the share
			* uid_owner: the username that started the share
			* parent: the parent file of the shared one
			* item_type: the type of resource being shared: either file or folder
			* item source: inode of file being shared
			* item_target: name of the file when appears in the sharee filesystem
			* file_source: the inode of the file being shared
			* file_target: the name of the file when appears in the sharee filesystem
			* permissions: the permissions for the sharee
			* stime: the time the share was created
			* accepted: the share was acepted: only valid for federated shares
			* expiration: when the share will expire: only valid for link shares
			* token: the token to access the share: only valid for link shares
			* mail_send: whether the sharee has been informed by email of the new share
			 */

			id, _ := strconv.Atoi(record[0])
			shareType, _ := strconv.Atoi(record[1])
			parent, _ := strconv.Atoi(record[4])
			itemSource, _ := strconv.Atoi(record[6])
			fileSource, _ := strconv.Atoi(record[8])
			stime, _ := strconv.Atoi(record[11])
			accepted, _ := strconv.Atoi(record[12])
			mailSend, _ := strconv.Atoi(record[15])

			shareInfo := &proto.ShareInfo{}
			shareInfo.Id = int64(id)
			shareInfo.ShareType = int64(shareType)
			shareInfo.ShareWith = record[2]
			shareInfo.UidOwner = record[3]
			shareInfo.Parent = int64(parent)
			shareInfo.ItemType = record[5]
			shareInfo.ItemSource = int64(itemSource)
			shareInfo.ItemTarget = record[7]
			shareInfo.FileSource = int64(fileSource)
			shareInfo.FileTarget = record[9]
			shareInfo.Permissions = record[10]
			shareInfo.Stime = int64(stime)
			shareInfo.Accepted = int64(accepted)
			shareInfo.Expiration = record[13]
			shareInfo.Token = record[14]
			shareInfo.MailSend = int64(mailSend)

			// we are interested in user shares
			if shareInfo.ShareType == 0 {
				shareInfos = append(shareInfos, shareInfo)
			}
		}
	}

	userMap := map[string]*proto.PersonInfo{}
	db, err := leveldb.OpenFile(phonebookdb, nil)
	if err != nil {
		fmt.Println(err)
		fmt.Println("phonebook calls won't be cached")
	} else {
		fmt.Println("Loading phonebook db into memory...")
		total := 0
		iter := db.NewIterator(nil, nil)
		for iter.Next() {
			key := iter.Key()
			value := iter.Value() // value is json
			personInfo := &proto.PersonInfo{}
			err := json.Unmarshal(value, personInfo)
			if err != nil {
				fmt.Println(err)
			} else {
				userMap[string(key)] = personInfo
				total++
			}
		}
		iter.Release()
		fmt.Printf("Loaded %d entries from phonebook cached db\n", total)
	}

	total := len(shareInfos)
	for i, shareInfo := range shareInfos {
		fmt.Printf("Resolving users (%d)/%d\n", i, total)
		if _, ok := userMap[shareInfo.UidOwner]; !ok {
			personInfo, err := getPersonInfo(shareInfo.UidOwner)
			if err != nil {
				log.Println(err)
				db.Delete([]byte(shareInfo.UidOwner), nil)
			} else {
				userMap[shareInfo.UidOwner] = personInfo
				if db != nil {
					json, err := json.Marshal(personInfo)
					if err != nil {
						fmt.Println(err)
					} else {
						db.Put([]byte(shareInfo.UidOwner), json, nil)
					}
				}
			}
		}
		if _, ok := userMap[shareInfo.ShareWith]; !ok {
			personInfo, err := getPersonInfo(shareInfo.ShareWith)
			if err != nil {
				log.Println(err)
				db.Delete([]byte(shareInfo.UidOwner), nil)
			} else {
				userMap[shareInfo.ShareWith] = personInfo
				if db != nil {
					json, err := json.Marshal(personInfo)
					if err != nil {
						fmt.Println(err)
					} else {
						db.Put([]byte(shareInfo.ShareWith), json, nil)
					}
				}
			}
		}
	}

	fmt.Printf("Found %d persons with valid information in phonebook\n", len(userMap))

	flatInfos := []*proto.FlatInfo{}
	// create flat infos with owner and sharee together with share info
	for _, shareInfo := range shareInfos {
		_, ownerFound := userMap[shareInfo.UidOwner]
		_, shareeFound := userMap[shareInfo.ShareWith]
		if ownerFound && shareeFound {
			flatInfo := &proto.FlatInfo{}
			flatInfo.ShareInfo = shareInfo
			flatInfo.OwnerInfo = userMap[shareInfo.UidOwner]
			flatInfo.ShareeInfo = userMap[shareInfo.ShareWith]
			flatInfos = append(flatInfos, flatInfo)
		}
	}

	// forward data to sql
	sqldb, err := dburl.Open(fmt.Sprintf("mysql://%s:%s@%s:%d/%s", mysqlusername, mysqlpassword, mysqlhost, mysqlport, mysqldatabase))
	if err != nil {
		log.Fatal(err)
	}

	createCompanies(sqldb, flatInfos)
}

func createCompanies(db *sql.DB, flatInfos []*proto.FlatInfo) {
	companies := map[string]*proto.FlatInfo{}
	for _, flatInfo := range flatInfos {
		if _, ok := companies[flatInfo.GetOwnerInfo().Company]; !ok {
			companies[flatInfo.GetOwnerInfo().Company] = flatInfo
		}
		if _, ok := companies[flatInfo.GetShareeInfo().Company]; !ok {
			companies[flatInfo.GetShareeInfo().Company] = flatInfo
		}
	}
	for pk := range companies {
		company := &models.DimensionCompany{}
		company.Company = pk
		if err := company.Save(db); err != nil {
			log.Fatal(err)
		}
	}
}
func getPersonInfo(username string) (*proto.PersonInfo, error) {
	cmd := exec.Command(phonebookBinary, "--login", username, "-t", "login", "-t", "uid", "-t", "department", "-t", "organization", "-t", "company", "-t", "office")
	stdout, _, err := executeCMD(cmd)
	if err != nil {
		return nil, err
	}
	if stdout == "" {
		return nil, errors.New("user " + username + " does not exist anymore")
	}
	personInfo := &proto.PersonInfo{}
	tokens := strings.Split(stdout, ";")
	uid, _ := strconv.Atoi(tokens[1])
	personInfo.Login = tokens[0]
	personInfo.Uid = int64(uid)
	personInfo.Department = tokens[2]
	personInfo.Organization = tokens[3]
	personInfo.Company = tokens[4]
	personInfo.Office = tokens[5]
	return personInfo, nil
}

func executeCMD(cmd *exec.Cmd) (string, string, error) {
	outBuf := &bytes.Buffer{}
	errBuf := &bytes.Buffer{}
	cmd.Stdout = outBuf
	cmd.Stderr = errBuf
	err := cmd.Run()
	return outBuf.String(), errBuf.String(), err
}
<commit_msg>create dimensions<commit_after>package main

import (
	"bytes"
	"encoding/csv"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"github.com/knq/dburl"
	"github.com/labkode/cernboxshareinfo/models"
	"github.com/labkode/cernboxshareinfo/proto"
	"github.com/syndtr/goleveldb/leveldb"
)

var sqlFile string
var phonebookBinary string
var phonebookdb string
var mysqlhost string
var mysqlusername string
var mysqlpassword string
var mysqldatabase string
var mysqlport int
var testcases int

func main() {
	flag.StringVar(&sqlFile, "sqlfile", "shares.sql", "file containing the mysql oc_shares dump")
	flag.StringVar(&phonebookBinary, "phonebookbinary", "/usr/bin/phonebook", "the phonebook binary")
	flag.StringVar(&phonebookdb, "phonebookdb", "phonebook.db", "phonebook cache db file")
	flag.StringVar(&mysqlhost, "mysqlhost", "localhost", "mysql hostname")
	flag.StringVar(&mysqlusername, "mysqlusername", "admin", "mysql username")
	flag.StringVar(&mysqlpassword, "mysqlpassword", "admin", "mysql password")
	flag.StringVar(&mysqldatabase, "mysqldatabase", "mydb", "mysql database")
	flag.IntVar(&mysqlport, "mysqlport", 3306, "mysql port")
	flag.IntVar(&testcases, "testcases", -1, "number of test cases")
	flag.Parse()

	fmt.Printf("Loading shares from: %s\n", sqlFile)
	fmt.Printf("PhoneBook Application: %s\n", phonebookBinary)

	handle, err := os.Open(sqlFile)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	defer handle.Close()

	r := csv.NewReader(handle)
	r.Comma = '\t'

	shareInfos := []*proto.ShareInfo{}
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(os.Stderr, err)
		} else {

			/*
			*
			* These are the attributes from the MySQL oc_share dump:
			*
			* id: unique identifier of the share
			* share_type: the type of the share: 0 is internal, 1 is group and 3 is by link
			* share_with: the receiver of the share
			* uid_owner: the username that started the share
			* parent: the parent file of the shared one
			* item_type: the type of resource being shared: either file or folder
			* item source: inode of file being shared
			* item_target: name of the file when appears in the sharee filesystem
			* file_source: the inode of the file being shared
			* file_target: the name of the file when appears in the sharee filesystem
			* permissions: the permissions for the sharee
			* stime: the time the share was created
			* accepted: the share was acepted: only valid for federated shares
			* expiration: when the share will expire: only valid for link shares
			* token: the token to access the share: only valid for link shares
			* mail_send: whether the sharee has been informed by email of the new share
			 */

			id, _ := strconv.Atoi(record[0])
			shareType, _ := strconv.Atoi(record[1])
			parent, _ := strconv.Atoi(record[4])
			itemSource, _ := strconv.Atoi(record[6])
			fileSource, _ := strconv.Atoi(record[8])
			stime, _ := strconv.Atoi(record[11])
			accepted, _ := strconv.Atoi(record[12])
			mailSend, _ := strconv.Atoi(record[15])

			shareInfo := &proto.ShareInfo{}
			shareInfo.Id = int64(id)
			shareInfo.ShareType = int64(shareType)
			shareInfo.ShareWith = record[2]
			shareInfo.UidOwner = record[3]
			shareInfo.Parent = int64(parent)
			shareInfo.ItemType = record[5]
			shareInfo.ItemSource = int64(itemSource)
			shareInfo.ItemTarget = record[7]
			shareInfo.FileSource = int64(fileSource)
			shareInfo.FileTarget = record[9]
			shareInfo.Permissions = record[10]
			shareInfo.Stime = int64(stime)
			shareInfo.Accepted = int64(accepted)
			shareInfo.Expiration = record[13]
			shareInfo.Token = record[14]
			shareInfo.MailSend = int64(mailSend)

			// we are interested in user shares
			if shareInfo.ShareType == 0 {
				shareInfos = append(shareInfos, shareInfo)
			}
		}
	}

	userMap := map[string]*proto.PersonInfo{}
	db, err := leveldb.OpenFile(phonebookdb, nil)
	if err != nil {
		fmt.Println(err)
		fmt.Println("phonebook calls won't be cached")
	} else {
		fmt.Println("Loading phonebook db into memory...")
		total := 0
		iter := db.NewIterator(nil, nil)
		for iter.Next() {
			key := iter.Key()
			value := iter.Value() // value is json
			personInfo := &proto.PersonInfo{}
			err := json.Unmarshal(value, personInfo)
			if err != nil {
				fmt.Println(err)
			} else {
				userMap[string(key)] = personInfo
				total++
			}
		}
		iter.Release()
		fmt.Printf("Loaded %d entries from phonebook cached db\n", total)
	}

	if testcases > -1 {
		shareInfos = shareInfos[:testcases]
	}

	total := len(shareInfos)
	for i, shareInfo := range shareInfos {
		fmt.Printf("Resolving users (%d)/%d\n", i, total)
		if _, ok := userMap[shareInfo.UidOwner]; !ok {
			personInfo, err := getPersonInfo(shareInfo.UidOwner)
			if err != nil {
				log.Println(err)
				db.Delete([]byte(shareInfo.UidOwner), nil)
			} else {
				userMap[shareInfo.UidOwner] = personInfo
				if db != nil {
					json, err := json.Marshal(personInfo)
					if err != nil {
						fmt.Println(err)
					} else {
						db.Put([]byte(shareInfo.UidOwner), json, nil)
					}
				}
			}
		}
		if _, ok := userMap[shareInfo.ShareWith]; !ok {
			personInfo, err := getPersonInfo(shareInfo.ShareWith)
			if err != nil {
				log.Println(err)
				db.Delete([]byte(shareInfo.UidOwner), nil)
			} else {
				userMap[shareInfo.ShareWith] = personInfo
				if db != nil {
					json, err := json.Marshal(personInfo)
					if err != nil {
						fmt.Println(err)
					} else {
						db.Put([]byte(shareInfo.ShareWith), json, nil)
					}
				}
			}
		}
	}

	fmt.Printf("Found %d persons with valid information in phonebook\n", len(userMap))

	flatInfos := []*proto.FlatInfo{}
	// create flat infos with owner and sharee together with share info
	for _, shareInfo := range shareInfos {
		_, ownerFound := userMap[shareInfo.UidOwner]
		_, shareeFound := userMap[shareInfo.ShareWith]
		if ownerFound && shareeFound {
			flatInfo := &proto.FlatInfo{}
			flatInfo.ShareInfo = shareInfo
			flatInfo.OwnerInfo = userMap[shareInfo.UidOwner]
			flatInfo.ShareeInfo = userMap[shareInfo.ShareWith]
			flatInfos = append(flatInfos, flatInfo)
		}
	}

	// forward data to sql
	sqldb, err := dburl.Open(fmt.Sprintf("mysql://%s:%s@%s:%d/%s", mysqlusername, mysqlpassword, mysqlhost, mysqlport, mysqldatabase))
	if err != nil {
		log.Fatal(err)
	}

	createDepartments(sqldb, flatInfos)
	createGroups(sqldb, flatInfos)
	createCompanies(sqldb, flatInfos)
}

func createCompanies(db *sql.DB, flatInfos []*proto.FlatInfo) {
	companies := map[string]*proto.FlatInfo{}
	for _, flatInfo := range flatInfos {
		if _, ok := companies[flatInfo.GetOwnerInfo().Company]; !ok {
			companies[flatInfo.GetOwnerInfo().Company] = flatInfo
		}
		if _, ok := companies[flatInfo.GetShareeInfo().Company]; !ok {
			companies[flatInfo.GetShareeInfo().Company] = flatInfo
		}
	}
	for pk := range companies {
		company := models.DimensionCompany{}
		company.Company = pk
		if err := company.Insert(db); err != nil {
			log.Fatal(err)
		}
	}
}

func createGroups(db *sql.DB, flatInfos []*proto.FlatInfo) {
	groups := map[string]*proto.FlatInfo{}
	for _, flatInfo := range flatInfos {
		if _, ok :=groups[flatInfo.GetOwnerInfo().Group]; !ok {
			groups[flatInfo.GetOwnerInfo().Group] = flatInfo
		}
		if _, ok :=groups[flatInfo.GetShareeInfo().Group]; !ok {
			groups[flatInfo.GetShareeInfo().Group] = flatInfo
		}
	}
	for pk := range groups {
		group := models.DimensionGroup{}
		group.Group = pk
		if err :=group.Insert(db); err != nil {
			log.Fatal(err)
		}
	}
}

func createDepartments(db *sql.DB, flatInfos []*proto.FlatInfo) {
	departments := map[string]*proto.FlatInfo{}
	for _, flatInfo := range flatInfos {
		if _, ok :=departments[flatInfo.GetOwnerInfo().Department]; !ok {
			departments[flatInfo.GetOwnerInfo().Department] = flatInfo
		}
		if _, ok :=departments[flatInfo.GetShareeInfo().Department]; !ok {
			departments[flatInfo.GetShareeInfo().Department] = flatInfo
		}
	}
	for pk := range departments {
		department := models.DimensionDepartment{}
		department.Department = pk
		if err :=department.Insert(db); err != nil {
			log.Fatal(err)
		}
	}
}

func getPersonInfo(username string) (*proto.PersonInfo, error) {
	cmd := exec.Command(phonebookBinary, "--login", username, "-t", "login", "-t", "uid", "-t", "department", "-t", "organization", "-t", "company", "-t", "office")
	stdout, _, err := executeCMD(cmd)
	if err != nil {
		return nil, err
	}
	if stdout == "" {
		return nil, errors.New("user " + username + " does not exist anymore")
	}
	personInfo := &proto.PersonInfo{}
	tokens := strings.Split(stdout, ";")
	uid, _ := strconv.Atoi(tokens[1])
	personInfo.Login = tokens[0]
	personInfo.Uid = int64(uid)
	personInfo.Department = tokens[2]
	personInfo.Organization = tokens[3]
	personInfo.Company = tokens[4]
	personInfo.Office = tokens[5]
	return personInfo, nil
}

func executeCMD(cmd *exec.Cmd) (string, string, error) {
	outBuf := &bytes.Buffer{}
	errBuf := &bytes.Buffer{}
	cmd.Stdout = outBuf
	cmd.Stderr = errBuf
	err := cmd.Run()
	return outBuf.String(), errBuf.String(), err
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"log"
	"net/http"
	"net/url"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

// Handler is your Lambda function handler
// It uses Amazon API Gateway request/responses provided by the aws-lambda-go/events package,
// However you could use other event sources (S3, Kinesis etc), or JSON-decoded primitive types such as 'string'.
func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	log.Printf("Processing Lambda request %s\n", request.RequestContext.RequestID)
	body := body{}
	json.Unmarshal([]byte(request.Body), &body)

	response := handle(body)

	responseArray, _ := json.Marshal(response)
	n := bytes.IndexByte(responseArray, 0)
	responseString := string(responseArray[:n])
	return events.APIGatewayProxyResponse{
		Body:       responseString,
		StatusCode: 200,
	}, nil
}

type message struct {
	Value string `json:"value"`
}

var servervar bool

func init() {
	flag.BoolVar(&servervar, "server", false, "Run Igor as a server")
	flag.Parse()
}

func main() {
	if servervar {
		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			if r.URL.Path != "/" {
				http.NotFound(w, r)
				return
			}
			r.ParseForm()
			v := url.Values{}
			for field, values := range r.Form {
				for _, value := range values {
					v.Add(field, value)
				}
			}
			body := body{Body: v.Encode()}
			response := handle(body)
			responseString, _ := json.Marshal(response)
			w.Header().Set("Content-Type", "application/json; charset=utf-8")
			w.Write(responseString)
		})
		http.ListenAndServe(":8080", nil)
	} else {
		lambda.Start(Handler)
	}
}

type body struct {
	Body string `json:"body"`
}
<commit_msg>Try direct cast of response<commit_after>package main

import (
	"encoding/json"
	"flag"
	"log"
	"net/http"
	"net/url"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

// Handler is your Lambda function handler
// It uses Amazon API Gateway request/responses provided by the aws-lambda-go/events package,
// However you could use other event sources (S3, Kinesis etc), or JSON-decoded primitive types such as 'string'.
func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	log.Printf("Processing Lambda request %s\n", request.RequestContext.RequestID)
	body := body{}
	json.Unmarshal([]byte(request.Body), &body)

	response := handle(body)

	responseArray, _ := json.Marshal(response)
	// n := bytes.IndexByte(responseArray, 0)
	responseString := string(responseArray)
	return events.APIGatewayProxyResponse{
		Body:       responseString,
		StatusCode: 200,
	}, nil
}

type message struct {
	Value string `json:"value"`
}

var servervar bool

func init() {
	flag.BoolVar(&servervar, "server", false, "Run Igor as a server")
	flag.Parse()
}

func main() {
	if servervar {
		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			if r.URL.Path != "/" {
				http.NotFound(w, r)
				return
			}
			r.ParseForm()
			v := url.Values{}
			for field, values := range r.Form {
				for _, value := range values {
					v.Add(field, value)
				}
			}
			body := body{Body: v.Encode()}
			response := handle(body)
			responseString, _ := json.Marshal(response)
			w.Header().Set("Content-Type", "application/json; charset=utf-8")
			w.Write(responseString)
		})
		http.ListenAndServe(":8080", nil)
	} else {
		lambda.Start(Handler)
	}
}

type body struct {
	Body string `json:"body"`
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"github.com/mithrandie/csvq/lib/color"
	"io/ioutil"
	"os"
	"runtime"

	"github.com/mithrandie/csvq/lib/action"
	"github.com/mithrandie/csvq/lib/cmd"
	"github.com/mithrandie/csvq/lib/query"

	"github.com/urfave/cli"
)

var version = "v1.4.2"

func main() {
	cli.AppHelpTemplate = appHHelpTemplate
	cli.CommandHelpTemplate = commandHelpTemplate

	app := cli.NewApp()

	app.Name = "csvq"
	app.Usage = "SQL like query language for csv"
	app.ArgsUsage = "[\"query\"|\"statements\"|argument]"
	app.Version = version

	defaultCPU := runtime.NumCPU() / 2
	if defaultCPU < 1 {
		defaultCPU = 1
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "delimiter, d",
			Usage: "field delimiter. Default is \",\" for csv files, \"\\t\" for tsv files.",
		},
		cli.StringFlag{
			Name:  "json-query, j",
			Usage: "`JSON_QUERY` for JSON data passed from standard input",
		},
		cli.StringFlag{
			Name:  "encoding, e",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "line-break, l",
			Value: "LF",
			Usage: "line break. one of: CRLF|LF|CR",
		},
		cli.StringFlag{
			Name:  "timezone, z",
			Value: "Local",
			Usage: "default timezone. \"Local\", \"UTC\" or a timezone name(e.g. \"America/Los_Angeles\")",
		},
		cli.StringFlag{
			Name:  "repository, r",
			Usage: "directory path where files are located",
		},
		cli.StringFlag{
			Name:  "source, s",
			Usage: "load query from `FILE`",
		},
		cli.StringFlag{
			Name:  "datetime-format, t",
			Usage: "set datetime format to parse strings",
		},
		cli.Float64Flag{
			Name:  "wait-timeout, w",
			Value: 10,
			Usage: "limit of the waiting time in seconds to wait for locked files to be released",
		},
		cli.BoolFlag{
			Name:  "no-header, n",
			Usage: "import the first line as a record",
		},
		cli.BoolFlag{
			Name:  "without-null, a",
			Usage: "parse empty fields as empty strings",
		},
		cli.StringFlag{
			Name:  "write-encoding, E",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "out, o",
			Usage: "write output to `FILE`",
		},
		cli.StringFlag{
			Name:  "format, f",
			Usage: "output format. one of: CSV|TSV|JSON|JSONH|JSONA|GFM|ORG|TEXT",
		},
		cli.StringFlag{
			Name:  "write-delimiter, D",
			Usage: "field delimiter for CSV",
		},
		cli.BoolFlag{
			Name:  "without-header, N",
			Usage: "when the file format is specified as CSV or TSV, write without the header line",
		},
		cli.BoolFlag{
			Name:  "pretty-print, P",
			Usage: "make JSON output easier to read",
		},
		cli.BoolFlag{
			Name:  "color, c",
			Usage: "use ANSI color escape sequences",
		},
		cli.BoolFlag{
			Name:  "quiet, q",
			Usage: "suppress operation log output",
		},
		cli.IntFlag{
			Name:  "cpu, p",
			Value: defaultCPU,
			Usage: "hint for the number of cpu cores to be used. 1 - number of cpu cores",
		},
		cli.BoolFlag{
			Name:  "stats, x",
			Usage: "show execution time and memory statistics",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "fields",
			Usage:     "Show fields in a file",
			ArgsUsage: "CSV_FILE_PATH",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "fields")
					return ExitError("table is not specified", 1)
				}

				table := c.Args().First()

				err := action.ShowFields(table)
				if err != nil {
					return ExitError(err.Error(), 1)
				}

				return nil
			},
		},
		{
			Name:      "calc",
			Usage:     "Calculate a value from stdin",
			ArgsUsage: "\"expression\"",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					cli.ShowCommandHelp(c, "calc")
					return ExitError("expression is empty", 1)
				}

				expr := c.Args().First()
				err := action.Calc(expr)
				if err != nil {
					return ExitError(err.Error(), 1)
				}

				return nil
			},
		},
	}

	app.Before = func(c *cli.Context) error {
		err := setFlags(c)
		if err != nil {
			return ExitError(err.Error(), 1)
		}
		return nil
	}

	app.Action = func(c *cli.Context) error {
		queryString, err := readQuery(c)
		if err != nil {
			cli.ShowAppHelp(c)
			return ExitError(err.Error(), 1)
		}

		if len(queryString) < 1 {
			err = action.LaunchInteractiveShell()
		} else {
			err = action.Run(queryString, cmd.GetFlags().Source)
		}

		if err != nil {
			code := 1
			if apperr, ok := err.(query.AppError); ok {
				code = apperr.GetCode()
			} else if ex, ok := err.(*query.ForcedExit); ok {
				code = ex.GetCode()
			}
			return ExitError(err.Error(), code)
		}

		return nil
	}

	app.Run(os.Args)
}

func readQuery(c *cli.Context) (string, error) {
	var queryString string

	flags := cmd.GetFlags()
	if 0 < len(flags.Source) {
		fp, err := os.Open(flags.Source)
		if err != nil {
			return queryString, err
		}
		defer fp.Close()

		buf, err := ioutil.ReadAll(fp)
		if err != nil {
			return queryString, err
		}
		queryString = string(buf)

	} else {
		if 1 < c.NArg() {
			return queryString, errors.New("multiple queries or statements were passed")
		}
		queryString = c.Args().First()
	}

	return queryString, nil
}

func setFlags(c *cli.Context) error {
	cmd.SetColor(c.GlobalBool("color"))

	if err := cmd.SetDelimiter(c.GlobalString("delimiter")); err != nil {
		return err
	}
	cmd.SetJsonQuery(c.GlobalString("json-query"))
	if err := cmd.SetEncoding(c.GlobalString("encoding")); err != nil {
		return err
	}
	if err := cmd.SetLineBreak(c.String("line-break")); err != nil {
		return err
	}
	if err := cmd.SetLocation(c.String("timezone")); err != nil {
		return err
	}
	if err := cmd.SetRepository(c.GlobalString("repository")); err != nil {
		return err
	}
	if err := cmd.SetSource(c.GlobalString("source")); err != nil {
		return err
	}
	cmd.SetDatetimeFormat(c.GlobalString("datetime-format"))
	cmd.SetWaitTimeout(c.GlobalFloat64("wait-timeout"))
	cmd.SetNoHeader(c.GlobalBool("no-header"))
	cmd.SetWithoutNull(c.GlobalBool("without-null"))

	if err := cmd.SetWriteEncoding(c.GlobalString("write-encoding")); err != nil {
		return err
	}
	if err := cmd.SetOut(c.GlobalString("out")); err != nil {
		return err
	}
	if err := cmd.SetFormat(c.GlobalString("format")); err != nil {
		return err
	}
	if err := cmd.SetWriteDelimiter(c.GlobalString("write-delimiter")); err != nil {
		return err
	}
	cmd.SetPrettyPrint(c.GlobalBool("pretty-print"))
	cmd.SetWithoutHeader(c.GlobalBool("without-header"))

	cmd.SetQuiet(c.GlobalBool("quiet"))
	cmd.SetCPU(c.GlobalInt("cpu"))
	cmd.SetStats(c.GlobalBool("stats"))

	return nil
}

func ExitError(message string, code int) *cli.ExitError {
	return cli.NewExitError(color.Error(message), code)
}
<commit_msg>Fix return code when on-usage-error occurred.<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/mithrandie/csvq/lib/action"
	"github.com/mithrandie/csvq/lib/cmd"
	"github.com/mithrandie/csvq/lib/color"
	"github.com/mithrandie/csvq/lib/query"
	"io/ioutil"
	"os"
	"runtime"

	"github.com/urfave/cli"
)

var version = "v1.4.2"

func main() {
	cli.AppHelpTemplate = appHHelpTemplate
	cli.CommandHelpTemplate = commandHelpTemplate

	app := cli.NewApp()

	app.Name = "csvq"
	app.Usage = "SQL like query language for csv"
	app.ArgsUsage = "[\"query\"|\"statements\"|argument]"
	app.Version = version

	app.OnUsageError = func(c *cli.Context, err error, isSubcommand bool) error {
		if isSubcommand {
			return err
		}

		return NewExitError(fmt.Sprintf("Incorrect Usage: %s", err.Error()), 1)
	}

	defaultCPU := runtime.NumCPU() / 2
	if defaultCPU < 1 {
		defaultCPU = 1
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "delimiter, d",
			Usage: "field delimiter. Default is \",\" for csv files, \"\\t\" for tsv files.",
		},
		cli.StringFlag{
			Name:  "json-query, j",
			Usage: "`JSON_QUERY` for JSON data passed from standard input",
		},
		cli.StringFlag{
			Name:  "encoding, e",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "line-break, l",
			Value: "LF",
			Usage: "line break. one of: CRLF|LF|CR",
		},
		cli.StringFlag{
			Name:  "timezone, z",
			Value: "Local",
			Usage: "default timezone. \"Local\", \"UTC\" or a timezone name(e.g. \"America/Los_Angeles\")",
		},
		cli.StringFlag{
			Name:  "repository, r",
			Usage: "directory path where files are located",
		},
		cli.StringFlag{
			Name:  "source, s",
			Usage: "load query from `FILE`",
		},
		cli.StringFlag{
			Name:  "datetime-format, t",
			Usage: "set datetime format to parse strings",
		},
		cli.Float64Flag{
			Name:  "wait-timeout, w",
			Value: 10,
			Usage: "limit of the waiting time in seconds to wait for locked files to be released",
		},
		cli.BoolFlag{
			Name:  "no-header, n",
			Usage: "import the first line as a record",
		},
		cli.BoolFlag{
			Name:  "without-null, a",
			Usage: "parse empty fields as empty strings",
		},
		cli.StringFlag{
			Name:  "write-encoding, E",
			Value: "UTF8",
			Usage: "file encoding. one of: UTF8|SJIS",
		},
		cli.StringFlag{
			Name:  "out, o",
			Usage: "write output to `FILE`",
		},
		cli.StringFlag{
			Name:  "format, f",
			Usage: "output format. one of: CSV|TSV|JSON|JSONH|JSONA|GFM|ORG|TEXT",
		},
		cli.StringFlag{
			Name:  "write-delimiter, D",
			Usage: "field delimiter for CSV",
		},
		cli.BoolFlag{
			Name:  "without-header, N",
			Usage: "when the file format is specified as CSV or TSV, write without the header line",
		},
		cli.BoolFlag{
			Name:  "pretty-print, P",
			Usage: "make JSON output easier to read",
		},
		cli.BoolFlag{
			Name:  "color, c",
			Usage: "use ANSI color escape sequences",
		},
		cli.BoolFlag{
			Name:  "quiet, q",
			Usage: "suppress operation log output",
		},
		cli.IntFlag{
			Name:  "cpu, p",
			Value: defaultCPU,
			Usage: "hint for the number of cpu cores to be used. 1 - number of cpu cores",
		},
		cli.BoolFlag{
			Name:  "stats, x",
			Usage: "show execution time and memory statistics",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:      "fields",
			Usage:     "Show fields in a file",
			ArgsUsage: "CSV_FILE_PATH",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					return NewExitError("table is not specified", 1)
				}

				table := c.Args().First()

				err := action.ShowFields(table)
				if err != nil {
					return NewExitError(err.Error(), 1)
				}

				return nil
			},
			OnUsageError: func(c *cli.Context, err error, isSubcommand bool) error {
				return NewExitError(fmt.Sprintf("Incorrect Usage: %s", err.Error()), 1)
			},
		},
		{
			Name:      "calc",
			Usage:     "Calculate a value from stdin",
			ArgsUsage: "\"expression\"",
			Action: func(c *cli.Context) error {
				if c.NArg() != 1 {
					return NewExitError("expression is empty", 1)
				}

				expr := c.Args().First()
				err := action.Calc(expr)
				if err != nil {
					return NewExitError(err.Error(), 1)
				}

				return nil
			},
			OnUsageError: func(c *cli.Context, err error, isSubcommand bool) error {
				return NewExitError(fmt.Sprintf("Incorrect Usage: %s", err.Error()), 1)
			},
		},
	}

	app.Before = func(c *cli.Context) error {
		err := setFlags(c)
		if err != nil {
			return NewExitError(err.Error(), 1)
		}
		return nil
	}

	app.Action = func(c *cli.Context) error {
		queryString, err := readQuery(c)
		if err != nil {
			return NewExitError(err.Error(), 1)
		}

		if len(queryString) < 1 {
			err = action.LaunchInteractiveShell()
		} else {
			err = action.Run(queryString, cmd.GetFlags().Source)
		}

		if err != nil {
			code := 1
			if apperr, ok := err.(query.AppError); ok {
				code = apperr.GetCode()
			} else if ex, ok := err.(*query.ForcedExit); ok {
				code = ex.GetCode()
			}
			return NewExitError(err.Error(), code)
		}

		return nil
	}

	app.Run(os.Args)
}

func readQuery(c *cli.Context) (string, error) {
	var queryString string

	flags := cmd.GetFlags()
	if 0 < len(flags.Source) {
		fp, err := os.Open(flags.Source)
		if err != nil {
			return queryString, err
		}
		defer fp.Close()

		buf, err := ioutil.ReadAll(fp)
		if err != nil {
			return queryString, err
		}
		queryString = string(buf)

	} else {
		if 1 < c.NArg() {
			return queryString, errors.New("multiple queries or statements were passed")
		}
		queryString = c.Args().First()
	}

	return queryString, nil
}

func setFlags(c *cli.Context) error {
	cmd.SetColor(c.GlobalBool("color"))

	if err := cmd.SetDelimiter(c.GlobalString("delimiter")); err != nil {
		return err
	}
	cmd.SetJsonQuery(c.GlobalString("json-query"))
	if err := cmd.SetEncoding(c.GlobalString("encoding")); err != nil {
		return err
	}
	if err := cmd.SetLineBreak(c.String("line-break")); err != nil {
		return err
	}
	if err := cmd.SetLocation(c.String("timezone")); err != nil {
		return err
	}
	if err := cmd.SetRepository(c.GlobalString("repository")); err != nil {
		return err
	}
	if err := cmd.SetSource(c.GlobalString("source")); err != nil {
		return err
	}
	cmd.SetDatetimeFormat(c.GlobalString("datetime-format"))
	cmd.SetWaitTimeout(c.GlobalFloat64("wait-timeout"))
	cmd.SetNoHeader(c.GlobalBool("no-header"))
	cmd.SetWithoutNull(c.GlobalBool("without-null"))

	if err := cmd.SetWriteEncoding(c.GlobalString("write-encoding")); err != nil {
		return err
	}
	if err := cmd.SetOut(c.GlobalString("out")); err != nil {
		return err
	}
	if err := cmd.SetFormat(c.GlobalString("format")); err != nil {
		return err
	}
	if err := cmd.SetWriteDelimiter(c.GlobalString("write-delimiter")); err != nil {
		return err
	}
	cmd.SetPrettyPrint(c.GlobalBool("pretty-print"))
	cmd.SetWithoutHeader(c.GlobalBool("without-header"))

	cmd.SetQuiet(c.GlobalBool("quiet"))
	cmd.SetCPU(c.GlobalInt("cpu"))
	cmd.SetStats(c.GlobalBool("stats"))

	return nil
}

func NewExitError(message string, code int) *cli.ExitError {
	return cli.NewExitError(color.Error(message), code)
}
<|endoftext|>


<commit_before>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

// +build go1.10

package main

import (
	"github.com/circonus-labs/circonus-agent/cmd"
	"github.com/circonus-labs/circonus-agent/internal/release"
)

func main() {
	cmd.Execute()
}

// defined during build (e.g. goreleaser, see .goreleaser.yml)
var (
	version = "dev"
	commit  = "none"
	date    = "unknown"
	tag     = ""
)

func init() {
	release.VERSION = version
	release.COMMIT = commit
	release.DATE = date
	release.TAG = tag
}
<commit_msg>upd: go1.11<commit_after>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

// +build go1.11

package main

import (
	"github.com/circonus-labs/circonus-agent/cmd"
	"github.com/circonus-labs/circonus-agent/internal/release"
)

func main() {
	cmd.Execute()
}

// defined during build (e.g. goreleaser, see .goreleaser.yml)
var (
	version = "dev"
	commit  = "none"
	date    = "unknown"
	tag     = ""
)

func init() {
	release.VERSION = version
	release.COMMIT = commit
	release.DATE = date
	release.TAG = tag
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"

	"github.com/alecthomas/kingpin"
	"github.com/getantibody/antibody/antibodylib"
	"github.com/getantibody/antibody/project"
	"github.com/getantibody/antibody/shell"
	"golang.org/x/crypto/ssh/terminal"
)

var (
	version = "dev"

	app         = kingpin.New("antibody", "The fastest shell plugin manager")
	parallelism = app.Flag("parallelism", "max amount of tasks to launch in parallel").
			Short('p').
			Default("4").
			Int()
	bundleCmd = app.Command("bundle", "downloads a bundle and prints its source line")
	bundles   = bundleCmd.Arg("bundles", "bundle list").Strings()
	updateCmd = app.Command("update", "updates all previously bundled bundles")
	homeCmd   = app.Command("home", "prints where antibody is cloning the bundles")
	purgeCmd  = app.Command("purge", "purges a bundle from your computer")
	purgee    = purgeCmd.Arg("bundle", "bundle to be purged").String()
	listCmd   = app.Command("list", "lists all currently instaled bundles").Alias("ls")
	initCmd   = app.Command("init", "initializes the shell so Antibody can work as expected")
)

func main() {
	app.Author("Carlos Alexandro Becker <caarlos0@gmail.com>")
	app.Version("antibody version " + version)
	app.VersionFlag.Short('v')
	app.HelpFlag.Short('h')

	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
	case bundleCmd.FullCommand():
		bundle()
	case updateCmd.FullCommand():
		update()
	case homeCmd.FullCommand():
		fmt.Println(antibodylib.Home())
	case purgeCmd.FullCommand():
		purge()
	case listCmd.FullCommand():
		list()
	case initCmd.FullCommand():
		sh, err := shell.Init()
		app.FatalIfError(err, "failed to init")
		fmt.Println(sh)
	}
}

func bundle() {
	var input io.Reader
	if !terminal.IsTerminal(int(os.Stdin.Fd())) && len(*bundles) == 0 {
		input = os.Stdin
	} else {
		input = bytes.NewBufferString(strings.Join(*bundles, " "))
	}
	sh, err := antibodylib.New(antibodylib.Home(), input, *parallelism).Bundle()
	app.FatalIfError(err, "failed to bundle")
	fmt.Println(sh)
}

func update() {
	var home = antibodylib.Home()
	fmt.Printf("Updating all bundles in %v...\n", home)
	var err = project.Update(home, *parallelism)
	app.FatalIfError(err, "failed to update")
}

func purge() {
	fmt.Println("Removing", *purgee)
	var err = os.RemoveAll(project.New(antibodylib.Home(), *purgee).Folder())
	app.FatalIfError(err, "failed to purge")
}

func list() {
	home := antibodylib.Home()
	projects, err := project.List(home)
	app.FatalIfError(err, "failed to list bundles")
	for _, b := range projects {
		fmt.Println(filepath.Join(home, b))
	}
}
<commit_msg>Revert "fixing parallelism to 4"<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"

	"github.com/alecthomas/kingpin"
	"github.com/getantibody/antibody/antibodylib"
	"github.com/getantibody/antibody/project"
	"github.com/getantibody/antibody/shell"
	"golang.org/x/crypto/ssh/terminal"
)

var (
	version = "dev"

	app         = kingpin.New("antibody", "The fastest shell plugin manager")
	parallelism = app.Flag("parallelism", "max amount of tasks to launch in parallel").
			Short('p').
			Default(strconv.Itoa(runtime.NumCPU())).
			Int()
	bundleCmd = app.Command("bundle", "downloads a bundle and prints its source line")
	bundles   = bundleCmd.Arg("bundles", "bundle list").Strings()
	updateCmd = app.Command("update", "updates all previously bundled bundles")
	homeCmd   = app.Command("home", "prints where antibody is cloning the bundles")
	purgeCmd  = app.Command("purge", "purges a bundle from your computer")
	purgee    = purgeCmd.Arg("bundle", "bundle to be purged").String()
	listCmd   = app.Command("list", "lists all currently instaled bundles").Alias("ls")
	initCmd   = app.Command("init", "initializes the shell so Antibody can work as expected")
)

func main() {
	app.Author("Carlos Alexandro Becker <caarlos0@gmail.com>")
	app.Version("antibody version " + version)
	app.VersionFlag.Short('v')
	app.HelpFlag.Short('h')

	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
	case bundleCmd.FullCommand():
		bundle()
	case updateCmd.FullCommand():
		update()
	case homeCmd.FullCommand():
		fmt.Println(antibodylib.Home())
	case purgeCmd.FullCommand():
		purge()
	case listCmd.FullCommand():
		list()
	case initCmd.FullCommand():
		sh, err := shell.Init()
		app.FatalIfError(err, "failed to init")
		fmt.Println(sh)
	}
}

func bundle() {
	var input io.Reader
	if !terminal.IsTerminal(int(os.Stdin.Fd())) && len(*bundles) == 0 {
		input = os.Stdin
	} else {
		input = bytes.NewBufferString(strings.Join(*bundles, " "))
	}
	sh, err := antibodylib.New(antibodylib.Home(), input, *parallelism).Bundle()
	app.FatalIfError(err, "failed to bundle")
	fmt.Println(sh)
}

func update() {
	var home = antibodylib.Home()
	fmt.Printf("Updating all bundles in %v...\n", home)
	var err = project.Update(home, *parallelism)
	app.FatalIfError(err, "failed to update")
}

func purge() {
	fmt.Println("Removing", *purgee)
	var err = os.RemoveAll(project.New(antibodylib.Home(), *purgee).Folder())
	app.FatalIfError(err, "failed to purge")
}

func list() {
	home := antibodylib.Home()
	projects, err := project.List(home)
	app.FatalIfError(err, "failed to list bundles")
	for _, b := range projects {
		fmt.Println(filepath.Join(home, b))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"net/http"

	"github.com/elazarl/go-bindata-assetfs"
	"github.com/golang/glog"

	"github.com/zefer/mothership/handlers"
	"github.com/zefer/mothership/mpd"
	"github.com/zefer/mothership/websocket"
)

var (
	client  *mpd.Client
	mpdAddr = flag.String("mpdaddr", "127.0.0.1:6600", "MPD address")
	port    = flag.String("port", ":8080", "listen port")
)

func main() {
	flag.Parse()
	glog.Infof("Starting API for MPD at %s.", *mpdAddr)

	// Send the browser the MPD state when they first connect.
	websocket.OnConnect(func(c *websocket.Conn) {
		b, err := mpdStatus()
		if err == nil {
			c.Send(b)
		}
	})

	// This watcher notifies us when MPD's state changes, without polling.
	watch := mpd.NewWatcher(*mpdAddr)
	defer watch.Close()
	// When mpd state changes, broadcast it to all websockets.
	watch.OnStateChange(func(s string) {
		glog.Info("MPD state change in subsystem: ", s)
		b, err := mpdStatus()
		if err != nil {
			glog.Errorln(err)
			return
		}
		websocket.Broadcast(b)
	})

	// This client connection provides an API to MPD's commands.
	client = mpd.NewClient(*mpdAddr)
	defer client.Close()

	http.HandleFunc("/websocket", websocket.Serve)
	http.Handle("/next", handlers.NextHandler(client.C))
	http.Handle("/previous", handlers.PreviousHandler(client.C))
	http.Handle("/play", handlers.PlayHandler(client.C))
	http.Handle("/pause", handlers.PauseHandler(client.C))
	http.Handle("/randomOn", handlers.RandomOnHandler(client.C))
	http.Handle("/randomOff", handlers.RandomOffHandler(client.C))
	http.Handle("/files", handlers.FileListHandler(client.C))
	http.Handle("/playlist", handlers.PlayListHandler(client.C))
	http.Handle("/library/updated", handlers.LibraryUpdateHandler(client.C))

	// The front-end assets are served from a go-bindata file.
	http.Handle("/", http.FileServer(&assetfs.AssetFS{Asset, AssetDir, ""}))

	glog.Infof("Listening on %s.", *port)
	err := http.ListenAndServe(*port, nil)
	if err != nil {
		glog.Errorf("http.ListenAndServe %s failed: %s", *port, err)
		return
	}
}

func mpdStatus() ([]byte, error) {
	data, err := client.C.Status()
	if err != nil {
		return nil, err
	}
	song, err := client.C.CurrentSong()
	if err != nil {
		return nil, err
	}
	for k, v := range song {
		data[k] = v
	}
	b, err := json.Marshal(data)
	return b, err
}
<commit_msg>Fix issue raised by `go vet` in assetfs usage<commit_after>package main

import (
	"encoding/json"
	"flag"
	"net/http"

	assetfs "github.com/elazarl/go-bindata-assetfs"
	"github.com/golang/glog"

	"github.com/zefer/mothership/handlers"
	"github.com/zefer/mothership/mpd"
	"github.com/zefer/mothership/websocket"
)

var (
	client  *mpd.Client
	mpdAddr = flag.String("mpdaddr", "127.0.0.1:6600", "MPD address")
	port    = flag.String("port", ":8080", "listen port")
)

func main() {
	flag.Parse()
	glog.Infof("Starting API for MPD at %s.", *mpdAddr)

	// Send the browser the MPD state when they first connect.
	websocket.OnConnect(func(c *websocket.Conn) {
		b, err := mpdStatus()
		if err == nil {
			c.Send(b)
		}
	})

	// This watcher notifies us when MPD's state changes, without polling.
	watch := mpd.NewWatcher(*mpdAddr)
	defer watch.Close()
	// When mpd state changes, broadcast it to all websockets.
	watch.OnStateChange(func(s string) {
		glog.Info("MPD state change in subsystem: ", s)
		b, err := mpdStatus()
		if err != nil {
			glog.Errorln(err)
			return
		}
		websocket.Broadcast(b)
	})

	// This client connection provides an API to MPD's commands.
	client = mpd.NewClient(*mpdAddr)
	defer client.Close()

	http.HandleFunc("/websocket", websocket.Serve)
	http.Handle("/next", handlers.NextHandler(client.C))
	http.Handle("/previous", handlers.PreviousHandler(client.C))
	http.Handle("/play", handlers.PlayHandler(client.C))
	http.Handle("/pause", handlers.PauseHandler(client.C))
	http.Handle("/randomOn", handlers.RandomOnHandler(client.C))
	http.Handle("/randomOff", handlers.RandomOffHandler(client.C))
	http.Handle("/files", handlers.FileListHandler(client.C))
	http.Handle("/playlist", handlers.PlayListHandler(client.C))
	http.Handle("/library/updated", handlers.LibraryUpdateHandler(client.C))

	// The front-end assets are served from a go-bindata file.
	http.Handle("/", http.FileServer(&assetfs.AssetFS{
		Asset: Asset, AssetDir: AssetDir, Prefix: "",
	}))

	glog.Infof("Listening on %s.", *port)
	err := http.ListenAndServe(*port, nil)
	if err != nil {
		glog.Errorf("http.ListenAndServe %s failed: %s", *port, err)
		return
	}
}

func mpdStatus() ([]byte, error) {
	data, err := client.C.Status()
	if err != nil {
		return nil, err
	}
	song, err := client.C.CurrentSong()
	if err != nil {
		return nil, err
	}
	for k, v := range song {
		data[k] = v
	}
	b, err := json.Marshal(data)
	return b, err
}
<|endoftext|>


<commit_before>package proksi

import (
	"bufio"
	"bytes"
	"io/ioutil"
	"net"
	"os"
	"strings"
	"time"
	"fmt"
)

//Alive stands for boolean whether the proxy responded in Resolve function.
//ResponseTime is time it took for the instance to respond.
//Address is (for now) a string representing the IP address of the proxy to be connected.
type Proxy struct {
	Alive        bool
	ResponseTime time.Duration
	Address      string
}

//Resolve makes TCP connection to given host with given timeout.
//The function broadcasts to given channel about the response of the connection.
//Even if the connection is refused or it times out, the channel will receive
//new proxy instance with filled fields.
func Resolve(status chan Proxy, host string, timeout time.Duration) {

	var proxy Proxy
	proxy.Address = host

	t0 := time.Now()
	_, err := net.DialTimeout("tcp", host, timeout)
	if err != nil {
		proxy.ResponseTime = time.Now().Sub(t0)
		proxy.Alive = false
		status <- proxy
		return
	}

	proxy.ResponseTime = time.Now().Sub(t0)
	proxy.Alive = true
	status <- proxy
	return
}

//Same as Resolve function, but takes in extra parameter which defines what HTTP site the
//proxy will attempt to connect with HEAD. The timeout in both TCP and HTTP connections are the same.
//Useful for checking whether a proxy is busy or not.
func ResolveAndWrite(status chan Proxy, host string, timeout time.Duration, endpoint string) {

	var proxy Proxy
	proxy.Address = host

	t0 := time.Now()
	conn, err := net.DialTimeout("tcp", host, timeout)
	if err != nil {
		proxy.ResponseTime = time.Now().Sub(t0)
		proxy.Alive = false
		status <- proxy
		return
	}

	conn.SetReadDeadline(time.Now().Add(timeout))
	fmt.Fprintf(conn, "HEAD "+ endpoint +" HTTP/1.0\r\n\r\n")
	_, err = bufio.NewReader(conn).ReadString('\n')
	if err != nil {
		proxy.ResponseTime = time.Now().Sub(t0)
		proxy.Alive = false
		status <- proxy
		return
	}

	proxy.ResponseTime = time.Now().Sub(t0)
	proxy.Alive = true
	status <- proxy
	return
}

//ReadFile returns string array of IP addresses in a file. It uses scanner.Scan()
//to parse IP's from the given file.
func ReadFile(filename string) ([]string, error) {

	var proxies []string
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return proxies, err
	}

	scanner := bufio.NewScanner(strings.NewReader(string(data)))
	for scanner.Scan() {
		proxies = append(proxies, scanner.Text())
	}
	if err := scanner.Err(); err != nil {
		return proxies, err
	}

	return proxies, nil
}

//WriteFile writes given buffer to given filename. It creates the file
//it is not yet created. The created file uses 0600 permissions by default.
func WriteFile(filename string, buffer bytes.Buffer) error {

	f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		return err
	}

	defer f.Close()
	if _, err = f.WriteString(buffer.String()); err != nil {
		return err
	}

	return nil
}
<commit_msg>doc: fix documentation syntax for godoc, go fmt<commit_after>package proksi

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"strings"
	"time"
)

// Alive stands for boolean whether the proxy responded in Resolve function.
// ResponseTime is time it took for the instance to respond.
// Address is (for now) a string representing the IP address of the proxy to be connected.
type Proxy struct {
	Alive        bool
	ResponseTime time.Duration
	Address      string
}

// Resolve makes TCP connection to given host with given timeout.
// The function broadcasts to given channel about the response of the connection.
// Even if the connection is refused or it times out, the channel will receive
// new proxy instance with filled fields.
func Resolve(status chan Proxy, host string, timeout time.Duration) {

	var proxy Proxy
	proxy.Address = host

	t0 := time.Now()
	_, err := net.DialTimeout("tcp", host, timeout)
	if err != nil {
		proxy.ResponseTime = time.Now().Sub(t0)
		proxy.Alive = false
		status <- proxy
		return
	}

	proxy.ResponseTime = time.Now().Sub(t0)
	proxy.Alive = true
	status <- proxy
	return
}

// Same as Resolve function, but takes in extra parameter which defines what HTTP site the
// proxy will attempt to connect with HEAD. The timeout in both TCP and HTTP connections are the same.
// Useful for checking whether a proxy is busy or not.
func ResolveAndWrite(status chan Proxy, host string, timeout time.Duration, endpoint string) {

	var proxy Proxy
	proxy.Address = host

	t0 := time.Now()
	conn, err := net.DialTimeout("tcp", host, timeout)
	if err != nil {
		proxy.ResponseTime = time.Now().Sub(t0)
		proxy.Alive = false
		status <- proxy
		return
	}

	conn.SetReadDeadline(time.Now().Add(timeout))
	fmt.Fprintf(conn, "HEAD "+endpoint+" HTTP/1.0\r\n\r\n")
	_, err = bufio.NewReader(conn).ReadString('\n')
	if err != nil {
		proxy.ResponseTime = time.Now().Sub(t0)
		proxy.Alive = false
		status <- proxy
		return
	}

	proxy.ResponseTime = time.Now().Sub(t0)
	proxy.Alive = true
	status <- proxy
	return
}

// ReadFile returns string array of IP addresses in a file. It uses scanner.Scan()
// to parse IP's from the given file.
func ReadFile(filename string) ([]string, error) {

	var proxies []string
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return proxies, err
	}

	scanner := bufio.NewScanner(strings.NewReader(string(data)))
	for scanner.Scan() {
		proxies = append(proxies, scanner.Text())
	}
	if err := scanner.Err(); err != nil {
		return proxies, err
	}

	return proxies, nil
}

// WriteFile writes given buffer to given filename. It creates the file
// it is not yet created. The created file uses 0600 permissions by default.
func WriteFile(filename string, buffer bytes.Buffer) error {

	f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		return err
	}

	defer f.Close()
	if _, err = f.WriteString(buffer.String()); err != nil {
		return err
	}

	return nil
}
<|endoftext|>