<commit_before>package main

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

	"time"

	"strings"

	"syscall"

	"os/signal"

	"github.com/claudetech/loggo"
	. "github.com/claudetech/loggo/default"
	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")
	argTempPath := flag.StringP("temp", "t", os.TempDir(), "Path to a temporary directory to store temporary data")
	argMongoURL := flag.StringP("mongo-host", "m", "localhost", "MongoDB host")
	argMongoUser := flag.String("mongo-user", "", "MongoDB username")
	argMongoPass := flag.String("mongo-password", "", "MongoDB password")
	argMongoDatabase := flag.String("mongo-database", "plexdrive", "MongoDB database")
	argChunkSize := flag.String("chunk-size", "5M", "The size of each chunk that is downloaded (units: B, K, M, G)")
	argRefreshInterval := flag.Duration("refresh-interval", 5*time.Minute, "The time to wait till checking for changes")
	argClearInterval := flag.Duration("clear-chunk-interval", 1*time.Minute, "The time to wait till clearing the chunk directory")
	argClearChunkAge := flag.Duration("clear-chunk-age", 30*time.Minute, "The maximum age of a cached chunk file")
	argClearChunkMaxSize := flag.String("clear-chunk-max-size", "", "The maximum size of the temporary chunk directory (units: B, K, M, G)")
	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("4.0.0")
		return
	}

	// check if mountpoint is specified
	argMountPoint := flag.Arg(0)
	if "" == argMountPoint {
		flag.Usage()
		fmt.Println()
		panic(fmt.Errorf("Mountpoint not specified"))
	}
	if "" == *argMongoURL {
		flag.Usage()
		fmt.Println()
		panic(fmt.Errorf("MongoDB URL not specified"))
	}
	if "" == *argMongoDatabase {
		flag.Usage()
		fmt.Println()
		panic(fmt.Errorf("MongoDB database 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("temp                 : %v", *argTempPath)
	Log.Debugf("mongo-host           : %v", *argMongoURL)
	Log.Debugf("mongo-user           : %v", *argMongoUser)
	Log.Debugf("mongo-password       : %v", *argMongoPass)
	Log.Debugf("mongo-database       : %v", *argMongoDatabase)
	Log.Debugf("chunk-size           : %v", *argChunkSize)
	Log.Debugf("refresh-interval     : %v", *argRefreshInterval)
	Log.Debugf("clear-chunk-interval : %v", *argClearInterval)
	Log.Debugf("clear-chunk-age      : %v", *argClearChunkAge)
	Log.Debugf("clear-chunk-max-size : %v", *argClearChunkMaxSize)
	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)
	}
	chunkPath := filepath.Join(*argTempPath, "chunks")

	// set the global buffer configuration
	SetChunkPath(chunkPath)
	chunkSize, err := parseSizeArg(*argChunkSize)
	if nil != err {
		Log.Errorf("%v", err)
		os.Exit(2)
	}
	SetChunkSize(chunkSize)
	clearMaxChunkSize, err := parseSizeArg(*argClearChunkMaxSize)
	if nil != err {
		Log.Errorf("%v", err)
		os.Exit(2)
	}
	SetChunkDirMaxSize(clearMaxChunkSize)
	downloadSpeedLimit, err := parseSizeArg(*argDownloadSpeedLimit)
	if nil != err {
		Log.Errorf("%v", err)
		os.Exit(2)
	}
	SetDownloadSpeedLimit(downloadSpeedLimit)

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

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

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

	// check os signals like SIGINT/TERM
	checkOsSignals(argMountPoint)
	go CleanChunkDir(chunkPath, *argClearInterval, *argClearChunkAge, clearMaxChunkSize)
	if err := Mount(drive, argMountPoint, mountOptions, uid, gid, umask); nil != err {
		Log.Debugf("%v", err)
		os.Exit(5)
	}
}

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 := 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>upgraded version<commit_after>package main

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

	"time"

	"strings"

	"syscall"

	"os/signal"

	"github.com/claudetech/loggo"
	. "github.com/claudetech/loggo/default"
	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")
	argTempPath := flag.StringP("temp", "t", os.TempDir(), "Path to a temporary directory to store temporary data")
	argMongoURL := flag.StringP("mongo-host", "m", "localhost", "MongoDB host")
	argMongoUser := flag.String("mongo-user", "", "MongoDB username")
	argMongoPass := flag.String("mongo-password", "", "MongoDB password")
	argMongoDatabase := flag.String("mongo-database", "plexdrive", "MongoDB database")
	argChunkSize := flag.String("chunk-size", "5M", "The size of each chunk that is downloaded (units: B, K, M, G)")
	argRefreshInterval := flag.Duration("refresh-interval", 5*time.Minute, "The time to wait till checking for changes")
	argClearInterval := flag.Duration("clear-chunk-interval", 1*time.Minute, "The time to wait till clearing the chunk directory")
	argClearChunkAge := flag.Duration("clear-chunk-age", 30*time.Minute, "The maximum age of a cached chunk file")
	argClearChunkMaxSize := flag.String("clear-chunk-max-size", "", "The maximum size of the temporary chunk directory (units: B, K, M, G)")
	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("4.1.0-beta")
		return
	}

	// check if mountpoint is specified
	argMountPoint := flag.Arg(0)
	if "" == argMountPoint {
		flag.Usage()
		fmt.Println()
		panic(fmt.Errorf("Mountpoint not specified"))
	}
	if "" == *argMongoURL {
		flag.Usage()
		fmt.Println()
		panic(fmt.Errorf("MongoDB URL not specified"))
	}
	if "" == *argMongoDatabase {
		flag.Usage()
		fmt.Println()
		panic(fmt.Errorf("MongoDB database 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("temp                 : %v", *argTempPath)
	Log.Debugf("mongo-host           : %v", *argMongoURL)
	Log.Debugf("mongo-user           : %v", *argMongoUser)
	Log.Debugf("mongo-password       : %v", *argMongoPass)
	Log.Debugf("mongo-database       : %v", *argMongoDatabase)
	Log.Debugf("chunk-size           : %v", *argChunkSize)
	Log.Debugf("refresh-interval     : %v", *argRefreshInterval)
	Log.Debugf("clear-chunk-interval : %v", *argClearInterval)
	Log.Debugf("clear-chunk-age      : %v", *argClearChunkAge)
	Log.Debugf("clear-chunk-max-size : %v", *argClearChunkMaxSize)
	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)
	}
	chunkPath := filepath.Join(*argTempPath, "chunks")

	// set the global buffer configuration
	SetChunkPath(chunkPath)
	chunkSize, err := parseSizeArg(*argChunkSize)
	if nil != err {
		Log.Errorf("%v", err)
		os.Exit(2)
	}
	SetChunkSize(chunkSize)
	clearMaxChunkSize, err := parseSizeArg(*argClearChunkMaxSize)
	if nil != err {
		Log.Errorf("%v", err)
		os.Exit(2)
	}
	SetChunkDirMaxSize(clearMaxChunkSize)
	downloadSpeedLimit, err := parseSizeArg(*argDownloadSpeedLimit)
	if nil != err {
		Log.Errorf("%v", err)
		os.Exit(2)
	}
	SetDownloadSpeedLimit(downloadSpeedLimit)

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

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

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

	// check os signals like SIGINT/TERM
	checkOsSignals(argMountPoint)
	go CleanChunkDir(chunkPath, *argClearInterval, *argClearChunkAge, clearMaxChunkSize)
	if err := Mount(drive, argMountPoint, mountOptions, uid, gid, umask); nil != err {
		Log.Debugf("%v", err)
		os.Exit(5)
	}
}

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 := 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
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
)

const PORT = "2525"

func main() {
	server := createServer(PORT)

	fmt.Println("Listening on port %s", PORT)

	defer server.Close()

	for {
		conn, err := server.Accept()

		if err != nil {
			log.Fatalf("Error accepting: %v\n", err)
		}

		go handleConnection(conn)
	}
}

func createServer(port string) (net.Listener) {
	server, err := net.Listen("tcp", ":" + PORT)

	if err != nil {
		log.Fatalf("Error listening to port %s\n", PORT)
	}

	return server
}

func handleConnection(conn net.Conn) {
	defer conn.Close()

	conn.Write([]byte("220 OK\n"))

	buffer := bufio.NewReader(conn)

	for {
		str, _ := buffer.ReadString('\n')

		if str == "DATA\r\n" {
			break
		}

		conn.Write([]byte("250 OK\n"))
	}

	conn.Write([]byte("354 OK\n"))

	buffer = bufio.NewReader(conn)

	fmt.Println("---")

	for {
		str, _ := buffer.ReadString('\n')

		if str == ".\r\n" {
			break
		}

		fmt.Print(str)
	}

	fmt.Println("")

	conn.Write([]byte("250 OK\n"))
	conn.Write([]byte("221 OK\n"))
}
<commit_msg>Fix welcome message.<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
)

const PORT = "2525"

func main() {
	server := createServer(PORT)

	fmt.Println("Listening on port", PORT)

	defer server.Close()

	for {
		conn, err := server.Accept()

		if err != nil {
			log.Fatalf("Error accepting: %v\n", err)
		}

		go handleConnection(conn)
	}
}

func createServer(port string) (net.Listener) {
	server, err := net.Listen("tcp", ":" + PORT)

	if err != nil {
		log.Fatalf("Error listening to port %s\n", PORT)
	}

	return server
}

func handleConnection(conn net.Conn) {
	defer conn.Close()

	conn.Write([]byte("220 OK\n"))

	buffer := bufio.NewReader(conn)

	for {
		str, _ := buffer.ReadString('\n')

		if str == "DATA\r\n" {
			break
		}

		conn.Write([]byte("250 OK\n"))
	}

	conn.Write([]byte("354 OK\n"))

	buffer = bufio.NewReader(conn)

	fmt.Println("---")

	for {
		str, _ := buffer.ReadString('\n')

		if str == ".\r\n" {
			break
		}

		fmt.Print(str)
	}

	fmt.Println("")

	conn.Write([]byte("250 OK\n"))
	conn.Write([]byte("221 OK\n"))
}
<|endoftext|>


<commit_before>package main

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

var (
	pipeOutput *bool = flag.Bool("pipeOutput", false, "If true, output will be piped to STDOUT (default: false)")
	pipeErr    *bool = flag.Bool("pipeErr", false, "If true, error output will be piped to STDERR (default: false)")
	wait       *bool = flag.Bool("wait", false, "If true, baka will wait for app to complete before exiting (default: false)")
)

func main() {
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(1)
	}
	var cmd *exec.Cmd
	if flag.NArg() > 1 {
		cmd = exec.Command(flag.Arg(0), flag.Args()[1:]...)
	} else {
		cmd = exec.Command(flag.Arg(0))
	}

	cmd.Stdin = os.Stdin
	if *pipeOutput {
		cmd.Stdout = os.Stdout
	}
	if *pipeErr {
		cmd.Stderr = os.Stderr
	}
	var err error
	if *wait {
		err = cmd.Run()
	} else {
		err = cmd.Start()
	}
	if err != nil {
		fmt.Println(err)
		os.Exit(100)
	}

	if !*wait {
		fmt.Printf("[%d]\n", cmd.Process.Pid)
	}
}

func usage() {
	fmt.Println("Usage: baka <app> [args...]")
	flag.PrintDefaults()
}
<commit_msg>added license header to main.go<commit_after>/*
The MIT License (MIT)

Copyright (c) 2016 Jon Bonazza

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

package main

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

var (
	pipeOutput *bool = flag.Bool("pipeOutput", false, "If true, output will be piped to STDOUT (default: false)")
	pipeErr    *bool = flag.Bool("pipeErr", false, "If true, error output will be piped to STDERR (default: false)")
	wait       *bool = flag.Bool("wait", false, "If true, baka will wait for app to complete before exiting (default: false)")
)

func main() {
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(1)
	}
	var cmd *exec.Cmd
	if flag.NArg() > 1 {
		cmd = exec.Command(flag.Arg(0), flag.Args()[1:]...)
	} else {
		cmd = exec.Command(flag.Arg(0))
	}

	cmd.Stdin = os.Stdin
	if *pipeOutput {
		cmd.Stdout = os.Stdout
	}
	if *pipeErr {
		cmd.Stderr = os.Stderr
	}
	var err error
	if *wait {
		err = cmd.Run()
	} else {
		err = cmd.Start()
	}
	if err != nil {
		fmt.Println(err)
		os.Exit(100)
	}

	if !*wait {
		fmt.Printf("[%d]\n", cmd.Process.Pid)
	}
}

func usage() {
	fmt.Println("Usage: baka <app> [args...]")
	flag.PrintDefaults()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/optiopay/klar/clair"
	"github.com/optiopay/klar/docker"
)

var priorities = []string{"Unknown", "Negligible", "Low", "Medium", "High", "Critical", "Defcon1"}
var store = make(map[string][]clair.Vulnerability)

func main() {
	if len(os.Args) != 2 {
		fmt.Printf("Image name must be provided")
		os.Exit(1)
	}

	clairAddr := os.Getenv("CLAIR_ADDR")
	if clairAddr == "" {
		clairAddr = "https://clair-staging.optiopay.com"
	}

	threshold := 0
	thresholdStr := os.Getenv("CLAIR_THRESHOLD")
	if thresholdStr != "" {
		threshold, _ = strconv.Atoi(thresholdStr)
	}

	dockerUser := os.Getenv("DOCKER_USER")
	dockerPassword := os.Getenv("DOCKER_PASSWORD")

	image, err := docker.NewImage(os.Args[1], dockerUser, dockerPassword)
	if err != nil {
		fmt.Printf("Can't parse qname: %s", err)
		os.Exit(1)
	}

	err = image.Pull()
	if err != nil {
		fmt.Printf("Can't pull image: %s", err)
		os.Exit(1)
	}
	if len(image.FsLayers) == 0 {
		fmt.Printf("Can't pull fsLayers")
		os.Exit(1)
	} else {
		fmt.Printf("Analysing %d layers\n", len(image.FsLayers))
	}

	c := clair.NewClair(clairAddr)
	vs := c.Analyse(image)
	groupBySeverity(vs)
	fmt.Printf("Found %d vulnerabilities \n", len(vs))
	highSevNumber := len(store["High"]) + len(store["Critical"]) + len(store["Defcon1"])

	iteratePriorities(func(sev string) {
		for _, v := range store[sev] {
			fmt.Printf("%s: [%s] \n%s\n%s\n", v.Name, v.Severity, v.Description, v.Link)
			fmt.Println("-----------------------------------------")
		}
	})
	iteratePriorities(func(sev string) { fmt.Printf("%s: %d\n", sev, len(store[sev])) })

	if highSevNumber > threshold {
		os.Exit(1)
	}
}

func iteratePriorities(f func(sev string)) {
	for _, sev := range priorities {
		if len(store[sev]) != 0 {
			f(sev)
		}
	}

}

func groupBySeverity(vs []clair.Vulnerability) {
	for _, v := range vs {
		sevRow := vulnsBy(v.Severity, store)
		store[v.Severity] = append(sevRow, v)
	}
}

func vulnsBy(sev string, store map[string][]clair.Vulnerability) []clair.Vulnerability {
	items, found := store[sev]
	if !found {
		items = make([]clair.Vulnerability, 0)
		store[sev] = items
	}
	return items
}
<commit_msg>Fail when clair address is not set<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/optiopay/klar/clair"
	"github.com/optiopay/klar/docker"
)

var priorities = []string{"Unknown", "Negligible", "Low", "Medium", "High", "Critical", "Defcon1"}
var store = make(map[string][]clair.Vulnerability)

func main() {
	if len(os.Args) != 2 {
		fmt.Printf("Image name must be provided")
		os.Exit(1)
	}

	clairAddr := os.Getenv("CLAIR_ADDR")
	if clairAddr == "" {
		fmt.Printf("Clair address must be provided")
		os.Exit(1)
	}

	threshold := 0
	thresholdStr := os.Getenv("CLAIR_THRESHOLD")
	if thresholdStr != "" {
		threshold, _ = strconv.Atoi(thresholdStr)
	}

	dockerUser := os.Getenv("DOCKER_USER")
	dockerPassword := os.Getenv("DOCKER_PASSWORD")

	image, err := docker.NewImage(os.Args[1], dockerUser, dockerPassword)
	if err != nil {
		fmt.Printf("Can't parse qname: %s", err)
		os.Exit(1)
	}

	err = image.Pull()
	if err != nil {
		fmt.Printf("Can't pull image: %s", err)
		os.Exit(1)
	}
	if len(image.FsLayers) == 0 {
		fmt.Printf("Can't pull fsLayers")
		os.Exit(1)
	} else {
		fmt.Printf("Analysing %d layers\n", len(image.FsLayers))
	}

	c := clair.NewClair(clairAddr)
	vs := c.Analyse(image)
	groupBySeverity(vs)
	fmt.Printf("Found %d vulnerabilities \n", len(vs))
	highSevNumber := len(store["High"]) + len(store["Critical"]) + len(store["Defcon1"])

	iteratePriorities(func(sev string) {
		for _, v := range store[sev] {
			fmt.Printf("%s: [%s] \n%s\n%s\n", v.Name, v.Severity, v.Description, v.Link)
			fmt.Println("-----------------------------------------")
		}
	})
	iteratePriorities(func(sev string) { fmt.Printf("%s: %d\n", sev, len(store[sev])) })

	if highSevNumber > threshold {
		os.Exit(1)
	}
}

func iteratePriorities(f func(sev string)) {
	for _, sev := range priorities {
		if len(store[sev]) != 0 {
			f(sev)
		}
	}

}

func groupBySeverity(vs []clair.Vulnerability) {
	for _, v := range vs {
		sevRow := vulnsBy(v.Severity, store)
		store[v.Severity] = append(sevRow, v)
	}
}

func vulnsBy(sev string, store map[string][]clair.Vulnerability) []clair.Vulnerability {
	items, found := store[sev]
	if !found {
		items = make([]clair.Vulnerability, 0)
		store[sev] = items
	}
	return items
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"runtime"
	"strconv"
	"sync"

	"github.com/mattn/go-tty"
	"github.com/pkg/browser"
)

type ActionType int

const (
	LABEL_AS_POSITIVE ActionType = iota
	LABEL_AS_NEGATIVE
	SAVE
	HELP
	SKIP
	EXIT
)

func input2ActionType() (ActionType, error) {
	t, err := tty.Open()
	defer t.Close()
	if err != nil {
		return EXIT, err
	}
	var r rune
	for r == 0 {
		r, err = t.ReadRune()
		if err != nil {
			return SKIP, err
		}
	}
	switch r {
	case 'p':
		return LABEL_AS_POSITIVE, nil
	case 'n':
		return LABEL_AS_NEGATIVE, nil
	case 's':
		return SAVE, nil
	case 'h':
		return HELP, nil
	case 'e':
		return EXIT, nil
	default:
		return SKIP, nil
	}
}

func main() {
	cacheFilename := "cache.bin"

	cache, _ := LoadCache(cacheFilename)
	examples, _ := ReadExamples(os.Args[1])

	outputFilename := os.Args[2]
	shuffle(examples)

	wg := &sync.WaitGroup{}
	cpus := runtime.NumCPU()
	runtime.GOMAXPROCS(cpus)
	sem := make(chan struct{}, cpus)
	for idx, e := range examples {
		wg.Add(1)
		sem <- struct{}{}
		go func(e *Example, idx int) {
			defer wg.Done()
			if example, ok := cache.Cache[e.Url]; ok {
				e.Title = example.Title
				e.Description = example.Description
				e.Body = example.Body
				e.RawHTML = example.RawHTML
			} else {
				article := GetArticle(e.Url)
				fmt.Println("Fetching(" + strconv.Itoa(idx) + "): " + e.Url)
				e.Title = article.Title
				e.Description = article.Description
				e.Body = article.Body
				e.RawHTML = article.RawHTML
				cache.Add(*e)
			}
			e.Fv = removeDuplicate(ExtractFeatures(*e))
			<-sem
		}(e, idx)
	}
	wg.Wait()

	model := TrainedModel(examples)

annotationLoop:
	for {
		unlabeledExamples := model.SortByScore(examples)
		if len(unlabeledExamples) == 0 {
			break
		}
		e := unlabeledExamples[0]
		if e == nil {
			break
		}
		fmt.Println("Label this example (Score: " + fmt.Sprintf("%0.03f", e.Score) + "): " + e.Url + " (" + e.Title + ")")
		browser.OpenURL(e.Url)
		cache.Add(*e)

		act, err := input2ActionType()
		if err != nil {
			return
		}
		switch act {
		case LABEL_AS_POSITIVE:
			fmt.Println("Labeled as positive")
			e.Annotate(POSITIVE)
		case LABEL_AS_NEGATIVE:
			fmt.Println("Labeled as negative")
			e.Annotate(NEGATIVE)
		case SKIP:
			fmt.Println("Skiped this example")
			continue
		case SAVE:
			fmt.Println("Saved labeld examples")
			WriteExamples(examples, outputFilename)
		case HELP:
			fmt.Println("ToDo: SHOW HELP")
		case EXIT:
			fmt.Println("EXIT")
			break annotationLoop
		default:
			break annotationLoop
		}
		model = TrainedModel(examples)
	}

	WriteExamples(examples, outputFilename)
	cache.Save(cacheFilename)
}
<commit_msg>cliで引数コントロール<commit_after>package main

import (
	"fmt"
	"os"
	"runtime"
	"strconv"
	"sync"

	"github.com/codegangsta/cli"
	"github.com/mattn/go-tty"
	"github.com/pkg/browser"
)

type ActionType int

const (
	LABEL_AS_POSITIVE ActionType = iota
	LABEL_AS_NEGATIVE
	SAVE
	HELP
	SKIP
	EXIT
)

func input2ActionType() (ActionType, error) {
	t, err := tty.Open()
	defer t.Close()
	if err != nil {
		return EXIT, err
	}
	var r rune
	for r == 0 {
		r, err = t.ReadRune()
		if err != nil {
			return SKIP, err
		}
	}
	switch r {
	case 'p':
		return LABEL_AS_POSITIVE, nil
	case 'n':
		return LABEL_AS_NEGATIVE, nil
	case 's':
		return SAVE, nil
	case 'h':
		return HELP, nil
	case 'e':
		return EXIT, nil
	default:
		return SKIP, nil
	}
}

func doAnnotate(c *cli.Context) error {
	inputFilename := c.String("input-filename")
	outputFilename := c.String("output-filename")

	if inputFilename == "" {
		_ = cli.ShowCommandHelp(c, "annotate")
		return cli.NewExitError("`input-filename` is a required field.", 1)
	}

	if outputFilename == "" {
		_ = cli.ShowCommandHelp(c, "annotate")
		return cli.NewExitError("`output-filename` is a required field.", 1)
	}

	cacheFilename := "cache.bin"

	cache, _ := LoadCache(cacheFilename)
	examples, _ := ReadExamples(inputFilename)

	shuffle(examples)

	wg := &sync.WaitGroup{}
	cpus := runtime.NumCPU()
	runtime.GOMAXPROCS(cpus)
	sem := make(chan struct{}, cpus)
	for idx, e := range examples {
		wg.Add(1)
		sem <- struct{}{}
		go func(e *Example, idx int) {
			defer wg.Done()
			if example, ok := cache.Cache[e.Url]; ok {
				e.Title = example.Title
				e.Description = example.Description
				e.Body = example.Body
				e.RawHTML = example.RawHTML
			} else {
				article := GetArticle(e.Url)
				fmt.Println("Fetching(" + strconv.Itoa(idx) + "): " + e.Url)
				e.Title = article.Title
				e.Description = article.Description
				e.Body = article.Body
				e.RawHTML = article.RawHTML
				cache.Add(*e)
			}
			e.Fv = removeDuplicate(ExtractFeatures(*e))
			<-sem
		}(e, idx)
	}
	wg.Wait()

	model := TrainedModel(examples)

annotationLoop:
	for {
		unlabeledExamples := model.SortByScore(examples)
		if len(unlabeledExamples) == 0 {
			break
		}
		e := unlabeledExamples[0]
		if e == nil {
			break
		}
		fmt.Println("Label this example (Score: " + fmt.Sprintf("%0.03f", e.Score) + "): " + e.Url + " (" + e.Title + ")")
		browser.OpenURL(e.Url)
		cache.Add(*e)

		act, err := input2ActionType()
		if err != nil {
			return err
		}
		switch act {
		case LABEL_AS_POSITIVE:
			fmt.Println("Labeled as positive")
			e.Annotate(POSITIVE)
		case LABEL_AS_NEGATIVE:
			fmt.Println("Labeled as negative")
			e.Annotate(NEGATIVE)
		case SKIP:
			fmt.Println("Skiped this example")
			continue
		case SAVE:
			fmt.Println("Saved labeld examples")
			WriteExamples(examples, outputFilename)
		case HELP:
			fmt.Println("ToDo: SHOW HELP")
		case EXIT:
			fmt.Println("EXIT")
			break annotationLoop
		default:
			break annotationLoop
		}
		model = TrainedModel(examples)
	}

	WriteExamples(examples, outputFilename)
	cache.Save(cacheFilename)

	return nil
}

var commandAnnotate = cli.Command{
	Name:  "annotate",
	Usage: "Annotate URLs",
	Description: `
Annotate URLs using active learning.
`,
	Action: doAnnotate,
	Flags: []cli.Flag{
		cli.StringFlag{Name: "input-filename"},
		cli.StringFlag{Name: "output-filename"},
	},
}

var Commands = []cli.Command{
	commandAnnotate,
}

func main() {
	app := cli.NewApp()
	app.Name = "go-active-learning"
	app.Commands = Commands

	app.Run(os.Args)
}
<|endoftext|>


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

package main

import (
	"errors"
	"log"
	"net/http"
	"os"
	"os/signal"
	"regexp"
	"runtime"
	"runtime/pprof"
	"strings"
	"syscall"
	"time"

	"github.com/codegangsta/cli"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/tsuru/planb/backend"
	"github.com/tsuru/planb/reverseproxy"
	"github.com/tsuru/planb/router"
	"github.com/tsuru/planb/tls"
)

func handleSignals(server interface {
	Stop()
}) {
	sigChan := make(chan os.Signal, 3)
	go func() {
		for sig := range sigChan {
			if sig == os.Interrupt || sig == os.Kill {
				server.Stop()
			}
			if sig == syscall.SIGUSR1 {
				pprof.Lookup("goroutine").WriteTo(os.Stdout, 2)
			}
			if sig == syscall.SIGUSR2 {
				go startProfiling()
			}
		}
	}()
	signal.Notify(sigChan, os.Interrupt, os.Kill, syscall.SIGUSR1, syscall.SIGUSR2)
}

func startProfiling() {
	cpufile, _ := os.OpenFile("./planb_cpu.pprof", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660)
	memfile, _ := os.OpenFile("./planb_mem.pprof", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660)
	lockfile, _ := os.OpenFile("./planb_lock.pprof", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660)
	log.Println("enabling profile...")
	runtime.GC()
	pprof.WriteHeapProfile(memfile)
	memfile.Close()
	runtime.SetBlockProfileRate(1)
	time.Sleep(30 * time.Second)
	pprof.Lookup("block").WriteTo(lockfile, 0)
	runtime.SetBlockProfileRate(0)
	lockfile.Close()
	pprof.StartCPUProfile(cpufile)
	time.Sleep(30 * time.Second)
	pprof.StopCPUProfile()
	cpufile.Close()
	log.Println("profiling done")
}

func runServer(c *cli.Context) {
	var rp reverseproxy.ReverseProxy
	switch c.String("engine") {
	case "native":
		rp = &reverseproxy.NativeReverseProxy{}
	case "fasthttp":
		rp = &reverseproxy.FastReverseProxy{}
	case "sni":
		rp = &reverseproxy.SNIReverseProxy{}
	default:
		log.Fatal(errors.New("invalid engine"))
	}
	log.Printf("Using %T engine\n", rp)
	readOpts := backend.RedisOptions{
		Network:       c.String("read-redis-network"),
		Host:          c.String("read-redis-host"),
		Port:          c.Int("read-redis-port"),
		SentinelAddrs: c.String("read-redis-sentinel-addrs"),
		SentinelName:  c.String("read-redis-sentinel-name"),
		Password:      c.String("read-redis-password"),
		DB:            c.Int("read-redis-db"),
	}
	writeOpts := backend.RedisOptions{
		Network:       c.String("write-redis-network"),
		Host:          c.String("write-redis-host"),
		Port:          c.Int("write-redis-port"),
		SentinelAddrs: c.String("write-redis-sentinel-addrs"),
		SentinelName:  c.String("write-redis-sentinel-name"),
		Password:      c.String("write-redis-password"),
		DB:            c.Int("write-redis-db"),
	}
	routesBE, err := backend.NewRedisBackend(readOpts, writeOpts)
	if err != nil {
		log.Fatal(err)
	}
	if c.Bool("active-healthcheck") {
		err = routesBE.StartMonitor()
		if err != nil {
			log.Fatal(err)
		}
	}
	r := router.Router{
		Backend:        routesBE,
		LogPath:        c.String("access-log"),
		DeadBackendTTL: c.Int("dead-backend-time"),
		CacheEnabled:   c.Bool("backend-cache"),
	}
	err = r.Init()
	if err != nil {
		log.Fatal(err)
	}
	err = rp.Initialize(reverseproxy.ReverseProxyConfig{
		Router:            &r,
		RequestIDHeader:   http.CanonicalHeaderKey(c.String("request-id-header")),
		FlushInterval:     time.Duration(c.Int("flush-interval")) * time.Millisecond,
		DialTimeout:       time.Duration(c.Int("dial-timeout")) * time.Second,
		RequestTimeout:    time.Duration(c.Int("request-timeout")) * time.Second,
		ReadTimeout:       c.Duration("client-read-timeout"),
		ReadHeaderTimeout: c.Duration("client-read-header-timeout"),
		WriteTimeout:      c.Duration("client-write-timeout"),
		IdleTimeout:       c.Duration("client-idle-timeout"),
	})
	if err != nil {
		log.Fatal(err)
	}

	listener := &router.RouterListener{
		ReverseProxy: rp,
		Listen:       c.String("listen"),
		TLSListen:    c.String("tls-listen"),
		CertLoader:   getCertificateLoader(c, readOpts),
	}

	if addr := c.String("metrics-address"); addr != "" {
		handler := http.NewServeMux()
		handler.Handle("/metrics", promhttp.Handler())
		go func() {
			log.Fatal(http.ListenAndServe(addr, handler))
		}()
	}

	handleSignals(listener)
	listener.Serve()

	r.Stop()
	routesBE.StopMonitor()
}

func getCertificateLoader(c *cli.Context, readOpts backend.RedisOptions) tls.CertificateLoader {
	if c.String("tls-listen") == "" {
		return nil
	}

	from := c.String("load-certificates-from")
	switch from {
	case "redis":
		client, err := readOpts.Client()
		if err != nil {
			log.Fatal(err)
		}

		return tls.NewRedisCertificateLoader(client)
	default:
		return tls.NewFSCertificateLoader(from)
	}
}

func fixUsage(s string) string {
	linebreakRegexp := regexp.MustCompile(`\n{1}[\t ]*`)
	s = linebreakRegexp.ReplaceAllString(s, " ")
	parts := strings.Split(s, " ")
	currLen := 0
	lastPart := 0
	var lines []string
	for i := range parts {
		if currLen+len(parts[i])+1 > 65 {
			lines = append(lines, strings.Join(parts[lastPart:i], " "))
			currLen = 0
			lastPart = i
		}
		currLen += len(parts[i]) + 1
	}
	lines = append(lines, strings.Join(parts[lastPart:], " "))
	return strings.Join(lines, "\n\t")
}

func main() {
	oldStringer := cli.FlagStringer
	cli.FlagStringer = func(flag cli.Flag) string {
		usage := oldStringer(flag)
		usageIdx := strings.LastIndex(usage, "\t")
		if usageIdx != -1 {
			usage = usage[:usageIdx] + "\t" + fixUsage(usage[usageIdx+1:])
		}
		return usage
	}
	app := cli.NewApp()
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "listen, l",
			Value: "0.0.0.0:8989",
			Usage: "Address to listen",
		},
		cli.StringFlag{
			Name:  "tls-listen",
			Usage: "Address to listen with tls",
		},
		cli.StringFlag{
			Name:  "metrics-address",
			Usage: "Address to expose prometheus /metrics",
		},
		cli.StringFlag{
			Name:  "load-certificates-from",
			Value: "redis",
			Usage: `Path where certificate will found.
If value equals 'redis' certificate will be loaded from redis service.`,
		},
		cli.StringFlag{
			Name:  "read-redis-network",
			Value: "tcp",
		},
		cli.StringFlag{
			Name:  "read-redis-host",
			Value: "127.0.0.1",
		},
		cli.IntFlag{
			Name:  "read-redis-port",
			Value: 6379,
		},
		cli.StringFlag{
			Name:  "read-redis-sentinel-addrs",
			Usage: "Comma separated list of redis addresses",
		},
		cli.StringFlag{
			Name: "read-redis-sentinel-name",
		},
		cli.StringFlag{
			Name: "read-redis-password",
		},
		cli.IntFlag{
			Name: "read-redis-db",
		},
		cli.StringFlag{
			Name:  "write-redis-network",
			Value: "tcp",
		},
		cli.StringFlag{
			Name:  "write-redis-host",
			Value: "127.0.0.1",
		},
		cli.IntFlag{
			Name:  "write-redis-port",
			Value: 6379,
		},
		cli.StringFlag{
			Name:  "write-redis-sentinel-addrs",
			Usage: "Comma separated list of redis addresses",
		},
		cli.StringFlag{
			Name: "write-redis-sentinel-name",
		},
		cli.StringFlag{
			Name: "write-redis-password",
		},
		cli.IntFlag{
			Name: "write-redis-db",
		},
		cli.StringFlag{
			Name:  "access-log",
			Value: "./access.log",
			Usage: `File path where access log will be written.
If value equals 'syslog' log will be sent to local syslog.
The value 'none' can be used to disable access logs.`,
		},
		cli.IntFlag{
			Name:  "request-timeout",
			Value: 30,
			Usage: "Total backend request timeout in seconds",
		},
		cli.IntFlag{
			Name:  "dial-timeout",
			Value: 10,
			Usage: "Dial backend request timeout in seconds",
		},
		cli.DurationFlag{
			Name:  "client-read-timeout",
			Value: 0,
			Usage: "Maximum duration for reading the entire request, including the body",
		},
		cli.DurationFlag{
			Name:  "client-read-header-timeout",
			Value: 0,
			Usage: "Amount of time allowed to read request headers",
		},
		cli.DurationFlag{
			Name:  "client-write-timeout",
			Value: 0,
			Usage: "Maximum duration before timing out writes of the response",
		},
		cli.DurationFlag{
			Name:  "client-idle-timeout",
			Value: 0,
			Usage: "Maximum amount of time to wait for the next request when keep-alives are enabled",
		},
		cli.IntFlag{
			Name:  "dead-backend-time",
			Value: 30,
			Usage: "Time in seconds a backend will remain disabled after a network failure",
		},
		cli.IntFlag{
			Name:  "flush-interval",
			Value: 10,
			Usage: "Time in milliseconds to flush the proxied request",
		},
		cli.StringFlag{
			Name:  "request-id-header",
			Usage: "Header to enable message tracking",
		},
		cli.BoolFlag{
			Name: "active-healthcheck",
		},
		cli.StringFlag{
			Name:  "engine",
			Value: "native",
			Usage: "Reverse proxy engine, options are 'native', 'sni' and 'fasthttp'. Using 'sni' and 'fasthttp' is highly experimental and not recommended for production environments.",
		},
		cli.BoolFlag{
			Name:  "backend-cache",
			Usage: "Enable caching backend results for 2 seconds. This may cause temporary inconsistencies.",
		},
	}
	app.Version = "0.1.13"
	app.Name = "planb"
	app.Usage = "http and websockets reverse proxy"
	app.Action = runServer
	app.Author = "tsuru team"
	app.Email = "https://github.com/tsuru/planb"
	app.Run(os.Args)
}
<commit_msg>bump version to 0.1.14<commit_after>// Copyright 2016 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"errors"
	"log"
	"net/http"
	"os"
	"os/signal"
	"regexp"
	"runtime"
	"runtime/pprof"
	"strings"
	"syscall"
	"time"

	"github.com/codegangsta/cli"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/tsuru/planb/backend"
	"github.com/tsuru/planb/reverseproxy"
	"github.com/tsuru/planb/router"
	"github.com/tsuru/planb/tls"
)

func handleSignals(server interface {
	Stop()
}) {
	sigChan := make(chan os.Signal, 3)
	go func() {
		for sig := range sigChan {
			if sig == os.Interrupt || sig == os.Kill {
				server.Stop()
			}
			if sig == syscall.SIGUSR1 {
				pprof.Lookup("goroutine").WriteTo(os.Stdout, 2)
			}
			if sig == syscall.SIGUSR2 {
				go startProfiling()
			}
		}
	}()
	signal.Notify(sigChan, os.Interrupt, os.Kill, syscall.SIGUSR1, syscall.SIGUSR2)
}

func startProfiling() {
	cpufile, _ := os.OpenFile("./planb_cpu.pprof", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660)
	memfile, _ := os.OpenFile("./planb_mem.pprof", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660)
	lockfile, _ := os.OpenFile("./planb_lock.pprof", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660)
	log.Println("enabling profile...")
	runtime.GC()
	pprof.WriteHeapProfile(memfile)
	memfile.Close()
	runtime.SetBlockProfileRate(1)
	time.Sleep(30 * time.Second)
	pprof.Lookup("block").WriteTo(lockfile, 0)
	runtime.SetBlockProfileRate(0)
	lockfile.Close()
	pprof.StartCPUProfile(cpufile)
	time.Sleep(30 * time.Second)
	pprof.StopCPUProfile()
	cpufile.Close()
	log.Println("profiling done")
}

func runServer(c *cli.Context) {
	var rp reverseproxy.ReverseProxy
	switch c.String("engine") {
	case "native":
		rp = &reverseproxy.NativeReverseProxy{}
	case "fasthttp":
		rp = &reverseproxy.FastReverseProxy{}
	case "sni":
		rp = &reverseproxy.SNIReverseProxy{}
	default:
		log.Fatal(errors.New("invalid engine"))
	}
	log.Printf("Using %T engine\n", rp)
	readOpts := backend.RedisOptions{
		Network:       c.String("read-redis-network"),
		Host:          c.String("read-redis-host"),
		Port:          c.Int("read-redis-port"),
		SentinelAddrs: c.String("read-redis-sentinel-addrs"),
		SentinelName:  c.String("read-redis-sentinel-name"),
		Password:      c.String("read-redis-password"),
		DB:            c.Int("read-redis-db"),
	}
	writeOpts := backend.RedisOptions{
		Network:       c.String("write-redis-network"),
		Host:          c.String("write-redis-host"),
		Port:          c.Int("write-redis-port"),
		SentinelAddrs: c.String("write-redis-sentinel-addrs"),
		SentinelName:  c.String("write-redis-sentinel-name"),
		Password:      c.String("write-redis-password"),
		DB:            c.Int("write-redis-db"),
	}
	routesBE, err := backend.NewRedisBackend(readOpts, writeOpts)
	if err != nil {
		log.Fatal(err)
	}
	if c.Bool("active-healthcheck") {
		err = routesBE.StartMonitor()
		if err != nil {
			log.Fatal(err)
		}
	}
	r := router.Router{
		Backend:        routesBE,
		LogPath:        c.String("access-log"),
		DeadBackendTTL: c.Int("dead-backend-time"),
		CacheEnabled:   c.Bool("backend-cache"),
	}
	err = r.Init()
	if err != nil {
		log.Fatal(err)
	}
	err = rp.Initialize(reverseproxy.ReverseProxyConfig{
		Router:            &r,
		RequestIDHeader:   http.CanonicalHeaderKey(c.String("request-id-header")),
		FlushInterval:     time.Duration(c.Int("flush-interval")) * time.Millisecond,
		DialTimeout:       time.Duration(c.Int("dial-timeout")) * time.Second,
		RequestTimeout:    time.Duration(c.Int("request-timeout")) * time.Second,
		ReadTimeout:       c.Duration("client-read-timeout"),
		ReadHeaderTimeout: c.Duration("client-read-header-timeout"),
		WriteTimeout:      c.Duration("client-write-timeout"),
		IdleTimeout:       c.Duration("client-idle-timeout"),
	})
	if err != nil {
		log.Fatal(err)
	}

	listener := &router.RouterListener{
		ReverseProxy: rp,
		Listen:       c.String("listen"),
		TLSListen:    c.String("tls-listen"),
		CertLoader:   getCertificateLoader(c, readOpts),
	}

	if addr := c.String("metrics-address"); addr != "" {
		handler := http.NewServeMux()
		handler.Handle("/metrics", promhttp.Handler())
		go func() {
			log.Fatal(http.ListenAndServe(addr, handler))
		}()
	}

	handleSignals(listener)
	listener.Serve()

	r.Stop()
	routesBE.StopMonitor()
}

func getCertificateLoader(c *cli.Context, readOpts backend.RedisOptions) tls.CertificateLoader {
	if c.String("tls-listen") == "" {
		return nil
	}

	from := c.String("load-certificates-from")
	switch from {
	case "redis":
		client, err := readOpts.Client()
		if err != nil {
			log.Fatal(err)
		}

		return tls.NewRedisCertificateLoader(client)
	default:
		return tls.NewFSCertificateLoader(from)
	}
}

func fixUsage(s string) string {
	linebreakRegexp := regexp.MustCompile(`\n{1}[\t ]*`)
	s = linebreakRegexp.ReplaceAllString(s, " ")
	parts := strings.Split(s, " ")
	currLen := 0
	lastPart := 0
	var lines []string
	for i := range parts {
		if currLen+len(parts[i])+1 > 65 {
			lines = append(lines, strings.Join(parts[lastPart:i], " "))
			currLen = 0
			lastPart = i
		}
		currLen += len(parts[i]) + 1
	}
	lines = append(lines, strings.Join(parts[lastPart:], " "))
	return strings.Join(lines, "\n\t")
}

func main() {
	oldStringer := cli.FlagStringer
	cli.FlagStringer = func(flag cli.Flag) string {
		usage := oldStringer(flag)
		usageIdx := strings.LastIndex(usage, "\t")
		if usageIdx != -1 {
			usage = usage[:usageIdx] + "\t" + fixUsage(usage[usageIdx+1:])
		}
		return usage
	}
	app := cli.NewApp()
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "listen, l",
			Value: "0.0.0.0:8989",
			Usage: "Address to listen",
		},
		cli.StringFlag{
			Name:  "tls-listen",
			Usage: "Address to listen with tls",
		},
		cli.StringFlag{
			Name:  "metrics-address",
			Usage: "Address to expose prometheus /metrics",
		},
		cli.StringFlag{
			Name:  "load-certificates-from",
			Value: "redis",
			Usage: `Path where certificate will found.
If value equals 'redis' certificate will be loaded from redis service.`,
		},
		cli.StringFlag{
			Name:  "read-redis-network",
			Value: "tcp",
		},
		cli.StringFlag{
			Name:  "read-redis-host",
			Value: "127.0.0.1",
		},
		cli.IntFlag{
			Name:  "read-redis-port",
			Value: 6379,
		},
		cli.StringFlag{
			Name:  "read-redis-sentinel-addrs",
			Usage: "Comma separated list of redis addresses",
		},
		cli.StringFlag{
			Name: "read-redis-sentinel-name",
		},
		cli.StringFlag{
			Name: "read-redis-password",
		},
		cli.IntFlag{
			Name: "read-redis-db",
		},
		cli.StringFlag{
			Name:  "write-redis-network",
			Value: "tcp",
		},
		cli.StringFlag{
			Name:  "write-redis-host",
			Value: "127.0.0.1",
		},
		cli.IntFlag{
			Name:  "write-redis-port",
			Value: 6379,
		},
		cli.StringFlag{
			Name:  "write-redis-sentinel-addrs",
			Usage: "Comma separated list of redis addresses",
		},
		cli.StringFlag{
			Name: "write-redis-sentinel-name",
		},
		cli.StringFlag{
			Name: "write-redis-password",
		},
		cli.IntFlag{
			Name: "write-redis-db",
		},
		cli.StringFlag{
			Name:  "access-log",
			Value: "./access.log",
			Usage: `File path where access log will be written.
If value equals 'syslog' log will be sent to local syslog.
The value 'none' can be used to disable access logs.`,
		},
		cli.IntFlag{
			Name:  "request-timeout",
			Value: 30,
			Usage: "Total backend request timeout in seconds",
		},
		cli.IntFlag{
			Name:  "dial-timeout",
			Value: 10,
			Usage: "Dial backend request timeout in seconds",
		},
		cli.DurationFlag{
			Name:  "client-read-timeout",
			Value: 0,
			Usage: "Maximum duration for reading the entire request, including the body",
		},
		cli.DurationFlag{
			Name:  "client-read-header-timeout",
			Value: 0,
			Usage: "Amount of time allowed to read request headers",
		},
		cli.DurationFlag{
			Name:  "client-write-timeout",
			Value: 0,
			Usage: "Maximum duration before timing out writes of the response",
		},
		cli.DurationFlag{
			Name:  "client-idle-timeout",
			Value: 0,
			Usage: "Maximum amount of time to wait for the next request when keep-alives are enabled",
		},
		cli.IntFlag{
			Name:  "dead-backend-time",
			Value: 30,
			Usage: "Time in seconds a backend will remain disabled after a network failure",
		},
		cli.IntFlag{
			Name:  "flush-interval",
			Value: 10,
			Usage: "Time in milliseconds to flush the proxied request",
		},
		cli.StringFlag{
			Name:  "request-id-header",
			Usage: "Header to enable message tracking",
		},
		cli.BoolFlag{
			Name: "active-healthcheck",
		},
		cli.StringFlag{
			Name:  "engine",
			Value: "native",
			Usage: "Reverse proxy engine, options are 'native', 'sni' and 'fasthttp'. Using 'sni' and 'fasthttp' is highly experimental and not recommended for production environments.",
		},
		cli.BoolFlag{
			Name:  "backend-cache",
			Usage: "Enable caching backend results for 2 seconds. This may cause temporary inconsistencies.",
		},
	}
	app.Version = "0.1.14"
	app.Name = "planb"
	app.Usage = "http and websockets reverse proxy"
	app.Action = runServer
	app.Author = "tsuru team"
	app.Email = "https://github.com/tsuru/planb"
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

type VootResponse struct {
	Assets []struct {
		ID          string `json:"id"`
		Type        int    `json:"type"`
		Name        string `json:"name"`
		Description string `json:"description"`
		Images      []struct {
			Ratio  string `json:"ratio"`
			Width  int    `json:"width"`
			Height int    `json:"height"`
			URL    string `json:"url"`
		} `json:"images"`
		Metas struct {
			ContentSynopsis string `json:"ContentSynopsis"`
			ContentType     string `json:"ContentType"`
			ContentFileName string `json:"ContentFileName"`
			MovieMainTitle  string `json:"MovieMainTitle"`
			SBU             string `json:"SBU"`
			IsDownable      string `json:"IsDownable"`
			ContentDuration string `json:"ContentDuration"`
			ReleaseYear     string `json:"ReleaseYear"`
		} `json:"metas"`
		Tags struct {
			Keywords        []string `json:"Keywords"`
			CharacterList   []string `json:"CharacterList"`
			ContributorList []string `json:"ContributorList"`
			Scene1          []string `json:"Scene1"`
			Scene2          []string `json:"Scene2"`
			Scene3          []string `json:"Scene3"`
			Scene4          []string `json:"Scene4"`
			Scene5          []string `json:"Scene5"`
			Scene6          []string `json:"Scene6"`
			Genre           []string `json:"Genre"`
			Language        []string `json:"Language"`
			AdCueTime1      []string `json:"AdCueTime1"`
			AdCueTime2      []string `json:"AdCueTime2"`
			AdCueTime3      []string `json:"AdCueTime3"`
			AdCueTime4      []string `json:"AdCueTime4"`
			AdCueTime5      []string `json:"AdCueTime5"`
			AdCueTime6      []string `json:"AdCueTime6"`
			AdCueTime7      []string `json:"AdCueTime7"`
			AdCueTime8      []string `json:"AdCueTime8"`
			MediaExternalID []string `json:"MediaExternalId"`
			WatermarkURL    []string `json:"WatermarkURL"`
			MovieDirector   []string `json:"MovieDirector"`
		} `json:"tags"`
		StartDate   int   `json:"start_date"`
		EndDate     int64 `json:"end_date"`
		ExtraParams struct {
			SysStartDate string      `json:"sys_start_date"`
			SysFinalDate string      `json:"sys_final_date"`
			ExternalIds  interface{} `json:"external_ids"`
			EntryID      string      `json:"entry_id"`
		} `json:"extra_params"`
		RURL interface{} `json:"rURL"`
	} `json:"assets"`
	TotalItems int `json:"total_items"`
	Status     struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	} `json:"status"`
}

func main() {

	index := 1
	totalMovies := 0
	for {
		b, _ := get(strconv.Itoa(index))
		count := unmarshalMovies(b)
		totalMovies = totalMovies + unmarshalMovies(b)
		if count == 0 {
			break
		}
		index++

	}
	fmt.Println(totalMovies)

}

func get(pageIndex string) ([]byte, error) {
	url := "https://wapi.voot.com/ws/ott/searchAssets.json?platform=Web&pId=2"
	req, _ := requesrUrl(url, pageIndex)
	req.Header.Add("content-type", "application/x-www-form-urlencoded")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	return ioutil.ReadAll(res.Body)

}

func unmarshalMovies(b []byte) int {
	r := VootResponse{}
	json.Unmarshal(b, &r)
	for _, movies := range r.Assets {
		fmt.Println(movies.Name)
	}
	return len(r.Assets)
}

func getPostVars(pageIndex string) io.Reader {
	form := url.Values{}
	form.Add("filterTypes", "390")
	//form.Add("filter", "(and (and  contentType='Movie' ))")
	form.Add("pageIndex", pageIndex)
	form.Add("pageSize", "10")
	fmt.Println(form.Encode())
	return strings.NewReader(form.Encode())
}

func requesrUrl(url, pageIndex string) (*http.Request, error) {
	return http.NewRequest("POST", url, getPostVars(pageIndex))

}
<commit_msg>change struct<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

type VootResponse struct {
	Assets []struct {
		ID          string `json:"id"`
		Type        int    `json:"type"`
		Name        string `json:"name"`
		Description string `json:"description"`
		Images      []struct {
			Ratio  string `json:"ratio"`
			Width  int    `json:"width"`
			Height int    `json:"height"`
			URL    string `json:"url"`
		} `json:"images"`
		Metas struct {
			ContentSynopsis string `json:"ContentSynopsis"`
			ContentType     string `json:"ContentType"`
			ContentFileName string `json:"ContentFileName"`
			MovieMainTitle  string `json:"MovieMainTitle"`
			SBU             string `json:"SBU"`
			IsDownable      string `json:"IsDownable"`
			ContentDuration string `json:"ContentDuration"`
			ReleaseYear     string `json:"ReleaseYear"`
		} `json:"metas"`
		Tags struct {
			Keywords        []string `json:"Keywords"`
			CharacterList   []string `json:"CharacterList"`
			ContributorList []string `json:"ContributorList"`
			Scene1          []string `json:"Scene1"`
			Scene2          []string `json:"Scene2"`
			Scene3          []string `json:"Scene3"`
			Scene4          []string `json:"Scene4"`
			Scene5          []string `json:"Scene5"`
			Scene6          []string `json:"Scene6"`
			Genre           []string `json:"Genre"`
			Language        []string `json:"Language"`
			AdCueTime1      []string `json:"AdCueTime1"`
			AdCueTime2      []string `json:"AdCueTime2"`
			AdCueTime3      []string `json:"AdCueTime3"`
			AdCueTime4      []string `json:"AdCueTime4"`
			AdCueTime5      []string `json:"AdCueTime5"`
			AdCueTime6      []string `json:"AdCueTime6"`
			AdCueTime7      []string `json:"AdCueTime7"`
			AdCueTime8      []string `json:"AdCueTime8"`
			MediaExternalID []string `json:"MediaExternalId"`
			WatermarkURL    []string `json:"WatermarkURL"`
			MovieDirector   []string `json:"MovieDirector"`
		} `json:"tags"`
		StartDate   int   `json:"start_date"`
		EndDate     int64 `json:"end_date"`
		ExtraParams struct {
			SysStartDate string      `json:"sys_start_date"`
			SysFinalDate string      `json:"sys_final_date"`
			ExternalIds  interface{} `json:"external_ids"`
			EntryID      string      `json:"entry_id"`
		} `json:"extra_params"`
		RURL interface{} `json:"rURL"`
	} `json:"assets"`
	TotalItems int `json:"total_items"`
	Status     struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	} `json:"status"`
}

type MovieRequester struct {
	url       string
	pageIndex string
	request   *http.Request
}

func main() {
	mr := MovieRequester{}
	mr.url = "https://wapi.voot.com/ws/ott/searchAssets.json?platform=Web&pId=2"

	index := 0
	totalMovies := 0
	for {
		mr.pageIndex = strconv.Itoa(index)
		b, _ := mr.get(mr.pageIndex)
		count := mr.unmarshalMovies(b)
		totalMovies = totalMovies + count
		if count == 0 {
			break
		}
		index++

	}
	fmt.Println(totalMovies)

}

func (mr *MovieRequester) get(pageIndex string) ([]byte, error) {
	//url := "https://wapi.voot.com/ws/ott/searchAssets.json?platform=Web&pId=2"
	mr.request, _ = mr.requesrUrl()
	mr.request.Header.Add("content-type", "application/x-www-form-urlencoded")
	res, _ := http.DefaultClient.Do(mr.request)
	defer res.Body.Close()
	return ioutil.ReadAll(res.Body)

}

func (mr *MovieRequester) unmarshalMovies(b []byte) int {
	r := VootResponse{}
	json.Unmarshal(b, &r)
	for _, movies := range r.Assets {
		fmt.Println(movies.Name)
	}
	return len(r.Assets)
}

func (mr *MovieRequester) getPostVars() io.Reader {
	form := url.Values{}
	form.Add("filterTypes", "390")
	//form.Add("filter", "(and (and  contentType='Movie' ))")
	form.Add("pageIndex", mr.pageIndex)
	form.Add("pageSize", "10")
	fmt.Println(form.Encode())
	return strings.NewReader(form.Encode())
}

func (mr *MovieRequester) requesrUrl() (*http.Request, error) {
	return http.NewRequest("POST", mr.url, mr.getPostVars())

}
<|endoftext|>


<commit_before>package main

import (
	"os"

	"github.com/99designs/aws-vault/cli"
	"gopkg.in/alecthomas/kingpin.v2"
)

// Version is provided at compile time
var Version = "dev"

func main() {
	run(os.Args[1:], os.Exit)
}

func run(args []string, exit func(int)) {
	app := kingpin.New(
		`aws-vault`,
		`A vault for securely storing and accessing AWS credentials in development environments.`,
	)

	app.Writer(os.Stdout)
	app.Version(Version)
	app.Terminate(exit)

	cli.ConfigureGlobals(app)
	cli.ConfigureAddCommand(app)
	cli.ConfigureListCommand(app)
	cli.ConfigureRotateCommand(app)
	cli.ConfigureExecCommand(app)
	cli.ConfigureRemoveCommand(app)
	cli.ConfigureLoginCommand(app)
	cli.ConfigureServerCommand(app)

	kingpin.MustParse(app.Parse(args))
}
<commit_msg>Report errors via stderr<commit_after>package main

import (
	"os"

	"github.com/99designs/aws-vault/cli"
	"gopkg.in/alecthomas/kingpin.v2"
)

// Version is provided at compile time
var Version = "dev"

func main() {
	run(os.Args[1:], os.Exit)
}

func run(args []string, exit func(int)) {
	app := kingpin.New(
		`aws-vault`,
		`A vault for securely storing and accessing AWS credentials in development environments.`,
	)

	app.ErrorWriter(os.Stderr)
	app.Writer(os.Stdout)
	app.Version(Version)
	app.Terminate(exit)

	cli.ConfigureGlobals(app)
	cli.ConfigureAddCommand(app)
	cli.ConfigureListCommand(app)
	cli.ConfigureRotateCommand(app)
	cli.ConfigureExecCommand(app)
	cli.ConfigureRemoveCommand(app)
	cli.ConfigureLoginCommand(app)
	cli.ConfigureServerCommand(app)

	kingpin.MustParse(app.Parse(args))
}
<|endoftext|>


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

package main

import (
	"encoding/binary"
	"fmt"
	"log"
	"time"

	"golang.org/x/mobile/app"
	"golang.org/x/mobile/audio"
	"golang.org/x/mobile/f32"
	"golang.org/x/mobile/gl"
	"golang.org/x/mobile/gl/glutil"
)

const (
	numBeats  = 8
	numTracks = 8
)

var (
	program  gl.Program
	position gl.Attrib
	offset   gl.Uniform
	color    gl.Uniform
	buf      gl.Buffer

	index    int
	green    float32
	greenDec bool

	started bool
)

func main() {
	app.Run(app.Callbacks{
		Start: start,
		Stop:  stop,
		Draw:  draw,
	})
}

func start() {
	var err error
	program, err = glutil.CreateProgram(vertexShader, fragmentShader)
	if err != nil {
		log.Printf("error creating GL program: %v", err)
		return
	}

	buf = gl.CreateBuffer()
	gl.BindBuffer(gl.ARRAY_BUFFER, buf)
	gl.BufferData(gl.ARRAY_BUFFER, rectData, gl.STATIC_DRAW)

	position = gl.GetAttribLocation(program, "position")
	color = gl.GetUniformLocation(program, "color")
	offset = gl.GetUniformLocation(program, "offset")

	if started {
		return
	}
	started = true

	for i := 0; i < numTracks; i++ {
		rc, err := app.Open(fmt.Sprintf("track%d.wav", i))
		if err != nil {
			log.Fatal(err)
		}

		p, err := audio.NewPlayer(rc, audio.Stereo16, 44100)
		if err != nil {
			log.Fatal(err)
		}
		players[i] = p
	}

	// hi hat
	hits[0][1] = true
	hits[2][1] = true
	hits[4][1] = true
	hits[6][1] = true

	// kick
	hits[5][2] = true
	hits[7][2] = true

	// bass
	hits[0][4] = true
	hits[3][4] = true
	hits[5][4] = true
	hits[6][4] = true

	// bass2
	hits[2][6] = true

	hits[4][7] = true

	go func() {
		for {
			index = (index + 1) % numBeats
			for t := 0; t < numTracks; t++ {
				go func(t int) {
					if hits[index][t] {
						players[t].Play()
					}
				}(t)
			}
			time.Sleep(400 * time.Millisecond)
		}
	}()
}

func stop() {
	for _, p := range players {
		p.Stop()
	}
	gl.DeleteProgram(program)
	gl.DeleteBuffer(buf)
	// TODO(jbd): Destroy the players, close the assets.
}

var rectData = f32.Bytes(binary.LittleEndian,
	0, 0,
	0, 0.1,
	0.1, 0,
	0.1, 0.1,
)

var (
	hits    [numBeats][numTracks]bool
	players [numTracks]*audio.Player
)

func draw() {
	gl.ClearColor(0, 0, 0, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)
	gl.UseProgram(program)

	if greenDec {
		green -= 0.01
	} else {
		green += 0.01
	}
	if green <= 0.2 {
		greenDec = false
	}
	if green >= 0.5 {
		greenDec = true
	}

	for i := 0; i < numBeats; i++ {
		for j := 0; j < numTracks; j++ {
			var c float32
			switch {
			case hits[i][j]:
				c = 1
			case i == index:
				c = green
			default:
				c = 0
			}
			drawButton(c, float32(i)*1/numBeats, float32(j)*1/numTracks)
		}
	}
}

func drawButton(g, x, y float32) {
	gl.Uniform4f(color, 0.1, g, 0.4, 1) // color
	gl.Uniform2f(offset, x, y)          // position

	gl.BindBuffer(gl.ARRAY_BUFFER, buf)
	gl.EnableVertexAttribArray(position)
	gl.VertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0)
	gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
	gl.DisableVertexAttribArray(position)
}

const vertexShader = `#version 100
uniform vec2 offset;
attribute vec4 position;
void main() {
  // offset comes in with x/y values between 0 and 1.
  // position bounds are -1 to 1.
  vec4 offset4 = vec4(2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0);
  gl_Position = position + offset4;
}`

const fragmentShader = `#version 100
precision mediump float;
uniform vec4 color;
void main() {
  gl_FragColor = color;
}`
<commit_msg>destroy and restart players on rotation.<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"encoding/binary"
	"fmt"
	"log"
	"time"

	"golang.org/x/mobile/app"
	"golang.org/x/mobile/audio"
	"golang.org/x/mobile/f32"
	"golang.org/x/mobile/gl"
	"golang.org/x/mobile/gl/glutil"
)

const (
	numBeats  = 8
	numTracks = 8
)

var (
	program  gl.Program
	position gl.Attrib
	offset   gl.Uniform
	color    gl.Uniform
	buf      gl.Buffer

	index    int
	green    float32
	greenDec bool

	stopped bool
)

func main() {
	app.Run(app.Callbacks{
		Start: start,
		Stop:  stop,
		Draw:  draw,
	})
}

func start() {
	var err error
	program, err = glutil.CreateProgram(vertexShader, fragmentShader)
	if err != nil {
		log.Printf("error creating GL program: %v", err)
		return
	}

	buf = gl.CreateBuffer()
	gl.BindBuffer(gl.ARRAY_BUFFER, buf)
	gl.BufferData(gl.ARRAY_BUFFER, rectData, gl.STATIC_DRAW)

	position = gl.GetAttribLocation(program, "position")
	color = gl.GetUniformLocation(program, "color")
	offset = gl.GetUniformLocation(program, "offset")

	for i := 0; i < numTracks; i++ {
		rc, err := app.Open(fmt.Sprintf("track%d.wav", i))
		if err != nil {
			log.Fatal(err)
		}

		p, err := audio.NewPlayer(rc, audio.Stereo16, 44100)
		if err != nil {
			log.Fatal(err)
		}
		players[i] = p
	}

	// hi hat
	hits[0][1] = true
	hits[2][1] = true
	hits[4][1] = true
	hits[6][1] = true

	// kick
	hits[5][2] = true
	hits[7][2] = true

	// bass
	hits[0][4] = true
	hits[3][4] = true
	hits[5][4] = true
	hits[6][4] = true

	// bass2
	hits[2][6] = true

	hits[4][7] = true

	go func() {
		for {
			if stopped {
				stopped = false
				return
			}
			index = (index + 1) % numBeats
			for t := 0; t < numTracks; t++ {
				go func(t int) {
					if hits[index][t] {
						players[t].Play()
					}
				}(t)
			}
			time.Sleep(400 * time.Millisecond)
		}
	}()
}

func stop() {
	for _, p := range players {
		p.Destroy()
	}
	gl.DeleteProgram(program)
	gl.DeleteBuffer(buf)
	stopped = true
	// TODO(jbd): Destroy the players, close the assets.
}

var rectData = f32.Bytes(binary.LittleEndian,
	0, 0,
	0, 0.1,
	0.1, 0,
	0.1, 0.1,
)

var (
	hits    [numBeats][numTracks]bool
	players [numTracks]*audio.Player
)

func draw() {
	gl.ClearColor(0, 0, 0, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)
	gl.UseProgram(program)

	if greenDec {
		green -= 0.01
	} else {
		green += 0.01
	}
	if green <= 0.2 {
		greenDec = false
	}
	if green >= 0.5 {
		greenDec = true
	}

	for i := 0; i < numBeats; i++ {
		for j := 0; j < numTracks; j++ {
			var c float32
			switch {
			case hits[i][j]:
				c = 1
			case i == index:
				c = green
			default:
				c = 0
			}
			drawButton(c, float32(i)*1/numBeats, float32(j)*1/numTracks)
		}
	}
}

func drawButton(g, x, y float32) {
	gl.Uniform4f(color, 0.1, g, 0.4, 1) // color
	gl.Uniform2f(offset, x, y)          // position

	gl.BindBuffer(gl.ARRAY_BUFFER, buf)
	gl.EnableVertexAttribArray(position)
	gl.VertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0)
	gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
	gl.DisableVertexAttribArray(position)
}

const vertexShader = `#version 100
uniform vec2 offset;
attribute vec4 position;
void main() {
  // offset comes in with x/y values between 0 and 1.
  // position bounds are -1 to 1.
  vec4 offset4 = vec4(2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0);
  gl_Position = position + offset4;
}`

const fragmentShader = `#version 100
precision mediump float;
uniform vec4 color;
void main() {
  gl_FragColor = color;
}`
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"sort"
	"strconv"
	"strings"
)

var (
	dir   = flag.String("d", "budget", "budget data directory")
	month = flag.String("m", "", "year/month in format YYYYMM")
)

// Transaction is a single transaction with a cost and name
type Transaction struct {
	Cost float64
	Name string
}

// Budget is a monthly budget
type Budget struct {
	Total        float64
	Remaining    float64
	Transactions []Transaction
}

func parseFile(name string) (Budget, error) {
	file, err := os.Open(name)
	if err != nil {
		return Budget{}, err
	}
	r := bufio.NewReader(file)
	b := Budget{}
	// first line is the total for the month
	line, _, err := r.ReadLine()
	if err != nil {
		return Budget{}, err
	}
	total, err := strconv.ParseFloat(string(line), 64)
	if err != nil {
		return Budget{}, err
	}
	b.Total = total
	for {
		line, _, err := r.ReadLine()
		if err == io.EOF {
			break
		}
		if err != nil {
			return Budget{}, err
		}
		t := strings.Split(string(line), ",")
		if len(t) != 2 {
			return Budget{}, fmt.Errorf("invalid line %q", line)
		}
		cost, err := strconv.ParseFloat(t[0], 64)
		if err != nil {
			return Budget{}, err
		}
		trans := Transaction{Cost: cost, Name: t[1]}

		b.Transactions = append(b.Transactions, trans)
	}

	b.Remaining = b.Total
	for _, trans := range b.Transactions {
		b.Remaining = b.Remaining + trans.Cost
	}
	return b, nil
}

// Pair is a data structure to hold a key/value pair.
// modified from https://groups.google.com/forum/#!topic/golang-nuts/FT7cjmcL7gw
type Pair struct {
	Key   string
	Value float64
}

// PairList is a slice of Pairs that implements sort.Interface to sort by Value.
type PairList []Pair

func (p PairList) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p PairList) Len() int           { return len(p) }
func (p PairList) Less(i, j int) bool { return p[i].Value < p[j].Value }

// A function to turn a map into a PairList, then sort and return it.
func sortMapByValue(m map[string]float64) PairList {
	p := make(PairList, len(m))
	i := 0
	for k, v := range m {
		p[i] = Pair{k, v}
		i++
	}
	sort.Sort(p)
	return p
}

func main() {
	flag.Parse()
	b, err := parseFile(fmt.Sprintf("%s/%s.txt", *dir, *month))
	if err != nil {
		log.Fatal(err)
	}
	top := map[string]float64{}
	fmt.Println("Total:", b.Total)
	fmt.Println("Remaining:", b.Remaining)
	for _, t := range b.Transactions {
		top[t.Name] += t.Cost
	}
	fmt.Println("Top costs:")
	pl := sortMapByValue(top)
	for _, p := range pl {
		fmt.Printf("%s:%f\n", p.Key, p.Value)
	}
}
<commit_msg>use precision 2 when printing<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"sort"
	"strconv"
	"strings"
)

var (
	dir   = flag.String("d", "budget", "budget data directory")
	month = flag.String("m", "", "year/month in format YYYYMM")
)

// Transaction is a single transaction with a cost and name
type Transaction struct {
	Cost float64
	Name string
}

// Budget is a monthly budget
type Budget struct {
	Total        float64
	Remaining    float64
	Transactions []Transaction
}

func parseFile(name string) (Budget, error) {
	file, err := os.Open(name)
	if err != nil {
		return Budget{}, err
	}
	r := bufio.NewReader(file)
	b := Budget{}
	// first line is the total for the month
	line, _, err := r.ReadLine()
	if err != nil {
		return Budget{}, err
	}
	total, err := strconv.ParseFloat(string(line), 64)
	if err != nil {
		return Budget{}, err
	}
	b.Total = total
	for {
		line, _, err := r.ReadLine()
		if err == io.EOF {
			break
		}
		if err != nil {
			return Budget{}, err
		}
		t := strings.Split(string(line), ",")
		if len(t) != 2 {
			return Budget{}, fmt.Errorf("invalid line %q", line)
		}
		cost, err := strconv.ParseFloat(t[0], 64)
		if err != nil {
			return Budget{}, err
		}
		trans := Transaction{Cost: cost, Name: t[1]}

		b.Transactions = append(b.Transactions, trans)
	}

	b.Remaining = b.Total
	for _, trans := range b.Transactions {
		b.Remaining = b.Remaining + trans.Cost
	}
	return b, nil
}

// Pair is a data structure to hold a key/value pair.
// modified from https://groups.google.com/forum/#!topic/golang-nuts/FT7cjmcL7gw
type Pair struct {
	Key   string
	Value float64
}

// PairList is a slice of Pairs that implements sort.Interface to sort by Value.
type PairList []Pair

func (p PairList) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p PairList) Len() int           { return len(p) }
func (p PairList) Less(i, j int) bool { return p[i].Value < p[j].Value }

// A function to turn a map into a PairList, then sort and return it.
func sortMapByValue(m map[string]float64) PairList {
	p := make(PairList, len(m))
	i := 0
	for k, v := range m {
		p[i] = Pair{k, v}
		i++
	}
	sort.Sort(p)
	return p
}

func main() {
	flag.Parse()
	b, err := parseFile(fmt.Sprintf("%s/%s.txt", *dir, *month))
	if err != nil {
		log.Fatal(err)
	}
	top := map[string]float64{}
	fmt.Println("Total:", b.Total)
	fmt.Println("Remaining:", b.Remaining)
	for _, t := range b.Transactions {
		top[t.Name] += t.Cost
	}
	fmt.Println("Top costs:")
	pl := sortMapByValue(top)
	for _, p := range pl {
		fmt.Printf("%s:%.2f\n", p.Key, p.Value)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"
	"os"
)

func main() {
	http.HandleFunc("/", compress(pinFeed))
	log.Fatal(http.ListenAndServe(":"+os.Getenv("PORT"), nil))
}
<commit_msg>temporarily disable compression<commit_after>package main

import (
	"log"
	"net/http"
	"os"
)

func main() {
	// Disable compression until we figure out what's wrong.
	//http.HandleFunc("/", compress(pinFeed))
	http.HandleFunc("/", pinFeed)
	log.Fatal(http.ListenAndServe(":"+os.Getenv("PORT"), nil))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
)

type options struct {
	all      bool
	dirsOnly bool
}

var (
	a = flag.Bool("a", false, "")
	d = flag.Bool("d", false, "")
	f = flag.Bool("f", false, "")
	s = flag.Bool("s", false, "")
	h = flag.Bool("h", false, "")
)

func main() {
	var nd, nf int
	var dirs = []string{"."}
	flag.Parse()
	// Make it work with leading dirs
	if args := flag.Args(); len(args) > 0 {
		dirs = args
	}
	opts := &options{
		all:      *a,
		dirsOnly: *d,
	}
	for _, dir := range dirs {
		inf := &info{path: dir}
		if d, f := inf.visit(opts); inf.err == nil {
			nd, nf = nd+d-1, nf+f
		}
		inf.print("")
	}
	fmt.Printf("\n%d directories, %d files\n", nd, nf)
}
<commit_msg>fix(main): print footer<commit_after>package main

import (
	"flag"
	"fmt"
)

type options struct {
	all      bool
	dirsOnly bool
}

var (
	a = flag.Bool("a", false, "")
	d = flag.Bool("d", false, "")
	f = flag.Bool("f", false, "")
	s = flag.Bool("s", false, "")
	h = flag.Bool("h", false, "")
)

func main() {
	var nd, nf int
	var dirs = []string{"."}
	flag.Parse()
	// Make it work with leading dirs
	if args := flag.Args(); len(args) > 0 {
		dirs = args
	}
	opts := &options{
		all:      *a,
		dirsOnly: *d,
	}
	for _, dir := range dirs {
		inf := &info{path: dir}
		if d, f := inf.visit(opts); inf.err == nil {
			nd, nf = nd+d-1, nf+f
		}
		inf.print("")
	}
	// print footer
	footer := fmt.Sprintf("\n%d directories", nd)
	if !opts.dirsOnly {
		footer += fmt.Sprintf(", %d files", nf)
	}
	fmt.Println(footer)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strconv"
	"strings"

	"github.com/mholt/caddy/caddy"
	"github.com/mholt/caddy/caddy/letsencrypt"
)

var (
	conf    string
	cpu     string
	version bool
	revoke  string
	logfile string
)

const (
	appName    = "Caddy"
	appVersion = "0.8 beta 3"
)

func init() {
	flag.StringVar(&conf, "conf", "", "Configuration file to use (default="+caddy.DefaultConfigFile+")")
	flag.BoolVar(&caddy.HTTP2, "http2", true, "HTTP/2 support") // TODO: temporary flag until http2 merged into std lib
	flag.BoolVar(&caddy.Quiet, "quiet", false, "Quiet mode (no initialization output)")
	flag.StringVar(&cpu, "cpu", "100%", "CPU cap")
	flag.StringVar(&caddy.Root, "root", caddy.DefaultRoot, "Root path to default site")
	flag.StringVar(&caddy.Host, "host", caddy.DefaultHost, "Default host")
	flag.StringVar(&caddy.Port, "port", caddy.DefaultPort, "Default port")
	flag.BoolVar(&version, "version", false, "Show version")
	// TODO: Boulder dev URL is: http://192.168.99.100:4000
	// TODO: Staging API URL is: https://acme-staging.api.letsencrypt.org
	// TODO: Production endpoint is: https://acme-v01.api.letsencrypt.org
	flag.StringVar(&letsencrypt.CAUrl, "ca", "https://acme-staging.api.letsencrypt.org", "Certificate authority ACME server")
	flag.BoolVar(&letsencrypt.Agreed, "agree", false, "Agree to Let's Encrypt Subscriber Agreement")
	flag.StringVar(&letsencrypt.DefaultEmail, "email", "", "Default Let's Encrypt account email address")
	flag.StringVar(&revoke, "revoke", "", "Hostname for which to revoke the certificate")
	flag.StringVar(&logfile, "log", "", "Process log file")
}

func main() {
	flag.Parse() // called here in main() to allow other packages to set flags in their inits

	caddy.AppName = appName
	caddy.AppVersion = appVersion

	// set up process log before anything bad happens
	switch logfile {
	case "stdout":
		log.SetOutput(os.Stdout)
	case "stderr":
		log.SetOutput(os.Stderr)
	case "":
		log.SetOutput(ioutil.Discard)
	default:
		file, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
		if err != nil {
			log.Fatalf("Error opening log file: %v", err)
		}
		log.SetOutput(file)
	}

	if version {
		fmt.Printf("%s %s\n", caddy.AppName, caddy.AppVersion)
		os.Exit(0)
	}
	if revoke != "" {
		err := letsencrypt.Revoke(revoke)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("Revoked certificate for %s\n", revoke)
		os.Exit(0)
	}

	// Set CPU cap
	err := setCPU(cpu)
	if err != nil {
		mustLogFatal(err)
	}

	// Get Caddyfile input
	caddyfile, err := caddy.LoadCaddyfile(loadCaddyfile)
	if err != nil {
		mustLogFatal(err)
	}

	// Start your engines
	err = caddy.Start(caddyfile)
	if err != nil {
		if caddy.IsRestart() {
			log.Printf("[ERROR] Upon starting %s: %v", appName, err)
		} else {
			mustLogFatal(err)
		}
	}

	// Twiddle your thumbs
	caddy.Wait()
}

// mustLogFatal just wraps log.Fatal() in a way that ensures the
// output is always printed to stderr so the user can see it,
// even if the process log was not enabled.
func mustLogFatal(args ...interface{}) {
	log.SetOutput(os.Stderr)
	log.Fatal(args...)
}

func loadCaddyfile() (caddy.Input, error) {
	// First try stdin pipe
	cdyfile, err := caddy.CaddyfileFromPipe(os.Stdin)
	if err != nil {
		return nil, err
	}
	if cdyfile != nil {
		// it is an error if -conf is also specified because, which to use?
		if conf != "" {
			return nil, errors.New("load: can't choose between stdin pipe and -conf flag")
		}
		return cdyfile, err
	}

	// -conf flag
	if conf != "" {
		contents, err := ioutil.ReadFile(conf)
		if err != nil {
			return nil, err
		}
		return caddy.CaddyfileInput{
			Contents: contents,
			Filepath: conf,
			RealFile: true,
		}, nil
	}

	// command line args
	if flag.NArg() > 0 {
		confBody := caddy.Host + ":" + caddy.Port + "\n" + strings.Join(flag.Args(), "\n")
		return caddy.CaddyfileInput{
			Contents: []byte(confBody),
			Filepath: "args",
		}, nil
	}

	// Caddyfile in cwd
	contents, err := ioutil.ReadFile(caddy.DefaultConfigFile)
	if err != nil {
		if os.IsNotExist(err) {
			return caddy.DefaultInput(), nil
		}
		return nil, err
	}
	return caddy.CaddyfileInput{
		Contents: contents,
		Filepath: caddy.DefaultConfigFile,
		RealFile: true,
	}, nil
}

// setCPU parses string cpu and sets GOMAXPROCS
// according to its value. It accepts either
// a number (e.g. 3) or a percent (e.g. 50%).
func setCPU(cpu string) error {
	var numCPU int

	availCPU := runtime.NumCPU()

	if strings.HasSuffix(cpu, "%") {
		// Percent
		var percent float32
		pctStr := cpu[:len(cpu)-1]
		pctInt, err := strconv.Atoi(pctStr)
		if err != nil || pctInt < 1 || pctInt > 100 {
			return errors.New("invalid CPU value: percentage must be between 1-100")
		}
		percent = float32(pctInt) / 100
		numCPU = int(float32(availCPU) * percent)
	} else {
		// Number
		num, err := strconv.Atoi(cpu)
		if err != nil || num < 1 {
			return errors.New("invalid CPU value: provide a number or percent greater than 0")
		}
		numCPU = num
	}

	if numCPU > availCPU {
		numCPU = availCPU
	}

	runtime.GOMAXPROCS(numCPU)
	return nil
}
<commit_msg>"-conf stdin" required to pipe in Caddyfile<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strconv"
	"strings"

	"github.com/mholt/caddy/caddy"
	"github.com/mholt/caddy/caddy/letsencrypt"
)

var (
	conf    string
	cpu     string
	version bool
	revoke  string
	logfile string
)

const (
	appName    = "Caddy"
	appVersion = "0.8 beta 3"
)

func init() {
	flag.StringVar(&conf, "conf", "", "Configuration file to use (default="+caddy.DefaultConfigFile+")")
	flag.BoolVar(&caddy.HTTP2, "http2", true, "HTTP/2 support") // TODO: temporary flag until http2 merged into std lib
	flag.BoolVar(&caddy.Quiet, "quiet", false, "Quiet mode (no initialization output)")
	flag.StringVar(&cpu, "cpu", "100%", "CPU cap")
	flag.StringVar(&caddy.Root, "root", caddy.DefaultRoot, "Root path to default site")
	flag.StringVar(&caddy.Host, "host", caddy.DefaultHost, "Default host")
	flag.StringVar(&caddy.Port, "port", caddy.DefaultPort, "Default port")
	flag.BoolVar(&version, "version", false, "Show version")
	// TODO: Boulder dev URL is: http://192.168.99.100:4000
	// TODO: Staging API URL is: https://acme-staging.api.letsencrypt.org
	// TODO: Production endpoint is: https://acme-v01.api.letsencrypt.org
	flag.StringVar(&letsencrypt.CAUrl, "ca", "https://acme-staging.api.letsencrypt.org", "Certificate authority ACME server")
	flag.BoolVar(&letsencrypt.Agreed, "agree", false, "Agree to Let's Encrypt Subscriber Agreement")
	flag.StringVar(&letsencrypt.DefaultEmail, "email", "", "Default Let's Encrypt account email address")
	flag.StringVar(&revoke, "revoke", "", "Hostname for which to revoke the certificate")
	flag.StringVar(&logfile, "log", "", "Process log file")
}

func main() {
	flag.Parse() // called here in main() to allow other packages to set flags in their inits

	caddy.AppName = appName
	caddy.AppVersion = appVersion

	// set up process log before anything bad happens
	switch logfile {
	case "stdout":
		log.SetOutput(os.Stdout)
	case "stderr":
		log.SetOutput(os.Stderr)
	case "":
		log.SetOutput(ioutil.Discard)
	default:
		file, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
		if err != nil {
			log.Fatalf("Error opening log file: %v", err)
		}
		log.SetOutput(file)
	}

	if version {
		fmt.Printf("%s %s\n", caddy.AppName, caddy.AppVersion)
		os.Exit(0)
	}
	if revoke != "" {
		err := letsencrypt.Revoke(revoke)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("Revoked certificate for %s\n", revoke)
		os.Exit(0)
	}

	// Set CPU cap
	err := setCPU(cpu)
	if err != nil {
		mustLogFatal(err)
	}

	// Get Caddyfile input
	caddyfile, err := caddy.LoadCaddyfile(loadCaddyfile)
	if err != nil {
		mustLogFatal(err)
	}

	// Start your engines
	err = caddy.Start(caddyfile)
	if err != nil {
		if caddy.IsRestart() {
			log.Printf("[ERROR] Upon starting %s: %v", appName, err)
		} else {
			mustLogFatal(err)
		}
	}

	// Twiddle your thumbs
	caddy.Wait()
}

// mustLogFatal just wraps log.Fatal() in a way that ensures the
// output is always printed to stderr so the user can see it,
// even if the process log was not enabled.
func mustLogFatal(args ...interface{}) {
	log.SetOutput(os.Stderr)
	log.Fatal(args...)
}

func loadCaddyfile() (caddy.Input, error) {
	// Try -conf flag
	if conf != "" {
		if conf == "stdin" {
			return caddy.CaddyfileFromPipe(os.Stdin)
		}

		contents, err := ioutil.ReadFile(conf)
		if err != nil {
			return nil, err
		}

		return caddy.CaddyfileInput{
			Contents: contents,
			Filepath: conf,
			RealFile: true,
		}, nil
	}

	// command line args
	if flag.NArg() > 0 {
		confBody := caddy.Host + ":" + caddy.Port + "\n" + strings.Join(flag.Args(), "\n")
		return caddy.CaddyfileInput{
			Contents: []byte(confBody),
			Filepath: "args",
		}, nil
	}

	// Caddyfile in cwd
	contents, err := ioutil.ReadFile(caddy.DefaultConfigFile)
	if err != nil {
		if os.IsNotExist(err) {
			return caddy.DefaultInput(), nil
		}
		return nil, err
	}
	return caddy.CaddyfileInput{
		Contents: contents,
		Filepath: caddy.DefaultConfigFile,
		RealFile: true,
	}, nil
}

// setCPU parses string cpu and sets GOMAXPROCS
// according to its value. It accepts either
// a number (e.g. 3) or a percent (e.g. 50%).
func setCPU(cpu string) error {
	var numCPU int

	availCPU := runtime.NumCPU()

	if strings.HasSuffix(cpu, "%") {
		// Percent
		var percent float32
		pctStr := cpu[:len(cpu)-1]
		pctInt, err := strconv.Atoi(pctStr)
		if err != nil || pctInt < 1 || pctInt > 100 {
			return errors.New("invalid CPU value: percentage must be between 1-100")
		}
		percent = float32(pctInt) / 100
		numCPU = int(float32(availCPU) * percent)
	} else {
		// Number
		num, err := strconv.Atoi(cpu)
		if err != nil || num < 1 {
			return errors.New("invalid CPU value: provide a number or percent greater than 0")
		}
		numCPU = num
	}

	if numCPU > availCPU {
		numCPU = availCPU
	}

	runtime.GOMAXPROCS(numCPU)
	return nil
}
<|endoftext|>


<commit_before>package main

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

  "github.com/urfave/negroni"
)

type User struct {
  FirstName string
  LastName string
  Username string
  Secret []byte
  Discoverable bool
  Network string
}

func main()  {
  mux := http.NewServeMux()

  mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    var s []byte
    s = make([]byte, 5, 5)
    user1 := User{"Armand", "Gray", "email", s, true, "Instruct2"}
    user2 := User{"Daniela", "Meza", "username", s, false, "Instruct2"}
    slcUser := []User{user1, user2}

    js, err := json.Marshal(slcUser)
    if err != nil {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      return
    }

    w.Header().Set("Content-Type", "application/json")
    w.Write(js)
  })

  n := negroni.Classic()
  n.UseHandler(mux)
  n.Run(":8080")

}
<commit_msg>Added role to User<commit_after>package main

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

  "github.com/urfave/negroni"
)

type User struct {
  FirstName string
  LastName string
  Username string
  Secret []byte
  Discoverable bool

  Role string
  Network string
}

func main()  {
  mux := http.NewServeMux()

  mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    var s []byte
    s = make([]byte, 5, 5)
    user1 := User{"Armand", "Gray", "email", s, true, "Instruct2", "Software Engineer"}
    user2 := User{"Daniela", "Meza", "username", s, false, "Instruct2", "Program Coordinator"}
    slcUser := []User{user1, user2}

    js, err := json.Marshal(slcUser)
    if err != nil {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      return
    }

    w.Header().Set("Content-Type", "application/json")
    w.Write(js)
  })

  n := negroni.Classic()
  n.UseHandler(mux)
  n.Run(":8080")

}
<|endoftext|>


<commit_before>/*
Package bootstrap implements the capability to connect to an existing and online
Tinzenite peer network.

TODO: add encryption bootstrap capabilities
*/
package bootstrap

import (
	"github.com/tinzenite/channel"
	"github.com/tinzenite/shared"
)

/*
Create returns a struct that will allow to bootstrap to an existing
Tinzenite network. To actually start bootstrapping call Bootstrap.Start(address).
*/
func Create(path, localPeerName string, f Success) (*Bootstrap, error) {
	if shared.IsTinzenite(path) {
		return nil, shared.ErrIsTinzenite
	}
	// build structure
	err := shared.MakeDotTinzenite(path)
	if err != nil {
		return nil, err
	}
	// create object
	boot := &Bootstrap{
		path:   path,
		onDone: f}
	boot.cInterface = createChanInterface(boot)
	channel, err := channel.Create(localPeerName, nil, boot.cInterface)
	if err != nil {
		return nil, err
	}
	boot.channel = channel
	// get address for peer
	address, err := boot.channel.Address()
	if err != nil {
		return nil, err
	}
	// make peer (at correct location!)
	peer, err := shared.CreatePeer(localPeerName, address)
	if err != nil {
		return nil, err
	}
	boot.peer = peer
	// bg stuff
	boot.wg.Add(1)
	boot.stop = make(chan bool, 1)
	go boot.run()
	return boot, nil
}

/*
Load tries to load the given directory as a bootstrap object, allowing it to
connect to an existing network. To actually start bootstrapping call
Bootstrap.Start(address). NOTE: will fail if already connected to other peers!

TODO: strictly speaking we only need the selfpeer... look into this?
*/
func Load(path string, f Success) (*Bootstrap, error) {
	if !shared.IsTinzenite(path) {
		return nil, shared.ErrNotTinzenite
	}
	if !checkValidBootstrap(path) {
		return nil, errNotBootstrapCapable
	}
	// create object
	boot := &Bootstrap{
		path:   path,
		onDone: f}
	boot.cInterface = createChanInterface(boot)
	// load
	toxPeerDump, err := shared.LoadToxDump(path)
	if err != nil {
		return nil, err
	}
	boot.peer = toxPeerDump.SelfPeer
	channel, err := channel.Create(boot.peer.Name, toxPeerDump.ToxData, boot.cInterface)
	if err != nil {
		return nil, err
	}
	boot.channel = channel
	// bg stuff
	boot.wg.Add(1)
	boot.stop = make(chan bool, 1)
	go boot.run()
	return boot, nil
}

/*
checkValidBootstrap from given path. To be valid: must be .TINZENITEDIR, must
have only one peer (hopefully itself), and local/self.json must exit.
*/
func checkValidBootstrap(path string) bool {
	if !shared.IsTinzenite(path) {
		return false
	}
	tinzenPath := path + "/" + shared.TINZENITEDIR
	peerAmount, err := shared.CountFiles(tinzenPath + "/" + shared.ORGDIR + "/" + shared.PEERSDIR)
	if err != nil {
		return false
	}
	return peerAmount == 1 && shared.FileExists(tinzenPath+"/"+shared.LOCALDIR+"/"+shared.SELFPEERJSON)
}
<commit_msg>applied removal of countFiles<commit_after>/*
Package bootstrap implements the capability to connect to an existing and online
Tinzenite peer network.

TODO: add encryption bootstrap capabilities
*/
package bootstrap

import (
	"io/ioutil"

	"github.com/tinzenite/channel"
	"github.com/tinzenite/shared"
)

/*
Create returns a struct that will allow to bootstrap to an existing
Tinzenite network. To actually start bootstrapping call Bootstrap.Start(address).
*/
func Create(path, localPeerName string, f Success) (*Bootstrap, error) {
	if shared.IsTinzenite(path) {
		return nil, shared.ErrIsTinzenite
	}
	// build structure
	err := shared.MakeDotTinzenite(path)
	if err != nil {
		return nil, err
	}
	// create object
	boot := &Bootstrap{
		path:   path,
		onDone: f}
	boot.cInterface = createChanInterface(boot)
	channel, err := channel.Create(localPeerName, nil, boot.cInterface)
	if err != nil {
		return nil, err
	}
	boot.channel = channel
	// get address for peer
	address, err := boot.channel.Address()
	if err != nil {
		return nil, err
	}
	// make peer (at correct location!)
	peer, err := shared.CreatePeer(localPeerName, address)
	if err != nil {
		return nil, err
	}
	boot.peer = peer
	// bg stuff
	boot.wg.Add(1)
	boot.stop = make(chan bool, 1)
	go boot.run()
	return boot, nil
}

/*
Load tries to load the given directory as a bootstrap object, allowing it to
connect to an existing network. To actually start bootstrapping call
Bootstrap.Start(address). NOTE: will fail if already connected to other peers!

TODO: strictly speaking we only need the selfpeer... look into this?
*/
func Load(path string, f Success) (*Bootstrap, error) {
	if !shared.IsTinzenite(path) {
		return nil, shared.ErrNotTinzenite
	}
	if !checkValidBootstrap(path) {
		return nil, errNotBootstrapCapable
	}
	// create object
	boot := &Bootstrap{
		path:   path,
		onDone: f}
	boot.cInterface = createChanInterface(boot)
	// load
	toxPeerDump, err := shared.LoadToxDump(path)
	if err != nil {
		return nil, err
	}
	boot.peer = toxPeerDump.SelfPeer
	channel, err := channel.Create(boot.peer.Name, toxPeerDump.ToxData, boot.cInterface)
	if err != nil {
		return nil, err
	}
	boot.channel = channel
	// bg stuff
	boot.wg.Add(1)
	boot.stop = make(chan bool, 1)
	go boot.run()
	return boot, nil
}

/*
checkValidBootstrap from given path. To be valid: must be .TINZENITEDIR, must
have only one peer (hopefully itself), and local/self.json must exit.
*/
func checkValidBootstrap(path string) bool {
	if !shared.IsTinzenite(path) {
		return false
	}
	tinzenPath := path + "/" + shared.TINZENITEDIR
	stats, err := ioutil.ReadDir(tinzenPath + "/" + shared.ORGDIR + "/" + shared.PEERSDIR)
	if err != nil {
		return false
	}
	return len(stats) == 1 && shared.FileExists(tinzenPath+"/"+shared.LOCALDIR+"/"+shared.SELFPEERJSON)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
)

func main() {
	config, err := ReadConfig("./vvrc")
	if err != nil {
		fmt.Printf("faied to load config file: %s\n", err)
		os.Exit(1)
	}
	addr := config.Mpd.Host + ":" + config.Mpd.Port
	player, err := Dial("tcp", addr)
	if err != nil {
		fmt.Printf("faied to connect/initialize mpd: %s\n", err)
		os.Exit(1)
	}
	App(player, config.Server)
}
<commit_msg>close connection<commit_after>package main

import (
	"fmt"
	"os"
)

func main() {
	config, err := ReadConfig("./vvrc")
	if err != nil {
		fmt.Printf("faied to load config file: %s\n", err)
		os.Exit(1)
	}
	addr := config.Mpd.Host + ":" + config.Mpd.Port
	player, err := Dial("tcp", addr)
	defer player.Close()
	if err != nil {
		fmt.Printf("faied to connect/initialize mpd: %s\n", err)
		os.Exit(1)
	}
	App(player, config.Server)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"

	"golang.org/x/mobile/app"
	"golang.org/x/mobile/event/lifecycle"
	"golang.org/x/mobile/event/paint"
	"golang.org/x/mobile/event/size"
	"golang.org/x/mobile/exp/app/debug"
	"golang.org/x/mobile/exp/gl/glutil"
	"golang.org/x/mobile/gl"
)

const vertexShader = `#version 100
uniform vec2 offset;
attribute vec4 position;
void main() {
	// offset comes in with x/y values between 0 and 1.
	// position bounds are -1 to 1.
	vec4 offset4 = vec4(2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0);
	gl_Position = position + offset4;
}`

const fragmentShader = `#version 100
precision mediump float;
uniform vec4 color;
void main() {
	gl_FragColor = color;
}`

var (
	images   *glutil.Images
	fps      *debug.FPS
	program  gl.Program
	position gl.Attrib
	offset   gl.Uniform
	color    gl.Uniform
	buf      gl.Buffer
)

func onStart(glctx gl.Context) {
	var err error
	program, err = glutil.CreateProgram(glctx, vertexShader, fragmentShader)
	if err != nil {
		log.Printf("error creating GL program: %v", err)
		return
	}

	buf = glctx.CreateBuffer()
	glctx.BindBuffer(gl.ARRAY_BUFFER, buf)

	images = glutil.NewImages(glctx)
	fps = debug.NewFPS(images)
}

func onStop(glctx gl.Context) {
	glctx.DeleteProgram(program)
	glctx.DeleteBuffer(buf)
	fps.Release()
	images.Release()
}

func onPaint(glctx gl.Context, sz size.Event) {
	glctx.ClearColor(1, 0, 0, 1)
	glctx.UseProgram(program)
	fps.Draw(sz)
}

func main() {

	fmt.Println("Starting the app")

	app.Main(func(a app.App) {

		var glctx gl.Context

		visible, sz := false, size.Event{}

		for e := range a.Events() {
			switch e := a.Filter(e).(type) {
			case lifecycle.Event:
				switch e.Crosses(lifecycle.StageVisible) {
				case lifecycle.CrossOn:
					visible = true
					glctx, _ = e.DrawContext.(gl.Context)
					onStart(glctx)
				case lifecycle.CrossOff:
					visible = false
					onStop(glctx)
				}
			case paint.Event:
				onPaint(glctx, sz)
				a.Publish()
				if visible {
					a.Send(paint.Event{})
				}
			}

		}

	})

}
<commit_msg>Fixing the app<commit_after>package main

import (
	"log"

	"golang.org/x/mobile/app"
	"golang.org/x/mobile/event/lifecycle"
	"golang.org/x/mobile/event/paint"
	"golang.org/x/mobile/event/size"
	"golang.org/x/mobile/exp/app/debug"
	"golang.org/x/mobile/exp/gl/glutil"
	"golang.org/x/mobile/gl"
)

const vertexShader = `#version 100
uniform vec2 offset;
attribute vec4 position;
void main() {
	// offset comes in with x/y values between 0 and 1.
	// position bounds are -1 to 1.
	vec4 offset4 = vec4(2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0);
	gl_Position = position + offset4;
}`

const fragmentShader = `#version 100
precision mediump float;
uniform vec4 color;
void main() {
	gl_FragColor = color;
}`

var (
	images   *glutil.Images
	fps      *debug.FPS
	program  gl.Program
	position gl.Attrib
	offset   gl.Uniform
	color    gl.Uniform
	buf      gl.Buffer
)

func onStart(glctx gl.Context) {
	var err error
	program, err = glutil.CreateProgram(glctx, vertexShader, fragmentShader)
	if err != nil {
		log.Printf("error creating GL program: %v", err)
		return
	}

	buf = glctx.CreateBuffer()
	glctx.BindBuffer(gl.ARRAY_BUFFER, buf)

	images = glutil.NewImages(glctx)
	fps = debug.NewFPS(images)
}

func onStop(glctx gl.Context) {
	glctx.DeleteProgram(program)
	glctx.DeleteBuffer(buf)
	fps.Release()
	images.Release()
}

func onPaint(glctx gl.Context, sz size.Event) {
	glctx.ClearColor(128, 0, 128, 1)
	glctx.Clear(gl.COLOR_BUFFER_BIT)

	glctx.UseProgram(program)

	glctx.BindBuffer(gl.ARRAY_BUFFER, buf)
	glctx.EnableVertexAttribArray(position)

	glctx.DisableVertexAttribArray(position)

	fps.Draw(sz)
}

func main() {

	log.Println("Starting the app")

	app.Main(func(a app.App) {

		var glctx gl.Context

		visible, sz := false, size.Event{}

		for e := range a.Events() {
			switch e := a.Filter(e).(type) {
			case lifecycle.Event:
				switch e.Crosses(lifecycle.StageVisible) {
				case lifecycle.CrossOn:
					visible = true
					glctx, _ = e.DrawContext.(gl.Context)
					onStart(glctx)
				case lifecycle.CrossOff:
					visible = false
					onStop(glctx)
				}
			case size.Event:
				sz = e
			case paint.Event:
				onPaint(glctx, sz)
				a.Publish()
				if visible {
					a.Send(paint.Event{})
				}
			}

		}

	})

}
<|endoftext|>