<commit_before>package main

import (
	"flag"
	"fmt"
	"net"
	"os"
	"os/signal"
	"runtime"
	"syscall"

	"github.com/Sirupsen/logrus"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
)

var ip, command, gateway, intf, logLevel, nsPath, mac string
var latency, jitter uint
var mtu int
var loss float64
var log = logrus.New()
var namespace, origns *netns.NsHandle
var proc *os.Process
var done = make(chan struct{})
var err error
var eth netlink.Link
var gwaddr net.IP
var addr *netlink.Addr

func init() {
	// Parse the arguments
	flag.StringVar(&ip, "ip", "192.168.1.11/24", "IP network from where the command will be executed")
	flag.StringVar(&intf, "interface", "eth0", "interface used to get out of the network")
	flag.StringVar(&command, "command", "ip route", "command to be executed")
	flag.StringVar(&gateway, "gw", "", "gateway of the request (default will be the default route of the given interface)")
	flag.StringVar(&logLevel, "log-level", "info", "min level of logs to print")
	flag.StringVar(&mac, "mac", "", "mac address of the interface inside the namespace (default will be a random one)")
	flag.UintVar(&latency, "latency", 0, "latency added on the interface in ms")
	flag.UintVar(&jitter, "jitter", 0, "jitter added on the interface in ms")
	flag.Float64Var(&loss, "loss", 0, "loss added on the interface in percentage")
	flag.IntVar(&mtu, "mtu", 0, "MTU of the interface")
	flag.StringVar(
		&nsPath,
		"ns-path",
		"",
		"path of the temporary namespace to be created (default will be /var/run/netns/w000t$PID)",
	)
	flag.Parse()
}

func initVar() error {
	lvl, err := logrus.ParseLevel(logLevel)
	if err != nil {
		logrus.Errorf("invalid log level %q: %q", logLevel, err)
		return err
	}

	// Setup the logger
	log.Level = lvl
	log.Out = os.Stdout
	log.Formatter = &logrus.TextFormatter{
		FullTimestamp: true,
	}

	// Check the /run/netns mount
	err = setupNetnsDir()
	if err != nil {
		log.Warn("Error setting up netns: ", err)
		return err
	}

	// Get the link
	eth, err = netlink.LinkByName(intf)
	if err != nil {
		log.Warnf("Error while getting %s : %s", intf, err)
		return err
	}
	log.Debugf("%s : %+v", intf, eth.Attrs().Flags)

	// If no nsPath is given, we'll use one named like
	// /var/run/netns/w000t$PID
	if nsPath == "" {
		nsPath = fmt.Sprintf("/var/run/netns/w000t%d", os.Getpid())
	}

	// If no gateway is specified, we'll use the first route of the given interface
	if gateway == "" {
		// Get the routes
		routes, err := netlink.RouteList(eth, netlink.FAMILY_V4)
		if err != nil {
			log.Warn("Failed to get the route of the interface: ", err)
			return err
		}

		for _, r := range routes {
			if r.Gw != nil {
				gateway = r.Gw.String()
				break
			}
		}
		if gateway == "" {
			return fmt.Errorf("Couldn't find a default gateway for the specified interface")
		}
	}
	gwaddr = net.ParseIP(gateway)

	// Parse the IP
	addr, err = netlink.ParseAddr(ip)
	if err != nil {
		log.Warn("Failed to parse the given IP: ", err)
		return err
	}
	return nil
}

func main() {
	// Lock the OS Thread so we don't accidentally switch namespaces
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	// Get the current network namespace
	origns, err = getOriginalNS()
	if err != nil {
		panic(fmt.Sprintf("panic when getting netns: %s", err))
	}
	defer origns.Close()

	// Init de main variables
	err = initVar()
	if err != nil {
		panic(fmt.Sprintf("panic when initializing vars: %s", err))
	}

	// ============================== Create the macVLAN

	log.Debug("Create a new macVlan")

	// Create the new macVlan interface
	link, err := newMacVLAN()
	if err != nil {
		log.Warn("Error while creating macVlan: ", err)
		return
	}

	// ============================= Set the mac address to the macVlan interface

	err = setMacVlanMacAddr(link)
	if err != nil {
		log.Warn("Error while setting vlan mac: ", err)
		return
	}

	// ============================= Set the mtu of the macVlan interface

	err = setMacVlanMTU(link)
	if err != nil {
		log.Warn("Error while setting vlan MTU: ", err)
		return
	}

	// ============================== Create the new Namespace

	namespace, err = newNS()
	if err != nil {
		log.Warn("error while creating new NS: ", err)
		return
	}
	defer deleteNS(namespace)

	log.Debug("Go back to original NS : ", int(*origns))

	err = netns.Set(*origns)
	if err != nil {
		log.Warn("Failed to change the namespace: ", err)
		return
	}

	// ============================== Add the MacVlan in the new Namespace

	log.Debug("Set the link in the NS")

	if err := netlink.LinkSetNsFd(*link, int(*namespace)); err != nil {
		log.Warn("Could not attach to Network namespace: ", err)
		return
	}
	// ============================= Enter the new namespace to configure it

	log.Debug("Enter the namespace")

	err = netns.Set(*namespace)
	if err != nil {
		log.Warn("Failed to enter the namespace: ", err)
		return
	}

	// ============================= Configure the new namespace to configure it

	log.Debugf("Add the addr to the macVlan: %+v", addr)

	// ============================= Set the address in the namespace

	err = netlink.AddrAdd(*link, addr)
	if err != nil {
		log.Warn("Failed to add the IP to the macVlan: ", err)
		return
	}

	log.Debug("Set the macVlan interface UP")

	// ============================= Set the link up in the namespace

	err = netlink.LinkSetUp(*link)
	if err != nil {
		log.Warn("Error while setting up the interface peth0: ", err)
		return
	}

	err = setTcAttributes(link)
	if err != nil {
		log.Warn("Error while setting up the interface TC attributes: ", err)
		return
	}

	// ============================= Set the default route in the namespace

	err = setLinkRoute(link)
	if err != nil {
		log.Warn("Error while setting up the interface route: ", err)
		return
	}
	// ============================= Execute the command in the namespace

	// Create a channel that will listen to SIGINT / SIGTERM
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT)
	signal.Notify(c, syscall.SIGTERM)

	// Wait for the process to end
	go func() {
		for {
			select {
			// If we recieve a signal, we let it flow to the process
			case signal := <-c:
				log.Debugf("Got a %s", signal.String())
			// If the process is done, we exit properly
			case <-done:
				log.Debugf("Process exited properly, exiting")
				return
			}
		}
	}()

	// Launch the command in a go routine
	err = execCmd(command)
	if err != nil {
		log.Warn("Error while running command : ", err)
	}
	done <- struct{}{}

	log.Debug("Go back to orignal namspace")

	err = netns.Set(*origns)
	if err != nil {
		log.Warn("Error while going back to the original namespace: ", err)
		return
	}

	log.Debug("Exiting properly ...")
}
<commit_msg>Fix rangeValCopy-ref<commit_after>package main

import (
	"flag"
	"fmt"
	"net"
	"os"
	"os/signal"
	"runtime"
	"syscall"

	"github.com/Sirupsen/logrus"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
)

var ip, command, gateway, intf, logLevel, nsPath, mac string
var latency, jitter uint
var mtu int
var loss float64
var log = logrus.New()
var namespace, origns *netns.NsHandle
var proc *os.Process
var done = make(chan struct{})
var err error
var eth netlink.Link
var gwaddr net.IP
var addr *netlink.Addr

func init() {
	// Parse the arguments
	flag.StringVar(&ip, "ip", "192.168.1.11/24", "IP network from where the command will be executed")
	flag.StringVar(&intf, "interface", "eth0", "interface used to get out of the network")
	flag.StringVar(&command, "command", "ip route", "command to be executed")
	flag.StringVar(&gateway, "gw", "", "gateway of the request (default will be the default route of the given interface)")
	flag.StringVar(&logLevel, "log-level", "info", "min level of logs to print")
	flag.StringVar(&mac, "mac", "", "mac address of the interface inside the namespace (default will be a random one)")
	flag.UintVar(&latency, "latency", 0, "latency added on the interface in ms")
	flag.UintVar(&jitter, "jitter", 0, "jitter added on the interface in ms")
	flag.Float64Var(&loss, "loss", 0, "loss added on the interface in percentage")
	flag.IntVar(&mtu, "mtu", 0, "MTU of the interface")
	flag.StringVar(
		&nsPath,
		"ns-path",
		"",
		"path of the temporary namespace to be created (default will be /var/run/netns/w000t$PID)",
	)
	flag.Parse()
}

func initVar() error {
	lvl, err := logrus.ParseLevel(logLevel)
	if err != nil {
		logrus.Errorf("invalid log level %q: %q", logLevel, err)
		return err
	}

	// Setup the logger
	log.Level = lvl
	log.Out = os.Stdout
	log.Formatter = &logrus.TextFormatter{
		FullTimestamp: true,
	}

	// Check the /run/netns mount
	err = setupNetnsDir()
	if err != nil {
		log.Warn("Error setting up netns: ", err)
		return err
	}

	// Get the link
	eth, err = netlink.LinkByName(intf)
	if err != nil {
		log.Warnf("Error while getting %s : %s", intf, err)
		return err
	}
	log.Debugf("%s : %+v", intf, eth.Attrs().Flags)

	// If no nsPath is given, we'll use one named like
	// /var/run/netns/w000t$PID
	if nsPath == "" {
		nsPath = fmt.Sprintf("/var/run/netns/w000t%d", os.Getpid())
	}

	// If no gateway is specified, we'll use the first route of the given interface
	if gateway == "" {
		// Get the routes
		routes, err := netlink.RouteList(eth, netlink.FAMILY_V4)
		if err != nil {
			log.Warn("Failed to get the route of the interface: ", err)
			return err
		}

		for i := range routes {
			if routes[i].Gw != nil {
				gateway = routes[i].Gw.String()
				break
			}
		}
		if gateway == "" {
			return fmt.Errorf("Couldn't find a default gateway for the specified interface")
		}
	}
	gwaddr = net.ParseIP(gateway)

	// Parse the IP
	addr, err = netlink.ParseAddr(ip)
	if err != nil {
		log.Warn("Failed to parse the given IP: ", err)
		return err
	}
	return nil
}

func main() {
	// Lock the OS Thread so we don't accidentally switch namespaces
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	// Get the current network namespace
	origns, err = getOriginalNS()
	if err != nil {
		panic(fmt.Sprintf("panic when getting netns: %s", err))
	}
	defer origns.Close()

	// Init de main variables
	err = initVar()
	if err != nil {
		panic(fmt.Sprintf("panic when initializing vars: %s", err))
	}

	// ============================== Create the macVLAN

	log.Debug("Create a new macVlan")

	// Create the new macVlan interface
	link, err := newMacVLAN()
	if err != nil {
		log.Warn("Error while creating macVlan: ", err)
		return
	}

	// ============================= Set the mac address to the macVlan interface

	err = setMacVlanMacAddr(link)
	if err != nil {
		log.Warn("Error while setting vlan mac: ", err)
		return
	}

	// ============================= Set the mtu of the macVlan interface

	err = setMacVlanMTU(link)
	if err != nil {
		log.Warn("Error while setting vlan MTU: ", err)
		return
	}

	// ============================== Create the new Namespace

	namespace, err = newNS()
	if err != nil {
		log.Warn("error while creating new NS: ", err)
		return
	}
	defer deleteNS(namespace)

	log.Debug("Go back to original NS : ", int(*origns))

	err = netns.Set(*origns)
	if err != nil {
		log.Warn("Failed to change the namespace: ", err)
		return
	}

	// ============================== Add the MacVlan in the new Namespace

	log.Debug("Set the link in the NS")

	if err := netlink.LinkSetNsFd(*link, int(*namespace)); err != nil {
		log.Warn("Could not attach to Network namespace: ", err)
		return
	}
	// ============================= Enter the new namespace to configure it

	log.Debug("Enter the namespace")

	err = netns.Set(*namespace)
	if err != nil {
		log.Warn("Failed to enter the namespace: ", err)
		return
	}

	// ============================= Configure the new namespace to configure it

	log.Debugf("Add the addr to the macVlan: %+v", addr)

	// ============================= Set the address in the namespace

	err = netlink.AddrAdd(*link, addr)
	if err != nil {
		log.Warn("Failed to add the IP to the macVlan: ", err)
		return
	}

	log.Debug("Set the macVlan interface UP")

	// ============================= Set the link up in the namespace

	err = netlink.LinkSetUp(*link)
	if err != nil {
		log.Warn("Error while setting up the interface peth0: ", err)
		return
	}

	err = setTcAttributes(link)
	if err != nil {
		log.Warn("Error while setting up the interface TC attributes: ", err)
		return
	}

	// ============================= Set the default route in the namespace

	err = setLinkRoute(link)
	if err != nil {
		log.Warn("Error while setting up the interface route: ", err)
		return
	}
	// ============================= Execute the command in the namespace

	// Create a channel that will listen to SIGINT / SIGTERM
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT)
	signal.Notify(c, syscall.SIGTERM)

	// Wait for the process to end
	go func() {
		for {
			select {
			// If we recieve a signal, we let it flow to the process
			case signal := <-c:
				log.Debugf("Got a %s", signal.String())
			// If the process is done, we exit properly
			case <-done:
				log.Debugf("Process exited properly, exiting")
				return
			}
		}
	}()

	// Launch the command in a go routine
	err = execCmd(command)
	if err != nil {
		log.Warn("Error while running command : ", err)
	}
	done <- struct{}{}

	log.Debug("Go back to orignal namspace")

	err = netns.Set(*origns)
	if err != nil {
		log.Warn("Error while going back to the original namespace: ", err)
		return
	}

	log.Debug("Exiting properly ...")
}
<|endoftext|>


<commit_before>package main

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

	"github.com/oct2pus/jadebot/command"
	"github.com/oct2pus/jadebot/markov"

	"github.com/oct2pus/bocto"
)

var (
	// emoji is a mapping to emojis for the sake of convience.
	// Do not edit it at runtime.
	emoji = map[string]string{
		"thinking":   "<:jbthink:601863277546569779>",
		"headpat":    "<:jbheadpat:601863276581748746>",
		"embarassed": "<:jbembarassed:601863277122813953>",
		"teefs":      "<:jbteefs:601863276833406976>",
		"owo":        "<:jbowo:601863276560777220>",
		"heart":      "💚",
	}
)

const (
	pre = "==>"
)

func main() {
	var token string
	var jade bocto.Bot
	flag.StringVar(&token, "t", "", "Bot Token")
	flag.Parse()

	err := jade.New("JadeBot", pre, token,
		"hello! :D\nby the way my prefix is `"+pre+"`. just incase you"+
			" wanted to know! :p",
		"i don't understand, maybe you should ask for `"+pre+"help` ;P", 0x4bec13)
	if err != nil {
		fmt.Printf("%v can't login\nerror: %v\n", jade.Name, err)
		return
	}
	// add commands and responses
	jade = addCommands(jade)
	jade = addPhrases(jade)
	// Event Handlers
	jade.Session.AddHandler(jade.ReadyEvent)
	jade.Session.AddHandler(jade.MessageCreate)
	// Open Bot
	err = jade.Session.Open()
	if err != nil {
		fmt.Printf("Error openning connection: %v\nDump bot info %v\n",
			err,
			jade.String())
	}
	// wait for ctrl+c to close.
	signalClose := make(chan os.Signal, 1)

	signal.Notify(signalClose,
		syscall.SIGINT,
		syscall.SIGTERM,
		os.Interrupt,
		os.Kill)
	<-signalClose

	jade.Session.Close()
}

func addCommands(bot bocto.Bot) bocto.Bot {
	// alphabetical order, shorter first
	// emojis last, alphabetical order by emoji name
	bot.AddCommand("about", command.Credits)
	bot.AddCommand("avatar", command.Avatar)
	bot.AddCommand("booru", command.Booru)
	//	bot.AddCommand("candy", command.Candy)
	bot.AddCommand("command", command.Help)
	bot.AddCommand("commands", command.Help)
	bot.AddCommand("credits", command.Credits)
	bot.AddCommand("discord", command.Discord)
	bot.AddCommand("dog", command.Dog)
	bot.AddCommand("doge", command.Doge)
	bot.AddCommand("help", command.Help)
	//	bot.AddCommand("epilogue", command.Epilogue)
	//	bot.AddCommand("epilogues", command.Epilogue)
	//	bot.AddCommand("homestuck", command.Homestuck)
	//	bot.AddCommand("hs", command.Homestuck)
	bot.AddCommand("invite", command.Invite)
	//	bot.AddCommand("meat", command.Meat)
	bot.AddCommand("mspa", command.Booru)
	bot.AddCommand("otp", command.OTP)
	//	bot.AddCommand("prologue", command.Prologue)
	//	bot.AddCommand("sbahj", command.SBAHJ)
	bot.AddCommand("ship", command.OTP)
	bot.AddCommand("wiki", command.Wiki)
	//	bot.AddCommand("🍬", command.Candy)
	//	bot.AddCommand("🍖", command.Meat)

	// if no model.json exist, disable markov commands
	// if model.json exists but does not parse, disable markov commands
	if markovSupport() {
		bot.AddCommand("", command.ReminderMarkov)
		bot.AddCommand("pester", command.Markov)
		bot.AddCommand("markov", command.Markov)
	} else {
		bot.AddCommand("", command.Reminder)
	}

	return bot
}

func addPhrases(bot bocto.Bot) bocto.Bot {
	bot.AddPhrase("owo", []string{"oh woah whats this?", emoji["owo"]})
	bot.AddPhrase("love you jade", []string{"i love you too!!", emoji["teefs"] +
		emoji["heart"]})
	bot.AddPhrase("love jade", []string{"i love you too!!", emoji["teefs"] +
		emoji["heart"]})
	bot.AddPhrase("good dog", []string{"best friend", emoji["headpat"]})
	bot.AddPhrase("teef", []string{emoji["teefs"]})
	bot.AddPhrase("kissjade", []string{emoji["embarassed"] + emoji["heart"]})
	bot.AddPhrase("headpat", []string{emoji["headpat"]})
	bot.AddPhrase("*pap*", []string{emoji["headpat"]})
	bot.AddPhrase("soosh pap", []string{emoji["headpat"]})
	bot.AddPhrase("*pats*", []string{emoji["headpat"]})
	bot.AddPhrase(":think", []string{emoji["thinking"]})
	bot.AddPhrase("think:", []string{emoji["thinking"]})
	bot.AddPhrase("thinking:", []string{emoji["thinking"]})
	bot.AddPhrase("🤔", []string{emoji["thinking"]})

	return bot
}

// markovSupport does a runtime test to verify if the markov command will work.
// disables markov support if false
func markovSupport() bool {
	file := "model.json"
	skip := "Skipping markov commands."

	// test if file exists.
	if _, err := os.Stat(file); os.IsNotExist(err) {
		fmt.Printf("%v does not exist. %v\n", file, skip)
		return false
	}

	// test if file can be read.
	err := markov.Load(file)
	if err != nil {
		fmt.Printf("%v cannot be read. %v\n", file, skip)
		return false
	}

	// test if valid markov file.
	_, err = markov.Generate(1)
	if err != nil {
		fmt.Printf("%v is an invalid gomarkov model.json. %v\n", file, skip)
		return false
	}

	return true
}
<commit_msg>remove responses in preperation for command based responses<commit_after>package main

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

	"github.com/oct2pus/jadebot/command"
	"github.com/oct2pus/jadebot/db"
	"github.com/oct2pus/jadebot/markov"

	"github.com/oct2pus/bocto"
)

const (
	pre = "==>"
)

func main() {
	var token string
	var jade bocto.Bot
	flag.StringVar(&token, "t", "", "Bot Token")
	flag.Parse()
	// create bot
	err := jade.New("JadeBot", pre, token, 0x4bec13)
	if err != nil {
		fmt.Printf("%v can't login\nerror: %v\n", jade.Name, err)
		return
	}
	// initialize databases (if they do not exist)
	if db.InitDB() != nil {
		fmt.Printf("Cannot init database: %v\n", err)
		return
	}
	if db.CreateTable("reponses") != nil {
		fmt.Printf("Cannot create table: %v\n", err)
		return
	}
	if db.CreateTable("mspa") != nil {
		fmt.Printf("Cannot create table: %v\n", err)
		return
	}

	// add commands and responses
	jade = addCommands(jade)
	jade.Confused = command.Confused
	jade.Mentioned = command.Mentioned
	// Event Handlers
	jade.Session.AddHandler(jade.ReadyEvent)
	jade.Session.AddHandler(jade.MessageCreate)
	// Open Bot
	err = jade.Session.Open()
	if err != nil {
		fmt.Printf("Error openning connection: %v\nDump bot info %v\n",
			err,
			jade.String())
	}
	// wait for ctrl+c to close.
	signalClose := make(chan os.Signal, 1)

	signal.Notify(signalClose,
		syscall.SIGINT,
		syscall.SIGTERM,
		os.Interrupt,
		os.Kill)
	<-signalClose

	jade.Session.Close()
}

func addCommands(bot bocto.Bot) bocto.Bot {
	// alphabetical order, shorter first
	// emojis last, alphabetical order by emoji name
	bot.AddCommand("about", command.Credits)
	bot.AddCommand("avatar", command.Avatar)
	bot.AddCommand("booru", command.Booru)
	//	bot.AddCommand("candy", command.Candy)
	bot.AddCommand("command", command.Help)
	bot.AddCommand("commands", command.Help)
	bot.AddCommand("credits", command.Credits)
	bot.AddCommand("discord", command.Discord)
	bot.AddCommand("dog", command.Dog)
	bot.AddCommand("doge", command.Doge)
	bot.AddCommand("help", command.Help)
	//	bot.AddCommand("epilogue", command.Epilogue)
	//	bot.AddCommand("epilogues", command.Epilogue)
	//	bot.AddCommand("homestuck", command.Homestuck)
	//	bot.AddCommand("hs", command.Homestuck)
	bot.AddCommand("invite", command.Invite)
	//	bot.AddCommand("meat", command.Meat)
	bot.AddCommand("mspa", command.Booru)
	bot.AddCommand("otp", command.OTP)
	//	bot.AddCommand("prologue", command.Prologue)
	//	bot.AddCommand("sbahj", command.SBAHJ)
	bot.AddCommand("ship", command.OTP)
	bot.AddCommand("wiki", command.Wiki)
	//	bot.AddCommand("🍬", command.Candy)
	//	bot.AddCommand("🍖", command.Meat)

	// if no model.json exist, disable markov commands
	// if model.json exists but does not parse, disable markov commands
	if markovSupport() {
		bot.AddCommand("", command.ReminderMarkov)
		bot.AddCommand("pester", command.Markov)
		bot.AddCommand("markov", command.Markov)
	} else {
		bot.AddCommand("", command.Reminder)
	}

	return bot
}

/*
func addPhrases(bot bocto.Bot) bocto.Bot {
	bot.AddPhrase("owo", []string{"oh woah whats this?", emoji["owo"]})
	bot.AddPhrase("love you jade", []string{"i love you too!!", emoji["teefs"] +
		emoji["heart"]})
	bot.AddPhrase("love jade", []string{"i love you too!!", emoji["teefs"] +
		emoji["heart"]})
	bot.AddPhrase("good dog", []string{"best friend", emoji["headpat"]})
	bot.AddPhrase("teef", []string{emoji["teefs"]})
	bot.AddPhrase("kissjade", []string{emoji["embarassed"] + emoji["heart"]})
	bot.AddPhrase("headpat", []string{emoji["headpat"]})
	bot.AddPhrase("*pap*", []string{emoji["headpat"]})
	bot.AddPhrase("soosh pap", []string{emoji["headpat"]})
	bot.AddPhrase("*pats*", []string{emoji["headpat"]})
	bot.AddPhrase(":think", []string{emoji["thinking"]})
	bot.AddPhrase("think:", []string{emoji["thinking"]})
	bot.AddPhrase("thinking:", []string{emoji["thinking"]})
	bot.AddPhrase("🤔", []string{emoji["thinking"]})

	return bot
}
*/
// markovSupport does a runtime test to verify if the markov command will work.
// disables markov support if false
func markovSupport() bool {
	file := "model.json"
	skip := "Skipping markov commands."

	// test if file exists.
	if _, err := os.Stat(file); os.IsNotExist(err) {
		fmt.Printf("%v does not exist. %v\n", file, skip)
		return false
	}

	// test if file can be read.
	err := markov.Load(file)
	if err != nil {
		fmt.Printf("%v cannot be read. %v\n", file, skip)
		return false
	}

	// test if valid markov file.
	_, err = markov.Generate(1)
	if err != nil {
		fmt.Printf("%v is an invalid gomarkov model.json. %v\n", file, skip)
		return false
	}

	return true
}
<|endoftext|>


<commit_before>package main

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

	"github.com/tcnksm/go-gitconfig"
)

//go:generate go-bindata _templates/...

const (
	defaultVCS    = "github.com"
	modelDir      = "models"
	controllerDir = "controllers"
	targetFile    = "main.go"
)

func usage() {
	fmt.Fprintf(os.Stderr, `Usage of %s:
	%s new <project name>
	%s gen
`, os.Args[0], os.Args[0], os.Args[0])
	os.Exit(1)
}

func main() {

	if len(os.Args) < 2 {
		usage()
	}

	cmd := os.Args[1]

	switch cmd {
	case "gen":
		curDir, err := os.Getwd()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		if !fileExists(filepath.Join(curDir, targetFile)) || !fileExists(filepath.Join(curDir, modelDir)) {
			fmt.Fprintf(os.Stderr, `%s is not project root. Please move.
`, curDir)
			os.Exit(1)
		}
		cmdGen(curDir)

	case "new":
		var (
			vcs      string
			username string
		)

		flag := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

		flag.Usage = func() {
			fmt.Fprintf(os.Stderr, `Usage of %s:
	%s new <project name>

Options:
`, os.Args[0], os.Args[0])
			flag.PrintDefaults()
		}

		flag.StringVar(&vcs, "v", "", "VCS")
		flag.StringVar(&username, "u", "", "Username")

		if len(os.Args) < 3 {
			flag.Usage()
			os.Exit(1)
		}

		flag.Parse(os.Args[3:])

		if vcs == "" {
			vcs = defaultVCS
		}

		if username == "" {
			var err error
			username, err = gitconfig.GithubUser()

			if err != nil {
				username, err = gitconfig.Username()
				if err != nil {
					msg := "Cannot find `~/.gitconfig` file.\n" +
						"Please use -u option"
					fmt.Println(msg)
					os.Exit(1)
				}
			}
		}

		project := os.Args[2]

		detail := &Detail{VCS: vcs, User: username, Project: project}

		cmdNew(detail)

	default:
		usage()
	}

}

func cmdNew(detail *Detail) {
	gopath := os.Getenv("GOPATH")

	if gopath == "" {
		fmt.Println("Error: $GOPATH is not found")
		os.Exit(1)
	}

	outDir := filepath.Join(gopath, "src", detail.VCS, detail.User, detail.Project)

	if err := generateSkeleton(detail, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	fmt.Fprintf(os.Stdout, `===> Created %s
`, outDir)
}

func cmdGen(outDir string) {
	absModelDir := filepath.Join(outDir, modelDir)
	files, err := ioutil.ReadDir(absModelDir)

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	var models []*Model
	mmap := make(map[string]*Model)

	var wg sync.WaitGroup
	for _, file := range files {
		wg.Add(1)
		go func(f os.FileInfo) {
			defer wg.Done()
			if f.IsDir() {
				return
			}

			if !strings.HasSuffix(f.Name(), ".go") {
				return
			}

			modelPath := filepath.Join(absModelDir, f.Name())
			ms, err := parseModel(modelPath)

			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}

			for _, model := range ms {
				models = append(models, model)
				mmap[model.Name] = model
			}
		}(file)
	}
	wg.Wait()

	paths, err := parseMain(filepath.Join(outDir, targetFile))

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	importDir := formatImportDir(paths)

	switch {
	case len(importDir) > 1:
		fmt.Println("Error: Conflict import path. Please check 'main.go'.")
		os.Exit(1)

	case len(importDir) == 0:
		fmt.Println("Error: Can't refer import path. Please check 'main.go'.")
		os.Exit(1)
	}

	vcs := filepath.Base(filepath.Dir(filepath.Dir(importDir[0])))
	user := filepath.Base(filepath.Dir(importDir[0]))
	project := filepath.Base(importDir[0])

	for _, model := range models {
		wg.Add(1)
		go func(m *Model) {
			defer wg.Done()
			// Check association, stdout "model.Fields[0].Association.Type"
			resolveAssoc(m, mmap, make(map[string]bool))

			d := &Detail{
				Model:     m,
				ImportDir: importDir[0],
				VCS:       vcs,
				User:      user,
				Project:   project,
			}

			if err := generateApibModel(d, outDir); err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}

			if err := generateController(d, outDir); err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
		}(model)
	}
	wg.Wait()

	detail := &Detail{
		Models:    models,
		ImportDir: importDir[0],
		VCS:       vcs,
		User:      user,
		Project:   filepath.Base(importDir[0]),
	}

	if err := generateApibIndex(detail, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if err := generateRouter(detail, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if err := generateDB(detail, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if err := generateREADME(models, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	fmt.Println("===> Generated...")
}

func formatImportDir(paths []string) []string {
	results := make([]string, 0, len(paths))
	flag := map[string]bool{}
	for i := 0; i < len(paths); i++ {
		dir := filepath.Dir(paths[i])
		if !flag[dir] {
			flag[dir] = true
			results = append(results, dir)
		}
	}
	return results
}

func resolveAssoc(model *Model, mmap map[string]*Model, parents map[string]bool) {
	parents[model.Name] = true

	for i, field := range model.Fields {
		str := strings.Trim(field.Type, "[]*")
		if mmap[str] != nil && parents[str] != true {
			resolveAssoc(mmap[str], mmap, parents)

			var assoc int
			switch string([]rune(field.Type)[0]) {
			case "[":
				if validateFKey(mmap[str].Fields, model.Name) {
					assoc = AssociationHasMany
					break
				}
				assoc = AssociationBelongsTo

			default:
				if validateFKey(mmap[str].Fields, model.Name) {
					assoc = AssociationHasOne
					break
				}
				assoc = AssociationBelongsTo
			}
			model.Fields[i].Association = &Association{Type: assoc, Model: mmap[str]}
		} else {
			model.Fields[i].Association = &Association{Type: AssociationNone}
		}
	}
}

func validateFKey(fields []*Field, name string) bool {
	for _, field := range fields {
		val := name + "ID"
		if field.Name == val {
			return true
		}
	}
	return false
}
<commit_msg>Solider parse of github username<commit_after>package main

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

	"github.com/tcnksm/go-gitconfig"
)

//go:generate go-bindata _templates/...

const (
	defaultVCS    = "github.com"
	modelDir      = "models"
	controllerDir = "controllers"
	targetFile    = "main.go"
)

func usage() {
	fmt.Fprintf(os.Stderr, `Usage of %s:
	%s new <project name>
	%s gen
`, os.Args[0], os.Args[0], os.Args[0])
	os.Exit(1)
}

func main() {

	if len(os.Args) < 2 {
		usage()
	}

	cmd := os.Args[1]

	switch cmd {
	case "gen":
		curDir, err := os.Getwd()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		if !fileExists(filepath.Join(curDir, targetFile)) || !fileExists(filepath.Join(curDir, modelDir)) {
			fmt.Fprintf(os.Stderr, `%s is not project root. Please move.
`, curDir)
			os.Exit(1)
		}
		cmdGen(curDir)

	case "new":
		var (
			vcs      string
			username string
		)

		flag := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

		flag.Usage = func() {
			fmt.Fprintf(os.Stderr, `Usage of %s:
	%s new <project name>

Options:
`, os.Args[0], os.Args[0])
			flag.PrintDefaults()
		}

		flag.StringVar(&vcs, "v", "", "VCS")
		flag.StringVar(&username, "u", "", "Username")

		if len(os.Args) < 3 {
			flag.Usage()
			os.Exit(1)
		}

		flag.Parse(os.Args[3:])

		if vcs == "" {
			vcs = defaultVCS
		}

		if username == "" {
			var err error
			username, err = gitconfig.GithubUser()

			if err != nil {
				username, err = gitconfig.Username()
				if err != nil || strings.Contains(username, " ") {
					msg := "Cannot find github username in `~/.gitconfig` file.\n" +
						"Please use -u option"
					fmt.Println(msg)
					os.Exit(1)
				}
			}
		}

		project := os.Args[2]

		detail := &Detail{VCS: vcs, User: username, Project: project}

		cmdNew(detail)

	default:
		usage()
	}

}

func cmdNew(detail *Detail) {
	gopath := os.Getenv("GOPATH")

	if gopath == "" {
		fmt.Println("Error: $GOPATH is not found")
		os.Exit(1)
	}

	outDir := filepath.Join(gopath, "src", detail.VCS, detail.User, detail.Project)

	if err := generateSkeleton(detail, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	fmt.Fprintf(os.Stdout, `===> Created %s
`, outDir)
}

func cmdGen(outDir string) {
	absModelDir := filepath.Join(outDir, modelDir)
	files, err := ioutil.ReadDir(absModelDir)

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	var models []*Model
	mmap := make(map[string]*Model)

	var wg sync.WaitGroup
	for _, file := range files {
		wg.Add(1)
		go func(f os.FileInfo) {
			defer wg.Done()
			if f.IsDir() {
				return
			}

			if !strings.HasSuffix(f.Name(), ".go") {
				return
			}

			modelPath := filepath.Join(absModelDir, f.Name())
			ms, err := parseModel(modelPath)

			if err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}

			for _, model := range ms {
				models = append(models, model)
				mmap[model.Name] = model
			}
		}(file)
	}
	wg.Wait()

	paths, err := parseMain(filepath.Join(outDir, targetFile))

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	importDir := formatImportDir(paths)

	switch {
	case len(importDir) > 1:
		fmt.Println("Error: Conflict import path. Please check 'main.go'.")
		os.Exit(1)

	case len(importDir) == 0:
		fmt.Println("Error: Can't refer import path. Please check 'main.go'.")
		os.Exit(1)
	}

	vcs := filepath.Base(filepath.Dir(filepath.Dir(importDir[0])))
	user := filepath.Base(filepath.Dir(importDir[0]))
	project := filepath.Base(importDir[0])

	for _, model := range models {
		wg.Add(1)
		go func(m *Model) {
			defer wg.Done()
			// Check association, stdout "model.Fields[0].Association.Type"
			resolveAssoc(m, mmap, make(map[string]bool))

			d := &Detail{
				Model:     m,
				ImportDir: importDir[0],
				VCS:       vcs,
				User:      user,
				Project:   project,
			}

			if err := generateApibModel(d, outDir); err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}

			if err := generateController(d, outDir); err != nil {
				fmt.Fprintln(os.Stderr, err)
				os.Exit(1)
			}
		}(model)
	}
	wg.Wait()

	detail := &Detail{
		Models:    models,
		ImportDir: importDir[0],
		VCS:       vcs,
		User:      user,
		Project:   filepath.Base(importDir[0]),
	}

	if err := generateApibIndex(detail, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if err := generateRouter(detail, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if err := generateDB(detail, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if err := generateREADME(models, outDir); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	fmt.Println("===> Generated...")
}

func formatImportDir(paths []string) []string {
	results := make([]string, 0, len(paths))
	flag := map[string]bool{}
	for i := 0; i < len(paths); i++ {
		dir := filepath.Dir(paths[i])
		if !flag[dir] {
			flag[dir] = true
			results = append(results, dir)
		}
	}
	return results
}

func resolveAssoc(model *Model, mmap map[string]*Model, parents map[string]bool) {
	parents[model.Name] = true

	for i, field := range model.Fields {
		str := strings.Trim(field.Type, "[]*")
		if mmap[str] != nil && parents[str] != true {
			resolveAssoc(mmap[str], mmap, parents)

			var assoc int
			switch string([]rune(field.Type)[0]) {
			case "[":
				if validateFKey(mmap[str].Fields, model.Name) {
					assoc = AssociationHasMany
					break
				}
				assoc = AssociationBelongsTo

			default:
				if validateFKey(mmap[str].Fields, model.Name) {
					assoc = AssociationHasOne
					break
				}
				assoc = AssociationBelongsTo
			}
			model.Fields[i].Association = &Association{Type: assoc, Model: mmap[str]}
		} else {
			model.Fields[i].Association = &Association{Type: AssociationNone}
		}
	}
}

func validateFKey(fields []*Field, name string) bool {
	for _, field := range fields {
		val := name + "ID"
		if field.Name == val {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>// ipify-api
//
// This software implements a basic REST API that provides users with a simple
// way to query their public IP address (IPv4 or IPv6).  This code assumes that
// you are running it on Heroku's platform (https://www.heroku.com/).

package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"os"
)

// IPAddress is a simple struct that we use to marshal our JSON responses.
type IPAddress struct {
	IP string `json:"ip"`
}

// getIP returns a user's public facing IP address (IPv4 OR IPv6).
//
// By default, it will return the IP address in plain text, but can also return
// data in both JSON and JSONP if requested to.
func getIP(w http.ResponseWriter, r *http.Request) {

	// Enable CORS support.
	w.Header().Set("Access-Control-Allow-Origin", "*")

	err := r.ParseForm()
	if err != nil {
		panic(err)
	}

	ip := net.ParseIP(r.Header["X-Forwarded-For"][len(r.Header["X-Forwarded-For"])-1]).String()

	// If the user specifies a 'format' querystring, we'll try to return the
	// user's IP address in the specified format.
	if format, ok := r.Form["format"]; ok && len(format) > 0 {
		jsonStr, _ := json.Marshal(IPAddress{ip})

		switch format[0] {
		case "json":
			w.Header().Set("Content-Type", "application/json")
			fmt.Fprintf(w, string(jsonStr))
			return
		case "jsonp":
			// If the user specifies a 'callback' parameter, we'll use that as
			// the name of our JSONP callback.
			callback := "callback"
			if val, ok := r.Form["callback"]; ok && len(val) > 0 {
				callback = val[0]
			}

			w.Header().Set("Content-Type", "application/javascript")
			fmt.Fprintf(w, callback+"("+string(jsonStr)+");")
			return
		}
	}

	// If no 'format' querystring was specified, we'll default to returning the
	// IP in plain text.
	w.Header().Set("Content-Type", "text/plain")
	fmt.Fprintf(w, ip)
}

// main launches our web server which runs indefinitely.
func main() {
	http.HandleFunc("/", getIP)

	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}
<commit_msg>Updating comments.<commit_after>// ipify-api
//
// This is the main package which starts up and runs our REST API service.
//
// ipify is a simple API service which returns a user's public IP address (it
// supports handling both IPv4 and IPv6 addresses).

package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"os"
)

// IPAddress is a struct we use to represent JSON API responses.
type IPAddress struct {
	IP string `json:"ip"`
}

// getIP returns a user's public facing IP address (IPv4 OR IPv6).
//
// By default, it will return the IP address in plain text, but can also return
// data in both JSON and JSONP if requested to.
func getIP(w http.ResponseWriter, r *http.Request) {

	// Enable CORS support.
	w.Header().Set("Access-Control-Allow-Origin", "*")

	err := r.ParseForm()
	if err != nil {
		panic(err)
	}

	ip := net.ParseIP(r.Header["X-Forwarded-For"][len(r.Header["X-Forwarded-For"])-1]).String()

	// If the user specifies a 'format' querystring, we'll try to return the
	// user's IP address in the specified format.
	if format, ok := r.Form["format"]; ok && len(format) > 0 {
		jsonStr, _ := json.Marshal(IPAddress{ip})

		switch format[0] {
		case "json":
			w.Header().Set("Content-Type", "application/json")
			fmt.Fprintf(w, string(jsonStr))
			return
		case "jsonp":
			// If the user specifies a 'callback' parameter, we'll use that as
			// the name of our JSONP callback.
			callback := "callback"
			if val, ok := r.Form["callback"]; ok && len(val) > 0 {
				callback = val[0]
			}

			w.Header().Set("Content-Type", "application/javascript")
			fmt.Fprintf(w, callback+"("+string(jsonStr)+");")
			return
		}
	}

	// If no 'format' querystring was specified, we'll default to returning the
	// IP in plain text.
	w.Header().Set("Content-Type", "text/plain")
	fmt.Fprintf(w, ip)
}

// main launches our web server which runs indefinitely.
func main() {
	http.HandleFunc("/", getIP)

	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package main

// Mathias Monnerville <mathias@monnerville.com>

import (
	"bufio"
	"container/list"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
)

// Node holding a letter and possible children. Boundary
// is true when word (root node to current node) is a valid word
// from the input list.
type Node struct {
	letter   string
	children map[string]*Node
	boundary bool // Marks a word boundary
}

func newNode(letter string) *Node {
	n := &Node{
		letter:   letter,
		children: make(map[string]*Node),
		boundary: false,
	}
	return n
}

// Prefix tree
type Tree struct {
	root *Node
}

// newTree creates a tree with a valid root node.
func newTree() *Tree {
	return &Tree{newNode("")}
}

// addWord inserts a word in the tree data structure.
func (t *Tree) addWord(word string) {
	curnode := t.root // Current node
	for _, code := range word {
		letter := fmt.Sprintf("%c", code)
		if _, ok := curnode.children[letter]; !ok {
			curnode.children[letter] = newNode(letter)
		}
		curnode = curnode.children[letter]
	}
	curnode.boundary = true // End of word
}

// findWordPrefixes looks for all prefixes of a given word.
func (t *Tree) findWordPrefixes(word string) []string {
	prefixes := make([]string, 0)
	var prefix string
	curnode := t.root

	for _, code := range word {
		letter := fmt.Sprintf("%c", code)
		if _, ok := curnode.children[letter]; !ok {
			return prefixes
		}
		prefix += letter
		curnode = curnode.children[letter]
		if curnode.boundary {
			prefixes = append(prefixes, prefix)
		}
	}
	return prefixes
}

// exists looks for the word in the tree.
func (t *Tree) exists(word string) bool {
	curnode := t.root
	for _, code := range word {
		letter := fmt.Sprintf("%c", code)
		if _, ok := curnode.children[letter]; !ok {
			return false
		}
		curnode = curnode.children[letter]
	}
	return curnode.boundary
}

type pair struct {
	word, suffix string
}

func findLongestCompoundWord(r io.Reader) string {
	tree := newTree()
	pq := list.New() // Processing queue
	scanner := bufio.NewScanner(r)

	// Insert words into the tree data structure
	count := 0
	for scanner.Scan() {
		word := scanner.Text()
		prefixes := tree.findWordPrefixes(word)
		for _, prefix := range prefixes {
			pq.PushBack(&pair{word, word[len(prefix):]})
		}
		tree.addWord(word)
		count++
	}

	// Now process pairs in the queue
	var match string
	maxLen := 0
	for pq.Len() > 0 {
		p := pq.Remove(pq.Front()).(*pair)
		if tree.exists(p.suffix) && len(p.word) > maxLen {
			maxLen = len(p.word)
			match = p.word
		} else {
			prefixes := tree.findWordPrefixes(p.suffix)
			for _, prefix := range prefixes {
				pq.PushBack(&pair{p.word, p.suffix[len(prefix):]})
			}
		}
	}
	return match
}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, fmt.Sprintf("Usage: %s wordfile\n", os.Args[0]))
		flag.PrintDefaults()
		os.Exit(2)
	}

	flag.Parse()
	if len(flag.Args()) == 0 {
		fmt.Fprint(os.Stderr, "word file is missing.\n\n")
		flag.Usage()
	}
	f, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(findLongestCompoundWord(f))
}
<commit_msg>Add timing debug information<commit_after>package main

// Mathias Monnerville <mathias@monnerville.com>

import (
	"bufio"
	"container/list"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"time"
)

// Node holding a letter and possible children. Boundary
// is true when word (root node to current node) is a valid word
// from the input list.
type Node struct {
	letter   string
	children map[string]*Node
	boundary bool // Marks a word boundary
}

func newNode(letter string) *Node {
	n := &Node{
		letter:   letter,
		children: make(map[string]*Node),
		boundary: false,
	}
	return n
}

// Prefix tree
type Tree struct {
	root *Node
}

// newTree creates a tree with a valid root node.
func newTree() *Tree {
	return &Tree{newNode("")}
}

// addWord inserts a word in the tree data structure.
func (t *Tree) addWord(word string) {
	curnode := t.root // Current node
	for _, code := range word {
		letter := fmt.Sprintf("%c", code)
		if _, ok := curnode.children[letter]; !ok {
			curnode.children[letter] = newNode(letter)
		}
		curnode = curnode.children[letter]
	}
	curnode.boundary = true // End of word
}

// findWordPrefixes looks for all prefixes of a given word.
func (t *Tree) findWordPrefixes(word string) []string {
	prefixes := make([]string, 0)
	var prefix string
	curnode := t.root

	for _, code := range word {
		letter := fmt.Sprintf("%c", code)
		if _, ok := curnode.children[letter]; !ok {
			return prefixes
		}
		prefix += letter
		curnode = curnode.children[letter]
		if curnode.boundary {
			prefixes = append(prefixes, prefix)
		}
	}
	return prefixes
}

// exists looks for the word in the tree.
func (t *Tree) exists(word string) bool {
	curnode := t.root
	for _, code := range word {
		letter := fmt.Sprintf("%c", code)
		if _, ok := curnode.children[letter]; !ok {
			return false
		}
		curnode = curnode.children[letter]
	}
	return curnode.boundary
}

type pair struct {
	word, suffix string
}

func findLongestCompoundWord(r io.Reader) string {
	tree := newTree()
	pq := list.New() // Processing queue
	scanner := bufio.NewScanner(r)

	start := time.Now()
	// Insert words into the tree data structure
	count := 0
	for scanner.Scan() {
		word := scanner.Text()
		prefixes := tree.findWordPrefixes(word)
		for _, prefix := range prefixes {
			pq.PushBack(&pair{word, word[len(prefix):]})
		}
		tree.addWord(word)
		count++
	}
	fmt.Printf("Inserted words in %v\n", time.Since(start))

	// Now process pairs in the queue
	var match string
	maxLen := 0
	for pq.Len() > 0 {
		p := pq.Remove(pq.Front()).(*pair)
		if tree.exists(p.suffix) && len(p.word) > maxLen {
			maxLen = len(p.word)
			match = p.word
		} else {
			prefixes := tree.findWordPrefixes(p.suffix)
			for _, prefix := range prefixes {
				pq.PushBack(&pair{p.word, p.suffix[len(prefix):]})
			}
		}
	}
	fmt.Printf("Took %v\n", time.Since(start))
	return match
}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, fmt.Sprintf("Usage: %s wordfile\n", os.Args[0]))
		flag.PrintDefaults()
		os.Exit(2)
	}

	flag.Parse()
	if len(flag.Args()) == 0 {
		fmt.Fprint(os.Stderr, "word file is missing.\n\n")
		flag.Usage()
	}
	f, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatal(err)
	}
	word := findLongestCompoundWord(f)
	fmt.Printf("\nWord is: %s (%d)\n", word, len(word))
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"

	"gopkg.in/tylerb/graceful.v1"

	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
)

type IssueComment struct {
	IssueNumber   int
	Comment       string
	IsPullRequest bool
	Repository    Repository
}

type Repository struct {
	Owner string
	Name  string
	URL   string
}

func main() {
	conf := NewConfig()
	githubClient := initGithubClient(conf.AccessToken)
	reposDir, err := ioutil.TempDir("", "github-review-helper")
	if err != nil {
		panic(err)
	}
	defer os.RemoveAll(reposDir)

	git := NewGit(reposDir)

	mux := http.NewServeMux()
	mux.Handle("/", Handler(func(w http.ResponseWriter, r *http.Request) Response {
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			return ErrorResponse{err, http.StatusInternalServerError, "Failed to read the request's body"}
		}
		signature := r.Header.Get("X-Hub-Signature")
		hasSecret, err := hasSecret(body, signature, conf.Secret)
		if err != nil {
			return ErrorResponse{err, http.StatusInternalServerError, "Failed to check the signature"}
		}
		if !hasSecret {
			return ErrorResponse{nil, http.StatusBadRequest, "Bad X-Hub-Signature"}
		}
		eventType := r.Header.Get("X-Github-Event")
		if eventType != "issue_comment" {
			return SuccessResponse{"Not an event I understand. Ignoring."}
		}
		issueComment, err := parseIssueComment(body)
		if err != nil {
			return ErrorResponse{err, http.StatusInternalServerError, "Failed to parse the requests body"}
		}
		if !issueComment.IsPullRequest {
			return SuccessResponse{"Not a PR. Ignoring."}
		}
		if issueComment.Comment != "!squash" {
			return SuccessResponse{"Not a command I understand. Ignoring."}
		}
		pr, _, err := githubClient.PullRequests.Get(issueComment.Repository.Owner, issueComment.Repository.Name, issueComment.IssueNumber)
		if err != nil {
			message := fmt.Sprintf("Getting PR %s/%s#%d failed", issueComment.Repository.Owner, issueComment.Repository.Name, issueComment.IssueNumber)
			return ErrorResponse{err, http.StatusInternalServerError, message}
		}
		log.Printf("Squashing %s that's going to be merged into %s\n", *pr.Head.Ref, *pr.Base.Ref)
		repo, err := git.GetUpdatedRepo(issueComment.Repository.URL, issueComment.Repository.Owner, issueComment.Repository.Name)
		if err != nil {
			return ErrorResponse{err, http.StatusInternalServerError, "Failed to update the local repo"}
		}
		if err = repo.RebaseAutosquash(*pr.Base.SHA, *pr.Head.SHA); err != nil {
			return ErrorResponse{err, http.StatusInternalServerError, "Failed to autosquash the commits with an interactive rebase"}
		}
		if err = repo.ForcePushHeadTo(*pr.Head.Ref); err != nil {
			return ErrorResponse{err, http.StatusInternalServerError, "Failed to push the squashed version"}
		}
		return SuccessResponse{}
	}))

	graceful.Run(fmt.Sprintf(":%d", conf.Port), 10*time.Second, mux)
}

func initGithubClient(accessToken string) *github.Client {
	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: accessToken},
	)
	tc := oauth2.NewClient(oauth2.NoContext, ts)
	return github.NewClient(tc)
}

func parseIssueComment(body []byte) (IssueComment, error) {
	var message struct {
		Issue struct {
			Number      int `json:"Number"`
			PullRequest struct {
				URL string `json:"url"`
			} `json:"pull_request"`
		} `json:"issue"`
		Repository struct {
			Name  string `json:"name"`
			Owner struct {
				Login string `json:"login"`
			} `json:"owner"`
			SSHURL string `json:"ssh_url"`
		} `json:"repository"`
		Comment struct {
			Body string `json:"body"`
		} `json:"comment"`
	}
	err := json.Unmarshal(body, &message)
	if err != nil {
		return IssueComment{}, err
	}
	return IssueComment{
		IssueNumber:   message.Issue.Number,
		Comment:       message.Comment.Body,
		IsPullRequest: message.Issue.PullRequest.URL != "",
		Repository: Repository{
			Owner: message.Repository.Owner.Login,
			Name:  message.Repository.Name,
			URL:   message.Repository.SSHURL,
		},
	}, nil
}

func hasSecret(message []byte, signature, key string) (bool, error) {
	var messageMACString string
	fmt.Sscanf(signature, "sha1=%s", &messageMACString)
	messageMAC, err := hex.DecodeString(messageMACString)
	if err != nil {
		return false, err
	}

	mac := hmac.New(sha1.New, []byte(key))
	mac.Write(message)
	expectedMAC := mac.Sum(nil)
	return hmac.Equal(messageMAC, expectedMAC), nil
}
<commit_msg>Split the handler based on event type<commit_after>package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"

	"gopkg.in/tylerb/graceful.v1"

	"github.com/google/go-github/github"
	"golang.org/x/oauth2"
)

type IssueComment struct {
	IssueNumber   int
	Comment       string
	IsPullRequest bool
	Repository    Repository
}

type PullRequestEvent struct {
	IssueNumber int
	Action      string
	Repository  Repository
}

type Repository struct {
	Owner string
	Name  string
	URL   string
}

func main() {
	conf := NewConfig()
	githubClient := initGithubClient(conf.AccessToken)
	reposDir, err := ioutil.TempDir("", "github-review-helper")
	if err != nil {
		panic(err)
	}
	defer os.RemoveAll(reposDir)

	git := NewGit(reposDir)

	mux := http.NewServeMux()
	mux.Handle("/", Handler(func(w http.ResponseWriter, r *http.Request) Response {
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			return ErrorResponse{err, http.StatusInternalServerError, "Failed to read the request's body"}
		}
		signature := r.Header.Get("X-Hub-Signature")
		hasSecret, err := hasSecret(body, signature, conf.Secret)
		if err != nil {
			return ErrorResponse{err, http.StatusInternalServerError, "Failed to check the signature"}
		}
		if !hasSecret {
			return ErrorResponse{nil, http.StatusBadRequest, "Bad X-Hub-Signature"}
		}
		eventType := r.Header.Get("X-Github-Event")
		switch eventType {
		case "issue_comment":
			return handleIssueComment(w, body, git, githubClient)
		case "pull_request":
			return handlePullRequest(w, body, git, githubClient)
		}
		return SuccessResponse{"Not an event I understand. Ignoring."}
	}))

	graceful.Run(fmt.Sprintf(":%d", conf.Port), 10*time.Second, mux)
}

func handleIssueComment(w http.ResponseWriter, body []byte, git Git, githubClient *github.Client) Response {
	issueComment, err := parseIssueComment(body)
	if err != nil {
		return ErrorResponse{err, http.StatusInternalServerError, "Failed to parse the request's body"}
	}
	if !issueComment.IsPullRequest {
		return SuccessResponse{"Not a PR. Ignoring."}
	}
	if issueComment.Comment != "!squash" {
		return SuccessResponse{"Not a command I understand. Ignoring."}
	}
	pr, _, err := githubClient.PullRequests.Get(issueComment.Repository.Owner, issueComment.Repository.Name, issueComment.IssueNumber)
	if err != nil {
		message := fmt.Sprintf("Getting PR %s/%s#%d failed", issueComment.Repository.Owner, issueComment.Repository.Name, issueComment.IssueNumber)
		return ErrorResponse{err, http.StatusInternalServerError, message}
	}
	log.Printf("Squashing %s that's going to be merged into %s\n", *pr.Head.Ref, *pr.Base.Ref)
	repo, err := git.GetUpdatedRepo(issueComment.Repository.URL, issueComment.Repository.Owner, issueComment.Repository.Name)
	if err != nil {
		return ErrorResponse{err, http.StatusInternalServerError, "Failed to update the local repo"}
	}
	if err = repo.RebaseAutosquash(*pr.Base.SHA, *pr.Head.SHA); err != nil {
		return ErrorResponse{err, http.StatusInternalServerError, "Failed to autosquash the commits with an interactive rebase"}
	}
	if err = repo.ForcePushHeadTo(*pr.Head.Ref); err != nil {
		return ErrorResponse{err, http.StatusInternalServerError, "Failed to push the squashed version"}
	}
	return SuccessResponse{}
}

func handlePullRequest(w http.ResponseWriter, body []byte, git Git, githubClient *github.Client) Response {
	_, err := parsePullRequestEvent(body)
	if err != nil {
		return ErrorResponse{err, http.StatusInternalServerError, "Failed to parse the request's body"}
	}
	return SuccessResponse{}
}

func initGithubClient(accessToken string) *github.Client {
	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: accessToken},
	)
	tc := oauth2.NewClient(oauth2.NoContext, ts)
	return github.NewClient(tc)
}

func parseIssueComment(body []byte) (IssueComment, error) {
	var message struct {
		Issue struct {
			Number      int `json:"Number"`
			PullRequest struct {
				URL string `json:"url"`
			} `json:"pull_request"`
		} `json:"issue"`
		Repository struct {
			Name  string `json:"name"`
			Owner struct {
				Login string `json:"login"`
			} `json:"owner"`
			SSHURL string `json:"ssh_url"`
		} `json:"repository"`
		Comment struct {
			Body string `json:"body"`
		} `json:"comment"`
	}
	err := json.Unmarshal(body, &message)
	if err != nil {
		return IssueComment{}, err
	}
	return IssueComment{
		IssueNumber:   message.Issue.Number,
		Comment:       message.Comment.Body,
		IsPullRequest: message.Issue.PullRequest.URL != "",
		Repository: Repository{
			Owner: message.Repository.Owner.Login,
			Name:  message.Repository.Name,
			URL:   message.Repository.SSHURL,
		},
	}, nil
}

func parsePullRequestEvent(body []byte) (PullRequestEvent, error) {
	var message struct {
		Action      string `json:"action"`
		Number      int    `json:"Number"`
		PullRequest struct {
			URL string `json:"url"`
		} `json:"pull_request"`
		Repository struct {
			Name  string `json:"name"`
			Owner struct {
				Login string `json:"login"`
			} `json:"owner"`
			SSHURL string `json:"ssh_url"`
		} `json:"repository"`
	}
	err := json.Unmarshal(body, &message)
	if err != nil {
		return PullRequestEvent{}, err
	}
	return PullRequestEvent{
		IssueNumber: message.Number,
		Action:      message.Action,
		Repository: Repository{
			Owner: message.Repository.Owner.Login,
			Name:  message.Repository.Name,
			URL:   message.Repository.SSHURL,
		},
	}, nil
}

func hasSecret(message []byte, signature, key string) (bool, error) {
	var messageMACString string
	fmt.Sscanf(signature, "sha1=%s", &messageMACString)
	messageMAC, err := hex.DecodeString(messageMACString)
	if err != nil {
		return false, err
	}

	mac := hmac.New(sha1.New, []byte(key))
	mac.Write(message)
	expectedMAC := mac.Sum(nil)
	return hmac.Equal(messageMAC, expectedMAC), nil
}
<|endoftext|>


<commit_before>package main

import (
	"bs3stat/db"
	"bs3stat/handlers"
	"bs3stat/model"
	"flag"
	"fmt"

	"github.com/labstack/echo"
	"github.com/labstack/echo/engine/standard"
)

func main() {
	port := flag.String("port", "3000", "Your port number (default to 3000).")
	migrate := flag.Bool("migrate", false, "Run database migrations.")
	seed := flag.Bool("seed", false, "Seed database with some demo data.")
	flag.Parse()

	db.InitDB("storage.db", *migrate, *seed)

	e := echo.New()
	e = routes(e)

	project := model.Project{
		Title: "Lalalalla dongo",
		Name:  "acme_dongo",
	}
	db.DB.Create(&project)

	// Start server
	e.Run(standard.New(":" + *port))
	fmt.Println("\n\x1b[32;1mRunning on: http://localhost:" + *port + ".\x1b[0m")
}

func routes(e *echo.Echo) *echo.Echo {
	e.GET("/projects", handlers.ProjectIndex)
	e.POST("/projects", handlers.CreateProject)
	e.GET("/projects/:id", handlers.GetProject)
	e.PUT("/projects/:id", handlers.UpdateProject)
	e.DELETE("/projects/:id", handlers.DeleteProject)

	return e
}
<commit_msg>🐛 Fix output<commit_after>package main

import (
	"bs3stat/db"
	"bs3stat/handlers"
	"bs3stat/model"
	"flag"
	"fmt"

	"github.com/labstack/echo"
	"github.com/labstack/echo/engine/standard"
)

func main() {
	port := flag.String("port", "3000", "Your port number (default to 3000).")
	migrate := flag.Bool("migrate", false, "Run database migrations.")
	seed := flag.Bool("seed", false, "Seed database with some demo data.")
	flag.Parse()

	db.InitDB("storage.db", *migrate, *seed)

	e := echo.New()
	e = routes(e)

	project := model.Project{
		Title: "Lalalalla dongo",
		Name:  "acme_dongo",
	}
	db.DB.Create(&project)

	// Start server
	fmt.Println("\n\x1b[32;1mRunning on: http://localhost:" + *port + ".\x1b[0m")
	e.Run(standard.New(":" + *port))
}

func routes(e *echo.Echo) *echo.Echo {
	e.GET("/projects", handlers.ProjectIndex)
	e.POST("/projects", handlers.CreateProject)
	e.GET("/projects/:id", handlers.GetProject)
	e.PUT("/projects/:id", handlers.UpdateProject)
	e.DELETE("/projects/:id", handlers.DeleteProject)

	return e
}
<|endoftext|>


<commit_before>package hookworm

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"strings"
	"text/template"
	"time"
)

var (
	rfc2822DateFmt        = "Mon, 02 Jan 2006 15:04:05 -0700"
	hostname              string
	secretCommitEmailTmpl = template.Must(template.New("email").Parse(`From: {{.From}}
To: {{.Recipients}}
Subject: [hookworm] Secret commit! {{.Repo}} {{.Ref}} {{.HeadCommitId}}
Date: {{.Date}}
Message-ID: <{{.MessageId}}@{{.Hostname}}>
List-ID: {{.Repo}} <hookworm.github.com>
Content-Type: multipart/alternative;
  boundary="--==ZOMGBOUNDARAAAYYYYY";
  charset=UTF-8
Content-Transfer-Encoding: 7bit

----==ZOMGBOUNDARAAAYYYYY
Date: {{.Date}}
Mime-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 7bit

Secret commit detected on {{.Repo}} {{.Ref}}

Id        {{.HeadCommitUrl}}
Message   {{.HeadCommitMessage}}
Author    {{.HeadCommitAuthor}}
Committer {{.HeadCommitCommitter}}
Timestamp {{.HeadCommitTimestamp}}

----==ZOMGBOUNDARAAAYYYYY
Date: {{.Date}}
Mime-Version: 1.0
Content-Type: text/html; charset=utf8
Content-Transfer-Encoding: 7bit

Secret commit detected on {{.Repo}} {{.Ref}}

Id	{{.HeadCommitId}}

Message	{{.HeadCommitMessage}}

Author	{{.HeadCommitAuthor}}

Committer	{{.HeadCommitCommitter}}

Timestamp	{{.HeadCommitTimestamp}}

----==ZOMGBOUNDARAAAYYYYY--
`))
)

func init() {
	var err error
	hostname, err = os.Hostname()
	if err != nil {
		hostname = "somewhere.local"
	}
}

type SecretSquirrelCommitHandler struct {
	emailer         *Emailer
	fromAddr        string
	recipients      []string
	policedBranches []string
	nextHandler     Handler
}

type secretCommitEmailContext struct {
	From                string
	Recipients          string
	Date                string
	MessageId           string
	Hostname            string
	Repo                string
	Ref                 string
	HeadCommitId        string
	HeadCommitUrl       string
	HeadCommitAuthor    string
	HeadCommitCommitter string
	HeadCommitMessage   string
	HeadCommitTimestamp string
}

func (me *SecretSquirrelCommitHandler) HandlePayload(payload *Payload) error {
	me.checkIfSecretSquirrelCommit(payload)
	return nil
}

func (me *SecretSquirrelCommitHandler) SetNextHandler(handler Handler) {
	me.nextHandler = handler
}

func (me *SecretSquirrelCommitHandler) NextHandler() Handler {
	return me.nextHandler
}

func (me *SecretSquirrelCommitHandler) checkIfSecretSquirrelCommit(payload *Payload) {
	if !me.isPolicedBranch(payload.Ref.String()) {
		log.Printf("%v is not a policed branch, yay!\n", payload.Ref.String())
		return
	}

	log.Printf("%v is a policed branch!\n", payload.Ref.String())

	if payload.IsPullRequestMerge() {
		log.Printf("%v is a pull request merge, yay!\n", payload.HeadCommit.Id.String())
		return
	}

	log.Printf("%v is not a pull request merge!\n", payload.HeadCommit.Id.String())

	if err := me.alert(payload); err != nil {
		log.Printf("ERROR sending alert: %+v\n", err)
		return
	}

	log.Printf("Sent alert to %+v\n", me.recipients)
}

func (me *SecretSquirrelCommitHandler) isPolicedBranch(ref string) bool {
	sansRefsHeads := strings.Replace(ref, "refs/heads/", "", 1)
	for _, ref := range me.policedBranches {
		if ref == sansRefsHeads {
			return true
		}
	}
	return false
}

func (me *SecretSquirrelCommitHandler) alert(payload *Payload) error {
	// FIXME use the emailer thing here
	log.Printf("WARNING secret squirrel commit! %+v\n", payload)
	if len(me.recipients) == 0 {
		log.Println("No email recipients specified, so no emailing!")
	}

	hc := payload.HeadCommit
	ctx := &secretCommitEmailContext{
		From:       me.fromAddr,
		Recipients: strings.Join(me.recipients, ", "),
		Date:       time.Now().UTC().Format(rfc2822DateFmt),
		MessageId:  fmt.Sprintf("%v", time.Now().UTC().UnixNano()),
		Hostname:   hostname,
		Repo: fmt.Sprintf("%s/%s", payload.Repository.Owner.Name.String(),
			payload.Repository.Name.String()),
		Ref:                 payload.Ref.String(),
		HeadCommitId:        hc.Id.String(),
		HeadCommitUrl:       hc.Url.String(),
		HeadCommitAuthor:    hc.Author.Name.String(),
		HeadCommitCommitter: hc.Committer.Name.String(),
		HeadCommitMessage:   hc.Message.String(),
		HeadCommitTimestamp: hc.Timestamp.String(),
	}
	var emailBuf bytes.Buffer

	err := secretCommitEmailTmpl.Execute(&emailBuf, ctx)
	if err != nil {
		return err
	}

	log.Printf("Email message:\n%v\n", string(emailBuf.Bytes()))
	return me.emailer.Send(me.fromAddr, me.recipients, emailBuf.Bytes())
}
<commit_msg>Another tweak to email template<commit_after>package hookworm

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"strings"
	"text/template"
	"time"
)

var (
	rfc2822DateFmt        = "Mon, 02 Jan 2006 15:04:05 -0700"
	hostname              string
	secretCommitEmailTmpl = template.Must(template.New("email").Parse(`From: {{.From}}
To: {{.Recipients}}
Subject: [hookworm] Secret commit! {{.Repo}} {{.Ref}} {{.HeadCommitId}}
Date: {{.Date}}
Message-ID: <{{.MessageId}}@{{.Hostname}}>
List-ID: {{.Repo}} <hookworm.github.com>
Content-Type: multipart/alternative;
  boundary="--==ZOMGBOUNDARAAAYYYYY";
  charset=UTF-8
Content-Transfer-Encoding: 7bit

----==ZOMGBOUNDARAAAYYYYY
Date: {{.Date}}
Mime-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 7bit

Secret commit detected on {{.Repo}} {{.Ref}}

Id        {{.HeadCommitUrl}}
Message   {{.HeadCommitMessage}}
Author    {{.HeadCommitAuthor}}
Committer {{.HeadCommitCommitter}}
Timestamp {{.HeadCommitTimestamp}}

----==ZOMGBOUNDARAAAYYYYY
Date: {{.Date}}
Mime-Version: 1.0
Content-Type: text/html; charset=utf8
Content-Transfer-Encoding: 7bit

Secret commit detected on {{.Repo}} {{.Ref}}

Id:	{{.HeadCommitId}}

Message:	{{.HeadCommitMessage}}

Author:	{{.HeadCommitAuthor}}

Committer:	{{.HeadCommitCommitter}}

Timestamp:	{{.HeadCommitTimestamp}}

----==ZOMGBOUNDARAAAYYYYY--
`))
)

func init() {
	var err error
	hostname, err = os.Hostname()
	if err != nil {
		hostname = "somewhere.local"
	}
}

type SecretSquirrelCommitHandler struct {
	emailer         *Emailer
	fromAddr        string
	recipients      []string
	policedBranches []string
	nextHandler     Handler
}

type secretCommitEmailContext struct {
	From                string
	Recipients          string
	Date                string
	MessageId           string
	Hostname            string
	Repo                string
	Ref                 string
	HeadCommitId        string
	HeadCommitUrl       string
	HeadCommitAuthor    string
	HeadCommitCommitter string
	HeadCommitMessage   string
	HeadCommitTimestamp string
}

func (me *SecretSquirrelCommitHandler) HandlePayload(payload *Payload) error {
	me.checkIfSecretSquirrelCommit(payload)
	return nil
}

func (me *SecretSquirrelCommitHandler) SetNextHandler(handler Handler) {
	me.nextHandler = handler
}

func (me *SecretSquirrelCommitHandler) NextHandler() Handler {
	return me.nextHandler
}

func (me *SecretSquirrelCommitHandler) checkIfSecretSquirrelCommit(payload *Payload) {
	if !me.isPolicedBranch(payload.Ref.String()) {
		log.Printf("%v is not a policed branch, yay!\n", payload.Ref.String())
		return
	}

	log.Printf("%v is a policed branch!\n", payload.Ref.String())

	if payload.IsPullRequestMerge() {
		log.Printf("%v is a pull request merge, yay!\n", payload.HeadCommit.Id.String())
		return
	}

	log.Printf("%v is not a pull request merge!\n", payload.HeadCommit.Id.String())

	if err := me.alert(payload); err != nil {
		log.Printf("ERROR sending alert: %+v\n", err)
		return
	}

	log.Printf("Sent alert to %+v\n", me.recipients)
}

func (me *SecretSquirrelCommitHandler) isPolicedBranch(ref string) bool {
	sansRefsHeads := strings.Replace(ref, "refs/heads/", "", 1)
	for _, ref := range me.policedBranches {
		if ref == sansRefsHeads {
			return true
		}
	}
	return false
}

func (me *SecretSquirrelCommitHandler) alert(payload *Payload) error {
	// FIXME use the emailer thing here
	log.Printf("WARNING secret squirrel commit! %+v\n", payload)
	if len(me.recipients) == 0 {
		log.Println("No email recipients specified, so no emailing!")
	}

	hc := payload.HeadCommit
	ctx := &secretCommitEmailContext{
		From:       me.fromAddr,
		Recipients: strings.Join(me.recipients, ", "),
		Date:       time.Now().UTC().Format(rfc2822DateFmt),
		MessageId:  fmt.Sprintf("%v", time.Now().UTC().UnixNano()),
		Hostname:   hostname,
		Repo: fmt.Sprintf("%s/%s", payload.Repository.Owner.Name.String(),
			payload.Repository.Name.String()),
		Ref:                 payload.Ref.String(),
		HeadCommitId:        hc.Id.String(),
		HeadCommitUrl:       hc.Url.String(),
		HeadCommitAuthor:    hc.Author.Name.String(),
		HeadCommitCommitter: hc.Committer.Name.String(),
		HeadCommitMessage:   hc.Message.String(),
		HeadCommitTimestamp: hc.Timestamp.String(),
	}
	var emailBuf bytes.Buffer

	err := secretCommitEmailTmpl.Execute(&emailBuf, ctx)
	if err != nil {
		return err
	}

	log.Printf("Email message:\n%v\n", string(emailBuf.Bytes()))
	return me.emailer.Send(me.fromAddr, me.recipients, emailBuf.Bytes())
}
<|endoftext|>


<commit_before>package builtin

import (
	"fmt"

	"github.com/hysios/apiai-go"
	"github.com/wanliu/brain_data/database"
	"github.com/wanliu/flow/builtin/ai"
	"github.com/wanliu/flow/context"
)

type CustomerOrders struct {
	TryGetEntities
	Ctx  <-chan context.Context
	Type <-chan string
	Out  chan<- ReplyData
}

func NewCustomerOrders() interface{} {
	return new(CustomerOrders)
}

func (c *CustomerOrders) OnCtx(ctx context.Context) {
	aiResult := ctx.Value("Result").(apiai.Result)
	aiParams := ai.ApiAiOrder{AiResult: aiResult}

	customer := aiParams.Customer()
	queryTime := aiParams.Time()

	if customer == "" {
		c.Out <- ReplyData{"请提供要查询的客户", ctx}
		return
	}

	var person database.People
	err := database.DB.Where("name = ?", customer).First(&person).Error
	if nil != err || database.DB.NewRecord(person) {
		c.Out <- ReplyData{fmt.Sprintf("客户\"%v\"不存在", customer), ctx}
		return
	}

	var orders []database.Order
	result := ""

	if queryTime.IsZero() {
		person.GetRecentOrders(&orders, nil)
		if len(orders) == 0 {
			reply := fmt.Sprintf("客户\"%v\"最近没有订单", customer)
			c.Out <- ReplyData{reply, ctx}
			return
		}

		result = fmt.Sprintf("客户\"%v\"最近的%v个订单：\n", customer, len(orders))
	} else {
		person.GetRecentOrders(&orders, &queryTime)
		date := queryTime.Format("2006年01月02日")

		if len(orders) == 0 {
			reply := fmt.Sprintf("客户\"%v\"在%v没有订单", customer, date)
			c.Out <- ReplyData{reply, ctx}
			return
		}

		result = fmt.Sprintf("客户\"%v\"%v最近的%v个订单：\n", customer, date, len(orders))
	}

	for _, order := range orders {
		result = result + fmt.Sprintf("订单号：%v   总金额：%v\n", order.No, order.Amount)
	}

	c.Out <- ReplyData{result, ctx}
}
<commit_msg>order details<commit_after>package builtin

import (
	"fmt"

	"github.com/hysios/apiai-go"
	"github.com/wanliu/brain_data/database"
	"github.com/wanliu/flow/builtin/ai"
	"github.com/wanliu/flow/context"
)

type CustomerOrders struct {
	TryGetEntities
	Ctx  <-chan context.Context
	Type <-chan string
	Out  chan<- ReplyData
}

func NewCustomerOrders() interface{} {
	return new(CustomerOrders)
}

func (c *CustomerOrders) OnCtx(ctx context.Context) {
	aiResult := ctx.Value("Result").(apiai.Result)
	aiParams := ai.ApiAiOrder{AiResult: aiResult}

	customer := aiParams.Customer()
	queryTime := aiParams.Time()

	if customer == "" {
		c.Out <- ReplyData{"请提供要查询的客户", ctx}
		return
	}

	var person database.People
	err := database.DB.Where("name = ?", customer).First(&person).Error
	if nil != err || database.DB.NewRecord(person) {
		c.Out <- ReplyData{fmt.Sprintf("客户\"%v\"不存在", customer), ctx}
		return
	}

	var orders []database.Order
	result := ""

	if queryTime.IsZero() {
		person.GetRecentOrders(&orders, nil, 2)
		if len(orders) == 0 {
			reply := fmt.Sprintf("客户\"%v\"最近没有订单", customer)
			c.Out <- ReplyData{reply, ctx}
			return
		}

		result = fmt.Sprintf("客户\"%v\"最近的%v个订单：\n", customer, len(orders))
	} else {
		person.GetRecentOrders(&orders, &queryTime, 2)
		date := queryTime.Format("2006年01月02日")

		if len(orders) == 0 {
			reply := fmt.Sprintf("客户\"%v\"在%v没有订单", customer, date)
			c.Out <- ReplyData{reply, ctx}
			return
		}

		result = fmt.Sprintf("客户\"%v\"%v最近的%v个订单：\n", customer, date, len(orders))
	}

	for _, order := range orders {
		result = result + "------------------------\n"
		result = result + fmt.Sprintf("订单号：%v\n总金额：%v\n送货时间：%v\n", order.No, order.Amount, order.DeliveryTime.Format("2006年01月02日"))
		if order.Note != "" {
			result = result + fmt.Sprint("备注：%v\n", order.Note)
		}

		result = result + "商品:\n"
		for _, item := range order.OrderItems {
			result = result + fmt.Sprintf("  %v %v%v\n", item.ProductName, item.Quantity, item.Unit)
		}

		if len(order.GiftItems) > 0 {
			result = result + "赠品:\n"
			for _, gift := range order.GiftItems {
				result = result + fmt.Sprintf("  %v %v%v\n", gift.ProductName, gift.Quantity, gift.Unit)
			}
		}
	}

	c.Out <- ReplyData{result, ctx}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

//global flag
var logLevel string
var outputType string

var RootCmd = &cobra.Command{
	Use:   "claw",
	Short: "Command Line Law",
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		// set the log level
	},
}

var newCmd = &cobra.Command{
	Use:   "new",
	Short: "New Contract",
	RunE:  newContract,
}

var compileCmd = &cobra.Command{
	Use:   "compile",
	Short: "Compile into readable contract",
	RunE:  compileContract,
}

func init() {
	//parse flag and set config
	RootCmd.PersistentFlags().StringVar(&logLevel, "log_level", "info", "Log level")

	compileCmd.Flags().StringVar(&outputType, "output", "md", "Output type: md | html | pdf")

	RootCmd.AddCommand(newCmd)
	RootCmd.AddCommand(compileCmd)
}

func main() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
<commit_msg>remove log level; uncessary overhead<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

// global flags
var outputType string

var RootCmd = &cobra.Command{
	Use:   "claw",
	Short: "Command Line Law",
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
	},
}

var newCmd = &cobra.Command{
	Use:   "new",
	Short: "New Contract",
	RunE:  newContract,
}

var compileCmd = &cobra.Command{
	Use:   "compile",
	Short: "Compile into readable contract",
	RunE:  compileContract,
}

func init() {
	compileCmd.Flags().StringVar(&outputType, "output", "md", "Output type: md | html | pdf")

	RootCmd.AddCommand(newCmd)
	RootCmd.AddCommand(compileCmd)
}

func main() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/format"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"reflect"
	"regexp"
	"strings"

	"github.com/elliotchance/c2go/ast"
	"github.com/elliotchance/c2go/program"
	"github.com/elliotchance/c2go/transpiler"
)

const Version = "0.9.3"

var (
	printAst = flag.Bool("print-ast", false, "Print AST before translated Go code.")
	version  = flag.Bool("version", false, "Print the version and exit.")
)

func readAST(data []byte) []string {
	uncolored := regexp.MustCompile(`\x1b\[[\d;]+m`).ReplaceAll(data, []byte{})
	return strings.Split(string(uncolored), "\n")
}

type treeNode struct {
	indent int
	node   ast.Node
}

func convertLinesToNodes(lines []string) []treeNode {
	nodes := []treeNode{}
	for _, line := range lines {
		if strings.TrimSpace(line) == "" {
			continue
		}

		// It is tempting to discard null AST nodes, but these may
		// have semantic importance: for example, they represent omitted
		// for-loop conditions, as in for(;;).
		line = strings.Replace(line, "<<<NULL>>>", "NullStmt", 1)

		indentAndType := regexp.MustCompile("^([|\\- `]*)(\\w+)").FindStringSubmatch(line)
		if len(indentAndType) == 0 {
			panic(fmt.Sprintf("Cannot understand line '%s'", line))
		}

		offset := len(indentAndType[1])
		node := ast.Parse(line[offset:])

		indentLevel := len(indentAndType[1]) / 2
		nodes = append(nodes, treeNode{indentLevel, node})
	}

	return nodes
}

// buildTree convert an array of nodes, each prefixed with a depth into a tree.
func buildTree(nodes []treeNode, depth int) []ast.Node {
	if len(nodes) == 0 {
		return []ast.Node{}
	}

	// Split the list into sections, treat each section as a a tree with its own root.
	sections := [][]treeNode{}
	for _, node := range nodes {
		if node.indent == depth {
			sections = append(sections, []treeNode{node})
		} else {
			sections[len(sections)-1] = append(sections[len(sections)-1], node)
		}
	}

	results := []ast.Node{}
	for _, section := range sections {
		slice := []treeNode{}
		for _, n := range section {
			if n.indent > depth {
				slice = append(slice, n)
			}
		}

		children := buildTree(slice, depth+1)
		for _, child := range children {
			section[0].node.AddChild(child)
		}
		results = append(results, section[0].node)
	}

	return results
}

func ToJSON(tree []interface{}) []map[string]interface{} {
	r := make([]map[string]interface{}, len(tree))

	for j, n := range tree {
		rn := reflect.ValueOf(n).Elem()
		r[j] = make(map[string]interface{})
		r[j]["node"] = rn.Type().Name()

		for i := 0; i < rn.NumField(); i++ {
			name := strings.ToLower(rn.Type().Field(i).Name)
			value := rn.Field(i).Interface()

			if name == "children" {
				v := value.([]interface{})

				if len(v) == 0 {
					continue
				}

				value = ToJSON(v)
			}

			r[j][name] = value
		}
	}

	return r
}

func Check(prefix string, e error) {
	if e != nil {
		panic(prefix + e.Error())
	}
}

func Start(args []string) string {
	if os.Getenv("GOPATH") == "" {
		panic("The $GOPATH must be set.")
	}

	// 1. Compile it first (checking for errors)
	cFilePath := args[0]

	_, err := os.Stat(cFilePath)
	Check("", err)

	// 2. Preprocess
	pp, err := exec.Command("clang", "-E", cFilePath).Output()
	Check("preprocess failed: ", err)

	pp_file_path := path.Join(os.TempDir(), "pp.c")
	err = ioutil.WriteFile(pp_file_path, pp, 0644)
	Check("writing to /tmp/pp.c failed: ", err)

	// 3. Generate JSON from AST
	ast_pp, err := exec.Command("clang", "-Xclang", "-ast-dump", "-fsyntax-only", pp_file_path).Output()
	if err != nil {
		// If clang fails it still prints out the AST, so we have to run it
		// again to get the real error.
		errBody, _ := exec.Command("clang", pp_file_path).CombinedOutput()

		panic("clang failed: " + err.Error() + ":\n\n" + string(errBody))
	}

	lines := readAST(ast_pp)
	if *printAst {
		for _, l := range lines {
			fmt.Println(l)
		}
		fmt.Println()
	}
	nodes := convertLinesToNodes(lines)
	tree := buildTree(nodes, 0)

	p := program.NewProgram()
	err = transpiler.TranspileAST(cFilePath, p, tree[0].(ast.Node))
	if err != nil {
		panic(err)
	}

	var buf bytes.Buffer
	if err := format.Node(&buf, p.FileSet, p.File); err != nil {
		panic(err)
	}

	return buf.String()
}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [options] <file.c>\n", os.Args[0])
		flag.PrintDefaults()
	}
	flag.Parse()

	if *version {
		// Simply print out the version and exit.
		fmt.Println(Version)
		return
	}

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

	fmt.Print(Start(flag.Args()))
}
<commit_msg>Bump version<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/format"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"reflect"
	"regexp"
	"strings"

	"github.com/elliotchance/c2go/ast"
	"github.com/elliotchance/c2go/program"
	"github.com/elliotchance/c2go/transpiler"
)

const Version = "0.10.0"

var (
	printAst = flag.Bool("print-ast", false, "Print AST before translated Go code.")
	version  = flag.Bool("version", false, "Print the version and exit.")
)

func readAST(data []byte) []string {
	uncolored := regexp.MustCompile(`\x1b\[[\d;]+m`).ReplaceAll(data, []byte{})
	return strings.Split(string(uncolored), "\n")
}

type treeNode struct {
	indent int
	node   ast.Node
}

func convertLinesToNodes(lines []string) []treeNode {
	nodes := []treeNode{}
	for _, line := range lines {
		if strings.TrimSpace(line) == "" {
			continue
		}

		// It is tempting to discard null AST nodes, but these may
		// have semantic importance: for example, they represent omitted
		// for-loop conditions, as in for(;;).
		line = strings.Replace(line, "<<<NULL>>>", "NullStmt", 1)

		indentAndType := regexp.MustCompile("^([|\\- `]*)(\\w+)").FindStringSubmatch(line)
		if len(indentAndType) == 0 {
			panic(fmt.Sprintf("Cannot understand line '%s'", line))
		}

		offset := len(indentAndType[1])
		node := ast.Parse(line[offset:])

		indentLevel := len(indentAndType[1]) / 2
		nodes = append(nodes, treeNode{indentLevel, node})
	}

	return nodes
}

// buildTree convert an array of nodes, each prefixed with a depth into a tree.
func buildTree(nodes []treeNode, depth int) []ast.Node {
	if len(nodes) == 0 {
		return []ast.Node{}
	}

	// Split the list into sections, treat each section as a a tree with its own root.
	sections := [][]treeNode{}
	for _, node := range nodes {
		if node.indent == depth {
			sections = append(sections, []treeNode{node})
		} else {
			sections[len(sections)-1] = append(sections[len(sections)-1], node)
		}
	}

	results := []ast.Node{}
	for _, section := range sections {
		slice := []treeNode{}
		for _, n := range section {
			if n.indent > depth {
				slice = append(slice, n)
			}
		}

		children := buildTree(slice, depth+1)
		for _, child := range children {
			section[0].node.AddChild(child)
		}
		results = append(results, section[0].node)
	}

	return results
}

func ToJSON(tree []interface{}) []map[string]interface{} {
	r := make([]map[string]interface{}, len(tree))

	for j, n := range tree {
		rn := reflect.ValueOf(n).Elem()
		r[j] = make(map[string]interface{})
		r[j]["node"] = rn.Type().Name()

		for i := 0; i < rn.NumField(); i++ {
			name := strings.ToLower(rn.Type().Field(i).Name)
			value := rn.Field(i).Interface()

			if name == "children" {
				v := value.([]interface{})

				if len(v) == 0 {
					continue
				}

				value = ToJSON(v)
			}

			r[j][name] = value
		}
	}

	return r
}

func Check(prefix string, e error) {
	if e != nil {
		panic(prefix + e.Error())
	}
}

func Start(args []string) string {
	if os.Getenv("GOPATH") == "" {
		panic("The $GOPATH must be set.")
	}

	// 1. Compile it first (checking for errors)
	cFilePath := args[0]

	_, err := os.Stat(cFilePath)
	Check("", err)

	// 2. Preprocess
	pp, err := exec.Command("clang", "-E", cFilePath).Output()
	Check("preprocess failed: ", err)

	pp_file_path := path.Join(os.TempDir(), "pp.c")
	err = ioutil.WriteFile(pp_file_path, pp, 0644)
	Check("writing to /tmp/pp.c failed: ", err)

	// 3. Generate JSON from AST
	ast_pp, err := exec.Command("clang", "-Xclang", "-ast-dump", "-fsyntax-only", pp_file_path).Output()
	if err != nil {
		// If clang fails it still prints out the AST, so we have to run it
		// again to get the real error.
		errBody, _ := exec.Command("clang", pp_file_path).CombinedOutput()

		panic("clang failed: " + err.Error() + ":\n\n" + string(errBody))
	}

	lines := readAST(ast_pp)
	if *printAst {
		for _, l := range lines {
			fmt.Println(l)
		}
		fmt.Println()
	}
	nodes := convertLinesToNodes(lines)
	tree := buildTree(nodes, 0)

	p := program.NewProgram()
	err = transpiler.TranspileAST(cFilePath, p, tree[0].(ast.Node))
	if err != nil {
		panic(err)
	}

	var buf bytes.Buffer
	if err := format.Node(&buf, p.FileSet, p.File); err != nil {
		panic(err)
	}

	return buf.String()
}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [options] <file.c>\n", os.Args[0])
		flag.PrintDefaults()
	}
	flag.Parse()

	if *version {
		// Simply print out the version and exit.
		fmt.Println(Version)
		return
	}

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

	fmt.Print(Start(flag.Args()))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"offend.me.uk/thiy/lib"

	"github.com/andrew-d/go-termutil"
)

func main() {
	if termutil.Isatty(os.Stdin.Fd()) {
		fmt.Fprintln(os.Stderr, "Could not read from stdin")
		os.Exit(1)
	}

	output, err := lib.Parse(os.Stdin)

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	fmt.Println("<!DOCTYPE html>")
	fmt.Println("")
	fmt.Println(output)
	fmt.Println("")
}
<commit_msg>Add FILE option and some help text<commit_after>package main

import (
	"fmt"
	"io"
	"os"

	"offend.me.uk/thiy/lib"

	"github.com/andrew-d/go-termutil"
)

func printHelp() {
	fmt.Println(`Usage: thiy [FILE]

Reads FILE as YAML, converts it into HTML, and outputs the result.

If FILE is missing or "-", input will be read from stdin.

The input document should be a map where each element represent an HTML node. The contents of each element should be a string, an array of strings and maps, or another map representing the contents of the HTML node.

The element keys take the form:

  <TAG>[#<ID>][.CLASS...][(ATTRIBUTE...)]

Example:

  head:
    title: My first page
  body:
    h1: Hello, world
    div#content:
      p:
      - Generated by
      - a(href=https://github.com/stilvoid/thiy): Thiy

Result:

  <!DOCTYPE html>

      <title>My first page</title>

Hello, world

Part 1

          Generated by
          Thiy

`)
}

func main() {
	var r io.Reader

	if len(os.Args) < 2 || os.Args[1] == "-" {
		if len(os.Args) < 2 && termutil.Isatty(os.Stdin.Fd()) {
			printHelp()
			os.Exit(1)
		}

		r = os.Stdin
	} else {
		file, err := os.Open(os.Args[1])
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		r = file
	}

	output, err := lib.Parse(r)

	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	fmt.Println("<!DOCTYPE html>")
	fmt.Println("")
	fmt.Println(output)
	fmt.Println("")
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"os/signal"
	"sync"

	"github.com/Shopify/sarama"
)

func main() {

	consumerBrokers := []string{"kafka-broker-01.ana.kochava.com:9092", "kafka-broker-02.ana.kochava.com:9092", "kafka-broker-03.ana.kochava.com:9092"}
	producerBrokers := []string{"analytics-kafka-v000-9lzw:9092", "analytics-kafka-v000-u40u:9092", "analytics-kafka-v000-wrdq:9092"}

	logFile, err := os.OpenFile("/var/log/firehose/firehose.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln("Failed to open log file:", err)
	}
	defer logFile.Close()

	log.SetOutput(logFile)

	metricsFile, err := os.OpenFile("/var/log/firehose/metrics.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln("Failed to open log file:", err)
	}
	defer metricsFile.Close()

	log.Println("Getting the Kafka consumer")
	consumer, err := GetKafkaConsumer(consumerBrokers, metricsFile)
	if err != nil {
		log.Println("Unable to create consumer", err)
	}

	log.Println("Getting the Kafka producer")
	producer, err := GetKafkaProducer(producerBrokers, metricsFile)
	if err != nil {
		log.Println("Unable to create producer", err)
	}

	defer CloseConsumer(consumer)
	defer CloseProducer(producer)

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, os.Interrupt)

	var wg sync.WaitGroup

	topic := "events"

	transferChan := make(chan sarama.ProducerMessage, 100000)
	for partition := 0; partition < 24; partition++ {

		partitionConsumer, err := consumer.ConsumePartition(topic, int32(partition), sarama.OffsetNewest)
		if err != nil {
			panic(err)
		}

		wg.Add(1)

		go PullFromTopic(partitionConsumer, transferChan, signals, &wg)
		log.Println("Started consumer for partition ", partition)

		wg.Add(2)
		go PushToTopic(producer, transferChan, signals, &wg)
		log.Println("Started producer")
		go PushToTopic(producer, transferChan, signals, &wg)
		log.Println("Started producer")
	}

	go MonitorChan(transferChan, signals)

	wg.Wait()
}
<commit_msg>Listen for sig int, term, and quit now<commit_after>package main

import (
	"log"
	"os"
	"os/signal"
	"sync"
	"syscall"

	"github.com/Shopify/sarama"
)

func main() {

	consumerBrokers := []string{"kafka-broker-01.ana.kochava.com:9092", "kafka-broker-02.ana.kochava.com:9092", "kafka-broker-03.ana.kochava.com:9092"}
	producerBrokers := []string{"analytics-kafka-v000-9lzw:9092", "analytics-kafka-v000-u40u:9092", "analytics-kafka-v000-wrdq:9092"}

	logFile, err := os.OpenFile("/var/log/firehose/firehose.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln("Failed to open log file:", err)
	}
	defer logFile.Close()

	log.SetOutput(logFile)

	metricsFile, err := os.OpenFile("/var/log/firehose/metrics.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln("Failed to open log file:", err)
	}
	defer metricsFile.Close()

	log.Println("Getting the Kafka consumer")
	consumer, err := GetKafkaConsumer(consumerBrokers, metricsFile)
	if err != nil {
		log.Println("Unable to create consumer", err)
	}

	log.Println("Getting the Kafka producer")
	producer, err := GetKafkaProducer(producerBrokers, metricsFile)
	if err != nil {
		log.Println("Unable to create producer", err)
	}

	defer CloseConsumer(consumer)
	defer CloseProducer(producer)

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT)

	var wg sync.WaitGroup

	topic := "events"

	transferChan := make(chan sarama.ProducerMessage, 100000)
	for partition := 0; partition < 24; partition++ {

		partitionConsumer, err := consumer.ConsumePartition(topic, int32(partition), sarama.OffsetNewest)
		if err != nil {
			panic(err)
		}

		wg.Add(1)

		go PullFromTopic(partitionConsumer, transferChan, signals, &wg)
		log.Println("Started consumer for partition ", partition)

		wg.Add(2)
		go PushToTopic(producer, transferChan, signals, &wg)
		log.Println("Started producer")
		go PushToTopic(producer, transferChan, signals, &wg)
		log.Println("Started producer")
	}

	go MonitorChan(transferChan, signals)

	wg.Wait()
}
<|endoftext|>


<commit_before>package main

import (
    "bytes"
    "fmt"
    "net/http"
    "net/smtp"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!
", r.URL.Path[1:])
    // Connect to the remote SMTP server.
    c, err := smtp.Dial("localhost:25")
    if err != nil {
        fmt.Fprintf(w, "Oh dear 1 - %s", err)
        return
    }
    defer c.Close()
    // Set the sender and recipient.
    c.Mail("admin@chrislhall.net")
    c.Rcpt("root@localhost")
    // Send the email body.
    wc, err := c.Data()
    if err != nil {
        fmt.Fprintf(w, "Oh dear 2 - %s", err)
        return
    }
    defer wc.Close()
    buf := bytes.NewBufferString("Test notification e-mail.")
    if _, err = buf.WriteTo(wc); err != nil {
        fmt.Fprintf(w, "Oh dear 3 - %s", err)
        return
    }
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":9001", nil)
}
<commit_msg>Testing a change so I can figure out why the thing emails me twice.<commit_after>package main

import (
    "fmt"
    "net/http"
    "net/smtp"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!
", r.URL.Path[1:])
    // Connect to the remote SMTP server.
    c, err := smtp.Dial("localhost:25")
    if err != nil {
        fmt.Fprintf(w, "Oh dear 1 - %s", err)
        return
    }
    defer c.Close()
    // Set the sender and recipient.
    c.Mail("admin@chrislhall.net")
    c.Rcpt("root@localhost")
    // Send the email body.
    wc, err := c.Data()
    if err != nil {
        fmt.Fprintf(w, "Oh dear 2 - %s", err)
        return
    }
    defer wc.Close()
    if err = r.Write(wc); err != nil {
        fmt.Fprintf(w, "Oh dear 3 - %s", err)
        return
    }
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":9001", nil)
}
<|endoftext|>