<commit_before>// main.go - onionwrap
//
// To the extent possible under law, Yawning Angel waived all copyright
// and related or neighboring rights to onionwrap, using the creative
// commons "cc0" public domain dedication. See LICENSE or
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.

// onionwrap serves delicious Onion Service Wraps.
package main

import (
	"errors"
	"flag"
	gofmt "fmt"
	"net"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"github.com/yawning/bulb"
	"github.com/yawning/bulb/utils"
)

const (
	controlPortEnv       = "TOR_CONTROL_PORT"
	controlPortPasswdEnv = "TOR_CONTROL_PASSWD"

	localhost          = "127.0.0.1"
	defaultControlPort = "tcp://" + localhost + ":9051"
)

var debugSpew bool
var quietSpew bool
var noRewriteArgs bool

func infof(fmt string, args ...interface{}) {
	if !quietSpew {
		gofmt.Fprintf(os.Stderr, "INFO: "+fmt, args...)
	}
}

func errorf(fmt string, args ...interface{}) {
	gofmt.Fprintf(os.Stderr, "ERROR: "+fmt, args...)
	os.Exit(-1)
}

func debugf(fmt string, args ...interface{}) {
	// This explicitly overrides quietSpew.
	if debugSpew {
		gofmt.Fprintf(os.Stderr, "DEBUG: "+fmt, args...)
	}
}

func parsePort(portStr string) (uint16, error) {
	p, err := strconv.ParseUint(portStr, 10, 16)
	if err != nil {
		return 0, err
	}
	if p == 0 {
		return 0, errors.New("invalid port '0'")
	}
	return uint16(p), nil
}

func parsePortArg(arg string) (virtPort, targetPort, target string, err error) {
	// This is formated as VIRTPORT[,TARGET], which is identical to
	// what the ADD_ONION command expects out of the 'Port' arguments.
	// If the 'TARGET' is omitted, 'VIRTPORT' is mirrored.  If 'TARGET'
	// only a naked port, then '127.0.0.1:TARGET' is used, otherwise
	// 'TARGET' is treated as an address.
	//
	// TODO: Figure out what to do with AF_UNIX.
	if arg == "" {
		return "", "", "", errors.New("no Onion Service port specified")
	}
	splitArg := strings.SplitN(arg, ",", 2)
	virtPort = splitArg[0]
	if _, err = parsePort(virtPort); err != nil {
		return "", "", "", err
	}
	if len(splitArg) == 1 {
		// Only a 'VIRTPORT' was provided, mirror it onto the target.
		return virtPort, virtPort, localhost + ":" + virtPort, nil
	}

	target = splitArg[1]
	if _, err = parsePort(target); err == nil {
		// The 'TARGET' is a naked port.
		return virtPort, target, localhost + ":" + target, nil
	}
	tcpAddr, err := net.ResolveTCPAddr("tcp", target)
	if err != nil {
		return "", "", "", err
	}
	if tcpAddr.Port == 0 {
		return "", "", "", errors.New("target has invalid port '0'")
	}
	targetPort = strconv.Itoa(tcpAddr.Port)
	return
}

func main() {
	//
	// Parse/validate the command line arguments.
	//

	const controlPortArg = "control-port"
	ctrlPortArg := flag.String(controlPortArg, "", "Tor control port")
	flag.Lookup(controlPortArg).DefValue = defaultControlPort
	hsPortArg := flag.String("port", "", "Onion Service port")
	flag.BoolVar(&debugSpew, "debug", false, "Print debug messages to stderr")
	flag.BoolVar(&quietSpew, "quiet", false, "Suppress non-error messages")
	flag.BoolVar(&noRewriteArgs, "no-rewrite", false, "Disable rewriting subprocess arguments")
	flag.Parse()

	// The control port is taken from the argument, the env var, and then
	// the hardcoded default in that order.
	if *ctrlPortArg == "" {
		*ctrlPortArg = os.Getenv(controlPortEnv)
		if *ctrlPortArg == "" {
			*ctrlPortArg = defaultControlPort
		}
	}
	ctrlNet, ctrlAddr, err := utils.ParseControlPortString(*ctrlPortArg)
	if err != nil {
		errorf("Invalid control port: %v\n", err)
	}

	virtPort, targetPort, target, err := parsePortArg(*hsPortArg)
	if err != nil {
		errorf("Invalid virtual port: %v\n", err)
	}

	// The command that will be fork/execed.
	cmdVec := flag.Args()
	var cmd *exec.Cmd
	switch len(cmdVec) {
	case 0:
		errorf("No command specified to wrap.\n")
	case 1:
		cmd = exec.Command(cmdVec[0])
	default:
		cmd = exec.Command(cmdVec[0], cmdVec[1:]...)
	}
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if !noRewriteArgs {
		// Unless explicitly disabled, replace certain variables in the
		// subprocess command line arguments with values propagated from
		// the onionwrap command line.
		//
		//  * %VPORT - The 'VIRTPORT'.
		//  * %TPORT - The port component of 'TARGET'.
		//  * %TADDR - The entire 'TARGET'.
		for i := 1; i < len(cmd.Args); i++ {
			v := cmd.Args[i]
			v = strings.Replace(v, "%VPORT", virtPort, -1)
			v = strings.Replace(v, "%TPORT", targetPort, -1)
			v = strings.Replace(v, "%TADDR", target, -1)
			cmd.Args[i] = v
		}
	}

	debugf("Cmd: %v\n", cmd.Args)
	debugf("CtrlPort: %v, %v\n", ctrlNet, ctrlAddr)
	debugf("VirtPort: %v Target: %v\n", virtPort, target)

	//
	// Do the actual work.
	//

	// Setup the Onion Service, after connecting to the control port.
	ctrlConn, err := bulb.Dial(ctrlNet, ctrlAddr)
	if err != nil {
		errorf("Failed to connect to the control port: %v\n", err)
	}
	defer ctrlConn.Close()
	if err = ctrlConn.Authenticate(os.Getenv(controlPortPasswdEnv)); err != nil {
		errorf("Failed to authenticate with the control port: %v\n", err)
	}

	// TODO: Support saving the PK/Loading a PK.
	resp, err := ctrlConn.Request("ADD_ONION NEW:BEST Port=%s Flags=DiscardPK", *hsPortArg)
	if err != nil {
		errorf("Failed to create onion service: %v\n", err)
	}
	var serviceID string
	for _, l := range resp.Data {
		serviceID = strings.TrimPrefix(l, "ServiceID=")
		if serviceID != l {
			break
		}
	}
	if serviceID == "" {
		// This should *NEVER* happen since the command succeded, and
		// the spec guarantees that this will be sent.
		errorf("Failed to determine service ID.")
	}
	infof("Created onion: %s.onion:%s -> %s\n", serviceID, virtPort, target)

	// Launch the actual process, and block till it exits.  Cleanup
	// is automatic because tor will tear down the Onion Service
	// when the control connection gets closed.
	err = cmd.Run()
	if !cmd.ProcessState.Success() {
		os.Exit(-1)
	}
}
<commit_msg>Try harder to ensure that the child process dies.<commit_after>// main.go - onionwrap
//
// To the extent possible under law, Yawning Angel waived all copyright
// and related or neighboring rights to onionwrap, using the creative
// commons "cc0" public domain dedication. See LICENSE or
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.

// onionwrap serves delicious Onion Service Wraps.
package main

import (
	"errors"
	"flag"
	gofmt "fmt"
	"net"
	"os"
	"os/exec"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/yawning/bulb"
	"github.com/yawning/bulb/utils"
)

const (
	controlPortEnv       = "TOR_CONTROL_PORT"
	controlPortPasswdEnv = "TOR_CONTROL_PASSWD"

	localhost          = "127.0.0.1"
	defaultControlPort = "tcp://" + localhost + ":9051"

	sigKillDelay = 5 * time.Second
)

var debugSpew bool
var quietSpew bool
var noRewriteArgs bool

func infof(fmt string, args ...interface{}) {
	if !quietSpew {
		gofmt.Fprintf(os.Stderr, "INFO: "+fmt, args...)
	}
}

func errorf(fmt string, args ...interface{}) {
	gofmt.Fprintf(os.Stderr, "ERROR: "+fmt, args...)
	os.Exit(-1)
}

func debugf(fmt string, args ...interface{}) {
	// This explicitly overrides quietSpew.
	if debugSpew {
		gofmt.Fprintf(os.Stderr, "DEBUG: "+fmt, args...)
	}
}

func parsePort(portStr string) (uint16, error) {
	p, err := strconv.ParseUint(portStr, 10, 16)
	if err != nil {
		return 0, err
	}
	if p == 0 {
		return 0, errors.New("invalid port '0'")
	}
	return uint16(p), nil
}

func parsePortArg(arg string) (virtPort, targetPort, target string, err error) {
	// This is formated as VIRTPORT[,TARGET], which is identical to
	// what the ADD_ONION command expects out of the 'Port' arguments.
	// If the 'TARGET' is omitted, 'VIRTPORT' is mirrored.  If 'TARGET'
	// only a naked port, then '127.0.0.1:TARGET' is used, otherwise
	// 'TARGET' is treated as an address.
	//
	// TODO: Figure out what to do with AF_UNIX.
	if arg == "" {
		return "", "", "", errors.New("no Onion Service port specified")
	}
	splitArg := strings.SplitN(arg, ",", 2)
	virtPort = splitArg[0]
	if _, err = parsePort(virtPort); err != nil {
		return "", "", "", err
	}
	if len(splitArg) == 1 {
		// Only a 'VIRTPORT' was provided, mirror it onto the target.
		return virtPort, virtPort, localhost + ":" + virtPort, nil
	}

	target = splitArg[1]
	if _, err = parsePort(target); err == nil {
		// The 'TARGET' is a naked port.
		return virtPort, target, localhost + ":" + target, nil
	}
	tcpAddr, err := net.ResolveTCPAddr("tcp", target)
	if err != nil {
		return "", "", "", err
	}
	if tcpAddr.Port == 0 {
		return "", "", "", errors.New("target has invalid port '0'")
	}
	targetPort = strconv.Itoa(tcpAddr.Port)
	return
}

func main() {
	//
	// Parse/validate the command line arguments.
	//

	const controlPortArg = "control-port"
	ctrlPortArg := flag.String(controlPortArg, "", "Tor control port")
	flag.Lookup(controlPortArg).DefValue = defaultControlPort
	hsPortArg := flag.String("port", "", "Onion Service port")
	flag.BoolVar(&debugSpew, "debug", false, "Print debug messages to stderr")
	flag.BoolVar(&quietSpew, "quiet", false, "Suppress non-error messages")
	flag.BoolVar(&noRewriteArgs, "no-rewrite", false, "Disable rewriting subprocess arguments")
	flag.Parse()

	// The control port is taken from the argument, the env var, and then
	// the hardcoded default in that order.
	if *ctrlPortArg == "" {
		*ctrlPortArg = os.Getenv(controlPortEnv)
		if *ctrlPortArg == "" {
			*ctrlPortArg = defaultControlPort
		}
	}
	ctrlNet, ctrlAddr, err := utils.ParseControlPortString(*ctrlPortArg)
	if err != nil {
		errorf("Invalid control port: %v\n", err)
	}

	virtPort, targetPort, target, err := parsePortArg(*hsPortArg)
	if err != nil {
		errorf("Invalid virtual port: %v\n", err)
	}

	// The command that will be fork/execed.
	cmdVec := flag.Args()
	var cmd *exec.Cmd
	switch len(cmdVec) {
	case 0:
		errorf("No command specified to wrap.\n")
	case 1:
		cmd = exec.Command(cmdVec[0])
	default:
		cmd = exec.Command(cmdVec[0], cmdVec[1:]...)
	}
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if !noRewriteArgs {
		// Unless explicitly disabled, replace certain variables in the
		// subprocess command line arguments with values propagated from
		// the onionwrap command line.
		//
		//  * %VPORT - The 'VIRTPORT'.
		//  * %TPORT - The port component of 'TARGET'.
		//  * %TADDR - The entire 'TARGET'.
		for i := 1; i < len(cmd.Args); i++ {
			v := cmd.Args[i]
			v = strings.Replace(v, "%VPORT", virtPort, -1)
			v = strings.Replace(v, "%TPORT", targetPort, -1)
			v = strings.Replace(v, "%TADDR", target, -1)
			cmd.Args[i] = v
		}
	}

	debugf("Cmd: %v\n", cmd.Args)
	debugf("CtrlPort: %v, %v\n", ctrlNet, ctrlAddr)
	debugf("VirtPort: %v Target: %v\n", virtPort, target)

	//
	// Do the actual work.
	//

	// Setup the Onion Service, after connecting to the control port.
	ctrlConn, err := bulb.Dial(ctrlNet, ctrlAddr)
	if err != nil {
		errorf("Failed to connect to the control port: %v\n", err)
	}
	defer ctrlConn.Close()
	if err = ctrlConn.Authenticate(os.Getenv(controlPortPasswdEnv)); err != nil {
		errorf("Failed to authenticate with the control port: %v\n", err)
	}

	// TODO: Support saving the PK/Loading a PK.
	resp, err := ctrlConn.Request("ADD_ONION NEW:BEST Port=%s Flags=DiscardPK", *hsPortArg)
	if err != nil {
		errorf("Failed to create onion service: %v\n", err)
	}
	var serviceID string
	for _, l := range resp.Data {
		serviceID = strings.TrimPrefix(l, "ServiceID=")
		if serviceID != l {
			break
		}
	}
	if serviceID == "" {
		// This should *NEVER* happen since the command succeded, and
		// the spec guarantees that this will be sent.
		errorf("Failed to determine service ID.")
	}
	infof("Created onion: %s.onion:%s -> %s\n", serviceID, virtPort, target)

	// TODO: Wait till the HS descriptor has been published.

	// Initialize the signal handling and launch the process.
	sigChan := make(chan os.Signal)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	err = cmd.Start()
	if err != nil {
		os.Exit(-1)
	}
	doneChan := make(chan error)
	go func() {
		doneChan <- cmd.Wait()
	}()

	onChildExit := func() {
		// Child terminated.
		debugf("child process terminated\n")
		if !cmd.ProcessState.Success() {
			// ProcessState doesn't give the exact return value. :(
			os.Exit(-1)
		}
		os.Exit(0)
	}

	// Wait for the child to finish, or the wrapper to receive
	// SIGINT/SIGTERM.
	select {
	case <-doneChan:
		onChildExit()
	case sig := <-sigChan:
		// Propagate the signal to the child, and wait for it to die.
		debugf("received signal: %v\n", sig)
		cmd.Process.Signal(sig)
		select {
		case <-doneChan:
			onChildExit()
		case <-time.After(sigKillDelay):
			debugf("post signal delay elapsed, killing child\n")
			cmd.Process.Kill()
			os.Exit(-1)
		}
	}
	panic("BUG: fell through the select???") // NOTREACHED
}
<|endoftext|>


<commit_before>/*
   Copyright 2011-2014 gtalent2@gmail.com

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

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

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

import (
	"fmt"
	"io/ioutil"
	"strings"
	"flag"
)

const (
	DEFAULT_LICENSE_FILE = ".liccor"
	SUFFIX_GO = ".go"
	SUFFIX_C = ".c"
	SUFFIX_CPP = ".cpp"
	SUFFIX_CXX = ".cxx"
	SUFFIX_H = ".h"
	SUFFIX_HPP = ".hpp"
	SUFFIX_JAVA = ".java"
	SUFFIX_JS = ".js"
)

var (
	flagLicenseFile string
	flagVerbose bool
)

func verboseLog(msg string) {
	if flagVerbose {
		fmt.Println(msg);
	}
}

func findLicense(dir string) (string, error) {
	verboseLog("Search for '" + flagLicenseFile + "' file at directory '" + dir + "'")

	d, err := ioutil.ReadDir(dir)
	if err != nil {
		return "", fmt.Errorf("Could not find " + flagLicenseFile + " file")
	}
	for _, v := range d {
		if v.Name() == flagLicenseFile {
			licenseData, err := ioutil.ReadFile(dir + "/" + v.Name())
			if err != nil {
				err = fmt.Errorf("Could not access " + flagLicenseFile + " file")
			}
			return string(licenseData), err
		}
	}

	return findLicense(dir + "./.")
}

func findSrcFiles(dir string) ([]string, error) {
	verboseLog("Search source files at '" + dir + "'")

	l, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}
	output := make([]string, 0)
	for _, v := range l {
		if v.IsDir() {
			// ignore .git dir
			if v.Name() != ".git" {
				files, err := findSrcFiles(dir + "/" + v.Name())
				if err != nil {
					return output, err
				}
				for _, v2 := range files {
					output = append(output, v2)
				}
			}
		} else {
			pt := strings.LastIndex(v.Name(), ".")
			if pt == -1 {
				continue
			}
			switch v.Name()[pt:] {
			case SUFFIX_GO, SUFFIX_C, SUFFIX_CPP, SUFFIX_CXX, SUFFIX_H, SUFFIX_HPP, SUFFIX_JAVA, SUFFIX_JS:
				srcPath := dir+"/"+v.Name()
				output = append(output, srcPath)
				verboseLog("Found source '" + srcPath + "'");
			}
		}
	}
	return output, err
}

func hasLicense(file string) (bool, int) {
	for i, c := range file {
		switch c {
		case ' ', '\t', '\n':
			continue
		case '/':
			i++
			if len(file) > i && file[i] == '*' {
				return true, i
			}
		default:
			return false, -1
		}
	}
	return false, -1
}

func correct(path, license string) (bool, error) {
	input, err := ioutil.ReadFile(path)
	if err != nil {
		return false, err
	}
	file := string(input)
	orig := file
	if hasLicense, licenseStart := hasLicense(file); hasLicense {
		//remove old license
		for i := licenseStart; i < len(file); i++ {
			if file[i] == '*' && file[i+1] == '/' {
				i += 2
				if file[i] == '\n' {
					i += 1
				}
				file = file[i:len(file)]
				break
			}
		}
	}
	file = license + file
	output := []byte(file)
	if file != orig {
		err = ioutil.WriteFile(path, output, 0)
		return true, err
	}
	return false, nil
}

func init() {
	flag.StringVar(&flagLicenseFile, "license", DEFAULT_LICENSE_FILE, "the name of the license file")
	flag.StringVar(&flagLicenseFile, "l", DEFAULT_LICENSE_FILE, "shortcut for license")
	flag.BoolVar(&flagVerbose, "verbose", false, "print verbose output")
	flag.BoolVar(&flagVerbose, "v", false, "shortcut for verbose")
}

func main() {
	flag.Parse()

	licenseData, err := findLicense(".")
	if err != nil {
		fmt.Println(err)
		return
	}
	licenseData = licenseData[0 : len(licenseData)-1]
	lics := make(map[string]string)
	lics["c-like"] = "/*\n * " + strings.Replace(string(licenseData), "\n", "\n * ", -1) + "\n */\n"
	lics["go"] = func() string {
		golic := "/*\n   " + strings.Replace(string(licenseData), "\n", "\n   ", -1) + "\n*/\n"
		golic = strings.Replace(golic, "\n   \n", "\n\n", -1)
		return golic
	}()

	files, err := findSrcFiles(".")
	if err != nil {
		return
	}

	for i := 0; i < len(files); i++ {
		pt := strings.LastIndex(files[i], ".")
		lic := ""
		//determine how to format the license
		switch files[i][pt:] {
		case SUFFIX_GO:
			lic = lics["go"]
		case SUFFIX_C, SUFFIX_CPP, SUFFIX_CXX, SUFFIX_H, SUFFIX_HPP, SUFFIX_JAVA, SUFFIX_JS:
			lic = lics["c-like"]
		}
		changed, err := correct(files[i], lic)
		if changed {
			if err != nil {
				fmt.Println("Correcting '" + files[i][2:]+"'... Failure!")
			} else {
				fmt.Println("Correcting '" + files[i][2:]+"'... Success!")
			}
		} else {
			fmt.Println("All files up to date!");
		}
	}
}
<commit_msg>Customize Usage out<commit_after>/*
   Copyright 2011-2014 gtalent2@gmail.com

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

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

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

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

const (
	DEFAULT_LICENSE_FILE = ".liccor"
	SUFFIX_GO = ".go"
	SUFFIX_C = ".c"
	SUFFIX_CPP = ".cpp"
	SUFFIX_CXX = ".cxx"
	SUFFIX_H = ".h"
	SUFFIX_HPP = ".hpp"
	SUFFIX_JAVA = ".java"
	SUFFIX_JS = ".js"
)

var (
	flagLicenseFile string
	flagVerbose bool
)

func verboseLog(msg string) {
	if flagVerbose {
		fmt.Println(msg);
	}
}

func findLicense(dir string) (string, error) {
	verboseLog("Search for '" + flagLicenseFile + "' file at directory '" + dir + "'")

	d, err := ioutil.ReadDir(dir)
	if err != nil {
		return "", fmt.Errorf("Could not find " + flagLicenseFile + " file")
	}
	for _, v := range d {
		if v.Name() == flagLicenseFile {
			licenseData, err := ioutil.ReadFile(dir + "/" + v.Name())
			if err != nil {
				err = fmt.Errorf("Could not access " + flagLicenseFile + " file")
			}
			return string(licenseData), err
		}
	}

	return findLicense(dir + "./.")
}

func findSrcFiles(dir string) ([]string, error) {
	verboseLog("Search source files at '" + dir + "'")

	l, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}
	output := make([]string, 0)
	for _, v := range l {
		if v.IsDir() {
			// ignore .git dir
			if v.Name() != ".git" {
				files, err := findSrcFiles(dir + "/" + v.Name())
				if err != nil {
					return output, err
				}
				for _, v2 := range files {
					output = append(output, v2)
				}
			}
		} else {
			pt := strings.LastIndex(v.Name(), ".")
			if pt == -1 {
				continue
			}
			switch v.Name()[pt:] {
			case SUFFIX_GO, SUFFIX_C, SUFFIX_CPP, SUFFIX_CXX, SUFFIX_H, SUFFIX_HPP, SUFFIX_JAVA, SUFFIX_JS:
				srcPath := dir+"/"+v.Name()
				output = append(output, srcPath)
				verboseLog("Found source '" + srcPath + "'");
			}
		}
	}
	return output, err
}

func hasLicense(file string) (bool, int) {
	for i, c := range file {
		switch c {
		case ' ', '\t', '\n':
			continue
		case '/':
			i++
			if len(file) > i && file[i] == '*' {
				return true, i
			}
		default:
			return false, -1
		}
	}
	return false, -1
}

func correct(path, license string) (bool, error) {
	input, err := ioutil.ReadFile(path)
	if err != nil {
		return false, err
	}
	file := string(input)
	orig := file
	if hasLicense, licenseStart := hasLicense(file); hasLicense {
		//remove old license
		for i := licenseStart; i < len(file); i++ {
			if file[i] == '*' && file[i+1] == '/' {
				i += 2
				if file[i] == '\n' {
					i += 1
				}
				file = file[i:len(file)]
				break
			}
		}
	}
	file = license + file
	output := []byte(file)
	if file != orig {
		err = ioutil.WriteFile(path, output, 0)
		return true, err
	}
	return false, nil
}

func init() {
	flag.StringVar(&flagLicenseFile, "license", DEFAULT_LICENSE_FILE, "the name of the license file")
	flag.StringVar(&flagLicenseFile, "l", DEFAULT_LICENSE_FILE, "shortcut for license")
	flag.BoolVar(&flagVerbose, "verbose", false, "print verbose output")
	flag.BoolVar(&flagVerbose, "v", false, "shortcut for verbose")
	flag.Usage = func() {
		fmt.Print("\n")
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
		fmt.Println("\nOptions:")
		flag.PrintDefaults()
		fmt.Println("\nExample usage:")
		fmt.Println("  ./liccor -verbose")
		fmt.Print("\n\n")
	}
}

func main() {
	flag.Parse()

	licenseData, err := findLicense(".")
	if err != nil {
		fmt.Println(err)
		return
	}
	licenseData = licenseData[0 : len(licenseData)-1]
	lics := make(map[string]string)
	lics["c-like"] = "/*\n * " + strings.Replace(string(licenseData), "\n", "\n * ", -1) + "\n */\n"
	lics["go"] = func() string {
		golic := "/*\n   " + strings.Replace(string(licenseData), "\n", "\n   ", -1) + "\n*/\n"
		golic = strings.Replace(golic, "\n   \n", "\n\n", -1)
		return golic
	}()

	files, err := findSrcFiles(".")
	if err != nil {
		return
	}

	for i := 0; i < len(files); i++ {
		pt := strings.LastIndex(files[i], ".")
		lic := ""
		//determine how to format the license
		switch files[i][pt:] {
		case SUFFIX_GO:
			lic = lics["go"]
		case SUFFIX_C, SUFFIX_CPP, SUFFIX_CXX, SUFFIX_H, SUFFIX_HPP, SUFFIX_JAVA, SUFFIX_JS:
			lic = lics["c-like"]
		}
		changed, err := correct(files[i], lic)
		if changed {
			if err != nil {
				fmt.Println("Correcting '" + files[i][2:]+"'... Failure!")
			} else {
				fmt.Println("Correcting '" + files[i][2:]+"'... Success!")
			}
		} else {
			fmt.Println("All files up to date!");
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 The Radio Noise Project Members
// See COPYING for the license terms and complete list of copyright holders

package main

import (
	"flag"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	"github.com/radionoiseproject/rnp-server/hub"
	"github.com/radionoiseproject/rnp-server/user"
	"net"
	"net/http"
	"os"
	"strings"
)

var (
	bind = flag.String("bind", ":8080", "address and port to listen on")
)

type misakaNotFoundHandler struct{}

func (_ misakaNotFoundHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	w.WriteHeader(404)
	fmt.Fprintf(w, "“‘You seem to be a bit lost,’ MISAKA says as she looks on with a concerned expression.”")
}

func main() {
	flag.Parse()

	h := hub.New()
	go h.Run()

	router := mux.NewRouter()
	router.NotFoundHandler = misakaNotFoundHandler{}
	router.Handle("/rnp", user.Handler(h))

	loggedRouter := handlers.CombinedLoggingHandler(os.Stderr, router)

	http.Handle("/", loggedRouter)

	var l net.Listener
	var listenFields log.Fields
	if strings.ContainsRune(*bind, '/') {
		listenFields = log.Fields{"bind": *bind, "listener": "unix"}
		a, err := net.ResolveUnixAddr("unix", *bind)
		if err != nil {
			log.WithFields(listenFields).Fatal(err)
		}
		l, err = net.ListenUnix("unix", a)
		if err != nil {
			log.WithFields(listenFields).Fatal(err)
		}
	} else {
		listenFields = log.Fields{"bind": *bind, "listener": "tcp"}
		a, err := net.ResolveTCPAddr("tcp", *bind)
		if err != nil {
			log.WithFields(listenFields).Fatal(err)
		}
		l, err = net.ListenTCP("tcp", a)
		if err != nil {
			log.WithFields(listenFields).Fatal(err)
		}
	}

	log.WithFields(listenFields).Info("Radio Noise Project listening")

	if err := http.Serve(l, nil); err != nil {
		log.Fatal(err)
	}

	h.Done()
}
<commit_msg>Unlink unix socket on exit<commit_after>// Copyright (c) 2015 The Radio Noise Project Members
// See COPYING for the license terms and complete list of copyright holders

package main

import (
	"flag"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	"github.com/radionoiseproject/rnp-server/hub"
	"github.com/radionoiseproject/rnp-server/user"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
)

var (
	bind     = flag.String("bind", ":8080", "address and port to listen on")
	loglevel = flag.String("loglevel", "info", "level of log output (debug, info, warn, error, fatal, panic)")
)

type misakaNotFoundHandler struct{}

func (_ misakaNotFoundHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	w.WriteHeader(404)
	fmt.Fprintf(w, "“‘You seem to be a bit lost,’ MISAKA says as she looks on with a concerned expression.”")
}

func main() {
	flag.Parse()

	// Logging setup
	level, err := log.ParseLevel(*loglevel)
	if err != nil {
		log.Fatal(err)
	}
	log.SetLevel(level)

	h := hub.New()
	go h.Run()

	router := mux.NewRouter()
	router.NotFoundHandler = misakaNotFoundHandler{}
	router.Handle("/rnp", user.Handler(h))

	logHandler := handlers.CombinedLoggingHandler(os.Stderr, router)
	proxyHeaderHandler := handlers.ProxyHeaders(logHandler)

	http.Handle("/", proxyHeaderHandler)

	var l net.Listener
	var listenFields log.Fields
	if strings.ContainsRune(*bind, '/') {
		listenFields = log.Fields{"bind": *bind, "listener": "unix"}
		a, err := net.ResolveUnixAddr("unix", *bind)
		if err != nil {
			log.WithFields(listenFields).Fatal(err)
		}
		l, err = net.ListenUnix("unix", a)
		if err != nil {
			log.WithFields(listenFields).Fatal(err)
		}
		defer func() {
			log.WithFields(listenFields).Debug("Cleaning up socket")
			err = os.Remove(*bind)
			if err != nil {
				log.WithFields(listenFields).Fatalf(
					"Failed to unlink socket: %s", err)
			}
		}()
		err = os.Chmod(*bind, os.ModePerm)
		if err != nil {
			log.WithFields(listenFields).Fatalf("Could not set socket permissions: %s", err)
		}
	} else {
		listenFields = log.Fields{"bind": *bind, "listener": "tcp"}
		a, err := net.ResolveTCPAddr("tcp", *bind)
		if err != nil {
			log.WithFields(listenFields).Fatal(err)
		}
		l, err = net.ListenTCP("tcp", a)
		if err != nil {
			log.WithFields(listenFields).Fatal(err)
		}
	}

	go func() {
		if err := http.Serve(l, nil); err != nil {
			log.Fatal(err)
		}
	}()
	log.WithFields(listenFields).Info("Radio Noise Project listening")

	sigChan := make(chan os.Signal)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGQUIT)

	sig := <-sigChan
	log.WithFields(log.Fields{"signal": sig}).Info("Exiting due to signal")

	h.Done()
}
<|endoftext|>


<commit_before>// Copyright 2016 Jacob Taylor jacob@ablox.io
// License: Apache2 - http://www.apache.org/licenses/LICENSE-2.0
package main

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/urfave/cli"
	"log"
	"os"
	"path/filepath"
)

// settings for the server
type Settings struct {
	Directory string
}

var globalSettings Settings = Settings{
	Directory: "",
}

func main() {
	fmt.Printf("replicat initializing....\n")

	app := cli.NewApp()
	app.Name = "Replicat"
	app.Usage = "rsync for the cloud"
	app.Action = func(c *cli.Context) error {
		globalSettings.Directory = c.GlobalString("directory")

		if globalSettings.Directory == "" {
			panic("directory is required to serve files\n")
		}

		return nil
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "directory, d",
			Value:  globalSettings.Directory,
			Usage:  "Specify a directory where the files to share are located.",
			EnvVar: "DIRECTORY",
		},
	}

	app.Run(os.Args)

	fmt.Printf("replicat online....\n")
	fmt.Printf("serving files from: %s\n", globalSettings.Directory)

	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}
	defer watcher.Close()
	defer fmt.Printf("End of line\n")

	done := make(chan bool)
	go func() {
		for {
			select {
			case event := <-watcher.Events:
				if event.Op&fsnotify.Write == fsnotify.Write {
					log.Println("file updated:", event.Name)
				} else {
					log.Println("event:", event)
				}
			case err := <-watcher.Errors:
				log.Println("error:", err)
			}
		}
	}()

	listOfFolders, err := createListOfFolders(globalSettings.Directory)
	if err != nil {
		log.Fatal(err)
	}

	for _, folder := range listOfFolders {
		err = watcher.Add(folder)
		if err != nil {
			log.Fatal(err)
		}
	}

	fmt.Printf("Now listing on: %d folders under: %s\n", len(listOfFolders), globalSettings.Directory)

	// Let's read the
	<-done

}

func createListOfFolders(basePath string) ([]string, error) {
	paths := make([]string, 0, 100)
	pendingPaths := make([]string, 0, 100)
	pendingPaths = append(pendingPaths, basePath)

	for len(pendingPaths) > 0 {
		currentPath := pendingPaths[0]
		paths = append(paths, currentPath)
		pendingPaths = pendingPaths[1:]

		// Read the directories in the path
		f, err := os.Open(currentPath)
		if err != nil {
			return nil, err
		}
		dirEntries, err := f.Readdir(-1)
		for _, entry := range dirEntries {
			if entry.IsDir() {
				entry.Mode()
				newDirectory := filepath.Join(currentPath, entry.Name())
				pendingPaths = append(pendingPaths, newDirectory)
			}
		}
		f.Close()
		if err != nil {
			return nil, err
		}
	}

	return paths, nil
}
<commit_msg>building file list with slop code<commit_after>// Copyright 2016 Jacob Taylor jacob@ablox.io
// License: Apache2 - http://www.apache.org/licenses/LICENSE-2.0
package main

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/urfave/cli"
	"log"
	"os"
	"path/filepath"
)

// settings for the server
type Settings struct {
	Directory string
}

var globalSettings Settings = Settings{
	Directory: "",
}

func main() {
	fmt.Printf("replicat initializing....\n")

	app := cli.NewApp()
	app.Name = "Replicat"
	app.Usage = "rsync for the cloud"
	app.Action = func(c *cli.Context) error {
		globalSettings.Directory = c.GlobalString("directory")

		if globalSettings.Directory == "" {
			panic("directory is required to serve files\n")
		}

		return nil
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "directory, d",
			Value:  globalSettings.Directory,
			Usage:  "Specify a directory where the files to share are located.",
			EnvVar: "DIRECTORY",
		},
	}

	app.Run(os.Args)

	fmt.Printf("replicat online....\n")
	fmt.Printf("serving files from: %s\n", globalSettings.Directory)

	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}
	defer watcher.Close()
	defer fmt.Printf("End of line\n")

	done := make(chan bool)
	go func() {
		for {
			select {
			case event := <-watcher.Events:
				if event.Op&fsnotify.Write == fsnotify.Write {
					log.Println("file updated:", event.Name)
				} else {
					log.Println("event:", event)
				}
			case err := <-watcher.Errors:
				log.Println("error:", err)
			}
		}
	}()

	listOfFolders, err := createListOfFolders(globalSettings.Directory)
	if err != nil {
		log.Fatal(err)
	}

	for _, folder := range listOfFolders {
		err = watcher.Add(folder)
		if err != nil {
			log.Fatal(err)
		}
	}

	fmt.Printf("Now listing on: %d folders under: %s\n", len(listOfFolders), globalSettings.Directory)

	fmt.Println("Scanning files")

	//listOfFiles := make(map[string][]string)
	//
	//sort.Strings(listOfFolders)
	//for _, folder := range listOfFolders {
	//	fmt.Printf("%s\n", folder)
	//
	//
	//}

	// Let's read the
	<-done

}

func createListOfFolders(basePath string) ([]string, error) {
	paths := make([]string, 0, 100)
	pendingPaths := make([]string, 0, 100)
	pendingPaths = append(pendingPaths, basePath)
	listOfFileInfo := make(map[string][]os.FileInfo)

	for len(pendingPaths) > 0 {
		currentPath := pendingPaths[0]
		paths = append(paths, currentPath)
		fileList := make([]os.FileInfo, 0, 100)
		pendingPaths = pendingPaths[1:]

		// Read the directories in the path
		f, err := os.Open(currentPath)
		if err != nil {
			return nil, err
		}
		dirEntries, err := f.Readdir(-1)
		for _, entry := range dirEntries {
			if entry.IsDir() {
				entry.Mode()
				newDirectory := filepath.Join(currentPath, entry.Name())
				pendingPaths = append(pendingPaths, newDirectory)
			} else {
				fmt.Println("Before Adding %s to %v", entry, fileList)
				fileList = append(fileList, entry)
				fmt.Println("Done   Adding %s to %v", entry, fileList)
			}
		}
		f.Close()
		if err != nil {
			return nil, err
		}

		fmt.Printf("setting %s files to %v\n", currentPath, fileList)
		listOfFileInfo[currentPath] = fileList
	}

	fmt.Println("About to print")
	for _, folder := range paths {
		fmt.Printf("PATH: %s\n", folder)
		for _, entry := range listOfFileInfo[folder] {
			fmt.Printf("%s\n", entry)
		}
	}

	return paths, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"sort"
)

type ItemFrequency struct {
	item string
	freq int
}

func GetFrequencies(str string, max_len int) (freqs []ItemFrequency) {
	freq_map := make(map[string]int, 10)

	for start := range str {
		for end := start + 1; end < len(str) && end-start <= max_len; end++ {
			slice := str[start:end]
			if _, ok := freq_map[slice]; ok {
				freq_map[slice] += 1
			} else {
				freq_map[slice] = 1
			}
		}
	}

	freqs = make([]ItemFrequency, len(freq_map))
	i := 0
	for item, freq := range freq_map {
		freqs[i] = ItemFrequency{
			item: item,
			freq: freq}
		i += 1
	}

	sort.Slice(freqs, func(i, j int) bool { return freqs[i].freq > freqs[j].freq })
	return
}

func main() {
	input_flag := flag.String("input", "", "Input string for the compression algorithm")

	flag.Parse()

	input := *input_flag

	freqs := GetFrequencies(input, 2)

	fmt.Printf("input = %s\n\n", input)
	fmt.Printf("freqs =\n")

	for _, pair := range freqs {
		fmt.Printf("%d\t'%s'\n", pair.freq, pair.item)
	}

}
<commit_msg>added reading from file or stdin<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"os"
	"sort"
)

type ItemFrequency struct {
	item string
	freq int
}

func GetFrequencies(str string, max_len int) (freqs []ItemFrequency) {
	freq_map := make(map[string]int, 10)

	for start := range str {
		for end := start + 1; end < len(str) && end-start <= max_len; end++ {
			slice := str[start:end]
			if _, ok := freq_map[slice]; ok {
				freq_map[slice] += 1
			} else {
				freq_map[slice] = 1
			}
		}
	}

	freqs = make([]ItemFrequency, len(freq_map))
	i := 0
	for item, freq := range freq_map {
		freqs[i] = ItemFrequency{
			item: item,
			freq: freq}
		i += 1
	}

	sort.Slice(freqs, func(i, j int) bool { return freqs[i].freq > freqs[j].freq })
	return
}

func main() {

	file_name := flag.String("i", "", "Input file")
	max_freq_group_len := flag.Int("mfgl", 2, "Maximum length in bytes for grouping in algorithm")
	flag.Parse()

	var file *os.File

	if *file_name == "" {
		file = os.Stdin
	} else {
		var err interface{}
		file, err = os.Open(*file_name)
		if err != nil {
			panic(err)
		}
	}

	if *max_freq_group_len < 1 || *max_freq_group_len >= 8 {
		panic("Specified max_freq_group_len is not allowed")
	}

	var input_buff bytes.Buffer
	io.Copy(&input_buff, file)

	input := input_buff.String()

	freqs := GetFrequencies(input, *max_freq_group_len)

	for _, pair := range freqs {
		fmt.Printf("%d\t'%s'\n", pair.freq, pair.item)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"os/exec"
	"runtime"
	"syscall"
)

const VERSION = "1.2"

func init() {
	// make sure we only have one process and that it runs on the main thread (so that ideally, when we Exec, we keep our user switches and stuff)
	runtime.GOMAXPROCS(1)
	runtime.LockOSThread()
}

func main() {
	log.SetFlags(0) // no timestamps on our logs

	if len(os.Args) <= 2 {
		log.Printf("Usage: %s user-spec command [args]", os.Args[0])
		log.Printf("   ie: %s tianon bash", os.Args[0])
		log.Printf("       %s nobody:root bash -c 'whoami && id'", os.Args[0])
		log.Printf("       %s 1000:1 id", os.Args[0])
		log.Println()
		log.Printf("%s version: %s (%s on %s/%s; %s)", os.Args[0], VERSION, runtime.Version(), runtime.GOOS, runtime.GOARCH, runtime.Compiler)
		log.Println()
		os.Exit(1)
	}

	err := SetupUser(os.Args[1])
	if err != nil {
		log.Fatalf("error: failed switching to %q: %v", os.Args[1], err)
	}

	name, err := exec.LookPath(os.Args[2])
	if err != nil {
		log.Fatalf("error: %v", err)
	}

	err = syscall.Exec(name, os.Args[2:], os.Environ())
	if err != nil {
		log.Fatalf("error: exec failed: %v", err)
	}
}
<commit_msg>Add golang.org/s/go14customimport<commit_after>package main // import "github.com/tianon/gosu"

import (
	"log"
	"os"
	"os/exec"
	"runtime"
	"syscall"
)

const VERSION = "1.2"

func init() {
	// make sure we only have one process and that it runs on the main thread (so that ideally, when we Exec, we keep our user switches and stuff)
	runtime.GOMAXPROCS(1)
	runtime.LockOSThread()
}

func main() {
	log.SetFlags(0) // no timestamps on our logs

	if len(os.Args) <= 2 {
		log.Printf("Usage: %s user-spec command [args]", os.Args[0])
		log.Printf("   ie: %s tianon bash", os.Args[0])
		log.Printf("       %s nobody:root bash -c 'whoami && id'", os.Args[0])
		log.Printf("       %s 1000:1 id", os.Args[0])
		log.Println()
		log.Printf("%s version: %s (%s on %s/%s; %s)", os.Args[0], VERSION, runtime.Version(), runtime.GOOS, runtime.GOARCH, runtime.Compiler)
		log.Println()
		os.Exit(1)
	}

	err := SetupUser(os.Args[1])
	if err != nil {
		log.Fatalf("error: failed switching to %q: %v", os.Args[1], err)
	}

	name, err := exec.LookPath(os.Args[2])
	if err != nil {
		log.Fatalf("error: %v", err)
	}

	err = syscall.Exec(name, os.Args[2:], os.Environ())
	if err != nil {
		log.Fatalf("error: exec failed: %v", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/captncraig/github-webhooks"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

var scriptDir string
var scriptExt = ".sh"

func init() {
	scriptDir = os.Getenv("TINYCI-SCRIPT-DIR")

	if scriptDir == "" {
		var err error
		scriptDir, err = os.Getwd()
		if err != nil {
			log.Fatal(err)
		}
		scriptDir = filepath.Join(scriptDir, "scripts")
	}
	if runtime.GOOS == "windows" {
		scriptExt = ".bat"
	}
}

func main() {

	gitHooks := webhooks.WebhookListener{}
	gitHooks.OnPush = githubHook
	http.HandleFunc("/gh", gitHooks.GetHttpListener())
	http.ListenAndServe(":4567", nil)
}

func githubHook(event *webhooks.PushEvent, _ *webhooks.WebhookContext) {
	repo := strings.Replace(event.Repository.FullName, "/", ".", -1)
	refPath := strings.Split(event.Ref, "/")
	ref := refPath[len(refPath)-1]
	runScriptIfExists(fmt.Sprintf("%s", repo))
	runScriptIfExists(fmt.Sprintf("%s:%s", repo, ref))
}

func runScriptIfExists(name string) {
	filename := filepath.Join(scriptDir, name+scriptExt)
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		fmt.Printf("no such file or directory: %s", filename)
		return
	}
	cmd := exec.Command(filename)
	output, err := cmd.CombinedOutput()
	fmt.Println(output, err)
}
<commit_msg>better message<commit_after>package main

import (
	"fmt"
	"github.com/captncraig/github-webhooks"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

var scriptDir string
var scriptExt = ".sh"

func init() {
	scriptDir = os.Getenv("TINYCI-SCRIPT-DIR")

	if scriptDir == "" {
		var err error
		scriptDir, err = os.Getwd()
		if err != nil {
			log.Fatal(err)
		}
		scriptDir = filepath.Join(scriptDir, "scripts")
	}
	if runtime.GOOS == "windows" {
		scriptExt = ".bat"
	}
}

func main() {

	gitHooks := webhooks.WebhookListener{}
	gitHooks.OnPush = githubHook
	http.HandleFunc("/gh", gitHooks.GetHttpListener())
	http.ListenAndServe(":4567", nil)
}

func githubHook(event *webhooks.PushEvent, _ *webhooks.WebhookContext) {
	repo := strings.Replace(event.Repository.FullName, "/", ".", -1)
	refPath := strings.Split(event.Ref, "/")
	ref := refPath[len(refPath)-1]
	runScriptIfExists(fmt.Sprintf("%s", repo))
	runScriptIfExists(fmt.Sprintf("%s:%s", repo, ref))
}

func runScriptIfExists(name string) {
	filename := filepath.Join(scriptDir, name+scriptExt)
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		fmt.Println("Script does not exist: %s. Skipping\n", filename)
		return
	}
	cmd := exec.Command(filename)
	output, err := cmd.CombinedOutput()
	fmt.Println(output, err)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
	"os"

	"github.com/concourse/atc/auth/provider"
	"github.com/concourse/fly/commands"
	"github.com/concourse/fly/rc"
	"github.com/concourse/fly/ui"
	"github.com/concourse/go-concourse/concourse"
	"github.com/jessevdk/go-flags"

	_ "github.com/concourse/atc/auth/genericoauth"
	_ "github.com/concourse/atc/auth/github"
	_ "github.com/concourse/atc/auth/uaa"
)

func main() {
	parser := flags.NewParser(&commands.Fly, flags.HelpFlag|flags.PassDoubleDash)
	parser.NamespaceDelimiter = "-"

	setTeamCommand := parser.Find("set-team")
	authConfigs := make(provider.AuthConfigs)

	for name, p := range provider.GetProviders() {
		authConfigs[name] = p.AddAuthGroup(setTeamCommand.Group)
	}

	commands.Fly.SetTeam.ProviderAuth = authConfigs

	_, err := parser.Parse()
	if err != nil {
		if err == concourse.ErrUnauthorized {
			fmt.Fprintln(ui.Stderr, "not authorized. run the following to log in:")
			fmt.Fprintln(ui.Stderr, "")
			fmt.Fprintln(ui.Stderr, "    "+ui.Embolden("fly -t %s login", commands.Fly.Target))
			fmt.Fprintln(ui.Stderr, "")
		} else if err == rc.ErrNoTargetSpecified {
			fmt.Fprintln(ui.Stderr, "no target specified. specify the target with "+ui.Embolden("-t")+" or log in like so:")
			fmt.Fprintln(ui.Stderr, "")
			fmt.Fprintln(ui.Stderr, "    "+ui.Embolden("fly -t (alias) login -c (concourse url)"))
			fmt.Fprintln(ui.Stderr, "")
		} else if versionErr, ok := err.(rc.ErrVersionMismatch); ok {
			fmt.Fprintln(ui.Stderr, versionErr.Error())
			fmt.Fprintln(ui.Stderr, ui.WarningColor("cowardly refusing to run due to significant version discrepancy"))
		} else if netErr, ok := err.(net.Error); ok {
			fmt.Fprintf(ui.Stderr, "could not reach the Concourse server called %s:\n", ui.Embolden("%s", commands.Fly.Target))

			fmt.Fprintln(ui.Stderr, "")
			fmt.Fprintln(ui.Stderr, "    "+ui.Embolden("%s", netErr))
			fmt.Fprintln(ui.Stderr, "")
			fmt.Fprintln(ui.Stderr, "is the targeted Concourse running? better go catch it lol")
		} else if err == commands.ErrShowHelpMessage {
			helpParser := flags.NewParser(&commands.Fly, flags.HelpFlag)
			helpParser.NamespaceDelimiter = "-"
			helpParser.ParseArgs([]string{"-h"})
			helpParser.WriteHelp(os.Stdout)
			os.Exit(0)
		} else {
			fmt.Fprintf(ui.Stderr, "error: %s\n", err)
		}

		os.Exit(1)
	}
}
<commit_msg>fix setting up auth flags<commit_after>package main

import (
	"fmt"
	"net"
	"os"

	"github.com/concourse/atc/auth/provider"
	"github.com/concourse/fly/commands"
	"github.com/concourse/fly/rc"
	"github.com/concourse/fly/ui"
	"github.com/concourse/go-concourse/concourse"
	"github.com/jessevdk/go-flags"

	_ "github.com/concourse/atc/auth/genericoauth"
	_ "github.com/concourse/atc/auth/github"
	_ "github.com/concourse/atc/auth/uaa"
)

func main() {
	parser := flags.NewParser(&commands.Fly, flags.HelpFlag|flags.PassDoubleDash)
	parser.NamespaceDelimiter = "-"

	setTeamCommand := parser.Find("set-team")
	authConfigs := make(provider.AuthConfigs)

	for name, p := range provider.GetProviders() {
		authGroup := p.AuthGroup()

		group, err := setTeamCommand.Group.AddGroup(authGroup.Name(), "", authGroup.AuthConfig())
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		group.Namespace = authGroup.Namespace()

		authConfigs[name] = authGroup.AuthConfig()
	}

	commands.Fly.SetTeam.ProviderAuth = authConfigs

	_, err := parser.Parse()
	if err != nil {
		if err == concourse.ErrUnauthorized {
			fmt.Fprintln(ui.Stderr, "not authorized. run the following to log in:")
			fmt.Fprintln(ui.Stderr, "")
			fmt.Fprintln(ui.Stderr, "    "+ui.Embolden("fly -t %s login", commands.Fly.Target))
			fmt.Fprintln(ui.Stderr, "")
		} else if err == rc.ErrNoTargetSpecified {
			fmt.Fprintln(ui.Stderr, "no target specified. specify the target with "+ui.Embolden("-t")+" or log in like so:")
			fmt.Fprintln(ui.Stderr, "")
			fmt.Fprintln(ui.Stderr, "    "+ui.Embolden("fly -t (alias) login -c (concourse url)"))
			fmt.Fprintln(ui.Stderr, "")
		} else if versionErr, ok := err.(rc.ErrVersionMismatch); ok {
			fmt.Fprintln(ui.Stderr, versionErr.Error())
			fmt.Fprintln(ui.Stderr, ui.WarningColor("cowardly refusing to run due to significant version discrepancy"))
		} else if netErr, ok := err.(net.Error); ok {
			fmt.Fprintf(ui.Stderr, "could not reach the Concourse server called %s:\n", ui.Embolden("%s", commands.Fly.Target))

			fmt.Fprintln(ui.Stderr, "")
			fmt.Fprintln(ui.Stderr, "    "+ui.Embolden("%s", netErr))
			fmt.Fprintln(ui.Stderr, "")
			fmt.Fprintln(ui.Stderr, "is the targeted Concourse running? better go catch it lol")
		} else if err == commands.ErrShowHelpMessage {
			helpParser := flags.NewParser(&commands.Fly, flags.HelpFlag)
			helpParser.NamespaceDelimiter = "-"
			helpParser.ParseArgs([]string{"-h"})
			helpParser.WriteHelp(os.Stdout)
			os.Exit(0)
		} else {
			fmt.Fprintf(ui.Stderr, "error: %s\n", err)
		}

		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"os"
	"strconv"
	"sync"
	"time"

	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
)

var semSize int

func init() {
	semSizeStr := os.Args[1]
	var err error
	semSize, err = strconv.Atoi(semSizeStr)
	if err != nil {
		panic("invalid sem size")
	}

	go func() {
		err = http.ListenAndServe(":28888", nil)
		if err != nil {
			panic(err)
		}
	}()
}

type ShopInfo struct {
	Qq            string
	Authenticated int
	Ww_nickname   string // 旺旺号
	Wechat        string
	Contacts_name string
	Telephone     []string
	MarketName    string // 市场
	Name          string // 档口名
	Id            int
	Position      string // 档口
	Floor         int    // 市场楼层
	Bid           int    // ?
	Shop_category string // 主营
	Cid           int    // ?
	Status        int    // ?
}

type Image struct {
	GoodId int `db:"good_id"`
	Url    string
	Sha512 []byte
}

type Url struct {
	UrlId  int `db:"url_id"`
	Url    string
	Sha512 []byte
}

func main() {
	if len(os.Args) > 2 {
		collectShops()
		collectGoods()
		hashImages()
	} else {
		hashImages()
		collectShops()
		collectGoods()
	}
}

func collectShops() {
	// collect pages
	page := 1
	infos := []ShopInfo{}
	for {
		pageUrl := fmt.Sprintf("http://www.vvic.com/api/shop/navigation?bid=&currentPage=%d&pageSize=500",
			page)
		var data struct {
			Code int
			Data struct {
				CurrentPage int
				PageSize    int
				PageCount   int // 无用
				RecordCount int // 不等于len(RecordList)
				RecordList  []ShopInfo
			}
		}
		ce(decodeFromUrl(pageUrl, &data), "decode")
		if len(data.Data.RecordList) == 0 {
			break
		}
		infos = append(infos, data.Data.RecordList...)
		page++
		pt("%d %d\n", page, len(infos))
	}

	skip := make(map[int]bool)
	var ids []int
	ts := time.Now().Add(-time.Hour * 8).Unix()
	err := db.Select(&ids, `SELECT shop_id
		FROM shops
		WHERE last_update_time > $1`,
		ts)
	ce(err, "select skip shop ids")
	for _, id := range ids {
		skip[id] = true
	}

	sem := make(chan bool, semSize)
	wg := new(sync.WaitGroup)
	wg.Add(len(infos))
	for i, shop := range infos {
		sem <- true
		i := i
		shop := shop
		go func() {
			defer func() {
				wg.Done()
				<-sem
			}()
			err := collectShop(skip, i, shop)
			if err != nil {
				pt("%v\n", err)
			}
		}()
	}
	wg.Wait()

	pt("shops collected\n")
}

func collectShop(skip map[int]bool, i int, shop ShopInfo) (err error) {
	defer ct(&err)
	pt("%20s %d\n", "shop", i)

	// 近期采集过的不管
	if _, ok := skip[shop.Id]; ok {
		return
	}

	db.MustExec(`INSERT INTO shops (
				shop_id, name, market_name, floor, position
			) VALUES ($1, $2, $3, $4, $5)
			ON CONFLICT (shop_id) DO UPDATE SET
				name = $2, market_name = $3, floor = $4, position = $5`,
		shop.Id,
		shop.Name,
		shop.MarketName,
		shop.Floor,
		shop.Position,
	)

	// set existing goods' status to 0
	db.MustExec(`UPDATE goods SET
		status = 0
		WHERE shop_id = $1`,
		shop.Id)

	// collect in sale goods
	maxPage := 9999
	page := 1
	for {
		if page > maxPage {
			break
		}

		var data struct {
			Code int
			Data struct {
				//CurrentPage int
				PageCount int // 总页数
				//PageSize    int
				//RecordCount int // 总商品数
				RecordList []struct {
					Discount_price interface{} // 拿货价
					//Tid            string  // ??
					//Is_shop_auth   int     // ?
					//Price          float64 // 原价
					Id     string
					Art_no string // 档口货号
					//Sub_name       string // 市场名
					//Shop_name      string // 档口名
					//Shop_id        int
					Up_time int64 // 上架时间，millisecond
					//Position       string  // 档口位置
					//Upload_num     int     // ?
					Is_tx int // 是否退现
					//Is_df          int     // 是否代发
					//Is_sp          int     // 是否实拍
					//Index_img_url  string  // 主图地址
					Title string // 标题
					//Bname          string  // ?
					//Bid            string  // ?
					Tcid       string  // 分类id
					Score      float64 // 分数 ？
					Sort_score float64 // 排序分数 ？
				}
			}
		}

		url := fmt.Sprintf("http://www.vvic.com/rest/shop/search-item?shop_id=%d&q=&currentPage=%d",
			shop.Id, page)
		retry := 5
	decode:
		err := decodeFromUrl(url, &data)
		if err != nil {
			if retry > 0 {
				retry--
				goto decode
			}
			ce(err, "decode data %s", url)
		}
		if page == 1 { // 第一页
			maxPage = data.Data.PageCount
		}
		ce(withTx(db, func(tx *sqlx.Tx) (err error) {
			defer ct(&err)
			for _, item := range data.Data.RecordList {

				if item.Discount_price == nil {
					continue
				}
				var price float64
				switch p := item.Discount_price.(type) {
				case string:
					price, err = strconv.ParseFloat(p, 64)
					ce(err, "parse price")
				case float64:
					price = p
				default:
					panic(fmt.Sprintf("invalid price %T", item.Discount_price))
				}
				if price == 0 { // 没有批发价的不理
					continue
				}

				var imagesCollected bool
				err := tx.QueryRow(`INSERT INTO goods (
					good_id,
					price,
					shop_id,
					added_at,
					category,
					score,
					sort_score,
					title,
					status,
					internal_id
				) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, 1, $9)
					ON CONFLICT (good_id) DO UPDATE SET
					price = $2,
					score = $6,
					sort_score = $7,
					title = $8,
					status = 1,
					internal_id = $9
					RETURNING images_collected
				`,
					item.Id,
					price,
					shop.Id,
					time.Unix(item.Up_time/1000, 0).Format("2006-01-02"),
					item.Tcid,
					item.Score,
					item.Sort_score,
					item.Title,
					item.Art_no,
				).Scan(&imagesCollected)
				ce(err, "insert goods")
				if !imagesCollected { // insert into images_not_collected
					_, err = tx.Exec(`INSERT INTO images_not_collected (good_id)
						VALUES ($1)
						ON CONFLICT (good_id) DO NOTHING
						`,
						item.Id,
					)
					ce(err, "insert into images_not_collected")
				}

			}
			return
		}), "tx")
		page++
	}

	// 更新
	db.MustExec(`UPDATE shops SET last_update_time = $1
		WHERE shop_id = $2`,
		time.Now().Unix(),
		shop.Id)

	return
}
<commit_msg>fixes<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"os"
	"strconv"
	"sync"
	"time"

	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
)

var semSize int

func init() {
	semSizeStr := os.Args[1]
	var err error
	semSize, err = strconv.Atoi(semSizeStr)
	if err != nil {
		panic("invalid sem size")
	}

	go func() {
		err = http.ListenAndServe(":28888", nil)
		if err != nil {
			panic(err)
		}
	}()
}

type ShopInfo struct {
	Qq            string
	Authenticated int
	Ww_nickname   string // 旺旺号
	Wechat        string
	Contacts_name string
	//Telephone     []string // may be string
	MarketName    string // 市场
	Name          string // 档口名
	Id            int
	Position      string // 档口
	Floor         int    // 市场楼层
	Bid           int    // ?
	Shop_category string // 主营
	Cid           int    // ?
	Status        int    // ?
}

type Image struct {
	GoodId int `db:"good_id"`
	Url    string
	Sha512 []byte
}

type Url struct {
	UrlId  int `db:"url_id"`
	Url    string
	Sha512 []byte
}

func main() {
	//collectShop(nil, 0, ShopInfo{
	//	Id: 14885,
	//})

	//return //TODO

	if len(os.Args) > 2 {
		collectShops()
		collectGoods()
		hashImages()
	} else {
		hashImages()
		collectShops()
		collectGoods()
	}
}

func collectShops() {
	// collect pages
	page := 1
	infos := []ShopInfo{}
	for {
		pageUrl := fmt.Sprintf("http://www.vvic.com/api/shop/navigation?bid=&currentPage=%d&pageSize=500",
			page)
		var data struct {
			Code int
			Data struct {
				CurrentPage int
				PageSize    int
				PageCount   int // 无用
				RecordCount int // 不等于len(RecordList)
				RecordList  []ShopInfo
			}
		}
		body, err := getBody(pageUrl)
		ce(err, "get body %s\n", pageUrl)
		ce(json.NewDecoder(bytes.NewReader(body)).Decode(&data), "decode \n %s\n", body)
		//ce(decodeFromUrl(pageUrl, &data), "decode")
		if len(data.Data.RecordList) == 0 {
			break
		}
		infos = append(infos, data.Data.RecordList...)
		page++
		pt("%d %d\n", page, len(infos))
	}

	skip := make(map[int]bool)
	var ids []int
	ts := time.Now().Add(-time.Hour * 8).Unix()
	err := db.Select(&ids, `SELECT shop_id
		FROM shops
		WHERE last_update_time > $1`,
		ts)
	ce(err, "select skip shop ids")
	for _, id := range ids {
		skip[id] = true
	}

	sem := make(chan bool, semSize)
	wg := new(sync.WaitGroup)
	wg.Add(len(infos))
	for i, shop := range infos {
		sem <- true
		i := i
		shop := shop
		go func() {
			defer func() {
				wg.Done()
				<-sem
			}()
			err := collectShop(skip, i, shop)
			if err != nil {
				pt("%v\n", err)
			}
		}()
	}
	wg.Wait()

	pt("shops collected\n")
}

func collectShop(skip map[int]bool, i int, shop ShopInfo) (err error) {
	defer ct(&err)

	// 近期采集过的不管
	if _, ok := skip[shop.Id]; ok {
		return
	}

	db.MustExec(`INSERT INTO shops (
				shop_id, name, market_name, floor, position
			) VALUES ($1, $2, $3, $4, $5)
			ON CONFLICT (shop_id) DO UPDATE SET
				name = $2, market_name = $3, floor = $4, position = $5`,
		shop.Id,
		shop.Name,
		shop.MarketName,
		shop.Floor,
		shop.Position,
	)

	// set existing goods' status to 0
	db.MustExec(`UPDATE goods SET
		status = 0
		WHERE shop_id = $1`,
		shop.Id)

	// collect in sale goods
	itemCount := 0
	maxPage := 9999
	page := 1
	for {
		if page > maxPage {
			break
		}

		var data struct {
			Code int
			Data struct {
				//CurrentPage int
				PageCount int // 总页数
				//PageSize    int
				//RecordCount int // 总商品数
				RecordList []struct {
					Discount_price interface{} // 拿货价
					//Tid            string  // ??
					//Is_shop_auth   int     // ?
					//Price          float64 // 原价
					Id     string
					Art_no string // 档口货号
					//Sub_name       string // 市场名
					//Shop_name      string // 档口名
					//Shop_id        int
					Up_time int64 // 上架时间，millisecond
					//Position       string  // 档口位置
					//Upload_num     int     // ?
					Is_tx int // 是否退现
					//Is_df          int     // 是否代发
					//Is_sp          int     // 是否实拍
					//Index_img_url  string  // 主图地址
					Title string // 标题
					//Bname          string  // ?
					//Bid            string  // ?
					Tcid       string  // 分类id
					Score      float64 // 分数 ？
					Sort_score float64 // 排序分数 ？
				}
			}
		}

		url := fmt.Sprintf("http://www.vvic.com/rest/shop/search-item?shop_id=%d&q=&currentPage=%d",
			shop.Id, page)
		retry := 5
	decode:
		err := decodeFromUrl(url, &data)
		if err != nil {
			if retry > 0 {
				retry--
				goto decode
			}
			ce(err, "decode data %s", url)
		}
		if page == 1 { // 第一页
			maxPage = data.Data.PageCount
		}
		ce(withTx(db, func(tx *sqlx.Tx) (err error) {
			defer ct(&err)
			for _, item := range data.Data.RecordList {

				if item.Discount_price == nil {
					continue
				}
				var price float64
				switch p := item.Discount_price.(type) {
				case string:
					price, err = strconv.ParseFloat(p, 64)
					ce(err, "parse price")
				case float64:
					price = p
				default:
					panic(fmt.Sprintf("invalid price %T", item.Discount_price))
				}
				if price == 0 { // 没有批发价的不理
					continue
				}

				var imagesCollected bool
				err := tx.QueryRow(`INSERT INTO goods (
					good_id,
					price,
					shop_id,
					added_at,
					category,
					score,
					sort_score,
					title,
					status,
					internal_id
				) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, 1, $9)
					ON CONFLICT (good_id) DO UPDATE SET
					price = $2,
					score = $6,
					sort_score = $7,
					title = $8,
					status = 1,
					internal_id = $9
					RETURNING images_collected
				`,
					item.Id,
					price,
					shop.Id,
					time.Unix(item.Up_time/1000, 0).Format("2006-01-02"),
					item.Tcid,
					item.Score,
					item.Sort_score,
					item.Title,
					item.Art_no,
				).Scan(&imagesCollected)
				ce(err, "insert goods")
				if !imagesCollected { // insert into images_not_collected
					_, err = tx.Exec(`INSERT INTO images_not_collected (good_id)
						VALUES ($1)
						ON CONFLICT (good_id) DO NOTHING
						`,
						item.Id,
					)
					ce(err, "insert into images_not_collected")
				}

			}
			return
		}), "tx")
		itemCount += len(data.Data.RecordList)
		page++
	}

	// 更新
	db.MustExec(`UPDATE shops SET last_update_time = $1
		WHERE shop_id = $2`,
		time.Now().Unix(),
		shop.Id)

	pt("No.%d shop %d %d items\n", i, shop.Id, itemCount)

	return
}
<|endoftext|>


<commit_before>// Package main - Server entrypoint for signature service
package main

import (
	"github.com/codegangsta/negroni"
	"github.com/gorilla/pat"
	"github.com/hashicorp/logutils"
	"github.com/husobee/dockerspew/content"
	"github.com/husobee/dockerspew/controllers"
	"github.com/husobee/dockerspew/middlewares"
	"github.com/husobee/dockerspew/models"
	"github.com/spf13/viper"
	"gopkg.in/unrolled/render.v1"
	"log"
	"os"
	"runtime"
	"strings"
)

func init() {
	// set some defaults
	viper.SetDefault("server_host", ":8080")
	viper.SetDefault("log_level", "WARN")
	viper.SetDefault("gomaxprocs", runtime.NumCPU())
	viper.SetDefault("docker_endpoint", "unix:///var/run/docker.sock")
	// get vars from viper env binding
	viper.SetEnvPrefix("dockerspew") // will be uppercased automatically
	viper.BindEnv("server_host")
	viper.BindEnv("log_level")
	viper.BindEnv("docker_endpoint")
	// setup logging
	filter := &logutils.LevelFilter{
		Levels:   []logutils.LogLevel{"DEBUG", "INFO", "WARN", "ERROR", "PANIC"},
		MinLevel: logutils.LogLevel(strings.ToUpper(viper.GetString("log_level"))),
		Writer:   os.Stderr,
	}
	log.SetOutput(filter)
	runtime.GOMAXPROCS(viper.GetInt("gomaxprocs"))
}

func main() {
	log.Print("[DEBUG] Starting Server, config options: docker_endpoint:",
		viper.GetString("docker_endpoint"),
		" server_host=",
		viper.GetString("server_host"),
		" log_level=",
		viper.GetString("log_level"))
	// setup renderer
	rend := render.New()
	// setup a docker client
	dockerClient, err := models.NewDockerClient(viper.GetString("docker_endpoint"))
	if err != nil {
		log.Fatalln("[PANIC] Docker enpoint not accessable, bailing")
	}
	// define routes
	r := pat.New()
	// setup a websocketUpgrader
	webSocketUpgrader := content.NewWebSocketUpgrader(1024, 1024)
	// setup our spew controller
	spewController := controllers.NewSpewController(rend, dockerClient, webSocketUpgrader)
	r.Get("/spew", spewController.SpewHandler)
	r.Get("/spew/", spewController.SpewHandler)
	// startup classic negroni
	n := negroni.Classic()
	n.Use(middlewares.NewContentNegotiate(rend))
	// attach router to negroni
	n.UseHandler(r)
	// run negroni
	runServer(n)
}

//runServer - run the server, broken out for unit tests
var runServer = func(n *negroni.Negroni) {
	log.Print("[DEBUG] Server starting to accept requests")
	n.Run(viper.GetString("server_host"))
}
<commit_msg> more tests<commit_after>// Package main - Server entrypoint for signature service
package main

import (
	"github.com/codegangsta/negroni"
	"github.com/gorilla/pat"
	"github.com/hashicorp/logutils"
	"github.com/husobee/dockerspew/content"
	"github.com/husobee/dockerspew/controllers"
	"github.com/husobee/dockerspew/middlewares"
	"github.com/husobee/dockerspew/models"
	"github.com/spf13/viper"
	"gopkg.in/unrolled/render.v1"
	"log"
	"os"
	"runtime"
	"strings"
)

func init() {
	// set some defaults
	viper.SetDefault("server_host", ":8080")
	viper.SetDefault("log_level", "WARN")
	viper.SetDefault("gomaxprocs", runtime.NumCPU())
	viper.SetDefault("docker_endpoint", "unix:///var/run/docker.sock")
	// get vars from viper env binding
	viper.SetEnvPrefix("dockerspew") // will be uppercased automatically
	viper.BindEnv("server_host")
	viper.BindEnv("log_level")
	viper.BindEnv("docker_endpoint")
	// setup logging
	filter := &logutils.LevelFilter{
		Levels:   []logutils.LogLevel{"DEBUG", "INFO", "WARN", "ERROR", "PANIC"},
		MinLevel: logutils.LogLevel(strings.ToUpper(viper.GetString("log_level"))),
		Writer:   os.Stderr,
	}
	log.SetOutput(filter)
	runtime.GOMAXPROCS(viper.GetInt("gomaxprocs"))
}

var modelsNewDockerClient = models.NewDockerClient

func main() {
	log.Print("[DEBUG] Starting Server, config options: docker_endpoint:",
		viper.GetString("docker_endpoint"),
		" server_host=",
		viper.GetString("server_host"),
		" log_level=",
		viper.GetString("log_level"))
	// setup renderer
	rend := render.New()
	// setup a docker client
	dockerClient, err := modelsNewDockerClient(viper.GetString("docker_endpoint"))
	if err != nil {
		log.Panic("[PANIC] Docker enpoint not accessable, bailing")
	}
	// define routes
	r := pat.New()
	// setup a websocketUpgrader
	webSocketUpgrader := content.NewWebSocketUpgrader(1024, 1024)
	// setup our spew controller
	spewController := controllers.NewSpewController(rend, dockerClient, webSocketUpgrader)
	r.Get("/spew", spewController.SpewHandler)
	r.Get("/spew/", spewController.SpewHandler)
	// startup classic negroni
	n := negroni.Classic()
	n.Use(middlewares.NewContentNegotiate(rend))
	// attach router to negroni
	n.UseHandler(r)
	// run negroni
	runServer(n)
}

//runServer - run the server, broken out for unit tests
var runServer = func(n *negroni.Negroni) {
	log.Print("[DEBUG] Server starting to accept requests")
	n.Run(viper.GetString("server_host"))
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"os"
	"regexp"
)

func main() {
	urls := getUrls()
	for _, url := range urls {
		fmt.Println(url)
	}
	fmt.Println("Total", len(urls))
}

func getUrls() []string {
	urls := []string{}
	r := regexp.MustCompile(`<a class="audibleTile__artworkLink" href="(.*)">`)

	// Read lines from stdin
	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		line := s.Text()
		match := r.FindStringSubmatch(line)
		if len(match) == 0 {
			continue
		}
		urls = append(urls, "https://soundcloud.com"+match[1])
	}
	return urls
}
<commit_msg>Get waveform urls<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
)

// Usage: cat ~/Desktop/sclikes_html.txt | go run main.go
func main() {
	urls := getBrowserUrls()
	for _, url := range urls {
		wurl := getWaveFormUrl(url)
		fmt.Println(wurl)
	}
	fmt.Println("Total", len(urls))
}

func getWaveFormUrl(browserUrl string) string {
	// input
	// browserUrl := "https://soundcloud.com/lana-del-rey/ultraviolence-disciples-remix-1"
	resp, err := http.Get(browserUrl)
	if err != nil {
		fmt.Println("Error getting", browserUrl)
	}

	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading", browserUrl)
	}
	respString := string(respBytes)

	r := regexp.MustCompile(`"waveform_url":"(http.*\.json)"`)

	match := r.FindStringSubmatch(respString)
	waveformUrl := match[1]

	// output
	// waveformUrl := "https://wis.sndcdn.com/iCvi12jhGTIQ_m.json"
	return waveformUrl
}

func getBrowserUrls() []string {
	urls := []string{}
	r := regexp.MustCompile(`<a class="audibleTile__artworkLink" href="(.*)">`)

	// Read lines from stdin
	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		line := s.Text()
		match := r.FindStringSubmatch(line)
		if len(match) == 0 {
			continue
		}
		urls = append(urls, "https://soundcloud.com"+match[1])
	}
	return urls
}
<|endoftext|>


<commit_before>package main

import (
	"runtime"

	"github.com/WeCanHearYou/wechy/app/models"
	"github.com/WeCanHearYou/wechy/app/pkg/dbx"
	"github.com/WeCanHearYou/wechy/app/pkg/env"
	"github.com/WeCanHearYou/wechy/app/pkg/oauth"
	"github.com/WeCanHearYou/wechy/app/storage/postgres"
	_ "github.com/lib/pq"
	mig "github.com/mattes/migrate"
	_ "github.com/mattes/migrate/database/postgres"
	_ "github.com/mattes/migrate/source/file"

	"fmt"
)

var buildtime string
var version = "0.2.0"

func migrate() {
	fmt.Printf("Running migrations... \n")
	m, err := mig.New(
		"file://./"+env.Path("/migrations"),
		env.MustGet("DATABASE_URL"),
	)

	if err == nil {
		err = m.Up()
	}

	if err != nil && err != mig.ErrNoChange {
		fmt.Printf("Error: %s.\n", err)

		panic("Migrations failed.")
	} else {
		fmt.Printf("Migrations finished with success.\n")
	}
}

func init() {
	fmt.Printf("Application is starting...\n")
	fmt.Printf("GO_ENV: %s\n", env.Current())
	migrate()
}

func main() {
	db, err := dbx.New()
	if err != nil {
		panic(err)
	}

	ctx := &AppServices{
		OAuth:  &oauth.HTTPService{},
		Idea:   &postgres.IdeaStorage{DB: db},
		User:   &postgres.UserStorage{DB: db},
		Tenant: &postgres.TenantStorage{DB: db},
		Settings: &models.AppSettings{
			BuildTime:   buildtime,
			Version:     version,
			Compiler:    runtime.Version(),
			Environment: env.Current(),
		},
	}

	e := GetMainEngine(ctx)
	e.Start(":" + env.GetEnvOrDefault("PORT", "3000"))
}
<commit_msg>fix path<commit_after>package main

import (
	"runtime"

	"github.com/WeCanHearYou/wechy/app/models"
	"github.com/WeCanHearYou/wechy/app/pkg/dbx"
	"github.com/WeCanHearYou/wechy/app/pkg/env"
	"github.com/WeCanHearYou/wechy/app/pkg/oauth"
	"github.com/WeCanHearYou/wechy/app/storage/postgres"
	_ "github.com/lib/pq"
	mig "github.com/mattes/migrate"
	_ "github.com/mattes/migrate/database/postgres"
	_ "github.com/mattes/migrate/source/file"

	"fmt"
)

var buildtime string
var version = "0.2.0"

func migrate() {
	fmt.Printf("Running migrations... \n")
	m, err := mig.New(
		"file://./migrations",
		env.MustGet("DATABASE_URL"),
	)

	if err == nil {
		err = m.Up()
	}

	if err != nil && err != mig.ErrNoChange {
		fmt.Printf("Error: %s.\n", err)

		panic("Migrations failed.")
	} else {
		fmt.Printf("Migrations finished with success.\n")
	}
}

func init() {
	fmt.Printf("Application is starting...\n")
	fmt.Printf("GO_ENV: %s\n", env.Current())
	migrate()
}

func main() {
	db, err := dbx.New()
	if err != nil {
		panic(err)
	}

	ctx := &AppServices{
		OAuth:  &oauth.HTTPService{},
		Idea:   &postgres.IdeaStorage{DB: db},
		User:   &postgres.UserStorage{DB: db},
		Tenant: &postgres.TenantStorage{DB: db},
		Settings: &models.AppSettings{
			BuildTime:   buildtime,
			Version:     version,
			Compiler:    runtime.Version(),
			Environment: env.Current(),
		},
	}

	e := GetMainEngine(ctx)
	e.Start(":" + env.GetEnvOrDefault("PORT", "3000"))
}
<|endoftext|>


<commit_before>package main

import (
	"image"
	"log"
	"strings"

	"github.com/crgimenes/metal/cmd"
	"github.com/crgimenes/metal/fonts"
	"github.com/hajimehoshi/ebiten"
)

const (
	screenWidth  = 320 // 40 columns
	screenHeight = 240 // 30 rows

	rows     = 30
	columns  = 40
	rgbaSize = 4
)

var (
	videoTextMemory [rows * columns * 2]byte
	cursor          int
	img             *image.RGBA
	square          *ebiten.Image
	font            fonts.Expert118x8
	currentColor    byte = 0x0f
)

var CGAColors = []struct {
	R byte
	G byte
	B byte
}{
	{0, 0, 0},
	{0, 0, 170},
	{0, 170, 0},
	{0, 170, 170},
	{170, 0, 0},
	{170, 0, 170},
	{170, 85, 0},
	{170, 170, 170},
	{85, 85, 85},
	{85, 85, 255},
	{85, 255, 85},
	{85, 255, 255},
	{255, 85, 85},
	{255, 85, 255},
	{255, 255, 85},
	{255, 255, 255},
}

func mergeColorCode(b, f byte) byte {
	return (f & 0xff) | (b << 4)
}

func drawPix(x, y int, color byte) {
	pos := 4*y*screenWidth + 4*x
	img.Pix[pos] = CGAColors[color].R
	img.Pix[pos+1] = CGAColors[color].G
	img.Pix[pos+2] = CGAColors[color].B
	img.Pix[pos+3] = 0xff
}

func getBit(n int, pos uint64) bool {
	// from right to left
	val := n & (1 << pos)
	return (val > 0)
}

func drawChar(index, fgColor, bgColor byte, x, y int) {
	var a, b uint64
	for a = 0; a < 8; a++ {
		for b = 0; b < 8; b++ {
			if font.Bitmap[index][b]&(0x80>>a) != 0 {
				drawPix(int(a)+x, int(b)+y, fgColor)
			} else {
				drawPix(int(a)+x, int(b)+y, bgColor)
			}
		}
	}
}

var cursorBlinkTimer int
var cursorSetBlink bool = true

func drawCursor(index, fgColor, bgColor byte, x, y int) {
	if cursorSetBlink {
		if cursorBlinkTimer < 15 {
			drawChar(index, fgColor, bgColor, x, y)
		} else {
			drawChar(index, bgColor, fgColor, x, y)
		}
		cursorBlinkTimer++
		if cursorBlinkTimer > 30 {
			cursorBlinkTimer = 0
		}
	} else {
		drawChar(index, bgColor, fgColor, x, y)
	}
}

func drawVideoTextMode() {
	i := 0
	for r := 0; r < rows; r++ {
		for c := 0; c < columns; c++ {
			color := videoTextMemory[i]
			f := color & 0x0f
			b := color & 0xf0 >> 4
			i++
			if i-1 == cursor {
				drawCursor(videoTextMemory[i], f, b, c*8, r*8)
			} else {
				drawChar(videoTextMemory[i], f, b, c*8, r*8)
			}
			i++
		}
	}
}

func clearVideoTextMode() {
	copy(videoTextMemory[:], make([]byte, len(videoTextMemory)))
	for i := 0; i < len(videoTextMemory); i += 2 {
		videoTextMemory[i] = currentColor
	}
}

func moveLineUp() {
	copy(videoTextMemory[0:], videoTextMemory[columns*2:])
	copy(videoTextMemory[len(videoTextMemory)-columns*2:], make([]byte, columns*2))
	for i := len(videoTextMemory) - columns*2; i < len(videoTextMemory); i += 2 {
		videoTextMemory[i] = currentColor
	}

}

func correctVideoCursor() {
	if cursor < 0 {
		cursor = 0
	}
	for cursor >= rows*columns*2 {
		cursor -= columns * 2
		moveLineUp()
	}
}

func putChar(c byte) {
	correctVideoCursor()
	videoTextMemory[cursor] = currentColor
	cursor++
	correctVideoCursor()
	videoTextMemory[cursor] = c
	cursor++
	correctVideoCursor()
}

func bPrint(msg string) {
	for i := 0; i < len(msg); i++ {
		c := msg[i]

		switch c {
		case 13:
			cursor += columns * 2
			continue
		case 10:
			aux := cursor / (columns * 2)
			aux = aux * (columns * 2)
			cursor = aux
			continue
		}
		putChar(msg[i])
	}
}

func bPrintln(msg string) {
	msg += "\r\n"
	bPrint(msg)
}

var lastKey = struct {
	Time uint64
	Char byte
}{
	0,
	0,
}

var uTime uint64
var c byte

var machine int

//var countaux int
var noKey bool

func keyTreatment(c byte, f func(c byte)) {
	if noKey || lastKey.Char != c || lastKey.Time+20 < uTime {
		f(c)
		noKey = false
		lastKey.Char = c
		lastKey.Time = uTime
	}
}

func getLine() string {
	aux := cursor / (columns * 2)
	var ret string
	for i := aux*(columns*2) + 1; i < aux*(columns*2)+columns*2; i += 2 {
		c := videoTextMemory[i]
		if c == 0 {
			break
		}
		ret += string(videoTextMemory[i])
	}

	ret = strings.TrimSpace(ret)
	return ret
}

func keyboard() {
	for c := 'A'; c <= 'Z'; c++ {
		if ebiten.IsKeyPressed(ebiten.Key(c) - 'A' + ebiten.KeyA) {
			keyTreatment(byte(c), func(c byte) {
				putChar(c)
			})
			return
		}
	}

	if ebiten.IsKeyPressed(ebiten.KeySpace) {
		keyTreatment(byte(' '), func(c byte) {
			putChar(c)
		})
		return
	}

	if ebiten.IsKeyPressed(ebiten.KeyEnter) {
		keyTreatment(0, func(c byte) {
			cmd.Eval(getLine())
			cursor += columns * 2
			aux := cursor / (columns * 2)
			aux = aux * (columns * 2)
			cursor = aux
			correctVideoCursor()
		})
		return
	}

	if ebiten.IsKeyPressed(ebiten.KeyBackspace) {
		keyTreatment(0, func(c byte) {
			cursor -= 2
			correctVideoCursor()
		})
		return
	}

	if ebiten.IsKeyPressed(ebiten.KeyUp) {
		keyTreatment(0, func(c byte) {
			cursor -= columns * 2
			correctVideoCursor()
		})
		return
	} else if ebiten.IsKeyPressed(ebiten.KeyDown) {
		keyTreatment(0, func(c byte) {
			cursor += columns * 2
			correctVideoCursor()
		})
		return
	} else if ebiten.IsKeyPressed(ebiten.KeyLeft) {
		keyTreatment(0, func(c byte) {
			cursor -= 2
			correctVideoCursor()
		})
		return
	} else if ebiten.IsKeyPressed(ebiten.KeyRight) {
		keyTreatment(0, func(c byte) {
			cursor += 2
			correctVideoCursor()
		})
		return
	}

	// When the "left mouse button" is pressed...
	if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
		//ebitenutil.DebugPrint(screen, "You're pressing the 'LEFT' mouse button.")
	}
	// When the "right mouse button" is pressed...
	if ebiten.IsMouseButtonPressed(ebiten.MouseButtonRight) {
		//ebitenutil.DebugPrint(screen, "\nYou're pressing the 'RIGHT' mouse button.")
	}
	// When the "middle mouse button" is pressed...
	if ebiten.IsMouseButtonPressed(ebiten.MouseButtonMiddle) {
		//ebitenutil.DebugPrint(screen, "\n\nYou're pressing the 'MIDDLE' mouse button.")
	}

	//x, y := ebiten.CursorPosition()
	//fmt.Printf("X: %d, Y: %d\n", x, y)

	// Display the information with "X: xx, Y: xx" format
	//ebitenutil.DebugPrint(screen, fmt.Sprintf("X: %d, Y: %d", x, y))

	noKey = true

}

func update(screen *ebiten.Image) error {

	uTime++
	//putChar(2)
	//cursor -= 2

	if machine == 0 {
		bPrintln("METAL BASIC 0.01")
		bPrintln("http://crg.eti.br")
		machine++
	}

	/*
		if countaux > 10 {
			countaux = 0
			putChar(dt)
			dt++
			currentColor = mergeColorCode(0x0, c)
			c++
			if c > 15 {
				c = 0
			}
		}
		countaux++
	*/
	drawVideoTextMode()
	screen.ReplacePixels(img.Pix)
	keyboard()
	return nil
}

func main() {

	font.Load()
	clearVideoTextMode()

	img = image.NewRGBA(image.Rect(0, 0, screenWidth, screenHeight))
	if err := ebiten.Run(update, screenWidth, screenHeight, 2, "METAL BASIC 0.01"); err != nil {
		log.Fatal(err)
	}

}
<commit_msg>add Comma and numbers<commit_after>package main

import (
	"image"
	"log"
	"strings"

	"github.com/crgimenes/metal/cmd"
	"github.com/crgimenes/metal/fonts"
	"github.com/hajimehoshi/ebiten"
)

const (
	screenWidth  = 320 // 40 columns
	screenHeight = 240 // 30 rows

	rows     = 30
	columns  = 40
	rgbaSize = 4
)

var (
	videoTextMemory [rows * columns * 2]byte
	cursor          int
	img             *image.RGBA
	square          *ebiten.Image
	font            fonts.Expert118x8
	currentColor    byte = 0x0f
)

var CGAColors = []struct {
	R byte
	G byte
	B byte
}{
	{0, 0, 0},
	{0, 0, 170},
	{0, 170, 0},
	{0, 170, 170},
	{170, 0, 0},
	{170, 0, 170},
	{170, 85, 0},
	{170, 170, 170},
	{85, 85, 85},
	{85, 85, 255},
	{85, 255, 85},
	{85, 255, 255},
	{255, 85, 85},
	{255, 85, 255},
	{255, 255, 85},
	{255, 255, 255},
}

func mergeColorCode(b, f byte) byte {
	return (f & 0xff) | (b << 4)
}

func drawPix(x, y int, color byte) {
	pos := 4*y*screenWidth + 4*x
	img.Pix[pos] = CGAColors[color].R
	img.Pix[pos+1] = CGAColors[color].G
	img.Pix[pos+2] = CGAColors[color].B
	img.Pix[pos+3] = 0xff
}

func getBit(n int, pos uint64) bool {
	// from right to left
	val := n & (1 << pos)
	return (val > 0)
}

func drawChar(index, fgColor, bgColor byte, x, y int) {
	var a, b uint64
	for a = 0; a < 8; a++ {
		for b = 0; b < 8; b++ {
			if font.Bitmap[index][b]&(0x80>>a) != 0 {
				drawPix(int(a)+x, int(b)+y, fgColor)
			} else {
				drawPix(int(a)+x, int(b)+y, bgColor)
			}
		}
	}
}

var cursorBlinkTimer int
var cursorSetBlink bool = true

func drawCursor(index, fgColor, bgColor byte, x, y int) {
	if cursorSetBlink {
		if cursorBlinkTimer < 15 {
			drawChar(index, fgColor, bgColor, x, y)
		} else {
			drawChar(index, bgColor, fgColor, x, y)
		}
		cursorBlinkTimer++
		if cursorBlinkTimer > 30 {
			cursorBlinkTimer = 0
		}
	} else {
		drawChar(index, bgColor, fgColor, x, y)
	}
}

func drawVideoTextMode() {
	i := 0
	for r := 0; r < rows; r++ {
		for c := 0; c < columns; c++ {
			color := videoTextMemory[i]
			f := color & 0x0f
			b := color & 0xf0 >> 4
			i++
			if i-1 == cursor {
				drawCursor(videoTextMemory[i], f, b, c*8, r*8)
			} else {
				drawChar(videoTextMemory[i], f, b, c*8, r*8)
			}
			i++
		}
	}
}

func clearVideoTextMode() {
	copy(videoTextMemory[:], make([]byte, len(videoTextMemory)))
	for i := 0; i < len(videoTextMemory); i += 2 {
		videoTextMemory[i] = currentColor
	}
}

func moveLineUp() {
	copy(videoTextMemory[0:], videoTextMemory[columns*2:])
	copy(videoTextMemory[len(videoTextMemory)-columns*2:], make([]byte, columns*2))
	for i := len(videoTextMemory) - columns*2; i < len(videoTextMemory); i += 2 {
		videoTextMemory[i] = currentColor
	}

}

func correctVideoCursor() {
	if cursor < 0 {
		cursor = 0
	}
	for cursor >= rows*columns*2 {
		cursor -= columns * 2
		moveLineUp()
	}
}

func putChar(c byte) {
	correctVideoCursor()
	videoTextMemory[cursor] = currentColor
	cursor++
	correctVideoCursor()
	videoTextMemory[cursor] = c
	cursor++
	correctVideoCursor()
}

func bPrint(msg string) {
	for i := 0; i < len(msg); i++ {
		c := msg[i]

		switch c {
		case 13:
			cursor += columns * 2
			continue
		case 10:
			aux := cursor / (columns * 2)
			aux = aux * (columns * 2)
			cursor = aux
			continue
		}
		putChar(msg[i])
	}
}

func bPrintln(msg string) {
	msg += "\r\n"
	bPrint(msg)
}

var lastKey = struct {
	Time uint64
	Char byte
}{
	0,
	0,
}

var uTime uint64
var c byte

var machine int

//var countaux int
var noKey bool

func keyTreatment(c byte, f func(c byte)) {
	if noKey || lastKey.Char != c || lastKey.Time+20 < uTime {
		f(c)
		noKey = false
		lastKey.Char = c
		lastKey.Time = uTime
	}
}

func getLine() string {
	aux := cursor / (columns * 2)
	var ret string
	for i := aux*(columns*2) + 1; i < aux*(columns*2)+columns*2; i += 2 {
		c := videoTextMemory[i]
		if c == 0 {
			break
		}
		ret += string(videoTextMemory[i])
	}

	ret = strings.TrimSpace(ret)
	return ret
}

func keyboard() {
	for c := 'A'; c <= 'Z'; c++ {
		if ebiten.IsKeyPressed(ebiten.Key(c) - 'A' + ebiten.KeyA) {
			keyTreatment(byte(c), func(c byte) {
				putChar(c)
			})
			return
		}
	}

	for c := '0'; c <= '9'; c++ {
		if ebiten.IsKeyPressed(ebiten.Key(c) - '0' + ebiten.Key0) {
			keyTreatment(byte(c), func(c byte) {
				putChar(c)
			})
			return
		}
	}

	if ebiten.IsKeyPressed(ebiten.KeySpace) {
		keyTreatment(byte(' '), func(c byte) {
			putChar(c)
		})
		return
	}

	if ebiten.IsKeyPressed(ebiten.KeyComma) {
		keyTreatment(byte(','), func(c byte) {
			putChar(c)
		})
		return
	}

	if ebiten.IsKeyPressed(ebiten.KeyEnter) {
		keyTreatment(0, func(c byte) {
			cmd.Eval(getLine())
			cursor += columns * 2
			aux := cursor / (columns * 2)
			aux = aux * (columns * 2)
			cursor = aux
			correctVideoCursor()
		})
		return
	}

	if ebiten.IsKeyPressed(ebiten.KeyBackspace) {
		keyTreatment(0, func(c byte) {
			cursor -= 2
			correctVideoCursor()
		})
		return
	}

	if ebiten.IsKeyPressed(ebiten.KeyUp) {
		keyTreatment(0, func(c byte) {
			cursor -= columns * 2
			correctVideoCursor()
		})
		return
	} else if ebiten.IsKeyPressed(ebiten.KeyDown) {
		keyTreatment(0, func(c byte) {
			cursor += columns * 2
			correctVideoCursor()
		})
		return
	} else if ebiten.IsKeyPressed(ebiten.KeyLeft) {
		keyTreatment(0, func(c byte) {
			cursor -= 2
			correctVideoCursor()
		})
		return
	} else if ebiten.IsKeyPressed(ebiten.KeyRight) {
		keyTreatment(0, func(c byte) {
			cursor += 2
			correctVideoCursor()
		})
		return
	}

	// When the "left mouse button" is pressed...
	if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
		//ebitenutil.DebugPrint(screen, "You're pressing the 'LEFT' mouse button.")
	}
	// When the "right mouse button" is pressed...
	if ebiten.IsMouseButtonPressed(ebiten.MouseButtonRight) {
		//ebitenutil.DebugPrint(screen, "\nYou're pressing the 'RIGHT' mouse button.")
	}
	// When the "middle mouse button" is pressed...
	if ebiten.IsMouseButtonPressed(ebiten.MouseButtonMiddle) {
		//ebitenutil.DebugPrint(screen, "\n\nYou're pressing the 'MIDDLE' mouse button.")
	}

	//x, y := ebiten.CursorPosition()
	//fmt.Printf("X: %d, Y: %d\n", x, y)

	// Display the information with "X: xx, Y: xx" format
	//ebitenutil.DebugPrint(screen, fmt.Sprintf("X: %d, Y: %d", x, y))

	noKey = true

}

func update(screen *ebiten.Image) error {

	uTime++
	//putChar(2)
	//cursor -= 2

	if machine == 0 {
		bPrintln("METAL BASIC 0.01")
		bPrintln("http://crg.eti.br")
		machine++
	}

	/*
		if countaux > 10 {
			countaux = 0
			putChar(dt)
			dt++
			currentColor = mergeColorCode(0x0, c)
			c++
			if c > 15 {
				c = 0
			}
		}
		countaux++
	*/
	drawVideoTextMode()
	screen.ReplacePixels(img.Pix)
	keyboard()
	return nil
}

func main() {

	font.Load()
	clearVideoTextMode()

	img = image.NewRGBA(image.Rect(0, 0, screenWidth, screenHeight))
	if err := ebiten.Run(update, screenWidth, screenHeight, 2, "METAL BASIC 0.01"); err != nil {
		log.Fatal(err)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/oschwald/geoip2-golang"
	"log"
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
)

// The GeoIP database containing data on what IP match to what city/country blah
// blah.
var db *geoip2.Reader

func main() {
	// Initialize the database.
	var err error
	db, err = geoip2.Open("GeoLite2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}

	// Get the HTTP server rollin'
	http.HandleFunc("/", HTTPRequestHandler)
	log.Println("Server listening!")
	http.ListenAndServe(":61430", nil)
}

// Standard request handler if there's no static file to be served.
func HTTPRequestHandler(w http.ResponseWriter, r *http.Request) {
	// Get the current time, so that we can then calculate the execution time.
	start := time.Now()

	var requestIP string
	// The request is most likely being done through a reverse proxy.
	if realIP, ok := r.Header["X-Real-Ip"]; ok && len(r.Header["X-Real-Ip"]) > 0 {
		requestIP = realIP[0]
	} else {
		// Get the real actual request IP without the trolls
		requestIP = UnfuckRequestIP(r.RemoteAddr)
	}

	// There's a very good reason for which we aren't using regexes.
	// http://ideone.com/jNEMob
	// (tl;dr: regex is holy shit fucking slow)
	isConnectingFromBrowser := strings.Index(r.UserAgent(), "mozilla") != -1 ||
		strings.Index(r.UserAgent(), "webkit") != -1 ||
		strings.Index(r.UserAgent(), "opera") != -1

	// Log how much time it took to respond to the request, when we're done.
	defer log.Printf(
		"[rq] %s %s %s %dns",
		requestIP,
		r.Method,
		r.URL.Path,
		time.Since(start).Nanoseconds())

	// Index, redirect to github.com page.
	if r.URL.Path == "/" && isConnectingFromBrowser {
		http.Redirect(w, r, "https://github.com/TheHowl/ip.zxq.co/blob/master/README.md", 301)
		return
	}

	// Separate two strings when there is a / in the URL requested.
	requestedThings := strings.Split(r.URL.Path, "/")

	var IPAddress string
	var Which string
	// How in the world the user would manage to even send a request to
	// something without even having Path = "/"?
	// I... have no idea. But I'm paranoid. So let's just do it anyway.
	if len(requestedThings) < 2 {
		IPAddress = ""
	} else {
		IPAddress = requestedThings[1]
	}
	// In case the user didn't write a specific index, let's specify it for
	// them.
	if len(requestedThings) < 3 {
		Which = ""
	} else {
		Which = requestedThings[2]
	}

	// Set the requested IP to the user's request request IP, if we got no address.
	if IPAddress == "" || IPAddress == "self" {
		IPAddress = requestIP
	}

	// Query parameters array making
	queryParamsRaw, _ := url.ParseQuery(r.URL.RawQuery)
	queryParams := SimplifyQueryMap(queryParamsRaw)
	queryParams = AppendDefaultIfNotSet(queryParams, "callback", "#none#")
	queryParams = AppendDefaultIfNotSet(queryParams, "pretty", "0")

	// Get the geodata of the requested IP.
	o, contentType := IPToResponse(IPAddress, Which, queryParams)

	// Set the content type as the one given by IPToResponse.
	w.Header().Set("Content-Type", contentType+"; charset=utf-8")
	// Write the data out to the response.
	fmt.Fprint(w, o)
}

// Appends a default value to a map only if the key, defined as k, doesn't
// already exist in the array.
func AppendDefaultIfNotSet(sl map[string]string, k string, dv string) map[string]string {
	if _, ok := sl[k]; !ok {
		sl[k] = dv
	}
	return sl
}

// url.ParseQuery returns a map containing as a value a slice with often just
// one value. We're fixing that.
func SimplifyQueryMap(sl url.Values) map[string]string {
	var ret map[string]string = map[string]string{}
	for k, v := range sl {
		// We're getting only the last element, because we take as granted that
		// what the use actually means is the last element, if he has provided
		// multiple values for the same key.
		if len(v) > 0 {
			ret[k] = v[len(v)-1]
		}
	}
	return ret
}

// Remove from the IP eventual [ or ], and remove the port part of the IP.
func UnfuckRequestIP(ip string) string {
	ip = strings.Replace(ip, "[", "", 1)
	ip = strings.Replace(ip, "]", "", 1)
	ss := strings.Split(ip, ":")
	ip = strings.Join(ss[:len(ss)-1], ":")
	return ip
}

// Turn the IP into a JSON string containing geodata.
//
// * i: the raw IP string.
// * specific: the specific value to get from the geodata array. Default is ""
// * params: Set callback in the map to a non-"#none#" value to use it as a
//   JSONP callback. Set "pretty" to 1 if you want a 2-space indented JSON
//   output.
func IPToResponse(i string, specific string, params map[string]string) (string, string) {
	ip := net.ParseIP(i)
	if ip == nil {
		return "Please provide a valid IP address", "text/html"
	}

	// Query the maxmind database for that IP address.
	record, err := db.City(ip)
	if err != nil {
		log.Fatal(err)
	}

	// String containing the region/subdivision of the IP. (E.g.: Scotland, or
	// California).
	var sd string
	// If there are subdivisions for this IP, set sd as the first element in the
	// array's name.
	if record.Subdivisions != nil {
		sd = record.Subdivisions[0].Names["en"]
	}

	// Create a new instance of all the data to be returned to the user.
	data := map[string]string{}
	// Fill up the data array with the geoip data.
	data["ip"] = ip.String()
	data["country"] = record.Country.IsoCode
	data["country_full"] = record.Country.Names["en"]
	data["city"] = record.City.Names["en"]
	data["region"] = sd
	data["continent"] = record.Continent.Code
	data["continent_full"] = record.Continent.Names["en"]
	data["postal"] = record.Postal.Code
	// precision of latitude/longitude is up to 4 decimal places (even on
	// ipinfo.io).
	data["loc"] = fmt.Sprintf("%.4f,%.4f", record.Location.Latitude, record.Location.Longitude)

	// Since we don't have HTML output, nor other data from geo data,
	// everything is the same if you do /8.8.8.8, /8.8.8.8/json or /8.8.8.8/geo.
	if specific == "" || specific == "json" || specific == "geo" {
		var bytes_output []byte
		if params["pretty"] == "1" {
			bytes_output, _ = json.MarshalIndent(data, "", "  ")
		} else {
			bytes_output, _ = json.Marshal(data)
		}
		return JSONPify(params["callback"], string(bytes_output[:])),
			"application/json"
	} else if val, ok := data[specific]; ok {
		// If we got a specific value for what the user requested, return only
		// that specific value.
		return val, "text/html"
	} else {
		// We got nothing to show to the user.
		return "undefined", "text/html"
	}
}

// Wraps wrapData into a JSONP callback, if the callback name is valid.
func JSONPify(callback string, wrapData string) string {
	// If you have a callback name longer than 2000 characters, I gotta say, you
	// really should learn to minify your javascript code!
	if callback != "#none#" && callback != "" && len(callback) < 2000 {
		// In case you're wondering, yes, there is a reason for the empty
		// comment! http://stackoverflow.com/a/16048976/5328069
		wrapData = fmt.Sprintf("/**/ typeof %s === 'function' "+
			"&& %s(%s);", callback, callback, wrapData)
	}
	return wrapData
}
<commit_msg>Check that it's a browser only when requesting /<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/oschwald/geoip2-golang"
	"log"
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
)

// The GeoIP database containing data on what IP match to what city/country blah
// blah.
var db *geoip2.Reader

func main() {
	// Initialize the database.
	var err error
	db, err = geoip2.Open("GeoLite2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}

	// Get the HTTP server rollin'
	http.HandleFunc("/", HTTPRequestHandler)
	log.Println("Server listening!")
	http.ListenAndServe(":61430", nil)
}

// Standard request handler if there's no static file to be served.
func HTTPRequestHandler(w http.ResponseWriter, r *http.Request) {
	// Get the current time, so that we can then calculate the execution time.
	start := time.Now()

	var requestIP string
	// The request is most likely being done through a reverse proxy.
	if realIP, ok := r.Header["X-Real-Ip"]; ok && len(r.Header["X-Real-Ip"]) > 0 {
		requestIP = realIP[0]
	} else {
		// Get the real actual request IP without the trolls
		requestIP = UnfuckRequestIP(r.RemoteAddr)
	}

	// Log how much time it took to respond to the request, when we're done.
	defer log.Printf(
		"[rq] %s %s %s %dns",
		requestIP,
		r.Method,
		r.URL.Path,
		time.Since(start).Nanoseconds())

	// Index, redirect to github.com page if the request is sent from a browser.
	// There's a very good reason for which we aren't using regexes.
	// http://ideone.com/jNEMob
	// (tl;dr: regex is holy shit fucking slow)
	if r.URL.Path == "/" && (strings.Index(r.UserAgent(), "mozilla") != -1 ||
		strings.Index(r.UserAgent(), "webkit") != -1 ||
		strings.Index(r.UserAgent(), "opera") != -1) {
		http.Redirect(w, r, "https://github.com/TheHowl/ip.zxq.co/blob/master/README.md", 301)
		return
	}

	// Separate two strings when there is a / in the URL requested.
	requestedThings := strings.Split(r.URL.Path, "/")

	var IPAddress string
	var Which string
	// How in the world the user would manage to even send a request to
	// something without even having Path = "/"?
	// I... have no idea. But I'm paranoid. So let's just do it anyway.
	if len(requestedThings) < 2 {
		IPAddress = ""
	} else {
		IPAddress = requestedThings[1]
	}
	// In case the user didn't write a specific index, let's specify it for
	// them.
	if len(requestedThings) < 3 {
		Which = ""
	} else {
		Which = requestedThings[2]
	}

	// Set the requested IP to the user's request request IP, if we got no address.
	if IPAddress == "" || IPAddress == "self" {
		IPAddress = requestIP
	}

	// Query parameters array making
	queryParamsRaw, _ := url.ParseQuery(r.URL.RawQuery)
	queryParams := SimplifyQueryMap(queryParamsRaw)
	queryParams = AppendDefaultIfNotSet(queryParams, "callback", "#none#")
	queryParams = AppendDefaultIfNotSet(queryParams, "pretty", "0")

	// Get the geodata of the requested IP.
	o, contentType := IPToResponse(IPAddress, Which, queryParams)

	// Set the content type as the one given by IPToResponse.
	w.Header().Set("Content-Type", contentType+"; charset=utf-8")
	// Write the data out to the response.
	fmt.Fprint(w, o)
}

// Appends a default value to a map only if the key, defined as k, doesn't
// already exist in the array.
func AppendDefaultIfNotSet(sl map[string]string, k string, dv string) map[string]string {
	if _, ok := sl[k]; !ok {
		sl[k] = dv
	}
	return sl
}

// url.ParseQuery returns a map containing as a value a slice with often just
// one value. We're fixing that.
func SimplifyQueryMap(sl url.Values) map[string]string {
	var ret map[string]string = map[string]string{}
	for k, v := range sl {
		// We're getting only the last element, because we take as granted that
		// what the use actually means is the last element, if he has provided
		// multiple values for the same key.
		if len(v) > 0 {
			ret[k] = v[len(v)-1]
		}
	}
	return ret
}

// Remove from the IP eventual [ or ], and remove the port part of the IP.
func UnfuckRequestIP(ip string) string {
	ip = strings.Replace(ip, "[", "", 1)
	ip = strings.Replace(ip, "]", "", 1)
	ss := strings.Split(ip, ":")
	ip = strings.Join(ss[:len(ss)-1], ":")
	return ip
}

// Turn the IP into a JSON string containing geodata.
//
// * i: the raw IP string.
// * specific: the specific value to get from the geodata array. Default is ""
// * params: Set callback in the map to a non-"#none#" value to use it as a
//   JSONP callback. Set "pretty" to 1 if you want a 2-space indented JSON
//   output.
func IPToResponse(i string, specific string, params map[string]string) (string, string) {
	ip := net.ParseIP(i)
	if ip == nil {
		return "Please provide a valid IP address", "text/html"
	}

	// Query the maxmind database for that IP address.
	record, err := db.City(ip)
	if err != nil {
		log.Fatal(err)
	}

	// String containing the region/subdivision of the IP. (E.g.: Scotland, or
	// California).
	var sd string
	// If there are subdivisions for this IP, set sd as the first element in the
	// array's name.
	if record.Subdivisions != nil {
		sd = record.Subdivisions[0].Names["en"]
	}

	// Create a new instance of all the data to be returned to the user.
	data := map[string]string{}
	// Fill up the data array with the geoip data.
	data["ip"] = ip.String()
	data["country"] = record.Country.IsoCode
	data["country_full"] = record.Country.Names["en"]
	data["city"] = record.City.Names["en"]
	data["region"] = sd
	data["continent"] = record.Continent.Code
	data["continent_full"] = record.Continent.Names["en"]
	data["postal"] = record.Postal.Code
	// precision of latitude/longitude is up to 4 decimal places (even on
	// ipinfo.io).
	data["loc"] = fmt.Sprintf("%.4f,%.4f", record.Location.Latitude, record.Location.Longitude)

	// Since we don't have HTML output, nor other data from geo data,
	// everything is the same if you do /8.8.8.8, /8.8.8.8/json or /8.8.8.8/geo.
	if specific == "" || specific == "json" || specific == "geo" {
		var bytes_output []byte
		if params["pretty"] == "1" {
			bytes_output, _ = json.MarshalIndent(data, "", "  ")
		} else {
			bytes_output, _ = json.Marshal(data)
		}
		return JSONPify(params["callback"], string(bytes_output[:])),
			"application/json"
	} else if val, ok := data[specific]; ok {
		// If we got a specific value for what the user requested, return only
		// that specific value.
		return val, "text/html"
	} else {
		// We got nothing to show to the user.
		return "undefined", "text/html"
	}
}

// Wraps wrapData into a JSONP callback, if the callback name is valid.
func JSONPify(callback string, wrapData string) string {
	// If you have a callback name longer than 2000 characters, I gotta say, you
	// really should learn to minify your javascript code!
	if callback != "#none#" && callback != "" && len(callback) < 2000 {
		// In case you're wondering, yes, there is a reason for the empty
		// comment! http://stackoverflow.com/a/16048976/5328069
		wrapData = fmt.Sprintf("/**/ typeof %s === 'function' "+
			"&& %s(%s);", callback, callback, wrapData)
	}
	return wrapData
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/rpc"
	"time"
)

// TODO the rest

var serverRoot = flag.String("serverRoot", "", "Path to the root directory in the prod machine")
var mode = flag.String("mode", "client", "'server' or 'client'")
var port = flag.Int("port", 8000, "port to serve on / connect to")
var runBackgroundCheck = flag.Bool("enforce", false, "Run background enforcer")
var deployFile = flag.String("cfg", "deploy.json", "Deploy config file")
var targetName = flag.String("target", "prod", "Target backend")

func main() {
	welcome()
	flag.Parse()
	if *mode == "server" {
		serverMain()
	} else {
		clientMain()
	}
}

func serverMain() {
	server, err := NewServerImpl(
		*serverRoot,
		*runBackgroundCheck,
		*port)
	if err != nil {
		log.Fatal("NewServer:", err)
	}
	rpcServer := &RpcServer{server}
	rpc.Register(rpcServer)
	rpc.HandleHTTP()

	// Localhost only, in case it's not behind a firewall!
	portStr := fmt.Sprintf("localhost:%d", *port)
	l, err := net.Listen("tcp", portStr)
	if err != nil {
		log.Fatal("failed to listen:", err)
	}
	fmt.Printf("Listening on %s\n", portStr)
	http.Serve(l, nil)
}

func clientMain() {
	client, err := NewClientImpl(*deployFile, *targetName)
	if err != nil {
		log.Fatal("NewClient:", err)
	}
	err = NewTerminalClient(flag.CommandLine, client).Run()
	if err != nil {
		log.Fatal(err)
	}
}

func welcome() {
	println()
	println("  " + QUOTES[time.Now().UnixNano()%int64(len(QUOTES))])
	println("      -- Camus")
	println()
}

func sleepSeconds(seconds int) {
	time.Sleep(time.Duration(seconds) * time.Second)
}
<commit_msg>Use -server as a flag instead of -mode server.<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/rpc"
	"time"
)

// TODO the rest

var serverRoot = flag.String("serverRoot", "", "Path to the root directory in the prod machine")
var port = flag.Int("port", 8000, "port to serve on / connect to")
var serverMode = flag.Bool("server", false, "If true, run as a server.")
var runBackgroundCheck = flag.Bool("enforce", false, "Run background enforcer")
var deployFile = flag.String("cfg", "deploy.json", "Deploy config file")
var targetName = flag.String("target", "prod", "Target backend")

func main() {
	welcome()
	flag.Parse()
	if *serverMode {
		serverMain()
	} else {
		clientMain()
	}
}

func serverMain() {
	server, err := NewServerImpl(
		*serverRoot,
		*runBackgroundCheck,
		*port)
	if err != nil {
		log.Fatal("NewServer:", err)
	}
	rpcServer := &RpcServer{server}
	rpc.Register(rpcServer)
	rpc.HandleHTTP()

	// Localhost only, in case it's not behind a firewall!
	portStr := fmt.Sprintf("localhost:%d", *port)
	l, err := net.Listen("tcp", portStr)
	if err != nil {
		log.Fatal("failed to listen:", err)
	}
	fmt.Printf("Listening on %s\n", portStr)
	http.Serve(l, nil)
}

func clientMain() {
	client, err := NewClientImpl(*deployFile, *targetName)
	if err != nil {
		log.Fatal("NewClient:", err)
	}
	err = NewTerminalClient(flag.CommandLine, client).Run()
	if err != nil {
		log.Fatal(err)
	}
}

func welcome() {
	println()
	println("  " + QUOTES[time.Now().UnixNano()%int64(len(QUOTES))])
	println("      -- Camus")
	println()
}

func sleepSeconds(seconds int) {
	time.Sleep(time.Duration(seconds) * time.Second)
}
<|endoftext|>