<commit_before>// 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 (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/garyburd/redigo/redis"
	"github.com/lancetw/hcfd-forecast/db"
	"github.com/lancetw/hcfd-forecast/rain"
	"github.com/line/line-bot-sdk-go/linebot"
)

const timeZone = "Asia/Taipei"

var bot *linebot.Client

func main() {
	strID := os.Getenv("ChannelID")
	numID, err := strconv.ParseInt(strID, 10, 64)
	if err != nil {
		log.Fatal("Wrong environment setting about ChannelID")
	}
	bot, err = linebot.NewClient(numID, os.Getenv("ChannelSecret"), os.Getenv("MID"))
	if err != nil {
		log.Println("Bot:", bot, " err:", err)
	}

	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	received, err := bot.ParseRequest(r)
	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	for _, result := range received.Results {
		content := result.Content()
		if content != nil && content.IsOperation && content.OpType == linebot.OpTypeAddedAsFriend {
			op, err := content.OperationContent()
			if err != nil {
				log.Println(err)
				return
			}
			from := op.Params[0]

			user, err := bot.GetUserProfile([]string{from})
			if err != nil {
				log.Println(err)
				return
			}
			_, err = bot.SendText([]string{from}, user.Contacts[0].DisplayName+" 您好，目前可用指令為：「加入」「退出」「雨量」「警報」「貓圖」「狀態」「時間」")
			if err != nil {
				log.Println(err)
			}
		}

		if content != nil && content.IsMessage && content.ContentType == linebot.ContentTypeText {
			user, err := bot.GetUserProfile([]string{content.From})
			if err != nil {
				return
			}
			text, err := content.TextContent()
			if err != nil {
				log.Println(err)
			}
			cmd := strings.Fields(text.Text)

			switch cmd[0] {
			case "加入":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				status, addErr := c.Do("SADD", "user", content.From)
				if addErr != nil {
					log.Println("SADD to redis error", addErr, status)
				} else {
					_, err = bot.SendText([]string{content.From}, user.Contacts[0].DisplayName+" 您好，已將您加入傳送對象，未來將會傳送天氣警報資訊給您 ^＿^ ")
					if err != nil {
						log.Println(err)
					}
				}
				defer c.Close()

			case "退出":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				status, setErr := c.Do("SREM", "user", content.From)
				if setErr != nil {
					log.Println("DEL to redis error", setErr, status)
				} else {
					_, err = bot.SendText([]string{content.From}, user.Contacts[0].DisplayName+" 掰掰 Q＿Q")
					if err != nil {
						log.Println(err)
					}
				}
				defer c.Close()

			case "服務":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				count, countErr := redis.Int(c.Do("SCARD", "user"))
				if countErr != nil {
					_, err = bot.SendText([]string{content.From}, fmt.Sprintf("目前有 %d 人加入自動警訊服務。", count))
					if err != nil {
						log.Println(err)
					}
				}
				defer c.Close()

			case "狀態":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				status, getErr := redis.Int(c.Do("SISMEMBER", "user", content.From))
				if getErr != nil || status == 0 {
					_, err = bot.SendText([]string{content.From}, "目前沒有登記您的編號喔！")
					if err != nil {
						log.Println(err)
					}
				} else {
					_, err = bot.SendText([]string{content.From}, "您已經是傳送對象 :D")
					if err != nil {
						log.Println(err)
					}
				}
				defer c.Close()

			case "時間":
				local := time.Now()
				location, timezoneErr := time.LoadLocation(timeZone)
				if timezoneErr == nil {
					local = local.In(location)
				}
				_, err = bot.SendText([]string{content.From}, local.Format("2006/01/02 15:04:05"))
				if err != nil {
					log.Println(err)
				}

			case "雨量":
				target := []string{"新竹市"}
				if len(cmd) > 1 {
					target[0] = cmd[1]
				}

				msgs, _ := rain.GetRainingInfo(target, true)
				if len(msgs) == 0 {
					_, err = bot.SendText([]string{content.From}, "目前沒有雨量資訊！")
					if err != nil {
						log.Println(err)
					}
				} else {
					for _, msg := range msgs {
						_, err = bot.SendText([]string{content.From}, msg)
						if err != nil {
							log.Println(err)
						}
					}
				}

			case "警報":
				msgs, _ := rain.GetWarningInfo(nil)
				for _, msg := range msgs {
					_, err = bot.SendText([]string{content.From}, msg)
					if err != nil {
						log.Println(err)
					}
				}

			case "重開":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				status0, clearErr0 := c.Do("DEL", "token0")
				if clearErr0 != nil {
					log.Println("DEL to redis error", clearErr0, status0)
				}
				status1, clearErr1 := c.Do("DEL", "token1")
				if clearErr1 != nil {
					log.Println("DEL to redis error", clearErr1, status1)
				}

				_, err = bot.SendText([]string{content.From}, "已重開")
				if err != nil {
					log.Println(err)
				}

			case "貓圖":
				type Cat struct {
					File string `json:"file"`
				}
				cat := new(Cat)
				getJSON("http://random.cat/meow", &cat)
				if cat.File != "" {
					_, err = bot.SendImage([]string{content.From}, cat.File, cat.File)
					if err != nil {
						log.Println(err)
					}
				}

			case "正妹":
				type Beauty struct {
					Count   int      `json:"count"`
					PhotoID []string `json:"photoId"`
				}
				beauty := new(Beauty)
				getJSON("", &beauty)
				if beauty.PhotoID[0] != "" {
					_, err = bot.SendImage([]string{content.From}, beauty.PhotoID[0], beauty.PhotoID[0])
					if err != nil {
						log.Println(err)
					}
				}

			default:
				_, err = bot.SendText([]string{content.From}, "指令錯誤，請重試")
				if err != nil {
					log.Println(err)
				}

			}
		}
	}
}

// getJSON func
func getJSON(url string, target interface{}) error {
	r, err := http.Get(url)
	if err != nil {
		return err
	}
	defer r.Body.Close()

	return json.NewDecoder(r.Body).Decode(target)
}
<commit_msg>show error<commit_after>// 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 (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/garyburd/redigo/redis"
	"github.com/lancetw/hcfd-forecast/db"
	"github.com/lancetw/hcfd-forecast/rain"
	"github.com/line/line-bot-sdk-go/linebot"
)

const timeZone = "Asia/Taipei"

var bot *linebot.Client

func main() {
	strID := os.Getenv("ChannelID")
	numID, err := strconv.ParseInt(strID, 10, 64)
	if err != nil {
		log.Fatal("Wrong environment setting about ChannelID")
	}
	bot, err = linebot.NewClient(numID, os.Getenv("ChannelSecret"), os.Getenv("MID"))
	if err != nil {
		log.Println("Bot:", bot, " err:", err)
	}

	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	received, err := bot.ParseRequest(r)
	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	for _, result := range received.Results {
		content := result.Content()
		if content != nil && content.IsOperation && content.OpType == linebot.OpTypeAddedAsFriend {
			op, err := content.OperationContent()
			if err != nil {
				log.Println(err)
				return
			}
			from := op.Params[0]

			user, err := bot.GetUserProfile([]string{from})
			if err != nil {
				log.Println(err)
				return
			}
			_, err = bot.SendText([]string{from}, user.Contacts[0].DisplayName+" 您好，目前可用指令為：「加入」「退出」「雨量」「警報」「貓圖」「狀態」「時間」")
			if err != nil {
				log.Println(err)
			}
		}

		if content != nil && content.IsMessage && content.ContentType == linebot.ContentTypeText {
			user, err := bot.GetUserProfile([]string{content.From})
			if err != nil {
				return
			}
			text, err := content.TextContent()
			if err != nil {
				log.Println(err)
			}
			cmd := strings.Fields(text.Text)

			switch cmd[0] {
			case "加入":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				status, addErr := c.Do("SADD", "user", content.From)
				if addErr != nil {
					log.Println("SADD to redis error", addErr, status)
				} else {
					_, err = bot.SendText([]string{content.From}, user.Contacts[0].DisplayName+" 您好，已將您加入傳送對象，未來將會傳送天氣警報資訊給您 ^＿^ ")
					if err != nil {
						log.Println(err)
					}
				}
				defer c.Close()

			case "退出":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				status, setErr := c.Do("SREM", "user", content.From)
				if setErr != nil {
					log.Println("DEL to redis error", setErr, status)
				} else {
					_, err = bot.SendText([]string{content.From}, user.Contacts[0].DisplayName+" 掰掰 Q＿Q")
					if err != nil {
						log.Println(err)
					}
				}
				defer c.Close()

			case "服務":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				count, countErr := redis.Int(c.Do("SCARD", "user"))
				if countErr != nil {
					_, err = bot.SendText([]string{content.From}, fmt.Sprintf("目前有 %d 人加入自動警訊服務。", count))
					if err != nil {
						log.Println(err)
					}
				} else {
					log.Println(countErr)
				}

				defer c.Close()

			case "狀態":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				status, getErr := redis.Int(c.Do("SISMEMBER", "user", content.From))
				if getErr != nil || status == 0 {
					_, err = bot.SendText([]string{content.From}, "目前沒有登記您的編號喔！")
					if err != nil {
						log.Println(err)
					}
				} else {
					_, err = bot.SendText([]string{content.From}, "您已經是傳送對象 :D")
					if err != nil {
						log.Println(err)
					}
				}
				defer c.Close()

			case "時間":
				local := time.Now()
				location, timezoneErr := time.LoadLocation(timeZone)
				if timezoneErr == nil {
					local = local.In(location)
				}
				_, err = bot.SendText([]string{content.From}, local.Format("2006/01/02 15:04:05"))
				if err != nil {
					log.Println(err)
				}

			case "雨量":
				target := []string{"新竹市"}
				if len(cmd) > 1 {
					target[0] = cmd[1]
				}

				msgs, _ := rain.GetRainingInfo(target, true)
				if len(msgs) == 0 {
					_, err = bot.SendText([]string{content.From}, "目前沒有雨量資訊！")
					if err != nil {
						log.Println(err)
					}
				} else {
					for _, msg := range msgs {
						_, err = bot.SendText([]string{content.From}, msg)
						if err != nil {
							log.Println(err)
						}
					}
				}

			case "警報":
				msgs, _ := rain.GetWarningInfo(nil)
				for _, msg := range msgs {
					_, err = bot.SendText([]string{content.From}, msg)
					if err != nil {
						log.Println(err)
					}
				}

			case "重開":
				c := db.Connect(os.Getenv("REDISTOGO_URL"))
				status0, clearErr0 := c.Do("DEL", "token0")
				if clearErr0 != nil {
					log.Println("DEL to redis error", clearErr0, status0)
				}
				status1, clearErr1 := c.Do("DEL", "token1")
				if clearErr1 != nil {
					log.Println("DEL to redis error", clearErr1, status1)
				}

				_, err = bot.SendText([]string{content.From}, "已重開")
				if err != nil {
					log.Println(err)
				}

			case "貓圖":
				type Cat struct {
					File string `json:"file"`
				}
				cat := new(Cat)
				getJSON("http://random.cat/meow", &cat)
				if cat.File != "" {
					_, err = bot.SendImage([]string{content.From}, cat.File, cat.File)
					if err != nil {
						log.Println(err)
					}
				}

			case "正妹":
				type Beauty struct {
					Count   int      `json:"count"`
					PhotoID []string `json:"photoId"`
				}
				beauty := new(Beauty)
				getJSON("", &beauty)
				if beauty.PhotoID[0] != "" {
					_, err = bot.SendImage([]string{content.From}, beauty.PhotoID[0], beauty.PhotoID[0])
					if err != nil {
						log.Println(err)
					}
				}

			default:
				_, err = bot.SendText([]string{content.From}, "指令錯誤，請重試")
				if err != nil {
					log.Println(err)
				}

			}
		}
	}
}

// getJSON func
func getJSON(url string, target interface{}) error {
	r, err := http.Get(url)
	if err != nil {
		return err
	}
	defer r.Body.Close()

	return json.NewDecoder(r.Body).Decode(target)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/codegangsta/cli"
)

func main() {
	handleSigint()
}

func handleSigint() {
	var sts int
	defer finalize(sts)

	chSig := make(chan os.Signal)
	signal.Notify(chSig, os.Interrupt, syscall.SIGTERM)

	chSts := make(chan int)
	go run(chSts)

	select {
	case <-chSig:
		fmt.Fprintln(os.Stderr, "CTRL-C; exiting")
		sts = 1
	case sts = <-chSts:
	}
}

func run(chSts chan int) {
	var sts int

	app := cli.NewApp()
	app.Name = "gat"
	app.Version = VERSION
	app.Usage = "Cat to anywhere"
	app.Author = "@goldeneggg"
	app.Email = "jpshadowapps@gmail.com"
	app.Flags = globalFlags
	app.Commands = commands

	if err := app.Run(os.Args); err != nil {
		fmt.Fprintln(os.Stderr, err)
		sts = 1
	}

	chSts <- sts
}

func finalize(sts int) {
	os.Exit(sts)
}
<commit_msg>fix description<commit_after>package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/codegangsta/cli"
)

func main() {
	handleSigint()
}

func handleSigint() {
	var sts int
	defer finalize(sts)

	chSig := make(chan os.Signal)
	signal.Notify(chSig, os.Interrupt, syscall.SIGTERM)

	chSts := make(chan int)
	go run(chSts)

	select {
	case <-chSig:
		fmt.Fprintln(os.Stderr, "CTRL-C; exiting")
		sts = 1
	case sts = <-chSts:
	}
}

func run(chSts chan int) {
	var sts int

	app := cli.NewApp()
	app.Name = "gat"
	app.Version = VERSION
	app.Usage = "Utility tool of concatnating and printing file to various services"
	app.Author = "@goldeneggg"
	app.Email = "jpshadowapps@gmail.com"
	app.Flags = globalFlags
	app.Commands = commands

	if err := app.Run(os.Args); err != nil {
		fmt.Fprintln(os.Stderr, err)
		sts = 1
	}

	chSts <- sts
}

func finalize(sts int) {
	os.Exit(sts)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/fabioxgn/go-bot/commands"
	"github.com/thoj/go-ircevent"
	"log"
	"os"
)

const (
	CONFIG_FILE = "config.json"
)

var (
	irccon *irc.Connection
	config = &Config{}
)

func printAvailableCommands(channel string) {
	irccon.Privmsg(channel, "Available Commands:")
	cmds := ""
	for k, _ := range commands.Commands {
		cmds += k + ", "
	}
	irccon.Privmsg(channel, cmds[:len(cmds)-2])
}

func handleCmd(cmd *Command, channel string) {
	irc_cmd := commands.Commands[cmd.Command]
	if irc_cmd == nil {
		irccon.Privmsg(channel, fmt.Sprintf("Command %v not found.", cmd.Command))
		printAvailableCommands(channel)
	} else {
		log.Printf("cmd %v args %v", cmd.Command, cmd.Args)
		irccon.Privmsg(channel, irc_cmd(cmd.Args))
	}
}

func onPRIVMSG(e *irc.Event) {
	channel := e.Arguments[0]
	args := ""
	if channel == config.Nick {
		channel = e.Nick
		args = e.Message
	} else {
		args = StrAfter(e.Message, config.Cmd)
	}

	cmd, err := Parse(args)
	if err != nil {
		irccon.Privmsg(channel, err.Error())
		return
	}

	handleCmd(cmd, channel)
}

func connect() {
	irccon = irc.IRC(config.User, config.Nick)
	irccon.UseTLS = config.UseTLS
	err := irccon.Connect(config.Server)
	if err != nil {
		log.Fatal(err)
	}
}

func configureEvents() {
	irccon.AddCallback("001", func(e *irc.Event) {
		irccon.Join(config.Channels[0])
	})

	irccon.AddCallback("366", func(e *irc.Event) {
		irccon.Privmsg(config.Channels[0], "Hi there.\n")
	})

	irccon.AddCallback("PRIVMSG", onPRIVMSG)
}

func readConfig() {
	configFile, err := os.Open(CONFIG_FILE)
	if err != nil {
		panic(err)
	}
	config.Read(configFile)
	fmt.Printf("%v", config)
}

func main() {
	readConfig()
	connect()
	configureEvents()
	irccon.Loop()
}
<commit_msg>converted constant from all caps<commit_after>package main

import (
	"fmt"
	"github.com/fabioxgn/go-bot/commands"
	"github.com/thoj/go-ircevent"
	"log"
	"os"
)

const (
	configFile = "config.json"
)

var (
	irccon *irc.Connection
	config = &Config{}
)

func printAvailableCommands(channel string) {
	irccon.Privmsg(channel, "Available Commands:")
	cmds := ""
	for k, _ := range commands.Commands {
		cmds += k + ", "
	}
	irccon.Privmsg(channel, cmds[:len(cmds)-2])
}

func handleCmd(cmd *Command, channel string) {
	irc_cmd := commands.Commands[cmd.Command]
	if irc_cmd == nil {
		irccon.Privmsg(channel, fmt.Sprintf("Command %v not found.", cmd.Command))
		printAvailableCommands(channel)
	} else {
		log.Printf("cmd %v args %v", cmd.Command, cmd.Args)
		irccon.Privmsg(channel, irc_cmd(cmd.Args))
	}
}

func onPRIVMSG(e *irc.Event) {
	channel := e.Arguments[0]
	args := ""
	if channel == config.Nick {
		channel = e.Nick
		args = e.Message
	} else {
		args = StrAfter(e.Message, config.Cmd)
	}

	cmd, err := Parse(args)
	if err != nil {
		irccon.Privmsg(channel, err.Error())
		return
	}

	handleCmd(cmd, channel)
}

func connect() {
	irccon = irc.IRC(config.User, config.Nick)
	irccon.UseTLS = config.UseTLS
	err := irccon.Connect(config.Server)
	if err != nil {
		log.Fatal(err)
	}
}

func configureEvents() {
	irccon.AddCallback("001", func(e *irc.Event) {
		irccon.Join(config.Channels[0])
	})

	irccon.AddCallback("366", func(e *irc.Event) {
		irccon.Privmsg(config.Channels[0], "Hi there.\n")
	})

	irccon.AddCallback("PRIVMSG", onPRIVMSG)
}

func readConfig() {
	file, err := os.Open(configFile)
	if err != nil {
		panic(err)
	}
	config.Read(file)
	fmt.Printf("%v", config)
}

func main() {
	readConfig()
	connect()
	configureEvents()
	irccon.Loop()
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"
)

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

	interactive := flag.Bool("i", false, "interactive mode")
	flag.Parse()

	if *interactive {
		repl()
		return
	}

	if flag.NArg() != 1 {
		fmt.Fprintln(os.Stderr, "Usage: arithmetic <program>")
		os.Exit(1)
	}

	result, err := Evaluate(strings.NewReader(flag.Arg(0)))
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	fmt.Println(result)
}

func repl() {
replloop:
	for {
		fmt.Print("> ")
		byteBuffer := []byte{0x00}
		progBuffer := new(bytes.Buffer)

	readloop:
		for {
			_, err := os.Stdin.Read(byteBuffer)
			if err != nil {
				fmt.Println()
				break replloop
			}
			if byteBuffer[0] == '\n' {
				break readloop
			}
			progBuffer.WriteByte(byteBuffer[0])
		}

		if progBuffer.String() == "exit" {
			break replloop
		}

		result, err := Evaluate(progBuffer)
		if err != nil {
			fmt.Println(err)
		} else {
			fmt.Println(result)
		}
	}
}
<commit_msg>Added -e option<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"
)

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

	evalArg := flag.String("e", "", "evaluate argument")
	interactive := flag.Bool("i", false, "interactive mode")
	flag.Parse()

	if *interactive {
		repl()
		return
	}

	if *evalArg != "" {
		result, err := Evaluate(strings.NewReader(*evalArg))
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		fmt.Println(result)
		return
	}

	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}
}

func repl() {
replloop:
	for {
		fmt.Print("> ")
		byteBuffer := []byte{0x00}
		progBuffer := new(bytes.Buffer)

	readloop:
		for {
			_, err := os.Stdin.Read(byteBuffer)
			if err != nil {
				fmt.Println()
				break replloop
			}
			if byteBuffer[0] == '\n' {
				break readloop
			}
			progBuffer.WriteByte(byteBuffer[0])
		}

		if progBuffer.String() == "exit" {
			break replloop
		}

		result, err := Evaluate(progBuffer)
		if err != nil {
			fmt.Println(err)
		} else {
			fmt.Println(result)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/codegangsta/cli"
)

const (
	ComposerRepo  = ".composer-repo"
	Manifest      = "manifest.json"
	ComposeFile   = "docker-compose.yml"
	defaultBranch = "master"
	defaultRemote = "origin/master"
)

type Repo struct {
	Path string `json:"path"`
	URL  string `json:"url"`
}

func (r Repo) Get() error {
	if r.exists() {
		fetch(r.Path)
	} else {
		clone(r.URL, r.Path)
	}
	return nil
}

func (r Repo) exists() bool {
	f, err := os.Open(r.Path)
	if err != nil {
		return false
	}
	defer f.Close()

	_, err = f.Stat()
	if err != nil {
		return false
	}

	return true
}

var repos []Repo

func Git(params ...string) *exec.Cmd {
	cmd := exec.Command("git", params...)
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	return cmd
}

func GitInDir(dir string, params ...string) *exec.Cmd {
	cmd := Git(params...)
	cmd.Dir = dir
	return cmd
}

func main() {
	log.SetFlags(0)
	log.SetPrefix("===> ")
	app := cli.NewApp()
	app.Name = "composer-repo"
	app.Usage = "sync multiple git repos"
	app.Version = "0.0.1"
	app.Commands = []cli.Command{
		{
			Name:        "init",
			Aliases:     []string{"i"},
			Usage:       "initialize repo with manifest.json and docker-compose.yml",
			Description: "",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "repo,r",
					Usage: "path to manifest repo",
				},
			},
			Action: initCmd,
		},
		{
			Name:        "sync",
			Aliases:     []string{"s"},
			Usage:       "syncronize repos from manifest.json",
			Description: "",
			Action:      syncCmd,
		},
		{
			Name:        "status",
			Aliases:     []string{"st"},
			Usage:       "show status across all repos",
			Description: "",
			Action:      statusCmd,
		},
	}

	app.Run(os.Args)
}

func statusCmd(c *cli.Context) {
	// TODO: show git status with appropriate format from all repos at once
}

func initCmd(c *cli.Context) {
	repoURL := c.String("repo")
	if repoURL == "" {
		log.Fatal("please provide --repo, -r param")
	}

	clone(repoURL, ComposerRepo)

	if err := os.Symlink(filepath.Join(ComposerRepo, ComposeFile), ComposeFile); err != nil {
		log.Fatal(err)
	}
}

func syncCmd(c *cli.Context) {
	f, err := os.Open(filepath.Join(ComposerRepo, Manifest))

	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	data, _ := ioutil.ReadAll(f)

	if err := json.Unmarshal(data, &repos); err != nil {
		log.Fatal(err)
	}

	for i, rep := range repos {
		log.Printf("syncing %s (%d/%d)\n", rep.Path, i+1, len(repos))
		rep.Get()
	}
}

func clone(src, dst string) {
	if err := Git("clone", src, dst).Run(); err != nil {
		log.Fatal(err)
	}
}

func fetch(dir string) {
	if err := GitInDir(dir, "fetch", "origin").Run(); err != nil {
		log.Fatal(err)
	}

	var b bytes.Buffer

	cmd := GitInDir(dir, "rev-parse", "--abbrev-ref", "HEAD")
	cmd.Stdout = &b
	err := cmd.Run()
	if err != nil {
		log.Fatal(err)
	}

	br := b.Bytes()
	curBranch := string(bytes.TrimSpace(br))

	if curBranch != defaultBranch {
		log.Printf("found that current branch is %q, switching to %q", curBranch, defaultBranch)
		if err := GitInDir(dir, "checkout", defaultBranch).Run(); err != nil {
			log.Fatal(err)
		}
	}

	args := []string{"reset", "--hard", defaultRemote}
	if err := GitInDir(dir, args...).Run(); err != nil {
		log.Fatal(err)
	}

	if curBranch != defaultBranch {
		log.Printf("switch back to %q branch after reseting %q to %q", curBranch, defaultBranch, defaultRemote)
		if err := GitInDir(dir, "checkout", curBranch).Run(); err != nil {
			log.Fatal(err)
		}
	}
}
<commit_msg>Sync .compose-repo every time<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/codegangsta/cli"
)

const (
	ComposerRepo  = ".compose-repo"
	Manifest      = "manifest.json"
	ComposeFile   = "docker-compose.yml"
	defaultBranch = "master"
	defaultRemote = "origin/master"
)

type Repo struct {
	Path string `json:"path"`
	URL  string `json:"url"`
}

func (r Repo) Get() error {
	if r.exists() {
		fetch(r.Path)
	} else {
		clone(r.URL, r.Path)
	}
	return nil
}

func (r Repo) exists() bool {
	f, err := os.Open(r.Path)
	if err != nil {
		return false
	}
	defer f.Close()

	_, err = f.Stat()
	if err != nil {
		return false
	}

	return true
}

var repos []Repo

func Git(params ...string) *exec.Cmd {
	cmd := exec.Command("git", params...)
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	return cmd
}

func GitInDir(dir string, params ...string) *exec.Cmd {
	cmd := Git(params...)
	cmd.Dir = dir
	return cmd
}

func main() {
	log.SetFlags(0)
	log.SetPrefix("===> ")
	app := cli.NewApp()
	app.Name = "composer-repo"
	app.Usage = "sync multiple git repos"
	app.Version = "0.0.1"
	app.Commands = []cli.Command{
		{
			Name:        "init",
			Aliases:     []string{"i"},
			Usage:       "initialize repo with manifest.json and docker-compose.yml",
			Description: "",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "repo,r",
					Usage: "path to manifest repo",
				},
			},
			Action: initCmd,
		},
		{
			Name:        "sync",
			Aliases:     []string{"s"},
			Usage:       "syncronize repos from manifest.json",
			Description: "",
			Action:      syncCmd,
		},
		{
			Name:        "status",
			Aliases:     []string{"st"},
			Usage:       "show status across all repos",
			Description: "",
			Action:      statusCmd,
		},
	}

	app.Run(os.Args)
}

func statusCmd(c *cli.Context) {
	// TODO: show git status with appropriate format from all repos at once
	// TODO: check if dir is not in manifest
}

func initCmd(c *cli.Context) {
	repoURL := c.String("repo")
	if repoURL == "" {
		log.Fatal("please provide --repo, -r param")
	}

	clone(repoURL, ComposerRepo)

	if err := os.Symlink(filepath.Join(ComposerRepo, ComposeFile), ComposeFile); err != nil {
		log.Fatal(err)
	}
}

func syncCmd(c *cli.Context) {
	fetch(ComposerRepo)

	f, err := os.Open(filepath.Join(ComposerRepo, Manifest))

	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	data, _ := ioutil.ReadAll(f)

	if err := json.Unmarshal(data, &repos); err != nil {
		log.Fatal(err)
	}

	for i, rep := range repos {
		log.Printf("syncing %s (%d/%d)\n", rep.Path, i+1, len(repos))
		rep.Get()
	}
}

func clone(src, dst string) {
	if err := Git("clone", src, dst).Run(); err != nil {
		log.Fatal(err)
	}
}

func fetch(dir string) {
	if err := GitInDir(dir, "fetch", "origin").Run(); err != nil {
		log.Fatal(err)
	}

	var b bytes.Buffer

	cmd := GitInDir(dir, "rev-parse", "--abbrev-ref", "HEAD")
	cmd.Stdout = &b
	err := cmd.Run()
	if err != nil {
		log.Fatal(err)
	}

	br := b.Bytes()
	curBranch := string(bytes.TrimSpace(br))

	if curBranch != defaultBranch {
		log.Printf("found that current branch is %q, switching to %q", curBranch, defaultBranch)
		if err := GitInDir(dir, "checkout", defaultBranch).Run(); err != nil {
			log.Fatal(err)
		}
	}

	args := []string{"reset", "--hard", defaultRemote}
	if err := GitInDir(dir, args...).Run(); err != nil {
		log.Fatal(err)
	}

	if curBranch != defaultBranch {
		log.Printf("switch back to %q branch after reseting %q to %q", curBranch, defaultBranch, defaultRemote)
		if err := GitInDir(dir, "checkout", curBranch).Run(); err != nil {
			log.Fatal(err)
		}
	}
}
<|endoftext|>


<commit_before>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 isCocUnderUpdate bool
var failedTries int
var emailTo, emailFrom string
var myClanTag, myKey string
var cocClient cocapi.Client

func init() {

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

	emailTo = os.Getenv("EMAIL_TO")
	emailFrom = os.Getenv("EMAIL_FROM")

	myClanTag = os.Getenv("COC_CLANTAG")
	myKey = os.Getenv("COC_KEY")
}

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()

	cocClient = cocapi.NewClient(myKey)

	isCocUnderUpdate = false
	failedTries = 0
	getMembersData(myClanTag)
	//return
	ticker := time.NewTicker(10 * time.Second)
	quit := make(chan struct{})
	go func() {
		for {
			select {
			case <-ticker.C:
				getMembersData(myClanTag)
			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 getPlayerInfo() error {
	rows, err := db.Query("SELECT tag FROM members WHERE active = 1")
	if err != nil {
		return err
	}

	for rows.Next() {
		var tag string
		err := rows.Scan(&tag)
		if err != nil {
			log.Println(err)
			continue
		}
		player, err := cocClient.GetPlayerInfo(tag)
		if err != nil {
			log.Println(err)
			continue
		}
		if _, err := db.Exec("UPDATE members SET war_stars = ? WHERE tag = ?", player.WarStars, tag); err != nil {
			log.Println(err)
		}
		time.Sleep(250 * time.Millisecond)
	}
	return nil
}

func getMembersData(clan string) error {
	members, err := cocClient.GetMembers(clan)
	if err != nil {
		//log.Println(err)
		reportError(err)
		return err
	}

	if isCocUnderUpdate {
		isCocUnderUpdate = false
		sendEmail("COC Alert", "Servers are up again")
	}
	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 {
				donations := 0
				if err := db.QueryRow("SELECT current_donations FROM members WHERE member_id = ?", id).Scan(&donations); err != nil {
					log.Println(err, "no 1")
				}
				//log.Println(m.Donations, donations)
				if m.Donations != donations {
					if _, err := db.Exec("UPDATE members SET prev_donations = ?, current_donations = ?, last_donation_time = NOW() WHERE member_id = ?", donations, m.Donations, id); err != nil {
						log.Println(err)
					}
					//if m.Donations > donations {
					if _, err := db.Exec("INSERT donations (member_id, ts, current_donations, prev_donations) VALUES (?, NOW(), ?, ?)", id, m.Donations, donations); err != nil {
						log.Println(err, "")
					}
					//}
				}

				received := 0
				if err := db.QueryRow("SELECT current_rec FROM members WHERE member_id = ?", id).Scan(&received); err != nil {
					log.Println(err)
				}
				if m.DonationsReceived != received {
					if _, err := db.Exec("UPDATE members SET current_rec = ? WHERE member_id = ?", m.DonationsReceived, id); err != nil {
						log.Println(err)
					}
					if _, err := db.Exec("INSERT receive (member_id, ts, current, prev) VALUES ( ?, NOW(), ?, ? )", id, m.DonationsReceived, donations); err != nil {
						log.Println(err)
					}
				}
				ids = append(ids, strconv.Itoa(int(id)))
			}
		}
		if m.Role == "member" && m.Donations >= 1000 {
			log.Println("Found member that should be upgraded", m.Name)
			var alerted int
			db.QueryRow("SELECT alert_sent_donations FROM members WHERE tag = ?", m.Tag).Scan(&alerted)
			if alerted == 0 {
				sendEmail("Member "+m.Name+" should be upgraded", "Member "+m.Name+" should be upgraded")
				db.Exec("UPDATE members SET alert_sent_donations = 1 WHERE tag = ?", m.Tag)
			}
		}
	}
	db.Exec("UPDATE members SET exited = NOW() WHERE member_id NOT IN (" + strings.Join(ids, ", ") + ") AND active = 1")
	db.Exec("UPDATE members SET active = 0 WHERE member_id NOT IN (" + strings.Join(ids, ", ") + ")")
	//log.Println("done members func")
	return nil
}

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

func sendEmail(subject, message string) bool {
	body := "To: " + emailTo + "\r\nSubject: " + subject + "\r\n\r\n" + message
	if err := smtp.SendMail("127.0.0.1:25", nil, emailFrom, []string{emailTo}, []byte(body)); err != nil {
		log.Println(err)
		return false
	}
	return true
}
<commit_msg>Bug fix<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 isCocUnderUpdate bool
var failedTries int
var emailTo, emailFrom string
var myClanTag, myKey string
var cocClient cocapi.Client

func init() {

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

	emailTo = os.Getenv("EMAIL_TO")
	emailFrom = os.Getenv("EMAIL_FROM")

	myClanTag = os.Getenv("COC_CLANTAG")
	myKey = os.Getenv("COC_KEY")
}

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()

	cocClient = cocapi.NewClient(myKey)

	isCocUnderUpdate = false
	failedTries = 0
	getMembersData(myClanTag)
	//return
	ticker := time.NewTicker(10 * time.Second)
	quit := make(chan struct{})
	go func() {
		for {
			select {
			case <-ticker.C:
				getMembersData(myClanTag)
			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 getPlayerInfo() error {
	rows, err := db.Query("SELECT tag FROM members WHERE active = 1")
	if err != nil {
		return err
	}

	for rows.Next() {
		var tag string
		err := rows.Scan(&tag)
		if err != nil {
			log.Println(err)
			continue
		}
		player, err := cocClient.GetPlayerInfo(tag)
		if err != nil {
			log.Println(err)
			continue
		}
		if _, err := db.Exec("UPDATE members SET war_stars = ? WHERE tag = ?", player.WarStars, tag); err != nil {
			log.Println(err)
		}
		time.Sleep(250 * time.Millisecond)
	}
	return nil
}

func getMembersData(clan string) error {
	members, err := cocClient.GetMembers(clan)
	if err != nil {
		//log.Println(err)
		reportError(err)
		return err
	}

	if isCocUnderUpdate {
		isCocUnderUpdate = false
		sendEmail("COC Alert", "Servers are up again")
	}
	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 {
				donations := 0
				if err := db.QueryRow("SELECT current_donations FROM members WHERE member_id = ?", id).Scan(&donations); err != nil {
					log.Println(err, "no 1")
				}
				//log.Println(m.Donations, donations)
				if m.Donations != donations {
					if _, err := db.Exec("UPDATE members SET prev_donations = ?, current_donations = ?, last_donation_time = NOW() WHERE member_id = ?", donations, m.Donations, id); err != nil {
						log.Println(err)
					}
					//if m.Donations > donations {
					if _, err := db.Exec("INSERT donations (member_id, ts, current_donations, prev_donations) VALUES (?, NOW(), ?, ?)", id, m.Donations, donations); err != nil {
						log.Println(err, "")
					}
					//}
				}

				received := 0
				if err := db.QueryRow("SELECT current_rec FROM members WHERE member_id = ?", id).Scan(&received); err != nil {
					log.Println(err)
				}
				if m.DonationsReceived != received {
					if _, err := db.Exec("UPDATE members SET current_rec = ? WHERE member_id = ?", m.DonationsReceived, id); err != nil {
						log.Println(err)
					}
					if _, err := db.Exec("INSERT receive (member_id, ts, current, prev) VALUES ( ?, NOW(), ?, ? )", id, m.DonationsReceived, received); err != nil {
						log.Println(err)
					}
				}
				ids = append(ids, strconv.Itoa(int(id)))
			}
		}
		if m.Role == "member" && m.Donations >= 1000 {
			log.Println("Found member that should be upgraded", m.Name)
			var alerted int
			db.QueryRow("SELECT alert_sent_donations FROM members WHERE tag = ?", m.Tag).Scan(&alerted)
			if alerted == 0 {
				sendEmail("Member "+m.Name+" should be upgraded", "Member "+m.Name+" should be upgraded")
				db.Exec("UPDATE members SET alert_sent_donations = 1 WHERE tag = ?", m.Tag)
			}
		}
	}
	db.Exec("UPDATE members SET exited = NOW() WHERE member_id NOT IN (" + strings.Join(ids, ", ") + ") AND active = 1")
	db.Exec("UPDATE members SET active = 0 WHERE member_id NOT IN (" + strings.Join(ids, ", ") + ")")
	//log.Println("done members func")
	return nil
}

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

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


<commit_before>// HTTP/2 web server with built-in support for Lua, Markdown, GCSS, Amber and JSX.
package main

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	internallog "log"
	"net/http"
	"os"
	"time"

	"github.com/bradfitz/http2"
	"github.com/xyproto/permissions2"
	"github.com/xyproto/simpleredis"
	"github.com/yuin/gopher-lua"
)

const (
	versionString = "Algernon 0.62"
	description   = "HTTP/2 web server"
)

var (
	// The default font
	defaultFont = "<link href='//fonts.googleapis.com/css?family=Lato:300' rel='stylesheet' type='text/css'>"

	// The default CSS style
	// Will be used for directory listings and when rendering markdown pages
	defaultStyle = "body { background-color: #e7eaed; color: #0b0b0b; font-family: 'Lato', sans-serif; font-weight: 300;  margin: 3.5em; font-size: 1.3em; } a { color: #4010010; font-family: courier; } a:hover { color: #801010; } a:active { color: yellow; } h1 { color: #101010; }"

	// List of filenames that should be displayed instead of a directory listing
	indexFilenames = []string{"index.lua", "index.html", "index.md", "index.txt", "index.amber", "stream.lua"}
)

func newServerConfiguration(mux *http.ServeMux, http2support bool, addr string) *http.Server {
	// Server configuration
	s := &http.Server{
		Addr:    addr,
		Handler: mux,

		// The timeout values is also the maximum time it can take
		// for a complete page of Server-Sent Events (SSE).
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 10 * time.Second,

		MaxHeaderBytes: 1 << 20,
	}
	if http2support {
		// Enable HTTP/2 support
		http2.ConfigureServer(s, nil)
	}
	return s
}

func main() {
	// Set several configuration variables, based on the given flags and arguments
	host := handleFlags()

	// Console output
	fmt.Println(banner())

	// Dividing line between the banner and output from any of the configuration scripts
	if len(serverConfigurationFilenames) > 0 {
		fmt.Println("--------------------------------------- - - · ·")
	}

	// Request handlers
	mux := http.NewServeMux()

	// TODO: Run a Redis clone in RAM if no server is available.
	if err := simpleredis.TestConnectionHost(redisAddr); err != nil {
		log.Info("A Redis database is required.")
		log.Fatal(err)
	}

	// New permissions middleware
	perm := permissions.NewWithRedisConf(redisDBindex, redisAddr)

	// Lua LState pool
	luapool := &lStatePool{saved: make([]*lua.LState, 0, 4)}
	defer luapool.Shutdown()

	// Register HTTP handler functions
	registerHandlers(mux, serverDir, perm, luapool)

	// Read server configuration script, if present.
	// The scripts may change global variables.
	for _, filename := range serverConfigurationFilenames {
		if exists(filename) {
			if err := runConfiguration(filename, perm, luapool); err != nil {
				log.Error("Could not use configuration script: " + filename)
				log.Fatal(err)
			}
		}
	}

	// Set the values that has not been set by flags nor scripts (and can be set by both)
	ranServerReadyFunction := finalConfiguration(host)

	// Dividing line between the banner and output from any of the configuration scripts
	if ranServerReadyFunction {
		fmt.Println("--------------------------------------- - - · ·")
	}

	// If we are not keeping the logs, reduce the verboseness
	http2.VerboseLogs = (serverHTTP2log != "/dev/null")

	// Direct the logging from the http2 package elsewhere
	f, err := os.Open(serverHTTP2log)
	defer f.Close()
	if err != nil {
		// Could not open the serverHTTP2log filename, try using another filename
		f, err := os.OpenFile("http2.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
		defer f.Close()
		if err != nil {
			log.Fatalf("Could not write to %s nor %s.", serverHTTP2log, "http2.log")
		}
		internallog.SetOutput(f)
	} else {
		internallog.SetOutput(f)
	}

	// Serve filesystem events in the background.
	// Used for reloading pages when the sources change.
	if debugMode {
		refresh, err := time.ParseDuration(eventRefresh)
		if err != nil {
			log.Fatal(err)
		}
		EventServer(eventAddr, "/fs", serverDir, refresh)
	}

	// Decide which protocol to listen to
	switch {
	case productionMode:
		go func() {
			log.Info("Serving HTTPS + HTTP/2 on port 443")
			HTTPSserver := newServerConfiguration(mux, true, host+":443")
			// Listen for HTTPS + HTTP/2 requests
			err := HTTPSserver.ListenAndServeTLS(serverCert, serverKey)
			if err != nil {
				log.Error(err)
			}
		}()
		log.Info("Serving HTTP on port 80")
		HTTPserver := newServerConfiguration(mux, false, host+":80")
		if err := HTTPserver.ListenAndServe(); err != nil {
			// If we can't serve regular HTTP on port 80, give up
			log.Fatal(err)
		}
	case serveJustHTTP2:
		log.Info("Serving HTTP/2")
		// Listen for HTTP/2 requests
		HTTP2server := newServerConfiguration(mux, true, serverAddr)
		if err := HTTP2server.ListenAndServe(); err != nil {
			log.Fatal(err)
		}
	case !(serveJustHTTP2 || serveJustHTTP):
		log.Info("Serving HTTPS + HTTP/2")
		// Listen for HTTPS + HTTP/2 requests
		HTTPS2server := newServerConfiguration(mux, true, serverAddr)
		err := HTTPS2server.ListenAndServeTLS(serverCert, serverKey)
		if err != nil {
			log.Error(err)
			// If HTTPS failed (perhaps the key + cert are missing), serve
			// plain HTTP instead, by falling through to the next case.
		} else {
			// Don't fall through to serve regular HTTP
			break
		}
		fallthrough
	default:
		log.Info("Serving HTTP")
		HTTPserver := newServerConfiguration(mux, false, serverAddr)
		if err := HTTPserver.ListenAndServe(); err != nil {
			// If we can't serve regular HTTP, give up
			log.Fatal(err)
		}
	}
}
<commit_msg>Added TODO<commit_after>// HTTP/2 web server with built-in support for Lua, Markdown, GCSS, Amber and JSX.
package main

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	internallog "log"
	"net/http"
	"os"
	"time"

	"github.com/bradfitz/http2"
	"github.com/xyproto/permissions2"
	"github.com/xyproto/simpleredis"
	"github.com/yuin/gopher-lua"
)

const (
	versionString = "Algernon 0.62"
	description   = "HTTP/2 web server"
)

var (
	// The default font
	defaultFont = "<link href='//fonts.googleapis.com/css?family=Lato:300' rel='stylesheet' type='text/css'>"

	// The default CSS style
	// Will be used for directory listings and when rendering markdown pages
	defaultStyle = "body { background-color: #e7eaed; color: #0b0b0b; font-family: 'Lato', sans-serif; font-weight: 300;  margin: 3.5em; font-size: 1.3em; } a { color: #4010010; font-family: courier; } a:hover { color: #801010; } a:active { color: yellow; } h1 { color: #101010; }"

	// List of filenames that should be displayed instead of a directory listing
	indexFilenames = []string{"index.lua", "index.html", "index.md", "index.txt", "index.amber", "stream.lua"}
)

func newServerConfiguration(mux *http.ServeMux, http2support bool, addr string) *http.Server {
	// Server configuration
	s := &http.Server{
		Addr:    addr,
		Handler: mux,

		// The timeout values is also the maximum time it can take
		// for a complete page of Server-Sent Events (SSE).
		ReadTimeout:  10 * time.Second,
		WriteTimeout: 10 * time.Second,

		MaxHeaderBytes: 1 << 20,
	}
	if http2support {
		// Enable HTTP/2 support
		http2.ConfigureServer(s, nil)
	}
	return s
}

func main() {
	// Set several configuration variables, based on the given flags and arguments
	host := handleFlags()

	// Console output
	fmt.Println(banner())

	// Dividing line between the banner and output from any of the configuration scripts
	if len(serverConfigurationFilenames) > 0 {
		fmt.Println("--------------------------------------- - - · ·")
	}

	// Request handlers
	mux := http.NewServeMux()

	// TODO: Run a Redis clone in RAM if no server is available.
	if err := simpleredis.TestConnectionHost(redisAddr); err != nil {
		log.Info("A Redis database is required.")
		log.Fatal(err)
	}

	// New permissions middleware
	perm := permissions.NewWithRedisConf(redisDBindex, redisAddr)

	// Lua LState pool
	luapool := &lStatePool{saved: make([]*lua.LState, 0, 4)}
	defer luapool.Shutdown()

	// Register HTTP handler functions
	registerHandlers(mux, serverDir, perm, luapool)

	// Read server configuration script, if present.
	// The scripts may change global variables.
	for _, filename := range serverConfigurationFilenames {
		if exists(filename) {
			if err := runConfiguration(filename, perm, luapool); err != nil {
				log.Error("Could not use configuration script: " + filename)
				log.Fatal(err)
			}
		}
	}

	// Set the values that has not been set by flags nor scripts (and can be set by both)
	ranServerReadyFunction := finalConfiguration(host)

	// Dividing line between the banner and output from any of the configuration scripts
	if ranServerReadyFunction {
		fmt.Println("--------------------------------------- - - · ·")
	}

	// If we are not keeping the logs, reduce the verboseness
	http2.VerboseLogs = (serverHTTP2log != "/dev/null")

	// Direct the logging from the http2 package elsewhere
	f, err := os.Open(serverHTTP2log)
	defer f.Close()
	if err != nil {
		// Could not open the serverHTTP2log filename, try using another filename
		f, err := os.OpenFile("http2.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
		defer f.Close()
		if err != nil {
			log.Fatalf("Could not write to %s nor %s.", serverHTTP2log, "http2.log")
		}
		internallog.SetOutput(f)
	} else {
		internallog.SetOutput(f)
	}

	// TODO: Mutex for log.Info!

	// Serve filesystem events in the background.
	// Used for reloading pages when the sources change.
	if debugMode {
		refresh, err := time.ParseDuration(eventRefresh)
		if err != nil {
			log.Fatal(err)
		}
		EventServer(eventAddr, "/fs", serverDir, refresh)
	}

	// Decide which protocol to listen to
	switch {
	case productionMode:
		go func() {
			log.Info("Serving HTTPS + HTTP/2 on port 443")
			HTTPSserver := newServerConfiguration(mux, true, host+":443")
			// Listen for HTTPS + HTTP/2 requests
			err := HTTPSserver.ListenAndServeTLS(serverCert, serverKey)
			if err != nil {
				log.Error(err)
			}
		}()
		log.Info("Serving HTTP on port 80")
		HTTPserver := newServerConfiguration(mux, false, host+":80")
		if err := HTTPserver.ListenAndServe(); err != nil {
			// If we can't serve regular HTTP on port 80, give up
			log.Fatal(err)
		}
	case serveJustHTTP2:
		log.Info("Serving HTTP/2")
		// Listen for HTTP/2 requests
		HTTP2server := newServerConfiguration(mux, true, serverAddr)
		if err := HTTP2server.ListenAndServe(); err != nil {
			log.Fatal(err)
		}
	case !(serveJustHTTP2 || serveJustHTTP):
		log.Info("Serving HTTPS + HTTP/2")
		// Listen for HTTPS + HTTP/2 requests
		HTTPS2server := newServerConfiguration(mux, true, serverAddr)
		err := HTTPS2server.ListenAndServeTLS(serverCert, serverKey)
		if err != nil {
			log.Error(err)
			// If HTTPS failed (perhaps the key + cert are missing), serve
			// plain HTTP instead, by falling through to the next case.
		} else {
			// Don't fall through to serve regular HTTP
			break
		}
		fallthrough
	default:
		log.Info("Serving HTTP")
		HTTPserver := newServerConfiguration(mux, false, serverAddr)
		if err := HTTPserver.ListenAndServe(); err != nil {
			// If we can't serve regular HTTP, give up
			log.Fatal(err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"fmt"
	"github.com/bwmarrin/discordgo"
	"encoding/binary"
	"io"
	"strings"
	"time"
	"math/rand"
	"io/ioutil"
	"path/filepath"
	"encoding/json"
)

const DIRNAME = "Dank";
var sounds = make(map[string][][]byte, 0);
var images map[string]string;

var statuses = []string{
	"hidden object games",
	"Oh... Sir!",
	"Minecraft 1.0 ALPHA",
	"with your mother",
	"something",
	"something else",
	"bored",
	"dead"}

type Settings struct{
	vc *discordgo.VoiceConnection
	playing bool
	commander string
}
var settings = make(map[string]*Settings);

func main(){
	args := os.Args[1:];

	if(len(args) < 1){
		fmt.Println("No token provided!");
		return;
	}
	token := args[0];

	fmt.Println("Loading...");

	err := os.MkdirAll(DIRNAME, 0755);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "I THINK THERE WAS ERROR ", err);
		return;
	}
	files, err := ioutil.ReadDir(DIRNAME);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "I THINK THERE WAS ERROR ", err);
		return;
	}
	for _, file := range files{
		if(file.IsDir()){
			continue;
		}
		name := file.Name();
		if(!strings.HasSuffix(name, ".dca")){
			continue;
		}

		bytes := make([][]byte, 0);
		err = load(name, &bytes);
		if(err != nil){
			continue;
		}

		name = strings.ToLower(strings.TrimSuffix(name, ".dca"));
		sounds[name] = bytes;
	}

	data, err := ioutil.ReadFile("Dank/images.json");
	if(err != nil){
		fmt.Fprintln(os.Stderr, "DAT images.json FILE EZ POOF!", err);
		images = make(map[string]string, 0);
	} else {
		err = json.Unmarshal(data, &images);
		if(err != nil){
			fmt.Fprintln(os.Stderr, "DO U EVEN JSON, BRUH?", err);
			images = make(map[string]string, 0);
		}
	}

	fmt.Println("Starting...");
	d, err := discordgo.New("Bot " + token);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "I THINK THERE WAS ERROR ", err);
		return;
	}
	d.AddHandler(ready);
	d.AddHandler(messageCreate);
	d.AddHandler(messageUpdate);
	err = d.Open();

	if(err != nil){
		fmt.Fprintln(os.Stderr, "I THINK THERE WAS ERROR ", err);
		return;
	}
	fmt.Println("Started!");

	<-make(chan struct{});
}

func load(file string, buffer *[][]byte) error{
	f, err := os.Open(filepath.Join(DIRNAME, file));
	if err != nil {
		fmt.Fprintln(os.Stderr, "FILE WAS WEIRD IDK: ", err);
		return err;
	}

	var length int16;
	for {
		err := binary.Read(f, binary.LittleEndian, &length);

		if(err == io.EOF || err == io.ErrUnexpectedEOF){
			break;
		} else if(err != nil){
			fmt.Fprintln(os.Stderr, "IDK WAT U DID BUT WEL DONN NOOB, ", err);
			return err;
		}

		buf := make([]byte, length);
		err = binary.Read(f, binary.LittleEndian, &buf);
		if(err != nil){
			fmt.Fprintln(os.Stderr, "IDK WAT U DID BUT WEL DONN NOOB, ", err);
			return err;
		}

		*buffer = append(*buffer, buf);
	}
	return nil;
}

func play(buffer [][]byte, session *discordgo.Session, guild, channel string, s *Settings){
	s.playing = true;
	var err error;
	s.vc, err = session.ChannelVoiceJoin(guild, channel, false, true);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "LEL FREGGIN NOOB, ", err);
		s.playing = false;
		return;
	}

	err = s.vc.Speaking(true);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "I HAS TO TYPE ALL DESE ERROR MESSAGES " +
		"HAVE SOME SYMPATHY PLS ", err);
		return;
	}

	for _, buf := range buffer {
		if s.vc == nil { return; }
		s.vc.OpusSend <- buf;
	}

	err = s.vc.Speaking(false);
	if(err != nil){
		fmt.Fprintln(os.Stderr, err);
		return;
	}
	err = s.vc.Disconnect();
	if(err != nil){
		fmt.Fprintln(os.Stderr, err);
		return;
	}
	s.playing = false;
}

func messageCreate(session *discordgo.Session, event *discordgo.MessageCreate){
	message(session, event.Message)
}
func messageUpdate(session *discordgo.Session, event *discordgo.MessageUpdate){
	message(session, event.Message)
}
func message(session *discordgo.Session, event *discordgo.Message){
	msg := strings.ToLower(strings.TrimSpace(event.Content));
	author := event.Author;

	channel, err := session.State.Channel(event.ChannelID);
	if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }

	guild, err := session.State.Guild(channel.GuildID);
	if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }

	s := settings[guild.ID];
	if(s == nil){
		s = &Settings{};
		settings[guild.ID] = s;
	}

	if(s.commander != "" && s.commander != author.ID){
		return;
	}

	buffer, ok := sounds[msg];
	if(ok){
		if(!s.playing){
			for _, state := range guild.VoiceStates{
				if state.UserID == event.Author.ID{
					play(buffer, session, guild.ID, state.ChannelID, s);
				}
			}
		}
		return;
	}

	for keyword, url := range images{
		if(strings.Contains(msg, strings.ToLower(keyword))){
			_, err = session.ChannelMessageSendEmbed(event.ChannelID,
				&discordgo.MessageEmbed{
					Image: &discordgo.MessageEmbedImage{
						URL: url,
					},
				});
			break;
		}
	}

	switch(msg){
		case "thx":
			if(s.vc != nil){
				err := s.vc.Speaking(false);
				if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }

				err = s.vc.Disconnect();
				if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }

				s.playing = false;
			}
		case "listen only to me plz":
			s.commander = author.ID;
		case "every1 owns u stopad robot":
			s.commander = "";
	}
}

func ready(session *discordgo.Session, event *discordgo.Ready){
	c := time.Tick(time.Second * 5);

	for _ = range c{
		err := session.UpdateStatus(0, statuses[rand.Intn(len(statuses))]);
		if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }
	}
}
<commit_msg>NAO IS HOMAN AND REACTS 2 MSG KTHX<commit_after>package main;

import (
	"os"
	"fmt"
	"github.com/bwmarrin/discordgo"
	"encoding/binary"
	"io"
	"strings"
	"time"
	"math/rand"
	"io/ioutil"
	"path/filepath"
	"encoding/json"
)

const DIRNAME = "Dank";
var sounds = make(map[string][][]byte, 0);
var images map[string]string;

var statuses = []string{
	"hidden object games",
	"Oh... Sir!",
	"Minecraft 1.0 ALPHA",
	"with your mother",
	"something",
	"something else",
	"bored",
	"dead"}

type Settings struct{
	vc *discordgo.VoiceConnection
	playing bool
	commander string
}
var settings = make(map[string]*Settings);

func main(){
	args := os.Args[1:];

	if(len(args) < 1){
		fmt.Println("No token provided!");
		return;
	}
	token := args[0];

	fmt.Println("Loading...");

	err := os.MkdirAll(DIRNAME, 0755);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "I THINK THERE WAS ERROR", err);
		return;
	}
	files, err := ioutil.ReadDir(DIRNAME);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "I THINK THERE WAS ERROR", err);
		return;
	}
	for _, file := range files{
		if(file.IsDir()){
			continue;
		}
		name := file.Name();
		if(!strings.HasSuffix(name, ".dca")){
			continue;
		}

		bytes := make([][]byte, 0);
		err = load(name, &bytes);
		if(err != nil){
			continue;
		}

		name = strings.ToLower(strings.TrimSuffix(name, ".dca"));
		sounds[name] = bytes;
	}

	data, err := ioutil.ReadFile("Dank/images.json");
	if(err != nil){
		fmt.Fprintln(os.Stderr, "DAT images.json FILE EZ POOF!", err);
		images = make(map[string]string, 0);
	} else {
		err = json.Unmarshal(data, &images);
		if(err != nil){
			fmt.Fprintln(os.Stderr, "DO U EVEN JSON, BRUH?", err);
			images = make(map[string]string, 0);
		}
	}

	fmt.Println("Starting...");
	d, err := discordgo.New("Bot " + token);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "I THINK THERE WAS ERROR", err);
		return;
	}
	d.AddHandler(ready);
	d.AddHandler(messageCreate);
	d.AddHandler(messageUpdate);
	err = d.Open();

	if(err != nil){
		fmt.Fprintln(os.Stderr, "I THINK THERE WAS ERROR", err);
		return;
	}
	fmt.Println("Started!");

	<-make(chan struct{});
}

func load(file string, buffer *[][]byte) error{
	f, err := os.Open(filepath.Join(DIRNAME, file));
	if err != nil {
		fmt.Fprintln(os.Stderr, "FILE WAS WEIRD IDK:", err);
		return err;
	}

	var length int16;
	for {
		err := binary.Read(f, binary.LittleEndian, &length);

		if(err == io.EOF || err == io.ErrUnexpectedEOF){
			break;
		} else if(err != nil){
			fmt.Fprintln(os.Stderr, "IDK WAT U DID BUT WEL DONN NOOB,", err);
			return err;
		}

		buf := make([]byte, length);
		err = binary.Read(f, binary.LittleEndian, &buf);
		if(err != nil){
			fmt.Fprintln(os.Stderr, "IDK WAT U DID BUT WEL DONN NOOB,", err);
			return err;
		}

		*buffer = append(*buffer, buf);
	}
	return nil;
}

func play(buffer [][]byte, session *discordgo.Session, guild, channel string, s *Settings){
	s.playing = true;
	var err error;
	s.vc, err = session.ChannelVoiceJoin(guild, channel, false, true);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "LEL FREGGIN NOOB,", err);
		s.playing = false;
		return;
	}

	err = s.vc.Speaking(true);
	if(err != nil){
		fmt.Fprintln(os.Stderr, "I HAS TO TYPE ALL DESE ERROR MESSAGES " +
		"HAVE SOME SYMPATHY PLS", err);
		return;
	}

	for _, buf := range buffer {
		if s.vc == nil { return; }
		s.vc.OpusSend <- buf;
	}

	err = s.vc.Speaking(false);
	if(err != nil){
		fmt.Fprintln(os.Stderr, err);
		return;
	}
	err = s.vc.Disconnect();
	if(err != nil){
		fmt.Fprintln(os.Stderr, err);
		return;
	}
	s.playing = false;
}

func messageCreate(session *discordgo.Session, event *discordgo.MessageCreate){
	message(session, event.Message)
}
func messageUpdate(session *discordgo.Session, event *discordgo.MessageUpdate){
	message(session, event.Message)
}
func message(session *discordgo.Session, event *discordgo.Message){
	msg := strings.ToLower(strings.TrimSpace(event.Content));
	author := event.Author;

	channel, err := session.State.Channel(event.ChannelID);
	if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }

	guild, err := session.State.Guild(channel.GuildID);
	if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }

	s := settings[guild.ID];
	if(s == nil){
		s = &Settings{};
		settings[guild.ID] = s;
	}

	if(s.commander != "" && s.commander != author.ID){
		return;
	}

	buffer, ok := sounds[msg];
	if(ok){
		if(!s.playing){
			for _, state := range guild.VoiceStates{
				if state.UserID == event.Author.ID{
					play(buffer, session, guild.ID, state.ChannelID, s);
					react(session, event);
					return;
				}
			}
		}
		return;
	}

	for keyword, url := range images{
		if(strings.Contains(msg, strings.ToLower(keyword))){
			_, err = session.ChannelMessageSendEmbed(event.ChannelID,
				&discordgo.MessageEmbed{
					Image: &discordgo.MessageEmbedImage{
						URL: url,
					},
				});
			react(session, event);
			return;
		}
	}

	switch(msg){
		case "thx":
			if(s.vc != nil){
				err := s.vc.Speaking(false);
				if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }

				err = s.vc.Disconnect();
				if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }

				s.playing = false;
			}
		case "listen only to me plz":
			s.commander = author.ID;
		case "every1 owns u stopad robot":
			s.commander = "";
	}
}

func ready(session *discordgo.Session, event *discordgo.Ready){
	c := time.Tick(time.Second * 5);

	for _ = range c{
		err := session.UpdateStatus(0, statuses[rand.Intn(len(statuses))]);
		if(err != nil){ fmt.Fprintln(os.Stderr, err); return; }
	}
}

func react(session *discordgo.Session, event *discordgo.Message){
	err := session.MessageReactionAdd(event.ChannelID, event.ID, "👌");
	if(err != nil){
		fmt.Fprintln(os.Stderr, "Couldn't react,", err);
		return;
	}
	err = session.MessageReactionAdd(event.ChannelID, event.ID, "😂");
	if(err != nil){
		fmt.Fprintln(os.Stderr, "Couldn't react,", err);
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/codegangsta/cli"
)

// Config holds the emoji configuration
type Config struct {
	Words map[string]string `toml:"commitKinds"`
}

var pwd string
var hook = "\n# simplifies emoji usage \nemojify -m \"`cat $1`\" > \"$1\""

func init() {
	var err error
	pwd, err = os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
}

func install() {
	if _, err := os.Stat(pwd + "/.git"); err != nil {
		log.Fatal("fatal: Not a git repository (or any of the parent directories): .git")
	}
	f, err := os.OpenFile(pwd+"/.git/hooks/prepare-commit-msg", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0777)
	defer f.Close()
	_, werr := f.WriteString(hook)
	if werr != nil || err != nil {
		log.Fatal("fatal: unable to create the prepare-commit-msg hook!", werr, err)
	}
	log.Println("created hook for ", pwd)
}

// Run ...
func Run(c *cli.Context) {
	cfg := loadEmojiMap()
	msg := c.String("message")
	if msg != "" {
		fmt.Println(replace(cfg, msg))
	}
}

func loadEmojiMap() *Config {
	wrds := Config{}
	if _, err := toml.DecodeFile(pwd+"/.emojifyrc", &wrds); err != nil {
		data, err := Asset("config/emoji.toml")
		if err != nil {
			log.Fatal("Fatal: No config file found")
		}
		if _, err := toml.Decode(string(data), &wrds); err != nil {
			log.Fatal(err)
		}
	}
	return &wrds
}

func replace(cfg *Config, msg string) string {
	words := strings.Split(msg, " ")
	for i, w := range words {
		if strings.HasPrefix(w, ":") {
			raw := strings.TrimPrefix(w, ":")
			if cfg.Words[raw] != "" {
				words[i] = cfg.Words[raw]
			}
		}
	}
	return strings.Join(words, " ")
}

func main() {
	// installHook()
	app := cli.NewApp()
	app.Name = "emojify"
	app.Usage = "Make your git commits more expressive"
	app.Action = Run
	app.Version = "0.1.4"
	app.Commands = []cli.Command{
		{
			Name:    "install",
			Aliases: []string{"i"},
			Usage:   "initialize the git hook",
			Action: func(c *cli.Context) {
				install()
			},
		},
	}
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "message, m",
			Usage: "The message to commit",
		},
	}
	app.Run(os.Args)
}
<commit_msg>:bugfix Works with multiline commits<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/codegangsta/cli"
	"github.com/pborman/getopt"
)

// Config holds the emoji configuration
type Config struct {
	Words map[string]string `toml:"commitKinds"`
}

var pwd string
var hook = "\n# simplifies emoji usage \nemojify \"`cat $1`\" > \"$1\""

func init() {
	var err error
	pwd, err = os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
}

func install() {
	if _, err := os.Stat(pwd + "/.git"); err != nil {
		log.Fatal("fatal: Not a git repository (or any of the parent directories): .git")
	}
	f, err := os.OpenFile(pwd+"/.git/hooks/prepare-commit-msg", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0777)
	defer f.Close()
	_, werr := f.WriteString(hook)
	if werr != nil || err != nil {
		log.Fatal("fatal: unable to create the prepare-commit-msg hook!", werr, err)
	}
	log.Println("created hook for ", pwd)
}

// Run ...
func Run(c *cli.Context) {
	getopt.Parse()
	args := getopt.Args()
	msg := strings.Join(args, " ")
	cfg := loadEmojiMap()
	if msg != "" {
		fmt.Println(replace(cfg, msg))
	}
}

func loadEmojiMap() *Config {
	wrds := Config{}
	if _, err := toml.DecodeFile(pwd+"/.emojifyrc", &wrds); err != nil {
		data, err := Asset("config/emoji.toml")
		if err != nil {
			log.Fatal("Fatal: No config file found")
		}
		if _, err := toml.Decode(string(data), &wrds); err != nil {
			log.Fatal(err)
		}
	}
	return &wrds
}

func replace(cfg *Config, msg string) string {
	words := strings.Split(msg, " ")
	for i, w := range words {
		if strings.HasPrefix(w, ":") {
			raw := strings.TrimPrefix(w, ":")
			if cfg.Words[raw] != "" {
				words[i] = cfg.Words[raw]
			}
		}
	}
	return strings.Join(words, " ")
}

func main() {
	// installHook()
	app := cli.NewApp()
	app.Name = "emojify"
	app.Usage = "Make your git commits more expressive"
	app.Action = Run
	app.Version = "0.1.4"
	app.Commands = []cli.Command{
		{
			Name:    "install",
			Aliases: []string{"i"},
			Usage:   "initialize the git hook",
			Action: func(c *cli.Context) {
				install()
			},
		},
	}
	// app.Flags = []cli.Flag{
	// 	cli.StringFlag{
	// 		Name:  "message, m",
	// 		Usage: "The message to commit",
	// 	},
	// }
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main //import "github.com/tutumcloud/events"

import (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"log"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/getsentry/raven-go"
)

type Event struct {
	Status     string `json:"status"`
	ID         string `json:"id"`
	From       string `json:"from"`
	Time       int64  `json:"time"`
	HandleTime int64  `json:"handletime"`
	ExitCode   string `json:"exitcode"`
}

type ContaineState struct {
	isRunning bool
	created   int64
	updated   int64
}

func init() {
	runtime.GOMAXPROCS(4)
}

const (
	VERSION    = "0.2"
	DockerPath = "/usr/bin/docker"
)

var (
	UserAgent      = "tutum-events/" + VERSION
	Interval       int
	TutumAuth      string
	TutumUrl       string
	sentryClient   *raven.Client = nil
	DSN            string
	Container      = make(map[string]*ContaineState)
	FlagStandalone *bool
)

func main() {
	FlagStandalone = flag.Bool("standalone", false, "Standalone mode")
	flag.Parse()

	TutumAuth = os.Getenv("TUTUM_AUTH")
	TutumUrl = os.Getenv("TUTUM_URL")
	if TutumAuth == "**None**" {
		log.Fatal("TUTUM_AUTH must be specified")
	}
	if TutumUrl == "**None**" {
		log.Fatal("TUTUM_URL must be specified")
	}

	DSN = os.Getenv("SENTRY_DSN")

	if !fileExist(DockerPath) {
		log.Fatal("docker client is not mounted to", DockerPath)
	}

	intervalStr := os.Getenv("REPORT_INTERVAL")

	if interval, err := strconv.Atoi(intervalStr); err == nil {
		Interval = interval
	} else {
		Interval = 5
	}

	if *FlagStandalone {
		log.Print("Running in standalone mode")
	} else {
		log.Print("POST docker event to: ", TutumUrl)
	}

	cmd := exec.Command(DockerPath, "version")
	if err := cmd.Start(); err != nil {
		sendError(err, "Fatal: Failed to run docker version", nil)
		log.Println(err)
		return
	}
	cmd.Wait()

	monitorEvents()
}

func monitorEvents() {
	log.Println("docker events starts")
	cmd := exec.Command(DockerPath, "events")
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal("Error creating StdoutPipe for Cmd", err)
	}

	err = cmd.Start()
	if err != nil {
		log.Fatal("Error starting docker evets", err)
	}

	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			eventStr := scanner.Text()
			if eventStr != "" {
				re := regexp.MustCompile("(.*) (.{64}): \\(from (.*)\\) (.*)")
				terms := re.FindStringSubmatch(eventStr)
				if len(terms) == 5 {
					var event Event
					eventTime, err := time.Parse(time.RFC3339Nano, terms[1])
					if err == nil {
						event.Time = eventTime.Unix()
					} else {
						event.Time = time.Now().Unix()
					}
					event.ID = terms[2]
					event.From = terms[3]
					event.Status = terms[4]
					event.HandleTime = time.Now().UnixNano()

					state := strings.ToLower(event.Status)
					if state == "start" || state == "die" {
						updateContainerState(&event)
						go eventHandler(&event)
					}
				}
			}
		}
		if scanner.Err() == nil {
			log.Fatal("The scanner returns an error:", "EOF")
		} else {
			log.Fatal("The scanner returns an error:", scanner.Err())
		}
	}()

	err = cmd.Wait()
	if err != nil {
		log.Fatal("Error waiting for docker events", err)
	}
	log.Println("docker events stops")
}

func updateContainerState(event *Event) {
	isRunning := false
	if strings.ToLower(event.Status) == "start" {
		isRunning = true
	}
	container := Container[event.ID]
	if container == nil {
		Container[event.ID] = &ContaineState{isRunning: isRunning, updated: event.HandleTime, created: event.HandleTime}
	} else {
		container.updated = event.HandleTime
		container.isRunning = isRunning
	}
}

func eventHandler(event *Event) {
	exitcode, isAutoRestart := getContainerStatus(event)
	event.ExitCode = exitcode

	if isAutoRestart {
		status := strings.ToLower(event.Status)
		if status == "die" {
			container := Container[event.ID]
			if container != nil && container.created == container.updated {
				sendContainerEvent(event)
			}
		}
		if status == "start" {
			container := Container[event.ID]
			if container == nil {
				sendContainerEvent(event)
			} else {
				if container.created == container.updated {
					delete(Container, event.ID)
					sendContainerEvent(event)
				} else {
					go delaySendContainerEvent(event)
				}
			}
		}
	} else {
		delete(Container, event.ID)
		sendContainerEvent(event)
	}

}

func getContainerStatus(event *Event) (exitcode string, isAutoRestart bool) {
	exitcode = "0"
	isAutoRestart = false
	if strings.ToLower(event.Status) == "start" ||
		strings.ToLower(event.Status) == "die" {

		result, err := exec.Command(DockerPath, "inspect", "-f",
			"{{index .HostConfig.RestartPolicy.Name}} {{index .State.ExitCode}}",
			event.ID).Output()

		if err == nil && len(result) > 0 {
			terms := strings.Split(string(result), " ")
			if len(terms) == 2 {
				if strings.HasPrefix(strings.ToLower(terms[0]), "on-failure") ||
					strings.HasPrefix(strings.ToLower(terms[0]), "always") {
					isAutoRestart = true
				}
				exitcode = strings.Trim(terms[1], "\n")
			}
		}
	}
	return
}

func sendContainerEvent(event *Event) {
	data, err := json.Marshal(*event)
	if err != nil {
		log.Printf("Cannot marshal the posting data: %s\n", event)
	}
	if *FlagStandalone {
		log.Print("Send event: ", string(data))
	} else {
		sendData(data)
	}
}

func delaySendContainerEvent(event *Event) {
	time.Sleep(time.Duration(Interval) * time.Second)
	container := Container[event.ID]
	if container == nil {
		log.Print("No container found")
		sendContainerEvent(event)
	} else {
		currentTime := time.Now().UnixNano()
		if currentTime-container.updated >= int64(Interval)*1000000000 && container.isRunning {
			delete(Container, event.ID)
			log.Printf("Run over %d", currentTime-container.updated)
			sendContainerEvent(event)
		}
	}
}

func sendData(data []byte) {
	counter := 1
	for {
		log.Println("sending event: ", string(data))
		err := send(TutumUrl, data)
		if err == nil {
			break
		} else {
			if counter > 100 {
				log.Println("Too many reties, give up")
				break
			} else {
				counter *= 2
				log.Printf("%s: Retry in %d seconds", err, counter)
				time.Sleep(time.Duration(counter) * time.Second)
			}
		}
	}
}

func send(url string, data []byte) error {
	client := &http.Client{}
	req, err := http.NewRequest("POST", url, bytes.NewReader(data))
	if err != nil {
		sendError(err, "Failed to create http.NewRequest", nil)
		return err
	}
	req.Header.Add("Authorization", TutumAuth)
	req.Header.Add("User-Agent", UserAgent)
	resp, err := client.Do(req)
	if err != nil {
		extra := map[string]interface{}{"data": string(data)}
		sendError(err, "Failed to POST the http request", extra)
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode >= 400 {
		log.Printf("Send event failed: %s - %s", resp.Status, string(data))
		extra := map[string]interface{}{"data": string(data)}
		sendError(errors.New(resp.Status), "http error", extra)
		if resp.StatusCode >= 500 {
			return errors.New(resp.Status)
		}
	}
	return nil
}

func fileExist(file string) bool {
	if _, err := os.Stat(file); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

func getSentryClient() *raven.Client {
	if sentryClient == nil && DSN != "" {
		client, _ := raven.NewClient(DSN, nil)
		sentryClient = client
	}
	return sentryClient
}

func sendError(err error, msg string, extra map[string]interface{}) {
	go func() {
		client := getSentryClient()
		if sentryClient != nil {
			packet := &raven.Packet{Message: msg, Interfaces: []raven.Interface{raven.NewException(err, raven.NewStacktrace(0, 5, nil))}}
			if extra != nil {
				packet.Extra = extra
			}
			_, ch := client.Capture(packet, nil)
			<-ch
		}
	}()
}
<commit_msg>fix type<commit_after>package main //import "github.com/tutumcloud/events"

import (
	"bufio"
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"log"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/getsentry/raven-go"
)

type Event struct {
	Status     string `json:"status"`
	ID         string `json:"id"`
	From       string `json:"from"`
	Time       int64  `json:"time"`
	HandleTime int64  `json:"handletime"`
	ExitCode   string `json:"exitcode"`
}

type ContainerState struct {
	isRunning bool
	created   int64
	updated   int64
}

func init() {
	runtime.GOMAXPROCS(4)
}

const (
	VERSION    = "0.2"
	DockerPath = "/usr/bin/docker"
)

var (
	UserAgent      = "tutum-events/" + VERSION
	Interval       int
	TutumAuth      string
	TutumUrl       string
	sentryClient   *raven.Client = nil
	DSN            string
	Container      = make(map[string]*ContainerState)
	FlagStandalone *bool
)

func main() {
	FlagStandalone = flag.Bool("standalone", false, "Standalone mode")
	flag.Parse()

	TutumAuth = os.Getenv("TUTUM_AUTH")
	TutumUrl = os.Getenv("TUTUM_URL")
	if TutumAuth == "**None**" {
		log.Fatal("TUTUM_AUTH must be specified")
	}
	if TutumUrl == "**None**" {
		log.Fatal("TUTUM_URL must be specified")
	}

	DSN = os.Getenv("SENTRY_DSN")

	if !fileExist(DockerPath) {
		log.Fatal("docker client is not mounted to", DockerPath)
	}

	intervalStr := os.Getenv("REPORT_INTERVAL")

	if interval, err := strconv.Atoi(intervalStr); err == nil {
		Interval = interval
	} else {
		Interval = 5
	}

	if *FlagStandalone {
		log.Print("Running in standalone mode")
	} else {
		log.Print("POST docker event to: ", TutumUrl)
	}

	cmd := exec.Command(DockerPath, "version")
	if err := cmd.Start(); err != nil {
		sendError(err, "Fatal: Failed to run docker version", nil)
		log.Println(err)
		return
	}
	cmd.Wait()

	monitorEvents()
}

func monitorEvents() {
	log.Println("docker events starts")
	cmd := exec.Command(DockerPath, "events")
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal("Error creating StdoutPipe for Cmd", err)
	}

	err = cmd.Start()
	if err != nil {
		log.Fatal("Error starting docker evets", err)
	}

	scanner := bufio.NewScanner(cmdReader)
	go func() {
		for scanner.Scan() {
			eventStr := scanner.Text()
			if eventStr != "" {
				re := regexp.MustCompile("(.*) (.{64}): \\(from (.*)\\) (.*)")
				terms := re.FindStringSubmatch(eventStr)
				if len(terms) == 5 {
					var event Event
					eventTime, err := time.Parse(time.RFC3339Nano, terms[1])
					if err == nil {
						event.Time = eventTime.Unix()
					} else {
						event.Time = time.Now().Unix()
					}
					event.ID = terms[2]
					event.From = terms[3]
					event.Status = terms[4]
					event.HandleTime = time.Now().UnixNano()

					state := strings.ToLower(event.Status)
					if state == "start" || state == "die" {
						updateContainerState(&event)
						go eventHandler(&event)
					}
				}
			}
		}
		if scanner.Err() == nil {
			log.Fatal("The scanner returns an error:", "EOF")
		} else {
			log.Fatal("The scanner returns an error:", scanner.Err())
		}
	}()

	err = cmd.Wait()
	if err != nil {
		log.Fatal("Error waiting for docker events", err)
	}
	log.Println("docker events stops")
}

func updateContainerState(event *Event) {
	isRunning := false
	if strings.ToLower(event.Status) == "start" {
		isRunning = true
	}
	container := Container[event.ID]
	if container == nil {
		Container[event.ID] = &ContainerState{isRunning: isRunning, updated: event.HandleTime, created: event.HandleTime}
	} else {
		container.updated = event.HandleTime
		container.isRunning = isRunning
	}
}

func eventHandler(event *Event) {
	exitcode, isAutoRestart := getContainerStatus(event)
	event.ExitCode = exitcode

	if isAutoRestart {
		status := strings.ToLower(event.Status)
		if status == "die" {
			container := Container[event.ID]
			if container != nil && container.created == container.updated {
				sendContainerEvent(event)
			}
		}
		if status == "start" {
			container := Container[event.ID]
			if container == nil {
				sendContainerEvent(event)
			} else {
				if container.created == container.updated {
					delete(Container, event.ID)
					sendContainerEvent(event)
				} else {
					go delaySendContainerEvent(event)
				}
			}
		}
	} else {
		delete(Container, event.ID)
		sendContainerEvent(event)
	}

}

func getContainerStatus(event *Event) (exitcode string, isAutoRestart bool) {
	exitcode = "0"
	isAutoRestart = false
	if strings.ToLower(event.Status) == "start" ||
		strings.ToLower(event.Status) == "die" {

		result, err := exec.Command(DockerPath, "inspect", "-f",
			"{{index .HostConfig.RestartPolicy.Name}} {{index .State.ExitCode}}",
			event.ID).Output()

		if err == nil && len(result) > 0 {
			terms := strings.Split(string(result), " ")
			if len(terms) == 2 {
				if strings.HasPrefix(strings.ToLower(terms[0]), "on-failure") ||
					strings.HasPrefix(strings.ToLower(terms[0]), "always") {
					isAutoRestart = true
				}
				exitcode = strings.Trim(terms[1], "\n")
			}
		}
	}
	return
}

func sendContainerEvent(event *Event) {
	data, err := json.Marshal(*event)
	if err != nil {
		log.Printf("Cannot marshal the posting data: %s\n", event)
	}
	if *FlagStandalone {
		log.Print("Send event: ", string(data))
	} else {
		sendData(data)
	}
}

func delaySendContainerEvent(event *Event) {
	time.Sleep(time.Duration(Interval) * time.Second)
	container := Container[event.ID]
	if container == nil {
		log.Print("No container found")
		sendContainerEvent(event)
	} else {
		currentTime := time.Now().UnixNano()
		if currentTime-container.updated >= int64(Interval)*1000000000 && container.isRunning {
			delete(Container, event.ID)
			log.Printf("Run over %d", currentTime-container.updated)
			sendContainerEvent(event)
		}
	}
}

func sendData(data []byte) {
	counter := 1
	for {
		log.Println("sending event: ", string(data))
		err := send(TutumUrl, data)
		if err == nil {
			break
		} else {
			if counter > 100 {
				log.Println("Too many reties, give up")
				break
			} else {
				counter *= 2
				log.Printf("%s: Retry in %d seconds", err, counter)
				time.Sleep(time.Duration(counter) * time.Second)
			}
		}
	}
}

func send(url string, data []byte) error {
	client := &http.Client{}
	req, err := http.NewRequest("POST", url, bytes.NewReader(data))
	if err != nil {
		sendError(err, "Failed to create http.NewRequest", nil)
		return err
	}
	req.Header.Add("Authorization", TutumAuth)
	req.Header.Add("User-Agent", UserAgent)
	resp, err := client.Do(req)
	if err != nil {
		extra := map[string]interface{}{"data": string(data)}
		sendError(err, "Failed to POST the http request", extra)
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode >= 400 {
		log.Printf("Send event failed: %s - %s", resp.Status, string(data))
		extra := map[string]interface{}{"data": string(data)}
		sendError(errors.New(resp.Status), "http error", extra)
		if resp.StatusCode >= 500 {
			return errors.New(resp.Status)
		}
	}
	return nil
}

func fileExist(file string) bool {
	if _, err := os.Stat(file); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

func getSentryClient() *raven.Client {
	if sentryClient == nil && DSN != "" {
		client, _ := raven.NewClient(DSN, nil)
		sentryClient = client
	}
	return sentryClient
}

func sendError(err error, msg string, extra map[string]interface{}) {
	go func() {
		client := getSentryClient()
		if sentryClient != nil {
			packet := &raven.Packet{Message: msg, Interfaces: []raven.Interface{raven.NewException(err, raven.NewStacktrace(0, 5, nil))}}
			if extra != nil {
				packet.Extra = extra
			}
			_, ch := client.Capture(packet, nil)
			<-ch
		}
	}()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"runtime"
	"time"
)

func main() {

	Welcome()
	InitMongo()
	InitHttpServer()

	time.Sleep(time.Second)

	var port = flag.Int("port", 9080, "the stream  login auth port")
	var nbCpus = flag.Int("cpus", runtime.NumCPU()-1, "the cpus to use")
	//var tcpNoDalay = flag.Bool("nodelay", false, "set TCP_NODELAY for connection")
	flag.Usage = func() {
		fmt.Println("Usage:[--port=int]")
		fmt.Println("		port,the listen port .default 9080")
	}
	flag.Parse()
	runtime.GOMAXPROCS(*nbCpus)
	InitStreamServer(*port)
	go StartStreamServer()
	beOver := 0
	for {
		time.Sleep(time.Second)
		if beOver > 1000 {
			break
		}
		fmt.Println(beOver, "was runing ")
		beOver++
	}
}
<commit_msg>test can runing 3<commit_after>package main

import (
	"flag"
	"fmt"
	"runtime"
	"time"
)

func main() {

	Welcome()
	//InitMongo()
	InitHttpServer()

	time.Sleep(time.Second)

	var port = flag.Int("port", 9080, "the stream  login auth port")
	var nbCpus = flag.Int("cpus", runtime.NumCPU()-1, "the cpus to use")
	//var tcpNoDalay = flag.Bool("nodelay", false, "set TCP_NODELAY for connection")
	flag.Usage = func() {
		fmt.Println("Usage:[--port=int]")
		fmt.Println("		port,the listen port .default 9080")
	}
	flag.Parse()
	runtime.GOMAXPROCS(*nbCpus)
	InitStreamServer(*port)
	go StartStreamServer()
	beOver := 0
	for {
		time.Sleep(time.Second)
		if beOver > 1000 {
			break
		}
		fmt.Println(beOver, "was runing... ")
		beOver++
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/codegangsta/cli"
	"io/ioutil"
	"os"
	"time"
)

type TimeSlice struct {
	Start *time.Time `json:"start"`
	End   *time.Time `json:"end"`
}

func deserialize(ctxFileName string) (*TimeSlice, error) {
	content, errReadFile := ioutil.ReadFile(ctxFileName)
	if errReadFile != nil {
		return nil, errReadFile
	}

	var slice TimeSlice
	if errUnmarshal := json.Unmarshal(content, &slice); errUnmarshal != nil {
		return nil, errUnmarshal
	}

	return &slice, nil
}

func switchContext(c *cli.Context) {
	ctxFileName := os.ExpandEnv(c.GlobalString("ctxfile"))
	now := time.Now()
	slice := TimeSlice{
		Start: &now,
		End:   nil,
	}
	sliceJson, errMarshal := json.Marshal(slice)
	if errMarshal != nil {
		fmt.Println("Cannot serialize to JSON: %s", errMarshal)
		return
	}

	err := ioutil.WriteFile(ctxFileName, sliceJson, 0644)

	if err != nil {
		fmt.Println("Cannot write %s: %s", ctxFileName, err)
		return
	}

	fmt.Printf("You're working on %s", ctxFileName)
}

func info(c *cli.Context) {
	ctxFileName := os.ExpandEnv(c.GlobalString("ctxfile"))

	slice, err := deserialize(ctxFileName)
	if err != nil {
		fmt.Printf("%s", err)
		return
	}
	now := time.Now()
	duration := now.Sub(*slice.Start)
	fmt.Println(duration)
}

func main() {
	app := cli.NewApp()
	app.Name = "ctx"
	app.Usage = "CLI command to manage your working context"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "ctxfile,f",
			Value: "${HOME}/.ctx",
			Usage: "Path to the context file",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:    "switch",
			Aliases: []string{"s"},
			Action:  switchContext,
		},
		{
			Name:    "info",
			Aliases: []string{"i"},
			Action:  info,
		},
	}
	app.Run(os.Args)
}
<commit_msg>Work with slices<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/codegangsta/cli"
	"io/ioutil"
	"os"
	"time"
)

type TimeSlice struct {
	Start *time.Time `json:"start"`
	End   *time.Time `json:"end"`
}

const InvalidDuration = time.Duration(-1)

func (timeSlice *TimeSlice) Duration() time.Duration {
	if timeSlice.Start == nil {
		return InvalidDuration
	}
	if timeSlice.End == nil {
		return InvalidDuration
	}

	return timeSlice.End.Sub(*timeSlice.Start)
}

func (timeSlice *TimeSlice) IsComplete() bool {
	return timeSlice.End != nil
}

func deserialize(ctxFileName string) ([]TimeSlice, error) {
	content, errReadFile := ioutil.ReadFile(ctxFileName)
	if errReadFile != nil {
		return nil, errReadFile
	}

	var slices []TimeSlice
	if errUnmarshal := json.Unmarshal(content, &slices); errUnmarshal != nil {
		return nil, errUnmarshal
	}

	return slices, nil
}

func switchContext(c *cli.Context) {
	ctxFileName := os.ExpandEnv(c.GlobalString("ctxfile"))

	now := time.Now()
	slice := TimeSlice{
		Start: &now,
		End:   nil,
	}
	sliceJson, errMarshal := json.Marshal(slice)
	if errMarshal != nil {
		fmt.Println("Cannot serialize to JSON: %s", errMarshal)
		return
	}

	err := ioutil.WriteFile(ctxFileName, sliceJson, 0644)

	if err != nil {
		fmt.Println("Cannot write %s: %s", ctxFileName, err)
		return
	}

	fmt.Printf("You're working on %s", ctxFileName)
}

func info(c *cli.Context) {
	ctxFileName := os.ExpandEnv(c.GlobalString("ctxfile"))

	slices, err := deserialize(ctxFileName)
	if err != nil {
		fmt.Printf("%s", err)
		return
	}

	if len(slices) == 0 {
		fmt.Println("You have not started a context")
		return
	}

	var duration time.Duration

	for _, slice := range slices {
		if slice.IsComplete() {
			duration += slice.Duration()
		}
	}

	lastSlice := slices[len(slices)-1]
	if !lastSlice.IsComplete() {
		now := time.Now()
		duration += now.Sub(*lastSlice.Start)
	}

	fmt.Println(duration)
}

func main() {
	app := cli.NewApp()
	app.Name = "ctx"
	app.Usage = "CLI command to manage your working context"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "ctxfile,f",
			Value: "${HOME}/.ctx",
			Usage: "Path to the context file",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:    "switch",
			Aliases: []string{"s"},
			Action:  switchContext,
		},
		{
			Name:    "info",
			Aliases: []string{"i"},
			Action:  info,
		},
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/hex"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net"
	"os"
	"strings"
)

func printToConn(conn net.Conn, message string, interpreted bool) {
	if interpreted {
		dst := make([]byte, hex.DecodedLen(len(message)))
		n, err := hex.Decode(dst, []byte(message))
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(dst[:n])
		conn.Write(dst[:n])
	} else {
		fmt.Println(conn)
		fmt.Fprintf(conn, message)
	}
}

func main() {
	BytePtr := flag.Bool("b", false, "Send as interpreted bytes")
	WaitPtr := flag.Bool("w", false, "Wait for a response after each message")

	flag.Parse()

	buff := bufio.NewReader(os.Stdin)

	if len(flag.Args()) < 1 {
		fmt.Println("You need to specify an address")
		os.Exit(0)
	}
	conn, err := net.Dial("tcp", flag.Args()[0])

	if err != nil {
		log.Fatal(err)
	}

	for {
		line, hasMoreInLine, err := buff.ReadLine()

		strLine := string(line)

		if err != nil && err != io.EOF {
			log.Fatal(err)
		}

		if *BytePtr {
			payload := strings.Split(strLine, " ")

			var data []byte

			for _, v := range payload {
				dst := make([]byte, hex.DecodedLen(len(v)))
				n, err := hex.Decode(dst, []byte(v))
				if err != nil {
					log.Fatal(err)
				}
				data = append(data, dst[:n]...)
			}

			conn.Write(data)
		} else {
			fmt.Println(conn)
			fmt.Fprintf(conn, strLine)
		}

		if *WaitPtr {
			fmt.Println(ioutil.ReadAll(conn))
		}

		if hasMoreInLine || err == io.EOF {
			break
		}

	}

}
<commit_msg>Late commit are always aweful<commit_after>package main

import (
	"bufio"
	"encoding/hex"
	"flag"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"strings"
)

func main() {
	BytePtr := flag.Bool("b", false, "Send as interpreted bytes")

	flag.Parse()

	buff := bufio.NewReader(os.Stdin)

	if len(flag.Args()) < 1 {
		fmt.Println("You need to specify an address")
		os.Exit(0)
	}
	conn, err := net.Dial("tcp", flag.Args()[0])

	if err != nil {
		log.Fatal(err)
	}

	for {
		line, hasMoreInLine, err := buff.ReadLine()

		strLine := string(line)

		if err != nil && err != io.EOF {
			log.Fatal(err)
		}

		if *BytePtr {
			payload := strings.Split(strLine, " ")

			var data []byte

			for _, v := range payload {
				dst := make([]byte, hex.DecodedLen(len(v)))
				n, err := hex.Decode(dst, []byte(v))
				if err != nil {
					log.Fatal(err)
				}
				data = append(data, dst[:n]...)
			}

			conn.Write(data)
		} else {
			fmt.Println(conn)
			fmt.Fprintf(conn, strLine)
		}

		r := make([]byte, 1024)

		_, err = conn.Read(r)
		println("Reply =>", r)

		if hasMoreInLine || err == io.EOF {
			break
		}

	}

}
<|endoftext|>


<commit_before>// Declare this file to be part of the main package so it can be compiled into
// an executable.
package main

// Import all Go packages required for this file.
import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/bwmarrin/discordgo"
)

// Declare a constant that stores the Disgord version information.
const Version = "v0.0.0-alpha"

// Declare a DiscordGo Session in the global space so it can be easily used
// throughout this program.
// In this use case, there is no error that would be returned.
var Session, _ = discordgo.New()

// Read in all configuration options from both environment variables and
// command line arguments.
func init() {

	// Discord Authentication Token
	Session.Token = os.Getenv("DG_TOKEN")
	if Session.Token == "" {
		flag.StringVar(&Session.Token, "t", "", "Discord Authentication Token")
	}
}

func main() {

	// Declare any variables needed later.
	var err error

	// Print out a fancy logo!
	fmt.Printf(`
	________  .__                               .___
	\______ \ |__| ______ ____   ___________  __| _/
	||    |  \|  |/  ___// ___\ /  _ \_  __ \/ __ |
	||    '   \  |\___ \/ /_/  >  <_> )  | \/ /_/ |
	||______  /__/____  >___  / \____/|__|  \____ |
	\_______\/        \/_____/   %-16s\/`+"\n\n", Version)

	// Parse command line arguments
	flag.Parse()

	// Verify a Token was provided
	if Session.Token == "" {
		log.Println("You must provide a Discord authentication token.")
		return
	}

	// Verify the Token is valid and grab user information
	Session.State.User, err = Session.User("@me")
	if err != nil {
		log.Printf("error fetching user information, %s\n", err)
	}

	// Open a websocket connection to Discord
	err = Session.Open()
	if err != nil {
		log.Printf("error opening connection to Discord, %s\n", err)
	}

	// Wait for a CTRL-C
	log.Printf(`Now running. Press CTRL-C to exit.`)
	sc := make(chan os.Signal, 1)
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
	<-sc

	// Clean up
	Session.Close()

	// Exit Normally.
}
<commit_msg>Lint..<commit_after>// Declare this file to be part of the main package so it can be compiled into
// an executable.
package main

// Import all Go packages required for this file.
import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/bwmarrin/discordgo"
)

// Version is a constant that stores the Disgord version information.
const Version = "v0.0.0-alpha"

// Session is declared in the global space so it can be easily used
// throughout this program.
// In this use case, there is no error that would be returned.
var Session, _ = discordgo.New()

// Read in all configuration options from both environment variables and
// command line arguments.
func init() {

	// Discord Authentication Token
	Session.Token = os.Getenv("DG_TOKEN")
	if Session.Token == "" {
		flag.StringVar(&Session.Token, "t", "", "Discord Authentication Token")
	}
}

func main() {

	// Declare any variables needed later.
	var err error

	// Print out a fancy logo!
	fmt.Printf(`
	________  .__                               .___
	\______ \ |__| ______ ____   ___________  __| _/
	||    |  \|  |/  ___// ___\ /  _ \_  __ \/ __ |
	||    '   \  |\___ \/ /_/  >  <_> )  | \/ /_/ |
	||______  /__/____  >___  / \____/|__|  \____ |
	\_______\/        \/_____/   %-16s\/`+"\n\n", Version)

	// Parse command line arguments
	flag.Parse()

	// Verify a Token was provided
	if Session.Token == "" {
		log.Println("You must provide a Discord authentication token.")
		return
	}

	// Verify the Token is valid and grab user information
	Session.State.User, err = Session.User("@me")
	if err != nil {
		log.Printf("error fetching user information, %s\n", err)
	}

	// Open a websocket connection to Discord
	err = Session.Open()
	if err != nil {
		log.Printf("error opening connection to Discord, %s\n", err)
	}

	// Wait for a CTRL-C
	log.Printf(`Now running. Press CTRL-C to exit.`)
	sc := make(chan os.Signal, 1)
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
	<-sc

	// Clean up
	Session.Close()

	// Exit Normally.
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"fmt"
	"github.com/gorilla/mux"
	"github.com/srtkkou/zgok"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
)

type Certificates struct {
	CertFile string
	KeyFile  string
}

func loadX509KeyPair(certFile, keyFile string) (tls.Certificate, error) {
	certPEMBlock, err := readFromZfs(certFile)
	if err != nil {
		return tls.Certificate{}, err
	}
	keyPEMBlock, err := readFromZfs(keyFile)
	if err != nil {
		return tls.Certificate{}, err
	}
	return tls.X509KeyPair(certPEMBlock, keyPEMBlock)
}

func readFromZfs(filePath string) ([]byte, error) {
	zfs, _ := zgok.RestoreFileSystem(os.Args[0])
	if zfs != nil {
		// 本番環境
		return zfs.ReadFile(filePath)
	} else {
		// 開発環境
		return ioutil.ReadFile(filePath)
	}
}

func listenAndServeTLSSNI(srv *http.Server, certs []Certificates) error {
	addr := srv.Addr
	if addr == "" {
		addr = ":https"
	}
	config := &tls.Config{}
	if srv.TLSConfig != nil {
		*config = *srv.TLSConfig
	}
	if config.NextProtos == nil {
		config.NextProtos = []string{"http/1.1"}
	}

	var err error

	config.Certificates = make([]tls.Certificate, len(certs))
	for i, v := range certs {
		config.Certificates[i], err = loadX509KeyPair(v.CertFile, v.KeyFile)
		if err != nil {
			return err
		}
	}

	config.BuildNameToCertificate()

	conn, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	tlsListener := tls.NewListener(conn, config)
	return srv.Serve(tlsListener)
}

func proxy3000() *httputil.ReverseProxy {
	remote3000, err3000 := url.Parse("http://lvh.me:3000")
	if err3000 != nil {
		panic(err3000)
	}

	return httputil.NewSingleHostReverseProxy(remote3000)
}

func proxy3001() *httputil.ReverseProxy {
	remote3001, err3001 := url.Parse("http://lvh.me:3001")
	if err3001 != nil {
		panic(err3001)
	}

	return httputil.NewSingleHostReverseProxy(remote3001)
}

func certManaboInfo() Certificates {
	return Certificates{
		CertFile: "ssl/manabo-info/fullchain.pem",
		KeyFile:  "ssl/manabo-info/privkey.pem",
	}
}

func certBoardManaboInfo() Certificates {
	return Certificates{
		CertFile: "ssl/board-manabo-info/fullchain.pem",
		KeyFile:  "ssl/board-manabo-info/privkey.pem",
	}
}

func main() {
	var certs []Certificates

	certs = append(certs, certManaboInfo())
	certs = append(certs, certBoardManaboInfo())

	route := mux.NewRouter()
	route.Host("manabo.info").PathPrefix("/").Handler(proxy3000())
	route.Host("board.manabo.info").PathPrefix("/").Handler(proxy3001())

	httpsServer := &http.Server{
		Addr:    ":443",
		Handler: route,
	}

	fmt.Println("Listening on port 443...")
	err := listenAndServeTLSSNI(httpsServer, certs)
	if err != nil {
		fmt.Printf("err: %s", err)
	}
}
<commit_msg>Support reverse proxy for socket.io.<commit_after>package main

import (
	"crypto/tls"
	"fmt"
	"github.com/dddaisuke/httputil2"
	"github.com/gorilla/mux"
	"github.com/srtkkou/zgok"
	"github.com/yhat/wsutil"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
)

type Certificates struct {
	CertFile string
	KeyFile  string
}

func loadX509KeyPair(certFile, keyFile string) (tls.Certificate, error) {
	certPEMBlock, err := readFromZfs(certFile)
	if err != nil {
		return tls.Certificate{}, err
	}
	keyPEMBlock, err := readFromZfs(keyFile)
	if err != nil {
		return tls.Certificate{}, err
	}
	return tls.X509KeyPair(certPEMBlock, keyPEMBlock)
}

func readFromZfs(filePath string) ([]byte, error) {
	zfs, _ := zgok.RestoreFileSystem(os.Args[0])
	if zfs != nil {
		// 本番環境
		return zfs.ReadFile(filePath)
	} else {
		// 開発環境
		return ioutil.ReadFile(filePath)
	}
}

func listenAndServeTLSSNI(srv *http.Server, certs []Certificates) error {
	addr := srv.Addr
	if addr == "" {
		addr = ":https"
	}
	config := &tls.Config{}
	if srv.TLSConfig != nil {
		*config = *srv.TLSConfig
	}
	if config.NextProtos == nil {
		config.NextProtos = []string{"http/1.1"}
	}

	var err error

	config.Certificates = make([]tls.Certificate, len(certs))
	for i, v := range certs {
		config.Certificates[i], err = loadX509KeyPair(v.CertFile, v.KeyFile)
		if err != nil {
			return err
		}
	}

	config.BuildNameToCertificate()

	conn, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	tlsListener := tls.NewListener(conn, config)
	return srv.Serve(tlsListener)
}

func proxy3000() *httputil.ReverseProxy {
	remote3000, err3000 := url.Parse("http://127.0.0.1:3000")
	if err3000 != nil {
		panic(err3000)
	}

	return httputil.NewSingleHostReverseProxy(remote3000)
}

func proxy3001() *httputil2.ReverseProxy {
	remote3001, err3001 := url.Parse("http://127.0.0.1:3001")
	if err3001 != nil {
		panic(err3001)
	}

	return httputil2.NewSingleHostReverseProxy(remote3001)
}

func proxy8080() *httputil.ReverseProxy {
	remote8080, err8080 := url.Parse("http://127.0.0.1:8080")
	if err8080 != nil {
		panic(err8080)
	}

	return httputil.NewSingleHostReverseProxy(remote8080)
}

func certManaboInfo() Certificates {
	return Certificates{
		CertFile: "ssl/manabo-info/fullchain.pem",
		KeyFile:  "ssl/manabo-info/privkey.pem",
	}
}

func certBoardManaboInfo() Certificates {
	return Certificates{
		CertFile: "ssl/board-manabo-info/fullchain.pem",
		KeyFile:  "ssl/board-manabo-info/privkey.pem",
	}
}

func main() {
	var certs []Certificates

	certs = append(certs, certManaboInfo())
	certs = append(certs, certBoardManaboInfo())

	route := mux.NewRouter()
	route.Host("manabo.info").PathPrefix("/").Handler(proxy3000())

	backendURL := &url.URL{Scheme: "ws://", Host: "127.0.0.1:8080"}
	p := wsutil.NewSingleHostReverseProxy(backendURL)
	route.Host("board.manabo.info").PathPrefix("/socket.io/1/websocket/").Handler(p)
	route.Host("board.manabo.info").PathPrefix("/socket.io/").Handler(proxy8080())
	route.Host("board.manabo.info").PathPrefix("/").Handler(proxy3001())

	httpsServer := &http.Server{
		Addr:    ":443",
		Handler: route,
	}

	fmt.Println("Listening on port 443...")
	err := listenAndServeTLSSNI(httpsServer, certs)
	if err != nil {
		fmt.Printf("err: %s", err)
	}
}
<|endoftext|>