<commit_before>// Deprecated project, no goway structure

package main

import (
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	tgbotapi "gopkg.in/telegram-bot-api.v4"
	"log"
)

const (
	TIMEOUT       = 60
	DATABASE      = "sqlite3"
	DATABASE_NAME = "db.sqlite3"

	fuGroupID = int64(-1001134192058)
)

var (
	bot *tgbotapi.BotAPI
	gdb *gorm.DB
)

// You must create bot_token.go file, which include TOKEN variable in global package scope
func init() {
	var err error

	gdb, err = gorm.Open(DATABASE, DATABASE_NAME)
	if err != nil {
		panic(err)
	}
	gdb.LogMode(true)

	gdb.AutoMigrate(
		&User{},
		&Group{},
		&Available{},
	)

	go startSchedule()

	bot, err = tgbotapi.NewBotAPI(TOKEN)
	if err != nil {
		log.Fatalf("cannot create bot: %s", err)
	}
}

func main() {
	defer gdb.Close()

	u := tgbotapi.NewUpdate(0)
	u.Timeout = TIMEOUT

	updates, err := bot.GetUpdatesChan(u)
	if err != nil {
		err.Error()
	}

	for update := range updates {
		update := update
		go func() {
			msg := update.Message
			if msg == nil {
				return
			}

			switch {
			case msg.IsCommand():
				handleCommand(msg, update)
			case msg.NewChatMembers != nil && len(*msg.NewChatMembers) > 0:
				handleNewMembers(msg, update)
			case msg.LeftChatMember != nil && !msg.LeftChatMember.IsBot:
				handleLeftMembers(msg, update)
			}
		}()
	}
}

func handleLeftMembers(msg *tgbotapi.Message, update tgbotapi.Update) {
	if msg.Chat.ID != fuGroupID {
		return
	}

	if msg != nil {
		newMsg := tgbotapi.NewMessage(update.Message.Chat.ID, fmt.Sprintf("нас покинул бротек @%s", update.Message.LeftChatMember.UserName))
		newMsg.ReplyToMessageID = msg.MessageID
		bot.Send(newMsg)
	}
}

func handleNewMembers(msg *tgbotapi.Message, update tgbotapi.Update) {
	if msg.Chat.ID != fuGroupID {
		return
	}

	if msg != nil {
		template := "@%s, поверь, в этом чате очко всегда сжато"
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, fmt.Sprintf(template, (*msg.NewChatMembers)[0].UserName))
		bot.Send(msg)
	}
}

func handleCommand(msg *tgbotapi.Message, update tgbotapi.Update) {
	command := msg.Command()
	createGroupRecord(msg)
	createAvailableRecord(msg)
	checkIfUsernameChanged(msg)
	checkIfPresenceUserNick(msg)
	switch command {
	case "regpi":
		regpi(msg, update)
	case "showpid":
		showpid(msg)
	case "pidor":
		startQuiz(msg)
	case "pidorstat":
		pidorStat(msg)
	case "unreg":
		if checkAdminAccess(msg, update) {
			unreg(msg, update)
		}
	case "kek":
		kekogen(msg)
	case "silent":
		disableNotify(msg, update)
	}
}
<commit_msg>welcome message now replies to user<commit_after>// Deprecated project, no goway structure

package main

import (
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
	tgbotapi "gopkg.in/telegram-bot-api.v4"
	"log"
)

const (
	TIMEOUT       = 60
	DATABASE      = "sqlite3"
	DATABASE_NAME = "db.sqlite3"

	fuGroupID = int64(-1001134192058)
)

var (
	bot *tgbotapi.BotAPI
	gdb *gorm.DB
)

// You must create bot_token.go file, which include TOKEN variable in global package scope
func init() {
	var err error

	gdb, err = gorm.Open(DATABASE, DATABASE_NAME)
	if err != nil {
		panic(err)
	}
	gdb.LogMode(true)

	gdb.AutoMigrate(
		&User{},
		&Group{},
		&Available{},
	)

	go startSchedule()

	bot, err = tgbotapi.NewBotAPI(TOKEN)
	if err != nil {
		log.Fatalf("cannot create bot: %s", err)
	}
}

func main() {
	defer gdb.Close()

	u := tgbotapi.NewUpdate(0)
	u.Timeout = TIMEOUT

	updates, err := bot.GetUpdatesChan(u)
	if err != nil {
		err.Error()
	}

	for update := range updates {
		update := update
		go func() {
			msg := update.Message
			if msg == nil {
				return
			}

			switch {
			case msg.IsCommand():
				handleCommand(msg, update)
			case msg.NewChatMembers != nil && len(*msg.NewChatMembers) > 0:
				handleNewMembers(msg, update)
			case msg.LeftChatMember != nil && !msg.LeftChatMember.IsBot:
				handleLeftMembers(msg, update)
			}
		}()
	}
}

func handleLeftMembers(msg *tgbotapi.Message, update tgbotapi.Update) {
	if msg.Chat.ID != fuGroupID {
		return
	}

	if msg != nil {
		newMsg := tgbotapi.NewMessage(update.Message.Chat.ID, fmt.Sprintf("нас покинул бротек @%s", update.Message.LeftChatMember.UserName))
		newMsg.ReplyToMessageID = msg.MessageID
		bot.Send(newMsg)
	}
}

func handleNewMembers(msg *tgbotapi.Message, update tgbotapi.Update) {
	if msg.Chat.ID != fuGroupID {
		return
	}

	if msg != nil {
		template := "@%s, поверь, в этом чате очко всегда сжато"
		newMsg := tgbotapi.NewMessage(update.Message.Chat.ID, fmt.Sprintf(template, (*msg.NewChatMembers)[0].UserName))
		newMsg.ReplyToMessageID = msg.MessageID
		bot.Send(newMsg)
	}
}

func handleCommand(msg *tgbotapi.Message, update tgbotapi.Update) {
	command := msg.Command()
	createGroupRecord(msg)
	createAvailableRecord(msg)
	checkIfUsernameChanged(msg)
	checkIfPresenceUserNick(msg)
	switch command {
	case "regpi":
		regpi(msg, update)
	case "showpid":
		showpid(msg)
	case "pidor":
		startQuiz(msg)
	case "pidorstat":
		pidorStat(msg)
	case "unreg":
		if checkAdminAccess(msg, update) {
			unreg(msg, update)
		}
	case "kek":
		kekogen(msg)
	case "silent":
		disableNotify(msg, update)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"log"
	"fmt"
	"net/http"

	"github.com/gorilla/mux"
	"github.com/codegangsta/negroni"
	"github.com/gorilla/context"
	"github.com/joho/godotenv"
	"github.com/xlab/closer"
	"github.com/pjebs/restgate"
	r "gopkg.in/unrolled/render.v1"

	"github.com/urakozz/transpoint.io/storage"
	"github.com/satori/go.uuid"
	"encoding/json"
	"time"
	t "github.com/urakozz/transpoint.io/translator"
)

const ApiVersion = "v1"

var (
	render *r.Render
	driver *storage.RedisDriver
	translator *t.YandexTranslator
)

func init() {
	godotenv.Load()
	render = r.New(r.Options{})
	driver = storage.NewRedisDriver(os.Getenv("REDIS_ADDR"), os.Getenv("REDIS_DB"), os.Getenv("REDIS_PASS"))
	translator = t.NewYandexTranslator()
}

func main() {
	closer.Bind(cleanup)
	closer.Checked(run, true)
}

func run() error {
	port := os.Getenv("PORT")

	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/ping", Ping).Methods("GET")
	router.HandleFunc("/"+ApiVersion, Default).Methods("GET")
	router.HandleFunc("/"+ApiVersion+"/translations", Create).Methods("POST")
	router.HandleFunc("/"+ApiVersion+"/translations/{id:[a-z0-9-]+}", Save).Methods("POST")
	router.HandleFunc("/"+ApiVersion+"/translations/{id}", Get).Methods("GET")
	router.HandleFunc("/"+ApiVersion+"/translations/{id}/{lang:[a-z]{2}}", GetParticular).Methods("GET")
	router.HandleFunc("/"+ApiVersion+"/translations/{id}", Delete).Methods("DELETE")
	router.HandleFunc("/"+ApiVersion+"/translations/{id}/{lang:[a-z]{2}}", DeleteParticular).Methods("DELETE")

	app := negroni.New()
	//These middleware is common to all routes
	app.Use(negroni.NewRecovery())
	app.Use(negroni.NewLogger())
//	app.Use(restgate.New(
//		"X-Auth-Key",
//		"X-Auth-Secret",
//		restgate.Static,
//		restgate.Config{
//			Context: C,
//			Key: []string{"12345"},
//			Secret: []string{"secret"},
//		},
//	))
	app.UseHandler(router)
	http.Handle("/", context.ClearHandler(app))

	log.Printf("Info: Starting application on port %s", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))

	//	log.Fatal(http.ListenAndServe(":"+port, router))
	return nil
}

func cleanup() {
	driver.Client.Close()
	log.Print("Info: Gracefully closing application")
}

func C(r *http.Request, authenticatedKey string) {
	context.Set(r, 0, authenticatedKey)
}

func Ping(w http.ResponseWriter, r *http.Request) {
	render.JSON(w, http.StatusOK, "PONG")
}

func Default(w http.ResponseWriter, r *http.Request) {
	methodMap := make(map[string]string)
	methodMap["translation_map"] = fmt.Sprintf("/%s/%s", ApiVersion, "translations")
	render.JSON(w, http.StatusOK, methodMap)
}

func Create(w http.ResponseWriter, r *http.Request) {
	u1 := uuid.NewV4().String()
	var request *RequestObject
	json.NewDecoder(r.Body).Decode(&request)
	bag := SmartSave(request, u1)

	w.Header().Set("Location", "/"+ApiVersion+"/translations/"+u1)
	render.JSON(w, http.StatusCreated, bag)
}

func Save(w http.ResponseWriter, r *http.Request) {
	var request *RequestObject
	json.NewDecoder(r.Body).Decode(&request)
	id := mux.Vars(r)["id"]
	bag := SmartSave(request, id)

	w.Header().Set("Location", "/"+ApiVersion+"/translations/"+id)
	render.JSON(w, http.StatusCreated, bag)
}

func SmartSave(request *RequestObject, id string) (bag storage.TranslationBag) {
	bag, err := driver.GetAll(id)
	log.Println(bag, err)

	langs := request.Lang
	if err == nil {
		var newLangs []string
		if bag.Original == request.Text {
			for _, lang := range langs {
				if _, exists := bag.Translations[lang]; !exists {
					newLangs = append(newLangs, lang)
				}
			}
		} else {
			newLangs = langs
			for lang, _ := range bag.Translations {
				newLangs = append(newLangs, lang)
			}
		}

		langs = newLangs
	}

	if 0 == len(langs) {
		return
	}
	container := translator.Translate(request.Text, langs)
	driver.Save(id, container.Source, request.Text, container.Translations)
	bag, err = driver.GetAll(id)
	log.Println(bag, err)
	return
}

func Get(w http.ResponseWriter, r *http.Request) {

	id := mux.Vars(r)["id"]
	start := time.Now()
	bag, err := driver.GetAll(id)
	log.Printf("Completed in %v", time.Since(start))
	if nil != err {
		render.JSON(w, http.StatusNotFound, map[string]string{"error":err.Error()})
		return
	}

	render.JSON(w, http.StatusOK, bag)
}

func GetParticular(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	lang := mux.Vars(r)["lang"]

	start := time.Now()
	bag, err := driver.GetLang(id, lang)
	log.Printf("Completed in %v", time.Since(start))

	if nil != err {
		render.JSON(w, http.StatusNotFound, map[string]string{"error":err.Error()})
		return
	}

	render.JSON(w, http.StatusOK, bag)
}

func Delete(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	err := driver.Delete(id)
	if err != nil {
		log.Println("Delete", id, err)
	}
	w.WriteHeader(http.StatusNoContent)
}

func DeleteParticular(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	lang := mux.Vars(r)["lang"]
	err := driver.DeleteLang(id, lang)

	if err != nil {
		log.Println("Delete", id, err)
	}
	w.WriteHeader(http.StatusNoContent)
}

type RequestObject struct {
	Id     string `json:"id"`
	Text   string `json:"text"`
	Lang   []string `json:"lang"`
	Source string `json:"source"`
}

<commit_msg>no auth<commit_after>package main

import (
	"os"
	"log"
	"fmt"
	"net/http"

	"github.com/gorilla/mux"
	"github.com/codegangsta/negroni"
	"github.com/gorilla/context"
	"github.com/joho/godotenv"
	"github.com/xlab/closer"
//	"github.com/pjebs/restgate"
	r "gopkg.in/unrolled/render.v1"

	"github.com/urakozz/transpoint.io/storage"
	"github.com/satori/go.uuid"
	"encoding/json"
	"time"
	t "github.com/urakozz/transpoint.io/translator"
)

const ApiVersion = "v1"

var (
	render *r.Render
	driver *storage.RedisDriver
	translator *t.YandexTranslator
)

func init() {
	godotenv.Load()
	render = r.New(r.Options{})
	driver = storage.NewRedisDriver(os.Getenv("REDIS_ADDR"), os.Getenv("REDIS_DB"), os.Getenv("REDIS_PASS"))
	translator = t.NewYandexTranslator()
}

func main() {
	closer.Bind(cleanup)
	closer.Checked(run, true)
}

func run() error {
	port := os.Getenv("PORT")

	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/ping", Ping).Methods("GET")
	router.HandleFunc("/"+ApiVersion, Default).Methods("GET")
	router.HandleFunc("/"+ApiVersion+"/translations", Create).Methods("POST")
	router.HandleFunc("/"+ApiVersion+"/translations/{id:[a-z0-9-]+}", Save).Methods("POST")
	router.HandleFunc("/"+ApiVersion+"/translations/{id}", Get).Methods("GET")
	router.HandleFunc("/"+ApiVersion+"/translations/{id}/{lang:[a-z]{2}}", GetParticular).Methods("GET")
	router.HandleFunc("/"+ApiVersion+"/translations/{id}", Delete).Methods("DELETE")
	router.HandleFunc("/"+ApiVersion+"/translations/{id}/{lang:[a-z]{2}}", DeleteParticular).Methods("DELETE")

	app := negroni.New()
	//These middleware is common to all routes
	app.Use(negroni.NewRecovery())
	app.Use(negroni.NewLogger())
//	app.Use(restgate.New(
//		"X-Auth-Key",
//		"X-Auth-Secret",
//		restgate.Static,
//		restgate.Config{
//			Context: C,
//			Key: []string{"12345"},
//			Secret: []string{"secret"},
//		},
//	))
	app.UseHandler(router)
	http.Handle("/", context.ClearHandler(app))

	log.Printf("Info: Starting application on port %s", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))

	//	log.Fatal(http.ListenAndServe(":"+port, router))
	return nil
}

func cleanup() {
	driver.Client.Close()
	log.Print("Info: Gracefully closing application")
}

func C(r *http.Request, authenticatedKey string) {
	context.Set(r, 0, authenticatedKey)
}

func Ping(w http.ResponseWriter, r *http.Request) {
	render.JSON(w, http.StatusOK, "PONG")
}

func Default(w http.ResponseWriter, r *http.Request) {
	methodMap := make(map[string]string)
	methodMap["translation_map"] = fmt.Sprintf("/%s/%s", ApiVersion, "translations")
	render.JSON(w, http.StatusOK, methodMap)
}

func Create(w http.ResponseWriter, r *http.Request) {
	u1 := uuid.NewV4().String()
	var request *RequestObject
	json.NewDecoder(r.Body).Decode(&request)
	bag := SmartSave(request, u1)

	w.Header().Set("Location", "/"+ApiVersion+"/translations/"+u1)
	render.JSON(w, http.StatusCreated, bag)
}

func Save(w http.ResponseWriter, r *http.Request) {
	var request *RequestObject
	json.NewDecoder(r.Body).Decode(&request)
	id := mux.Vars(r)["id"]
	bag := SmartSave(request, id)

	w.Header().Set("Location", "/"+ApiVersion+"/translations/"+id)
	render.JSON(w, http.StatusCreated, bag)
}

func SmartSave(request *RequestObject, id string) (bag storage.TranslationBag) {
	bag, err := driver.GetAll(id)
	log.Println(bag, err)

	langs := request.Lang
	if err == nil {
		var newLangs []string
		if bag.Original == request.Text {
			for _, lang := range langs {
				if _, exists := bag.Translations[lang]; !exists {
					newLangs = append(newLangs, lang)
				}
			}
		} else {
			newLangs = langs
			for lang, _ := range bag.Translations {
				newLangs = append(newLangs, lang)
			}
		}

		langs = newLangs
	}

	if 0 == len(langs) {
		return
	}
	container := translator.Translate(request.Text, langs)
	driver.Save(id, container.Source, request.Text, container.Translations)
	bag, err = driver.GetAll(id)
	log.Println(bag, err)
	return
}

func Get(w http.ResponseWriter, r *http.Request) {

	id := mux.Vars(r)["id"]
	start := time.Now()
	bag, err := driver.GetAll(id)
	log.Printf("Completed in %v", time.Since(start))
	if nil != err {
		render.JSON(w, http.StatusNotFound, map[string]string{"error":err.Error()})
		return
	}

	render.JSON(w, http.StatusOK, bag)
}

func GetParticular(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	lang := mux.Vars(r)["lang"]

	start := time.Now()
	bag, err := driver.GetLang(id, lang)
	log.Printf("Completed in %v", time.Since(start))

	if nil != err {
		render.JSON(w, http.StatusNotFound, map[string]string{"error":err.Error()})
		return
	}

	render.JSON(w, http.StatusOK, bag)
}

func Delete(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	err := driver.Delete(id)
	if err != nil {
		log.Println("Delete", id, err)
	}
	w.WriteHeader(http.StatusNoContent)
}

func DeleteParticular(w http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	lang := mux.Vars(r)["lang"]
	err := driver.DeleteLang(id, lang)

	if err != nil {
		log.Println("Delete", id, err)
	}
	w.WriteHeader(http.StatusNoContent)
}

type RequestObject struct {
	Id     string `json:"id"`
	Text   string `json:"text"`
	Lang   []string `json:"lang"`
	Source string `json:"source"`
}

<|endoftext|>


<commit_before>// Enhanced Markdown template processor.
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/mh-cbon/emd/cli"
	"github.com/mh-cbon/emd/deprecated"
	"github.com/mh-cbon/emd/emd"
	gostd "github.com/mh-cbon/emd/go"
	gononstd "github.com/mh-cbon/emd/go-nonstd"
	"github.com/mh-cbon/emd/provider"
	"github.com/mh-cbon/emd/std"
)

// VERSION defines the running build id.
var VERSION = "0.0.0"

var program = cli.NewProgram("emd", VERSION)

func main() {
	program.Bind()
	if err := program.Run(os.Args); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

// gen sub command
type gencommand struct {
	*cli.Command
	in        string
	out       string
	data      string
	help      bool
	shortHelp bool
}

// init sub command
type initcommand struct {
	*cli.Command
	help      bool
	shortHelp bool
	out       string
	force     bool
}

func init() {
	gen := &gencommand{Command: cli.NewCommand("gen", "Process an emd file.", Generate)}
	gen.Set.StringVar(&gen.in, "in", "", "Input src file")
	gen.Set.StringVar(&gen.out, "out", "-", "Output destination, defaults to stdout")
	gen.Set.StringVar(&gen.data, "data", "", "JSON map of data")
	gen.Set.BoolVar(&gen.help, "help", false, "Show help")
	gen.Set.BoolVar(&gen.shortHelp, "h", false, "Show help")

	program.Add(gen)

	ini := &initcommand{Command: cli.NewCommand("init", "Init a basic emd file.", InitFile)}
	ini.Set.BoolVar(&ini.help, "help", false, "Show help")
	ini.Set.BoolVar(&ini.shortHelp, "h", false, "Show help")
	ini.Set.BoolVar(&ini.force, "force", false, "Force write")
	ini.Set.StringVar(&ini.out, "out", "README.e.md", "Out file")
	program.Add(ini)
}

// Generate is the cli command implementation of gen.
func Generate(s cli.Commander) error {

	cmd, ok := s.(*gencommand)
	if ok == false {
		return fmt.Errorf("Invalid command type %T", s)
	}

	if cmd.help || cmd.shortHelp {
		return program.ShowCmdUsage(cmd)
	}

	out, err := getStdout(cmd.out)
	if err != nil {
		return err
	}
	if x, ok := out.(io.Closer); ok {
		defer x.Close()
	}

	cwd, err := getCwd()
	if err != nil {
		return err
	}
	gopath := filepath.Join(os.Getenv("GOPATH"), "src")
	gopath = strings.Replace(gopath, "\\", "/", -1)
	projectPath := cwd[len(gopath):]

	plugins := getPlugins()
	data := getData(projectPath)

	if cmd.data != "" {
		if err := json.Unmarshal([]byte(cmd.data), &data); err != nil {
			return fmt.Errorf("Cannot decode JSON data string: %v", err)
		}
	}

	gen := emd.NewGenerator()

	if cmd.in != "" {
		if err := gen.AddFileTemplate(cmd.in); err != nil {
			return err
		}
	} else if s, err := os.Stat("README.e.md"); !os.IsNotExist(err) && s.IsDir() == false {
		if err := gen.AddFileTemplate("README.e.md"); err != nil {
			return err
		}
	} else {
		gen.AddTemplate(defTemplate)
	}

	gen.SetDataMap(data)

	for name, plugin := range plugins {
		if err := plugin(gen); err != nil {
			return fmt.Errorf("Failed to register %v package: %v", name, err)
		}
	}

	if err := gen.Execute(out); err != nil {
		return fmt.Errorf("Generator failed: %v", err)
	}

	return nil
}

func getData(cwd string) map[string]interface{} {
	p := provider.Default(cwd)
	if p.Match() == false {
		log.Printf("Failed to identify this project url %v\n", cwd)
	}
	return map[string]interface{}{
		"Name":         p.GetProjectName(),
		"User":         p.GetUserName(),
		"ProviderURL":  p.GetProviderURL(),
		"ProviderName": p.GetProviderID(),
		"URL":          p.GetURL(),
		"ProjectURL":   p.GetProjectURL(),
		"Branch":       "master",
	}
}

func getPlugins() map[string]func(*emd.Generator) error {
	return map[string]func(*emd.Generator) error{
		"std":        std.Register,
		"gostd":      gostd.Register,
		"gononstd":   gononstd.Register,
		"deprecated": deprecated.Register,
	}
}

func getStdout(out string) (io.Writer, error) {

	ret := os.Stdout

	if out != "-" {
		f, err := os.Create(out)
		if err != nil {
			f, err = os.Open(out)
			if err != nil {
				return nil, fmt.Errorf("Cannot open out destination: %v", err)
			}
		}
		ret = f
	}
	return ret, nil
}

func getCwd() (string, error) {
	cwd, err := os.Getwd()
	if err != nil {
		return "", fmt.Errorf("Failed to determmine cwd: %v", err)
	}
	// for those who uses symlinks to relocate their code,
	// the path must be evaluated.
	cwd, err = filepath.EvalSymlinks(cwd)
	if err != nil {
		return "", fmt.Errorf("Failed to determmine eval path: %v", err)
	}
	return cwd, nil
}

// InitFile creates a basic emd file if none exits.
func InitFile(s cli.Commander) error {

	cmd, ok := s.(*initcommand)
	if ok == false {
		return fmt.Errorf("Invalid command type %T", s)
	}

	if cmd.help || cmd.shortHelp {
		return program.ShowCmdUsage(cmd)
	}

	out := cmd.out
	if cmd.out == "" {
		out = "README.e.md"
	}
	if _, err := os.Stat(out); !cmd.force && !os.IsNotExist(err) {
		return fmt.Errorf("File exits at %q", out)
	}
	return ioutil.WriteFile(out, []byte(defTemplate), os.ModePerm)
}

var defTemplate = `# {{.Name}}

{{template "badge/goreport" .}} {{template "badge/godoc" .}}

{{pkgdoc}}

# {{toc 5}}

# Install

{{template "gh/releases" .}}

#### go
{{template "go/install" .}}
`
<commit_msg>data: allow prelude data to override predefined data extracted from the cwd<commit_after>// Enhanced Markdown template processor.
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/mh-cbon/emd/cli"
	"github.com/mh-cbon/emd/deprecated"
	"github.com/mh-cbon/emd/emd"
	gostd "github.com/mh-cbon/emd/go"
	gononstd "github.com/mh-cbon/emd/go-nonstd"
	"github.com/mh-cbon/emd/provider"
	"github.com/mh-cbon/emd/std"
)

// VERSION defines the running build id.
var VERSION = "0.0.0"

var program = cli.NewProgram("emd", VERSION)

func main() {
	program.Bind()
	if err := program.Run(os.Args); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

// gen sub command
type gencommand struct {
	*cli.Command
	in        string
	out       string
	data      string
	help      bool
	shortHelp bool
}

// init sub command
type initcommand struct {
	*cli.Command
	help      bool
	shortHelp bool
	out       string
	force     bool
}

func init() {
	gen := &gencommand{Command: cli.NewCommand("gen", "Process an emd file.", Generate)}
	gen.Set.StringVar(&gen.in, "in", "", "Input src file")
	gen.Set.StringVar(&gen.out, "out", "-", "Output destination, defaults to stdout")
	gen.Set.StringVar(&gen.data, "data", "", "JSON map of data")
	gen.Set.BoolVar(&gen.help, "help", false, "Show help")
	gen.Set.BoolVar(&gen.shortHelp, "h", false, "Show help")

	program.Add(gen)

	ini := &initcommand{Command: cli.NewCommand("init", "Init a basic emd file.", InitFile)}
	ini.Set.BoolVar(&ini.help, "help", false, "Show help")
	ini.Set.BoolVar(&ini.shortHelp, "h", false, "Show help")
	ini.Set.BoolVar(&ini.force, "force", false, "Force write")
	ini.Set.StringVar(&ini.out, "out", "README.e.md", "Out file")
	program.Add(ini)
}

// Generate is the cli command implementation of gen.
func Generate(s cli.Commander) error {

	cmd, ok := s.(*gencommand)
	if ok == false {
		return fmt.Errorf("Invalid command type %T", s)
	}

	if cmd.help || cmd.shortHelp {
		return program.ShowCmdUsage(cmd)
	}

	out, err := getStdout(cmd.out)
	if err != nil {
		return err
	}
	if x, ok := out.(io.Closer); ok {
		defer x.Close()
	}

	cwd, err := getCwd()
	if err != nil {
		return err
	}
	gopath := filepath.Join(os.Getenv("GOPATH"), "src")
	gopath = strings.Replace(gopath, "\\", "/", -1)
	projectPath := cwd[len(gopath):]

	plugins := getPlugins()
	data := getData(projectPath)

	if cmd.data != "" {
		if err := json.Unmarshal([]byte(cmd.data), &data); err != nil {
			return fmt.Errorf("Cannot decode JSON data string: %v", err)
		}
	}

	gen := emd.NewGenerator()

	gen.SetDataMap(data)

	if cmd.in != "" {
		if err := gen.AddFileTemplate(cmd.in); err != nil {
			return err
		}
	} else if s, err := os.Stat("README.e.md"); !os.IsNotExist(err) && s.IsDir() == false {
		if err := gen.AddFileTemplate("README.e.md"); err != nil {
			return err
		}
	} else {
		gen.AddTemplate(defTemplate)
	}

	for name, plugin := range plugins {
		if err := plugin(gen); err != nil {
			return fmt.Errorf("Failed to register %v package: %v", name, err)
		}
	}

	if err := gen.Execute(out); err != nil {
		return fmt.Errorf("Generator failed: %v", err)
	}

	return nil
}

func getData(cwd string) map[string]interface{} {
	p := provider.Default(cwd)
	if p.Match() == false {
		log.Printf("Failed to identify this project url %v\n", cwd)
	}
	return map[string]interface{}{
		"Name":         p.GetProjectName(),
		"User":         p.GetUserName(),
		"ProviderURL":  p.GetProviderURL(),
		"ProviderName": p.GetProviderID(),
		"URL":          p.GetURL(),
		"ProjectURL":   p.GetProjectURL(),
		"Branch":       "master",
	}
}

func getPlugins() map[string]func(*emd.Generator) error {
	return map[string]func(*emd.Generator) error{
		"std":        std.Register,
		"gostd":      gostd.Register,
		"gononstd":   gononstd.Register,
		"deprecated": deprecated.Register,
	}
}

func getStdout(out string) (io.Writer, error) {

	ret := os.Stdout

	if out != "-" {
		f, err := os.Create(out)
		if err != nil {
			f, err = os.Open(out)
			if err != nil {
				return nil, fmt.Errorf("Cannot open out destination: %v", err)
			}
		}
		ret = f
	}
	return ret, nil
}

func getCwd() (string, error) {
	cwd, err := os.Getwd()
	if err != nil {
		return "", fmt.Errorf("Failed to determmine cwd: %v", err)
	}
	// for those who uses symlinks to relocate their code,
	// the path must be evaluated.
	cwd, err = filepath.EvalSymlinks(cwd)
	if err != nil {
		return "", fmt.Errorf("Failed to determmine eval path: %v", err)
	}
	return cwd, nil
}

// InitFile creates a basic emd file if none exits.
func InitFile(s cli.Commander) error {

	cmd, ok := s.(*initcommand)
	if ok == false {
		return fmt.Errorf("Invalid command type %T", s)
	}

	if cmd.help || cmd.shortHelp {
		return program.ShowCmdUsage(cmd)
	}

	out := cmd.out
	if cmd.out == "" {
		out = "README.e.md"
	}
	if _, err := os.Stat(out); !cmd.force && !os.IsNotExist(err) {
		return fmt.Errorf("File exits at %q", out)
	}
	return ioutil.WriteFile(out, []byte(defTemplate), os.ModePerm)
}

var defTemplate = `# {{.Name}}

{{template "badge/goreport" .}} {{template "badge/godoc" .}}

{{pkgdoc}}

# {{toc 5}}

# Install

{{template "gh/releases" .}}

#### go
{{template "go/install" .}}
`
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	"os"

	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	"github.com/justinas/alice"
)

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/hello/{name}", helloHandler)

	// add middleware
	stderrLoggingHandler := func(http.Handler) http.Handler {
		return handlers.LoggingHandler(os.Stderr, r)
	}
	middlewareRouter := alice.New(handlers.CompressHandler, stderrLoggingHandler).Then(r)

	// serve http
	http.Handle("/", middlewareRouter)
	http.ListenAndServe(":8080", nil)
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
	args := mux.Vars(r)
	fmt.Fprintf(w, "Hello %s!", args["name"])
}
<commit_msg>fixed merge conflict in imports<commit_after>package main

import (
	"fmt"
	"net/http"
	_ "net/http/pprof" // import for side effects
	"os"

	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	"github.com/justinas/alice"
)

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/hello/{name}", helloHandler)

	// add middleware
	stderrLoggingHandler := func(http.Handler) http.Handler {
		return handlers.LoggingHandler(os.Stderr, r)
	}
	middlewareRouter := alice.New(handlers.CompressHandler, stderrLoggingHandler).Then(r)

	// serve http
	http.Handle("/", middlewareRouter)
	http.ListenAndServe(":8080", nil)
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
	args := mux.Vars(r)
	fmt.Fprintf(w, "Hello %s!", args["name"])
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
)

type Line struct {
	Epoch   float64
	Db      int
	Command string
	Key     string
	Args    string
}

type Command struct {
	Name string
	Cnt  int
	Sum  float64
	Avg  float64
}

type Commands []Command

type Profile struct {
	Call string
	Args string
	Cnt  int
	Max  float64
	Min  float64
	Avg  float64
	Sum  float64
}

type Profiles []Profile

type ByCnt struct{ Profiles }
type ByMax struct{ Profiles }
type ByAvg struct{ Profiles }

type ByCommand struct{ Commands }
type ByHeavyCommand struct{ Commands }

func (p Profiles) Len() int      { return len(p) }
func (p Profiles) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

func (c Commands) Len() int      { return len(c) }
func (c Commands) Swap(i, j int) { c[i], c[j] = c[j], c[i] }

func (p ByCnt) Less(i, j int) bool { return p.Profiles[i].Cnt < p.Profiles[j].Cnt }
func (p ByMax) Less(i, j int) bool { return p.Profiles[i].Max < p.Profiles[j].Max }
func (p ByAvg) Less(i, j int) bool { return p.Profiles[i].Avg < p.Profiles[j].Avg }

func (c ByCommand) Less(i, j int) bool      { return c.Commands[i].Cnt < c.Commands[j].Cnt }
func (c ByHeavyCommand) Less(i, j int) bool { return c.Commands[i].Sum < c.Commands[j].Sum }

const (
	SORT_TYPE_BY_MAX = "max"
	SORT_TYPE_BY_AVG = "avg"
	SORT_TYPE_BY_CNT = "cnt"
)

var (
	filePath = flag.String("f", "", "redis-cli monitor out put file")
	listNum  = flag.Int("n", 10, "Show Slowest Calls Count")
	sortType = flag.String("s", "max", "SlowestCalls type: max, avg, cnt")

	// regexp
	// refs: https://play.golang.org/p/yl6B1oWtvE
	// 0: line
	// 1: epoch
	// 2; db
	// 3: command
	// 4: command args
	// 5: key
	// 6: args
	lineRegexpRule = `([\d\.]+)\s\[(\d+)\s\d+\.\d+\.\d+\.\d+:\d+]\s"(\w+)"(\s"([^(?<!\\)"]+)"|\s"([^(?<!\\)"]+)"\s(.+)|)`
	lineRegexp     = regexp.MustCompile(lineRegexpRule)

	readFile    *os.File
	monitorLogs Profiles
	commands    Commands

	logIndex  = make(map[string]int)
	logLength = 0
	logCursor = 0

	commandIndex  = make(map[string]int)
	commandLength = 0
	commandCursor = 0

	lineCount = 0
)

func SetProfileIndex(call string) {
	if _, ok := logIndex[call]; ok {
		logCursor = logIndex[call]
	} else {
		logIndex[call] = logLength
		logCursor = logLength
		logLength++
		monitorLogs = append(monitorLogs, Profile{
			Call: call,
			Cnt:  0,
			Min:  0,
			Avg:  0,
			Sum:  0,
		})
	}
}

func SetCommandIndex(command string) {
	if _, ok := commandIndex[command]; ok {
		commandCursor = commandIndex[command]
	} else {
		commandIndex[command] = commandLength
		commandCursor = commandLength
		commandLength++
		commands = append(commands, Command{
			Name: command,
			Cnt:  0,
			Avg:  0,
			Sum:  0,
		})
	}
}

func main() {
	flag.Parse()

	if !strings.Contains(*sortType, SORT_TYPE_BY_MAX) && !strings.Contains(*sortType, SORT_TYPE_BY_AVG) && !strings.Contains(*sortType, SORT_TYPE_BY_CNT) {
		log.Fatal("Please set sort type max, avg or cnt")
	}

	if *filePath != "" {
		rf, err := os.Open(*filePath)
		if err != nil {
			log.Fatal(err)
		}
		readFile = rf
		defer rf.Close()
	} else {
		readFile = os.Stdin
	}

	scanner := bufio.NewScanner(readFile)
	var beforeLine Line

	for scanner.Scan() {
		group := lineRegexp.FindStringSubmatch(scanner.Text())
		if 1 > len(group) {
			continue
		}

		epoch, err := strconv.ParseFloat(group[1], 64)
		if err != nil {
			log.Println(err)
			continue
		}
		db, err := strconv.Atoi(group[2])
		if err != nil {
			log.Println(err)
			continue
		}

		line := Line{
			Epoch:   epoch,
			Db:      db,
			Command: group[3],
			Key:     group[5],
			Args:    group[6],
		}

		var commandTime float64
		if beforeLine.Command != "" {
			commandTime = line.Epoch - beforeLine.Epoch
		} else {
			commandTime = 0
		}

		SetProfileIndex(fmt.Sprintf("%s %s", line.Command, line.Key))
		SetCommandIndex(line.Command)

		if monitorLogs[logCursor].Max < commandTime {
			monitorLogs[logCursor].Max = commandTime
		}

		if commandTime < monitorLogs[logCursor].Min {
			monitorLogs[logCursor].Min = commandTime
		}
		monitorLogs[logCursor].Cnt++
		monitorLogs[logCursor].Sum = monitorLogs[logCursor].Sum + commandTime
		monitorLogs[logCursor].Avg = monitorLogs[logCursor].Sum / float64(monitorLogs[logCursor].Cnt)

		commands[commandCursor].Cnt++
		commands[commandCursor].Sum = commands[commandCursor].Sum + commandTime

		beforeLine = line
		lineCount++
	}

	err := PrintResult()
	if err != nil {
		log.Println(err)
	}
}

func PrintTitle(key string) {
	fmt.Println(key)
	fmt.Println("==================================")
}

func PrintResult() error {
	PrintTitle("Overall Stats")
	fmt.Printf("LineCount \t %d \n\n", lineCount)
	fmt.Printf("\n")

	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 0, 8, 0, '\t', tabwriter.AlignRight)
	PrintTitle("Commands Rate")
	sort.Sort(sort.Reverse((ByCommand{commands})))
	for _, v := range commands {
		fmt.Fprintf(w, "%s\t %d \n", v.Name, v.Cnt)
	}
	w.Flush()
	fmt.Printf("\n")

	PrintTitle("Heavy Commands")
	fmt.Fprintln(w, "Command \tSum(msec)")
	sort.Sort(sort.Reverse((ByHeavyCommand{commands})))
	for _, v := range commands {
		fmt.Fprintf(w, "%s \t %f \n", v.Name, v.Sum)
	}
	w.Flush()
	fmt.Printf("\n")

	PrintTitle("Slowest Calls")
	if strings.Contains(*sortType, SORT_TYPE_BY_AVG) {
		sort.Sort(sort.Reverse((ByAvg{monitorLogs})))
	} else if strings.Contains(*sortType, SORT_TYPE_BY_CNT) {
		sort.Sort(sort.Reverse((ByCnt{monitorLogs})))
	} else {
		sort.Sort(sort.Reverse((ByMax{monitorLogs})))
	}

	fmt.Fprintln(w, "KEY \tCount \tMax(msec) \t Avg(msec)")
	for i, v := range monitorLogs {
		if *listNum < i {
			break
		}
		fmt.Fprintf(w, "%s\t %d \t %f\t %f\n", v.Call, v.Cnt, v.Max, v.Avg)
	}
	w.Flush()

	return nil
}
<commit_msg>fix error handling<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
)

type Line struct {
	Epoch   float64
	Db      int
	Command string
	Key     string
	Args    string
}

type Command struct {
	Name string
	Cnt  int
	Sum  float64
	Avg  float64
}

type Commands []Command

type Profile struct {
	Call string
	Args string
	Cnt  int
	Max  float64
	Min  float64
	Avg  float64
	Sum  float64
}

type Profiles []Profile

type ByCnt struct{ Profiles }
type ByMax struct{ Profiles }
type ByAvg struct{ Profiles }

type ByCommand struct{ Commands }
type ByHeavyCommand struct{ Commands }

func (p Profiles) Len() int      { return len(p) }
func (p Profiles) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

func (c Commands) Len() int      { return len(c) }
func (c Commands) Swap(i, j int) { c[i], c[j] = c[j], c[i] }

func (p ByCnt) Less(i, j int) bool { return p.Profiles[i].Cnt < p.Profiles[j].Cnt }
func (p ByMax) Less(i, j int) bool { return p.Profiles[i].Max < p.Profiles[j].Max }
func (p ByAvg) Less(i, j int) bool { return p.Profiles[i].Avg < p.Profiles[j].Avg }

func (c ByCommand) Less(i, j int) bool      { return c.Commands[i].Cnt < c.Commands[j].Cnt }
func (c ByHeavyCommand) Less(i, j int) bool { return c.Commands[i].Sum < c.Commands[j].Sum }

const (
	SORT_TYPE_BY_MAX = "max"
	SORT_TYPE_BY_AVG = "avg"
	SORT_TYPE_BY_CNT = "cnt"
)

var (
	filePath = flag.String("f", "", "redis-cli monitor out put file")
	listNum  = flag.Int("n", 10, "Show Slowest Calls Count")
	sortType = flag.String("s", "max", "SlowestCalls type: max, avg, cnt")

	// regexp
	// refs: https://play.golang.org/p/yl6B1oWtvE
	// 0: line
	// 1: epoch
	// 2; db
	// 3: command
	// 4: command args
	// 5: key
	// 6: args
	lineRegexpRule = `([\d\.]+)\s\[(\d+)\s\d+\.\d+\.\d+\.\d+:\d+]\s"(\w+)"(\s"([^(?<!\\)"]+)"|\s"([^(?<!\\)"]+)"\s(.+)|)`
	lineRegexp     = regexp.MustCompile(lineRegexpRule)

	readFile    *os.File
	monitorLogs Profiles
	commands    Commands

	logIndex  = make(map[string]int)
	logLength = 0
	logCursor = 0

	commandIndex  = make(map[string]int)
	commandLength = 0
	commandCursor = 0

	lineCount = 0
)

func SetProfileIndex(call string) {
	if _, ok := logIndex[call]; ok {
		logCursor = logIndex[call]
	} else {
		logIndex[call] = logLength
		logCursor = logLength
		logLength++
		monitorLogs = append(monitorLogs, Profile{
			Call: call,
			Cnt:  0,
			Min:  0,
			Avg:  0,
			Sum:  0,
		})
	}
}

func SetCommandIndex(command string) {
	if _, ok := commandIndex[command]; ok {
		commandCursor = commandIndex[command]
	} else {
		commandIndex[command] = commandLength
		commandCursor = commandLength
		commandLength++
		commands = append(commands, Command{
			Name: command,
			Cnt:  0,
			Avg:  0,
			Sum:  0,
		})
	}
}

func main() {
	flag.Parse()

	if !strings.Contains(*sortType, SORT_TYPE_BY_MAX) && !strings.Contains(*sortType, SORT_TYPE_BY_AVG) && !strings.Contains(*sortType, SORT_TYPE_BY_CNT) {
		log.Fatal("Please set sort type max, avg or cnt")
	}

	if *filePath != "" {
		rf, err := os.Open(*filePath)
		if err != nil {
			log.Fatal(err)
		}
		readFile = rf
		defer rf.Close()
	} else {
		readFile = os.Stdin
	}

	scanner := bufio.NewScanner(readFile)
	var beforeLine Line

	for scanner.Scan() {
		group := lineRegexp.FindStringSubmatch(scanner.Text())
		if 1 > len(group) {
			continue
		}

		epoch, err := strconv.ParseFloat(group[1], 64)
		if err != nil {
			log.Println(err)
			continue
		}
		db, err := strconv.Atoi(group[2])
		if err != nil {
			log.Println(err)
			continue
		}

		line := Line{
			Epoch:   epoch,
			Db:      db,
			Command: group[3],
			Key:     group[5],
			Args:    group[6],
		}

		var commandTime float64
		if beforeLine.Command != "" {
			commandTime = line.Epoch - beforeLine.Epoch
		} else {
			commandTime = 0
		}

		SetProfileIndex(fmt.Sprintf("%s %s", line.Command, line.Key))
		SetCommandIndex(line.Command)

		if monitorLogs[logCursor].Max < commandTime {
			monitorLogs[logCursor].Max = commandTime
		}

		if commandTime < monitorLogs[logCursor].Min {
			monitorLogs[logCursor].Min = commandTime
		}
		monitorLogs[logCursor].Cnt++
		monitorLogs[logCursor].Sum = monitorLogs[logCursor].Sum + commandTime
		monitorLogs[logCursor].Avg = monitorLogs[logCursor].Sum / float64(monitorLogs[logCursor].Cnt)

		commands[commandCursor].Cnt++
		commands[commandCursor].Sum = commands[commandCursor].Sum + commandTime

		beforeLine = line
		lineCount++
	}

	PrintResult()
}

func PrintTitle(key string) {
	fmt.Println(key)
	fmt.Println("==================================")
}

func PrintResult() {
	PrintTitle("Overall Stats")
	fmt.Printf("LineCount \t %d \n\n", lineCount)
	fmt.Printf("\n")

	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 0, 8, 0, '\t', tabwriter.AlignRight)
	PrintTitle("Commands Rate")
	sort.Sort(sort.Reverse((ByCommand{commands})))
	for _, v := range commands {
		fmt.Fprintf(w, "%s\t %d \n", v.Name, v.Cnt)
	}
	w.Flush()
	fmt.Printf("\n")

	PrintTitle("Heavy Commands")
	fmt.Fprintln(w, "Command \tSum(msec)")
	sort.Sort(sort.Reverse((ByHeavyCommand{commands})))
	for _, v := range commands {
		fmt.Fprintf(w, "%s \t %f \n", v.Name, v.Sum)
	}
	w.Flush()
	fmt.Printf("\n")

	PrintTitle("Slowest Calls")
	if strings.Contains(*sortType, SORT_TYPE_BY_AVG) {
		sort.Sort(sort.Reverse((ByAvg{monitorLogs})))
	} else if strings.Contains(*sortType, SORT_TYPE_BY_CNT) {
		sort.Sort(sort.Reverse((ByCnt{monitorLogs})))
	} else {
		sort.Sort(sort.Reverse((ByMax{monitorLogs})))
	}

	fmt.Fprintln(w, "KEY \tCount \tMax(msec) \t Avg(msec)")
	for i, v := range monitorLogs {
		if *listNum < i {
			break
		}
		fmt.Fprintf(w, "%s\t %d \t %f\t %f\n", v.Call, v.Cnt, v.Max, v.Avg)
	}
	w.Flush()
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"

	"github.com/go-martini/martini"
	"github.com/jijeshmohan/mtgrid/config"
	"github.com/jijeshmohan/mtgrid/middleware"
	"github.com/jijeshmohan/mtgrid/models"
	"github.com/jijeshmohan/mtgrid/routes"
	"github.com/martini-contrib/render"
)

var (
	m *martini.ClassicMartini
	c *config.Config
)

func startServer() {
	m = martini.Classic()
	m.Use(render.Renderer(render.Options{
		Layout:    "layout",
		Directory: "views",
	}))

	if _, err := models.InitDb(c); err != nil {
		log.Fatalln("Error :", err)
	}

	m.Use(middleware.InitContext())
	routes.InitRoutes(m)

	log.Println("Starting server at ", c.Addr)
	http.ListenAndServe(c.Addr, m)
}

func main() {
	c = config.New()
	if err := c.LoadFile("app.conf"); err != nil {
		log.Fatalln("Error :", err)
	}
	if err := c.LoadEnv(); err != nil {
		log.Fatalln("Error :", err)
	}

	startServer()
}
<commit_msg>added mux route<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

var (
	host = flag.String("h", "", "Host name")
	port = flag.String("p", "8080", "port number")
)

func main() {
	flag.Parse()
	address := fmt.Sprintf("%s:%s", *host, *port)
	r := mux.NewRouter()

	// non REST routes
	r.PathPrefix("/").Handler(http.FileServer(http.Dir("static/")))
	log.Println("Running on " + address)
	http.ListenAndServe(address, r)
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"regexp"
	"strconv"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/julienschmidt/httprouter"
)

var db *sql.DB
var err error

type UrlResponse struct {
	OriginalURL interface{} `json:"original_url"`
	ShortURL    interface{} `json:"short_url"`
}

type ErrorResponse struct {
	Error interface{} `json:"error"`
}

type Config struct {
	Database struct {
		User     string `json:"user"`
		Password string `json:"password"`
	} `json:"database"`
	Host string `json:"host"`
	Port string `json:"port"`
	Name string `json:"name"`
}

func main() {
	var config = loadConfig("config.json")
	databaseURI := os.Getenv("MYSQL_URL") //This is the config variable for Heroku

	db, err = sql.Open("mysql", databaseURI)
	check(err)
	defer db.Close()

	err = db.Ping()
	check(err)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	router := httprouter.New()
	router.GET("/new/*url", createURL)
	router.GET("/get/:id", getURL)
	router.GET("/", index)
	http.ListenAndServe(":"+port, router)
}

func loadConfig(file string) Config {
	var config Config
	configFile, err := os.Open(file)
	if err != nil {
		fmt.Println(err.Error())
	}
	jsonParser := json.NewDecoder(configFile)
	jsonParser.Decode(&config)
	configFile.Close()
	return config
}

func index(res http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	http.ServeFile(res, req, "./static/index.html")
}

func createURL(res http.ResponseWriter, req *http.Request, ps httprouter.Params) {

	var response = UrlResponse{}
	var shortUrl string
	var originalUrl string = ps.ByName("url")
	var newUrl string = strings.Replace(originalUrl, "/", "", 1) //This removes the first forward slash: '/'
	reg, _ := regexp.Compile(`^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?:!(?:10|127)(?:\.\d{1,3}){3})(?:!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?:!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$`)

	if reg.MatchString(newUrl) {
		err = db.QueryRow("SELECT original_url, short_url FROM urls WHERE original_url = ?", newUrl).Scan(&newUrl, &shortUrl)
		if err != nil {
			idNum := random(0, 9999)
			idStr := strconv.Itoa(idNum)
			check(err)
			shortUrl = "https://morning-retreat-24523.herokuapp.com/get/" + idStr
			_, err := db.Exec("INSERT INTO urls(id, original_url, short_url) VALUES(?, ?, ?)", idNum, newUrl, shortUrl)
			check(err)
			response = UrlResponse{OriginalURL: newUrl, ShortURL: shortUrl}
		} else {
			response = UrlResponse{OriginalURL: newUrl, ShortURL: shortUrl}
		}
		js, err := json.Marshal(response)
		check(err)
		res.Header().Set("Content-Type", "application/json")
		res.Write(js)
	} else {
		errorResponse := ErrorResponse{Error: "Sorry, wrong url format. Please make sure you have a valid protocol and real site."}
		js, err := json.Marshal(errorResponse)
		check(err)
		res.Header().Set("Content-Type", "application/json")
		res.Write(js)
	}

}

func getURL(res http.ResponseWriter, req *http.Request, ps httprouter.Params) {

	var idStr string = ps.ByName("id")

	var idNum, err = strconv.Atoi(idStr)
	var originalUrl string
	err = db.QueryRow("SELECT original_url FROM urls WHERE id = ?", idNum).Scan(&originalUrl)
	check(err)

	http.Redirect(res, req, originalUrl, 301) //This needs to have a protocol, i.e. http or https
}

func random(min, max int) int {
	rand.Seed(time.Now().Unix())
	return rand.Intn(max-min) + min
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}
<commit_msg>removed config variable<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"regexp"
	"strconv"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/julienschmidt/httprouter"
)

var db *sql.DB
var err error

type UrlResponse struct {
	OriginalURL interface{} `json:"original_url"`
	ShortURL    interface{} `json:"short_url"`
}

type ErrorResponse struct {
	Error interface{} `json:"error"`
}

type Config struct {
	Database struct {
		User     string `json:"user"`
		Password string `json:"password"`
	} `json:"database"`
	Host string `json:"host"`
	Port string `json:"port"`
	Name string `json:"name"`
}

func main() {
	databaseURI := os.Getenv("MYSQL_URL") //This is the config variable for Heroku

	db, err = sql.Open("mysql", databaseURI)
	check(err)
	defer db.Close()

	err = db.Ping()
	check(err)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	router := httprouter.New()
	router.GET("/new/*url", createURL)
	router.GET("/get/:id", getURL)
	router.GET("/", index)
	http.ListenAndServe(":"+port, router)
}

func loadConfig(file string) Config {
	var config Config
	configFile, err := os.Open(file)
	if err != nil {
		fmt.Println(err.Error())
	}
	jsonParser := json.NewDecoder(configFile)
	jsonParser.Decode(&config)
	configFile.Close()
	return config
}

func index(res http.ResponseWriter, req *http.Request, _ httprouter.Params) {
	http.ServeFile(res, req, "./static/index.html")
}

func createURL(res http.ResponseWriter, req *http.Request, ps httprouter.Params) {

	var response = UrlResponse{}
	var shortUrl string
	var originalUrl string = ps.ByName("url")
	var newUrl string = strings.Replace(originalUrl, "/", "", 1) //This removes the first forward slash: '/'
	reg, _ := regexp.Compile(`^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?:!(?:10|127)(?:\.\d{1,3}){3})(?:!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?:!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$`)

	if reg.MatchString(newUrl) {
		err = db.QueryRow("SELECT original_url, short_url FROM urls WHERE original_url = ?", newUrl).Scan(&newUrl, &shortUrl)
		if err != nil {
			idNum := random(0, 9999)
			idStr := strconv.Itoa(idNum)
			check(err)
			shortUrl = "https://morning-retreat-24523.herokuapp.com/get/" + idStr
			_, err := db.Exec("INSERT INTO urls(id, original_url, short_url) VALUES(?, ?, ?)", idNum, newUrl, shortUrl)
			check(err)
			response = UrlResponse{OriginalURL: newUrl, ShortURL: shortUrl}
		} else {
			response = UrlResponse{OriginalURL: newUrl, ShortURL: shortUrl}
		}
		js, err := json.Marshal(response)
		check(err)
		res.Header().Set("Content-Type", "application/json")
		res.Write(js)
	} else {
		errorResponse := ErrorResponse{Error: "Sorry, wrong url format. Please make sure you have a valid protocol and real site."}
		js, err := json.Marshal(errorResponse)
		check(err)
		res.Header().Set("Content-Type", "application/json")
		res.Write(js)
	}

}

func getURL(res http.ResponseWriter, req *http.Request, ps httprouter.Params) {

	var idStr string = ps.ByName("id")

	var idNum, err = strconv.Atoi(idStr)
	var originalUrl string
	err = db.QueryRow("SELECT original_url FROM urls WHERE id = ?", idNum).Scan(&originalUrl)
	check(err)

	http.Redirect(res, req, originalUrl, 301) //This needs to have a protocol, i.e. http or https
}

func random(min, max int) int {
	rand.Seed(time.Now().Unix())
	return rand.Intn(max-min) + min
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// 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 (
	"log"

	"github.com/venicegeo/pz-gocommon/elasticsearch"
	piazza "github.com/venicegeo/pz-gocommon/gocommon"
	pzsyslog "github.com/venicegeo/pz-gocommon/syslog"
	pzuuidgen "github.com/venicegeo/pz-uuidgen/uuidgen"
	pzworkflow "github.com/venicegeo/pz-workflow/workflow"
)

func main() {
	sys, logger, uuidgen := makeSystem()

	log.Printf("pz-workflow starting...")

	indices := makeIndexes(sys)

	workflowServer := makeWorkflow(sys, indices, logger, uuidgen)

	serverLoop(sys, workflowServer)
}

func makeWorkflow(sys *piazza.SystemConfig,
	indices []*elasticsearch.Index,
	logger *pzsyslog.Logger,
	uuidgen pzuuidgen.IClient) *pzworkflow.Server {
	workflowService := &pzworkflow.Service{}
	err := workflowService.Init(
		sys,
		logger,
		uuidgen,
		indices[0],
		indices[1],
		indices[2],
		indices[3],
		indices[4],
		indices[5])
	if err != nil {
		log.Fatal(err)
	}

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

	workflowServer := &pzworkflow.Server{}
	err = workflowServer.Init(workflowService)
	if err != nil {
		log.Fatal(err)
	}

	return workflowServer
}

func makeSystem() (
	*piazza.SystemConfig,
	*pzsyslog.Logger,
	*pzuuidgen.Client) {

	required := []piazza.ServiceName{
		piazza.PzElasticSearch,
		piazza.PzLogger,
		piazza.PzUuidgen,
		piazza.PzKafka,
		piazza.PzServiceController,
		piazza.PzIdam,
	}

	sys, err := piazza.NewSystemConfig(piazza.PzWorkflow, required)
	if err != nil {
		log.Fatal(err)
	}

	logUrl, err := sys.GetURL(piazza.PzLogger)
	if err != nil {
		log.Fatal(err)
	}
	logWriter, err := pzsyslog.NewHttpWriter(logUrl)
	if err != nil {
		log.Fatal(err)
	}
	//logWriter := &pzsyslog.NilWriter{}
	logger := pzsyslog.NewLogger(logWriter, "pz-uuidgen")

	uuidgen, err := pzuuidgen.NewClient(sys)
	if err != nil {
		log.Fatal(err)
	}

	return sys, logger, uuidgen
}

func serverLoop(sys *piazza.SystemConfig,
	workflowServer *pzworkflow.Server) {
	genericServer := piazza.GenericServer{Sys: sys}

	err := genericServer.Configure(workflowServer.Routes)
	if err != nil {
		log.Fatal(err)
	}

	done, err := genericServer.Start()
	if err != nil {
		log.Fatal(err)
	}

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

func makeIndexes(sys *piazza.SystemConfig) []*elasticsearch.Index {
	eventtypesIndex, err := elasticsearch.NewIndex(sys, "eventtypes003", pzworkflow.EventTypeIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	eventsIndex, err := elasticsearch.NewIndex(sys, "events004", pzworkflow.EventIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	triggersIndex, err := elasticsearch.NewIndex(sys, "triggers003", pzworkflow.TriggerIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	alertsIndex, err := elasticsearch.NewIndex(sys, "alerts003", pzworkflow.AlertIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	cronIndex, err := elasticsearch.NewIndex(sys, "crons003", pzworkflow.CronIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	testElasticsearchIndex, err := elasticsearch.NewIndex(sys, "testelasticsearch003", pzworkflow.TestElasticsearchSettings)
	if err != nil {
		log.Fatal(err)
	}

	ret := []*elasticsearch.Index{
		eventtypesIndex, eventsIndex, triggersIndex,
		alertsIndex, cronIndex, testElasticsearchIndex,
	}
	return ret
}
<commit_msg>umm, yeah<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// 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 (
	"log"

	"github.com/venicegeo/pz-gocommon/elasticsearch"
	piazza "github.com/venicegeo/pz-gocommon/gocommon"
	pzsyslog "github.com/venicegeo/pz-gocommon/syslog"
	pzuuidgen "github.com/venicegeo/pz-uuidgen/uuidgen"
	pzworkflow "github.com/venicegeo/pz-workflow/workflow"
)

func main() {
	sys, logger, uuidgen := makeSystem()

	log.Printf("pz-workflow starting...")

	indices := makeIndexes(sys)

	workflowServer := makeWorkflow(sys, indices, logger, uuidgen)

	serverLoop(sys, workflowServer)
}

func makeWorkflow(sys *piazza.SystemConfig,
	indices []*elasticsearch.Index,
	logger *pzsyslog.Logger,
	uuidgen pzuuidgen.IClient) *pzworkflow.Server {
	workflowService := &pzworkflow.Service{}
	err := workflowService.Init(
		sys,
		logger,
		uuidgen,
		indices[0],
		indices[1],
		indices[2],
		indices[3],
		indices[4],
		indices[5])
	if err != nil {
		log.Fatal(err)
	}

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

	workflowServer := &pzworkflow.Server{}
	err = workflowServer.Init(workflowService)
	if err != nil {
		log.Fatal(err)
	}

	return workflowServer
}

func makeSystem() (
	*piazza.SystemConfig,
	*pzsyslog.Logger,
	*pzuuidgen.Client) {

	required := []piazza.ServiceName{
		piazza.PzElasticSearch,
		piazza.PzLogger,
		piazza.PzUuidgen,
		piazza.PzKafka,
		piazza.PzServiceController,
		piazza.PzIdam,
	}

	sys, err := piazza.NewSystemConfig(piazza.PzWorkflow, required)
	if err != nil {
		log.Fatal(err)
	}

	logUrl, err := sys.GetURL(piazza.PzLogger)
	if err != nil {
		log.Fatal(err)
	}
	logWriter, err := pzsyslog.NewHttpWriter(logUrl)
	if err != nil {
		log.Fatal(err)
	}
	//logWriter := &pzsyslog.NilWriter{}
	logger := pzsyslog.NewLogger(logWriter, "pz-workflow")

	uuidgen, err := pzuuidgen.NewClient(sys)
	if err != nil {
		log.Fatal(err)
	}

	return sys, logger, uuidgen
}

func serverLoop(sys *piazza.SystemConfig,
	workflowServer *pzworkflow.Server) {
	genericServer := piazza.GenericServer{Sys: sys}

	err := genericServer.Configure(workflowServer.Routes)
	if err != nil {
		log.Fatal(err)
	}

	done, err := genericServer.Start()
	if err != nil {
		log.Fatal(err)
	}

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

func makeIndexes(sys *piazza.SystemConfig) []*elasticsearch.Index {
	eventtypesIndex, err := elasticsearch.NewIndex(sys, "eventtypes003", pzworkflow.EventTypeIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	eventsIndex, err := elasticsearch.NewIndex(sys, "events004", pzworkflow.EventIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	triggersIndex, err := elasticsearch.NewIndex(sys, "triggers003", pzworkflow.TriggerIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	alertsIndex, err := elasticsearch.NewIndex(sys, "alerts003", pzworkflow.AlertIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	cronIndex, err := elasticsearch.NewIndex(sys, "crons003", pzworkflow.CronIndexSettings)
	if err != nil {
		log.Fatal(err)
	}
	testElasticsearchIndex, err := elasticsearch.NewIndex(sys, "testelasticsearch003", pzworkflow.TestElasticsearchSettings)
	if err != nil {
		log.Fatal(err)
	}

	ret := []*elasticsearch.Index{
		eventtypesIndex, eventsIndex, triggersIndex,
		alertsIndex, cronIndex, testElasticsearchIndex,
	}
	return ret
}
<|endoftext|>


<commit_before>// This is the boot2docker management utilty.
package main

import (
	"flag"
	"log"
	"os"
	"path/filepath"
	"strconv"
)

// B2D reprents boot2docker config.
var B2D struct {
	VBM        string // VirtualBox management utility
	SSH        string // SSH client executable
	VM         string // virtual machine name
	Dir        string // boot2docker directory
	ISO        string // boot2docker ISO image path
	Disk       string // VM disk image path
	DiskSize   int    // VM disk image size (MB)
	Memory     int    // VM memory size (MB)
	SSHPort    int    // host SSH port (forward to port 22 in VM)
	DockerPort int    // host Docker port (forward to port 4243 in VM)
}

func init() {
	if getenv("HOME", "") == "" {
		log.Fatalf("$HOME is not set") // TODO workaround for Windows
	}
	B2D.VBM = getenv("BOOT2DOCKER_VBM", "VBoxManage")
	B2D.SSH = getenv("BOOT2DOCKER_SSH", "ssh")
	B2D.VM = getenv("BOOT2DOCKER_VM", "boot2docker-vm")
	B2D.Dir = getenv("BOOT2DOCKER_DIR", filepath.Join(getenv("HOME", ""), ".boot2docker"))
	B2D.ISO = getenv("BOOT2DOCKER_ISO", filepath.Join(B2D.Dir, "boot2docker.iso"))
	B2D.Disk = getenv("BOOT2DOCKER_DISK", filepath.Join(B2D.Dir, "boot2docker.vmdk"))

	var err error
	if B2D.DiskSize, err = strconv.Atoi(getenv("BOOT2DOCKER_DISKSIZE", "20000")); err != nil {
		log.Fatalf("Invalid BOOT2DOCKER_DISKSIZE: %s", err)
	}
	if B2D.DiskSize <= 0 {
		log.Fatalf("BOOT2DOCKER_DISKSIZE way too small.")
	}
	if B2D.Memory, err = strconv.Atoi(getenv("BOOT2DOCKER_MEMORY", "1024")); err != nil {
		log.Fatalf("Invalid BOOT2DOCKER_MEMORY: %s", err)
	}
	if B2D.Memory <= 0 {
		log.Fatalf("BOOT2DOCKER_MEMORY way too small.")
	}
	if B2D.SSHPort, err = strconv.Atoi(getenv("BOOT2DOCKER_SSH_PORT", "2022")); err != nil {
		log.Fatalf("Invalid BOOT2DOCKER_SSH_PORT: %s", err)
	}
	if B2D.SSHPort <= 0 {
		log.Fatalf("Invalid BOOT2DOCKER_SSH_PORT: must be in the range of 1--65535: got %d", B2D.SSHPort)
	}
	if B2D.DockerPort, err = strconv.Atoi(getenv("BOOT2DOCKER_DOCKER_PORT", "4243")); err != nil {
		log.Fatalf("Invalid BOOT2DOCKER_DOCKER_PORT: %s", err)
	}
	if B2D.DockerPort <= 0 {
		log.Fatalf("Invalid BOOT2DOCKER_DOCKER_PORT: must be in the range of 1--65535: got %d", B2D.DockerPort)
	}

	// TODO maybe allow flags to override ENV vars?
	flag.Parse()
}

func main() {
	if vm := flag.Arg(1); vm != "" {
		B2D.VM = vm
	}

	// TODO maybe use reflect here?
	switch flag.Arg(0) { // choose subcommand
	case "download":
		cmdDownload()
	case "init":
		cmdInit()
	case "start", "up", "boot", "resume":
		cmdStart()
	case "ssh":
		cmdSSH()
	case "save", "suspend":
		cmdSave()
	case "pause":
		cmdPause()
	case "halt", "down", "stop":
		cmdStop()
	case "poweroff":
		cmdPoweroff()
	case "restart":
		cmdRestart()
	case "reset":
		cmdReset()
	case "info":
		cmdInfo()
	case "status":
		cmdStatus()
	case "delete":
		cmdDelete()
	default:
		log.Fatalf("Usage: %s {init|start|up|ssh|save|pause|stop|poweroff|reset|restart|status|info|delete|download} [vm]", os.Args[0])
	}
}
<commit_msg>Guess the correct config directory on *nix and Windows.<commit_after>// This is the boot2docker management utilty.
package main

import (
	"flag"
	"log"
	"os"
	"path/filepath"
	"strconv"
)

// B2D reprents boot2docker config.
var B2D struct {
	VBM        string // VirtualBox management utility
	SSH        string // SSH client executable
	VM         string // virtual machine name
	Dir        string // boot2docker directory
	ISO        string // boot2docker ISO image path
	Disk       string // VM disk image path
	DiskSize   int    // VM disk image size (MB)
	Memory     int    // VM memory size (MB)
	SSHPort    int    // host SSH port (forward to port 22 in VM)
	DockerPort int    // host Docker port (forward to port 4243 in VM)
}

func getCfgDir(name string) string {
	if b2dDir := os.Getenv("BOOT2DOCKER_DIR"); b2dDir != "" {
		return b2dDir
	}

	// unix
	if home := os.Getenv("HOME"); home != "" {
		return filepath.Join(home, name)
	}

	// windows
	for _, env := range []string{
		"APPDATA",
		"LOCALAPPDATA",
		"USERPROFILE", // let's try USERPROFILE only as a very last resort
	} {
		if val := os.Getenv(env); val != "" {
			return filepath.Join(val, "boot2docker")
		}
	}
	// ok, we've tried everything reasonable - now let's go for CWD
	cwd, err := os.Getwd()
	if err != nil {
		log.Fatalf("error getting current directory: %v\n", err)
	}
	return filepath.Join(cwd, name)
}

func init() {
	B2D.VBM = getenv("BOOT2DOCKER_VBM", "VBoxManage")
	B2D.SSH = getenv("BOOT2DOCKER_SSH", "ssh")
	B2D.VM = getenv("BOOT2DOCKER_VM", "boot2docker-vm")
	B2D.Dir = getCfgDir(".boot2docker")
	B2D.ISO = getenv("BOOT2DOCKER_ISO", filepath.Join(B2D.Dir, "boot2docker.iso"))
	B2D.Disk = getenv("BOOT2DOCKER_DISK", filepath.Join(B2D.Dir, "boot2docker.vmdk"))

	var err error
	if B2D.DiskSize, err = strconv.Atoi(getenv("BOOT2DOCKER_DISKSIZE", "20000")); err != nil {
		log.Fatalf("Invalid BOOT2DOCKER_DISKSIZE: %s", err)
	}
	if B2D.DiskSize <= 0 {
		log.Fatalf("BOOT2DOCKER_DISKSIZE way too small.")
	}
	if B2D.Memory, err = strconv.Atoi(getenv("BOOT2DOCKER_MEMORY", "1024")); err != nil {
		log.Fatalf("Invalid BOOT2DOCKER_MEMORY: %s", err)
	}
	if B2D.Memory <= 0 {
		log.Fatalf("BOOT2DOCKER_MEMORY way too small.")
	}
	if B2D.SSHPort, err = strconv.Atoi(getenv("BOOT2DOCKER_SSH_PORT", "2022")); err != nil {
		log.Fatalf("Invalid BOOT2DOCKER_SSH_PORT: %s", err)
	}
	if B2D.SSHPort <= 0 {
		log.Fatalf("Invalid BOOT2DOCKER_SSH_PORT: must be in the range of 1--65535: got %d", B2D.SSHPort)
	}
	if B2D.DockerPort, err = strconv.Atoi(getenv("BOOT2DOCKER_DOCKER_PORT", "4243")); err != nil {
		log.Fatalf("Invalid BOOT2DOCKER_DOCKER_PORT: %s", err)
	}
	if B2D.DockerPort <= 0 {
		log.Fatalf("Invalid BOOT2DOCKER_DOCKER_PORT: must be in the range of 1--65535: got %d", B2D.DockerPort)
	}

	// TODO maybe allow flags to override ENV vars?
	flag.Parse()
}

func main() {
	if vm := flag.Arg(1); vm != "" {
		B2D.VM = vm
	}

	// TODO maybe use reflect here?
	switch flag.Arg(0) { // choose subcommand
	case "download":
		cmdDownload()
	case "init":
		cmdInit()
	case "start", "up", "boot", "resume":
		cmdStart()
	case "ssh":
		cmdSSH()
	case "save", "suspend":
		cmdSave()
	case "pause":
		cmdPause()
	case "halt", "down", "stop":
		cmdStop()
	case "poweroff":
		cmdPoweroff()
	case "restart":
		cmdRestart()
	case "reset":
		cmdReset()
	case "info":
		cmdInfo()
	case "status":
		cmdStatus()
	case "delete":
		cmdDelete()
	default:
		log.Fatalf("Usage: %s {init|start|up|ssh|save|pause|stop|poweroff|reset|restart|status|info|delete|download} [vm]", os.Args[0])
	}
}
<|endoftext|>


<commit_before>package main

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

	"github.com/lair-framework/api-server/client"
	"github.com/lair-framework/go-lair"
	"github.com/mattburch/go-nikto"
)

const (
	version = "2.0.1"
	tool    = "nikto"
	usage   = `
Usage:
  drone-nikto <id> <filename>
  export LAIR_ID=<id>; drone-nikto <filename>
Options:
  -v              show version and exit
  -h              show usage and exit
  -k              allow insecure SSL connections
  -force-ports    disable data protection in the API server for excessive ports
  -tags           a comma separated list of tags to add to every host that is imported
`
)

func buildProject(nikto *nikto.NiktoData, exproject *lair.Project, tags []string) (map[string]bool, error) {
	bNotFound := make(map[string]bool)
	exproject.Tool = tool
	var command string

	for _, scan := range nikto.NiktoScan {
		for _, item := range scan.ScanDetails {
			command = scan.Options

			// Confirm if Host and Port existing in current project
			found := false
			hname := false
			for x, h := range exproject.Hosts {
				if item.TargetIP == h.IPv4 {
					for y, p := range h.Services {
						if item.TargetPort == p.Port {
							found = true

							// Append host tags
							exproject.Hosts[x].Tags = append(h.Tags, tags...)

							// Update Modified By
							h.LastModifiedBy = tool
							p.LastModifiedBy = tool

							// Append Note information to Service
							note := &lair.Note{
								Title:          fmt.Sprintf("Nikto v%v (%v:%v)", scan.Version, item.HostHeader, item.TargetPort),
								LastModifiedBy: tool,
							}

							scheme, err := url.Parse(item.TargetHostname)
							if err != nil {
								return bNotFound, err
							}
							if scheme.Scheme == "https" {
								note.Content = fmt.Sprintf("SSL Information:\nSubject: %v\nCiphers: %v\nIssuer: %v\n\n", item.SSL.Info, item.SSL.Ciphers, item.SSL.Issuers)
							}

							for _, item := range item.Items {
								if item.OSVDBID > 0 {
									note.Content += fmt.Sprintf("%v URI: %v OSVDBID: %v\n", item.Description, item.URI, item.OSVDBID)
								} else {
									note.Content += fmt.Sprintf("%v URI: %v\n", item.Description, item.URI)
								}
							}
							note.Content += fmt.Sprintf("\nStart: %s End: %s", scan.ScanStart, scan.ScanEnd)
							exproject.Hosts[x].Services[y].Notes = append(p.Notes, *note)
						}
					}
					// Check for existing hostname and append
					for _, n := range h.Hostnames {
						if n == item.TargetHostname {
							hname = true
						}
					}
					if !hname && (item.TargetHostname != item.TargetIP) {
						exproject.Hosts[x].Hostnames = append(h.Hostnames, item.TargetHostname)
					}
				}
			}
			if !found {
				bNotFound[fmt.Sprintf("%s (%s:%v)", item.TargetHostname, item.TargetIP, item.TargetPort)] = true
				continue
			}
		}
	}
	// Update project with Nikto command
	var com []lair.Command
	com = append(com, lair.Command{
		Tool:    tool,
		Command: command,
	})
	exproject.Commands = com

	return bNotFound, nil
}

func main() {
	showVersion := flag.Bool("v", false, "")
	insecureSSL := flag.Bool("k", false, "")
	forcePorts := flag.Bool("force-ports", false, "")
	tags := flag.String("tags", "", "")
	flag.Usage = func() {
		fmt.Println(usage)
	}
	flag.Parse()
	if *showVersion {
		log.Println(version)
		os.Exit(0)
	}
	lairURL := os.Getenv("LAIR_API_SERVER")
	if lairURL == "" {
		log.Fatal("Fatal: Missing LAIR_API_SERVER environment variable")
	}
	lairPID := os.Getenv("LAIR_ID")
	var filename string
	switch len(flag.Args()) {
	case 2:
		lairPID = flag.Arg(0)
		filename = flag.Arg(1)
	case 1:
		filename = flag.Arg(0)
	default:
		log.Fatal("Fatal: Missing required argument")
	}

	u, err := url.Parse(lairURL)
	if err != nil {
		log.Fatalf("Fatal: Error parsing LAIR_API_SERVER URL. Error %s", err.Error())
	}
	if u.User == nil {
		log.Fatal("Fatal: Missing username and/or password")
	}
	user := u.User.Username()
	pass, _ := u.User.Password()
	if user == "" || pass == "" {
		log.Fatal("Fatal: Missing username and/or password")
	}
	c, err := client.New(&client.COptions{
		User:               user,
		Password:           pass,
		Host:               u.Host,
		Scheme:             u.Scheme,
		InsecureSkipVerify: *insecureSSL,
	})
	if err != nil {
		log.Fatalf("Fatal: Error setting up client. Error %s", err.Error())
	}

	buf, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Fatalf("Fatal: Could not open file. Error %s", err.Error())
	}

	niktoData, err := nikto.Parse(buf)
	if err != nil {
		log.Fatalf("Fatal: Error parsing nikto data. Error %s", err.Error())
	}

	hostTags := []string{}
	if *tags != "" {
		hostTags = strings.Split(*tags, ",")
	}

	project, err := c.ExportProject(lairPID)
	if err != nil {
		log.Fatalf("Fatal: Unable to export project. Error %s", err.Error())
	}
	bNotFound, err := buildProject(niktoData, &project, hostTags)
	if err != nil {
		log.Fatal(err.Error())
	}

	res, err := c.ImportProject(&client.DOptions{ForcePorts: *forcePorts}, &project)
	if err != nil {
		log.Fatalf("Fatal: Unable to import project. Error %s", err)
	}

	defer res.Body.Close()
	droneRes := &client.Response{}
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatalf("Fatal: Error %s", err.Error())
	}
	if err := json.Unmarshal(body, droneRes); err != nil {
		log.Fatalf("Fatal: Could not unmarshal JSON. Error %s", err.Error())
	}
	if droneRes.Status == "Error" {
		log.Fatalf("Fatal: Import failed. Error %s", droneRes.Message)
	}

	if len(bNotFound) > 0 {
		log.Printf("Info: The following host ports contained Nikto results but did not exist in project %s", lairPID)
	}
	for k := range bNotFound {
		fmt.Println(k)
	}

	log.Println("Success: Operation completed successfully")
}
<commit_msg>Correct Imports<commit_after>package main

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

	"github.com/lair-framework/api-server/client"
	"github.com/lair-framework/go-lair"
	"github.com/lair-framework/go-nikto"
)

const (
	version = "2.0.1"
	tool    = "nikto"
	usage   = `
Usage:
  drone-nikto <id> <filename>
  export LAIR_ID=<id>; drone-nikto <filename>
Options:
  -v              show version and exit
  -h              show usage and exit
  -k              allow insecure SSL connections
  -force-ports    disable data protection in the API server for excessive ports
  -tags           a comma separated list of tags to add to every host that is imported
`
)

func buildProject(nikto *nikto.NiktoData, exproject *lair.Project, tags []string) (map[string]bool, error) {
	bNotFound := make(map[string]bool)
	exproject.Tool = tool
	var command string

	for _, scan := range nikto.NiktoScan {
		for _, item := range scan.ScanDetails {
			command = scan.Options

			// Confirm if Host and Port existing in current project
			found := false
			hname := false
			for x, h := range exproject.Hosts {
				if item.TargetIP == h.IPv4 {
					for y, p := range h.Services {
						if item.TargetPort == p.Port {
							found = true

							// Append host tags
							exproject.Hosts[x].Tags = append(h.Tags, tags...)

							// Update Modified By
							h.LastModifiedBy = tool
							p.LastModifiedBy = tool

							// Append Note information to Service
							note := &lair.Note{
								Title:          fmt.Sprintf("Nikto v%v (%v:%v)", scan.Version, item.HostHeader, item.TargetPort),
								LastModifiedBy: tool,
							}

							scheme, err := url.Parse(item.TargetHostname)
							if err != nil {
								return bNotFound, err
							}
							if scheme.Scheme == "https" {
								note.Content = fmt.Sprintf("SSL Information:\nSubject: %v\nCiphers: %v\nIssuer: %v\n\n", item.SSL.Info, item.SSL.Ciphers, item.SSL.Issuers)
							}

							for _, item := range item.Items {
								if item.OSVDBID > 0 {
									note.Content += fmt.Sprintf("%v URI: %v OSVDBID: %v\n", item.Description, item.URI, item.OSVDBID)
								} else {
									note.Content += fmt.Sprintf("%v URI: %v\n", item.Description, item.URI)
								}
							}
							note.Content += fmt.Sprintf("\nStart: %s End: %s", scan.ScanStart, scan.ScanEnd)
							exproject.Hosts[x].Services[y].Notes = append(p.Notes, *note)
						}
					}
					// Check for existing hostname and append
					for _, n := range h.Hostnames {
						if n == item.TargetHostname {
							hname = true
						}
					}
					if !hname && (item.TargetHostname != item.TargetIP) {
						exproject.Hosts[x].Hostnames = append(h.Hostnames, item.TargetHostname)
					}
				}
			}
			if !found {
				bNotFound[fmt.Sprintf("%s (%s:%v)", item.TargetHostname, item.TargetIP, item.TargetPort)] = true
				continue
			}
		}
	}
	// Update project with Nikto command
	var com []lair.Command
	com = append(com, lair.Command{
		Tool:    tool,
		Command: command,
	})
	exproject.Commands = com

	return bNotFound, nil
}

func main() {
	showVersion := flag.Bool("v", false, "")
	insecureSSL := flag.Bool("k", false, "")
	forcePorts := flag.Bool("force-ports", false, "")
	tags := flag.String("tags", "", "")
	flag.Usage = func() {
		fmt.Println(usage)
	}
	flag.Parse()
	if *showVersion {
		log.Println(version)
		os.Exit(0)
	}
	lairURL := os.Getenv("LAIR_API_SERVER")
	if lairURL == "" {
		log.Fatal("Fatal: Missing LAIR_API_SERVER environment variable")
	}
	lairPID := os.Getenv("LAIR_ID")
	var filename string
	switch len(flag.Args()) {
	case 2:
		lairPID = flag.Arg(0)
		filename = flag.Arg(1)
	case 1:
		filename = flag.Arg(0)
	default:
		log.Fatal("Fatal: Missing required argument")
	}

	u, err := url.Parse(lairURL)
	if err != nil {
		log.Fatalf("Fatal: Error parsing LAIR_API_SERVER URL. Error %s", err.Error())
	}
	if u.User == nil {
		log.Fatal("Fatal: Missing username and/or password")
	}
	user := u.User.Username()
	pass, _ := u.User.Password()
	if user == "" || pass == "" {
		log.Fatal("Fatal: Missing username and/or password")
	}
	c, err := client.New(&client.COptions{
		User:               user,
		Password:           pass,
		Host:               u.Host,
		Scheme:             u.Scheme,
		InsecureSkipVerify: *insecureSSL,
	})
	if err != nil {
		log.Fatalf("Fatal: Error setting up client. Error %s", err.Error())
	}

	buf, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Fatalf("Fatal: Could not open file. Error %s", err.Error())
	}

	niktoData, err := nikto.Parse(buf)
	if err != nil {
		log.Fatalf("Fatal: Error parsing nikto data. Error %s", err.Error())
	}

	hostTags := []string{}
	if *tags != "" {
		hostTags = strings.Split(*tags, ",")
	}

	project, err := c.ExportProject(lairPID)
	if err != nil {
		log.Fatalf("Fatal: Unable to export project. Error %s", err.Error())
	}
	bNotFound, err := buildProject(niktoData, &project, hostTags)
	if err != nil {
		log.Fatal(err.Error())
	}

	res, err := c.ImportProject(&client.DOptions{ForcePorts: *forcePorts}, &project)
	if err != nil {
		log.Fatalf("Fatal: Unable to import project. Error %s", err)
	}

	defer res.Body.Close()
	droneRes := &client.Response{}
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatalf("Fatal: Error %s", err.Error())
	}
	if err := json.Unmarshal(body, droneRes); err != nil {
		log.Fatalf("Fatal: Could not unmarshal JSON. Error %s", err.Error())
	}
	if droneRes.Status == "Error" {
		log.Fatalf("Fatal: Import failed. Error %s", droneRes.Message)
	}

	if len(bNotFound) > 0 {
		log.Printf("Info: The following host ports contained Nikto results but did not exist in project %s", lairPID)
	}
	for k := range bNotFound {
		fmt.Println(k)
	}

	log.Println("Success: Operation completed successfully")
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"os"
	"syscall"

	"github.com/jaxxstorm/flexvolume"
	"github.com/kolyshkin/goploop-cli"
	"github.com/urfave/cli"
	"github.com/virtuozzo/ploop-flexvol/vstorage"
)

func main() {
	app := cli.NewApp()
	app.Name = "ploop flexvolume"
	app.Usage = "Mount ploop volumes in kubernetes using the flexvolume driver"
	app.Commands = flexvolume.Commands(Ploop{})
	app.CommandNotFound = flexvolume.CommandNotFound
	app.Authors = []cli.Author{
		cli.Author{
			Name: "Lee Briggs",
		},
		cli.Author{
			Name: "Virtuozzo",
		},
	}
	app.Version = "0.2a"
	app.Run(os.Args)
}

type Ploop struct{}

const WorkingDir = "/var/run/ploop-flexvol/"

func (p Ploop) Init() flexvolume.Response {
	return flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Ploop is available",
	}
}

func (p Ploop) path(options map[string]string) string {
	path := "/"
	if options["volumePath"] != "" {
		path += options["volumePath"] + "/"
	}
	path += options["volumeId"]
	return path
}

func (p Ploop) GetVolumeName(options map[string]string) flexvolume.Response {
	if options["volumeId"] == "" {
		return flexvolume.Response{
			Status:  flexvolume.StatusFailure,
			Message: "Must specify a volume id",
		}
	}

	return flexvolume.Response{
		Status:     flexvolume.StatusSuccess,
		VolumeName: options["volumeId"],
	}
}

func prepareVstorage(options map[string]string, mount string) error {
	mounted, _ := vstorage.IsVstorage(mount)
	if mounted {
		return nil
	}

	if options["kubernetes.io/secret/clusterPassword"] == "" {
		return errors.New("Please provide vstorage credentials")
	}

	// not mounted in proper place, prepare mount place and check other
	// mounts
	if err := os.MkdirAll(mount, 0755); err != nil {
		return err
	}

	v := vstorage.Vstorage{options["kubernetes.io/secret/clusterName"]}
	p, _ := v.Mountpoint()
	if p != "" {
		return syscall.Mount(p, mount, "", syscall.MS_BIND, "")
	}

	if err := v.Auth(options["kubernetes.io/secret/clusterPassword"]); err != nil {
		return err
	}
	if err := v.Mount(mount); err != nil {
		return err
	}

	return nil
}

func (p Ploop) Mount(target string, options map[string]string) flexvolume.Response {
	// make the target directory we're going to mount to
	err := os.MkdirAll(target, 0755)
	if err != nil {
		return flexvolume.Response{
			Status:  flexvolume.StatusFailure,
			Message: err.Error(),
		}
	}

	path := p.path(options)

	if options["kubernetes.io/secret/clusterName"] != "" {
		mount := WorkingDir + options["kubernetes.io/secret/clusterName"]
		if err := prepareVstorage(options, mount); err != nil {
			return flexvolume.Response{
				Status:  flexvolume.StatusFailure,
				Message: err.Error(),
			}
		}
		path = mount + path
	}
	// open the disk descriptor first
	volume, err := ploop.Open(path + "/" + "DiskDescriptor.xml")
	if err != nil {
		return flexvolume.Response{
			Status:  flexvolume.StatusFailure,
			Message: err.Error(),
		}
	}
	defer volume.Close()

	if m, _ := volume.IsMounted(); !m {
		// If it's mounted, let's mount it!

		readonly := false
		if options["kubernetes.io/readwrite"] == "ro" {
			readonly = true
		}

		mp := ploop.MountParam{Target: target, Readonly: readonly}

		dev, err := volume.Mount(&mp)
		if err != nil {
			return flexvolume.Response{
				Status:  flexvolume.StatusFailure,
				Message: err.Error(),
				Device:  dev,
			}
		}

		return flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Successfully mounted the ploop volume",
		}
	} else {

		return flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Ploop volume already mounted",
		}

	}
}

func (p Ploop) Unmount(mount string) flexvolume.Response {
	if err := ploop.UmountByMount(mount); err != nil {
		return flexvolume.Response{
			Status:  flexvolume.StatusFailure,
			Message: err.Error(),
		}
	}

	return flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully unmounted the ploop volume",
	}
}
<commit_msg>vstorage: don't forget to decode secretes<commit_after>package main

import (
	"encoding/base64"
	"errors"
	"os"
	"syscall"

	"github.com/jaxxstorm/flexvolume"
	"github.com/kolyshkin/goploop-cli"
	"github.com/urfave/cli"
	"github.com/virtuozzo/ploop-flexvol/vstorage"
)

func main() {
	app := cli.NewApp()
	app.Name = "ploop flexvolume"
	app.Usage = "Mount ploop volumes in kubernetes using the flexvolume driver"
	app.Commands = flexvolume.Commands(Ploop{})
	app.CommandNotFound = flexvolume.CommandNotFound
	app.Authors = []cli.Author{
		cli.Author{
			Name: "Lee Briggs",
		},
		cli.Author{
			Name: "Virtuozzo",
		},
	}
	app.Version = "0.2a"
	app.Run(os.Args)
}

type Ploop struct{}

const WorkingDir = "/var/run/ploop-flexvol/"

func (p Ploop) Init() flexvolume.Response {
	return flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Ploop is available",
	}
}

func (p Ploop) path(options map[string]string) string {
	path := "/"
	if options["volumePath"] != "" {
		path += options["volumePath"] + "/"
	}
	path += options["volumeId"]
	return path
}

func (p Ploop) GetVolumeName(options map[string]string) flexvolume.Response {
	if options["volumeId"] == "" {
		return flexvolume.Response{
			Status:  flexvolume.StatusFailure,
			Message: "Must specify a volume id",
		}
	}

	return flexvolume.Response{
		Status:     flexvolume.StatusSuccess,
		VolumeName: options["volumeId"],
	}
}

func prepareVstorage(clusterName, clusterPasswd string, mount string) error {
	mounted, _ := vstorage.IsVstorage(mount)
	if mounted {
		return nil
	}

	// not mounted in proper place, prepare mount place and check other
	// mounts
	if err := os.MkdirAll(mount, 0755); err != nil {
		return err
	}

	v := vstorage.Vstorage{clusterName}
	p, _ := v.Mountpoint()
	if p != "" {
		return syscall.Mount(p, mount, "", syscall.MS_BIND, "")
	}

	if clusterPasswd == "" {
		return errors.New("Please provide vstorage credentials")
	}

	if err := v.Auth(clusterPasswd); err != nil {
		return err
	}
	if err := v.Mount(mount); err != nil {
		return err
	}

	return nil
}

func (p Ploop) Mount(target string, options map[string]string) flexvolume.Response {
	// make the target directory we're going to mount to
	err := os.MkdirAll(target, 0755)
	if err != nil {
		return flexvolume.Response{
			Status:  flexvolume.StatusFailure,
			Message: err.Error(),
		}
	}

	path := p.path(options)

	if options["kubernetes.io/secret/clusterName"] != "" {
		_cluster, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterName"])
		if err != nil {
			return flexvolume.Response{
				Status:  flexvolume.StatusFailure,
				Message: fmt.Sprintf("Unable to decode a cluster name: %v", err.Error()),
			}
		}
		cluster := string(_cluster)

		_passwd, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterPassword"])
		if err != nil {
			return flexvolume.Response{
				Status:  flexvolume.StatusFailure,
				Message: fmt.Sprintf("Unable to decode a cluster password: %v", err.Error()),
			}
		}
		passwd := string(_passwd)

		mount := WorkingDir + cluster
		if err := prepareVstorage(cluster, passwd, mount); err != nil {
			return flexvolume.Response{
				Status:  flexvolume.StatusFailure,
				Message: err.Error(),
			}
		}
		path = mount + path
	}
	// open the disk descriptor first
	volume, err := ploop.Open(path + "/" + "DiskDescriptor.xml")
	if err != nil {
		return flexvolume.Response{
			Status:  flexvolume.StatusFailure,
			Message: err.Error(),
		}
	}
	defer volume.Close()

	if m, _ := volume.IsMounted(); !m {
		// If it's mounted, let's mount it!

		readonly := false
		if options["kubernetes.io/readwrite"] == "ro" {
			readonly = true
		}

		mp := ploop.MountParam{Target: target, Readonly: readonly}

		dev, err := volume.Mount(&mp)
		if err != nil {
			return flexvolume.Response{
				Status:  flexvolume.StatusFailure,
				Message: err.Error(),
				Device:  dev,
			}
		}

		return flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Successfully mounted the ploop volume",
		}
	} else {

		return flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Ploop volume already mounted",
		}

	}
}

func (p Ploop) Unmount(mount string) flexvolume.Response {
	if err := ploop.UmountByMount(mount); err != nil {
		return flexvolume.Response{
			Status:  flexvolume.StatusFailure,
			Message: err.Error(),
		}
	}

	return flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully unmounted the ploop volume",
	}
}
<|endoftext|>


<commit_before>package main

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

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ecs"
	"github.com/wpalmer/ecscron/schedule"
	"github.com/wpalmer/ecscron/schedule/crontab"
	"github.com/wpalmer/ecscron/schedule/retry"
	"github.com/wpalmer/ecscron/taskrunner"
	"github.com/wpalmer/ecscron/taskrunner/ecstaskrunner"
	"github.com/wpalmer/ecscron/taskrunner/tweak"
)

const (
	DEBUG_ERROR  = 0
	DEBUG_INFO   = 1
	DEBUG_DETAIL = 2
	DEBUG_STATUS = 5
)

type simulatedStatus struct {
	TaskName string
}

func main() {
	var async string
	var prevTick time.Time
	var nextTick time.Time
	var timezone string
	var cluster string
	var prefix string
	var suffix string
	var region string
	var filePath string
	var doRetry bool
	var retryCount int64
	var simulate bool
	var verbosity int

	var doDump bool
	var dumpFrom string
	var dumpFromTime time.Time
	var dumpUntil string
	var dumpUntilTime time.Time
	var dumpFormat string
	first := true

	flag.StringVar(&timezone, "timezone", "UTC", "The TimeZone in which to evaluate cron expressions")
	flag.StringVar(&async, "async", "", "The \"last run\" of cron (to resume after interruption) in YYYY-MM-DD HH:mm:ss format")
	flag.BoolVar(&doRetry, "retry", false, "When true, any failed run-task will be attempted again in the next iteration (same as -retry-count=-1)")
	flag.Int64Var(&retryCount, "retry-count", 0, "The number of times to retry a failed run-task before giving up (-1 means forever)")
	flag.StringVar(&cluster, "cluster", "", "The ECS Cluster on which to run tasks")
	flag.StringVar(&region, "region", "", "The AWS Region in which the ECS Cluster resides")
	flag.StringVar(&filePath, "crontab", "/etc/ecscrontab", "The location of the crontab file to parse")
	flag.StringVar(&prefix, "prefix", "", "An optional prefix to add to all ECS Task names within the crontab")
	flag.StringVar(&suffix, "suffix", "", "An optional suffix to add to all ECS Task names within the crontab")
	flag.BoolVar(&simulate, "simulate", false, "When true, don't actually run anything, only print what would be run")
	flag.IntVar(&verbosity, "debug", 0, "Debug level 0 = errors/warnings, 1 = run info, 2 = detail, 5 = status")

	flag.BoolVar(&doDump, "dump", false, "Rather than running the cron, output a summary of the schedule")
	flag.StringVar(&dumpFrom, "dump-from", "", "Output the schedule up starting from the specified time, in YYYY-MM-DD HH:mm:ss format")
	flag.StringVar(&dumpUntil, "dump-until", "", "Output the schedule up until the specified time, in YYYY-MM-DD HH:mm:ss format")
	flag.StringVar(&dumpFormat, "dump-format", "", "Output the schedule in the specified format. Currently the only supported format is 'json'")
	flag.Parse()

	location, err := time.LoadLocation(timezone)
	if err != nil {
		log.Fatalf("Failed to parse timzeone: %s", err)
	}

	if async != "" {
		prevTick, err = time.ParseInLocation("2006-01-02 15:04:05", async, location)
		if err != nil {
			log.Fatalf("Failed to parse time of last run: %s", err)
		}

		first = false
	}

	if doRetry && retryCount == int64(0) {
		retryCount = -1
	}

	file, err := os.Open(filePath)
	if err != nil {
		log.Fatalf("Error opening crontab: %s", err)
	}

	var sched schedule.Schedule
	table := crontab.NewCrontab()
	if ok, err := table.Load(file); !ok {
		log.Fatalf("Error loading crontab: %s", err)
	}
	sched = table

	if retryCount != 0 {
		numAttempts := retryCount
		if numAttempts > 0 {
			numAttempts += 1
		}

		sched = retry.NewRetrySchedule(sched, numAttempts)
	}

	var runner taskrunner.TaskRunner
	if simulate {
		runner = taskrunner.TaskRunnerFunc(func(task string) (*taskrunner.TaskStatus, error) {
			log.Printf("[-simulate] Running: %s", task)
			return &taskrunner.TaskStatus{Ran: true, Output: &simulatedStatus{TaskName: task}}, nil
		})
	} else {
		awsConfig := aws.NewConfig()
		if region != "" {
			awsConfig = awsConfig.WithRegion(region)
		}

		awsSession := session.Must(session.NewSession(awsConfig))
		ecsService := ecs.New(awsSession)

		runner = ecstaskrunner.NewEcsTaskRunner(ecsService, cluster)
	}

	if prefix != "" || suffix != "" {
		runner = tweak.NewTweakTaskRunner(runner, func(task string) string {
			return fmt.Sprintf("%s%s%s", prefix, task, suffix)
		})
	}

	if dumpFrom != "" {
		doDump = true
		dumpFromTime, err = time.ParseInLocation("2006-01-02 15:04:05", dumpFrom, location)
		if err != nil {
			log.Fatalf("Failed to parse time to dump from: %s", err)
		}
	} else {
		dumpFromTime = time.Now()
	}

	if dumpUntil != "" {
		doDump = true
		dumpUntilTime, err = time.ParseInLocation("2006-01-02 15:04:05", dumpUntil, location)
		if err != nil {
			log.Fatalf("Failed to parse time to dump until: %s", err)
		}
	} else {
		dumpUntilTime = dumpFromTime.Add(time.Hour * 24)
	}

	if dumpFormat == "" {
		dumpFormat = "json"
	} else {
		doDump = true
		if dumpFormat != "json" {
			log.Fatalf("Unknown dump format: %s", dumpFormat)
		}
	}

	if doDump {
		_, err := schedule.DumpJson(os.Stdout, sched, dumpFromTime.Add(-1), dumpUntilTime)
		if err != nil {
			log.Fatalf("Failed to dump schedule: %s", err)
		}

		fmt.Printf("\n")
		os.Exit(0)
	}

	if first {
		prevTick = time.Now().In(location)
	}

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

	ticks := make(chan time.Time, 1)

	for {
		nextTick = sched.Next(prevTick)
		pause := nextTick.Sub(time.Now().In(location))
		if pause < time.Duration(0) {
			log.Printf("Cron tasks running slowly: %0.2f seconds late entering tick scheduled for %v",
				(pause * time.Duration(-1)).Seconds(), nextTick)
			ticks <- nextTick
		} else {
			if verbosity >= DEBUG_STATUS {
				log.Printf("Sleeping for %0.2f seconds", pause.Seconds())
			}
			go func() {
				time.Sleep(pause)
				ticks <- nextTick
			}()
		}

		ticked := false
		for ticked == false {
			select {
			case <-ticks:
				ticked = true
			case <-signals:
				log.Printf("Received SIGUSR1, pausing...")
				<-signals
				log.Printf("Received SIGUSR1 while paused, resuming...")
			default:
			}
		}

		prevTick = nextTick
		results, err := sched.Tick(runner, nextTick)
		if err != nil {
			log.Fatalf("Fatal error in tick: %s", err)
		}

		for task, result := range results {
			if verbosity >= DEBUG_DETAIL {
				switch info := result.Info.(type) {
				default:
				case *retry.RetryInfo:
					if info.MaxRetries > 0 {
						log.Printf("Retrying %s (attempt %d of %d)\n",
							task, info.Attempt, info.MaxRetries)
					} else {
						log.Printf("Retrying %s (attempt %d)\n", task, info.Attempt)
					}
				}
			}

			if result.Ran {
				if verbosity >= DEBUG_DETAIL {
					switch output := result.Output.(type) {
					default:
						log.Printf("%s Scheduled to Run via an unknown method", task)
					case *simulatedStatus:
						log.Printf("[-simulate] %s Would have been scheduled to run as %s", task, output.TaskName)
					case *ecs.RunTaskOutput:
						for _, scheduledTask := range output.Tasks {
							log.Printf("%s Scheduled to run on Container Instance %s using Task Definition %s\n",
								task, *scheduledTask.ContainerInstanceArn, *scheduledTask.TaskDefinitionArn)
						}
					}
				}
			} else {
				if result.Error != nil {
					log.Printf("Error when running task '%s': %s", task, result.Error)
				}

				for _, warning := range result.Warnings {
					log.Printf("Warning when running task '%s': %s", task, warning)
				}
			}
		}
	}
}
<commit_msg>teach -pause option, for starting in "paused" mode<commit_after>package main

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

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ecs"
	"github.com/wpalmer/ecscron/schedule"
	"github.com/wpalmer/ecscron/schedule/crontab"
	"github.com/wpalmer/ecscron/schedule/retry"
	"github.com/wpalmer/ecscron/taskrunner"
	"github.com/wpalmer/ecscron/taskrunner/ecstaskrunner"
	"github.com/wpalmer/ecscron/taskrunner/tweak"
)

const (
	DEBUG_ERROR  = 0
	DEBUG_INFO   = 1
	DEBUG_DETAIL = 2
	DEBUG_STATUS = 5
)

type simulatedStatus struct {
	TaskName string
}

func main() {
	var async string
	var doPause bool
	var prevTick time.Time
	var nextTick time.Time
	var timezone string
	var cluster string
	var prefix string
	var suffix string
	var region string
	var filePath string
	var doRetry bool
	var retryCount int64
	var simulate bool
	var verbosity int

	var doDump bool
	var dumpFrom string
	var dumpFromTime time.Time
	var dumpUntil string
	var dumpUntilTime time.Time
	var dumpFormat string
	first := true

	flag.StringVar(&timezone, "timezone", "UTC", "The TimeZone in which to evaluate cron expressions")
	flag.StringVar(&async, "async", "", "The \"last run\" of cron (to resume after interruption) in YYYY-MM-DD HH:mm:ss format")
	flag.BoolVar(&doPause, "pause", false, "Start cron in a 'paused' state, awaiting SIGUSR1 to resume")
	flag.BoolVar(&doRetry, "retry", false, "When true, any failed run-task will be attempted again in the next iteration (same as -retry-count=-1)")
	flag.Int64Var(&retryCount, "retry-count", 0, "The number of times to retry a failed run-task before giving up (-1 means forever)")
	flag.StringVar(&cluster, "cluster", "", "The ECS Cluster on which to run tasks")
	flag.StringVar(&region, "region", "", "The AWS Region in which the ECS Cluster resides")
	flag.StringVar(&filePath, "crontab", "/etc/ecscrontab", "The location of the crontab file to parse")
	flag.StringVar(&prefix, "prefix", "", "An optional prefix to add to all ECS Task names within the crontab")
	flag.StringVar(&suffix, "suffix", "", "An optional suffix to add to all ECS Task names within the crontab")
	flag.BoolVar(&simulate, "simulate", false, "When true, don't actually run anything, only print what would be run")
	flag.IntVar(&verbosity, "debug", 0, "Debug level 0 = errors/warnings, 1 = run info, 2 = detail, 5 = status")

	flag.BoolVar(&doDump, "dump", false, "Rather than running the cron, output a summary of the schedule")
	flag.StringVar(&dumpFrom, "dump-from", "", "Output the schedule up starting from the specified time, in YYYY-MM-DD HH:mm:ss format")
	flag.StringVar(&dumpUntil, "dump-until", "", "Output the schedule up until the specified time, in YYYY-MM-DD HH:mm:ss format")
	flag.StringVar(&dumpFormat, "dump-format", "", "Output the schedule in the specified format. Currently the only supported format is 'json'")
	flag.Parse()

	location, err := time.LoadLocation(timezone)
	if err != nil {
		log.Fatalf("Failed to parse timzeone: %s", err)
	}

	if async != "" {
		prevTick, err = time.ParseInLocation("2006-01-02 15:04:05", async, location)
		if err != nil {
			log.Fatalf("Failed to parse time of last run: %s", err)
		}

		first = false
	}

	if doRetry && retryCount == int64(0) {
		retryCount = -1
	}

	file, err := os.Open(filePath)
	if err != nil {
		log.Fatalf("Error opening crontab: %s", err)
	}

	var sched schedule.Schedule
	table := crontab.NewCrontab()
	if ok, err := table.Load(file); !ok {
		log.Fatalf("Error loading crontab: %s", err)
	}
	sched = table

	if retryCount != 0 {
		numAttempts := retryCount
		if numAttempts > 0 {
			numAttempts += 1
		}

		sched = retry.NewRetrySchedule(sched, numAttempts)
	}

	var runner taskrunner.TaskRunner
	if simulate {
		runner = taskrunner.TaskRunnerFunc(func(task string) (*taskrunner.TaskStatus, error) {
			log.Printf("[-simulate] Running: %s", task)
			return &taskrunner.TaskStatus{Ran: true, Output: &simulatedStatus{TaskName: task}}, nil
		})
	} else {
		awsConfig := aws.NewConfig()
		if region != "" {
			awsConfig = awsConfig.WithRegion(region)
		}

		awsSession := session.Must(session.NewSession(awsConfig))
		ecsService := ecs.New(awsSession)

		runner = ecstaskrunner.NewEcsTaskRunner(ecsService, cluster)
	}

	if prefix != "" || suffix != "" {
		runner = tweak.NewTweakTaskRunner(runner, func(task string) string {
			return fmt.Sprintf("%s%s%s", prefix, task, suffix)
		})
	}

	if dumpFrom != "" {
		doDump = true
		dumpFromTime, err = time.ParseInLocation("2006-01-02 15:04:05", dumpFrom, location)
		if err != nil {
			log.Fatalf("Failed to parse time to dump from: %s", err)
		}
	} else {
		dumpFromTime = time.Now()
	}

	if dumpUntil != "" {
		doDump = true
		dumpUntilTime, err = time.ParseInLocation("2006-01-02 15:04:05", dumpUntil, location)
		if err != nil {
			log.Fatalf("Failed to parse time to dump until: %s", err)
		}
	} else {
		dumpUntilTime = dumpFromTime.Add(time.Hour * 24)
	}

	if dumpFormat == "" {
		dumpFormat = "json"
	} else {
		doDump = true
		if dumpFormat != "json" {
			log.Fatalf("Unknown dump format: %s", dumpFormat)
		}
	}

	if doDump {
		_, err := schedule.DumpJson(os.Stdout, sched, dumpFromTime.Add(-1), dumpUntilTime)
		if err != nil {
			log.Fatalf("Failed to dump schedule: %s", err)
		}

		fmt.Printf("\n")
		os.Exit(0)
	}

	if first {
		prevTick = time.Now().In(location)
	}

	signals := make(chan os.Signal, 1)
	if doPause {
		signals <- syscall.SIGUSR1
	}
	signal.Notify(signals, syscall.SIGUSR1)

	ticks := make(chan time.Time, 1)

	for {
		nextTick = sched.Next(prevTick)
		pause := nextTick.Sub(time.Now().In(location))
		if pause < time.Duration(0) {
			log.Printf("Cron tasks running slowly: %0.2f seconds late entering tick scheduled for %v",
				(pause * time.Duration(-1)).Seconds(), nextTick)
			ticks <- nextTick
		} else {
			if verbosity >= DEBUG_STATUS {
				log.Printf("Sleeping for %0.2f seconds", pause.Seconds())
			}
			go func() {
				time.Sleep(pause)
				ticks <- nextTick
			}()
		}

		ticked := false
		for ticked == false {
			select {
			case <-ticks:
				ticked = true
			case <-signals:
				if doPause {
					doPause = false
					log.Printf("Pausing, send SIGUSR1 to resume...")
				} else {
					log.Printf("Received SIGUSR1, pausing...")
				}

				<-signals
				log.Printf("Received SIGUSR1 while paused, resuming...")
			default:
			}
		}

		prevTick = nextTick
		results, err := sched.Tick(runner, nextTick)
		if err != nil {
			log.Fatalf("Fatal error in tick: %s", err)
		}

		for task, result := range results {
			if verbosity >= DEBUG_DETAIL {
				switch info := result.Info.(type) {
				default:
				case *retry.RetryInfo:
					if info.MaxRetries > 0 {
						log.Printf("Retrying %s (attempt %d of %d)\n",
							task, info.Attempt, info.MaxRetries)
					} else {
						log.Printf("Retrying %s (attempt %d)\n", task, info.Attempt)
					}
				}
			}

			if result.Ran {
				if verbosity >= DEBUG_DETAIL {
					switch output := result.Output.(type) {
					default:
						log.Printf("%s Scheduled to Run via an unknown method", task)
					case *simulatedStatus:
						log.Printf("[-simulate] %s Would have been scheduled to run as %s", task, output.TaskName)
					case *ecs.RunTaskOutput:
						for _, scheduledTask := range output.Tasks {
							log.Printf("%s Scheduled to run on Container Instance %s using Task Definition %s\n",
								task, *scheduledTask.ContainerInstanceArn, *scheduledTask.TaskDefinitionArn)
						}
					}
				}
			} else {
				if result.Error != nil {
					log.Printf("Error when running task '%s': %s", task, result.Error)
				}

				for _, warning := range result.Warnings {
					log.Printf("Warning when running task '%s': %s", task, warning)
				}
			}
		}
	}
}
<|endoftext|>