<commit_before>package main

import (
	"fmt"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sqs"
)

func getQueue(sqsInstance *sqs.SQS, queueName string) (*string, error) {
	queueURLOutput, err := sqsInstance.GetQueueURL(&sqs.GetQueueURLInput{QueueName: &queueName})

	if err != nil {
		return nil, err
	}

	return queueURLOutput.QueueURL, nil
}

func createQueue(sqsInstance *sqs.SQS, queueName string) (*string, error) {
	createQueueOutput, err := sqsInstance.CreateQueue(&sqs.CreateQueueInput{QueueName: &queueName})

	if err != nil {
		return nil, err
	}

	return createQueueOutput.QueueURL, nil
}

func makeReceiveMessageInput(queueURL *string) *sqs.ReceiveMessageInput {
	var maxNumberOfMessages int64 = 1
	allString := "All"
	allArray := []*string{&allString}
	var visibilityTimeout int64 = 0
	var waitTimeSeconds int64 = 20
	return &sqs.ReceiveMessageInput{
		AttributeNames:        allArray,
		MaxNumberOfMessages:   &maxNumberOfMessages,
		MessageAttributeNames: allArray,
		QueueURL:              queueURL,
		VisibilityTimeout:     &visibilityTimeout,
		WaitTimeSeconds:       &waitTimeSeconds,
	}
}

func sendMessage(sqsInstance *sqs.SQS, queueURL *string, message string) error {
	_, err := sqsInstance.SendMessage(&sqs.SendMessageInput{
		QueueURL:    queueURL,
		MessageBody: &message,
	})
	return err
}

func printMessage(message *sqs.Message) {
	fmt.Println("attributes:")
	for k, v := range message.Attributes {
		fmt.Println(k, *v)
	}

	fmt.Println("body:")
	fmt.Println(*message.Body)

	fmt.Println("message attributes:")
	for k, _ := range message.MessageAttributes {
		fmt.Println(k)
	}

	if message.MessageID != nil {
		fmt.Println("message id:", *message.MessageID)
	} else {
		fmt.Println("message id: nil")
	}

	if message.ReceiptHandle != nil {
		fmt.Println("receipt handle:", *message.ReceiptHandle)
	} else {
		fmt.Println("receipt handle: nil")
	}
}

func main() {
	sqsInstance := sqs.New(&aws.Config{Region: "us-east-1"})

	queueURL, err := getQueue(sqsInstance, "domen-test-sqs")
	if err != nil {
		fmt.Println("GetQueue:", err)
		return
	}

	fmt.Println("QueueURL:", *queueURL)

	// send message after 10s
	go func() {
		time.Sleep(10 * time.Second)
		err := sendMessage(sqsInstance, queueURL, "test message")
		if err != nil {
			fmt.Println("SendMessage:", err)
		}
	}()

	// receive loop
	receiveMessageInput := makeReceiveMessageInput(queueURL)
	for {
		receiveMessageOutput, err := sqsInstance.ReceiveMessage(receiveMessageInput)
		if err != nil {
			fmt.Println("ReceiveMessage:", err)
			return
		}

		if len(receiveMessageOutput.Messages) < 1 {
			fmt.Println("no messages received")
			continue
		}

		message := receiveMessageOutput.Messages[0]
		fmt.Println("New message:")
		printMessage(message)
	}
}
<commit_msg>Added delete message.<commit_after>package main

import (
	"fmt"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sqs"
)

func getQueue(sqsInstance *sqs.SQS, queueName string) (*string, error) {
	queueURLOutput, err := sqsInstance.GetQueueURL(&sqs.GetQueueURLInput{QueueName: &queueName})

	if err != nil {
		return nil, err
	}

	return queueURLOutput.QueueURL, nil
}

func createQueue(sqsInstance *sqs.SQS, queueName string) (*string, error) {
	createQueueOutput, err := sqsInstance.CreateQueue(&sqs.CreateQueueInput{QueueName: &queueName})

	if err != nil {
		return nil, err
	}

	return createQueueOutput.QueueURL, nil
}

func makeReceiveMessageInput(queueURL *string) *sqs.ReceiveMessageInput {
	var maxNumberOfMessages int64 = 1
	allString := "All"
	allArray := []*string{&allString}
	var visibilityTimeout int64 = 0
	var waitTimeSeconds int64 = 20
	return &sqs.ReceiveMessageInput{
		AttributeNames:        allArray,
		MaxNumberOfMessages:   &maxNumberOfMessages,
		MessageAttributeNames: allArray,
		QueueURL:              queueURL,
		VisibilityTimeout:     &visibilityTimeout,
		WaitTimeSeconds:       &waitTimeSeconds,
	}
}

func sendMessage(sqsInstance *sqs.SQS, queueURL *string, message string) error {
	_, err := sqsInstance.SendMessage(&sqs.SendMessageInput{
		QueueURL:    queueURL,
		MessageBody: &message,
	})
	return err
}

func printMessage(message *sqs.Message) {
	fmt.Println("attributes:")
	for k, v := range message.Attributes {
		fmt.Println(k, *v)
	}

	fmt.Println("body:")
	fmt.Println(*message.Body)

	fmt.Println("message attributes:")
	for k, _ := range message.MessageAttributes {
		fmt.Println(k)
	}

	if message.MessageID != nil {
		fmt.Println("message id:", *message.MessageID)
	} else {
		fmt.Println("message id: nil")
	}

	if message.ReceiptHandle != nil {
		fmt.Println("receipt handle:", *message.ReceiptHandle)
	} else {
		fmt.Println("receipt handle: nil")
	}
}

func main() {
	sqsInstance := sqs.New(&aws.Config{Region: "us-east-1"})

	queueURL, err := getQueue(sqsInstance, "domen-test-sqs")
	if err != nil {
		fmt.Println("GetQueue:", err)
		return
	}

	fmt.Println("QueueURL:", *queueURL)

	// send message after 10s
	go func() {
		time.Sleep(10 * time.Second)
		err := sendMessage(sqsInstance, queueURL, "test message")
		if err != nil {
			fmt.Println("SendMessage:", err)
		}
	}()

	// receive loop
	receiveMessageInput := makeReceiveMessageInput(queueURL)
	for {
		receiveMessageOutput, err := sqsInstance.ReceiveMessage(receiveMessageInput)
		if err != nil {
			fmt.Println("ReceiveMessage:", err)
			return
		}

		if len(receiveMessageOutput.Messages) < 1 {
			fmt.Println("no messages received")
			continue
		}

		message := receiveMessageOutput.Messages[0]
		fmt.Println("New message:")
		printMessage(message)

		// delete received message
		_, err = sqsInstance.DeleteMessage(&sqs.DeleteMessageInput{
			QueueURL: queueURL,
			ReceiptHandle: message.ReceiptHandle,
		})
		if err != nil {
			fmt.Println("DeleteMessage:", err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
)

func shortUsage() {
	os.Stderr.WriteString(`
Usage: vub [OPTION]... URI
Try 'vub --help' for more information.
`[1:])
}

func usage() {
	os.Stderr.WriteString(`
Usage: vub [OPTION]... URI
Install Vim plugin to under the management of vim-unbundle.

URI:
  sunaku/vim-unbundle                    # short URI
  https://github.com/sunaku/vim-unbundle # full URI

Options:
  -f, --filetype=TYPE       installing under the ftbundle/TYPE
  -r, --remove              change the behavior to remove
  -u, --update              change the behavior to clean update
  -v, --verbose             display the process
  -h, --help                show this help message
`[1:])
}

func main() {
	filetype, removeMode, updateMode, verbose := "", false, false, false
	flag.StringVar(&filetype, "f", "", "")
	flag.StringVar(&filetype, "filetype", "", "")
	flag.BoolVar(&removeMode, "r", false, "")
	flag.BoolVar(&removeMode, "remove", false, "")
	flag.BoolVar(&updateMode, "u", false, "")
	flag.BoolVar(&updateMode, "update", false, "")
	flag.BoolVar(&verbose, "v", false, "")
	flag.BoolVar(&verbose, "verbose", false, "")

	isHelp := false
	flag.BoolVar(&isHelp, "h", false, "")
	flag.BoolVar(&isHelp, "help", false, "")
	flag.Usage = usage
	flag.Parse()
	switch {
	case isHelp:
		usage()
		os.Exit(0)
	case flag.NArg() < 1:
		shortUsage()
		os.Exit(2)
	case removeMode && updateMode:
		fmt.Fprintln(os.Stderr, "vub:", "cannot specify multiple mode")
		shortUsage()
		os.Exit(2)
	}
	uri := flag.Arg(0)

	p, err := NewPackage(uri, filetype)
	if err != nil {
		fmt.Fprintln(os.Stderr, "vub:", err)
		os.Exit(2)
	}
	p.Verbose(verbose)

	switch {
	case removeMode:
		if err := p.Remove(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	case updateMode:
		if err := p.Update(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	default:
		if err := p.Install(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	}
}
<commit_msg>Change way to write declear flags<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
)

func shortUsage() {
	os.Stderr.WriteString(`
Usage: vub [OPTION]... URI
Try 'vub --help' for more information.
`[1:])
}

func usage() {
	os.Stderr.WriteString(`
Usage: vub [OPTION]... URI
Install Vim plugin to under the management of vim-unbundle.

URI:
  sunaku/vim-unbundle                    # short URI
  https://github.com/sunaku/vim-unbundle # full URI

Options:
  -f, --filetype=TYPE       installing under the ftbundle/TYPE
  -r, --remove              change the behavior to remove
  -u, --update              change the behavior to clean update
  -v, --verbose             display the process
  -h, --help                show this help message
`[1:])
}

func main() {
	var filetype string
	flag.StringVar(&filetype, "f", "", "")
	flag.StringVar(&filetype, "filetype", "", "")

	var removeMode, updateMode bool
	flag.BoolVar(&removeMode, "r", false, "")
	flag.BoolVar(&removeMode, "remove", false, "")
	flag.BoolVar(&updateMode, "u", false, "")
	flag.BoolVar(&updateMode, "update", false, "")

	var verbose bool
	flag.BoolVar(&verbose, "v", false, "")
	flag.BoolVar(&verbose, "verbose", false, "")

	var isHelp bool
	flag.BoolVar(&isHelp, "h", false, "")
	flag.BoolVar(&isHelp, "help", false, "")
	flag.Usage = usage
	flag.Parse()
	switch {
	case isHelp:
		usage()
		os.Exit(0)
	case flag.NArg() < 1:
		shortUsage()
		os.Exit(2)
	case removeMode && updateMode:
		fmt.Fprintln(os.Stderr, "vub:", "cannot specify multiple mode")
		shortUsage()
		os.Exit(2)
	}
	uri := flag.Arg(0)

	p, err := NewPackage(uri, filetype)
	if err != nil {
		fmt.Fprintln(os.Stderr, "vub:", err)
		os.Exit(2)
	}
	p.Verbose(verbose)

	switch {
	case removeMode:
		if err := p.Remove(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	case updateMode:
		if err := p.Update(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	default:
		if err := p.Install(os.Stdout); err != nil {
			fmt.Fprintln(os.Stderr, "vub:", err)
			os.Exit(1)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
)

func parseArgs() (*Listener, *Connector, error) {
	var connectMode, listenMode bool
	modeArgs := flag.NewFlagSet("mode", flag.ExitOnError)

	modeArgs.BoolVar(&connectMode, "C", false, "connect mode")
	modeArgs.BoolVar(&listenMode, "L", false, "listen mode")

	connector := &Connector{}
	connectArgs := flag.NewFlagSet("connect", flag.ExitOnError)
	connectArgs.StringVar(&connector.src, "s", "", "the host and port of the local server")
	connectArgs.StringVar(&connector.dst, "c", "", "the host and port of the Listen/Listen server")
	connectArgs.IntVar(&connector.interval, "i", 5, "interval when (re)connecting to either host in seconds, must be positive")

	clientCert := TLSCert{}
	connectArgs.StringVar(&clientCert.ca, "ca", "", "certificate authority (used to signed the server cert) to encrypt the connection to the Listen/Listen server, connection will be unencrypted if not specified")
	connectArgs.StringVar(&clientCert.crt, "crt", "", "client certificate signed by the CA provided to the server")
	connectArgs.StringVar(&clientCert.key, "key", "", "client key file")

	listener := &Listener{}
	listenArgs := flag.NewFlagSet("listen", flag.ExitOnError)
	listenArgs.StringVar(&listener.from, "p", "", "the port to listen on for actual client connection")
	listenArgs.StringVar(&listener.to, "q", "", "the port to listen on for connection from the other Connect/Connect node")

	serverCert := TLSCert{}
	listenArgs.StringVar(&serverCert.ca, "ca", "", "certificate authority (used to sign the client cert) to encrypt the connection to the Connect/Connect client, connection will be unencrypted if not specified")
	listenArgs.StringVar(&serverCert.crt, "crt", "", "server certificate signed by the CA provided to the client")
	listenArgs.StringVar(&serverCert.key, "key", "", "server key file")

	flag.Usage = func() {
		modeArgs.PrintDefaults()
		fmt.Fprintf(os.Stderr, "For connect mode:\n")
		connectArgs.PrintDefaults()
		fmt.Fprintf(os.Stderr, "For listen mode:\n")
		listenArgs.PrintDefaults()

	}

	modeArgs.Parse(os.Args[1:2])
	if !connectMode && !listenMode {
		return nil, nil, fmt.Errorf("no options")
	}

	if listenMode {
		listenArgs.Parse(os.Args[2:])
		if listener.from == "" || listener.to == "" {
			return nil, nil, fmt.Errorf("no listen options")
		}
		var err error
		if listener.tlsConfig, err = serverCert.CreateServerConfig(); err != nil {
			return nil, nil, err
		}
		return listener, nil, nil
	} else if connectMode {
		connectArgs.Parse(os.Args[2:])
		if connector.src == "" || connector.dst == "" {
			return nil, nil, fmt.Errorf("no connect options")
		}
		if connector.interval <= 0 {
			return nil, nil, fmt.Errorf("delay must be a positive integer")
		}
		if clientCert.ca != "" {
			var err error
			if connector.tlsConfig, err = clientCert.CreateClientConfig(); err != nil {
				return nil, nil, err
			}
		}

		return nil, connector, nil
	}
	return nil, nil, fmt.Errorf("too many options")
}

func main() {
	listener, connector, err := parseArgs()
	if err != nil {
		fmt.Fprintf(os.Stderr, fmt.Sprintf("%v\n", err))
		flag.Usage()
		os.Exit(2)
	}
	if listener != nil {
		if err := listener.Listen(); err != nil {
			log.Fatalln(err)
		}
	} else if connector != nil {
		connector.Connect()
	}
}
<commit_msg>Check if CA is supplied as argument to listener<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
)

func parseArgs() (*Listener, *Connector, error) {
	var connectMode, listenMode bool
	modeArgs := flag.NewFlagSet("mode", flag.ExitOnError)

	modeArgs.BoolVar(&connectMode, "C", false, "connect mode")
	modeArgs.BoolVar(&listenMode, "L", false, "listen mode")

	connector := &Connector{}
	connectArgs := flag.NewFlagSet("connect", flag.ExitOnError)
	connectArgs.StringVar(&connector.src, "s", "", "the host and port of the local server")
	connectArgs.StringVar(&connector.dst, "c", "", "the host and port of the Listen/Listen server")
	connectArgs.IntVar(&connector.interval, "i", 5, "interval when (re)connecting to either host in seconds, must be positive")

	clientCert := TLSCert{}
	connectArgs.StringVar(&clientCert.ca, "ca", "", "certificate authority (used to signed the server cert) to encrypt the connection to the Listen/Listen server, connection will be unencrypted if not specified")
	connectArgs.StringVar(&clientCert.crt, "crt", "", "client certificate signed by the CA provided to the server")
	connectArgs.StringVar(&clientCert.key, "key", "", "client key file")

	listener := &Listener{}
	listenArgs := flag.NewFlagSet("listen", flag.ExitOnError)
	listenArgs.StringVar(&listener.from, "p", "", "the port to listen on for actual client connection")
	listenArgs.StringVar(&listener.to, "q", "", "the port to listen on for connection from the other Connect/Connect node")

	serverCert := TLSCert{}
	listenArgs.StringVar(&serverCert.ca, "ca", "", "certificate authority (used to sign the client cert) to encrypt the connection to the Connect/Connect client, connection will be unencrypted if not specified")
	listenArgs.StringVar(&serverCert.crt, "crt", "", "server certificate signed by the CA provided to the client")
	listenArgs.StringVar(&serverCert.key, "key", "", "server key file")

	flag.Usage = func() {
		modeArgs.PrintDefaults()
		fmt.Fprintf(os.Stderr, "For connect mode:\n")
		connectArgs.PrintDefaults()
		fmt.Fprintf(os.Stderr, "For listen mode:\n")
		listenArgs.PrintDefaults()

	}

	modeArgs.Parse(os.Args[1:2])
	if !connectMode && !listenMode {
		return nil, nil, fmt.Errorf("no options")
	}

	if listenMode {
		listenArgs.Parse(os.Args[2:])
		if listener.from == "" || listener.to == "" {
			return nil, nil, fmt.Errorf("no listen options")
		}
		var err error
		if serverCert.ca != "" {
			if listener.tlsConfig, err = serverCert.CreateServerConfig(); err != nil {
				return nil, nil, err
			}
		}
		return listener, nil, nil
	} else if connectMode {
		connectArgs.Parse(os.Args[2:])
		if connector.src == "" || connector.dst == "" {
			return nil, nil, fmt.Errorf("no connect options")
		}
		if connector.interval <= 0 {
			return nil, nil, fmt.Errorf("delay must be a positive integer")
		}
		if clientCert.ca != "" {
			var err error
			if connector.tlsConfig, err = clientCert.CreateClientConfig(); err != nil {
				return nil, nil, err
			}
		}

		return nil, connector, nil
	}
	return nil, nil, fmt.Errorf("too many options")
}

func main() {
	listener, connector, err := parseArgs()
	if err != nil {
		fmt.Fprintf(os.Stderr, fmt.Sprintf("%v\n", err))
		flag.Usage()
		os.Exit(2)
	}
	if listener != nil {
		if err := listener.Listen(); err != nil {
			log.Fatalln(err)
		}
	} else if connector != nil {
		connector.Connect()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"flag"
	"log"
	"log/syslog"
	"net/smtp"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/dghubble/go-twitter/twitter"
	"github.com/dghubble/oauth1"
	_ "github.com/go-sql-driver/mysql"
	"github.com/johansundell/cocapi"
)

var db *sql.DB
var mysqlUser, mysqlPass, mysqlDb, mysqlHost string
var queryInsertUpdateMember = `INSERT INTO members (tag, name, created, last_updated, active) VALUES (?, ?, null, null, 1) ON DUPLICATE KEY UPDATE member_id=LAST_INSERT_ID(member_id), last_updated = NOW(), active = 1`
var consumerKey, consumerSecret, accessToken, accessSecret string

func init() {

	mysqlDb = "cocsniffer"
	mysqlHost = os.Getenv("MYSQL_COC_HOST")
	mysqlUser = os.Getenv("MYSQL_USER")
	mysqlPass = os.Getenv("MYSQL_PASS")

	consumerKey = os.Getenv("TWITTER_CONSKEY")
	consumerSecret = os.Getenv("TWITTER_CONSSEC")
	accessToken = os.Getenv("TWITTER_ACCTOK")
	accessSecret = os.Getenv("TWITTER_ACCSEC")
}

func main() {
	useSyslog := flag.Bool("syslog", false, "Use syslog")
	flag.Parse()
	if *useSyslog {
		logwriter, e := syslog.New(syslog.LOG_NOTICE, "cocsniffer")
		if e == nil {
			log.SetOutput(logwriter)
		}
	}
	db, _ = sql.Open("mysql", mysqlUser+":"+mysqlPass+"@tcp("+mysqlHost+":3306)/"+mysqlDb)
	defer db.Close()

	getMembersData()
	ticker := time.NewTicker(1 * time.Minute)
	quit := make(chan struct{})
	go func() {
		for {
			select {
			case <-ticker.C:
				getMembersData()
			case <-quit:
				ticker.Stop()
				return
			}
		}
	}()

	config := oauth1.NewConfig(consumerKey, consumerSecret)
	token := oauth1.NewToken(accessToken, accessSecret)
	// OAuth1 http.Client will automatically authorize Requests
	httpClient := config.Client(oauth1.NoContext, token)

	// Twitter client
	client := twitter.NewClient(httpClient)

	// Convenience Demux demultiplexed stream messages
	demux := twitter.NewSwitchDemux()
	demux.Tweet = func(tweet *twitter.Tweet) {
		if tweet.User.ID == 730400376 || tweet.User.ID == 250293507 {
			log.Println("found one", tweet.Text)
			log.Println(tweet.User.ScreenName)
			if strings.Contains(strings.ToLower(tweet.Text), strings.ToLower("Maintenance")) {
				sendEmail("johan@pixpro.net", "johan@sundell.com", "COC alert", tweet.Text)
				log.Println("Email sent:", tweet.Text)
			}
		}

	}
	filterParams := &twitter.StreamFilterParams{
		Follow: []string{"730400376", "240359880", "250293507"},
		//Track:         []string{"Maintenance", "Maintenance.", "sudde"},
		StallWarnings: twitter.Bool(true),
	}
	var stream *twitter.Stream
	demux.DM = func(dm *twitter.DirectMessage) {
		//fmt.Println(dm.SenderID)
	}
	demux.Event = func(event *twitter.Event) {
		log.Printf("%#v\n", event)
	}
	demux.StreamDisconnect = func(d *twitter.StreamDisconnect) {
		log.Println("Lost connection")
		stream.Stop()
		stream, err := client.Streams.Filter(filterParams)
		if err != nil {
			log.Fatal(err)
		}

		// Receive messages until stopped or stream quits
		go demux.HandleChan(stream.Messages)
	}

	log.Println("Starting Stream...")

	// FILTER
	/*filterParams := &twitter.StreamFilterParams{
		Follow: []string{"730400376", "240359880", "250293507"},
		//Track:         []string{"Maintenance", "Maintenance.", "sudde"},
		StallWarnings: twitter.Bool(true),
	}*/

	stream, err := client.Streams.Filter(filterParams)
	if err != nil {
		log.Fatal(err)
	}

	// Receive messages until stopped or stream quits
	go demux.HandleChan(stream.Messages)

	// Wait for SIGINT and SIGTERM (HIT CTRL-C)
	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
	log.Println(<-ch)

	close(quit)
	stream.Stop()
	log.Println("Bye ;)")
}

func getMembersData() {
	members, err := cocapi.GetMemberInfo()
	if err != nil {
		reportError(err)
	}

	var ids = make([]string, 0)
	for _, m := range members.Items {
		if result, err := db.Exec(queryInsertUpdateMember, m.Tag, m.Name); err != nil {
			log.Println(err)
		} else {
			if id, err := result.LastInsertId(); err != nil {
				log.Println(err)
			} else {
				ids = append(ids, strconv.Itoa(int(id)))
			}
		}
	}
	db.Exec("UPDATE members SET active = 0 WHERE member_id NOT IN (" + strings.Join(ids, ", ") + ")")
	log.Println("done members func")
}

func reportError(err error) {
	log.Println("Fatal error coc:", err)
	//os.Exit(0)
}

func sendEmail(to, from, subject, message string) bool {
	body := "To: " + to + "\r\nSubject: " + subject + "\r\n\r\n" + message
	if err := smtp.SendMail("127.0.0.1:25", nil, from, []string{to}, []byte(body)); err != nil {
		log.Println(err)
		return false
	}
	return true
}
<commit_msg>Removed twitter support<commit_after>package main

import (
	"database/sql"
	"flag"
	"log"
	"log/syslog"
	"net/smtp"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/johansundell/cocapi"
)

var db *sql.DB
var mysqlUser, mysqlPass, mysqlDb, mysqlHost string
var queryInsertUpdateMember = `INSERT INTO members (tag, name, created, last_updated, active) VALUES (?, ?, null, null, 1) ON DUPLICATE KEY UPDATE member_id=LAST_INSERT_ID(member_id), last_updated = NOW(), active = 1`
var consumerKey, consumerSecret, accessToken, accessSecret string
var isCocUnderUpdate bool
var failedTries int

func init() {

	mysqlDb = "cocsniffer"
	mysqlHost = os.Getenv("MYSQL_COC_HOST")
	mysqlUser = os.Getenv("MYSQL_USER")
	mysqlPass = os.Getenv("MYSQL_PASS")

	consumerKey = os.Getenv("TWITTER_CONSKEY")
	consumerSecret = os.Getenv("TWITTER_CONSSEC")
	accessToken = os.Getenv("TWITTER_ACCTOK")
	accessSecret = os.Getenv("TWITTER_ACCSEC")
}

func main() {
	useSyslog := flag.Bool("syslog", false, "Use syslog")
	flag.Parse()
	if *useSyslog {
		logwriter, e := syslog.New(syslog.LOG_NOTICE, "cocsniffer")
		if e == nil {
			log.SetOutput(logwriter)
		}
	}
	db, _ = sql.Open("mysql", mysqlUser+":"+mysqlPass+"@tcp("+mysqlHost+":3306)/"+mysqlDb)
	defer db.Close()
	isCocUnderUpdate = false
	failedTries = 0
	getMembersData()
	ticker := time.NewTicker(1 * time.Minute)
	quit := make(chan struct{})
	go func() {
		for {
			select {
			case <-ticker.C:
				getMembersData()
			case <-quit:
				ticker.Stop()
				return
			}
		}
	}()

	// Wait for SIGINT and SIGTERM (HIT CTRL-C)
	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
	log.Println(<-ch)

	close(quit)
	log.Println("Bye ;)")
}

func getMembersData() {
	members, err := cocapi.GetMemberInfo()
	if err != nil {
		reportError(err)
		return
	}
	isCocUnderUpdate = false
	failedTries = 0

	var ids = make([]string, 0)
	for _, m := range members.Items {
		if result, err := db.Exec(queryInsertUpdateMember, m.Tag, m.Name); err != nil {
			log.Println(err)
		} else {
			if id, err := result.LastInsertId(); err != nil {
				log.Println(err)
			} else {
				ids = append(ids, strconv.Itoa(int(id)))
			}
		}
	}
	db.Exec("UPDATE members SET active = 0 WHERE member_id NOT IN (" + strings.Join(ids, ", ") + ")")
	log.Println("done members func")
}

func reportError(err error) {
	switch t := err.(type) {
	case *cocapi.ServerError:
		if t.ErrorCode == 503 {
			failedTries++
			if failedTries > 3 {
				if !isCocUnderUpdate {
					isCocUnderUpdate = true
					sendEmail("johan@sundell.com", "johan@pixpro.net", "COC Alert", "Servers under update")
				}
			}
		}
		break
	default:
		log.Println("Fatal error coc:", t)
		break
	}
	//log.Println("Fatal error coc:", err)
	//os.Exit(0)
}

func sendEmail(to, from, subject, message string) bool {
	body := "To: " + to + "\r\nSubject: " + subject + "\r\n\r\n" + message
	if err := smtp.SendMail("127.0.0.1:25", nil, from, []string{to}, []byte(body)); err != nil {
		log.Println(err)
		return false
	}
	return true
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log/syslog"
	"os"
	"sort"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
	flags "github.com/jessevdk/go-flags"
	"github.com/pkg/errors"
)

// This will automatically be overridden at build time if the provided
// Makefile is used.
var version = "unknown"

var log = logrus.New()

var opts struct {
	Mode           string        `short:"m" long:"mode" description:"Operating mode" default:"daemon" choice:"daemon" choice:"oneshot"`
	File           string        `short:"f" long:"file" description:"Input file in /etc/hosts format" default:"/etc/hosts" value-name:"HOSTFILE"`
	Networks       []CIDRNet     `long:"network" description:"Filter by CIDR network" value-name:"x.x.x.x/len"`
	Domain         string        `short:"d" long:"domain" description:"Domain to update records in"`
	Interval       time.Duration `short:"i" long:"interval" description:"Seconds between scheduled resync times." default:"15m"`
	TTL            int64         `long:"ttl" description:"TTL to use for Route 53 records" default:"3600"`
	NoQualifyHosts bool          `long:"no-qualify-hosts" description:"Don't force domain to be added to end of hosts"`
	NoWait         bool          `long:"no-wait" description:"Don't wait for Route 53 to finish update"`
	Syslog         bool          `long:"syslog" description:"Send logging to syslog in addition to stdout"`
	SyslogOnly     bool          `long:"syslog-only" description:"Send logging *only* to syslog"`
	Debug          bool          `long:"debug" description:"Enable debug logging"`
	Version        bool          `long:"version" description:"Print version number and exit"`
}

func parseOpts() {
	parser := flags.NewParser(&opts, flags.Default)

	if _, err := parser.Parse(); err != nil {
		if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp {
			os.Exit(0)
		} else {
			os.Exit(1)
		}
	}

	if opts.Version {
		fmt.Println("version: ", version)
		os.Exit(0)
	}

	if opts.Domain == "" {
		fmt.Fprintln(os.Stderr, "domain name must be specified (-d or --domain)")
		os.Exit(1)
	}

	if len(opts.Networks) == 0 {
		fmt.Fprintln(os.Stderr, "one or more networks must be provided (--network)")
		os.Exit(1)
	}

	// Accept trailing dot, but ignore it for consistency sake
	if strings.HasSuffix(opts.Domain, ".") {
		opts.Domain = opts.Domain[:len(opts.Domain)-1]
	}
}

func configureLogging() {
	if opts.SyslogOnly {
		log.Out = ioutil.Discard
	} else {
		// logrus defaults to stderr, but stdout is more conventional
		log.Out = os.Stdout
	}

	if opts.Debug {
		log.Level = logrus.DebugLevel
	}

	if opts.Syslog || opts.SyslogOnly {
		log.Info("Disabling color for syslog")
		tf := &logrus.TextFormatter{DisableColors: true}
		log.Formatter = tf

		hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_USER, "sync-hosts-to-route53")
		if err == nil {
			log.Hooks.Add(hook)
		} else {
			log.Fatal("Cannot initialize syslog: ", err)
		}
	}

}

func canonifyHostname(hostname string) string {
	hostname = strings.ToLower(hostname)
	// Accept trailing dot, but ignore it for consistency sake
	if strings.HasSuffix(hostname, ".") {
		hostname = hostname[:len(hostname)-1]
	}

	return hostname
}

// compareHosts takes the contents of the local /etc/hosts file and the
// Route 53 hosts that should be compared and produces two arrays.  The first
// array is a list of Route 53 records that need to be updated, and the second
// array is a list of Route 53 records that should be deleted.
func compareHosts(hosts hostList, r53hosts hostList) (hostList, hostList) {
	// Build index on name, we'll delete entries out of here a we match them
	// against /etc/hosts entries.  The remaining entries aren't present
	// locally anymore and will need to be deleted.
	rhByName := map[string]hostEntry{}
	for _, rh := range r53hosts {
		rhByName[rh.hostname] = rh
	}

	toUpdate := hostList{}
	// Find existing hosts
	for _, h := range hosts {
		rh, ok := rhByName[h.hostname]
		if ok {
			delete(rhByName, h.hostname)
			if !h.ip.Equal(rh.ip) {
				toUpdate = append(toUpdate, h)
			}
		} else {
			toUpdate = append(toUpdate, h)
		}
	}

	toDelete := make(hostList, 0, len(rhByName))
	for _, rh := range rhByName {
		toDelete = append(toDelete, rh)
	}

	return toUpdate, toDelete
}

func removeDupes(hosts hostList) hostList {
	found := make(map[string]bool, len(hosts))

	// Sort hostlist to ensure stable duplication suppression.  We don't want
	// to ping pont between choosing different options because of parse order.
	sort.Sort(hosts)

	dupCount := 0
	result := make(hostList, 0, len(hosts))
	for _, h := range hosts {
		if _, ok := found[h.hostname]; ok {
			log.Warnf("Duplicate hostname found in /etc/hosts, ignoring (%v/%v)",
				h.hostname, h.ip.String())
			dupCount++
		} else {
			found[h.hostname] = true
			result = append(result, h)
		}
	}

	return result
}

func runOnce() {
	hosts := readHosts(opts.File)
	hosts = filterHosts(hosts, opts.Networks)
	if !opts.NoQualifyHosts {
		hosts = qualifyHosts(hosts, opts.Domain)
	}
	hosts = removeDupes(hosts)

	r53 := newRoute53()
	r53Hosts, err := r53.getHosts(opts.Domain)
	if err != nil {
		log.Fatal(errors.Wrap(err, "error when retrieving zones"))
	}
	r53Hosts = filterHosts(r53Hosts, opts.Networks)

	toUpdate, toDelete := compareHosts(hosts, r53Hosts)
	if len(toUpdate) > 0 || len(toDelete) > 0 {
		if err := r53.sync(opts.Domain, opts.TTL, !opts.NoWait, toUpdate, toDelete); err != nil {
			log.Fatal(errors.Wrap(err, "Could not sync records to Route 53"))
		}
	} else {
		log.Info("No changes needed.  Everything in sync.")
	}

}

func main() {
	parseOpts()
	configureLogging()
	if opts.Mode == "oneshot" {
		runOnce()
	} else {
		daemon(opts.Interval, opts.File)
	}
}
<commit_msg>Add ability to specify syslog facility<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log/syslog"
	"os"
	"sort"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
	flags "github.com/jessevdk/go-flags"
	"github.com/pkg/errors"
)

// This will automatically be overridden at build time if the provided
// Makefile is used.
var version = "unknown"

var log = logrus.New()

var opts struct {
	Mode           string        `short:"m" long:"mode" description:"Operating mode" default:"daemon" choice:"daemon" choice:"oneshot"`
	File           string        `short:"f" long:"file" description:"Input file in /etc/hosts format" default:"/etc/hosts" value-name:"HOSTFILE"`
	Networks       []CIDRNet     `long:"network" description:"Filter by CIDR network" value-name:"x.x.x.x/len"`
	Domain         string        `short:"d" long:"domain" description:"Domain to update records in"`
	Interval       time.Duration `short:"i" long:"interval" description:"Seconds between scheduled resync times." default:"15m"`
	TTL            int64         `long:"ttl" description:"TTL to use for Route 53 records" default:"3600"`
	NoQualifyHosts bool          `long:"no-qualify-hosts" description:"Don't force domain to be added to end of hosts"`
	NoWait         bool          `long:"no-wait" description:"Don't wait for Route 53 to finish update"`
	Syslog         bool          `long:"syslog" description:"Send logging to syslog in addition to stdout"`
	SyslogFacility string        `long:"syslog-facility" description:"Syslog facility to log under" default:"user"`
	SyslogOnly     bool          `long:"syslog-only" description:"Send logging *only* to syslog"`
	Debug          bool          `long:"debug" description:"Enable debug logging"`
	Version        bool          `long:"version" description:"Print version number and exit"`
}

func facilityStringToInt(facility string) syslog.Priority {
	lookup := map[string]syslog.Priority{
		"kern":     syslog.LOG_KERN,
		"user":     syslog.LOG_USER,
		"mail":     syslog.LOG_MAIL,
		"daemon":   syslog.LOG_DAEMON,
		"auth":     syslog.LOG_AUTH,
		"syslog":   syslog.LOG_SYSLOG,
		"lpr":      syslog.LOG_LPR,
		"news":     syslog.LOG_NEWS,
		"uucp":     syslog.LOG_UUCP,
		"cron":     syslog.LOG_CRON,
		"authpriv": syslog.LOG_AUTHPRIV,
		"ftp":      syslog.LOG_FTP,
		"local0":   syslog.LOG_LOCAL0,
		"local1":   syslog.LOG_LOCAL1,
		"local2":   syslog.LOG_LOCAL2,
		"local3":   syslog.LOG_LOCAL3,
		"local4":   syslog.LOG_LOCAL4,
		"local5":   syslog.LOG_LOCAL5,
		"local6":   syslog.LOG_LOCAL6,
		"local7":   syslog.LOG_LOCAL7,
	}

	p, ok := lookup[facility]

	if !ok {
		keys := make([]string, len(lookup))
		for k := range lookup {
			keys = append(keys, k)
		}
		sort.Strings(keys)

		log.Errorf("\"%v\" is not a valid syslog facility", facility)
		log.Fatalln("Valid facilities are:", strings.Join(keys, " "))
	}

	return p
}

func parseOpts() {
	parser := flags.NewParser(&opts, flags.Default)

	if _, err := parser.Parse(); err != nil {
		if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp {
			os.Exit(0)
		} else {
			os.Exit(1)
		}
	}

	if opts.Version {
		fmt.Println("version: ", version)
		os.Exit(0)
	}

	if opts.Domain == "" {
		fmt.Fprintln(os.Stderr, "domain name must be specified (-d or --domain)")
		os.Exit(1)
	}

	if len(opts.Networks) == 0 {
		fmt.Fprintln(os.Stderr, "one or more networks must be provided (--network)")
		os.Exit(1)
	}

	// Accept trailing dot, but ignore it for consistency sake
	if strings.HasSuffix(opts.Domain, ".") {
		opts.Domain = opts.Domain[:len(opts.Domain)-1]
	}
}

func configureLogging() {
	if opts.SyslogOnly {
		log.Out = ioutil.Discard
	} else {
		// logrus defaults to stderr, but stdout is more conventional
		log.Out = os.Stdout
	}

	if opts.Debug {
		log.Level = logrus.DebugLevel
	}

	if opts.Syslog || opts.SyslogOnly {
		facility := facilityStringToInt(opts.SyslogFacility)
		log.Info("Disabling color for syslog")
		tf := &logrus.TextFormatter{DisableColors: true}
		log.Formatter = tf

		hook, err := logrus_syslog.NewSyslogHook("", "", facility, "sync-hosts-to-route53")
		if err == nil {
			log.Hooks.Add(hook)
		} else {
			log.Fatal("Cannot initialize syslog: ", err)
		}
	}

}

func canonifyHostname(hostname string) string {
	hostname = strings.ToLower(hostname)
	// Accept trailing dot, but ignore it for consistency sake
	if strings.HasSuffix(hostname, ".") {
		hostname = hostname[:len(hostname)-1]
	}

	return hostname
}

// compareHosts takes the contents of the local /etc/hosts file and the
// Route 53 hosts that should be compared and produces two arrays.  The first
// array is a list of Route 53 records that need to be updated, and the second
// array is a list of Route 53 records that should be deleted.
func compareHosts(hosts hostList, r53hosts hostList) (hostList, hostList) {
	// Build index on name, we'll delete entries out of here a we match them
	// against /etc/hosts entries.  The remaining entries aren't present
	// locally anymore and will need to be deleted.
	rhByName := map[string]hostEntry{}
	for _, rh := range r53hosts {
		rhByName[rh.hostname] = rh
	}

	toUpdate := hostList{}
	// Find existing hosts
	for _, h := range hosts {
		rh, ok := rhByName[h.hostname]
		if ok {
			delete(rhByName, h.hostname)
			if !h.ip.Equal(rh.ip) {
				toUpdate = append(toUpdate, h)
			}
		} else {
			toUpdate = append(toUpdate, h)
		}
	}

	toDelete := make(hostList, 0, len(rhByName))
	for _, rh := range rhByName {
		toDelete = append(toDelete, rh)
	}

	return toUpdate, toDelete
}

func removeDupes(hosts hostList) hostList {
	found := make(map[string]bool, len(hosts))

	// Sort hostlist to ensure stable duplication suppression.  We don't want
	// to ping pont between choosing different options because of parse order.
	sort.Sort(hosts)

	dupCount := 0
	result := make(hostList, 0, len(hosts))
	for _, h := range hosts {
		if _, ok := found[h.hostname]; ok {
			log.Warnf("Duplicate hostname found in /etc/hosts, ignoring (%v/%v)",
				h.hostname, h.ip.String())
			dupCount++
		} else {
			found[h.hostname] = true
			result = append(result, h)
		}
	}

	return result
}

func runOnce() {
	hosts := readHosts(opts.File)
	hosts = filterHosts(hosts, opts.Networks)
	if !opts.NoQualifyHosts {
		hosts = qualifyHosts(hosts, opts.Domain)
	}
	hosts = removeDupes(hosts)

	r53 := newRoute53()
	r53Hosts, err := r53.getHosts(opts.Domain)
	if err != nil {
		log.Fatal(errors.Wrap(err, "error when retrieving zones"))
	}
	r53Hosts = filterHosts(r53Hosts, opts.Networks)

	toUpdate, toDelete := compareHosts(hosts, r53Hosts)
	if len(toUpdate) > 0 || len(toDelete) > 0 {
		if err := r53.sync(opts.Domain, opts.TTL, !opts.NoWait, toUpdate, toDelete); err != nil {
			log.Fatal(errors.Wrap(err, "Could not sync records to Route 53"))
		}
	} else {
		log.Info("No changes needed.  Everything in sync.")
	}

}

func main() {
	parseOpts()
	configureLogging()
	if opts.Mode == "oneshot" {
		runOnce()
	} else {
		daemon(opts.Interval, opts.File)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"./models"
	"fmt"
)

func main() {
	p := models.NewProject("Project Test", "ptest", "A test project")
	fmt.Println("Created test project\n", p)
	r := models.NewRelease(1, "ch12")
	fmt.Println("\nCreated test release\n", r)
	page := models.NewPage(1, "manga/chapters/rnrl/001.jpg")
	fmt.Println("\nCreated test page\n", page)
}
<commit_msg>Set up the HTTP server in main<commit_after>package main

import (
	"./endpoints"

	"fmt"
	"net/http"

	"github.com/gorilla/mux"
)

func main() {
	router := mux.NewRouter()
	projectsRouter := router.PathPrefix("/projects").Subrouter()
	endpoints.RegisterProjectHandlers(projectsRouter, nil, nil)

	address := "0.0.0.0:3000"
	fmt.Printf("Listening on %s\n", address)
	http.ListenAndServe(address, router)
}
<|endoftext|>


<commit_before>package main

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

	rdb "github.com/dancannon/gorethink"
	"github.com/julienschmidt/httprouter"
	"github.com/rs/cors"
)

// Person is the model for our user
type Person struct {
	ID             string `gorethink:"id,omitempty"` // Need json
	FirstName      string `json:"firstName"`
	LastName       string `json:"lastName"`
	CoolnessFactor int    `json:"coolnessFactor"`
}

// DB holds our connection to the database
type DB struct {
	Session *rdb.Session
}

func newDBConn() *DB {
	session, err := rdb.Connect(rdb.ConnectOpts{
		Address: "localhost:28015",
	})
	if err != nil {
		log.Fatal("Error: %s\n", err)
	}
	return &DB{
		Session: session,
	}
}

// InitTable creates a new table
func (db *DB) InitTable(tableName string) {
	resp, err := rdb.TableCreate(tableName).RunWrite(db.Session)
	if err != nil {
		log.Printf("Note: %s\n", err)
	}
	log.Println("Tables created: ", resp.TablesCreated)
}

// List all users
func (db *DB) List(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var people []Person
	rows, err := rdb.Table("People").Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	err = rows.All(&people)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(people)
}

// Get all users
func (db *DB) Get(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var p Person
	row, err := rdb.Table("People").Get(ps.ByName("id")).Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	row.One(&p)
	json.NewEncoder(w).Encode(p)
}

// Update a specific user
func (db *DB) Update(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var p Person
	json.NewDecoder(r.Body).Decode(&p)

	resp, err := rdb.Table("People").Get(ps.ByName("id")).Update(p).RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(resp.GeneratedKeys)
}

// Delete a specific user
func (db *DB) Delete(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	resp, err := rdb.Table("People").Get(ps.ByName("id")).Delete().RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(resp)
}

// Add a new user
func (db *DB) Add(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var p Person
	json.NewDecoder(r.Body).Decode(&p)

	row, err := rdb.Table("People").Insert(p).RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	// While this is cool it's probably easier just to use a marshaler. On the
	// other hand, this keep it consistent, so it's probably easier to
	// understand this way.
	id := row.GeneratedKeys
	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(map[string]string{"id": id[0]})
}

func main() {
	db := newDBConn()
	db.InitTable("People")
	c := cors.New(cors.Options{
		AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "HEAD"},
	})
	router := httprouter.New()

	router.GET("/api/people", db.List)
	router.GET("/api/people/:id", db.Get)
	router.PUT("/api/people/:id", db.Update)
	router.DELETE("/api/people/:id", db.Delete)
	router.POST("/api/people", db.Add)

	http.ListenAndServe(":8000", c.Handler(router))
}
<commit_msg>Fix json and gorethink struct defs<commit_after>package main

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

	rdb "github.com/dancannon/gorethink"
	"github.com/julienschmidt/httprouter"
	"github.com/rs/cors"
)

// Person is the model for our user.
type Person struct {
	ID             string `json:"id" gorethink:"id,omitempty"`
	FirstName      string `json:"firstName"`
	LastName       string `json:"lastName"`
	CoolnessFactor int    `json:"coolnessFactor"`
}

// DB stores our connection to the database.
type DB struct {
	Session *rdb.Session
}

func newDBConn() *DB {
	session, err := rdb.Connect(rdb.ConnectOpts{
		Address: "localhost:28015",
	})
	if err != nil {
		log.Fatal("Error: %s\n", err)
	}
	return &DB{
		Session: session,
	}
}

// InitTable creates a new table.
func (db *DB) InitTable(tableName string) {
	resp, err := rdb.TableCreate(tableName).RunWrite(db.Session)
	if err != nil {
		log.Printf("Note: %s\n", err)
	}
	log.Println("Tables created: ", resp.TablesCreated)
}

// List all users
func (db *DB) List(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var people []Person
	rows, err := rdb.Table("People").Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	err = rows.All(&people)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(people)
}

// Get all users
func (db *DB) Get(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var p Person
	row, err := rdb.Table("People").Get(ps.ByName("id")).Run(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	row.One(&p)
	json.NewEncoder(w).Encode(p)
}

// Update a specific user
func (db *DB) Update(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var p Person
	json.NewDecoder(r.Body).Decode(&p)

	resp, err := rdb.Table("People").Get(ps.ByName("id")).Update(p).RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(resp.GeneratedKeys)
}

// Delete a specific user
func (db *DB) Delete(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	resp, err := rdb.Table("People").Get(ps.ByName("id")).Delete().RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	json.NewEncoder(w).Encode(resp)
}

// Add a new user
func (db *DB) Add(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	var p Person
	json.NewDecoder(r.Body).Decode(&p)

	row, err := rdb.Table("People").Insert(p).RunWrite(db.Session)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	// While this is cool it's probably easier just to use a marshaler. On the
	// other hand, this keep it consistent, so it's probably easier to
	// understand this way.
	id := row.GeneratedKeys
	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(map[string]string{"id": id[0]})
}

func main() {
	db := newDBConn()
	db.InitTable("People")
	c := cors.New(cors.Options{
		AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "HEAD"},
	})
	router := httprouter.New()

	router.GET("/api/people", db.List)
	router.GET("/api/people/:id", db.Get)
	router.PUT("/api/people/:id", db.Update)
	router.DELETE("/api/people/:id", db.Delete)
	router.POST("/api/people", db.Add)

	http.ListenAndServe(":8000", c.Handler(router))
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"strings"

	"github.com/gammons/todolist/todolist"
)

// the current version of todolist
const (
	VERSION = "0.8.1"
)

func main() {
	if len(os.Args) <= 1 {
		todolist.Usage()
		os.Exit(0)
	}
	input := strings.Join(os.Args[1:], " ")
	routeInput(os.Args[1], input)
}

func routeInput(command string, input string) {
	app := todolist.NewApp()
	switch command {
	case "l", "ln", "list", "agenda":
		app.ListTodos(input)
	case "a", "add":
		app.AddTodo(input)
	case "done":
		app.AddDoneTodo(input)
	case "d", "delete":
		app.DeleteTodo(input)
	case "c", "complete":
		app.CompleteTodo(input)
	case "uc", "uncomplete":
		app.UncompleteTodo(input)
	case "ar", "archive":
		app.ArchiveTodo(input)
	case "uar", "unarchive":
		app.UnarchiveTodo(input)
	case "ac":
		app.ArchiveCompleted()
	case "e", "edit":
		app.EditTodo(input)
	case "ex", "expand":
		app.ExpandTodo(input)
	case "an", "n", "dn", "en":
		app.HandleNotes(input)
	case "gc":
		app.GarbageCollect()
	case "p", "prioritize":
		app.PrioritizeTodo(input)
	case "up", "unprioritize":
		app.UnprioritizeTodo(input)
	case "init":
		app.InitializeRepo()
	case "sync":
		app.Sync(input)
	case "auth":
		app.AuthWorkflow()
	}
}
<commit_msg>update main to be ultralist<commit_after>package main

import (
	"os"
	"strings"

	"github.com/gammons/ultralist/ultralist"
)

// the current version of ultralist
const (
	VERSION = "0.9"
)

func main() {
	if len(os.Args) <= 1 {
		ultralist.Usage()
		os.Exit(0)
	}
	input := strings.Join(os.Args[1:], " ")
	routeInput(os.Args[1], input)
}

func routeInput(command string, input string) {
	app := ultralist.NewApp()
	switch command {
	case "l", "ln", "list", "agenda":
		app.ListTodos(input)
	case "a", "add":
		app.AddTodo(input)
	case "done":
		app.AddDoneTodo(input)
	case "d", "delete":
		app.DeleteTodo(input)
	case "c", "complete":
		app.CompleteTodo(input)
	case "uc", "uncomplete":
		app.UncompleteTodo(input)
	case "ar", "archive":
		app.ArchiveTodo(input)
	case "uar", "unarchive":
		app.UnarchiveTodo(input)
	case "ac":
		app.ArchiveCompleted()
	case "e", "edit":
		app.EditTodo(input)
	case "ex", "expand":
		app.ExpandTodo(input)
	case "an", "n", "dn", "en":
		app.HandleNotes(input)
	case "gc":
		app.GarbageCollect()
	case "p", "prioritize":
		app.PrioritizeTodo(input)
	case "up", "unprioritize":
		app.UnprioritizeTodo(input)
	case "init":
		app.InitializeRepo()
	case "sync":
		app.Sync(input)
	case "auth":
		app.AuthWorkflow()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"strings"

	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/cf/trace"
	"github.com/cloudfoundry/cli/plugin"
	"github.com/kkellner/cloudfoundry-top-plugin/top"
	"github.com/kkellner/cloudfoundry-top-plugin/util"
	"github.com/simonleung8/flags"
)

type TopCmd struct {
	ui terminal.UI
}

func (c *TopCmd) GetMetadata() plugin.PluginMetadata {
	return plugin.PluginMetadata{
		Name: "top",
		Version: plugin.VersionType{
			Major: 0,
			Minor: 6,
			Build: 8,
		},
		MinCliVersion: plugin.VersionType{
			Major: 6,
			Minor: 17,
			Build: 0,
		},
		Commands: []plugin.Command{
			{
				Name:     "top",
				HelpText: "Displays top stats - by Kurt Kellner of ECS Team",
				UsageDetails: plugin.Usage{
					Usage: "cf top",
					Options: map[string]string{
						"debug":   "-d, enable debugging",
						"cygwin":  "-c, force run under cygwin (Use this to run: 'cmd /c start cf top -cygwin' )",
						"nozzles": "-n, specify the number of nozzle instances (default: 2)",
					},
				},
			},
		},
	}
}

func main() {
	plugin.Start(new(TopCmd))
}

func (c *TopCmd) Run(cliConnection plugin.CliConnection, args []string) {
	var options *top.ClientOptions

	traceLogger := trace.NewLogger(os.Stdout, true, os.Getenv("CF_TRACE"), "")
	c.ui = terminal.NewUI(os.Stdin, os.Stdout, terminal.NewTeePrinter(os.Stdout), traceLogger)

	switch args[0] {
	case "top":
		options = c.buildClientOptions(args)
	case "app-top":
		options = c.buildClientOptions(args)
		appModel, err := cliConnection.GetApp(args[1])
		if err != nil {
			c.ui.Warn(err.Error())
			return
		}
		options.AppGUID = appModel.Guid
	default:
		return
	}

	cfTrace := os.Getenv("CF_TRACE")
	if strings.ToLower(cfTrace) == "true" {
		c.ui.Failed("The cf top plugin will not run with CF_TRACE environment variable set to true")
		return
	}

	if !options.Cygwin && util.IsCygwin() {
		c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top -cygwin'")
		return
	}

	/***********************************************************
	Trying to find a way to detect cygwin but not detect cygwin if cmd.exe is spawned from cygwin

	values := os.Environ()
	for _, v := range values  {
		fmt.Printf("value: [%v]\n", v)
	}

	fmt.Printf("Separator: [%v]\n", os.PathSeparator)
	fmt.Printf("PathListSeparator: [%v]\n", os.PathListSeparator)
	fmt.Printf("Geteuid: %v\n", os.Geteuid())
	fmt.Printf("Getppid: %v\n", os.Getppid())
	p, e := os.FindProcess(os.Getppid())
	fmt.Printf("Getppid: %+v [Err:%v]\n", p, e)

	if strings.Contains(strings.ToLower(os.Getenv("OS")), "windows") {
		shell := os.Getenv("SHELL")
		if len(shell) > 0 {
			c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top'")
			return
		}
	}
	fmt.Printf("runtime.GOOS: [%v]\n", runtime.GOOS)
	*/

	/*
		if strings.ToLower(osType) == "cygwin" {
			c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top'")
			return
		}
	*/

	client := top.NewClient(cliConnection, options, c.ui)
	client.Start()
}

func (c *TopCmd) buildClientOptions(args []string) *top.ClientOptions {
	var debug bool
	var cygwin bool
	var nozzles int

	fc := flags.New()
	fc.NewBoolFlag("debug", "d", "used for debugging")
	fc.NewBoolFlag("cygwin", "c", "force run under cygwin (Use this to run: 'cmd /c start cf top -cygwin' )")
	fc.NewIntFlagWithDefault("nozzles", "n", "number of nozzles", 2)
	//fc.NewStringFlag("filter", "f", "specify message filter such as LogMessage, ValueMetric, CounterEvent, HttpStartStop")
	err := fc.Parse(args[1:]...)

	if err != nil {
		c.ui.Failed(err.Error())
	}
	if fc.IsSet("debug") {
		debug = fc.Bool("debug")
	}
	if fc.IsSet("cygwin") {
		cygwin = fc.Bool("cygwin")
	}

	nozzles = fc.Int("nozzles")

	/*
		if fc.IsSet("filter") {
			filter = fc.String("filter")
		}
	*/
	return &top.ClientOptions{
		Debug:   debug,
		Cygwin:  cygwin,
		Nozzles: nozzles,
	}
}
<commit_msg>Build version v0.6.9<commit_after>package main

import (
	"os"
	"strings"

	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/cf/trace"
	"github.com/cloudfoundry/cli/plugin"
	"github.com/kkellner/cloudfoundry-top-plugin/top"
	"github.com/kkellner/cloudfoundry-top-plugin/util"
	"github.com/simonleung8/flags"
)

type TopCmd struct {
	ui terminal.UI
}

func (c *TopCmd) GetMetadata() plugin.PluginMetadata {
	return plugin.PluginMetadata{
		Name: "top",
		Version: plugin.VersionType{
			Major: 0,
			Minor: 6,
			Build: 9,
		},
		MinCliVersion: plugin.VersionType{
			Major: 6,
			Minor: 17,
			Build: 0,
		},
		Commands: []plugin.Command{
			{
				Name:     "top",
				HelpText: "Displays top stats - by Kurt Kellner of ECS Team",
				UsageDetails: plugin.Usage{
					Usage: "cf top",
					Options: map[string]string{
						"debug":   "-d, enable debugging",
						"cygwin":  "-c, force run under cygwin (Use this to run: 'cmd /c start cf top -cygwin' )",
						"nozzles": "-n, specify the number of nozzle instances (default: 2)",
					},
				},
			},
		},
	}
}

func main() {
	plugin.Start(new(TopCmd))
}

func (c *TopCmd) Run(cliConnection plugin.CliConnection, args []string) {
	var options *top.ClientOptions

	traceLogger := trace.NewLogger(os.Stdout, true, os.Getenv("CF_TRACE"), "")
	c.ui = terminal.NewUI(os.Stdin, os.Stdout, terminal.NewTeePrinter(os.Stdout), traceLogger)

	switch args[0] {
	case "top":
		options = c.buildClientOptions(args)
	case "app-top":
		options = c.buildClientOptions(args)
		appModel, err := cliConnection.GetApp(args[1])
		if err != nil {
			c.ui.Warn(err.Error())
			return
		}
		options.AppGUID = appModel.Guid
	default:
		return
	}

	cfTrace := os.Getenv("CF_TRACE")
	if strings.ToLower(cfTrace) == "true" {
		c.ui.Failed("The cf top plugin will not run with CF_TRACE environment variable set to true")
		return
	}

	if !options.Cygwin && util.IsCygwin() {
		c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top -cygwin'")
		return
	}

	/***********************************************************
	Trying to find a way to detect cygwin but not detect cygwin if cmd.exe is spawned from cygwin

	values := os.Environ()
	for _, v := range values  {
		fmt.Printf("value: [%v]\n", v)
	}

	fmt.Printf("Separator: [%v]\n", os.PathSeparator)
	fmt.Printf("PathListSeparator: [%v]\n", os.PathListSeparator)
	fmt.Printf("Geteuid: %v\n", os.Geteuid())
	fmt.Printf("Getppid: %v\n", os.Getppid())
	p, e := os.FindProcess(os.Getppid())
	fmt.Printf("Getppid: %+v [Err:%v]\n", p, e)

	if strings.Contains(strings.ToLower(os.Getenv("OS")), "windows") {
		shell := os.Getenv("SHELL")
		if len(shell) > 0 {
			c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top'")
			return
		}
	}
	fmt.Printf("runtime.GOOS: [%v]\n", runtime.GOOS)
	*/

	/*
		if strings.ToLower(osType) == "cygwin" {
			c.ui.Failed("The cf top plugin will not run under cygwin.  Use this to run: 'cmd /c start cf top'")
			return
		}
	*/

	client := top.NewClient(cliConnection, options, c.ui)
	client.Start()
}

func (c *TopCmd) buildClientOptions(args []string) *top.ClientOptions {
	var debug bool
	var cygwin bool
	var nozzles int

	fc := flags.New()
	fc.NewBoolFlag("debug", "d", "used for debugging")
	fc.NewBoolFlag("cygwin", "c", "force run under cygwin (Use this to run: 'cmd /c start cf top -cygwin' )")
	fc.NewIntFlagWithDefault("nozzles", "n", "number of nozzles", 2)
	//fc.NewStringFlag("filter", "f", "specify message filter such as LogMessage, ValueMetric, CounterEvent, HttpStartStop")
	err := fc.Parse(args[1:]...)

	if err != nil {
		c.ui.Failed(err.Error())
	}
	if fc.IsSet("debug") {
		debug = fc.Bool("debug")
	}
	if fc.IsSet("cygwin") {
		cygwin = fc.Bool("cygwin")
	}

	nozzles = fc.Int("nozzles")

	/*
		if fc.IsSet("filter") {
			filter = fc.String("filter")
		}
	*/
	return &top.ClientOptions{
		Debug:   debug,
		Cygwin:  cygwin,
		Nozzles: nozzles,
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/fsouza/go-dockerclient"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("no container provided")
		os.Exit(1)
	}

	client, err := docker.NewClient("tcp://127.0.0.1:4243")
	if err != nil {
		panic(err)
	}

	g := &Grid{make(map[string]*Container)}
	for _, c := range os.Args[1:] {
		g.AddContainer(c)
	}

	for _, c := range g.containers {
		c.Collect(client)
	}

	Display(g)

}
<commit_msg>get dockerhost from environment<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/fsouza/go-dockerclient"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("no container provided")
		os.Exit(1)
	}

	dockerhost := os.Getenv("DOCKER_HOST")
	if dockerhost == "" {
		dockerhost = "unix:///var/run/docker.sock"
	}

	client, err := docker.NewClient(dockerhost)
	if err != nil {
		panic(err)
	}

	g := &Grid{make(map[string]*Container)}
	for _, c := range os.Args[1:] {
		g.AddContainer(c)
	}

	for _, c := range g.containers {
		c.Collect(client)
	}

	Display(g)

}
<|endoftext|>


<commit_before>package main

import odin "github.com/jwaldrip/odin/cli"

// VERSION is the odin version
var VERSION = "0.9.0"

var cli = odin.NewCLI(VERSION, "a command line DSL for go-lang", func(cmd odin.Command) { cmd.Usage() })

func main() {
	cli.Start()
}
<commit_msg>version 1.0.0<commit_after>package main

import odin "github.com/jwaldrip/odin/cli"

// VERSION is the odin version
var VERSION = "1.0.0"

var cli = odin.NewCLI(VERSION, "a command line DSL for go-lang", func(cmd odin.Command) { cmd.Usage() })

func main() {
	cli.Start()
}
<|endoftext|>


<commit_before>// A command line tool that shows the status of (many) Go packages.
package main

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"sync"

	"github.com/kisielk/gotool"
	"github.com/shurcooL/gostatus/status"

	"github.com/shurcooL/go/gists/gist7480523"
	"github.com/shurcooL/go/gists/gist7651991"
)

const numWorkers = 8

var vFlag = flag.Bool("v", false, "Verbose output: show all Go packages, not just ones with notable status.")
var stdinFlag = flag.Bool("stdin", false, "Read the list of newline separated Go packages from stdin.")
var plumbingFlag = flag.Bool("plumbing", false, "Give the output in an easy-to-parse format for scripts.")
var debugFlag = flag.Bool("debug", false, "Give the output with verbose debug information.")

func init() {
	flag.BoolVar(&status.FFlag, "f", false, "Force not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.")
}

func usage() {
	fmt.Fprint(os.Stderr, "Usage: gostatus [flags] [packages]\n")
	fmt.Fprint(os.Stderr, "       [newline separated packages] | gostatus --stdin [flags]\n")
	flag.PrintDefaults()
	fmt.Fprint(os.Stderr, `
Examples:
  # Show status of package in current directory, if notable.
  gostatus .

  # Show status of all packages with notable status.
  gostatus all

  # Show status of all dependencies (recursive) of package in cur working dir.
  go list -f '{{join .Deps "\n"}}' . | gostatus --stdin -v

Legend:
  ???? - Not under (recognized) version control
  b - Non-master branch checked out
  * - Uncommited changes in working dir
  + - Update available
  - - Local revision is ahead of remote (need to push?)
  ! - No remote
  # - Remote path doesn't match import path
  $ - Stash exists
`)
	os.Exit(2)
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Usage = usage
	flag.Parse()

	// Get current directory.
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	shouldShow := func(goPackage *gist7480523.GoPackage) bool {
		// Check for notable status.
		return status.PorcelainPresenter(goPackage)[:4] != "    "
	}
	if *vFlag == true {
		shouldShow = func(_ *gist7480523.GoPackage) bool { return true }
	}

	var presenter gist7480523.GoPackageStringer = status.PorcelainPresenter
	if *debugFlag == true {
		presenter = status.DebugPresenter
	} else if *plumbingFlag == true {
		presenter = status.PlumbingPresenter
	}

	// A map of repos that have been checked, to avoid doing same repo more than once.
	var lock sync.Mutex
	checkedRepos := map[string]bool{}

	// Input: Go package Import Path
	// Output: If a valid Go package and not inside GOROOT, output a status string, else nil.
	reduceFunc := func(in string) interface{} {
		goPackage, err := gist7480523.GoPackageFromPath(in, wd)
		if err != nil {
			fmt.Fprintf(os.Stderr, "can't load package: %s\n", err)
			return nil
		}
		if goPackage == nil {
			return nil
		}
		if goPackage.Bpkg.Goroot {
			return nil
		}

		goPackage.UpdateVcs()
		// Check that the same repo hasn't already been done.
		if goPackage.Dir.Repo != nil {
			rootPath := goPackage.Dir.Repo.Vcs.RootPath()
			lock.Lock()
			if !checkedRepos[rootPath] {
				checkedRepos[rootPath] = true
				lock.Unlock()
			} else {
				lock.Unlock()
				// Skip repos that were done.
				return nil
			}
		}

		goPackage.UpdateVcsFields()

		if shouldShow(goPackage) == false {
			return nil
		}
		return presenter(goPackage)
	}

	// Run reduceFunc on all import paths in parallel.
	var outChan <-chan interface{}
	switch *stdinFlag {
	case false:
		importPathPatterns := flag.Args()
		if len(importPathPatterns) == 0 {
			importPathPatterns = []string{"."}
		}
		importPaths := gotool.ImportPaths(importPathPatterns)
		outChan = gist7651991.GoReduceLinesFromSlice(importPaths, numWorkers, reduceFunc)
	case true:
		outChan = gist7651991.GoReduceLinesFromReader(os.Stdin, numWorkers, reduceFunc)
	}

	// Output results.
	for out := range outChan {
		fmt.Println(out.(string))
	}
}
<commit_msg>Remove unneeded step.<commit_after>// A command line tool that shows the status of (many) Go packages.
package main

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"sync"

	"github.com/kisielk/gotool"
	"github.com/shurcooL/gostatus/status"

	"github.com/shurcooL/go/gists/gist7480523"
	"github.com/shurcooL/go/gists/gist7651991"
)

const numWorkers = 8

var vFlag = flag.Bool("v", false, "Verbose output: show all Go packages, not just ones with notable status.")
var stdinFlag = flag.Bool("stdin", false, "Read the list of newline separated Go packages from stdin.")
var plumbingFlag = flag.Bool("plumbing", false, "Give the output in an easy-to-parse format for scripts.")
var debugFlag = flag.Bool("debug", false, "Give the output with verbose debug information.")

func init() {
	flag.BoolVar(&status.FFlag, "f", false, "Force not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.")
}

func usage() {
	fmt.Fprint(os.Stderr, "Usage: gostatus [flags] [packages]\n")
	fmt.Fprint(os.Stderr, "       [newline separated packages] | gostatus --stdin [flags]\n")
	flag.PrintDefaults()
	fmt.Fprint(os.Stderr, `
Examples:
  # Show status of package in current directory, if notable.
  gostatus .

  # Show status of all packages with notable status.
  gostatus all

  # Show status of all dependencies (recursive) of package in cur working dir.
  go list -f '{{join .Deps "\n"}}' . | gostatus --stdin -v

Legend:
  ???? - Not under (recognized) version control
  b - Non-master branch checked out
  * - Uncommited changes in working dir
  + - Update available
  - - Local revision is ahead of remote (need to push?)
  ! - No remote
  # - Remote path doesn't match import path
  $ - Stash exists
`)
	os.Exit(2)
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	flag.Usage = usage
	flag.Parse()

	// Get current directory.
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	shouldShow := func(goPackage *gist7480523.GoPackage) bool {
		// Check for notable status.
		return status.PorcelainPresenter(goPackage)[:4] != "    "
	}
	if *vFlag == true {
		shouldShow = func(_ *gist7480523.GoPackage) bool { return true }
	}

	var presenter gist7480523.GoPackageStringer = status.PorcelainPresenter
	if *debugFlag == true {
		presenter = status.DebugPresenter
	} else if *plumbingFlag == true {
		presenter = status.PlumbingPresenter
	}

	// A map of repos that have been checked, to avoid doing same repo more than once.
	var lock sync.Mutex
	checkedRepos := map[string]bool{}

	// Input: Go package Import Path
	// Output: If a valid Go package and not inside GOROOT, output a status string, else nil.
	reduceFunc := func(in string) interface{} {
		goPackage, err := gist7480523.GoPackageFromPath(in, wd)
		if err != nil {
			fmt.Fprintf(os.Stderr, "can't load package: %s\n", err)
			return nil
		}
		if goPackage == nil {
			return nil
		}
		if goPackage.Bpkg.Goroot {
			return nil
		}

		goPackage.UpdateVcs()
		// Check that the same repo hasn't already been done.
		if goPackage.Dir.Repo != nil {
			rootPath := goPackage.Dir.Repo.Vcs.RootPath()
			lock.Lock()
			if !checkedRepos[rootPath] {
				checkedRepos[rootPath] = true
				lock.Unlock()
			} else {
				lock.Unlock()
				// Skip repos that were done.
				return nil
			}
		}

		goPackage.UpdateVcsFields()

		if shouldShow(goPackage) == false {
			return nil
		}
		return presenter(goPackage)
	}

	// Run reduceFunc on all import paths in parallel.
	var outChan <-chan interface{}
	switch *stdinFlag {
	case false:
		importPathPatterns := flag.Args()
		importPaths := gotool.ImportPaths(importPathPatterns)
		outChan = gist7651991.GoReduceLinesFromSlice(importPaths, numWorkers, reduceFunc)
	case true:
		outChan = gist7651991.GoReduceLinesFromReader(os.Stdin, numWorkers, reduceFunc)
	}

	// Output results.
	for out := range outChan {
		fmt.Println(out.(string))
	}
}
<|endoftext|>


<commit_before>// Copyright 2018 The Nakama Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"strings"
	"syscall"
	"time"

	"github.com/gofrs/uuid"
	"github.com/heroiclabs/nakama/v3/ga"
	"github.com/heroiclabs/nakama/v3/migrate"
	"github.com/heroiclabs/nakama/v3/server"
	"github.com/heroiclabs/nakama/v3/social"
	_ "github.com/jackc/pgx/v4/stdlib"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"google.golang.org/protobuf/encoding/protojson"
)

const cookieFilename = ".cookie"

var (
	version  string = "3.0.0"
	commitID string = "dev"

	// Shared utility components.
	jsonpbMarshaler = &protojson.MarshalOptions{
		UseEnumNumbers:  true,
		EmitUnpopulated: false,
		Indent:          "",
		UseProtoNames:   true,
	}
	jsonpbUnmarshaler = &protojson.UnmarshalOptions{
		DiscardUnknown: false,
	}
)

func main() {
	semver := fmt.Sprintf("%s+%s", version, commitID)
	// Always set default timeout on HTTP client.
	http.DefaultClient.Timeout = 1500 * time.Millisecond
	// Initialize the global random obj with customs seed.
	rand.Seed(time.Now().UnixNano())

	tmpLogger := server.NewJSONLogger(os.Stdout, zapcore.InfoLevel, server.JSONFormat)

	if len(os.Args) > 1 {
		switch os.Args[1] {
		case "--version":
			fmt.Println(semver)
			return
		case "migrate":
			migrate.Parse(os.Args[2:], tmpLogger)
		case "check":
			// Parse any command line args to look up runtime path.
			// Use full config structure even if not all of its options are available in this command.
			config := server.NewConfig(tmpLogger)
			var runtimePath string
			flags := flag.NewFlagSet("check", flag.ExitOnError)
			flags.StringVar(&runtimePath, "runtime.path", filepath.Join(config.GetDataDir(), "modules"), "Path for the server to scan for Lua and Go library files.")
			if err := flags.Parse(os.Args[2:]); err != nil {
				tmpLogger.Fatal("Could not parse check flags.")
			}
			config.GetRuntime().Path = runtimePath

			if err := server.CheckRuntime(tmpLogger, config); err != nil {
				// Errors are already logged in the function above.
				os.Exit(1)
			}
			return
		}
	}

	config := server.ParseArgs(tmpLogger, os.Args)
	logger, startupLogger := server.SetupLogging(tmpLogger, config)
	configWarnings := server.CheckConfig(logger, config)

	startupLogger.Info("Nakama starting")
	startupLogger.Info("Node", zap.String("name", config.GetName()), zap.String("version", semver), zap.String("runtime", runtime.Version()), zap.Int("cpu", runtime.NumCPU()), zap.Int("proc", runtime.GOMAXPROCS(0)))
	startupLogger.Info("Data directory", zap.String("path", config.GetDataDir()))

	redactedAddresses := make([]string, 0, 1)
	for _, address := range config.GetDatabase().Addresses {
		rawURL := fmt.Sprintf("postgres://%s", address)
		parsedURL, err := url.Parse(rawURL)
		if err != nil {
			logger.Fatal("Bad connection URL", zap.Error(err))
		}
		redactedAddresses = append(redactedAddresses, strings.TrimPrefix(parsedURL.Redacted(), "postgres://"))
	}
	startupLogger.Info("Database connections", zap.Strings("dsns", redactedAddresses))

	// Global server context.
	ctx, ctxCancelFn := context.WithCancel(context.Background())

	db, dbVersion := server.DbConnect(ctx, startupLogger, config)
	startupLogger.Info("Database information", zap.String("version", dbVersion))

	// Check migration status and fail fast if the schema has diverged.
	migrate.StartupCheck(startupLogger, db)

	// Access to social provider integrations.
	socialClient := social.NewClient(logger, 5*time.Second)

	// Start up server components.
	cookie := newOrLoadCookie(config)
	metrics := server.NewLocalMetrics(logger, startupLogger, db, config)
	sessionRegistry := server.NewLocalSessionRegistry(metrics)
	sessionCache := server.NewLocalSessionCache(config)
	statusRegistry := server.NewStatusRegistry(logger, config, sessionRegistry, jsonpbMarshaler)
	tracker := server.StartLocalTracker(logger, config, sessionRegistry, statusRegistry, metrics, jsonpbMarshaler)
	router := server.NewLocalMessageRouter(sessionRegistry, tracker, jsonpbMarshaler)
	leaderboardCache := server.NewLocalLeaderboardCache(logger, startupLogger, db)
	leaderboardRankCache := server.NewLocalLeaderboardRankCache(startupLogger, db, config.GetLeaderboard(), leaderboardCache)
	leaderboardScheduler := server.NewLocalLeaderboardScheduler(logger, db, config, leaderboardCache, leaderboardRankCache)
	matchRegistry := server.NewLocalMatchRegistry(logger, startupLogger, config, sessionRegistry, tracker, router, metrics, config.GetName())
	tracker.SetMatchJoinListener(matchRegistry.Join)
	tracker.SetMatchLeaveListener(matchRegistry.Leave)
	streamManager := server.NewLocalStreamManager(config, sessionRegistry, tracker)
	runtime, runtimeInfo, err := server.NewRuntime(ctx, logger, startupLogger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, sessionCache, matchRegistry, tracker, metrics, streamManager, router)
	if err != nil {
		startupLogger.Fatal("Failed initializing runtime modules", zap.Error(err))
	}
	matchmaker := server.NewLocalMatchmaker(logger, startupLogger, config, router, runtime)
	partyRegistry := server.NewLocalPartyRegistry(logger, matchmaker, tracker, streamManager, router, config.GetName())
	tracker.SetPartyJoinListener(partyRegistry.Join)
	tracker.SetPartyLeaveListener(partyRegistry.Leave)

	leaderboardScheduler.Start(runtime)

	pipeline := server.NewPipeline(logger, config, db, jsonpbMarshaler, jsonpbUnmarshaler, sessionRegistry, statusRegistry, matchRegistry, partyRegistry, matchmaker, tracker, router, runtime)
	statusHandler := server.NewLocalStatusHandler(logger, sessionRegistry, matchRegistry, tracker, metrics, config.GetName())

	apiServer := server.StartApiServer(logger, startupLogger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, sessionRegistry, sessionCache, statusRegistry, matchRegistry, matchmaker, tracker, router, metrics, pipeline, runtime)
	consoleServer := server.StartConsoleServer(logger, startupLogger, db, config, tracker, router, sessionCache, statusHandler, runtimeInfo, matchRegistry, configWarnings, semver, leaderboardCache, leaderboardRankCache, apiServer, cookie)

	gaenabled := len(os.Getenv("NAKAMA_TELEMETRY")) < 1
	const gacode = "UA-89792135-1"
	var telemetryClient *http.Client
	if gaenabled {
		telemetryClient = &http.Client{
			Timeout: 1500 * time.Millisecond,
		}
		runTelemetry(telemetryClient, gacode, cookie)
	}

	// Respect OS stop signals.
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

	startupLogger.Info("Startup done")

	// Wait for a termination signal.
	<-c

	graceSeconds := config.GetShutdownGraceSec()

	// If a shutdown grace period is allowed, prepare a timer.
	var timer *time.Timer
	timerCh := make(<-chan time.Time, 1)
	if graceSeconds != 0 {
		timer = time.NewTimer(time.Duration(graceSeconds) * time.Second)
		timerCh = timer.C
		startupLogger.Info("Shutdown started - use CTRL^C to force stop server", zap.Int("grace_period_sec", graceSeconds))
	} else {
		// No grace period.
		startupLogger.Info("Shutdown started")
	}

	// Stop any running authoritative matches and do not accept any new ones.
	select {
	case <-matchRegistry.Stop(graceSeconds):
		// Graceful shutdown has completed.
		startupLogger.Info("All authoritative matches stopped")
	case <-timerCh:
		// Timer has expired, terminate matches immediately.
		startupLogger.Info("Shutdown grace period expired")
		<-matchRegistry.Stop(0)
	case <-c:
		// A second interrupt has been received.
		startupLogger.Info("Skipping graceful shutdown")
		<-matchRegistry.Stop(0)
	}
	if timer != nil {
		timer.Stop()
	}

	// Signal cancellation to the global runtime context.
	ctxCancelFn()

	// Gracefully stop remaining server components.
	apiServer.Stop()
	consoleServer.Stop()
	matchmaker.Stop()
	leaderboardScheduler.Stop()
	tracker.Stop()
	statusRegistry.Stop()
	sessionCache.Stop()
	sessionRegistry.Stop()
	metrics.Stop(logger)

	if gaenabled {
		_ = ga.SendSessionStop(telemetryClient, gacode, cookie)
	}

	startupLogger.Info("Shutdown complete")

	os.Exit(0)
}

// Help improve Nakama by sending anonymous usage statistics.
//
// You can disable the telemetry completely before server start by setting the
// environment variable "NAKAMA_TELEMETRY" - i.e. NAKAMA_TELEMETRY=0 nakama
//
// These properties are collected:
// * A unique UUID v4 random identifier which is generated.
// * Version of Nakama being used which includes build metadata.
// * Amount of time the server ran for.
//
// This information is sent via Google Analytics which allows the Nakama team to
// analyze usage patterns and errors in order to help improve the server.
func runTelemetry(httpc *http.Client, gacode string, cookie string) {
	if ga.SendSessionStart(httpc, gacode, cookie) != nil {
		return
	}
	if ga.SendEvent(httpc, gacode, cookie, &ga.Event{Ec: "version", Ea: fmt.Sprintf("%s+%s", version, commitID)}) != nil {
		return
	}
	_ = ga.SendEvent(httpc, gacode, cookie, &ga.Event{Ec: "variant", Ea: "nakama"})
}

func newOrLoadCookie(config server.Config) string {
	filePath := filepath.FromSlash(config.GetDataDir() + "/" + cookieFilename)
	b, err := ioutil.ReadFile(filePath)
	cookie := uuid.FromBytesOrNil(b)
	if err != nil || cookie == uuid.Nil {
		cookie = uuid.Must(uuid.NewV4())
		_ = ioutil.WriteFile(filePath, cookie.Bytes(), 0644)
	}
	return cookie.String()
}
<commit_msg>Seed global random using crypto/rand. (#786)<commit_after>// Copyright 2018 The Nakama Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"context"
	cryptorand "crypto/rand"
	"encoding/binary"
	"flag"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"strings"
	"syscall"
	"time"

	"github.com/gofrs/uuid"
	"github.com/heroiclabs/nakama/v3/ga"
	"github.com/heroiclabs/nakama/v3/migrate"
	"github.com/heroiclabs/nakama/v3/server"
	"github.com/heroiclabs/nakama/v3/social"
	_ "github.com/jackc/pgx/v4/stdlib"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"google.golang.org/protobuf/encoding/protojson"
)

const cookieFilename = ".cookie"

var (
	version  string = "3.0.0"
	commitID string = "dev"

	// Shared utility components.
	jsonpbMarshaler = &protojson.MarshalOptions{
		UseEnumNumbers:  true,
		EmitUnpopulated: false,
		Indent:          "",
		UseProtoNames:   true,
	}
	jsonpbUnmarshaler = &protojson.UnmarshalOptions{
		DiscardUnknown: false,
	}
)

func main() {
	semver := fmt.Sprintf("%s+%s", version, commitID)
	// Always set default timeout on HTTP client.
	http.DefaultClient.Timeout = 1500 * time.Millisecond

	tmpLogger := server.NewJSONLogger(os.Stdout, zapcore.InfoLevel, server.JSONFormat)

	if len(os.Args) > 1 {
		switch os.Args[1] {
		case "--version":
			fmt.Println(semver)
			return
		case "migrate":
			migrate.Parse(os.Args[2:], tmpLogger)
		case "check":
			// Parse any command line args to look up runtime path.
			// Use full config structure even if not all of its options are available in this command.
			config := server.NewConfig(tmpLogger)
			var runtimePath string
			flags := flag.NewFlagSet("check", flag.ExitOnError)
			flags.StringVar(&runtimePath, "runtime.path", filepath.Join(config.GetDataDir(), "modules"), "Path for the server to scan for Lua and Go library files.")
			if err := flags.Parse(os.Args[2:]); err != nil {
				tmpLogger.Fatal("Could not parse check flags.")
			}
			config.GetRuntime().Path = runtimePath

			if err := server.CheckRuntime(tmpLogger, config); err != nil {
				// Errors are already logged in the function above.
				os.Exit(1)
			}
			return
		}
	}

	config := server.ParseArgs(tmpLogger, os.Args)
	logger, startupLogger := server.SetupLogging(tmpLogger, config)
	configWarnings := server.CheckConfig(logger, config)

	startupLogger.Info("Nakama starting")
	startupLogger.Info("Node", zap.String("name", config.GetName()), zap.String("version", semver), zap.String("runtime", runtime.Version()), zap.Int("cpu", runtime.NumCPU()), zap.Int("proc", runtime.GOMAXPROCS(0)))
	startupLogger.Info("Data directory", zap.String("path", config.GetDataDir()))

	// Initialize the global random obj with customs seed.
	var seed int64
	err := binary.Read(cryptorand.Reader, binary.BigEndian, &seed)
	if err != nil {
		startupLogger.Warn("Failed to get strongly random seed, fallback to a less random one.", zap.Error(err))
		seed = time.Now().UnixNano()
	}
	rand.Seed(seed)

	redactedAddresses := make([]string, 0, 1)
	for _, address := range config.GetDatabase().Addresses {
		rawURL := fmt.Sprintf("postgres://%s", address)
		parsedURL, err := url.Parse(rawURL)
		if err != nil {
			logger.Fatal("Bad connection URL", zap.Error(err))
		}
		redactedAddresses = append(redactedAddresses, strings.TrimPrefix(parsedURL.Redacted(), "postgres://"))
	}
	startupLogger.Info("Database connections", zap.Strings("dsns", redactedAddresses))

	// Global server context.
	ctx, ctxCancelFn := context.WithCancel(context.Background())

	db, dbVersion := server.DbConnect(ctx, startupLogger, config)
	startupLogger.Info("Database information", zap.String("version", dbVersion))

	// Check migration status and fail fast if the schema has diverged.
	migrate.StartupCheck(startupLogger, db)

	// Access to social provider integrations.
	socialClient := social.NewClient(logger, 5*time.Second)

	// Start up server components.
	cookie := newOrLoadCookie(config)
	metrics := server.NewLocalMetrics(logger, startupLogger, db, config)
	sessionRegistry := server.NewLocalSessionRegistry(metrics)
	sessionCache := server.NewLocalSessionCache(config)
	statusRegistry := server.NewStatusRegistry(logger, config, sessionRegistry, jsonpbMarshaler)
	tracker := server.StartLocalTracker(logger, config, sessionRegistry, statusRegistry, metrics, jsonpbMarshaler)
	router := server.NewLocalMessageRouter(sessionRegistry, tracker, jsonpbMarshaler)
	leaderboardCache := server.NewLocalLeaderboardCache(logger, startupLogger, db)
	leaderboardRankCache := server.NewLocalLeaderboardRankCache(startupLogger, db, config.GetLeaderboard(), leaderboardCache)
	leaderboardScheduler := server.NewLocalLeaderboardScheduler(logger, db, config, leaderboardCache, leaderboardRankCache)
	matchRegistry := server.NewLocalMatchRegistry(logger, startupLogger, config, sessionRegistry, tracker, router, metrics, config.GetName())
	tracker.SetMatchJoinListener(matchRegistry.Join)
	tracker.SetMatchLeaveListener(matchRegistry.Leave)
	streamManager := server.NewLocalStreamManager(config, sessionRegistry, tracker)
	runtime, runtimeInfo, err := server.NewRuntime(ctx, logger, startupLogger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, sessionCache, matchRegistry, tracker, metrics, streamManager, router)
	if err != nil {
		startupLogger.Fatal("Failed initializing runtime modules", zap.Error(err))
	}
	matchmaker := server.NewLocalMatchmaker(logger, startupLogger, config, router, runtime)
	partyRegistry := server.NewLocalPartyRegistry(logger, matchmaker, tracker, streamManager, router, config.GetName())
	tracker.SetPartyJoinListener(partyRegistry.Join)
	tracker.SetPartyLeaveListener(partyRegistry.Leave)

	leaderboardScheduler.Start(runtime)

	pipeline := server.NewPipeline(logger, config, db, jsonpbMarshaler, jsonpbUnmarshaler, sessionRegistry, statusRegistry, matchRegistry, partyRegistry, matchmaker, tracker, router, runtime)
	statusHandler := server.NewLocalStatusHandler(logger, sessionRegistry, matchRegistry, tracker, metrics, config.GetName())

	apiServer := server.StartApiServer(logger, startupLogger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, sessionRegistry, sessionCache, statusRegistry, matchRegistry, matchmaker, tracker, router, metrics, pipeline, runtime)
	consoleServer := server.StartConsoleServer(logger, startupLogger, db, config, tracker, router, sessionCache, statusHandler, runtimeInfo, matchRegistry, configWarnings, semver, leaderboardCache, leaderboardRankCache, apiServer, cookie)

	gaenabled := len(os.Getenv("NAKAMA_TELEMETRY")) < 1
	const gacode = "UA-89792135-1"
	var telemetryClient *http.Client
	if gaenabled {
		telemetryClient = &http.Client{
			Timeout: 1500 * time.Millisecond,
		}
		runTelemetry(telemetryClient, gacode, cookie)
	}

	// Respect OS stop signals.
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

	startupLogger.Info("Startup done")

	// Wait for a termination signal.
	<-c

	graceSeconds := config.GetShutdownGraceSec()

	// If a shutdown grace period is allowed, prepare a timer.
	var timer *time.Timer
	timerCh := make(<-chan time.Time, 1)
	if graceSeconds != 0 {
		timer = time.NewTimer(time.Duration(graceSeconds) * time.Second)
		timerCh = timer.C
		startupLogger.Info("Shutdown started - use CTRL^C to force stop server", zap.Int("grace_period_sec", graceSeconds))
	} else {
		// No grace period.
		startupLogger.Info("Shutdown started")
	}

	// Stop any running authoritative matches and do not accept any new ones.
	select {
	case <-matchRegistry.Stop(graceSeconds):
		// Graceful shutdown has completed.
		startupLogger.Info("All authoritative matches stopped")
	case <-timerCh:
		// Timer has expired, terminate matches immediately.
		startupLogger.Info("Shutdown grace period expired")
		<-matchRegistry.Stop(0)
	case <-c:
		// A second interrupt has been received.
		startupLogger.Info("Skipping graceful shutdown")
		<-matchRegistry.Stop(0)
	}
	if timer != nil {
		timer.Stop()
	}

	// Signal cancellation to the global runtime context.
	ctxCancelFn()

	// Gracefully stop remaining server components.
	apiServer.Stop()
	consoleServer.Stop()
	matchmaker.Stop()
	leaderboardScheduler.Stop()
	tracker.Stop()
	statusRegistry.Stop()
	sessionCache.Stop()
	sessionRegistry.Stop()
	metrics.Stop(logger)

	if gaenabled {
		_ = ga.SendSessionStop(telemetryClient, gacode, cookie)
	}

	startupLogger.Info("Shutdown complete")

	os.Exit(0)
}

// Help improve Nakama by sending anonymous usage statistics.
//
// You can disable the telemetry completely before server start by setting the
// environment variable "NAKAMA_TELEMETRY" - i.e. NAKAMA_TELEMETRY=0 nakama
//
// These properties are collected:
// * A unique UUID v4 random identifier which is generated.
// * Version of Nakama being used which includes build metadata.
// * Amount of time the server ran for.
//
// This information is sent via Google Analytics which allows the Nakama team to
// analyze usage patterns and errors in order to help improve the server.
func runTelemetry(httpc *http.Client, gacode string, cookie string) {
	if ga.SendSessionStart(httpc, gacode, cookie) != nil {
		return
	}
	if ga.SendEvent(httpc, gacode, cookie, &ga.Event{Ec: "version", Ea: fmt.Sprintf("%s+%s", version, commitID)}) != nil {
		return
	}
	_ = ga.SendEvent(httpc, gacode, cookie, &ga.Event{Ec: "variant", Ea: "nakama"})
}

func newOrLoadCookie(config server.Config) string {
	filePath := filepath.FromSlash(config.GetDataDir() + "/" + cookieFilename)
	b, err := ioutil.ReadFile(filePath)
	cookie := uuid.FromBytesOrNil(b)
	if err != nil || cookie == uuid.Nil {
		cookie = uuid.Must(uuid.NewV4())
		_ = ioutil.WriteFile(filePath, cookie.Bytes(), 0644)
	}
	return cookie.String()
}
<|endoftext|>


<commit_before>package main

import (
	_ "expvar"
	"net/http"
	"os"

	"github.com/bmizerany/pat"
	"github.com/codegangsta/negroni"
	"github.com/meatballhat/negroni-logrus"
	"github.com/unrolled/render"
)

func main() {
	m := pat.New()
	n := negroni.New(negroni.NewRecovery(), negroni.NewStatic(http.Dir("assets")))
	l := negronilogrus.NewMiddleware()
	o := render.New(render.Options{
		Layout: "layout",
	})

	n.Use(l)
	n.UseHandler(m)

	m.Get("/debug/vars", http.DefaultServeMux)

	m.Get("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		o.HTML(w, http.StatusOK, "index", "world")
	}))

	var addr string

	if os.Getenv("TIMEOFF_ADDR") == "" {
		addr = ":3000"
	} else {
		addr = os.Getenv("TIMEOFF_ADDR")
	}

	l.Logger.Infof("Listening on %s", addr)
	if os.Getenv("TIMEOFF_TLS_CERT") == "" && os.Getenv("TIMEOFF_TLS_KEY") == "" {
		l.Logger.Warningln(noTLSCertificateError)
		l.Logger.Fatal(http.ListenAndServe(addr, n))
	} else {
		l.Logger.Infoln("Listening with TLS")
		l.Logger.Fatal(http.ListenAndServeTLS(addr, os.Getenv("TIMEOFF_TLS_CERT"), os.Getenv("TIMEOFF_TLS_KEY"), n))
	}
}

const noTLSCertificateError = "No TLS certficiate supplied. Consider setting TIMEOFF_TLS_CERT " +
	"and TIMEOFF_TLS_KEY environment variables to enable TLS."
<commit_msg>Split initialisation into init() and main() funcs<commit_after>package main

import (
	_ "expvar"
	"net/http"
	"os"

	"github.com/bmizerany/pat"
	"github.com/codegangsta/negroni"
	"github.com/meatballhat/negroni-logrus"
	"github.com/unrolled/render"
)

var (
	addr string
	m    *pat.PatternServeMux
	n    *negroni.Negroni
	l    *negronilogrus.Middleware
	o    *render.Render
)

func init() {
	m = pat.New()
	n = negroni.New(negroni.NewRecovery(), negroni.NewStatic(http.Dir("assets")))
	l = negronilogrus.NewMiddleware()
	o = render.New(render.Options{
		Layout: "layout",
	})

	n.Use(l)
	n.UseHandler(m)

	m.Get("/debug/vars", http.DefaultServeMux)

	m.Get("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		o.HTML(w, http.StatusOK, "index", "world")
	}))

	if os.Getenv("TIMEOFF_ADDR") == "" {
		addr = ":3000"
	} else {
		addr = os.Getenv("TIMEOFF_ADDR")
	}
}

func main() {
	l.Logger.Infof("Listening on %s", addr)
	if os.Getenv("TIMEOFF_TLS_CERT") == "" && os.Getenv("TIMEOFF_TLS_KEY") == "" {
		l.Logger.Warningln(noTLSCertificateError)
		l.Logger.Fatal(http.ListenAndServe(addr, n))
	} else {
		l.Logger.Infoln("Listening with TLS")
		l.Logger.Fatal(http.ListenAndServeTLS(addr, os.Getenv("TIMEOFF_TLS_CERT"), os.Getenv("TIMEOFF_TLS_KEY"), n))
	}
}

const noTLSCertificateError = "No TLS certficiate supplied. Consider setting TIMEOFF_TLS_CERT " +
	"and TIMEOFF_TLS_KEY environment variables to enable TLS."
<|endoftext|>