<commit_before>//Irc Bot for New Years Eve Celebration. Posts to irc when new year happens in each timezone
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/url"
	"os"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/hako/durafmt"
	irc "github.com/ugjka/dumbirc"
	c "github.com/ugjka/newyearsbot/common"
)

//Custom flag to get irc channelsn to join
var ircChansFlag c.IrcChans

func init() {
	flag.Var(&ircChansFlag, "chans", "comma seperated list of irc channels to join")
}

//Set target year
var target = func() time.Time {
	tmp := time.Now().UTC()
	if tmp.Month() == time.January && tmp.Day() < 2 {
		return time.Date(tmp.Year(), time.January, 1, 0, 0, 0, 0, time.UTC)
	}
	return time.Date(tmp.Year()+1, time.January, 1, 0, 0, 0, 0, time.UTC)
}()

var usage = `New Year Eve Party Irc Bot
This bot announces new years as they happen in each timezone
You can query location using "hny" trigger for example "hny New York"

CMD Options:
-chans			comma seperated list of irc channels to join eg. "#test, #test2"
-tzpath			path to tz database (./tz.json)
-ircserver		irc server to use irc.example.com:7000 (must be TLS enabled)
-botnick		nick for the bot `

const ircName = "nyebot"

//Default channel list
var ircChannel = []string{"#ugjka", "#ugjkatest", "#ugjkatest2"}

var start = make(chan bool)
var once sync.Once
var next c.TZ

func main() {
	//flags
	tzdatapath := flag.String("tzpath", "./tz.json", "path to tz.json")
	ircServer := flag.String("ircserver", "irc.freenode.net:7000", "Irc server to use, must be TLS")
	ircNick := flag.String("botnick", "HNYbot18", "Irc Nick for the bot")
	flag.Usage = func() {
		fmt.Fprint(os.Stderr, fmt.Sprintf(usage))
	}
	flag.Parse()
	if len(ircChansFlag) > 0 {
		ircChannel = ircChansFlag
	}
	//Check if tz.json exists
	if _, err := os.Stat(*tzdatapath); os.IsNotExist(err) {
		fmt.Fprintf(os.Stderr, "Error: file %s does not exist\n", *tzdatapath)
		os.Exit(1)
	}

	//
	//Set up irc and its callbacks
	//
	ircobj := irc.New(*ircNick, ircName, *ircServer, true)
	ircobj.AddCallback(irc.WELCOME, func(msg irc.Message) {
		ircobj.Join(ircChannel)
		//Prevent early start
		once.Do(func() {
			start <- true
		})
	})
	//Reply ping messages with pong
	ircobj.AddCallback(irc.PING, func(msg irc.Message) {
		ircobj.Pong()
	})
	//Change nick if taken
	ircobj.AddCallback(irc.NICKTAKEN, func(msg irc.Message) {
		if strings.HasSuffix(ircobj.Nick, "_") {
			ircobj.Nick = ircobj.Nick[:len(ircobj.Nick)-1]
		} else {
			ircobj.Nick += "_"
		}
		ircobj.NewNick(ircobj.Nick)
	})
	//Handler for Location queries
	ircobj.AddCallback(irc.PRIVMSG, func(msg irc.Message) {
		if strings.HasPrefix(msg.Trailing, "hny !next") {
			dur, err := time.ParseDuration(next.Offset + "h")
			if err != nil {
				return
			}
			humandur, err := durafmt.ParseString(target.Sub(time.Now().UTC().Add(dur)).String())
			if err != nil {
				return
			}
			ircobj.Reply(msg, fmt.Sprintf("Next new year in %s in %s", humandur, next.String()))
			return
		}
		if strings.HasPrefix(msg.Trailing, "hny ") {
			tz, err := getNewYear(msg.Trailing[4:])
			if err != nil {
				ircobj.Reply(msg, "Some error occurred!")
				return
			}
			ircobj.Reply(msg, tz)
			return
		}

	})
	ircobj.Start()
	//IRC pinger
	go func() {
		for {
			time.Sleep(time.Minute)
			ircobj.Ping()
		}
	}()
	//Reconnect logic
	go func() {
		for {
			log.Println(<-ircobj.Errchan)
			time.Sleep(time.Second * 30)
			ircobj.Start()
		}
	}()
	//Starts when joined, see once.Do
	<-start
	var zones c.TZS
	file, err := os.Open(*tzdatapath)
	if err != nil {
		log.Fatal(err)
	}
	content, err := ioutil.ReadAll(file)
	if err != nil {
		log.Fatal(err)
	}
	if err := json.Unmarshal(content, &zones); err != nil {
		log.Fatal(err)
	}
	sort.Sort(sort.Reverse(zones))
	for i := 0; i < len(zones); i++ {
		dur, err := time.ParseDuration(zones[i].Offset + "h")
		if err != nil {
			log.Fatal(err)
		}
		//Check if zone is past target
		if time.Now().UTC().Add(dur).Before(target) {
			next = zones[i]
			time.Sleep(time.Second * 2)
			humandur, err := durafmt.ParseString(target.Sub(time.Now().UTC().Add(dur)).String())
			if err != nil {
				log.Fatal(err)
			}
			msg := fmt.Sprintf("Next New Year in %s in %s", humandur, zones[i])
			ircobj.PrivMsgBulk(ircChannel, msg)
			//Wait till Target in Timezone
			time.Sleep(target.Sub(time.Now().UTC().Add(dur)))
			msg = fmt.Sprintf("Happy New Year in %s", zones[i])
			ircobj.PrivMsgBulk(ircChannel, msg)
		}
	}
	ircobj.PrivMsgBulk(ircChannel, fmt.Sprintf("That's it, year %d is here across the globe", target.Year()))

}

//Func for querying newyears in specified location
func getNewYear(loc string) (string, error) {
	maps := url.Values{}
	maps.Add("address", loc)
	maps.Add("sensor", "false")
	maps.Add("language", "en")
	data, err := c.Getter(c.Geocode + maps.Encode())
	if err != nil {
		log.Println(err)
		return "", err
	}
	var mapj c.Gmap
	if err = json.Unmarshal(data, &mapj); err != nil {
		log.Println(err)
		return "", err
	}
	if mapj.Status != "OK" {
		return "I don't know that place.", nil
	}
	adress := mapj.Results[0].FormattedAddress
	location := fmt.Sprintf("%.7f,%.7f", mapj.Results[0].Geometry.Location.Lat, mapj.Results[0].Geometry.Location.Lng)
	tmzone := url.Values{}
	tmzone.Add("location", location)
	tmzone.Add("timestamp", fmt.Sprintf("%d", time.Now().Unix()))
	tmzone.Add("sensor", "false")
	data, err = c.Getter(c.Timezone + tmzone.Encode())
	if err != nil {
		log.Println(err)
		return "", err
	}
	var timej c.Gtime
	if err = json.Unmarshal(data, &timej); err != nil {
		log.Println(err)
		return "", err
	}
	if timej.Status != "OK" {
		return "Couldn't get timezone info.", nil
	}
	//RawOffset
	raw, err := time.ParseDuration(fmt.Sprintf("%ds", timej.RawOffset))
	if err != nil {
		log.Println(err)
		return "", err
	}
	//DstOffset
	dst, err := time.ParseDuration(fmt.Sprintf("%ds", timej.DstOffset))
	if err != nil {
		log.Println(err)
		return "", err
	}
	//Check if past target
	if time.Now().UTC().Add(raw + dst).Before(target) {
		humandur, err := durafmt.ParseString(target.Sub(time.Now().UTC().Add(raw + dst)).String())
		if err != nil {
			log.Println(err)
			return "", err
		}
		return fmt.Sprintf("New Year in %s will happen in %s", adress, humandur), nil
	}
	return fmt.Sprintf("New year in %s already happened.", adress), nil
}
<commit_msg>use time.Timer instead of time.Sleep<commit_after>//Irc Bot for New Years Eve Celebration. Posts to irc when new year happens in each timezone
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/url"
	"os"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/hako/durafmt"
	irc "github.com/ugjka/dumbirc"
	c "github.com/ugjka/newyearsbot/common"
)

//Custom flag to get irc channelsn to join
var ircChansFlag c.IrcChans

func init() {
	flag.Var(&ircChansFlag, "chans", "comma seperated list of irc channels to join")
}

//Set target year
var target = func() time.Time {
	tmp := time.Now().UTC()
	if tmp.Month() == time.January && tmp.Day() < 2 {
		return time.Date(tmp.Year(), time.January, 1, 0, 0, 0, 0, time.UTC)
	}
	//return time.Date(tmp.Year(), time.April, 4, 0, 0, 0, 0, time.UTC)
	return time.Date(tmp.Year()+1, time.January, 1, 0, 0, 0, 0, time.UTC)
}()

var usage = `New Year Eve Party Irc Bot
This bot announces new years as they happen in each timezone
You can query location using "hny" trigger for example "hny New York"

CMD Options:
-chans			comma seperated list of irc channels to join eg. "#test, #test2"
-tzpath			path to tz database (./tz.json)
-ircserver		irc server to use irc.example.com:7000 (must be TLS enabled)
-botnick		nick for the bot `

const ircName = "nyebot"

//Default channel list
var ircChannel = []string{"#ugjka", "#ugjkatest", "#ugjkatest2"}

var start = make(chan bool)
var once sync.Once
var next c.TZ

func main() {
	//flags
	tzdatapath := flag.String("tzpath", "./tz.json", "path to tz.json")
	ircServer := flag.String("ircserver", "irc.freenode.net:7000", "Irc server to use, must be TLS")
	ircNick := flag.String("botnick", "HNYbot18", "Irc Nick for the bot")
	flag.Usage = func() {
		fmt.Fprint(os.Stderr, fmt.Sprintf(usage))
	}
	flag.Parse()
	if len(ircChansFlag) > 0 {
		ircChannel = ircChansFlag
	}
	//Check if tz.json exists
	if _, err := os.Stat(*tzdatapath); os.IsNotExist(err) {
		fmt.Fprintf(os.Stderr, "Error: file %s does not exist\n", *tzdatapath)
		os.Exit(1)
	}

	//
	//Set up irc and its callbacks
	//
	ircobj := irc.New(*ircNick, ircName, *ircServer, true)
	ircobj.AddCallback(irc.WELCOME, func(msg irc.Message) {
		ircobj.Join(ircChannel)
		//Prevent early start
		once.Do(func() {
			start <- true
		})
	})
	//Reply ping messages with pong
	ircobj.AddCallback(irc.PING, func(msg irc.Message) {
		ircobj.Pong()
	})
	//Change nick if taken
	ircobj.AddCallback(irc.NICKTAKEN, func(msg irc.Message) {
		if strings.HasSuffix(ircobj.Nick, "_") {
			ircobj.Nick = ircobj.Nick[:len(ircobj.Nick)-1]
		} else {
			ircobj.Nick += "_"
		}
		ircobj.NewNick(ircobj.Nick)
	})
	//Handler for Location queries
	ircobj.AddCallback(irc.PRIVMSG, func(msg irc.Message) {
		if strings.HasPrefix(msg.Trailing, "hny !next") {
			dur, err := time.ParseDuration(next.Offset + "h")
			if err != nil {
				return
			}
			humandur, err := durafmt.ParseString(target.Sub(time.Now().UTC().Add(dur)).String())
			if err != nil {
				return
			}
			ircobj.Reply(msg, fmt.Sprintf("Next new year in %s in %s", humandur, next.String()))
			return
		}
		if strings.HasPrefix(msg.Trailing, "hny ") {
			tz, err := getNewYear(msg.Trailing[4:])
			if err != nil {
				ircobj.Reply(msg, "Some error occurred!")
				return
			}
			ircobj.Reply(msg, tz)
			return
		}

	})
	ircobj.Start()
	//IRC pinger
	go func() {
		for {
			time.Sleep(time.Minute)
			ircobj.Ping()
		}
	}()
	//Reconnect logic
	go func() {
		for {
			log.Println(<-ircobj.Errchan)
			time.Sleep(time.Second * 30)
			ircobj.Start()
		}
	}()
	//Starts when joined, see once.Do
	<-start
	var zones c.TZS
	file, err := os.Open(*tzdatapath)
	if err != nil {
		log.Fatal(err)
	}
	content, err := ioutil.ReadAll(file)
	if err != nil {
		log.Fatal(err)
	}
	if err := json.Unmarshal(content, &zones); err != nil {
		log.Fatal(err)
	}
	sort.Sort(sort.Reverse(zones))
	for i := 0; i < len(zones); i++ {
		dur, err := time.ParseDuration(zones[i].Offset + "h")
		if err != nil {
			log.Fatal(err)
		}
		//Check if zone is past target
		if time.Now().UTC().Add(dur).Before(target) {
			next = zones[i]
			time.Sleep(time.Second * 2)
			humandur, err := durafmt.ParseString(target.Sub(time.Now().UTC().Add(dur)).String())
			if err != nil {
				log.Fatal(err)
			}
			msg := fmt.Sprintf("Next New Year in %s in %s", humandur, zones[i])
			ircobj.PrivMsgBulk(ircChannel, msg)
			//Wait till Target in Timezone
			timer := time.NewTimer(target.Sub(time.Now().UTC().Add(dur)))
			<-timer.C
			msg = fmt.Sprintf("Happy New Year in %s", zones[i])
			ircobj.PrivMsgBulk(ircChannel, msg)
		}
	}
	ircobj.PrivMsgBulk(ircChannel, fmt.Sprintf("That's it, year %d is here across the globe", target.Year()))

}

//Func for querying newyears in specified location
func getNewYear(loc string) (string, error) {
	maps := url.Values{}
	maps.Add("address", loc)
	maps.Add("sensor", "false")
	maps.Add("language", "en")
	data, err := c.Getter(c.Geocode + maps.Encode())
	if err != nil {
		log.Println(err)
		return "", err
	}
	var mapj c.Gmap
	if err = json.Unmarshal(data, &mapj); err != nil {
		log.Println(err)
		return "", err
	}
	if mapj.Status != "OK" {
		return "I don't know that place.", nil
	}
	adress := mapj.Results[0].FormattedAddress
	location := fmt.Sprintf("%.7f,%.7f", mapj.Results[0].Geometry.Location.Lat, mapj.Results[0].Geometry.Location.Lng)
	tmzone := url.Values{}
	tmzone.Add("location", location)
	tmzone.Add("timestamp", fmt.Sprintf("%d", time.Now().Unix()))
	tmzone.Add("sensor", "false")
	data, err = c.Getter(c.Timezone + tmzone.Encode())
	if err != nil {
		log.Println(err)
		return "", err
	}
	var timej c.Gtime
	if err = json.Unmarshal(data, &timej); err != nil {
		log.Println(err)
		return "", err
	}
	if timej.Status != "OK" {
		return "Couldn't get timezone info.", nil
	}
	//RawOffset
	raw, err := time.ParseDuration(fmt.Sprintf("%ds", timej.RawOffset))
	if err != nil {
		log.Println(err)
		return "", err
	}
	//DstOffset
	dst, err := time.ParseDuration(fmt.Sprintf("%ds", timej.DstOffset))
	if err != nil {
		log.Println(err)
		return "", err
	}
	//Check if past target
	if time.Now().UTC().Add(raw + dst).Before(target) {
		humandur, err := durafmt.ParseString(target.Sub(time.Now().UTC().Add(raw + dst)).String())
		if err != nil {
			log.Println(err)
			return "", err
		}
		return fmt.Sprintf("New Year in %s will happen in %s", adress, humandur), nil
	}
	return fmt.Sprintf("New year in %s already happened.", adress), nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime/pprof"
)

var (
	file    = flag.String("file", "", "Source file (required)")
	in      = flag.String("in", "", "Input file")
	out     = flag.String("out", "", "Output file or /dev/null")
	profile = flag.String("profile", "", "Write CPU profile to file")
	tape    = flag.String("tape", "static", "Tape type: static or dynamic")
	dump    = flag.Bool("dump", false, "Dump AST and terminate")
	noop    = flag.Bool("noop", false, "Disable optimization")
	show    = flag.Int("show", 0, "Dump # tape cells around last position")
)

func output(out, in string) (io.ReadWriter, error) {
	var err error
	var r io.Reader
	var w io.Writer

	if out != "" {
		w, err = os.Create(out)
		if err != nil {
			return nil, err
		}
	} else {
		w = os.Stdout
	}

	if in != "" {
		r, err = os.Open(in)
		if err != nil {
			return nil, err
		}
	} else {
		r = os.Stdin
	}
	return struct {
		io.Reader
		io.Writer
	}{r, w}, nil
}

var storage = map[string]func(io.ReadWriter) Storage{
	"static":  NewStaticTape,
	"dynamic": NewDynamicTape,
}

func main() {
	flag.Parse()

	if *profile != "" {
		f, err := os.Create(*profile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if *file == "" {
		flag.Usage()
		return
	}

	program, err := ParseFile(*file)
	if err != nil {
		log.Fatal(err)
	}

	if !*noop {
		program = Optimize(program)
	}

	if *dump {
		fmt.Println(program)
		return
	}

	if st, ok := storage[*tape]; ok {
		o, err := output(*out, *in)
		if err != nil {
			log.Fatal(err)
		}
		s := st(o)
		Execute(program, s)
		if *show > 0 {
			cels, pos := s.Dump()
			from := pos - *show/2
			if from < 0 {
				from = 0
			}
			to := pos + *show/2
			if to > len(cels) {
				to = len(cels)
			}
			log.Println("From", from, "to", to, cels[from:to])
		}
	} else {
		flag.Usage()
		return
	}
}
<commit_msg>Catch panics<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime/pprof"
)

var (
	file    = flag.String("file", "", "Source file (required)")
	in      = flag.String("in", "", "Input file")
	out     = flag.String("out", "", "Output file or /dev/null")
	profile = flag.String("profile", "", "Write CPU profile to file")
	tape    = flag.String("tape", "static", "Tape type: static or dynamic")
	dump    = flag.Bool("dump", false, "Dump AST and terminate")
	noop    = flag.Bool("noop", false, "Disable optimization")
	show    = flag.Int("show", 0, "Dump # tape cells around last position")
)

func output(out, in string) (io.ReadWriter, error) {
	var err error
	var r io.Reader
	var w io.Writer

	if out != "" {
		w, err = os.Create(out)
		if err != nil {
			return nil, err
		}
	} else {
		w = os.Stdout
	}

	if in != "" {
		r, err = os.Open(in)
		if err != nil {
			return nil, err
		}
	} else {
		r = os.Stdin
	}
	return struct {
		io.Reader
		io.Writer
	}{r, w}, nil
}

var storage = map[string]func(io.ReadWriter) Storage{
	"static":  NewStaticTape,
	"dynamic": NewDynamicTape,
}

func main() {
	flag.Parse()

	defer func() {
		if r := recover(); r != nil {
			log.Fatal(r)
		}
	}()

	if *profile != "" {
		f, err := os.Create(*profile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if *file == "" {
		flag.Usage()
		return
	}

	program, err := ParseFile(*file)
	if err != nil {
		log.Fatal(err)
	}

	if !*noop {
		program = Optimize(program)
	}

	if *dump {
		fmt.Println(program)
		return
	}

	if st, ok := storage[*tape]; ok {
		o, err := output(*out, *in)
		if err != nil {
			log.Fatal(err)
		}
		s := st(o)
		Execute(program, s)
		if *show > 0 {
			cels, pos := s.Dump()
			from := pos - *show/2
			if from < 0 {
				from = 0
			}
			to := pos + *show/2
			if to > len(cels) {
				to = len(cels)
			}
			log.Println("From", from, "to", to, cels[from:to])
		}
	} else {
		flag.Usage()
		return
	}
}
<|endoftext|>


<commit_before>package main

// The import section defines libraries that we are going to use in our program.
import (
	"fmt"
	"log"
	"net/http"
	"crypto/rand"

	"encoding/json"
	"github.com/gorilla/mux"
	"github.com/ory-am/common/env"
	"github.com/ory-am/common/pkg"
	"github.com/pborman/uuid"
	"github.com/rs/cors"
	"math"
	"strconv"

	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
	. "github.com/ory-am/workshop-dbg/store"
	"github.com/ory-am/workshop-dbg/store/memory"
	"github.com/ory-am/workshop-dbg/store/postgres"
	"time"
)

// In a 12 factor app, we must obey the environment variables.
var envHost = env.Getenv("HOST", "")
var envPort = env.Getenv("PORT", "5678")
var databaseURL = env.Getenv("DATABASE_URL", "")
var thisID = uuid.New()

// MyContacts is an exemplary list of contacts.
var MyContacts = Contacts{
	// Each contact hs identified by its ID which is prepended with "my-id":
	// We are doing this because it is easier to manage and simpler to read.
	"john-bravo": &Contact{
		Name:       "Andreas Preuss",
		Department: "IT",
		Company:    "ACME Inc",
	},
	"cathrine-mueller": &Contact{
		Name:       "Cathrine Müller",
		Department: "HR",
		Company:    "Grove AG",
	},
	"maximilian-schmidt": &Contact{
		Name:       "Maximilian Schmidt",
		Department: "PR",
		Company:    "Titanpad AG",
	},
	"uwe-charly": &Contact{
		Name:       "Uwe Charly",
		Department: "FAC",
		Company:    "KPMG",
	},
	"Thomas-Aidan": &Contact{
		Name:       "Thomas Aidan",
		Department: "INO",
		Company:    "OuterSpace",
	},
	"frank-sec": &Contact{
		Name:       "Frank Secure",
		Department: "Unknown",
		Company:    "Secret",
	},
	"juergen-elsner": &Contact{
		Name:       "Jürgen Elsner",
		Department: "DaCS",
		Company:    "DBG",
	},
	"Stephane-Deschamps": &Contact{
		Name:       "Stephane Deschamps",
		Department: "DaCS",
		Company:    "DBG",
	},
	"Gilles-Lamy": &Contact{
		Name:       "MGilles Lamy",
		Department: "DaCS",
		Company:    "DBG",
	},
}

var memoryStore = &memory.InMemoryStore{Contacts: MyContacts}

// The main routine is going the "entry" point.
func main() {
	// Create a new router.
	router := mux.NewRouter()

	// RESTful defines operations
	// * GET for fetching data
	// * POST for inserting data
	// * PUT for updating existing data
	// * DELETE for deleting data
	router.HandleFunc("/memory/contacts", ListContacts(memoryStore)).Methods("GET")
	router.HandleFunc("/memory/contacts", AddContact(memoryStore)).Methods("POST")
	router.HandleFunc("/memory/contacts/{id}", UpdateContact(memoryStore)).Methods("PUT")
	router.HandleFunc("/memory/contacts/{id}", DeleteContact(memoryStore)).Methods("DELETE")

	// Connect to database store
	db, err := sqlx.Connect("postgres", databaseURL)
	if err != nil {
		log.Printf("Could not connect to database because %s", err)
	} else {
		databaseStore := &postgres.PostgresStore{DB: db}
		if err := databaseStore.CreateSchemas(); err != nil {
			log.Printf("Could not set up relations %s", err)
		} else {
			router.HandleFunc("/database/contacts", ListContacts(databaseStore)).Methods("GET")
			router.HandleFunc("/database/contacts", AddContact(databaseStore)).Methods("POST")
			router.HandleFunc("/database/contacts/{id}", UpdateContact(databaseStore)).Methods("PUT")
			router.HandleFunc("/database/contacts/{id}", DeleteContact(databaseStore)).Methods("DELETE")
		}
	}

	// The info endpoint is for showing demonstration purposes only and is not subject to any task.
	router.HandleFunc("/info", InfoHandler).Methods("GET")
	router.HandleFunc("/pi", ComputePi).Methods("GET")
	router.HandleFunc("/pis", ComputePis).Methods("GET")
	router.HandleFunc("/allocate", Allocate).Methods("GET")

	// Print where to point the browser at.
	fmt.Printf("Listening on %s\n", "http://localhost:5678")

	// Cross origin resource requests
	c := cors.New(cors.Options{
		AllowedOrigins: []string{"*"},
		AllowedMethods: []string{"GET", "POST", "DELETE", "PUT"}},
	)

	// Start up the server and check for errors.
	listenOn := fmt.Sprintf("%s:%s", envHost, envPort)
	if err := http.ListenAndServe(listenOn, c.Handler(router)); err != nil {
		log.Fatalf("Could not set up server because %s", err)
	}
}

// ListContacts takes a contact list and outputs it.
func ListContacts(store ContactStorer) func(rw http.ResponseWriter, r *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {

		// Write contact list to output
		contacts, err := store.FetchContacts()
		if err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		pkg.WriteIndentJSON(rw, contacts)
	}
}

// AddContact will add a contact to the list
func AddContact(contacts ContactStorer) func(rw http.ResponseWriter, r *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {

		// We parse the request's information into contactToBeAdded
		contactToBeAdded, err := ReadContactData(rw, r)

		// Abort handling the request if an error occurs.
		if err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		// Save newContact to the list of contacts.
		if err = contacts.CreateContact(&contactToBeAdded); err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		// Output our newly created contact
		pkg.WriteIndentJSON(rw, contactToBeAdded)
	}
}

// DeleteContact will delete a contact from the list
func DeleteContact(contacts ContactStorer) func(rw http.ResponseWriter, r *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {
		// Fetch the ID of the contact that is going to be deleted
		contactToBeDeleted := mux.Vars(r)["id"]

		// Delete the contact from the list
		if err := contacts.DeleteContact(contactToBeDeleted); err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		// Per specification, RESTful may return an empty response when a DELETE request was successful
		rw.WriteHeader(http.StatusNoContent)
	}
}

// UpdateContact will update a contact on the list
func UpdateContact(store ContactStorer) func(rw http.ResponseWriter, r *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {
		// We parse the request's information into newContactData.
		newContactData, err := ReadContactData(rw, r)

		// Abort handling the request if an error occurs.
		if err != nil {
			http.Error(rw, err.Error(), http.StatusBadRequest)
			return
		}

		// Update the data in the contact list.
		if err := store.UpdateContact(&newContactData); err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		// Set the new data
		pkg.WriteIndentJSON(rw, newContactData)
	}
}

// ReadContactData is a helper function for parsing a HTTP request body. It returns a contact on success and an
// error if something went wrong.
func ReadContactData(rw http.ResponseWriter, r *http.Request) (contact Contact, err error) {
	err = json.NewDecoder(r.Body).Decode(&contact)
	if err != nil {
		http.Error(rw, fmt.Sprintf("Could not read input data because %s", err), http.StatusBadRequest)
		return contact, err
	}

	return contact, nil
}

func Allocate(rw http.ResponseWriter, r *http.Request) {
	n, err := strconv.Atoi(r.URL.Query().Get("n"))
	if err != nil {
		n = 0
	}
	t, err := strconv.Atoi(r.URL.Query().Get("t"))
	if err != nil {
		t = 5
	}
	m := make([][]byte, n + 1)

	for i := 0; i < n; i++ {
		z := make([]byte, n + 1)
		_, _ = rand.Read(z)
		m[i] = z
	}

	time.Sleep(time.Second * time.Duration(t))

	pkg.WriteIndentJSON(rw, struct {
		Result string `json:"result"`
		N      int `json:"n"`
	}{
		Result: "Processed!",
		N: n,
	})
}

func ComputePi(rw http.ResponseWriter, r *http.Request) {
	n, err := strconv.Atoi(r.URL.Query().Get("n"))
	if err != nil {
		n = 0
	}

	pkg.WriteIndentJSON(rw, struct {
		Pi string `json:"pi"`
		N  int    `json:"n"`
	}{
		Pi: strconv.FormatFloat(pi(n), 'E', -1, 64),
		N:  n,
	})
}

func ComputePis(rw http.ResponseWriter, r *http.Request) {
	n, err := strconv.Atoi(r.URL.Query().Get("n"))
	if err != nil {
		n = 0
	}

	pkg.WriteIndentJSON(rw, struct {
		Pi string `json:"pi"`
		N  int    `json:"n"`
	}{
		Pi: strconv.FormatFloat(pis(int64(n)), 'E', -1, 64),
		N:  n,
	})
}

func InfoHandler(rw http.ResponseWriter, r *http.Request) {
	rw.Write([]byte(thisID))
}

// pi launches n goroutines to compute an
// approximation of pi.
func pis(n int64) float64 {
	f := 0.0
	k := 0.0
	start := time.Now()
	for start.Add(time.Second * time.Duration(n)).After(time.Now()) {
		f += terms(k)
		k++
	}
	return f
}

func terms(k float64) float64 {
	return 4 * math.Pow(-1, k) / (2 * k + 1)
}

// pi launches n goroutines to compute an
// approximation of pi.
func pi(n int) float64 {
	ch := make(chan float64)
	for k := 0; k <= n; k++ {
		go term(ch, float64(k))
	}
	f := 0.0
	for k := 0; k <= n; k++ {
		f += <-ch
	}
	return f
}

func term(ch chan float64, k float64) {
	ch <- 4 * math.Pow(-1, k) / (2 * k + 1)
}
<commit_msg>super code<commit_after>package main

// The import section defines libraries that we are going to use in our program.
import (
	"fmt"
	"log"
	"net/http"
	"crypto/rand"

	"encoding/json"
	"github.com/gorilla/mux"
	"github.com/ory-am/common/env"
	"github.com/ory-am/common/pkg"
	"github.com/pborman/uuid"
	"github.com/rs/cors"
	"math"
	"strconv"

	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
	. "github.com/ory-am/workshop-dbg/store"
	"github.com/ory-am/workshop-dbg/store/memory"
	"github.com/ory-am/workshop-dbg/store/postgres"
	"time"
)

// In a 12 factor app, we must obey the environment variables.
var envHost = env.Getenv("HOST", "")
var envPort = env.Getenv("PORT", "5678")
var databaseURL = env.Getenv("DATABASE_URL", "")
var thisID = uuid.New()

// MyContacts is an exemplary list of contacts.
var MyContacts = Contacts{
	// Each contact hs identified by its ID which is prepended with "my-id":
	// We are doing this because it is easier to manage and simpler to read.
	"john-bravo": &Contact{
		Name:       "Andreas Preuss",
		Department: "IT",
		Company:    "ACME Inc",
	},
	"cathrine-mueller": &Contact{
		Name:       "Cathrine Müller",
		Department: "HR",
		Company:    "Grove AG",
	},
	"maximilian-schmidt": &Contact{
		Name:       "Maximilian Schmidt",
		Department: "PR",
		Company:    "Titanpad AG",
	},
	"uwe-charly": &Contact{
		Name:       "Uwe Charly",
		Department: "FAC",
		Company:    "KPMG",
	},
	"Thomas-Aidan": &Contact{
		Name:       "Thomas Aidan",
		Department: "INO",
		Company:    "OuterSpace",
	},
	"frank-sec": &Contact{
		Name:       "Frank Secure",
		Department: "Unknown",
		Company:    "Secret",
	},
	"juergen-elsner": &Contact{
		Name:       "Jürgen Elsner",
		Department: "DaCS",
		Company:    "DBG",
	},
	"Stephane-Deschamps": &Contact{
		Name:       "Stephane Deschamps",
		Department: "DaCS",
		Company:    "DBG",
	},
	"Gilles-Lamy": &Contact{
		Name:       "MGilles Lamy",
		Department: "DaCS",
		Company:    "DBG",
	},
	"Helge Harren": &Contact{
		Name:       "Helge Harren",
		Department: "TRIT",
		Company:    "DBG",
	},
	"Stephan Reinartz": &Contact{
		Name:       "Stephan Reinartz",
		Department: "SMMI",
		Company:    "DBG",
	},
	"Ulrich Meyer": &Contact{
		Name:       "Ulrich Meyer",
		Department: "TRIT",
		Company:    "DBG",
	},
}

var memoryStore = &memory.InMemoryStore{Contacts: MyContacts}

// The main routine is going the "entry" point.
func main() {
	// Create a new router.
	router := mux.NewRouter()

	// RESTful defines operations
	// * GET for fetching data
	// * POST for inserting data
	// * PUT for updating existing data
	// * DELETE for deleting data
	router.HandleFunc("/memory/contacts", ListContacts(memoryStore)).Methods("GET")
	router.HandleFunc("/memory/contacts", AddContact(memoryStore)).Methods("POST")
	router.HandleFunc("/memory/contacts/{id}", UpdateContact(memoryStore)).Methods("PUT")
	router.HandleFunc("/memory/contacts/{id}", DeleteContact(memoryStore)).Methods("DELETE")

	// Connect to database store
	db, err := sqlx.Connect("postgres", databaseURL)
	if err != nil {
		log.Printf("Could not connect to database because %s", err)
	} else {
		databaseStore := &postgres.PostgresStore{DB: db}
		if err := databaseStore.CreateSchemas(); err != nil {
			log.Printf("Could not set up relations %s", err)
		} else {
			router.HandleFunc("/database/contacts", ListContacts(databaseStore)).Methods("GET")
			router.HandleFunc("/database/contacts", AddContact(databaseStore)).Methods("POST")
			router.HandleFunc("/database/contacts/{id}", UpdateContact(databaseStore)).Methods("PUT")
			router.HandleFunc("/database/contacts/{id}", DeleteContact(databaseStore)).Methods("DELETE")
		}
	}

	// The info endpoint is for showing demonstration purposes only and is not subject to any task.
	router.HandleFunc("/info", InfoHandler).Methods("GET")
	router.HandleFunc("/pi", ComputePi).Methods("GET")
	router.HandleFunc("/pis", ComputePis).Methods("GET")
	router.HandleFunc("/allocate", Allocate).Methods("GET")

	// Print where to point the browser at.
	fmt.Printf("Listening on %s\n", "http://localhost:5678")

	// Cross origin resource requests
	c := cors.New(cors.Options{
		AllowedOrigins: []string{"*"},
		AllowedMethods: []string{"GET", "POST", "DELETE", "PUT"}},
	)

	// Start up the server and check for errors.
	listenOn := fmt.Sprintf("%s:%s", envHost, envPort)
	if err := http.ListenAndServe(listenOn, c.Handler(router)); err != nil {
		log.Fatalf("Could not set up server because %s", err)
	}
}

// ListContacts takes a contact list and outputs it.
func ListContacts(store ContactStorer) func(rw http.ResponseWriter, r *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {

		// Write contact list to output
		contacts, err := store.FetchContacts()
		if err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		pkg.WriteIndentJSON(rw, contacts)
	}
}

// AddContact will add a contact to the list
func AddContact(contacts ContactStorer) func(rw http.ResponseWriter, r *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {

		// We parse the request's information into contactToBeAdded
		contactToBeAdded, err := ReadContactData(rw, r)

		// Abort handling the request if an error occurs.
		if err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		// Save newContact to the list of contacts.
		if err = contacts.CreateContact(&contactToBeAdded); err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		// Output our newly created contact
		pkg.WriteIndentJSON(rw, contactToBeAdded)
	}
}

// DeleteContact will delete a contact from the list
func DeleteContact(contacts ContactStorer) func(rw http.ResponseWriter, r *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {
		// Fetch the ID of the contact that is going to be deleted
		contactToBeDeleted := mux.Vars(r)["id"]

		// Delete the contact from the list
		if err := contacts.DeleteContact(contactToBeDeleted); err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		// Per specification, RESTful may return an empty response when a DELETE request was successful
		rw.WriteHeader(http.StatusNoContent)
	}
}

// UpdateContact will update a contact on the list
func UpdateContact(store ContactStorer) func(rw http.ResponseWriter, r *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {
		// We parse the request's information into newContactData.
		newContactData, err := ReadContactData(rw, r)

		// Abort handling the request if an error occurs.
		if err != nil {
			http.Error(rw, err.Error(), http.StatusBadRequest)
			return
		}

		// Update the data in the contact list.
		if err := store.UpdateContact(&newContactData); err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}

		// Set the new data
		pkg.WriteIndentJSON(rw, newContactData)
	}
}

// ReadContactData is a helper function for parsing a HTTP request body. It returns a contact on success and an
// error if something went wrong.
func ReadContactData(rw http.ResponseWriter, r *http.Request) (contact Contact, err error) {
	err = json.NewDecoder(r.Body).Decode(&contact)
	if err != nil {
		http.Error(rw, fmt.Sprintf("Could not read input data because %s", err), http.StatusBadRequest)
		return contact, err
	}

	return contact, nil
}

func Allocate(rw http.ResponseWriter, r *http.Request) {
	n, err := strconv.Atoi(r.URL.Query().Get("n"))
	if err != nil {
		n = 0
	}
	t, err := strconv.Atoi(r.URL.Query().Get("t"))
	if err != nil {
		t = 5
	}
	m := make([][]byte, n + 1)

	for i := 0; i < n; i++ {
		z := make([]byte, n + 1)
		_, _ = rand.Read(z)
		m[i] = z
	}

	time.Sleep(time.Second * time.Duration(t))

	pkg.WriteIndentJSON(rw, struct {
		Result string `json:"result"`
		N      int `json:"n"`
	}{
		Result: "Processed!",
		N: n,
	})
}

func ComputePi(rw http.ResponseWriter, r *http.Request) {
	n, err := strconv.Atoi(r.URL.Query().Get("n"))
	if err != nil {
		n = 0
	}

	pkg.WriteIndentJSON(rw, struct {
		Pi string `json:"pi"`
		N  int    `json:"n"`
	}{
		Pi: strconv.FormatFloat(pi(n), 'E', -1, 64),
		N:  n,
	})
}

func ComputePis(rw http.ResponseWriter, r *http.Request) {
	n, err := strconv.Atoi(r.URL.Query().Get("n"))
	if err != nil {
		n = 0
	}

	pkg.WriteIndentJSON(rw, struct {
		Pi string `json:"pi"`
		N  int    `json:"n"`
	}{
		Pi: strconv.FormatFloat(pis(int64(n)), 'E', -1, 64),
		N:  n,
	})
}

func InfoHandler(rw http.ResponseWriter, r *http.Request) {
	rw.Write([]byte(thisID))
}

// pi launches n goroutines to compute an
// approximation of pi.
func pis(n int64) float64 {
	f := 0.0
	k := 0.0
	start := time.Now()
	for start.Add(time.Second * time.Duration(n)).After(time.Now()) {
		f += terms(k)
		k++
	}
	return f
}

func terms(k float64) float64 {
	return 4 * math.Pow(-1, k) / (2 * k + 1)
}

// pi launches n goroutines to compute an
// approximation of pi.
func pi(n int) float64 {
	ch := make(chan float64)
	for k := 0; k <= n; k++ {
		go term(ch, float64(k))
	}
	f := 0.0
	for k := 0; k <= n; k++ {
		f += <-ch
	}
	return f
}

func term(ch chan float64, k float64) {
	ch <- 4 * math.Pow(-1, k) / (2 * k + 1)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"os"
	"regexp"
	"strconv"
	"strings"

	logrus "github.com/Sirupsen/logrus"
	docopt "github.com/docopt/docopt-go"

	"github.com/9seconds/ah/app/commands"
	"github.com/9seconds/ah/app/environments"
	"github.com/9seconds/ah/app/slices"
	"github.com/9seconds/ah/app/utils"
)

const docoptOptions = `ah - A better history.

Ah is a better way to traverse the history of your shell prompts. You can
store an outputs of your commands, you can search with regular expressions
out of box, bookmark commands etc.

You may want to check detailed readme at https://github.com/9seconds/ah

Just a short reminder on possible subcommands:
    - s  - shows extended output from your HISTFILE
    - b  - bookmarks any command you want to have a faster access.
    - e  - executes a command by its bookmark name or history number.
    - t  - traces an output of the command and stores it safely.
    - l  - lists you an output of the command.
    - lb - lists available bookmarks.
    - rb - removes bookmarks.
    - gt - garbage collecting of the traces. Cleans old outputs.
    - gb - garbage collecting of the bookmarks. Swipes out old ones.
	- ad - add command to the list of auto ah'ed
	- ar - remove commands from the list of auto ah'ed
	- al - list of commands which should be auto ah'ed

Usage:
    ah [options] s [-z] [-g PATTERN] [<lastNcommands> | <startFromNCommand> <finishByMCommand>]
    ah [options] b <commandNumber> <bookmarkAs>
    ah [options] e [-x] [-y] <commandNumberOrBookMarkName>
    ah [options] t [-x] [-y] [--] <command>...
    ah [options] l <numberOfCommandYouWantToCheck>
    ah [options] lb
    ah [options] rb <bookmarkToRemove>...
    ah [options] (gt | gb) (--keepLatest <keepLatest> | --olderThan <olderThan> | --all)
    ah [options] al
    ah [options] ad [-x] [-y] <command>...
    ah [options] ar <command>...
    ah (-h | --help)
    ah --version

Options:
    -s SHELL, --shell=SHELL
       Shell flavour you are using.
       By default, ah will do some shallow investigations.
    -f HISTFILE, --histfile=HISTFILE
       The path to a history file.
       By default ah will try to use default history file of your shell.
    -t HISTTIMEFORMAT, --histtimeformat=HISTTIMEFORMAT
       A time format for history output. Will use $HISTTIMEFORMAT by default.
    -d APPDIR, --appdir=APPDIR
       A place where ah has to store its data.
    -m TMPDIR, --tmpdir=TMPDIR
       A temporary place where ah stores an output. Set it only if you need it.
    -g PATTERN, --grep PATTERN
       A pattern to filter command lines. It is regular expression if no -f option is set.
    -y, --tty
       Allocates pseudo-tty is necessary.
    -x, --run-in-real-shell
       Runs a command in real interactive shell.
    -z, --fuzzy
       Interpret -g pattern as fuzzy match string.
    -v, --debug
       Shows a debug log of command execution.`

const version = "ah 0.12"

var validateBookmarkName = utils.CreateRegexp(`^[A-Za-z_]\w*$`)

type executor func(map[string]interface{}, *environments.Environment)

func main() {
	defer func() {
		if exc := recover(); exc != nil {
			utils.Logger.Fatal(exc)
		}
	}()

	arguments, err := docopt.Parse(docoptOptions, nil, true, version, false)
	if err != nil {
		panic(err)
	}

	if arguments["--debug"].(bool) {
		utils.EnableLogging()
	} else {
		utils.DisableLogging()
	}

	env := new(environments.Environment)
	argShell := arguments["--shell"]
	if argShell == nil {
		env.DiscoverShell()
	} else {
		env.SetShell(argShell.(string))
	}

	argHistFile := arguments["--histfile"]
	if argHistFile == nil {
		env.DiscoverHistFile()
	} else {
		env.SetHistFile(argHistFile.(string))
	}

	argHistTimeFormat := arguments["--histtimeformat"]
	if argHistTimeFormat == nil {
		env.DiscoverHistTimeFormat()
	} else {
		env.SetHistTimeFormat(argHistTimeFormat.(string))
	}

	argAppDir := arguments["--appdir"]
	if argAppDir == nil {
		env.DiscoverAppDir()
	} else {
		env.SetAppDir(argAppDir.(string))
	}

	argTmpDir := arguments["--tmpdir"]
	if argTmpDir == nil {
		env.DiscoverTmpDir()
	} else {
		env.SetTmpDir(argTmpDir.(string))
	}

	utils.Logger.WithFields(logrus.Fields{
		"arguments":   arguments,
		"environment": env,
	}).Debug("Ready to start")

	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.GetTracesDir(), 0777),
	}).Info("Create traces dir")
	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.GetBookmarksDir(), 0777),
	}).Info("Create bookmarks dir")
	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.GetTmpDir(), 0777),
	}).Info("Create create temporary dir")

	var exec executor
	switch {
	case arguments["t"].(bool):
		utils.Logger.Info("Execute command 'tee'")
		exec = executeTee
	case arguments["s"].(bool):
		utils.Logger.Info("Execute command 'show'")
		exec = executeShow
	case arguments["l"].(bool):
		utils.Logger.Info("Execute command 'listTrace'")
		exec = executeListTrace
	case arguments["b"].(bool):
		utils.Logger.Info("Execute command 'listTrace'")
		exec = executeListTrace
	case arguments["e"].(bool):
		utils.Logger.Info("Execute command 'execute'")
		exec = executeExec
	case arguments["lb"].(bool):
		utils.Logger.Info("Execute command 'listBookmarks'")
		exec = executeListBookmarks
	case arguments["rb"].(bool):
		utils.Logger.Info("Execute command 'removeBookmarks'")
		exec = executeRemoveBookmarks
	case arguments["gt"].(bool) || arguments["gb"].(bool):
		utils.Logger.Info("Execute command 'gc'")
		exec = executeGC
	case arguments["al"].(bool):
		utils.Logger.Info("Execute command 'al'")
		exec = executeAl
	case arguments["ad"].(bool):
		utils.Logger.Info("Execute command 'ad'")
		exec = executeAd
	case arguments["ar"].(bool):
		utils.Logger.Info("Execute command 'ar'")
		exec = executeAr
	default:
		utils.Logger.Panic("Unknown command. Please be more precise")
		return
	}
	exec(arguments, env)
}

func executeTee(arguments map[string]interface{}, env *environments.Environment) {
	cmds := arguments["<command>"].([]string)
	cmd := strings.Join(cmds, " ")
	tty := arguments["--tty"].(bool)
	interactive := arguments["--run-in-real-shell"].(bool)

	utils.Logger.WithFields(logrus.Fields{
		"command":     cmd,
		"pseudo-tty":  tty,
		"interactive": interactive,
	}).Info("Arguments of 'tee'")

	commands.Tee(cmd, interactive, tty, env)
}

func executeShow(arguments map[string]interface{}, env *environments.Environment) {
	slice, err := slices.ExtractSlice(
		arguments["<lastNcommands>"],
		arguments["<startFromNCommand>"],
		arguments["<finishByMCommand>"])
	if err != nil {
		utils.Logger.Panic(err)
	}

	var filter *utils.Regexp
	if arguments["--grep"] != nil {
		query := arguments["--grep"].(string)
		if arguments["--fuzzy"].(bool) {
			regex := new(bytes.Buffer)
			for _, character := range query {
				regex.WriteString(".*?")
				regex.WriteString(regexp.QuoteMeta(string(character)))
			}
			regex.WriteString(".*?")
			query = regex.String()
		}
		filter = utils.CreateRegexp(query)
	}

	utils.Logger.WithFields(logrus.Fields{
		"slice":  slice,
		"filter": filter,
	}).Info("Arguments of 'show'")

	commands.Show(slice, filter, env)
}

func executeListTrace(arguments map[string]interface{}, env *environments.Environment) {
	cmd := arguments["<numberOfCommandYouWantToCheck>"].(string)

	utils.Logger.WithFields(logrus.Fields{
		"cmd": cmd,
	}).Info("Arguments of 'listTrace'")

	commands.ListTrace(cmd, env)
}

func executeBookmark(arguments map[string]interface{}, env *environments.Environment) {
	number, err := strconv.Atoi(arguments["<commandNumber>"].(string))
	if err != nil {
		utils.Logger.Panicf("Cannot understand command number: %d", number)
	}

	bookmarkAs := arguments["<bookmarkAs>"].(string)
	if !validateBookmarkName.Match(bookmarkAs) {
		utils.Logger.Panic("Incorrect bookmark name!")
	}

	utils.Logger.WithFields(logrus.Fields{
		"commandNumber": number,
		"bookmarkAs":    bookmarkAs,
	}).Info("Arguments of 'bookmark'")

	commands.Bookmark(number, bookmarkAs, env)
}

func executeExec(arguments map[string]interface{}, env *environments.Environment) {
	commandNumberOrBookMarkName := arguments["<commandNumberOrBookMarkName>"].(string)
	tty := arguments["--tty"].(bool)
	interactive := arguments["--run-in-real-shell"].(bool)

	utils.Logger.WithFields(logrus.Fields{
		"commandNumberOrBookMarkName": commandNumberOrBookMarkName,
		"tty":         tty,
		"interactive": interactive,
	}).Info("Arguments of 'bookmark'")

	commandNumber, err := strconv.Atoi(commandNumberOrBookMarkName)
	switch {
	case err == nil:
		utils.Logger.Info("Execute command number ", commandNumber)
		commands.ExecuteCommandNumber(commandNumber, interactive, tty, env)
	case validateBookmarkName.Match(commandNumberOrBookMarkName):
		utils.Logger.Info("Execute bookmark ", commandNumberOrBookMarkName)
		commands.ExecuteBookmark(commandNumberOrBookMarkName, interactive, tty, env)
	default:
		utils.Logger.Panic("Incorrect bookmark name! It should be started with alphabet letter, and alphabet or digits after!")
	}
}

func executeGC(arguments map[string]interface{}, env *environments.Environment) {
	gcDir := commands.GcTracesDir
	if arguments["gb"].(bool) {
		gcDir = commands.GcBookmarksDir
	}

	var gcType commands.GcType
	stringParam := "1"
	switch {
	case arguments["--keepLatest"].(bool):
		gcType = commands.GcKeepLatest
		stringParam = arguments["<keepLatest>"].(string)
	case arguments["--olderThan"].(bool):
		gcType = commands.GcOlderThan
		stringParam = arguments["<keepLatest>"].(string)
	case arguments["--all"].(bool):
		gcType = commands.GcAll
	default:
		utils.Logger.Panic("Unknown subcommand command")
	}

	param, err := strconv.Atoi(stringParam)
	if err != nil {
		utils.Logger.Panic(err)
	} else if param <= 0 {
		utils.Logger.Panic("Parameter of garbage collection has to be > 0")
	}

	utils.Logger.WithFields(logrus.Fields{
		"gcType": gcType,
		"param":  param,
	}).Info("Arguments")

	commands.GC(gcType, gcDir, param, env)
}

func executeListBookmarks(_ map[string]interface{}, env *environments.Environment) {
	commands.ListBookmarks(env)
}

func executeRemoveBookmarks(arguments map[string]interface{}, env *environments.Environment) {
	bookmarks, ok := arguments["<bookmarkToRemove>"].([]string)
	if !ok || bookmarks == nil || len(bookmarks) == 0 {
		utils.Logger.Info("Nothing to do here")
		return
	}

	for _, bookmark := range bookmarks {
		if !validateBookmarkName.Match(bookmark) {
			utils.Logger.WithFields(logrus.Fields{
				"bookmark": bookmark,
			}).Panicf("Bookmark name %s is invalid", bookmark)
		}
	}

	commands.RemoveBookmarks(bookmarks, env)
}

func executeAd(arguments map[string]interface{}, env *environments.Environment) {
	cmds := arguments["<command>"].([]string)
	tty := arguments["--tty"].(bool)
	interactive := arguments["--run-in-real-shell"].(bool)

	utils.Logger.WithFields(logrus.Fields{
		"commands":    cmds,
		"tty":         tty,
		"interactive": interactive,
	}).Info("Arguments")

	commands.AutoTeeAdd(cmds, tty, interactive, env)
}

func executeAl(_ map[string]interface{}, env *environments.Environment) {
	commands.AutoTeeList(env)
}

func executeAr(arguments map[string]interface{}, env *environments.Environment) {
	cmds := arguments["<command>"].([]string)

	utils.Logger.WithFields(logrus.Fields{
		"commands": cmds,
	}).Info("Arguments")

	commands.AutoTeeRemove(cmds, env)
}
<commit_msg>Bump version up<commit_after>package main

import (
	"bytes"
	"os"
	"regexp"
	"strconv"
	"strings"

	logrus "github.com/Sirupsen/logrus"
	docopt "github.com/docopt/docopt-go"

	"github.com/9seconds/ah/app/commands"
	"github.com/9seconds/ah/app/environments"
	"github.com/9seconds/ah/app/slices"
	"github.com/9seconds/ah/app/utils"
)

const docoptOptions = `ah - A better history.

Ah is a better way to traverse the history of your shell prompts. You can
store an outputs of your commands, you can search with regular expressions
out of box, bookmark commands etc.

You may want to check detailed readme at https://github.com/9seconds/ah

Just a short reminder on possible subcommands:
    - s  - shows extended output from your HISTFILE
    - b  - bookmarks any command you want to have a faster access.
    - e  - executes a command by its bookmark name or history number.
    - t  - traces an output of the command and stores it safely.
    - l  - lists you an output of the command.
    - lb - lists available bookmarks.
    - rb - removes bookmarks.
    - gt - garbage collecting of the traces. Cleans old outputs.
    - gb - garbage collecting of the bookmarks. Swipes out old ones.
	- ad - add command to the list of auto ah'ed
	- ar - remove commands from the list of auto ah'ed
	- al - list of commands which should be auto ah'ed

Usage:
    ah [options] s [-z] [-g PATTERN] [<lastNcommands> | <startFromNCommand> <finishByMCommand>]
    ah [options] b <commandNumber> <bookmarkAs>
    ah [options] e [-x] [-y] <commandNumberOrBookMarkName>
    ah [options] t [-x] [-y] [--] <command>...
    ah [options] l <numberOfCommandYouWantToCheck>
    ah [options] lb
    ah [options] rb <bookmarkToRemove>...
    ah [options] (gt | gb) (--keepLatest <keepLatest> | --olderThan <olderThan> | --all)
    ah [options] al
    ah [options] ad [-x] [-y] <command>...
    ah [options] ar <command>...
    ah (-h | --help)
    ah --version

Options:
    -s SHELL, --shell=SHELL
       Shell flavour you are using.
       By default, ah will do some shallow investigations.
    -f HISTFILE, --histfile=HISTFILE
       The path to a history file.
       By default ah will try to use default history file of your shell.
    -t HISTTIMEFORMAT, --histtimeformat=HISTTIMEFORMAT
       A time format for history output. Will use $HISTTIMEFORMAT by default.
    -d APPDIR, --appdir=APPDIR
       A place where ah has to store its data.
    -m TMPDIR, --tmpdir=TMPDIR
       A temporary place where ah stores an output. Set it only if you need it.
    -g PATTERN, --grep PATTERN
       A pattern to filter command lines. It is regular expression if no -f option is set.
    -y, --tty
       Allocates pseudo-tty is necessary.
    -x, --run-in-real-shell
       Runs a command in real interactive shell.
    -z, --fuzzy
       Interpret -g pattern as fuzzy match string.
    -v, --debug
       Shows a debug log of command execution.`

const version = "ah 0.13"

var validateBookmarkName = utils.CreateRegexp(`^[A-Za-z_]\w*$`)

type executor func(map[string]interface{}, *environments.Environment)

func main() {
	defer func() {
		if exc := recover(); exc != nil {
			utils.Logger.Fatal(exc)
		}
	}()

	arguments, err := docopt.Parse(docoptOptions, nil, true, version, false)
	if err != nil {
		panic(err)
	}

	if arguments["--debug"].(bool) {
		utils.EnableLogging()
	} else {
		utils.DisableLogging()
	}

	env := new(environments.Environment)
	argShell := arguments["--shell"]
	if argShell == nil {
		env.DiscoverShell()
	} else {
		env.SetShell(argShell.(string))
	}

	argHistFile := arguments["--histfile"]
	if argHistFile == nil {
		env.DiscoverHistFile()
	} else {
		env.SetHistFile(argHistFile.(string))
	}

	argHistTimeFormat := arguments["--histtimeformat"]
	if argHistTimeFormat == nil {
		env.DiscoverHistTimeFormat()
	} else {
		env.SetHistTimeFormat(argHistTimeFormat.(string))
	}

	argAppDir := arguments["--appdir"]
	if argAppDir == nil {
		env.DiscoverAppDir()
	} else {
		env.SetAppDir(argAppDir.(string))
	}

	argTmpDir := arguments["--tmpdir"]
	if argTmpDir == nil {
		env.DiscoverTmpDir()
	} else {
		env.SetTmpDir(argTmpDir.(string))
	}

	utils.Logger.WithFields(logrus.Fields{
		"arguments":   arguments,
		"environment": env,
	}).Debug("Ready to start")

	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.GetTracesDir(), 0777),
	}).Info("Create traces dir")
	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.GetBookmarksDir(), 0777),
	}).Info("Create bookmarks dir")
	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.GetTmpDir(), 0777),
	}).Info("Create create temporary dir")

	var exec executor
	switch {
	case arguments["t"].(bool):
		utils.Logger.Info("Execute command 'tee'")
		exec = executeTee
	case arguments["s"].(bool):
		utils.Logger.Info("Execute command 'show'")
		exec = executeShow
	case arguments["l"].(bool):
		utils.Logger.Info("Execute command 'listTrace'")
		exec = executeListTrace
	case arguments["b"].(bool):
		utils.Logger.Info("Execute command 'listTrace'")
		exec = executeListTrace
	case arguments["e"].(bool):
		utils.Logger.Info("Execute command 'execute'")
		exec = executeExec
	case arguments["lb"].(bool):
		utils.Logger.Info("Execute command 'listBookmarks'")
		exec = executeListBookmarks
	case arguments["rb"].(bool):
		utils.Logger.Info("Execute command 'removeBookmarks'")
		exec = executeRemoveBookmarks
	case arguments["gt"].(bool) || arguments["gb"].(bool):
		utils.Logger.Info("Execute command 'gc'")
		exec = executeGC
	case arguments["al"].(bool):
		utils.Logger.Info("Execute command 'al'")
		exec = executeAl
	case arguments["ad"].(bool):
		utils.Logger.Info("Execute command 'ad'")
		exec = executeAd
	case arguments["ar"].(bool):
		utils.Logger.Info("Execute command 'ar'")
		exec = executeAr
	default:
		utils.Logger.Panic("Unknown command. Please be more precise")
		return
	}
	exec(arguments, env)
}

func executeTee(arguments map[string]interface{}, env *environments.Environment) {
	cmds := arguments["<command>"].([]string)
	cmd := strings.Join(cmds, " ")
	tty := arguments["--tty"].(bool)
	interactive := arguments["--run-in-real-shell"].(bool)

	utils.Logger.WithFields(logrus.Fields{
		"command":     cmd,
		"pseudo-tty":  tty,
		"interactive": interactive,
	}).Info("Arguments of 'tee'")

	commands.Tee(cmd, interactive, tty, env)
}

func executeShow(arguments map[string]interface{}, env *environments.Environment) {
	slice, err := slices.ExtractSlice(
		arguments["<lastNcommands>"],
		arguments["<startFromNCommand>"],
		arguments["<finishByMCommand>"])
	if err != nil {
		utils.Logger.Panic(err)
	}

	var filter *utils.Regexp
	if arguments["--grep"] != nil {
		query := arguments["--grep"].(string)
		if arguments["--fuzzy"].(bool) {
			regex := new(bytes.Buffer)
			for _, character := range query {
				regex.WriteString(".*?")
				regex.WriteString(regexp.QuoteMeta(string(character)))
			}
			regex.WriteString(".*?")
			query = regex.String()
		}
		filter = utils.CreateRegexp(query)
	}

	utils.Logger.WithFields(logrus.Fields{
		"slice":  slice,
		"filter": filter,
	}).Info("Arguments of 'show'")

	commands.Show(slice, filter, env)
}

func executeListTrace(arguments map[string]interface{}, env *environments.Environment) {
	cmd := arguments["<numberOfCommandYouWantToCheck>"].(string)

	utils.Logger.WithFields(logrus.Fields{
		"cmd": cmd,
	}).Info("Arguments of 'listTrace'")

	commands.ListTrace(cmd, env)
}

func executeBookmark(arguments map[string]interface{}, env *environments.Environment) {
	number, err := strconv.Atoi(arguments["<commandNumber>"].(string))
	if err != nil {
		utils.Logger.Panicf("Cannot understand command number: %d", number)
	}

	bookmarkAs := arguments["<bookmarkAs>"].(string)
	if !validateBookmarkName.Match(bookmarkAs) {
		utils.Logger.Panic("Incorrect bookmark name!")
	}

	utils.Logger.WithFields(logrus.Fields{
		"commandNumber": number,
		"bookmarkAs":    bookmarkAs,
	}).Info("Arguments of 'bookmark'")

	commands.Bookmark(number, bookmarkAs, env)
}

func executeExec(arguments map[string]interface{}, env *environments.Environment) {
	commandNumberOrBookMarkName := arguments["<commandNumberOrBookMarkName>"].(string)
	tty := arguments["--tty"].(bool)
	interactive := arguments["--run-in-real-shell"].(bool)

	utils.Logger.WithFields(logrus.Fields{
		"commandNumberOrBookMarkName": commandNumberOrBookMarkName,
		"tty":         tty,
		"interactive": interactive,
	}).Info("Arguments of 'bookmark'")

	commandNumber, err := strconv.Atoi(commandNumberOrBookMarkName)
	switch {
	case err == nil:
		utils.Logger.Info("Execute command number ", commandNumber)
		commands.ExecuteCommandNumber(commandNumber, interactive, tty, env)
	case validateBookmarkName.Match(commandNumberOrBookMarkName):
		utils.Logger.Info("Execute bookmark ", commandNumberOrBookMarkName)
		commands.ExecuteBookmark(commandNumberOrBookMarkName, interactive, tty, env)
	default:
		utils.Logger.Panic("Incorrect bookmark name! It should be started with alphabet letter, and alphabet or digits after!")
	}
}

func executeGC(arguments map[string]interface{}, env *environments.Environment) {
	gcDir := commands.GcTracesDir
	if arguments["gb"].(bool) {
		gcDir = commands.GcBookmarksDir
	}

	var gcType commands.GcType
	stringParam := "1"
	switch {
	case arguments["--keepLatest"].(bool):
		gcType = commands.GcKeepLatest
		stringParam = arguments["<keepLatest>"].(string)
	case arguments["--olderThan"].(bool):
		gcType = commands.GcOlderThan
		stringParam = arguments["<keepLatest>"].(string)
	case arguments["--all"].(bool):
		gcType = commands.GcAll
	default:
		utils.Logger.Panic("Unknown subcommand command")
	}

	param, err := strconv.Atoi(stringParam)
	if err != nil {
		utils.Logger.Panic(err)
	} else if param <= 0 {
		utils.Logger.Panic("Parameter of garbage collection has to be > 0")
	}

	utils.Logger.WithFields(logrus.Fields{
		"gcType": gcType,
		"param":  param,
	}).Info("Arguments")

	commands.GC(gcType, gcDir, param, env)
}

func executeListBookmarks(_ map[string]interface{}, env *environments.Environment) {
	commands.ListBookmarks(env)
}

func executeRemoveBookmarks(arguments map[string]interface{}, env *environments.Environment) {
	bookmarks, ok := arguments["<bookmarkToRemove>"].([]string)
	if !ok || bookmarks == nil || len(bookmarks) == 0 {
		utils.Logger.Info("Nothing to do here")
		return
	}

	for _, bookmark := range bookmarks {
		if !validateBookmarkName.Match(bookmark) {
			utils.Logger.WithFields(logrus.Fields{
				"bookmark": bookmark,
			}).Panicf("Bookmark name %s is invalid", bookmark)
		}
	}

	commands.RemoveBookmarks(bookmarks, env)
}

func executeAd(arguments map[string]interface{}, env *environments.Environment) {
	cmds := arguments["<command>"].([]string)
	tty := arguments["--tty"].(bool)
	interactive := arguments["--run-in-real-shell"].(bool)

	utils.Logger.WithFields(logrus.Fields{
		"commands":    cmds,
		"tty":         tty,
		"interactive": interactive,
	}).Info("Arguments")

	commands.AutoTeeAdd(cmds, tty, interactive, env)
}

func executeAl(_ map[string]interface{}, env *environments.Environment) {
	commands.AutoTeeList(env)
}

func executeAr(arguments map[string]interface{}, env *environments.Environment) {
	cmds := arguments["<command>"].([]string)

	utils.Logger.WithFields(logrus.Fields{
		"commands": cmds,
	}).Info("Arguments")

	commands.AutoTeeRemove(cmds, env)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
	"time"
)

var replace = map[string]func(){
	"nnf":       nnf,
	"nnl":       nnl,
	"openFile":  openFile,
	"readFile":  readFile,
	"getURL":    getURL,
	"reqStdin":  reqStdin,
	"goMain":    goMain,
	"tempFile":  tempFile,
	"serveHTTP": serveHTTP,
	"pymain":    pyMain,
	"html5":     html5,
	"now":       now,
	"ubb":       bash,
	"ubp":       python,
	"gomain":    goMain,
	"flagsh":    flagsh,
}

var update = map[string]func(string){
	"lpf(":  lpf,
	"lpl(":  lpl,
	"fpf(":  fpf,
	"fpl(":  fpl,
	"hfunc": hfunc,
	"ow:":   pyOpenWrite,
	"ul":    ul,
}

func main() {
	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		line := s.Text()
		trim := strings.TrimSpace(s.Text())

		if f, found := replace[trim]; found {
			f()
			continue
		}

	DONE:
		for pre := range update {
			if strings.HasPrefix(trim, pre) {
				update[pre](trim)
				break DONE
			}

			continue
		}
		fmt.Println(line)
	}

}

func nnf() {
	fmt.Println(`if err != nil{
	log.Fatalf("Failed to do something: %s\n", err)
	}`)
}

func nnl() {
	fmt.Println(`if err != nil{
	log.Printf("Failed to do something: %s\n", err)
	}`)
}

func lpf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fpf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lpl(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fpl(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}

func serveHTTP() {
	fmt.Println(`package main

import (
    "fmt"
	"net/http"
)

func main() {
    http.HandleFunc("/", index)
	http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w, "hello")
}
`)
}

func pyMain() {
	fmt.Println(`#!/usr/bin/env python
"""
You should probably write something here.
"""

from __future__ import unicode_literals

def main():
    """
    Do the thing.
    """
    print "python"

if __name__ == '__main__':
    main()
`)
}

func html5() {
	fmt.Println(`<!DOCTYPE html>

		<meta charset="UTF-8">
		<title>title</title>
		<link rel="stylesheet" href="./css/style.css" type="text/css">
		<meta name="viewport" content="width-device-width, initial-scale=1">

content

`)
}

func hfunc(line string) {
	parts := strings.Split(line, " ")
	name := "index"
	if len(parts) > 1 {
		name = parts[1]
	}
	fmt.Printf(`func %s(w http.ResponseWriter, r *http.Request){
	}`, name)
}

func pyOpenWrite(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	lines := []string{
		`with open("out.txt", "wb") as raw:`,
		`    raw.write("{0}\n".format(msg))`,
	}

	for _, line = range lines {
		fmt.Printf("%s%s\n", pad, line)
	}

}

func ul(line string) {
	trim := strings.TrimSpace(line)
	margin := len(line) - len(strings.TrimLeft(trim, " \t"))
	padding := strings.Repeat(" ", margin)
	fmt.Printf(padding)
	fmt.Println("
")
	for i := 0; i < 3; i++ {
		fmt.Printf(padding)
		fmt.Println("\t
")
		fmt.Printf(padding)
		fmt.Println("\t\tthing")
		fmt.Printf(padding)
		fmt.Println("\t
")
	}
	fmt.Printf(padding)
	fmt.Println("
")

}

func openFile() {
	fmt.Println(`f, err := os.Open(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}
	defer f.Close()`)
}

func readFile() {
	fmt.Println(`b, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}`)
}

func getURL() {
	fmt.Println(`resp, err := http.Get(link)
	if err != nil {
		log.Printf("Unable to fetch %q: %s\n", link, err)
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("Unable to read response from  %q: %s\n", link, err)
		return
	}
	`)
}

func reqStdin() {
	fmt.Println(`stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}`)
}

func tempFile() {
	fmt.Println(`t, err := ioutil.TempFile("", "temp")
if err != nil{
	log.Fatalf("Unable to create temp file: %s\n", err)
}
fmt.Printf("Created temp file %q\n", t.Name())
defer t.Close()
`)
}

func now() {
	fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}

func bash() {
	fmt.Println("#!/usr/bin/env bash")
}

func python() {
	fmt.Println("#!/usr/bin/env python")
}

func flagsh() {

	fmt.Println(`#!/usr/bin/env bash

flag=$(mktemp)
touch $flag

while true; do
sleep 5
    find . -mmin -1 -name '*.go' 2>>/dev/null | while read file; do
        if [[ "$file" -nt $flag ]]; then
            if [[ "$file" == "$flag" ]]; then
                continue
            fi
            echo "$file was updated"
            touch $flag
        fi
    done
done
`)
}
<commit_msg>Add dummyType<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
	"time"
)

var replace = map[string]func(){
	"nnf":       nnf,
	"nnl":       nnl,
	"openFile":  openFile,
	"readFile":  readFile,
	"getURL":    getURL,
	"reqStdin":  reqStdin,
	"goMain":    goMain,
	"tempFile":  tempFile,
	"serveHTTP": serveHTTP,
	"pymain":    pyMain,
	"html5":     html5,
	"now":       now,
	"ubb":       bash,
	"ubp":       python,
	"gomain":    goMain,
	"flagsh":    flagsh,
	"dummyType": dummyType,
}

var update = map[string]func(string){
	"lpf(":  lpf,
	"lpl(":  lpl,
	"fpf(":  fpf,
	"fpl(":  fpl,
	"hfunc": hfunc,
	"ow:":   pyOpenWrite,
	"ul":    ul,
}

func main() {
	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		line := s.Text()
		trim := strings.TrimSpace(s.Text())

		if f, found := replace[trim]; found {
			f()
			continue
		}

	DONE:
		for pre := range update {
			if strings.HasPrefix(trim, pre) {
				update[pre](trim)
				break DONE
			}

			continue
		}
		fmt.Println(line)
	}

}

func nnf() {
	fmt.Println(`if err != nil{
	log.Fatalf("Failed to do something: %s\n", err)
	}`)
}

func nnl() {
	fmt.Println(`if err != nil{
	log.Printf("Failed to do something: %s\n", err)
	}`)
}

func lpf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fpf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lpl(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fpl(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}

func serveHTTP() {
	fmt.Println(`package main

import (
    "fmt"
	"net/http"
)

func main() {
    http.HandleFunc("/", index)
	http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, r *http.Request){
	fmt.Fprintf(w, "hello")
}
`)
}

func pyMain() {
	fmt.Println(`#!/usr/bin/env python
"""
You should probably write something here.
"""

from __future__ import unicode_literals

def main():
    """
    Do the thing.
    """
    print "python"

if __name__ == '__main__':
    main()
`)
}

func html5() {
	fmt.Println(`<!DOCTYPE html>

		<meta charset="UTF-8">
		<title>title</title>
		<link rel="stylesheet" href="./css/style.css" type="text/css">
		<meta name="viewport" content="width-device-width, initial-scale=1">

content

`)
}

func hfunc(line string) {
	parts := strings.Split(line, " ")
	name := "index"
	if len(parts) > 1 {
		name = parts[1]
	}
	fmt.Printf(`func %s(w http.ResponseWriter, r *http.Request){
	}`, name)
}

func pyOpenWrite(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	lines := []string{
		`with open("out.txt", "wb") as raw:`,
		`    raw.write("{0}\n".format(msg))`,
	}

	for _, line = range lines {
		fmt.Printf("%s%s\n", pad, line)
	}

}

func ul(line string) {
	trim := strings.TrimSpace(line)
	margin := len(line) - len(strings.TrimLeft(trim, " \t"))
	padding := strings.Repeat(" ", margin)
	fmt.Printf(padding)
	fmt.Println("
")
	for i := 0; i < 3; i++ {
		fmt.Printf(padding)
		fmt.Println("\t
")
		fmt.Printf(padding)
		fmt.Println("\t\tthing")
		fmt.Printf(padding)
		fmt.Println("\t
")
	}
	fmt.Printf(padding)
	fmt.Println("
")

}

func openFile() {
	fmt.Println(`f, err := os.Open(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}
	defer f.Close()`)
}

func readFile() {
	fmt.Println(`b, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Printf("Unable to open %q: %s\n", filename, err)
	}`)
}

func getURL() {
	fmt.Println(`resp, err := http.Get(link)
	if err != nil {
		log.Printf("Unable to fetch %q: %s\n", link, err)
		return
	}
	defer resp.Body.Close()
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("Unable to read response from  %q: %s\n", link, err)
		return
	}
	`)
}

func reqStdin() {
	fmt.Println(`stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}`)
}

func tempFile() {
	fmt.Println(`t, err := ioutil.TempFile("", "temp")
if err != nil{
	log.Fatalf("Unable to create temp file: %s\n", err)
}
fmt.Printf("Created temp file %q\n", t.Name())
defer t.Close()
`)
}

func now() {
	fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}

func bash() {
	fmt.Println("#!/usr/bin/env bash")
}

func python() {
	fmt.Println("#!/usr/bin/env python")
}

func flagsh() {

	fmt.Println(`#!/usr/bin/env bash

flag=$(mktemp)
touch $flag

while true; do
sleep 5
    find . -mmin -1 -name '*.go' 2>>/dev/null | while read file; do
        if [[ "$file" -nt $flag ]]; then
            if [[ "$file" == "$flag" ]]; then
                continue
            fi
            echo "$file was updated"
            touch $flag
        fi
    done
done
`)
}

func dummyType() {
	fmt.Println(`type dummy struct {
    thing string
    size int
    color string
}
`)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"os/signal"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/bwmarrin/discordgo"
	"github.com/legolord208/stdutil"
)

type image struct {
	Keyword string
	URL     string
}

const dir = "Dank"

var sounds = make(map[string][][]byte, 0)
var images []*image

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

type settingsType struct {
	playing   bool
	commander string
}

var settings = make(map[string]*settingsType)
var settingsMutex sync.RWMutex

func main() {
	//stdutil.ShouldTrace = true;
	args := os.Args[1:]

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

	fmt.Println("Loading...")

	err := os.Mkdir(dir, 0755)
	if err != nil && !os.IsExist(err) {
		stdutil.PrintErr("", err)
		return
	}
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		stdutil.PrintErr("", 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
	}

	file, err := os.Open("Dank/images.txt")
	if err != nil {
		stdutil.PrintErr("", err)
	} else {
		reader := bufio.NewScanner(file)
		for reader.Scan() {
			parts := strings.SplitN(reader.Text(), ", ", 2)
			if len(parts) != 2 {
				stdutil.PrintErr("Corrupt file or something", nil)
				continue
			}

			images = append(images, &image{
				Keyword: parts[0],
				URL:     parts[1],
			})
		}

		file.Close()

		if err := reader.Err(); err != nil {
			stdutil.PrintErr("Error reading file", err)
			return
		}
	}

	fmt.Println("Starting...")
	session, err := discordgo.New("Bot " + token)
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}
	session.AddHandler(messageCreate)
	err = session.Open()

	if err != nil {
		stdutil.PrintErr("", err)
		return
	}

	go func() {
		c := time.Tick(time.Minute * 5)

		for _ = range c {
			err := session.UpdateStatus(0, statuses[rand.Intn(len(statuses))])
			if err != nil {
				stdutil.PrintErr("", err)
				return
			}
		}
	}()
	fmt.Println("Started!")

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

	<-interrupt
	fmt.Println("\nExiting")
	session.Close()
}

func load(file string, buffer *[][]byte) error {
	f, err := os.Open(filepath.Join(dir, file))
	defer f.Close()
	if err != nil {
		stdutil.PrintErr("", 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 {
			stdutil.PrintErr("", err)
			return err
		}

		buf := make([]byte, length)
		err = binary.Read(f, binary.LittleEndian, &buf)
		if err != nil {
			stdutil.PrintErr("", err)
			return err
		}

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

func play(buffer [][]byte, session *discordgo.Session, guild, channel string, s *settingsType) {
	s.playing = true
	defer func() { s.playing = false }()
	vc, err := session.ChannelVoiceJoin(guild, channel, false, true)
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}

	err = vc.Speaking(true)
	if err != nil {
		stdutil.PrintErr("", err)

		err = vc.Disconnect()
		if err != nil {
			stdutil.PrintErr("", err)
		}
		return
	}

	for _, buf := range buffer {
		if !s.playing {
			break
		}
		vc.OpusSend <- buf
	}

	err = vc.Speaking(false)
	if err != nil {
		stdutil.PrintErr("", err)
	}
	err = vc.Disconnect()
	if err != nil {
		stdutil.PrintErr("", err)
	}
}

func messageCreate(session *discordgo.Session, event *discordgo.MessageCreate) {
	if event.Author == nil {
		return
	}
	msg := strings.ToLower(strings.TrimSpace(event.Content))
	author := event.Author

	if msg == "" {
		return
	}

	channel, err := session.State.Channel(event.ChannelID)
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}

	if channel.IsPrivate {
		return
	}

	guild, err := session.State.Guild(channel.GuildID)
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}

	settingsMutex.RLock()
	s := settings[guild.ID]
	settingsMutex.RUnlock()

	if s == nil {
		s = &settingsType{}

		settingsMutex.Lock()
		settings[guild.ID] = s
		settingsMutex.Unlock()
	}

	if msg == "meemz who ur master" {
		msg := ""
		if s.commander == "" {
			msg = "nobody is idiot"
		} else if s.commander == author.ID {
			msg = "u is... idiot"
		} else if s.commander == "-" {
			msg = "im no suppos 2 talk 2 u"
		} else {
			msg = "dat wuld b <@" + s.commander + ">"
		}
		_, err = session.ChannelMessageSend(event.ChannelID, msg)
		if err != nil {
			stdutil.PrintErr("", err)
		}
	}

	if guild.OwnerID == author.ID && strings.HasPrefix(msg, "meemz idfc ") {
		msg = strings.TrimPrefix(msg, "meemz idfc ")
	} else {
		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 {
					go react(session, event.Message)
					play(buffer, session, guild.ID, state.ChannelID, s)
					return
				}
			}
		}
		return
	}

	for _, image := range images {
		contains, err := regexp.MatchString(`(^|[^:])\b`+regexp.QuoteMeta(image.Keyword)+`\b($|[^:])`, msg)
		if err != nil {
			stdutil.PrintErr("", err)
			return
		}
		if contains {
			go react(session, event.Message)
			_, err = session.ChannelMessageSendEmbed(event.ChannelID,
				&discordgo.MessageEmbed{
					Image: &discordgo.MessageEmbedImage{
						URL: image.URL,
					},
				})
			if err != nil {
				stdutil.PrintErr("", err)
			}
			return
		}
	}

	switch msg {
	case "thx":
		s.playing = false
	case "listen only to me plz":
		s.commander = author.ID
		fmt.Println("In guild '" + guild.Name + "', the user '" + author.Username + "' took control.")
	case "meemz stfu":
		s.commander = "-"
		fmt.Println("In guild '" + guild.Name + "', the user '" + author.Username + "' disabled meemz.")
	case "every1 owns u stopad robot":
		s.commander = ""
		fmt.Println("In guild '" + guild.Name + "', the user '" + author.Username + "' returned the control to everyone.")
	case "plz list da stuff":
		strSounds := ""
		for name := range sounds {
			if strSounds != "" {
				strSounds += ", "
			}
			strSounds += "`" + name + "`"
		}

		strImages := ""
		for _, image := range images {
			if strImages != "" {
				strImages += ", "
			}
			strImages += "`" + image.Keyword + "`"
		}

		_, err := session.ChannelMessageSendEmbed(event.ChannelID, &discordgo.MessageEmbed{
			Fields: []*discordgo.MessageEmbedField{
				&discordgo.MessageEmbedField{
					Name:  "DA SOUNDZ",
					Value: strSounds,
				},
				&discordgo.MessageEmbedField{
					Name:   "DA IMAGEZ",
					Value:  strImages,
					Inline: true,
				},
			},
		})
		if err != nil {
			stdutil.PrintErr("", err)
			return
		}
	}
}

func react(session *discordgo.Session, event *discordgo.Message) {
	err := session.MessageReactionAdd(event.ChannelID, event.ID, "👌")
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}
	err = session.MessageReactionAdd(event.ChannelID, event.ID, "😂")
	if err != nil {
		stdutil.PrintErr("", err)
	}
}
<commit_msg>ADDAD MIZZIN SOHRT<commit_after>package main

import (
	"bufio"
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"os/signal"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/bwmarrin/discordgo"
	"github.com/legolord208/stdutil"
)

type image struct {
	Keyword string
	URL     string
}

const dir = "Dank"

var sounds = make(map[string][][]byte, 0)
var images []*image

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

type settingsType struct {
	playing   bool
	commander string
}

var settings = make(map[string]*settingsType)
var settingsMutex sync.RWMutex

func main() {
	//stdutil.ShouldTrace = true;
	args := os.Args[1:]

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

	fmt.Println("Loading...")

	err := os.Mkdir(dir, 0755)
	if err != nil && !os.IsExist(err) {
		stdutil.PrintErr("", err)
		return
	}
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		stdutil.PrintErr("", 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
	}

	file, err := os.Open("Dank/images.txt")
	if err != nil {
		stdutil.PrintErr("", err)
	} else {
		reader := bufio.NewScanner(file)
		for reader.Scan() {
			parts := strings.SplitN(reader.Text(), ", ", 2)
			if len(parts) != 2 {
				stdutil.PrintErr("Corrupt file or something", nil)
				continue
			}

			images = append(images, &image{
				Keyword: parts[0],
				URL:     parts[1],
			})
		}

		file.Close()

		if err := reader.Err(); err != nil {
			stdutil.PrintErr("Error reading file", err)
			return
		}

		sort.Slice(images, func(i int, i2 int) bool {
			return len(images[i].Keyword) > len(images[i2].Keyword)
		})
	}

	fmt.Println("Starting...")
	session, err := discordgo.New("Bot " + token)
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}
	session.AddHandler(messageCreate)
	err = session.Open()

	if err != nil {
		stdutil.PrintErr("", err)
		return
	}

	go func() {
		c := time.Tick(time.Minute * 5)

		for _ = range c {
			err := session.UpdateStatus(0, statuses[rand.Intn(len(statuses))])
			if err != nil {
				stdutil.PrintErr("", err)
				return
			}
		}
	}()
	fmt.Println("Started!")

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

	<-interrupt
	fmt.Println("\nExiting")
	session.Close()
}

func load(file string, buffer *[][]byte) error {
	f, err := os.Open(filepath.Join(dir, file))
	defer f.Close()
	if err != nil {
		stdutil.PrintErr("", 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 {
			stdutil.PrintErr("", err)
			return err
		}

		buf := make([]byte, length)
		err = binary.Read(f, binary.LittleEndian, &buf)
		if err != nil {
			stdutil.PrintErr("", err)
			return err
		}

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

func play(buffer [][]byte, session *discordgo.Session, guild, channel string, s *settingsType) {
	s.playing = true
	defer func() { s.playing = false }()
	vc, err := session.ChannelVoiceJoin(guild, channel, false, true)
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}

	err = vc.Speaking(true)
	if err != nil {
		stdutil.PrintErr("", err)

		err = vc.Disconnect()
		if err != nil {
			stdutil.PrintErr("", err)
		}
		return
	}

	for _, buf := range buffer {
		if !s.playing {
			break
		}
		vc.OpusSend <- buf
	}

	err = vc.Speaking(false)
	if err != nil {
		stdutil.PrintErr("", err)
	}
	err = vc.Disconnect()
	if err != nil {
		stdutil.PrintErr("", err)
	}
}

func messageCreate(session *discordgo.Session, event *discordgo.MessageCreate) {
	if event.Author == nil {
		return
	}
	msg := strings.ToLower(strings.TrimSpace(event.Content))
	author := event.Author

	if msg == "" {
		return
	}

	channel, err := session.State.Channel(event.ChannelID)
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}

	if channel.IsPrivate {
		return
	}

	guild, err := session.State.Guild(channel.GuildID)
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}

	settingsMutex.RLock()
	s := settings[guild.ID]
	settingsMutex.RUnlock()

	if s == nil {
		s = &settingsType{}

		settingsMutex.Lock()
		settings[guild.ID] = s
		settingsMutex.Unlock()
	}

	if msg == "meemz who ur master" {
		msg := ""
		if s.commander == "" {
			msg = "nobody is idiot"
		} else if s.commander == author.ID {
			msg = "u is... idiot"
		} else if s.commander == "-" {
			msg = "im no suppos 2 talk 2 u"
		} else {
			msg = "dat wuld b <@" + s.commander + ">"
		}
		_, err = session.ChannelMessageSend(event.ChannelID, msg)
		if err != nil {
			stdutil.PrintErr("", err)
		}
	}

	if guild.OwnerID == author.ID && strings.HasPrefix(msg, "meemz idfc ") {
		msg = strings.TrimPrefix(msg, "meemz idfc ")
	} else {
		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 {
					go react(session, event.Message)
					play(buffer, session, guild.ID, state.ChannelID, s)
					return
				}
			}
		}
		return
	}

	for _, image := range images {
		contains, err := regexp.MatchString(`(^|[^:])\b`+regexp.QuoteMeta(image.Keyword)+`\b($|[^:])`, msg)
		if err != nil {
			stdutil.PrintErr("", err)
			return
		}
		if contains {
			go react(session, event.Message)
			_, err = session.ChannelMessageSendEmbed(event.ChannelID,
				&discordgo.MessageEmbed{
					Image: &discordgo.MessageEmbedImage{
						URL: image.URL,
					},
				})
			if err != nil {
				stdutil.PrintErr("", err)
			}
			return
		}
	}

	switch msg {
	case "thx":
		s.playing = false
	case "listen only to me plz":
		s.commander = author.ID
		fmt.Println("In guild '" + guild.Name + "', the user '" + author.Username + "' took control.")
	case "meemz stfu":
		s.commander = "-"
		fmt.Println("In guild '" + guild.Name + "', the user '" + author.Username + "' disabled meemz.")
	case "every1 owns u stopad robot":
		s.commander = ""
		fmt.Println("In guild '" + guild.Name + "', the user '" + author.Username + "' returned the control to everyone.")
	case "plz list da stuff":
		strSounds := ""
		for name := range sounds {
			if strSounds != "" {
				strSounds += ", "
			}
			strSounds += "`" + name + "`"
		}

		strImages := ""
		for _, image := range images {
			if strImages != "" {
				strImages += ", "
			}
			strImages += "`" + image.Keyword + "`"
		}

		_, err := session.ChannelMessageSendEmbed(event.ChannelID, &discordgo.MessageEmbed{
			Fields: []*discordgo.MessageEmbedField{
				&discordgo.MessageEmbedField{
					Name:  "DA SOUNDZ",
					Value: strSounds,
				},
				&discordgo.MessageEmbedField{
					Name:   "DA IMAGEZ",
					Value:  strImages,
					Inline: true,
				},
			},
		})
		if err != nil {
			stdutil.PrintErr("", err)
			return
		}
	}
}

func react(session *discordgo.Session, event *discordgo.Message) {
	err := session.MessageReactionAdd(event.ChannelID, event.ID, "👌")
	if err != nil {
		stdutil.PrintErr("", err)
		return
	}
	err = session.MessageReactionAdd(event.ChannelID, event.ID, "😂")
	if err != nil {
		stdutil.PrintErr("", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
)

func (m *Movie) GetImdbInfo() {
	res, err := http.Get(m.ApiUrl())
	if err != nil {
		panic(err.Error())
	}
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		panic(err.Error())
	}
	err = json.Unmarshal(body, &m)
	if err != nil {
		panic(err.Error())
	}
}

func (m *Movie) ApiUrl() string {
	url := "http://www.omdbapi.com/?i=%s&plot=short&r=json"
	return fmt.Sprintf(url, m.Id)
}

func (m *Movie) ParsleyFlags() {
	fmt.Printf("--title \"%s\" --artist \"%s\" --year \"%s\" --description \"%s\" --genre \"%s\"", m.Title, m.Director, m.Year, m.Plot, m.Genre)
}

type Movie struct {
	Id       string
	Title    string
	Director string
	Year     string
	Plot     string
	Genre    string
}

func FindMovie(id string) Movie {
	m := Movie{Id: id}
	m.GetImdbInfo()
	return m
}

func main() {
	var id string
	flag.StringVar(&id, "id", "", "IMDB ID of movie. (e.g. tt1564349)")
	flag.Parse()

	if id != "" {
		m := FindMovie(id)
		m.ParsleyFlags()
	}
}
<commit_msg>Add more flags<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
)

func (m *Movie) GetImdbInfo() {
	res, err := http.Get(m.ApiUrl())
	if err != nil {
		panic(err.Error())
	}
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		panic(err.Error())
	}
	err = json.Unmarshal(body, &m)
	if err != nil {
		panic(err.Error())
	}
}

func (m *Movie) ApiUrl() string {
	url := "http://www.omdbapi.com/?i=%s&plot=short&r=json"
	return fmt.Sprintf(url, m.Id)
}

func (m *Movie) ParsleyFlags() string {
	return fmt.Sprintf("--title \"%s\" --artist \"%s\" --year \"%s\" --description \"%s\" --genre \"%s\"", m.Title, m.Director, m.Year, m.Plot, m.Genre)
}

type Movie struct {
	Id       string
	Title    string
	Director string
	Year     string
	Plot     string
	Genre    string
}

func FindMovie(id string) Movie {
	m := Movie{Id: id}
	m.GetImdbInfo()
	return m
}

func main() {
	var id string
	var file_path string
	var format string
	flag.StringVar(&id, "id", "", "IMDB ID of movie (e.g. tt1564349)")
	flag.StringVar(&file_path, "file", "", "Path to video file")
	flag.StringVar(&format, "format", "m4v", "File format of video file (defaults to m4v)")
	flag.Parse()

	if id != "" && file_path != "" && format != "" {
		m := FindMovie(id)
		fmt.Printf("Running: AtomicParsley %s.%s %s", file_path, format, m.ParsleyFlags())
	} else {
		flag.Usage()
	}
}
<|endoftext|>


<commit_before>package gopwt

import (
	"flag"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path"
	"syscall"

	"github.com/ToQoz/gopwt/translator"
	"github.com/mattn/go-isatty"
)

var (
	verbose  = false
	testdata = flag.String("testdata", "testdata", "name of test data directories. e.g. -testdata testdata,migrations")
)

func Empower() {
	if os.Getenv("GOPWT_OFF") != "" {
		return
	}

	if err := doMain(); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())

		if exiterr, ok := err.(*exec.ExitError); ok {
			if s, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				os.Exit(s.ExitStatus())
			} else {
				panic(fmt.Errorf("Unimplemented for system where exec.ExitError.Sys() is not syscall.WaitStatus."))
			}
		}

		os.Exit(127)
	}
	os.Exit(0)
}
func doMain() error {
	if !flag.Parsed() {
		flag.Parse()
	}
	flag.VisitAll(func(f *flag.Flag) {
		if f.Name == "test.v" {
			if f.Value.String() != "false" {
				verbose = true
			}
		}
	})

	translator.Verbose(verbose)
	translator.Testdata(*testdata)
	if isatty.IsTerminal(os.Stdout.Fd()) {
		translator.TermWidth(getTermCols(os.Stdin.Fd()))
	}

	tmpGopath, importpath, err := translator.Translate(flag.Arg(0))
	defer os.RemoveAll(tmpGopath)
	if err != nil {
		return err
	}

	return runTest(tmpGopath, importpath, os.Stdout, os.Stderr)
}

func runTest(gopath string, importpath string, stdout, stderr io.Writer) error {
	err := os.Setenv("GOPATH", gopath+":"+os.Getenv("GOPATH"))
	if err != nil {
		return err
	}
	cmd := exec.Command("go", "test")

	if verbose {
		cmd.Args = append(cmd.Args, "-v")
	}
	cmd.Dir = path.Join(gopath, "src", importpath)
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	return cmd.Run()
}
<commit_msg>feat(output): color output now!<commit_after>package gopwt

import (
	"flag"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path"
	"syscall"

	"github.com/ToQoz/gopwt/translator"
	"github.com/mattn/go-isatty"
)

var (
	verbose  = false
	testdata = flag.String("testdata", "testdata", "name of test data directories. e.g. -testdata testdata,migrations")
)

func Empower() {
	if os.Getenv("GOPWT_OFF") != "" {
		return
	}

	if err := doMain(); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())

		if exiterr, ok := err.(*exec.ExitError); ok {
			if s, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				os.Exit(s.ExitStatus())
			} else {
				panic(fmt.Errorf("Unimplemented for system where exec.ExitError.Sys() is not syscall.WaitStatus."))
			}
		}

		os.Exit(127)
	}
	os.Exit(0)
}
func doMain() error {
	if !flag.Parsed() {
		flag.Parse()
	}
	flag.VisitAll(func(f *flag.Flag) {
		if f.Name == "test.v" {
			if f.Value.String() != "false" {
				verbose = true
			}
		}
	})

	translator.Verbose(verbose)
	translator.Testdata(*testdata)
	if isatty.IsTerminal(os.Stdout.Fd()) {
		translator.TermWidth(getTermCols(os.Stdout.Fd()))
	}

	tmpGopath, importpath, err := translator.Translate(flag.Arg(0))
	defer os.RemoveAll(tmpGopath)
	if err != nil {
		return err
	}

	return runTest(tmpGopath, importpath, os.Stdout, os.Stderr)
}

func runTest(gopath string, importpath string, stdout, stderr io.Writer) error {
	err := os.Setenv("GOPATH", gopath+":"+os.Getenv("GOPATH"))
	if err != nil {
		return err
	}
	cmd := exec.Command("go", "test")

	if verbose {
		cmd.Args = append(cmd.Args, "-v")
	}
	cmd.Dir = path.Join(gopath, "src", importpath)
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	return cmd.Run()
}
<|endoftext|>


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

import (
	"context"
	"flag"
	"log"
	"os"
	"os/signal"
	"time"

	"google.golang.org/grpc"
	healthpb "google.golang.org/grpc/health/grpc_health_v1"
)

var (
	flAddr        string
	flConnTimeout time.Duration
	flRPCTimeout  time.Duration
)

const (
	// StatusInvalidArguments indicates specified invalid arguments.
	StatusInvalidArguments = 1
	// StatusConnectionFailure indicates connection failed.
	StatusConnectionFailure = 2
	// StatusRPCFailure indicates rpc failed.
	StatusRPCFailure = 3
	// StatusUnhealthy indicates rpc succeeded but indicates unhealthy service.
	StatusUnhealthy = 4
)

func init() {
	log.SetFlags(0)

	// TODO(ahmetb) add flags for -insecure and authentication
	flag.DurationVar(&flConnTimeout, "connect-timeout", time.Second, "timeout for establishing connection")
	flag.DurationVar(&flRPCTimeout, "rpc-timeout", time.Second, "timeout for health check rpc")
	flag.StringVar(&flAddr, "addr", "", "(required) tcp host:port to connect")
	flag.Parse()

	if flAddr == "" {
		log.Println("-addr not specified")
		os.Exit(StatusInvalidArguments)
	}
	if flConnTimeout <= 0 {
		log.Printf("-connect-timeout must be greater than zero (specified: %v)", flConnTimeout)
		os.Exit(StatusInvalidArguments)
	}
	if flRPCTimeout <= 0 {
		log.Printf("-rpc-timeout must be greater than zero (specified: %v)", flRPCTimeout)
		os.Exit(StatusInvalidArguments)
	}
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		sig := <-c
		if sig == os.Interrupt {
			log.Printf("cancellation received")
			cancel()
			return
		}
	}()
	log.Printf("establishing connection")
	conn, err := grpc.DialContext(ctx, flAddr,
		grpc.WithInsecure(),
		grpc.WithUserAgent("grpc_health_probe"),
		grpc.WithBlock(),
		grpc.WithTimeout(flConnTimeout))
	if err != nil {
		log.Printf("failed to connect service at %q: %+v", flAddr, err)
		os.Exit(StatusConnectionFailure)
	}
	defer conn.Close()

	rpcCtx, rpcCancel := context.WithTimeout(ctx, flRPCTimeout)
	defer rpcCancel()
	resp, err := healthpb.NewHealthClient(conn).Check(rpcCtx, &healthpb.HealthCheckRequest{})
	if err != nil {
		log.Printf("health check rpc failed: %+v", err)
		os.Exit(StatusRPCFailure)
	}

	if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING {
		log.Printf("service unhealthy (responded with %q)", resp.GetStatus().String())
		os.Exit(StatusUnhealthy)
	}
	log.Printf("healthy: %v", resp.GetStatus().String())
}
<commit_msg>add -tls* flags<commit_after>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	healthpb "google.golang.org/grpc/health/grpc_health_v1"
)

var (
	flAddr          string
	flConnTimeout   time.Duration
	flRPCTimeout    time.Duration
	flTLS           bool
	flTLSNoVerify   bool
	flTLSCACert     string
	flTLSClientCert string
	flTLSClientKey  string
	flTLSServerName string
)

const (
	// StatusInvalidArguments indicates specified invalid arguments.
	StatusInvalidArguments = 1
	// StatusConnectionFailure indicates connection failed.
	StatusConnectionFailure = 2
	// StatusRPCFailure indicates rpc failed.
	StatusRPCFailure = 3
	// StatusUnhealthy indicates rpc succeeded but indicates unhealthy service.
	StatusUnhealthy = 4
)

func init() {
	log.SetFlags(0)
	flag.StringVar(&flAddr, "addr", "", "(required) tcp host:port to connect")
	// timeouts
	flag.DurationVar(&flConnTimeout, "connect-timeout", time.Second, "timeout for establishing connection")
	flag.DurationVar(&flRPCTimeout, "rpc-timeout", time.Second, "timeout for health check rpc")
	// tls settings
	flag.BoolVar(&flTLS, "tls", false, "use TLS (default: false, INSECURE plaintext transport)")
	flag.BoolVar(&flTLSNoVerify, "tls-no-verify", false, "(with -tls) don't verify the certificate (INSECURE) presented by the server (default: false)")
	flag.StringVar(&flTLSCACert, "tls-ca-cert", "", "(with -tls, optional) file containing trusted certificates for verifying server")
	flag.StringVar(&flTLSClientCert, "tls-client-cert", "", "(with -tls, optional) client certificate for authenticating to the server (requires -tls-client-key)")
	flag.StringVar(&flTLSClientKey, "tls-client-key", "", "(with -tls) client private key for authenticating to the server (requires -tls-client-cert)")
	flag.StringVar(&flTLSServerName, "tls-server-name", "", "(with -tls) override the server name used to verify server certificates")

	flag.Parse()

	argError := func(s string, v ...interface{}) {
		log.Printf("error: "+s, v...)
		os.Exit(StatusInvalidArguments)
	}

	if flAddr == "" {
		argError("-addr not specified")
	}
	if flConnTimeout <= 0 {
		argError("-connect-timeout must be greater than zero (specified: %v)", flConnTimeout)
	}
	if flRPCTimeout <= 0 {
		argError("-rpc-timeout must be greater than zero (specified: %v)", flRPCTimeout)
	}
	if !flTLS && flTLSNoVerify {
		argError("specified -tls-no-verify without specifying -tls")
	}
	if !flTLS && flTLSCACert != "" {
		argError("specified -tls-ca-cert without specifying -tls")
	}
	if !flTLS && flTLSClientCert != "" {
		argError("specified -tls-client-cert without specifying -tls")
	}
	if !flTLS && flTLSServerName != "" {
		argError("specified -tls-server-name without specifying -tls")
	}
	if flTLSClientCert != "" && flTLSClientKey == "" {
		argError("specified -tls-client-cert without specifying -tls-client-key")
	}
	if flTLSClientCert == "" && flTLSClientKey != "" {
		argError("specified -tls-client-key without specifying -tls-client-cert")
	}
	if flTLSNoVerify && flTLSCACert != "" {
		argError("cannot specify -tls-ca-cert with -tls-no-verify (CA cert would not be used)")
	}
	if flTLSNoVerify && flTLSServerName != "" {
		argError("cannot specify -tls-server-name with -tls-no-verify (server name would not be used)")
	}
	log.Printf("config:")
	log.Printf("> addr=%s conn_timeout=%v rpc_timeout=%v", flAddr, flConnTimeout, flRPCTimeout)
	log.Printf("> tls=%v", flTLS)
	if flTLS {
		log.Printf("  > no-verify=%v ", flTLSNoVerify)
		log.Printf("  > ca-cert=%s", flTLSCACert)
		log.Printf("  > client-cert=%s", flTLSClientCert)
		log.Printf("  > client-key=%s", flTLSClientKey)
		log.Printf("  > server-name=%s", flTLSServerName)
	}
}

func buildCredentials(skipVerify bool, caCerts, clientCert, clientKey, serverName string) (credentials.TransportCredentials, error) {
	var cfg tls.Config

	if clientCert != "" && clientKey != "" {
		keyPair, err := tls.LoadX509KeyPair(clientCert, clientKey)
		if err != nil {
			return nil, fmt.Errorf("failed to load tls client cert/key pair. error=%v", err)
		}
		cfg.Certificates = []tls.Certificate{keyPair}
	}

	if skipVerify {
		cfg.InsecureSkipVerify = true
	} else if caCerts != "" {
		// override system roots
		rootCAs := x509.NewCertPool()
		pem, err := ioutil.ReadFile(caCerts)
		if err != nil {
			return nil, fmt.Errorf("failed to load root CA certificates from file (%s) error=%v", caCerts, err)
		}
		if !rootCAs.AppendCertsFromPEM(pem) {
			return nil, fmt.Errorf("no root CA certs parsed from file %s", caCerts)
		}
		cfg.RootCAs = rootCAs
	}
	if serverName != "" {
		cfg.ServerName = serverName
	}
	return credentials.NewTLS(&cfg), nil
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		sig := <-c
		if sig == os.Interrupt {
			log.Printf("cancellation received")
			cancel()
			return
		}
	}()
	log.Printf("establishing connection")

	opts := []grpc.DialOption{
		grpc.WithUserAgent("grpc_health_probe"),
		grpc.WithBlock(),
		grpc.WithTimeout(flConnTimeout)}
	if flTLS {
		creds, err := buildCredentials(flTLSNoVerify, flTLSCACert, flTLSClientCert, flTLSClientKey, flTLSServerName)
		if err != nil {
			log.Printf("failed to initialize tls credentials. error=%v", err)
			os.Exit(StatusInvalidArguments)
		}
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}
	connStart := time.Now()
	conn, err := grpc.DialContext(ctx, flAddr, opts...)
	if err != nil {
		log.Printf("failed to connect service at %q: %+v", flAddr, err)
		os.Exit(StatusConnectionFailure)
	}
	connDuration := time.Since(connStart)
	defer conn.Close()

	rpcStart := time.Now()
	rpcCtx, rpcCancel := context.WithTimeout(ctx, flRPCTimeout)
	defer rpcCancel()
	resp, err := healthpb.NewHealthClient(conn).Check(rpcCtx, &healthpb.HealthCheckRequest{})
	if err != nil {
		log.Printf("health check rpc failed: %+v", err)
		os.Exit(StatusRPCFailure)
	}
	rpcDuration := time.Since(rpcStart)

	if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING {
		log.Printf("service unhealthy (responded with %q)", resp.GetStatus().String())
		os.Exit(StatusUnhealthy)
	}
	log.Printf("time elapsed: connect=%v rpc=%v", connDuration, rpcDuration)
	log.Printf("status: %v", resp.GetStatus().String())
}
<|endoftext|>