<commit_before>//
// Ebase frame for daemon program
// Author Jonsen Yang
// Date 2013-07-05
// Copyright (c) 2013 ForEase Times Technology Co., Ltd. All rights reserved.
//
package ebase

import (
	"flag"
	"fmt"
	"github.com/forease/config"
	"os"
	"os/signal"
	"path"
	"reflect"
	"runtime"
	"syscall"
)

var (
	// 日志
	Log        *BaseLog
	Config     *config.Config
	SigHandler = make(map[string]interface{}) //
	G          = make(map[string]interface{}) //

	// 定义命令行参数
	verbose = flag.Bool("v", false, "Verbose output")
	help    = flag.Bool("h", false, "Show this help")
	chroot  = flag.Bool("w", false, "Setup enable chroot")
	cfgfile = flag.String("c", "", "Config file")
	workdir = flag.String("d", "", "Setup work dir")
	pidfile = flag.String("p", "", "Pid file")
)

func init() {
	flag.Parse()
	if *help {
		Help()
		return
	}

	if *workdir != "" {
		fmt.Println("workdir: ", *workdir, os.Args)
		if err := syscall.Chdir(*workdir); err != nil {
			fmt.Printf("Can't change to work dir [%s]: %s\n", *workdir, err)
			os.Exit(1)
		}

		if *chroot {
			pwd, _ := os.Getwd()
			if err := syscall.Chroot(pwd); err != nil {
				fmt.Printf("Can't Chroot to %s: %s\n", *workdir, err)
				os.Exit(1)
			}
			fmt.Printf("I'll Chroot to %s !\n", pwd)
		}
	}

	CreatePid()

	runtime.GOMAXPROCS(runtime.NumCPU())

	Config = LoadConfig("")
	Log = defaultLog()

	SigHandler["sighup"] = func() {
		Log.Debug("reload config")
		Config = LoadConfig("")
	}

	//
	if ok, _ := Config.Bool("sys.signal", false); ok {
		go SignalHandle(SigHandler)
	}
}

func LoadConfig(configFile string) (cfg *config.Config) {
	var err error
	if configFile == "" {
		if *cfgfile != "" {
			configFile = *cfgfile
		} else {
			configFile = "/opt/etc/" + path.Base(os.Args[0]) + ".conf"
		}
	}

	cfg, err = config.NewConfig(configFile, 5)
	if err != nil {
		fmt.Println("read config file error: ", err)
		os.Exit(1)
	}

	return cfg
}

func defaultLog() (l *BaseLog) {

	logType, _ := Config.String("log.type", "consloe")
	logFile, _ := Config.String("log.file", "")
	logLevel, _ := Config.Int("log.level", 5)
	logFlag, _ := Config.Int("log.flag", 9)
	//logEnable, _ = Config.Bool("log.enable", true)
	opt := &LogOptions{Type: logType, File: logFile, Level: logLevel, Flag: logFlag}
	return NewLog(opt)
}

//
func SignalHandle(funcs map[string]interface{}) {
	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGHUP)

	for {
		select {
		case s := <-ch:
			switch s {
			default:
			case syscall.SIGHUP:
				if f, ok := funcs["sighup"]; ok {
					if ff := reflect.ValueOf(f); ff.Kind() == reflect.Func {
						ff.Call(nil)
					}
				}
				break
			case syscall.SIGINT:
				if f, ok := funcs["sigint"]; ok {
					if ff := reflect.ValueOf(f); ff.Kind() == reflect.Func {
						ff.Call(nil)
					}
				}
				os.Exit(1)
			case syscall.SIGUSR1:
				if f, ok := funcs["sigusr1"]; ok {
					if ff := reflect.ValueOf(f); ff.Kind() == reflect.Func {
						ff.Call(nil)
					}
				}
			case syscall.SIGUSR2:
				if f, ok := funcs["sigusr2"]; ok {
					if ff := reflect.ValueOf(f); ff.Kind() == reflect.Func {
						ff.Call(nil)
					}
				}
			}
		}
	}
}

// create pid file
func CreatePid() {
	pid := os.Getpid()

	if pid < 1 {
		fmt.Println("Get pid err")
		os.Exit(1)
	}

	var pidf string
	if *pidfile != "" {
		pidf = *pidfile
	} else {
		pidf, _ = Config.String("sys.pid", "")
		if pidf == "" {
			pidf = "/var/run/" + path.Base(os.Args[0]) + ".pid"
		}
	}
	f, err := os.OpenFile(pidf, os.O_CREATE|os.O_RDWR, 0666)
	if err != nil {
		fmt.Println("Open pid file err ", err)
		os.Exit(1)
	}

	f.WriteString(GetIntStr(pid))
	f.Close()
}

func Daemon(nochdir, noclose int) int {
	var ret, ret2 uintptr
	var err syscall.Errno

	darwin := runtime.GOOS == "darwin"

	// already a daemon
	if syscall.Getppid() == 1 {
		return 0
	}

	// fork off the parent process
	ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if err != 0 {
		return -1
	}

	// failure
	if ret2 < 0 {
		os.Exit(-1)
	}

	// handle exception for darwin
	if darwin && ret2 == 1 {
		ret = 0
	}

	// if we got a good PID, then we call exit the parent process.
	if ret > 0 {
		os.Exit(0)
	}

	/* Change the file mode mask */
	_ = syscall.Umask(0)

	// create a new SID for the child process
	s_ret, s_errno := syscall.Setsid()
	if s_errno != nil {
		Log.Errorf("Error: syscall.Setsid errno: %d", s_errno)
	}
	if s_ret < 0 {
		return -1
	}

	if nochdir == 0 {
		os.Chdir("/")
	}

	if noclose == 0 {
		f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
		if e == nil {
			fd := f.Fd()
			syscall.Dup2(int(fd), int(os.Stdin.Fd()))
			syscall.Dup2(int(fd), int(os.Stdout.Fd()))
			syscall.Dup2(int(fd), int(os.Stderr.Fd()))
		}
	}

	return 0
}

func Help() {
	fmt.Printf(
		"\nUseage: %s [ Options ]\n\n"+
			"Options:\n"+
			"  -c Server config file [Default: etc/serverd.conf]\n"+
			"  -d Work dir [Default: publish]\n"+
			"  -h Display this mssage\n"+
			"  -p Pid file [Default: var/serverd.pid]\n"+
			"  -w Enable chroot to work dir [Required: -d ]\n\n"+
			"------------------------------------------------------\n\n"+
			"  Author:  16hot (im16hot@gmail.com) \n"+
			"  Company: Beijing ForEase Times Technology Co., Ltd.\n"+
			"  Website: http://www.forease.net\n"+
			"  MyBlog:  http://16hot.com\n"+
			"  Version: 1.0 Beta1\n\n"+
			"------------------------------------------------------\n\n",
		os.Args[0])

	os.Exit(0)
}
<commit_msg>add pid file check<commit_after>//
// Ebase frame for daemon program
// Author Jonsen Yang
// Date 2013-07-05
// Copyright (c) 2013 ForEase Times Technology Co., Ltd. All rights reserved.
//
package ebase

import (
	"flag"
	"fmt"
	"github.com/forease/config"
	"os"
	"os/signal"
	"path"
	"reflect"
	"runtime"
	"syscall"
)

var (
	// 日志
	Log        *BaseLog
	Config     *config.Config
	SigHandler = make(map[string]interface{}) //
	G          = make(map[string]interface{}) //

	// 定义命令行参数
	verbose = flag.Bool("v", false, "Verbose output")
	help    = flag.Bool("h", false, "Show this help")
	chroot  = flag.Bool("w", false, "Setup enable chroot")
	cfgfile = flag.String("c", "", "Config file")
	workdir = flag.String("d", "", "Setup work dir")
	pidfile = flag.String("p", "", "Pid file")
)

func init() {
	flag.Parse()
	if *help {
		Help()
		return
	}

	if *workdir != "" {
		fmt.Println("workdir: ", *workdir, os.Args)
		if err := syscall.Chdir(*workdir); err != nil {
			fmt.Printf("Can't change to work dir [%s]: %s\n", *workdir, err)
			os.Exit(1)
		}

		if *chroot {
			pwd, _ := os.Getwd()
			if err := syscall.Chroot(pwd); err != nil {
				fmt.Printf("Can't Chroot to %s: %s\n", *workdir, err)
				os.Exit(1)
			}
			fmt.Printf("I'll Chroot to %s !\n", pwd)
		}
	}

	CreatePid()

	runtime.GOMAXPROCS(runtime.NumCPU())

	Config = LoadConfig("")
	Log = defaultLog()

	SigHandler["sighup"] = func() {
		Log.Debug("reload config")
		Config = LoadConfig("")
	}

	//
	if ok, _ := Config.Bool("sys.signal", false); ok {
		go SignalHandle(SigHandler)
	}
}

func LoadConfig(configFile string) (cfg *config.Config) {
	var err error
	if configFile == "" {
		if *cfgfile != "" {
			configFile = *cfgfile
		} else {
			configFile = "/opt/etc/" + path.Base(os.Args[0]) + ".conf"
		}
	}

	cfg, err = config.NewConfig(configFile, 5)
	if err != nil {
		fmt.Println("read config file error: ", err)
		os.Exit(1)
	}

	return cfg
}

func defaultLog() (l *BaseLog) {

	logType, _ := Config.String("log.type", "consloe")
	logFile, _ := Config.String("log.file", "")
	logLevel, _ := Config.Int("log.level", 5)
	logFlag, _ := Config.Int("log.flag", 9)
	//logEnable, _ = Config.Bool("log.enable", true)
	opt := &LogOptions{Type: logType, File: logFile, Level: logLevel, Flag: logFlag}
	return NewLog(opt)
}

//
func SignalHandle(funcs map[string]interface{}) {
	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGHUP)

	for {
		select {
		case s := <-ch:
			switch s {
			default:
			case syscall.SIGHUP:
				if f, ok := funcs["sighup"]; ok {
					if ff := reflect.ValueOf(f); ff.Kind() == reflect.Func {
						ff.Call(nil)
					}
				}
				break
			case syscall.SIGINT:
				if f, ok := funcs["sigint"]; ok {
					if ff := reflect.ValueOf(f); ff.Kind() == reflect.Func {
						ff.Call(nil)
					}
				}
				os.Exit(1)
			case syscall.SIGUSR1:
				if f, ok := funcs["sigusr1"]; ok {
					if ff := reflect.ValueOf(f); ff.Kind() == reflect.Func {
						ff.Call(nil)
					}
				}
			case syscall.SIGUSR2:
				if f, ok := funcs["sigusr2"]; ok {
					if ff := reflect.ValueOf(f); ff.Kind() == reflect.Func {
						ff.Call(nil)
					}
				}
			}
		}
	}
}

// create pid file
func CreatePid() {
	pid := os.Getpid()

	if pid < 1 {
		fmt.Println("Get pid err")
		os.Exit(1)
	}

	var pidf string
	if *pidfile != "" {
		pidf = *pidfile
	} else {
		pidf, _ = Config.String("sys.pid", "")
		if pidf == "" {
			pidf = "/var/run/" + path.Base(os.Args[0]) + ".pid"
		}
	}

	if pidf == "" {
		fmt.Println("pid file not setup")
		os.Exit(1)
	}

	f, err := os.OpenFile(pidf, os.O_CREATE|os.O_RDWR, 0666)
	if err != nil {
		fmt.Println("Open pid file err ", err)
		os.Exit(1)
	}

	f.WriteString(GetIntStr(pid))
	f.Close()
}

func Daemon(nochdir, noclose int) int {
	var ret, ret2 uintptr
	var err syscall.Errno

	darwin := runtime.GOOS == "darwin"

	// already a daemon
	if syscall.Getppid() == 1 {
		return 0
	}

	// fork off the parent process
	ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
	if err != 0 {
		return -1
	}

	// failure
	if ret2 < 0 {
		os.Exit(-1)
	}

	// handle exception for darwin
	if darwin && ret2 == 1 {
		ret = 0
	}

	// if we got a good PID, then we call exit the parent process.
	if ret > 0 {
		os.Exit(0)
	}

	/* Change the file mode mask */
	_ = syscall.Umask(0)

	// create a new SID for the child process
	s_ret, s_errno := syscall.Setsid()
	if s_errno != nil {
		Log.Errorf("Error: syscall.Setsid errno: %d", s_errno)
	}
	if s_ret < 0 {
		return -1
	}

	if nochdir == 0 {
		os.Chdir("/")
	}

	if noclose == 0 {
		f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
		if e == nil {
			fd := f.Fd()
			syscall.Dup2(int(fd), int(os.Stdin.Fd()))
			syscall.Dup2(int(fd), int(os.Stdout.Fd()))
			syscall.Dup2(int(fd), int(os.Stderr.Fd()))
		}
	}

	return 0
}

func Help() {
	fmt.Printf(
		"\nUseage: %s [ Options ]\n\n"+
			"Options:\n"+
			"  -c Server config file [Default: etc/serverd.conf]\n"+
			"  -d Work dir [Default: publish]\n"+
			"  -h Display this mssage\n"+
			"  -p Pid file [Default: var/serverd.pid]\n"+
			"  -w Enable chroot to work dir [Required: -d ]\n\n"+
			"------------------------------------------------------\n\n"+
			"  Author:  16hot (im16hot@gmail.com) \n"+
			"  Company: Beijing ForEase Times Technology Co., Ltd.\n"+
			"  Website: http://www.forease.net\n"+
			"  MyBlog:  http://16hot.com\n"+
			"  Version: 1.0 Beta1\n\n"+
			"------------------------------------------------------\n\n",
		os.Args[0])

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


<commit_before>package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
	"log"
	"os"
)

func getPublicIP() ([]byte, error) {
	res, err := http.Get("http://ip.nfriedly.com/text")
	defer res.Body.Close()
	if err != nil {
		return nil, err
	}
	return ioutil.ReadAll(res.Body)
}

func main() {
	publicIP, err := getPublicIP()

	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	fmt.Printf("%s\n", publicIP)
}
<commit_msg>logErrorThenExit function<commit_after>package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
	"log"
	"os"
	// "github.com/awslabs/aws-sdk-go/aws"
	// "github.com/awslabs/aws-sdk-go/service/route53"
)

func getPublicIP() ([]byte, error) {
	res, err := http.Get("http://ip.nfriedly.com/text")
	defer res.Body.Close()
	if err != nil {
		return nil, err
	}
	return ioutil.ReadAll(res.Body)
}

func logErrorThenExit(err error) {
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
}

func main() {
	publicIP, err := getPublicIP()
	logErrorThenExit(err)

	fmt.Printf("%s\n", publicIP)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
	"log"
	"os"
	"github.com/goamz/goamz/aws"
	"github.com/goamz/goamz/route53"
	"encoding/json"
)

type config struct {
	AWS_ACCESS_KEY string
	AWS_SECRET_ACCESS_KEY string
	HOSTED_ZONE_ID string
	SUBDOMAIN string
}

func readConfigFile() (*config, error) {
	fileContent, err := ioutil.ReadFile("/etc/go-dyn-dns-conf.json")
	logErrorThenExit(err)

	res := &config{}

	if err := json.Unmarshal(fileContent, res); err != nil {
		return nil, err
	}

	return res, nil
}

func getPublicIP() ([]byte, error) {
	res, err := http.Get("http://ip.nfriedly.com/text")
	defer res.Body.Close()
	if err != nil {
		return nil, err
	}
	return ioutil.ReadAll(res.Body)
}

func connectToRoute53(AWS_ACCESS_KEY string, AWS_SECRET_ACCESS_KEY string) (*route53.Route53, error) {
	auth := aws.Auth{
		AccessKey: AWS_ACCESS_KEY,
		SecretKey: AWS_SECRET_ACCESS_KEY,
	}
	return route53.NewRoute53(auth)
}

func updateRoute53Record(publicIP string, configMap *config, route53Client *route53.Route53) (*route53.ChangeResourceRecordSetsResponse, error) {
	rrv := []route53.ResourceRecordValue{route53.ResourceRecordValue{Value: publicIP}}
	basicRRS := route53.BasicResourceRecordSet{Action: "UPSERT", Name: configMap.SUBDOMAIN, Type: "A", TTL: 60, Values: rrv}
	RRSSlice := []route53.ResourceRecordSet{route53.ResourceRecordSet(basicRRS)}
	createRequest := route53.ChangeResourceRecordSetsRequest{Changes: RRSSlice, Xmlns: "https://route53.amazonaws.com/doc/2013-04-01/"}

	return route53Client.ChangeResourceRecordSet(&createRequest, configMap.HOSTED_ZONE_ID)
}

func logErrorThenExit(err error) {
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
}

func main() {
	publicIP, err := getPublicIP()
	logErrorThenExit(err)
	fmt.Printf("%s\n", publicIP)

	configMap, err := readConfigFile()
	logErrorThenExit(err)
	fmt.Printf("%s\n", configMap.HOSTED_ZONE_ID)

	route53Client, err := connectToRoute53(configMap.AWS_ACCESS_KEY, configMap.AWS_SECRET_ACCESS_KEY)
	logErrorThenExit(err)
	fmt.Printf("%s\n", route53Client.Endpoint)

	_, err = updateRoute53Record(string(publicIP), configMap, route53Client)
	logErrorThenExit(err)
	fmt.Println("All done!")
}
<commit_msg>remove some logging<commit_after>package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
	"log"
	"os"
	"github.com/goamz/goamz/aws"
	"github.com/goamz/goamz/route53"
	"encoding/json"
)

type config struct {
	AWS_ACCESS_KEY string
	AWS_SECRET_ACCESS_KEY string
	HOSTED_ZONE_ID string
	SUBDOMAIN string
}

func readConfigFile() (*config, error) {
	fileContent, err := ioutil.ReadFile("/etc/go-dyn-dns-conf.json")
	logErrorThenExit(err)

	res := &config{}

	if err := json.Unmarshal(fileContent, res); err != nil {
		return nil, err
	}

	return res, nil
}

func getPublicIP() ([]byte, error) {
	res, err := http.Get("http://ip.nfriedly.com/text")
	defer res.Body.Close()
	if err != nil {
		return nil, err
	}
	return ioutil.ReadAll(res.Body)
}

func connectToRoute53(AWS_ACCESS_KEY string, AWS_SECRET_ACCESS_KEY string) (*route53.Route53, error) {
	auth := aws.Auth{
		AccessKey: AWS_ACCESS_KEY,
		SecretKey: AWS_SECRET_ACCESS_KEY,
	}
	return route53.NewRoute53(auth)
}

func updateRoute53Record(publicIP string, configMap *config, route53Client *route53.Route53) (*route53.ChangeResourceRecordSetsResponse, error) {
	rrv := []route53.ResourceRecordValue{route53.ResourceRecordValue{Value: publicIP}}
	basicRRS := route53.BasicResourceRecordSet{Action: "UPSERT", Name: configMap.SUBDOMAIN, Type: "A", TTL: 60, Values: rrv}
	RRSSlice := []route53.ResourceRecordSet{route53.ResourceRecordSet(basicRRS)}
	createRequest := route53.ChangeResourceRecordSetsRequest{Changes: RRSSlice, Xmlns: "https://route53.amazonaws.com/doc/2013-04-01/"}

	return route53Client.ChangeResourceRecordSet(&createRequest, configMap.HOSTED_ZONE_ID)
}

func logErrorThenExit(err error) {
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
}

func main() {
	publicIP, err := getPublicIP()
	logErrorThenExit(err)

	configMap, err := readConfigFile()
	logErrorThenExit(err)

	route53Client, err := connectToRoute53(configMap.AWS_ACCESS_KEY, configMap.AWS_SECRET_ACCESS_KEY)
	logErrorThenExit(err)

	_, err = updateRoute53Record(string(publicIP), configMap, route53Client)
	logErrorThenExit(err)
	fmt.Printf("Successfully mapped %s to IP %s.\n", configMap.SUBDOMAIN, publicIP)
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"flag"
	"fmt"
	"os"
	"strconv"
	"time"

	"github.com/rubenv/sql-migrate"

	"github.com/af83/edwig/api"
	"github.com/af83/edwig/audit"
	"github.com/af83/edwig/config"
	"github.com/af83/edwig/logger"
	"github.com/af83/edwig/model"
	"github.com/af83/edwig/siri"

	_ "github.com/lib/pq"
)

func main() {
	uuidPtr := flag.Bool("testuuid", false, "Use the test uuid generator")
	clockPtr := flag.String("testclock", "", "Use a fake clock at time given. Format 20060102-1504")
	pidPtr := flag.String("pidfile", "", "Write processus pid in given file")
	// configPtr := flag.String("config", "", "Config directory")
	flag.BoolVar(&logger.Log.Debug, "debug", false, "Enable debug messages")
	flag.BoolVar(&logger.Log.Syslog, "syslog", false, "Redirect messages to syslog")

	flag.Parse()

	if len(flag.Args()) == 0 {
		fmt.Println("usage: edwig [-testuuid] [-testclock=<time>] [-pidfile=<filename>]")
		fmt.Println("             [-config=<path>] [-debug] [-syslog]")
		fmt.Println("\tcheck [-requestor-ref=<requestorRef>] <url>")
		fmt.Println("\tapi")
		fmt.Println("\tmigrate [-path=<path>] <up|down>")
		os.Exit(1)
	}

	// Load configuration files
	var err error
	// err = config.LoadConfig(*configPtr)
	// if err != nil {
	// 	logger.Log.Panicf("Error while loading configuration: %v", err)
	// }

	if *uuidPtr {
		model.SetDefaultUUIDGenerator(model.NewFakeUUIDGenerator())
	}
	if *clockPtr != "" {
		testTime, err := time.Parse("20060102-1504", *clockPtr)
		if err != nil {
			panic(err)
		}
		model.SetDefaultClock(model.NewFakeClockAt(testTime))
	}
	if *pidPtr != "" {
		f, err := os.Create(*pidPtr)
		if err != nil {
			logger.Log.Printf("Error: Unable to create a file at given path")
			os.Exit(2)
		}
		defer f.Close()
		_, err = f.WriteString(strconv.Itoa(os.Getpid()))
		if err != nil {
			panic(err)
		}
	}

	command := flag.Args()[0]

	switch command {
	case "check":
		checkFlags := flag.NewFlagSet("check", flag.ExitOnError)
		requestorRefPtr := checkFlags.String("requestor-ref", "Edwig", "Specify requestorRef")
		checkFlags.Parse(flag.Args()[1:])

		err = checkStatus(checkFlags.Args()[0], *requestorRefPtr)
	case "api":
		err = api.NewServer("localhost:8080").ListenAndServe("default")
	case "migrate":
		checkFlags := flag.NewFlagSet("migrate", flag.ExitOnError)
		migrationFilesPtr := checkFlags.String("path", "db/migrations", "Specify migration files path")
		checkFlags.Parse(flag.Args()[1:])

		err = applyMigrations(checkFlags.Args()[0], *migrationFilesPtr)
	}

	if err != nil {
		if _, ok := err.(*siri.SiriError); !ok {
			logger.Log.Panicf("Error while running: %v", err)
		}
		// Siri errors
		logger.Log.Printf("%v", err)
		os.Exit(2)
	}

	os.Exit(0)
}

func checkStatus(url string, requestorRef string) error {
	client := siri.NewSOAPClient(url)
	request := &siri.SIRICheckStatusRequest{
		RequestorRef:      requestorRef,
		RequestTimestamp:  model.DefaultClock().Now(),
		MessageIdentifier: "Edwig:Message::6ba7b814-9dad-11d1-0-00c04fd430c8:LOC",
	}

	startTime := time.Now()

	xmlResponse, err := client.CheckStatus(request)
	if err != nil {
		return err
	}

	responseTime := time.Since(startTime)

	// Logstash
	logstashDatas := make(map[string]string)
	logstashDatas["requestXML"] = request.BuildXML()
	logstashDatas["responseXML"] = xmlResponse.RawXML()
	logstashDatas["processingDuration"] = responseTime.String()
	// ...
	err = audit.CurrentLogStash().WriteEvent(logstashDatas)
	if err != nil {
		logger.Log.Panicf("Error while sending datas to Logstash: %v", err)
	}

	// Log
	var logMessage []byte
	if xmlResponse.Status() {
		logMessage = []byte("SIRI OK - status true - ")
	} else {
		logMessage = []byte("SIRI CRITICAL: status false - ")
		if xmlResponse.ErrorType() == "OtherError" {
			logMessage = append(logMessage, fmt.Sprintf("%s %d %s - ", xmlResponse.ErrorType(), xmlResponse.ErrorNumber(), xmlResponse.ErrorText())...)
		} else {
			logMessage = append(logMessage, fmt.Sprintf("%s %s - ", xmlResponse.ErrorType(), xmlResponse.ErrorText())...)
		}
	}
	logMessage = append(logMessage, fmt.Sprintf("%.3f seconds response time", responseTime.Seconds())...)
	logger.Log.Printf(string(logMessage))

	return nil
}

func applyMigrations(operation, path string) error {
	migrations := &migrate.FileMigrationSource{
		Dir: path,
	}

	dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
		config.Config.DB.User,
		config.Config.DB.Password,
		config.Config.DB.Name,
	)
	db, err := sql.Open("postgres", dbinfo)
	if err != nil {
		return err
	}
	defer db.Close()

	var n int
	switch operation {
	case "up":
		n, err = migrate.Exec(db, "postgres", migrations, migrate.Up)
	case "down":
		n, err = migrate.Exec(db, "postgres", migrations, migrate.Down)
	}
	if err != nil {
		return err
	}
	logger.Log.Debugf("Applied %d migrations\n", n)

	return nil
}
<commit_msg>enable config<commit_after>package main

import (
	"database/sql"
	"flag"
	"fmt"
	"os"
	"strconv"
	"time"

	"github.com/rubenv/sql-migrate"

	"github.com/af83/edwig/api"
	"github.com/af83/edwig/audit"
	"github.com/af83/edwig/config"
	"github.com/af83/edwig/logger"
	"github.com/af83/edwig/model"
	"github.com/af83/edwig/siri"

	_ "github.com/lib/pq"
)

func main() {
	uuidPtr := flag.Bool("testuuid", false, "Use the test uuid generator")
	clockPtr := flag.String("testclock", "", "Use a fake clock at time given. Format 20060102-1504")
	pidPtr := flag.String("pidfile", "", "Write processus pid in given file")
	configPtr := flag.String("config", "", "Config directory")
	flag.BoolVar(&logger.Log.Debug, "debug", false, "Enable debug messages")
	flag.BoolVar(&logger.Log.Syslog, "syslog", false, "Redirect messages to syslog")

	flag.Parse()

	if len(flag.Args()) == 0 {
		fmt.Println("usage: edwig [-testuuid] [-testclock=<time>] [-pidfile=<filename>]")
		fmt.Println("             [-config=<path>] [-debug] [-syslog]")
		fmt.Println("\tcheck [-requestor-ref=<requestorRef>] <url>")
		fmt.Println("\tapi")
		fmt.Println("\tmigrate [-path=<path>] <up|down>")
		os.Exit(1)
	}

	// Load configuration files
	var err error
	err = config.LoadConfig(*configPtr)
	if err != nil {
		logger.Log.Panicf("Error while loading configuration: %v", err)
	}

	if *uuidPtr {
		model.SetDefaultUUIDGenerator(model.NewFakeUUIDGenerator())
	}
	if *clockPtr != "" {
		testTime, err := time.Parse("20060102-1504", *clockPtr)
		if err != nil {
			panic(err)
		}
		model.SetDefaultClock(model.NewFakeClockAt(testTime))
	}
	if *pidPtr != "" {
		f, err := os.Create(*pidPtr)
		if err != nil {
			logger.Log.Printf("Error: Unable to create a file at given path")
			os.Exit(2)
		}
		defer f.Close()
		_, err = f.WriteString(strconv.Itoa(os.Getpid()))
		if err != nil {
			panic(err)
		}
	}

	command := flag.Args()[0]

	switch command {
	case "check":
		checkFlags := flag.NewFlagSet("check", flag.ExitOnError)
		requestorRefPtr := checkFlags.String("requestor-ref", "Edwig", "Specify requestorRef")
		checkFlags.Parse(flag.Args()[1:])

		err = checkStatus(checkFlags.Args()[0], *requestorRefPtr)
	case "api":
		err = api.NewServer("localhost:8080").ListenAndServe("default")
	case "migrate":
		checkFlags := flag.NewFlagSet("migrate", flag.ExitOnError)
		migrationFilesPtr := checkFlags.String("path", "db/migrations", "Specify migration files path")
		checkFlags.Parse(flag.Args()[1:])

		err = applyMigrations(checkFlags.Args()[0], *migrationFilesPtr)
	}

	if err != nil {
		if _, ok := err.(*siri.SiriError); !ok {
			logger.Log.Panicf("Error while running: %v", err)
		}
		// Siri errors
		logger.Log.Printf("%v", err)
		os.Exit(2)
	}

	os.Exit(0)
}

func checkStatus(url string, requestorRef string) error {
	client := siri.NewSOAPClient(url)
	request := &siri.SIRICheckStatusRequest{
		RequestorRef:      requestorRef,
		RequestTimestamp:  model.DefaultClock().Now(),
		MessageIdentifier: "Edwig:Message::6ba7b814-9dad-11d1-0-00c04fd430c8:LOC",
	}

	startTime := time.Now()

	xmlResponse, err := client.CheckStatus(request)
	if err != nil {
		return err
	}

	responseTime := time.Since(startTime)

	// Logstash
	logstashDatas := make(map[string]string)
	logstashDatas["requestXML"] = request.BuildXML()
	logstashDatas["responseXML"] = xmlResponse.RawXML()
	logstashDatas["processingDuration"] = responseTime.String()
	// ...
	err = audit.CurrentLogStash().WriteEvent(logstashDatas)
	if err != nil {
		logger.Log.Panicf("Error while sending datas to Logstash: %v", err)
	}

	// Log
	var logMessage []byte
	if xmlResponse.Status() {
		logMessage = []byte("SIRI OK - status true - ")
	} else {
		logMessage = []byte("SIRI CRITICAL: status false - ")
		if xmlResponse.ErrorType() == "OtherError" {
			logMessage = append(logMessage, fmt.Sprintf("%s %d %s - ", xmlResponse.ErrorType(), xmlResponse.ErrorNumber(), xmlResponse.ErrorText())...)
		} else {
			logMessage = append(logMessage, fmt.Sprintf("%s %s - ", xmlResponse.ErrorType(), xmlResponse.ErrorText())...)
		}
	}
	logMessage = append(logMessage, fmt.Sprintf("%.3f seconds response time", responseTime.Seconds())...)
	logger.Log.Printf(string(logMessage))

	return nil
}

func applyMigrations(operation, path string) error {
	migrations := &migrate.FileMigrationSource{
		Dir: path,
	}

	dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
		config.Config.DB.User,
		config.Config.DB.Password,
		config.Config.DB.Name,
	)
	db, err := sql.Open("postgres", dbinfo)
	if err != nil {
		return err
	}
	defer db.Close()

	var n int
	switch operation {
	case "up":
		n, err = migrate.Exec(db, "postgres", migrations, migrate.Up)
	case "down":
		n, err = migrate.Exec(db, "postgres", migrations, migrate.Down)
	}
	if err != nil {
		return err
	}
	logger.Log.Debugf("Applied %d migrations\n", n)

	return nil
}
<|endoftext|>


<commit_before>// gof3r is a command-line interface for s3gof3r: fast, concurrent, streaming access to Amazon S3.
//
// Example Usage:
//   To stream up to S3:
//      $  <input_stream> | gof3r put -b <bucket> -k <s3_path>
//   To stream down from S3:
//      $ gof3r get -b <bucket> -k <s3_path> | <output_stream>
//   To upload a file to S3:
//      $ gof3r cp <local_path> s3://<bucket>/<s3_path> -m<http_header1> -m<http_header2>...
//   To download a file from S3:
//      $ gof3r cp s3://<bucket>/<s3_path> <local_path>
//
//
// Set AWS keys as environment Variables (required unless using ec2 instance-based credentials):
//
//  $ export AWS_ACCESS_KEY_ID=<access_key>
//  $ export AWS_SECRET_ACCESS_KEY=<secret_key>
//
// Examples:
//  $ tar -cf - /foo_dir/ | gof3r put -b my_s3_bucket -k bar_dir/s3_object -m x-amz-meta-custom-metadata:abc123 -m x-amz-server-side-encryption:AES256
//  $ gof3r get -b my_s3_bucket -k bar_dir/s3_object | tar -x
//
//
// MAN PAGE
//
// http://randallmcpherson.com/s3gof3r/gof3r/gof3r.html
//
// A man page may also be generated with `gof3r -m`
//
package main

import (
	"errors"
	"fmt"
	"os"
	"runtime"
	"time"

	"github.com/jessevdk/go-flags"
	"github.com/rlmcpherson/s3gof3r"
)

const (
	name    = "gof3r"
	version = "0.4.2"
)

func main() {
	// set the number of processors to use to the number of cpus for parallelization of concurrent transfers
	runtime.GOMAXPROCS(runtime.NumCPU())

	start := time.Now()

	// parse ini file
	if err := parseIni(); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	// parser calls the Execute function for the command after parsing the command line options.
	if _, err := parser.Parse(); err != nil {

		if appOpts.WriteIni {
			writeIni() // exits
		}

		// handling for flag parse errors
		if ferr, ok := err.(*flags.Error); ok {
			if ferr.Type == flags.ErrHelp {
				parser.WriteHelp(os.Stderr)
			} else {
				var cmd string
				if parser.Active != nil {
					cmd = parser.Active.Name
				}
				fmt.Fprintf(os.Stderr, "gof3r error: %s\n", err)
				fmt.Fprintf(os.Stderr, "run 'gof3r %s -help' for usage.\n", cmd)
			}
		} else { // handle non-parse errors
			fmt.Fprintf(os.Stderr, "gof3r error: %s\n", err)
		}
		os.Exit(1)
	}
	fmt.Fprintf(os.Stderr, "Duration: %v\n", time.Since(start))
}

// getAWSKeys gets the AWS Keys from environment variables or the instance-based metadata on EC2
// Environment variables are attempted first, followed by the instance-based credentials.
func getAWSKeys() (keys s3gof3r.Keys, err error) {

	keys, err = s3gof3r.EnvKeys()
	if err == nil {
		return
	}
	keys, err = s3gof3r.InstanceKeys()
	if err == nil {
		return
	}
	err = errors.New("no AWS keys found")
	return
}
<commit_msg>Bump version to 0.4.3<commit_after>// gof3r is a command-line interface for s3gof3r: fast, concurrent, streaming access to Amazon S3.
//
// Example Usage:
//   To stream up to S3:
//      $  <input_stream> | gof3r put -b <bucket> -k <s3_path>
//   To stream down from S3:
//      $ gof3r get -b <bucket> -k <s3_path> | <output_stream>
//   To upload a file to S3:
//      $ gof3r cp <local_path> s3://<bucket>/<s3_path> -m<http_header1> -m<http_header2>...
//   To download a file from S3:
//      $ gof3r cp s3://<bucket>/<s3_path> <local_path>
//
//
// Set AWS keys as environment Variables (required unless using ec2 instance-based credentials):
//
//  $ export AWS_ACCESS_KEY_ID=<access_key>
//  $ export AWS_SECRET_ACCESS_KEY=<secret_key>
//
// Examples:
//  $ tar -cf - /foo_dir/ | gof3r put -b my_s3_bucket -k bar_dir/s3_object -m x-amz-meta-custom-metadata:abc123 -m x-amz-server-side-encryption:AES256
//  $ gof3r get -b my_s3_bucket -k bar_dir/s3_object | tar -x
//
//
// MAN PAGE
//
// http://randallmcpherson.com/s3gof3r/gof3r/gof3r.html
//
// A man page may also be generated with `gof3r -m`
//
package main

import (
	"errors"
	"fmt"
	"os"
	"runtime"
	"time"

	"github.com/jessevdk/go-flags"
	"github.com/rlmcpherson/s3gof3r"
)

const (
	name    = "gof3r"
	version = "0.4.3"
)

func main() {
	// set the number of processors to use to the number of cpus for parallelization of concurrent transfers
	runtime.GOMAXPROCS(runtime.NumCPU())

	start := time.Now()

	// parse ini file
	if err := parseIni(); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	// parser calls the Execute function for the command after parsing the command line options.
	if _, err := parser.Parse(); err != nil {

		if appOpts.WriteIni {
			writeIni() // exits
		}

		// handling for flag parse errors
		if ferr, ok := err.(*flags.Error); ok {
			if ferr.Type == flags.ErrHelp {
				parser.WriteHelp(os.Stderr)
			} else {
				var cmd string
				if parser.Active != nil {
					cmd = parser.Active.Name
				}
				fmt.Fprintf(os.Stderr, "gof3r error: %s\n", err)
				fmt.Fprintf(os.Stderr, "run 'gof3r %s -help' for usage.\n", cmd)
			}
		} else { // handle non-parse errors
			fmt.Fprintf(os.Stderr, "gof3r error: %s\n", err)
		}
		os.Exit(1)
	}
	fmt.Fprintf(os.Stderr, "Duration: %v\n", time.Since(start))
}

// getAWSKeys gets the AWS Keys from environment variables or the instance-based metadata on EC2
// Environment variables are attempted first, followed by the instance-based credentials.
func getAWSKeys() (keys s3gof3r.Keys, err error) {

	keys, err = s3gof3r.EnvKeys()
	if err == nil {
		return
	}
	keys, err = s3gof3r.InstanceKeys()
	if err == nil {
		return
	}
	err = errors.New("no AWS keys found")
	return
}
<|endoftext|>


<commit_before>package google

// Asset is the CAI representation of a resource.
type Asset struct {
    // The name, in a peculiar format: `\\<api>.googleapis.com/<self_link>`
    Name string
    // The type name in `google.<api>.<resourcename>` format.
    Type string
    Resource *AssetResource
}

// AssetResource is the Asset's Resource field.
type AssetResource struct {
    // Api version
    Version string
    // URI including scheme for the discovery doc - assembled from
    // product name and version.
    DiscoveryDocumentURI string
    // Resource name.
    DiscoveryName string
    // Actual resource state as per Terraform.  Note that this does
    // not necessarily correspond perfectly with the CAI representation
    // as there are occasional deviations between CAI and API responses.
    // This returns the API response values instead.
    Data map[string]interface{}
}
<commit_msg>Add IAMPolicy to CAI Asset<commit_after>package google

// Asset is the CAI representation of a resource.
type Asset struct {
	// The name, in a peculiar format: `\\<api>.googleapis.com/<self_link>`
	Name string
	// The type name in `google.<api>.<resourcename>` format.
	Type      string
	Resource  *AssetResource
	IAMPolicy *IAMPolicy
}

// AssetResource is the Asset's Resource field.
type AssetResource struct {
	// Api version
	Version string
	// URI including scheme for the discovery doc - assembled from
	// product name and version.
	DiscoveryDocumentURI string
	// Resource name.
	DiscoveryName string
	// Actual resource state as per Terraform.  Note that this does
	// not necessarily correspond perfectly with the CAI representation
	// as there are occasional deviations between CAI and API responses.
	// This returns the API response values instead.
	Data map[string]interface{}
}

type IAMPolicy struct {
	Bindings []IAMBinding
}

type IAMBinding struct {
	Role    string
	Members []string
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/disiqueira/gotree"
	"gopkg.in/ini.v1"
)

const (
	configFile = ".gorganizer-{lang}.ini"
)

var cfg *ini.File
var cfgFile string
var language string

func addToTree(folder, file string, tree gotree.GTStructure) gotree.GTStructure {

	newFile := gotree.GTStructure{Name: file}

	// append to parent, if exists
	for i, item := range tree.Items {
		if item.Name == folder {
			item.Items = append(item.Items, newFile)
			tree.Items[i] = item
			return tree
		}
	}

	// create parent if missing
	newFolder := gotree.GTStructure{Name: folder}
	newFolder.Items = append(newFolder.Items, newFile)
	tree.Items = append(tree.Items, newFolder)

	return tree
}

type excludeListType []string

func (e excludeListType) checkExclude(ext string) bool {
	for _, item := range e {
		if item == ext {
			return true
		}
	}
	return false
}

func main() {
	outputFolder := flag.String("output", ".", "Main directory to put organized folders")
	inputFolder := flag.String("directory", ".", "The directory whose files to classify")

	newRule := flag.String("newrule", "", "Insert a new rule. Format ext:folder Example: mp3:Music")
	delRule := flag.String("delrule", "", "Delete a rule. Format ext Example: mp3")

	printRules := flag.Bool("allrules", false, "Print all rules")

	preview := flag.Bool("preview", false, "Only preview, do not move files")

	excludeExtentions := flag.String("exclude", "", "Exclude files will ignore files for organizer. Format pdf,odt")

	flag.StringVar(&language, "language", "en", "Specify language: en|tr|pt")

	flag.Parse()

	initDb()

	defer closeDb()

	var excludeList excludeListType
	excludeList = strings.Split(*excludeExtentions, ",")

	if len(*newRule) > 0 {
		fmt.Println("Creating new rule")
		err := insertRule(*newRule)
		if err != nil {
			fmt.Println(err)
			return
		}
		showRules()
		return
	}

	if len(*delRule) > 0 {
		fmt.Println("Deleting rule")
		deleteRule(*delRule)
		showRules()
		return
	}

	if *printRules {
		showRules()
		return
	}

	files, _ := ioutil.ReadDir(*inputFolder)
	fmt.Println("GOrganizing your Files")

	var tree gotree.GTStructure

	tree.Name = "Files"

	for _, f := range files {
		if f.IsDir() {
			continue
		}

		file := filepath.Join(*inputFolder, f.Name())
		ext := strings.TrimPrefix(path.Ext(file), ".")

		if excludeList.checkExclude(ext) {
			tree = addToTree("Excluded Files", f.Name(), tree)
			continue
		}

		newFolder := iniGet(ext)

		if len(newFolder) > 0 {

			folder := filepath.Join(*outputFolder, newFolder)
			newFile := filepath.Join(folder, f.Name())

			if !*preview {
				_ = os.Mkdir(folder, os.ModePerm)
				os.Rename(file, newFile)
			}
		} else {
			newFolder = "Unknown extension (will not be moved)"
		}

		tree = addToTree(newFolder, f.Name(), tree)

	}

	gotree.PrintTree(tree)

	fmt.Println("All files have been gorganized!")

}
<commit_msg>using pointer  in addToTree function<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/disiqueira/gotree"
	"gopkg.in/ini.v1"
)

const (
	configFile = ".gorganizer-{lang}.ini"
)

var cfg *ini.File
var cfgFile string
var language string

func addToTree(folder, file string, tree *gotree.GTStructure) {

	newFile := gotree.GTStructure{Name: file}

	// append to parent, if exists
	for i, item := range tree.Items {
		if item.Name == folder {
			item.Items = append(item.Items, newFile)
			tree.Items[i] = item
			return
		}
	}

	// create parent if missing
	newFolder := gotree.GTStructure{Name: folder}
	newFolder.Items = append(newFolder.Items, newFile)
	tree.Items = append(tree.Items, newFolder)
}

type excludeListType []string

func (e excludeListType) checkExclude(ext string) bool {
	for _, item := range e {
		if item == ext {
			return true
		}
	}
	return false
}

func main() {
	outputFolder := flag.String("output", ".", "Main directory to put organized folders")
	inputFolder := flag.String("directory", ".", "The directory whose files to classify")

	newRule := flag.String("newrule", "", "Insert a new rule. Format ext:folder Example: mp3:Music")
	delRule := flag.String("delrule", "", "Delete a rule. Format ext Example: mp3")

	printRules := flag.Bool("allrules", false, "Print all rules")

	preview := flag.Bool("preview", false, "Only preview, do not move files")

	excludeExtentions := flag.String("exclude", "", "Exclude files will ignore files for organizer. Format pdf,odt")

	flag.StringVar(&language, "language", "en", "Specify language: en|tr|pt")

	flag.Parse()

	initDb()

	defer closeDb()

	var excludeList excludeListType
	excludeList = strings.Split(*excludeExtentions, ",")

	if len(*newRule) > 0 {
		fmt.Println("Creating new rule")
		err := insertRule(*newRule)
		if err != nil {
			fmt.Println(err)
			return
		}
		showRules()
		return
	}

	if len(*delRule) > 0 {
		fmt.Println("Deleting rule")
		deleteRule(*delRule)
		showRules()
		return
	}

	if *printRules {
		showRules()
		return
	}

	files, _ := ioutil.ReadDir(*inputFolder)
	fmt.Println("GOrganizing your Files")

	var tree gotree.GTStructure

	tree.Name = "Files"

	for _, f := range files {
		if f.IsDir() {
			continue
		}

		file := filepath.Join(*inputFolder, f.Name())
		ext := strings.TrimPrefix(path.Ext(file), ".")

		if excludeList.checkExclude(ext) {
			addToTree("Excluded Files", f.Name(), &tree)
			continue
		}

		newFolder := iniGet(ext)

		if len(newFolder) > 0 {

			folder := filepath.Join(*outputFolder, newFolder)
			newFile := filepath.Join(folder, f.Name())

			if !*preview {
				_ = os.Mkdir(folder, os.ModePerm)
				os.Rename(file, newFile)
			}
		} else {
			newFolder = "Unknown extension (will not be moved)"
		}

		addToTree(newFolder, f.Name(), &tree)
	}

	gotree.PrintTree(tree)

	fmt.Println("All files have been gorganized!")
}
<|endoftext|>


<commit_before>/*
Package embed allows for storing data resources in a virtual filesystem
that gets compiled directly into the output program, eliminating the need
to distribute data files with the application. This is especially useful for small
web servers that need to deliver content files.

The data is gzipped to save space.

An external tool for generating output files can be found at http://github.com/cratonica/embedder

Author: Clint Caywood

http://github.com/cratonica/embed
*/
package embed

import (
	"bytes"
	"compress/gzip"
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

// A mapping of resource identifiers to associated data
type ResourceMap map[string][]byte

// A compressed resource map that can be used for serialization
type PackedResourceMap []byte

var byteOrder binary.ByteOrder = binary.LittleEndian

// Packs the map of resource identifiers => []byte into
// a buffer. This process is revered by calling Unpack.
func Pack(data ResourceMap) (PackedResourceMap, error) {
	var buf bytes.Buffer
	writer, err := gzip.NewWriterLevel(&buf, gzip.BestCompression)
	if err != nil {
		return nil, err
	}
	for i, v := range data {
		if err = binary.Write(writer, byteOrder, int32(len(i))); err != nil {
			return nil, err
		}
		if _, err = writer.Write([]byte(i)); err != nil {
			return nil, err
		}
		if err = binary.Write(writer, byteOrder, int32(len(v))); err != nil {
			return nil, err
		}
		if _, err = writer.Write(v); err != nil {
		}
	}
	if err = writer.Close(); err != nil {
		return nil, err
	}
	result := buf.Bytes()
	return result, nil
}

type DeserializationError struct {
	what     string
	expected int
	actual   int
}

func (this *DeserializationError) Error() string {
	return fmt.Sprintf("Failure deserializing resource: expected %v to be %v bytes, but only read %v bytes", this.what, this.expected, this.actual)
}

func NewDeserializationError(what string, expected int, actual int) *DeserializationError {
	return &DeserializationError{what, expected, actual}
}

// Reads a buffer generated by a call to Pack, returning the original map
func Unpack(data PackedResourceMap) (ResourceMap, error) {
	result := make(map[string][]byte)
	buf := bytes.NewBuffer(data)
	reader, err := gzip.NewReader(buf)
	defer func() {
		reader.Close()
	}()
	if err != nil {
		return nil, err
	}
	for {
		var size int32
		err := binary.Read(reader, byteOrder, &size)
		if err != nil {
			break // EOF
		}
		keyBuf, err := readAll(reader, int(size))
		if err != nil {
			return nil, err
		}
		err = binary.Read(reader, byteOrder, &size)
		if err != nil {
			return nil, err
		}
		dataBuf, err := readAll(reader, int(size))
		if err != nil {
			return nil, err
		}
		result[string(keyBuf)] = dataBuf
	}
	return result, nil
}

// Recursively packs all files in the given directory into
// a resource map. Directory delimiters are converted to Unix-style /
// regardless of the host operating system.
func CreateFromFiles(path string) (ResourceMap, error) {
	result := make(map[string][]byte)
	err := crawl(filepath.Clean(path), filepath.Clean(path), result)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// Generates Go code containing the given data that can be included in the target project
func GenerateGoCode(packageName string, varName string, data PackedResourceMap) string {
	template := `
package %v

var %v PackedResourceMap = %#v
`
	return fmt.Sprintf(template, packageName, varName, data)
}

func readAll(reader io.Reader, size int) ([]byte, error) {
	result := make([]byte, size)
	totalBytes := 0
	for totalBytes < size {
		readSize, err := reader.Read(result[totalBytes:])
		if err != nil {
			return nil, err
		}
		totalBytes += readSize
	}
	return result, nil
}

func crawl(rootPath string, currentPath string, dest map[string][]byte) error {
	files, err := ioutil.ReadDir(currentPath)
	if err != nil {
		return err
	}
	for _, file := range files {
		fullPath := filepath.Join(currentPath, file.Name())
		if file.IsDir() {
			err := crawl(rootPath, fullPath, dest)
			if err != nil {
				return err
			}
		} else {
			buf, err := ioutil.ReadFile(fullPath)
			if err != nil {
				log.Printf("Failure reading file %v: %v", fullPath, err)
			} else {
				key := strings.TrimLeft(fullPath, rootPath)
				if strings.HasPrefix(key, string(os.PathSeparator)) {
					key = key[1:]
				}
				// Convert to unix style for internal use
				key = strings.Replace(key, string(os.PathSeparator), "/", -1)
				dest[key] = buf
			}
		}
	}
	return nil
}
<commit_msg>Fix bug in generated go files<commit_after>/*
Package embed allows for storing data resources in a virtual filesystem
that gets compiled directly into the output program, eliminating the need
to distribute data files with the application. This is especially useful for small
web servers that need to deliver content files.

The data is gzipped to save space.

An external tool for generating output files can be found at http://github.com/cratonica/embedder

Author: Clint Caywood

http://github.com/cratonica/embed
*/
package embed

import (
	"bytes"
	"compress/gzip"
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

// A mapping of resource identifiers to associated data
type ResourceMap map[string][]byte

// A compressed resource map that can be used for serialization
type PackedResourceMap []byte

var byteOrder binary.ByteOrder = binary.LittleEndian

// Packs the map of resource identifiers => []byte into
// a buffer. This process is revered by calling Unpack.
func Pack(data ResourceMap) (PackedResourceMap, error) {
	var buf bytes.Buffer
	writer, err := gzip.NewWriterLevel(&buf, gzip.BestCompression)
	if err != nil {
		return nil, err
	}
	for i, v := range data {
		if err = binary.Write(writer, byteOrder, int32(len(i))); err != nil {
			return nil, err
		}
		if _, err = writer.Write([]byte(i)); err != nil {
			return nil, err
		}
		if err = binary.Write(writer, byteOrder, int32(len(v))); err != nil {
			return nil, err
		}
		if _, err = writer.Write(v); err != nil {
		}
	}
	if err = writer.Close(); err != nil {
		return nil, err
	}
	result := buf.Bytes()
	return result, nil
}

type DeserializationError struct {
	what     string
	expected int
	actual   int
}

func (this *DeserializationError) Error() string {
	return fmt.Sprintf("Failure deserializing resource: expected %v to be %v bytes, but only read %v bytes", this.what, this.expected, this.actual)
}

func NewDeserializationError(what string, expected int, actual int) *DeserializationError {
	return &DeserializationError{what, expected, actual}
}

// Reads a buffer generated by a call to Pack, returning the original map
func Unpack(data PackedResourceMap) (ResourceMap, error) {
	result := make(map[string][]byte)
	buf := bytes.NewBuffer(data)
	reader, err := gzip.NewReader(buf)
	defer func() {
		reader.Close()
	}()
	if err != nil {
		return nil, err
	}
	for {
		var size int32
		err := binary.Read(reader, byteOrder, &size)
		if err != nil {
			break // EOF
		}
		keyBuf, err := readAll(reader, int(size))
		if err != nil {
			return nil, err
		}
		err = binary.Read(reader, byteOrder, &size)
		if err != nil {
			return nil, err
		}
		dataBuf, err := readAll(reader, int(size))
		if err != nil {
			return nil, err
		}
		result[string(keyBuf)] = dataBuf
	}
	return result, nil
}

// Recursively packs all files in the given directory into
// a resource map. Directory delimiters are converted to Unix-style /
// regardless of the host operating system.
func CreateFromFiles(path string) (ResourceMap, error) {
	result := make(map[string][]byte)
	err := crawl(filepath.Clean(path), filepath.Clean(path), result)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// Generates Go code containing the given data that can be included in the target project
func GenerateGoCode(packageName string, varName string, data PackedResourceMap) string {
	template := `
package %v

import "github.com/cratonica/embed"

var %v embed.PackedResourceMap = %#v
`
	return fmt.Sprintf(template, packageName, varName, data)
}

func readAll(reader io.Reader, size int) ([]byte, error) {
	result := make([]byte, size)
	totalBytes := 0
	for totalBytes < size {
		readSize, err := reader.Read(result[totalBytes:])
		if err != nil {
			return nil, err
		}
		totalBytes += readSize
	}
	return result, nil
}

func crawl(rootPath string, currentPath string, dest map[string][]byte) error {
	files, err := ioutil.ReadDir(currentPath)
	if err != nil {
		return err
	}
	for _, file := range files {
		fullPath := filepath.Join(currentPath, file.Name())
		if file.IsDir() {
			err := crawl(rootPath, fullPath, dest)
			if err != nil {
				return err
			}
		} else {
			buf, err := ioutil.ReadFile(fullPath)
			if err != nil {
				log.Printf("Failure reading file %v: %v", fullPath, err)
			} else {
				key := strings.TrimLeft(fullPath, rootPath)
				if strings.HasPrefix(key, string(os.PathSeparator)) {
					key = key[1:]
				}
				// Convert to unix style for internal use
				key = strings.Replace(key, string(os.PathSeparator), "/", -1)
				dest[key] = buf
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package dsig

import (
	"time"

	"github.com/jonboulle/clockwork"
)

// Clock wraps a clockwork.Clock (which could be real or fake) in order
// to default to a real clock when a nil *Clock is used. In other words,
// if you attempt to use a nil *Clock it will defer to the real system
// clock. This allows Clock to be easily added to structs with methods
// that currently reference the time package, without requiring every
// instantiation of that struct to be updated.
type Clock struct {
	wrapped clockwork.Clock
}

func (c *Clock) getWrapped() clockwork.Clock {
	if c == nil {
		return clockwork.NewRealClock()
	}

	return c.wrapped
}

func (c *Clock) After(d time.Duration) <-chan time.Time {
	return c.getWrapped().After(d)
}

func (c *Clock) Sleep(d time.Duration) {
	c.getWrapped().Sleep(d)
}

func (c *Clock) Now() time.Time {
	return c.getWrapped().Now()
}

func NewRealClock() *Clock {
	return &Clock{
		wrapped: clockwork.NewRealClock(),
	}
}

func NewFakeClock(wrapped clockwork.Clock) *Clock {
	return &Clock{
		wrapped: wrapped,
	}
}
<commit_msg>Add NewFakeClockAt method<commit_after>package dsig

import (
	"time"

	"github.com/jonboulle/clockwork"
)

// Clock wraps a clockwork.Clock (which could be real or fake) in order
// to default to a real clock when a nil *Clock is used. In other words,
// if you attempt to use a nil *Clock it will defer to the real system
// clock. This allows Clock to be easily added to structs with methods
// that currently reference the time package, without requiring every
// instantiation of that struct to be updated.
type Clock struct {
	wrapped clockwork.Clock
}

func (c *Clock) getWrapped() clockwork.Clock {
	if c == nil {
		return clockwork.NewRealClock()
	}

	return c.wrapped
}

func (c *Clock) After(d time.Duration) <-chan time.Time {
	return c.getWrapped().After(d)
}

func (c *Clock) Sleep(d time.Duration) {
	c.getWrapped().Sleep(d)
}

func (c *Clock) Now() time.Time {
	return c.getWrapped().Now()
}

func NewRealClock() *Clock {
	return &Clock{
		wrapped: clockwork.NewRealClock(),
	}
}

func NewFakeClock(wrapped clockwork.Clock) *Clock {
	return &Clock{
		wrapped: wrapped,
	}
}

func NewFakeClockAt(t time.Time) *Clock {
	return &Clock{
		wrapped: clockwork.NewFakeClockAt(t),
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"html/template"
	"regexp"
	"strings"
	"time"

	"github.com/kennygrant/sanitize"
	"golang.org/x/net/context"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
)

type Entry struct {
	Id       int64     `json:"id"`
	Title    string    `json:"title"`                     // optional
	Content  string    `datastore:",noindex" json:"text"` // Markdown
	Datetime time.Time `json:"date"`
	Created  time.Time `json:"created"`
	Modified time.Time `json:"modified"`
	Tags     []string  `json:"tags"`
	Longform string    `json:"-"`
	Draft    bool      `json:"-"`
}

func NewEntry(title string, content string, datetime time.Time, tags []string) *Entry {
	e := new(Entry)

	// User supplied content
	e.Title = title
	e.Content = content
	e.Datetime = datetime
	e.Tags = tags

	// Computer generated content
	e.Created = time.Now()
	e.Modified = time.Now()
	e.Draft = false

	return e
}

func ParseTags(text string) ([]string, error) {
	// http://golang.org/pkg/regexp/#Regexp.FindAllStringSubmatch
	finds := HashtagRegex.FindAllStringSubmatch(text, -1)
	ret := make([]string, 0)
	for _, v := range finds {
		if len(v) > 2 {
			ret = append(ret, strings.ToLower(v[2]))
		}
	}

	return ret, nil
}

func GetEntry(c context.Context, id int64) (*Entry, error) {
	var entry Entry
	q := datastore.NewQuery("Entry").Filter("Id =", id).Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		return nil, err
	}

	return &entry, nil
}

func GetLongform(c context.Context, longform string) (*Entry, error) {
	var entry Entry
	q := datastore.NewQuery("Entry").Filter("Longform =", longform).Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		return nil, err
	}

	return &entry, nil
}

func MaxId(c context.Context) (int64, error) {
	var entry Entry
	q := datastore.NewQuery("Entry").Order("-Id").Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		return 0, err
	}
	return entry.Id, nil
}

func AllPosts(c context.Context) (*[]Entry, error) {
	return Posts(c, -1, true)
}

func Pagination(c context.Context, posts, offset int) (*[]Entry, error) {
	q := datastore.NewQuery("Entry").
		Filter("Draft =", false).
		Order("-Datetime").
		Limit(posts).
		Offset(offset)

	entries := new([]Entry)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func ArchivePageQuery() *datastore.Query {
	return datastore.NewQuery("Entry").
		Filter("Draft =", false).
		Project("Id", "Datetime").
		Order("-Datetime").
		Limit(50)
}

func Posts(c context.Context, limit int, recentFirst bool) (*[]Entry, error) {
	q := datastore.NewQuery("Entry").Filter("Draft =", false)

	if recentFirst {
		q = q.Order("-Datetime")
	} else {
		q = q.Order("Datetime")
	}

	if limit > 0 {
		q = q.Limit(limit)
	}

	entries := new([]Entry)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func Drafts(c context.Context) (*[]Entry, error) {
	q := datastore.NewQuery("Entry").Filter("Draft =", true).Order("-Datetime")
	entries := new([]Entry)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func LongformPosts(c context.Context) (*[]Entry, error) {
	q := datastore.NewQuery("Entry").Filter("Longform >", "")
	entries := new([]Entry)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func RecentPosts(c context.Context) (*[]Entry, error) {
	return Posts(c, 20, true)
}

func (e *Entry) HasId() bool {
	return (e.Id > 0)
}

func (e *Entry) Save(c context.Context) error {
	var k *datastore.Key
	if !e.HasId() {
		id, _ := MaxId(c)
		e.Id = id + 1
		k = datastore.NewIncompleteKey(c, "Entry", nil)
	} else {
		// Find the key
		var err error
		q := datastore.NewQuery("Entry").Filter("Id =", e.Id).Limit(1).KeysOnly()
		k, err = q.Run(c).Next(nil)
		if err != nil {
			return err
		}
	}

	cnt, err := datastore.NewQuery("Entry").Filter("Id =", e.Id).Count(c)
	if err != nil {
		return err
	}
	log.Infof(c, "ID: %v: %v", e.Id, cnt)
	if cnt >= 2 {
		id, _ := MaxId(c)
		e.Id = id + 1
	}

	// Pull out links
	// TODO: Do something with the output
	GetLinksFromContent(c, e.Content)

	// Figure out Tags
	tags, err := ParseTags(e.Content)
	if err != nil {
		return err
	}
	e.Tags = tags

	k2, err := datastore.Put(c, k, e)
	if err == nil {
		log.Infof(c, "Wrote %+v", e)
		log.Infof(c, "Old key: %+v; New Key: %+v", k, k2)
	} else {
		log.Warningf(c, "Error writing entry: %v", e)
	}

	return err
}

func (e *Entry) Url() string {
	return fmt.Sprintf("/post/%d", e.Id)
}

func (e *Entry) EditUrl() string {
	return fmt.Sprintf("/edit/%d", e.Id)
}

func (e *Entry) Html() template.HTML {
	return Markdown(e.Content)
}

func (e *Entry) Summary() string {
	// truncate(strip_tags(m(p.text)), :length => 100).strip
	stripped := sanitize.HTML(string(e.Html()))
	if len(stripped) > 100 {
		return fmt.Sprintf("%s...", stripped[:100])
	} else {
		return stripped
	}
}

func (e *Entry) PrevPost(c context.Context) string {
	var entry Entry
	q := datastore.NewQuery("Entry").Order("-Datetime").Filter("Datetime <", e.Datetime).Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		log.Infof(c, "Error getting previous post for %d.", e.Id)
		return ""
	}

	return entry.Url()
}

func (e *Entry) NextPost(c context.Context) string {
	var entry Entry
	q := datastore.NewQuery("Entry").Order("Datetime").Filter("Datetime >", e.Datetime).Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		log.Infof(c, "Error getting next post for %d.", e.Id)
		return ""
	}

	return entry.Url()
}

func GetLinksFromContent(c context.Context, content string) ([]string, error) {
	httpRegex := regexp.MustCompile(`https?:\/\/((\w|\.)+)`)
	matches := httpRegex.FindAllString(content, -1)
	if matches == nil {
		return []string{}, nil
	}

	log.Infof(c, "URLs Found: %+v", matches)

	return matches, nil
}

func PostsForDay(c context.Context, year, month, day int64) (*[]Entry, error) {
	entries := new([]Entry)
	start := time.Date(int(year), time.Month(month), int(day), 0, 0, 0, 0, time.UTC)
	end := start.AddDate(0, 0, 1)
	q := datastore.NewQuery("Entry").Order("-Datetime").Filter("Datetime >=", start).Filter("Datetime <", end).Filter("Draft =", false)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func PostsWithTag(c context.Context, tag string) (*map[int64]Entry, error) {
	entries := make(map[int64]Entry, 0)
	aliases := GetTagAliases(c, tag)
	aliasesAndTag := append(*aliases, tag)

	for _, v := range aliasesAndTag {
		more_entries := new([]Entry)
		q := datastore.NewQuery("Entry").Order("-Datetime").Filter("Tags =", v)
		_, err := q.GetAll(c, more_entries)
		if err != nil {
			return &entries, err
		}
		for _, e := range *more_entries {
			entries[e.Id] = e
		}
	}

	return &entries, nil
}
<commit_msg>cleaning<commit_after>package main

import (
	"fmt"
	"html/template"
	"regexp"
	"strings"
	"time"

	"github.com/kennygrant/sanitize"
	"golang.org/x/net/context"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
)

type Entry struct {
	Id       int64     `json:"id"`
	Title    string    `json:"title"`                     // optional
	Content  string    `datastore:",noindex" json:"text"` // Markdown
	Datetime time.Time `json:"date"`
	Created  time.Time `json:"created"`
	Modified time.Time `json:"modified"`
	Tags     []string  `json:"tags"`
	Longform string    `json:"-"`
	Draft    bool      `json:"-"`
}

func NewEntry(title string, content string, datetime time.Time, tags []string) *Entry {
	e := new(Entry)

	// User supplied content
	e.Title = title
	e.Content = content
	e.Datetime = datetime
	e.Tags = tags

	// Computer generated content
	e.Created = time.Now()
	e.Modified = time.Now()
	e.Draft = false

	return e
}

func ParseTags(text string) ([]string, error) {
	// http://golang.org/pkg/regexp/#Regexp.FindAllStringSubmatch
	finds := HashtagRegex.FindAllStringSubmatch(text, -1)
	ret := make([]string, 0)
	for _, v := range finds {
		if len(v) > 2 {
			ret = append(ret, strings.ToLower(v[2]))
		}
	}

	return ret, nil
}

func GetEntry(c context.Context, id int64) (*Entry, error) {
	var entry Entry
	q := datastore.NewQuery("Entry").Filter("Id =", id).Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		return nil, err
	}

	return &entry, nil
}

func GetLongform(c context.Context, longform string) (*Entry, error) {
	var entry Entry
	q := datastore.NewQuery("Entry").Filter("Longform =", longform).Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		return nil, err
	}

	log.Infof(c, "Attempted to find %v. %+v %+v", longform, entry, err)

	return &entry, nil
}

func MaxId(c context.Context) (int64, error) {
	var entry Entry
	q := datastore.NewQuery("Entry").Order("-Id").Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		return 0, err
	}
	return entry.Id, nil
}

func AllPosts(c context.Context) (*[]Entry, error) {
	return Posts(c, -1, true)
}

func Pagination(c context.Context, posts, offset int) (*[]Entry, error) {
	q := datastore.NewQuery("Entry").
		Filter("Draft =", false).
		Order("-Datetime").
		Limit(posts).
		Offset(offset)

	entries := new([]Entry)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func ArchivePageQuery() *datastore.Query {
	return datastore.NewQuery("Entry").
		Filter("Draft =", false).
		Project("Id", "Datetime").
		Order("-Datetime").
		Limit(50)
}

func Posts(c context.Context, limit int, recentFirst bool) (*[]Entry, error) {
	q := datastore.NewQuery("Entry").Filter("Draft =", false)

	if recentFirst {
		q = q.Order("-Datetime")
	} else {
		q = q.Order("Datetime")
	}

	if limit > 0 {
		q = q.Limit(limit)
	}

	entries := new([]Entry)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func Drafts(c context.Context) (*[]Entry, error) {
	q := datastore.NewQuery("Entry").Filter("Draft =", true).Order("-Datetime")
	entries := new([]Entry)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func LongformPosts(c context.Context) (*[]Entry, error) {
	q := datastore.NewQuery("Entry").Filter("Longform >", "").Order("-Longform")
	entries := new([]Entry)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func RecentPosts(c context.Context) (*[]Entry, error) {
	return Posts(c, 20, true)
}

func (e *Entry) HasId() bool {
	return (e.Id > 0)
}

func (e *Entry) Save(c context.Context) error {
	var k *datastore.Key
	if !e.HasId() {
		id, _ := MaxId(c)
		e.Id = id + 1
		k = datastore.NewIncompleteKey(c, "Entry", nil)
	} else {
		// Find the key
		var err error
		q := datastore.NewQuery("Entry").Filter("Id =", e.Id).Limit(1).KeysOnly()
		k, err = q.Run(c).Next(nil)
		if err != nil {
			return err
		}
	}

	cnt, err := datastore.NewQuery("Entry").Filter("Id =", e.Id).Count(c)
	if err != nil {
		return err
	}
	log.Infof(c, "ID: %v: %v", e.Id, cnt)
	if cnt >= 2 {
		id, _ := MaxId(c)
		e.Id = id + 1
	}

	// Pull out links
	// TODO: Do something with the output
	GetLinksFromContent(c, e.Content)

	// Figure out Tags
	tags, err := ParseTags(e.Content)
	if err != nil {
		return err
	}
	e.Tags = tags

	k2, err := datastore.Put(c, k, e)
	if err == nil {
		// log.Infof(c, "Wrote %+v", e)
		log.Infof(c, "Old key: %+v; New Key: %+v", k, k2)
	} else {
		log.Warningf(c, "Error writing entry: %v", e)
	}

	return err
}

func (e *Entry) Url() string {
	return fmt.Sprintf("/post/%d", e.Id)
}

func (e *Entry) EditUrl() string {
	return fmt.Sprintf("/edit/%d", e.Id)
}

func (e *Entry) Html() template.HTML {
	return Markdown(e.Content)
}

func (e *Entry) Summary() string {
	// truncate(strip_tags(m(p.text)), :length => 100).strip
	stripped := sanitize.HTML(string(e.Html()))
	if len(stripped) > 100 {
		return fmt.Sprintf("%s...", stripped[:100])
	} else {
		return stripped
	}
}

func (e *Entry) PrevPost(c context.Context) string {
	var entry Entry
	q := datastore.NewQuery("Entry").Order("-Datetime").Filter("Datetime <", e.Datetime).Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		log.Infof(c, "Error getting previous post for %d.", e.Id)
		return ""
	}

	return entry.Url()
}

func (e *Entry) NextPost(c context.Context) string {
	var entry Entry
	q := datastore.NewQuery("Entry").Order("Datetime").Filter("Datetime >", e.Datetime).Limit(1)
	_, err := q.Run(c).Next(&entry)
	if err != nil {
		log.Infof(c, "Error getting next post for %d.", e.Id)
		return ""
	}

	return entry.Url()
}

func GetLinksFromContent(c context.Context, content string) ([]string, error) {
	httpRegex := regexp.MustCompile(`https?:\/\/((\w|\.)+)`)
	matches := httpRegex.FindAllString(content, -1)
	if matches == nil {
		return []string{}, nil
	}

	log.Infof(c, "URLs Found: %+v", matches)

	return matches, nil
}

func PostsForDay(c context.Context, year, month, day int64) (*[]Entry, error) {
	entries := new([]Entry)
	start := time.Date(int(year), time.Month(month), int(day), 0, 0, 0, 0, time.UTC)
	end := start.AddDate(0, 0, 1)
	q := datastore.NewQuery("Entry").Order("-Datetime").Filter("Datetime >=", start).Filter("Datetime <", end).Filter("Draft =", false)
	_, err := q.GetAll(c, entries)
	return entries, err
}

func PostsWithTag(c context.Context, tag string) (*map[int64]Entry, error) {
	entries := make(map[int64]Entry, 0)
	aliases := GetTagAliases(c, tag)
	aliasesAndTag := append(*aliases, tag)

	for _, v := range aliasesAndTag {
		more_entries := new([]Entry)
		q := datastore.NewQuery("Entry").Order("-Datetime").Filter("Tags =", v)
		_, err := q.GetAll(c, more_entries)
		if err != nil {
			return &entries, err
		}
		for _, e := range *more_entries {
			entries[e.Id] = e
		}
	}

	return &entries, nil
}
<|endoftext|>


<commit_before>// clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2017, 5, 1, 0, 0, 0, 0, time.Local)
	motto := "Just Go"
	printTargetTime(target, motto)
	exitOnEnterKey()

	var previous time.Time
	for {
		now := time.Now().Truncate(time.Second)
		if now != previous {
			previous = now
			countdown := now.Sub(target) // Negative times are before the target
			printCountdown(now, countdown)
		}
		time.Sleep(100 * time.Millisecond)
	}
}

func exitOnEnterKey() {
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()
}

const (
	indent         = "\t"
	highlightStart = "\x1b[1;35m"
	highlightEnd   = "\x1b[0m"
)

func printTargetTime(target time.Time, motto string) {
	fmt.Print(indent, highlightStart, motto, highlightEnd, "\n")
	fmt.Print(indent, target.Format(time.UnixDate), "\n")
}

func printCountdown(now time.Time, countdown time.Duration) {
	var sign string
	if countdown >= 0 {
		sign = "+"
	} else {
		sign = "-"
		countdown = -countdown
	}

	days := int(countdown / (24 * time.Hour))
	countdown = countdown % (24 * time.Hour)

	fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
	if days > 0 {
		fmt.Print(days, "d")
	}
	fmt.Print(countdown, "          \r")
	os.Stdout.Sync()
}
<commit_msg>May (the) 4th<commit_after>// clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2017, 5, 4, 0, 0, 0, 0, time.UTC)
	motto := "Just Go"
	printTargetTime(target, motto)
	exitOnEnterKey()

	var previous time.Time
	for {
		now := time.Now().Truncate(time.Second)
		if now != previous {
			previous = now
			countdown := now.Sub(target) // Negative times are before the target
			printCountdown(now, countdown)
		}
		time.Sleep(100 * time.Millisecond)
	}
}

func exitOnEnterKey() {
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()
}

const (
	indent         = "\t"
	highlightStart = "\x1b[1;35m"
	highlightEnd   = "\x1b[0m"
)

func printTargetTime(target time.Time, motto string) {
	fmt.Print(indent, highlightStart, motto, highlightEnd, "\n")
	fmt.Print(indent, target.Format(time.UnixDate), "\n")
}

func printCountdown(now time.Time, countdown time.Duration) {
	var sign string
	if countdown >= 0 {
		sign = "+"
	} else {
		sign = "-"
		countdown = -countdown
	}

	days := int(countdown / (24 * time.Hour))
	countdown = countdown % (24 * time.Hour)

	fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
	if days > 0 {
		fmt.Print(days, "d")
	}
	fmt.Print(countdown, "          \r")
	os.Stdout.Sync()
}
<|endoftext|>


<commit_before>package clone

import (
	"crypto/md5"
	"encoding/hex"
	"errors"
	"github.com/jeffail/tunny"
	csv "github.com/whosonfirst/go-whosonfirst-csv"
	log "github.com/whosonfirst/go-whosonfirst-log"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"sync/atomic"
)

type WOFClone struct {
	Source    string
	Dest      string
	Count     int64
	Success   int64
	Error     int64
	Skipped   int64
	Scheduled int64
	Completed int64
	Logger    *log.WOFLogger
	client    *http.Client
	pool      *tunny.WorkPool
}

func NewWOFClone(source string, dest string, procs int, logger *log.WOFLogger) *WOFClone {

	// cd := &sync.Cond{L: &sync.Mutex{}}

	cl := &http.Client{}

	runtime.GOMAXPROCS(procs)

	pool, _ := tunny.CreatePoolGeneric(procs).Open()

	c := WOFClone{
		Count:   0,
		Success: 0,
		Error:   0,
		Skipped: 0,
		Source:  source,
		Dest:    dest,
		Logger:  logger,
		client:  cl,
		pool:    pool,
	}

	return &c
}

func (c *WOFClone) CloneMetaFile(file string) error {

	abs_path, _ := filepath.Abs(file)
	// c.Logger.Debug("Parse meta file %s", abs_path)

	reader, read_err := csv.NewDictReader(abs_path)

	if read_err != nil {
		c.Logger.Error("Failed to read %s, because %v", abs_path, read_err)
		return read_err
	}

	wg := new(sync.WaitGroup)

	for {
		row, err := reader.Read()

		if err == io.EOF {
			break
		}

		if err != nil {
			return err
		}

		rel_path, ok := row["path"]

		if !ok {
			continue
		}

		// this does not account for counts - need to think about who calls what, when
		// probably needs to moved in to ClonePath... (20151105/thisisaaronland)

		ensure_changes := true
		skip_existing := false

		remote := c.Source + rel_path
		local := path.Join(c.Dest, rel_path)

		if !os.IsNotExist(err) {

			if skip_existing {
				c.Logger.Debug("%s already exists and we are skipping things that exist", local)
				continue
			}

			change, _ := c.HasChanged(local, remote)

			if !change {
				c.Logger.Info("no changes to %s", local)
				continue
			}
		}

		wg.Add(1)
		atomic.AddInt64(&c.Scheduled, 1)

		go func() {

			defer wg.Done()

			_, err = c.pool.SendWork(func() {

				cl_err := c.ClonePath(rel_path, ensure_changes)

				if cl_err != nil {
					atomic.AddInt64(&c.Error, 1)
				} else {
					atomic.AddInt64(&c.Success, 1)
				}

				atomic.AddInt64(&c.Completed, 1)
				c.Status()
			})

		}()
	}

	wg.Wait()
	return nil
}

func (c *WOFClone) ClonePath(rel_path string, ensure_changes bool) error {

	atomic.AddInt64(&c.Count, 1)

	remote := c.Source + rel_path
	local := path.Join(c.Dest, rel_path)

	_, err := os.Stat(local)

	if !os.IsNotExist(err) && ensure_changes {

		change, _ := c.HasChanged(local, remote)

		if !change {

			c.Logger.Debug("%s has not changed so skipping", local)
			atomic.AddInt64(&c.Skipped, 1)
			return nil
		}

	}

	process_err := c.Process(remote, local)

	if process_err != nil {
		atomic.AddInt64(&c.Error, 1)
		return process_err
	}

	return nil
}

// don't return true if there's a problem - move that logic up above

func (c *WOFClone) HasChanged(local string, remote string) (bool, error) {

	change := true

	body, err := ioutil.ReadFile(local)

	if err != nil {
		c.Logger.Error("Failed to read %s, becase %v", local, err)
		return change, err
	}

	hash := md5.Sum(body)
	local_hash := hex.EncodeToString(hash[:])

	return c.HasHashChanged(local_hash, remote)
}

func (c *WOFClone) HasHashChanged(local_hash string, remote string) (bool, error) {

	change := true

	rsp, err := c.Fetch("HEAD", remote)

	if err != nil {
		return change, err
	}

	defer rsp.Body.Close()

	etag := rsp.Header.Get("Etag")
	remote_hash := strings.Replace(etag, "\"", "", -1)

	if local_hash == remote_hash {
		change = false
	}

	return change, nil
}

func (c *WOFClone) Process(remote string, local string) error {

	c.Logger.Debug("fetch %s and store in %s", remote, local)

	local_root := path.Dir(local)

	_, err := os.Stat(local_root)

	if os.IsNotExist(err) {
		c.Logger.Info("create %s", local_root)
		os.MkdirAll(local_root, 0755)
	}

	rsp, fetch_err := c.Fetch("GET", remote)

	if fetch_err != nil {
		return fetch_err
	}

	defer rsp.Body.Close()

	contents, read_err := ioutil.ReadAll(rsp.Body)

	if read_err != nil {
		c.Logger.Error("failed to read body for %s, because %v", remote, read_err)
		return read_err
	}

	go func() error {

		write_err := ioutil.WriteFile(local, contents, 0644)

		if write_err != nil {
			c.Logger.Error("Failed to write %s, because %v", local, write_err)

			atomic.AddInt64(&c.Success, -1)
			atomic.AddInt64(&c.Error, 1)

			return write_err
		}

		c.Logger.Debug("Wrote %s to disk", local)
		return nil
	}()

	return nil
}

func (c *WOFClone) Fetch(method string, url string) (*http.Response, error) {

	c.Logger.Debug("%s %s", method, url)

	req, _ := http.NewRequest(method, url, nil)
	req.Close = true

	rsp, err := c.client.Do(req)

	if err != nil {
		c.Logger.Error("Failed to %s %s, because %v", method, url, err)
		// golog.Fatal(err)
		return nil, err
	}

	expected := 200

	if rsp.StatusCode != expected {
		c.Logger.Error("Failed to %s %s, because we expected %d from S3 and got '%s' instead", method, url, expected, rsp.Status)
		return nil, errors.New(rsp.Status)
	}

	return rsp, err
}

func (c *WOFClone) Status() {
	c.Logger.Info("scheduled: %d completed: %d success: %d error: %d goroutines: %d", c.Scheduled, c.Completed, c.Success, c.Error, runtime.NumGoroutine())
}
<commit_msg>notes to self<commit_after>package clone

import (
	"crypto/md5"
	"encoding/hex"
	"errors"
	"github.com/jeffail/tunny"
	csv "github.com/whosonfirst/go-whosonfirst-csv"
	log "github.com/whosonfirst/go-whosonfirst-log"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"sync/atomic"
)

type WOFClone struct {
	Source    string
	Dest      string
	Count     int64
	Success   int64
	Error     int64
	Skipped   int64
	Scheduled int64
	Completed int64
	Logger    *log.WOFLogger
	client    *http.Client
	pool      *tunny.WorkPool
}

func NewWOFClone(source string, dest string, procs int, logger *log.WOFLogger) *WOFClone {

	// cd := &sync.Cond{L: &sync.Mutex{}}

	cl := &http.Client{}

	runtime.GOMAXPROCS(procs)

	pool, _ := tunny.CreatePoolGeneric(procs).Open()

	c := WOFClone{
		Count:   0,
		Success: 0,
		Error:   0,
		Skipped: 0,
		Source:  source,
		Dest:    dest,
		Logger:  logger,
		client:  cl,
		pool:    pool,
	}

	return &c
}

func (c *WOFClone) CloneMetaFile(file string) error {

	abs_path, _ := filepath.Abs(file)
	// c.Logger.Debug("Parse meta file %s", abs_path)

	reader, read_err := csv.NewDictReader(abs_path)

	if read_err != nil {
		c.Logger.Error("Failed to read %s, because %v", abs_path, read_err)
		return read_err
	}

	wg := new(sync.WaitGroup)

	for {
		row, err := reader.Read()

		if err == io.EOF {
			break
		}

		if err != nil {
			return err
		}

		rel_path, ok := row["path"]

		if !ok {
			continue
		}

		// this does not account for counts - need to think about who calls what, when
		// probably needs to moved in to ClonePath... (20151105/thisisaaronland)

		ensure_changes := true
		skip_existing := false

		remote := c.Source + rel_path
		local := path.Join(c.Dest, rel_path)

		if !os.IsNotExist(err) {

			if skip_existing {
				c.Logger.Debug("%s already exists and we are skipping things that exist", local)
				continue
			}

			change, _ := c.HasChanged(local, remote)

			if !change {
				c.Logger.Info("no changes to %s", local)
				continue
			}
		}

		wg.Add(1)
		atomic.AddInt64(&c.Scheduled, 1)

		go func() {

			defer wg.Done()

			_, err = c.pool.SendWork(func() {

				cl_err := c.ClonePath(rel_path, ensure_changes)

				if cl_err != nil {
					atomic.AddInt64(&c.Error, 1)
				} else {
					atomic.AddInt64(&c.Success, 1)
				}

				atomic.AddInt64(&c.Completed, 1)
				c.Status()
			})

		}()
	}

	wg.Wait()
	return nil
}

func (c *WOFClone) ClonePath(rel_path string, ensure_changes bool) error {

	atomic.AddInt64(&c.Count, 1)

	remote := c.Source + rel_path
	local := path.Join(c.Dest, rel_path)

	_, err := os.Stat(local)

	if !os.IsNotExist(err) && ensure_changes {

		change, _ := c.HasChanged(local, remote)

		if !change {

			c.Logger.Debug("%s has not changed so skipping", local)
			atomic.AddInt64(&c.Skipped, 1)
			return nil
		}

	}

	process_err := c.Process(remote, local)

	if process_err != nil {
		atomic.AddInt64(&c.Error, 1)
		return process_err
	}

	return nil
}

// don't return true if there's a problem - move that logic up above

func (c *WOFClone) HasChanged(local string, remote string) (bool, error) {

	change := true

	body, err := ioutil.ReadFile(local)

	if err != nil {
		c.Logger.Error("Failed to read %s, becase %v", local, err)
		return change, err
	}

	hash := md5.Sum(body)
	local_hash := hex.EncodeToString(hash[:])

	return c.HasHashChanged(local_hash, remote)
}

func (c *WOFClone) HasHashChanged(local_hash string, remote string) (bool, error) {

	change := true

	rsp, err := c.Fetch("HEAD", remote)

	if err != nil {
		return change, err
	}

	defer rsp.Body.Close()

	etag := rsp.Header.Get("Etag")
	remote_hash := strings.Replace(etag, "\"", "", -1)

	if local_hash == remote_hash {
		change = false
	}

	return change, nil
}

func (c *WOFClone) Process(remote string, local string) error {

	c.Logger.Debug("fetch %s and store in %s", remote, local)

	local_root := path.Dir(local)

	_, err := os.Stat(local_root)

	if os.IsNotExist(err) {
		c.Logger.Info("create %s", local_root)
		os.MkdirAll(local_root, 0755)
	}

	rsp, fetch_err := c.Fetch("GET", remote)

	if fetch_err != nil {
		return fetch_err
	}

	defer rsp.Body.Close()

	contents, read_err := ioutil.ReadAll(rsp.Body)

	if read_err != nil {
		c.Logger.Error("failed to read body for %s, because %v", remote, read_err)
		return read_err
	}

	go func() error {

		write_err := ioutil.WriteFile(local, contents, 0644)

		if write_err != nil {
			c.Logger.Error("Failed to write %s, because %v", local, write_err)

			atomic.AddInt64(&c.Success, -1)
			atomic.AddInt64(&c.Error, 1)

			return write_err
		}

		c.Logger.Debug("Wrote %s to disk", local)
		return nil
	}()

	return nil
}

func (c *WOFClone) Fetch(method string, url string) (*http.Response, error) {

	c.Logger.Debug("%s %s", method, url)

	req, _ := http.NewRequest(method, url, nil)
	req.Close = true

	rsp, err := c.client.Do(req)

	if err != nil {
		c.Logger.Error("Failed to %s %s, because %v", method, url, err)
		// golog.Fatal(err)
		return nil, err
	}

	// See also: https://github.com/whosonfirst/go-whosonfirst-clone/issues/6

	expected := 200

	if rsp.StatusCode != expected {
		c.Logger.Error("Failed to %s %s, because we expected %d from S3 and got '%s' instead", method, url, expected, rsp.Status)
		return nil, errors.New(rsp.Status)
	}

	return rsp, err
}

func (c *WOFClone) Status() {
	c.Logger.Info("scheduled: %d completed: %d success: %d error: %d goroutines: %d", c.Scheduled, c.Completed, c.Success, c.Error, runtime.NumGoroutine())
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/elazarl/goproxy"
	"github.com/xlvector/cproxy"
	"github.com/xlvector/cproxy/manager"
	"log"
	"net/http"
	"time"
)

func main() {
	proxyPort := flag.String("proxyPort", "7182", "port of cproxy")
	managePort := flag.String("managePort", "7183", "manage port")
	managerHost := flag.String("managerHost", "", "manager host")
	host := flag.String("host", "", "host of current machine")
	flag.Parse()
	proxy := goproxy.NewProxyHttpServer()
	proxy.Verbose = true
	proxy.OnRequest().Do(&cproxy.RequestHandler{})
	proxy.OnResponse().Do(&cproxy.RespHandler{})

	if len(*managerHost) == 0 {
		http.HandleFunc("/register", manager.HandleRegister)
		http.HandleFunc("/heartbeat", manager.HandleHeartBeat)
		http.HandleFunc("/select", manager.HandleSelect)
		http.HandleFunc("/check", manager.HandleCheck)
		s := &http.Server{
			Addr:           ":" + *managePort,
			ReadTimeout:    30 * time.Second,
			WriteTimeout:   40 * time.Second,
			MaxHeaderBytes: 1 << 20,
		}
		go s.ListenAndServe()
	} else {
		c := http.Client{}
		time.Sleep(time.Minute)
		c.Get(*managerHost + "/register?proxy=" + *host)
	}
	log.Fatal(http.ListenAndServe(":"+*proxyPort, proxy))
}
<commit_msg>regular check in manager<commit_after>package main

import (
	"flag"
	"github.com/elazarl/goproxy"
	"github.com/xlvector/cproxy"
	"github.com/xlvector/cproxy/manager"
	"log"
	"net/http"
	"time"
)

func main() {
	proxyPort := flag.String("proxyPort", "7182", "port of cproxy")
	managePort := flag.String("managePort", "7183", "manage port")
	managerHost := flag.String("managerHost", "", "manager host")
	host := flag.String("host", "", "host of current machine")
	flag.Parse()
	proxy := goproxy.NewProxyHttpServer()
	proxy.Verbose = true
	proxy.OnRequest().Do(&cproxy.RequestHandler{})
	proxy.OnResponse().Do(&cproxy.RespHandler{})

	if len(*managerHost) == 0 {
		http.HandleFunc("/register", manager.HandleRegister)
		http.HandleFunc("/select", manager.HandleSelect)
		http.HandleFunc("/check", manager.HandleCheck)
		s := &http.Server{
			Addr:           ":" + *managePort,
			ReadTimeout:    30 * time.Second,
			WriteTimeout:   40 * time.Second,
			MaxHeaderBytes: 1 << 20,
		}
		go s.ListenAndServe()
	} else {
		c := http.Client{}
		time.Sleep(time.Minute)
		c.Get(*managerHost + "/register?proxy=" + *host)
	}
	log.Fatal(http.ListenAndServe(":"+*proxyPort, proxy))
}
<|endoftext|>


<commit_before>package golangNeo4jBoltDriver

import (
	"os"
	"testing"

	"time"

	"github.com/johnnadratowski/golang-neo4j-bolt-driver/log"
	"sync"
)

var (
	neo4jConnStr = ""
)

func TestMain(m *testing.M) {
	log.SetLevel(os.Getenv("BOLT_DRIVER_LOG"))

	neo4jConnStr = os.Getenv("NEO4J_BOLT")
	if neo4jConnStr != "" {
		log.Info("Using NEO4J for tests:", neo4jConnStr)
	} else if os.Getenv("ENSURE_NEO4J_BOLT") != "" {
		log.Fatal("Must give NEO4J_BOLT environment variable")
	}

	output := m.Run()

	if neo4jConnStr != "" {
		// If we're using a DB for testing neo, clear it out after all the test runs
		clearNeo()
	}

	os.Exit(output)
}

func clearNeo() {
	driver := NewDriver()
	conn, err := driver.OpenNeo(neo4jConnStr)
	if err != nil {
		panic("Error getting conn to clear DB")
	}

	stmt, err := conn.PrepareNeo(`MATCH (n) DETACH DELETE n`)
	if err != nil {
		panic("Error getting stmt to clear DB")
	}
	defer stmt.Close()

	_, err = stmt.ExecNeo(nil)
	if err != nil {
		panic("Error running query to clear DB")
	}
}

func TestBoltDriverPool_OpenNeo(t *testing.T) {
	if neo4jConnStr == "" {
		t.Skip("Cannot run this test when in recording mode")
	}

	pool, err := NewDriverPool(neo4jConnStr, 25)
	if err != nil {
		t.Fatalf("An error occurred opening driver pool: %#v", err)
	}

	now := time.Now().Unix()
	for i := 0; i < 25; i++ {
		go func() {
			c, err := pool.OpenPool()
			if err != nil {
				t.Fatalf("An error occurred opening conn from pool: %#v", err)
			}
			defer c.Close()
			time.Sleep(time.Millisecond * time.Duration(200))
		}()
	}

	c, err := pool.OpenPool()
	if !(time.Now().Unix()-now < 200) {
		t.Fatalf("An error occurred opening conn from pool at end: %#v", err)
	}
	defer c.Close()
}

func TestBoltDriverPool_Concurrent(t *testing.T) {
	if neo4jConnStr == "" {
		t.Skip("Cannot run this test when in recording mode")
	}

	var wg sync.WaitGroup
	wg.Add(2)
	driver, err := NewDriverPool(neo4jConnStr, 2)
	if err != nil {
		t.Fatalf("An error occurred opening driver pool: %#v", err)
	}

	one := make(chan bool)
	two := make(chan bool)
	three := make(chan bool)
	four := make(chan bool)
	five := make(chan bool)
	six := make(chan bool)
	seven := make(chan bool)
	go func() {
		defer wg.Done()

		conn, err := driver.OpenPool()
		if err != nil {
			t.Fatalf("An error occurred opening conn: %s", err)
		}
		defer conn.Close()

		data, _, _, err := conn.QueryNeoAll(`MATCH (n) RETURN n`, nil)
		if err != nil {
			t.Fatalf("An error occurred querying neo: %s", err)
		}

		log.Info("1")
		one <- true
		<-two

		if len(data) != 0 {
			t.Fatalf("Expected no data: %#v", data)
		}

		data, _, _, err = conn.QueryNeoAll(`MATCH (n) RETURN n`, nil)
		if err != nil {
			t.Fatalf("An error occurred querying neo: %s", err)
		}

		log.Infof("data: %#v", data)
		if len(data) != 1 {
			t.Fatalf("Expected no data: %#v", data)
		}

		log.Info("3")
		three <- true
		<-four

		data, _, _, err = conn.QueryNeoAll(`MATCH path=(:FOO)-[:BAR]->(:BAZ) RETURN path`, nil)
		if err != nil {
			t.Fatalf("An error occurred querying neo: %s", err)
		}

		if len(data) != 1 {
			t.Fatalf("Expected no data: %#v", data)
		}

		log.Info("5")
		five <- true
		<-six

		data, _, _, err = conn.QueryNeoAll(`MATCH path=(:FOO)-[:BAR]->(:BAZ) RETURN path`, nil)
		if err != nil {
			t.Fatalf("An error occurred querying neo: %s", err)
		}

		if len(data) != 0 {
			t.Fatalf("Expected no data: %#v", data)
		}

		log.Info("7")
		seven <- true
	}()

	go func() {
		<-one
		defer wg.Done()

		conn, err := driver.OpenPool()
		if err != nil {
			t.Fatalf("An error occurred opening conn: %s", err)
		}
		defer conn.Close()

		_, err = conn.ExecNeo(`CREATE (f:FOO)`, nil)
		if err != nil {
			t.Fatalf("An error occurred creating f neo: %s", err)
		}

		log.Info("2")
		two <- true
		<-three

		_, err = conn.ExecNeo(`MATCH (f:FOO) CREATE UNIQUE (f)-[b:BAR]->(c:BAZ)`, nil)
		if err != nil {
			t.Fatalf("An error occurred creating f neo: %s", err)
		}

		log.Info("4")
		four <- true
		<-five

		_, err = conn.ExecNeo(`MATCH (:FOO)-[b:BAR]->(:BAZ) DELETE b`, nil)
		if err != nil {
			t.Fatalf("An error occurred creating f neo: %s", err)
		}

		_, err = conn.ExecNeo(`MATCH (n) DETACH DELETE n`, nil)
		if err != nil {
			t.Fatalf("An error occurred creating f neo: %s", err)
		}

		log.Info("6")
		six <- true
		<-seven

	}()

	wg.Wait()
}
<commit_msg>Updated README. Fixed broken test<commit_after>package golangNeo4jBoltDriver

import (
	"os"
	"testing"

	"time"

	"github.com/johnnadratowski/golang-neo4j-bolt-driver/log"
	"sync"
)

var (
	neo4jConnStr = ""
)

func TestMain(m *testing.M) {
	log.SetLevel(os.Getenv("BOLT_DRIVER_LOG"))

	neo4jConnStr = os.Getenv("NEO4J_BOLT")
	if neo4jConnStr != "" {
		log.Info("Using NEO4J for tests:", neo4jConnStr)
	} else if os.Getenv("ENSURE_NEO4J_BOLT") != "" {
		log.Fatal("Must give NEO4J_BOLT environment variable")
	}

	output := m.Run()

	if neo4jConnStr != "" {
		// If we're using a DB for testing neo, clear it out after all the test runs
		clearNeo()
	}

	os.Exit(output)
}

func clearNeo() {
	driver := NewDriver()
	conn, err := driver.OpenNeo(neo4jConnStr)
	if err != nil {
		panic("Error getting conn to clear DB")
	}

	stmt, err := conn.PrepareNeo(`MATCH (n) DETACH DELETE n`)
	if err != nil {
		panic("Error getting stmt to clear DB")
	}
	defer stmt.Close()

	_, err = stmt.ExecNeo(nil)
	if err != nil {
		panic("Error running query to clear DB")
	}
}

func TestBoltDriverPool_OpenNeo(t *testing.T) {
	if neo4jConnStr == "" {
		t.Skip("Cannot run this test when in recording mode")
	}

	pool, err := NewDriverPool(neo4jConnStr, 25)
	if err != nil {
		t.Fatalf("An error occurred opening driver pool: %#v", err)
	}

	now := time.Now().Unix()
	for i := 0; i < 25; i++ {
		go func() {
			c, err := pool.OpenPool()
			if err != nil {
				t.Fatalf("An error occurred opening conn from pool: %#v", err)
			}
			defer c.Close()
			time.Sleep(time.Millisecond * time.Duration(200))
		}()
	}

	c, err := pool.OpenPool()
	if !(time.Now().Unix()-now < 200) {
		t.Fatalf("An error occurred opening conn from pool at end: %#v", err)
	}
	defer c.Close()
}

func TestBoltDriverPool_Concurrent(t *testing.T) {
	if neo4jConnStr == "" {
		t.Skip("Cannot run this test when in recording mode")
	}

	var wg sync.WaitGroup
	wg.Add(2)
	driver, err := NewDriverPool(neo4jConnStr, 2)
	if err != nil {
		t.Fatalf("An error occurred opening driver pool: %#v", err)
	}

	one := make(chan bool)
	two := make(chan bool)
	three := make(chan bool)
	four := make(chan bool)
	five := make(chan bool)
	six := make(chan bool)
	seven := make(chan bool)
	go func() {
		defer wg.Done()

		conn, err := driver.OpenPool()
		if err != nil {
			t.Fatalf("An error occurred opening conn: %s", err)
		}
		defer conn.Close()

		data, _, _, err := conn.QueryNeoAll(`MATCH (n) RETURN n`, nil)
		if err != nil {
			t.Fatalf("An error occurred querying neo: %s", err)
		}

		log.Info("1")
		one <- true
		<-two

		if len(data) != 0 {
			t.Fatalf("Expected no data: %#v", data)
		}

		data, _, _, err = conn.QueryNeoAll(`MATCH (n) RETURN n`, nil)
		if err != nil {
			t.Fatalf("An error occurred querying neo: %s", err)
		}

		log.Infof("data: %#v", data)
		if len(data) != 1 {
			t.Fatalf("Expected no data: %#v", data)
		}

		log.Info("3")
		three <- true
		<-four

		data, _, _, err = conn.QueryNeoAll(`MATCH path=(:FOO)-[:BAR]->(:BAZ) RETURN path`, nil)
		if err != nil {
			t.Fatalf("An error occurred querying neo: %s", err)
		}

		if len(data) != 1 {
			t.Fatalf("Expected no data: %#v", data)
		}

		log.Info("5")
		five <- true
		<-six

		data, _, _, err = conn.QueryNeoAll(`MATCH path=(:FOO)-[:BAR]->(:BAZ) RETURN path`, nil)
		if err != nil {
			t.Fatalf("An error occurred querying neo: %s", err)
		}

		if len(data) != 0 {
			t.Fatalf("Expected no data: %#v", data)
		}

		log.Info("7")
		seven <- true
	}()

	go func() {
		<-one
		defer wg.Done()

		conn, err := driver.OpenPool()
		if err != nil {
			t.Fatalf("An error occurred opening conn: %s", err)
		}
		defer conn.Close()

		_, err = conn.ExecNeo(`CREATE (f:FOO)`, nil)
		if err != nil {
			t.Fatalf("An error occurred creating f neo: %s", err)
		}

		log.Info("2")
		two <- true
		<-three

		_, err = conn.ExecNeo(`MATCH (f:FOO) CREATE UNIQUE (f)-[b:BAR]->(c:BAZ)`, nil)
		if err != nil {
			t.Fatalf("An error occurred creating f neo: %s", err)
		}

		log.Info("4")
		four <- true
		<-five

		_, err = conn.ExecNeo(`MATCH (:FOO)-[b:BAR]->(:BAZ) DELETE b`, nil)
		if err != nil {
			t.Fatalf("An error occurred creating f neo: %s", err)
		}

		_, err = conn.ExecNeo(`MATCH (n) DETACH DELETE n`, nil)
		if err != nil {
			t.Fatalf("An error occurred creating f neo: %s", err)
		}

		log.Info("6")
		six <- true
		<-seven

	}()

	wg.Wait()
}
<|endoftext|>


<commit_before>package drone

import (
	"errors"
	"fmt"
)

type RepoService struct {
	*Client
}

// GET /api/repos/{host}/{owner}/{name}
func (s *RepoService) Get(host, owner, name string) (*Repo, error) {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	var repo = Repo{}
	var err = s.run("GET", path, nil, &repo)
	if err == nil {
		return &repo, nil
	} else {
		return nil, err
	}
}

// POST /api/repos/{owner}/{name}
func (s *RepoService) Create(owner, name string) (*Repo, error) {
	if !s.isServer04 {
		return nil, errors.New("No create repos method before Drone 0.4")
	}
	path := fmt.Sprintf("/api/repos/%s/%s?activate=false", owner, name)
	var result = Repo{}
	var err = s.run("POST", path, nil, &result)
	if err == nil {
		return &result, nil
	} else {
		return nil, err
	}
}

// PUT /api/repos/{host}/{owner}/{name}
func (s *RepoService) Update(repo *Repo) (*Repo, error) {
	var path, method string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", repo.Owner, repo.Name)
		method = "PATCH"
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", repo.Host, repo.Owner, repo.Name)
		method = "PUT"
	}
	var result = Repo{}
	var err = s.run(method, path, &repo, &result)
	return &result, err
}

// POST /api/repos/{host}/{owner}/{name}
func (s *RepoService) Enable(host, owner, name string) (*Repo, error) {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	var result = Repo{}
	var err error
	err = s.run("POST", path, nil, &result)
	if err != nil {
		return nil, err
	} else {
		return &result, nil
	}
}

func (s *RepoService) EnableWithActivate(host, owner, name string, activate bool) (*Repo, error) {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s?activate=%v", owner, name, activate)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	var result = Repo{}
	var err error
	err = s.run("POST", path, nil, &result)
	if err != nil {
		return nil, err
	} else {
		return &result, err
	}
}

// POST /api/repos/{host}/{owner}/{name}/deactivate
func (s *RepoService) Disable(host, owner, name string) error {
	var path string
	if s.isServer04 {
		return errors.New("No disable function in Drone 0.4")
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s/deactivate", host, owner, name)
	}
	return s.run("POST", path, nil, nil)
}

// DELETE /api/repos/{host}/{owner}/{name}?remove=true
func (s *RepoService) Delete(host, owner, name string) error {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	return s.run("DELETE", path, nil, nil)
}

// PUT /api/repos/{host}/{owner}/{name}
func (s *RepoService) SetKey(host, owner, name, pub, priv string) error {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	var in = struct {
		PublicKey  string `json:"public_key"`
		PrivateKey string `json:"private_key"`
	}{pub, priv}
	return s.run("PUT", path, &in, nil)
}

// PUT /api/repos/{host}/{owner}/{name}
func (s *RepoService) SetParams(host, owner, name, params interface{}) error {
	var path, method string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
		method = "PATCH"
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
		method = "PUT"
	}
	var in = struct {
		Params interface{} `json:"params"`
	}{params}
	return s.run(method, path, &in, nil)
}

// GET /api/user/repos
func (s *RepoService) List() ([]*Repo, error) {
	var repos []*Repo
	var err = s.run("GET", "/api/user/repos", nil, &repos)
	return repos, err
}
<commit_msg>Skip Enable Repo for drone 0.4<commit_after>package drone

import (
	"errors"
	"fmt"
)

type RepoService struct {
	*Client
}

// GET /api/repos/{host}/{owner}/{name}
func (s *RepoService) Get(host, owner, name string) (*Repo, error) {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	var repo = Repo{}
	var err = s.run("GET", path, nil, &repo)
	if err == nil {
		return &repo, nil
	} else {
		return nil, err
	}
}

// POST /api/repos/{owner}/{name}
func (s *RepoService) Create(owner, name string) (*Repo, error) {
	if !s.isServer04 {
		return nil, errors.New("No create repos method before Drone 0.4")
	}
	path := fmt.Sprintf("/api/repos/%s/%s?activate=false", owner, name)
	var result = Repo{}
	var err = s.run("POST", path, nil, &result)
	if err == nil {
		return &result, nil
	} else {
		return nil, err
	}
}

// PUT /api/repos/{host}/{owner}/{name}
func (s *RepoService) Update(repo *Repo) (*Repo, error) {
	var path, method string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", repo.Owner, repo.Name)
		method = "PATCH"
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", repo.Host, repo.Owner, repo.Name)
		method = "PUT"
	}
	var result = Repo{}
	var err = s.run(method, path, &repo, &result)
	return &result, err
}

// POST /api/repos/{host}/{owner}/{name}
func (s *RepoService) Enable(host, owner, name string) (*Repo, error) {
	if s.isServer04 {
		return nil, nil
	}
	path := fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	var result = Repo{}
	var err error
	err = s.run("POST", path, nil, &result)
	if err != nil {
		return nil, err
	} else {
		return &result, nil
	}
}

func (s *RepoService) EnableWithActivate(host, owner, name string, activate bool) (*Repo, error) {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s?activate=%v", owner, name, activate)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	var result = Repo{}
	var err error
	err = s.run("POST", path, nil, &result)
	if err != nil {
		return nil, err
	} else {
		return &result, err
	}
}

// POST /api/repos/{host}/{owner}/{name}/deactivate
func (s *RepoService) Disable(host, owner, name string) error {
	var path string
	if s.isServer04 {
		return errors.New("No disable function in Drone 0.4")
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s/deactivate", host, owner, name)
	}
	return s.run("POST", path, nil, nil)
}

// DELETE /api/repos/{host}/{owner}/{name}?remove=true
func (s *RepoService) Delete(host, owner, name string) error {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	return s.run("DELETE", path, nil, nil)
}

// PUT /api/repos/{host}/{owner}/{name}
func (s *RepoService) SetKey(host, owner, name, pub, priv string) error {
	var path string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
	}
	var in = struct {
		PublicKey  string `json:"public_key"`
		PrivateKey string `json:"private_key"`
	}{pub, priv}
	return s.run("PUT", path, &in, nil)
}

// PUT /api/repos/{host}/{owner}/{name}
func (s *RepoService) SetParams(host, owner, name, params interface{}) error {
	var path, method string
	if s.isServer04 {
		path = fmt.Sprintf("/api/repos/%s/%s", owner, name)
		method = "PATCH"
	} else {
		path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)
		method = "PUT"
	}
	var in = struct {
		Params interface{} `json:"params"`
	}{params}
	return s.run(method, path, &in, nil)
}

// GET /api/user/repos
func (s *RepoService) List() ([]*Repo, error) {
	var repos []*Repo
	var err = s.run("GET", "/api/user/repos", nil, &repos)
	return repos, err
}
<|endoftext|>