<commit_before>package main

import (
"bufio"
	"encoding/json"
	"fmt"
	"flag"
	"github.com/gorilla/feeds"
	"github.com/gorilla/mux"

	"github.com/ewhal/nyaa/model"
	"github.com/ewhal/nyaa/service/torrent"
	"github.com/ewhal/nyaa/util/log"
	"github.com/ewhal/nyaa/config"

	"html"
	"html/template"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

var router *mux.Router
type SearchParam struct {
	Category   string
	Order      string
	Query      string
	Max        int
	Status     string
	Sort       string
}

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

	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))

	b := model.CategoryJson{Torrents: []model.TorrentsJson{}}
	maxPerPage := 50
	nbTorrents := 0

	torrents, nbTorrents := torrentService.GetAllTorrents(maxPerPage, maxPerPage*(pagenum-1))
	for i, _ := range torrents {
		res := torrents[i].ToJson()
		b.Torrents = append(b.Torrents, res)
	}

	b.QueryRecordCount = maxPerPage
	b.TotalRecordCount = nbTorrents
	w.Header().Set("Content-Type", "application/json")
	err := json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

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

	vars := mux.Vars(r)
	id := vars["id"]
	b := model.CategoryJson{Torrents: []model.TorrentsJson{}}

	torrent, err := torrentService.GetTorrentById(id)
	res := torrent.ToJson()
	b.Torrents = append(b.Torrents, res)

	b.QueryRecordCount = 1
	b.TotalRecordCount = 1
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
	var templates = template.Must(template.New("home").Funcs(funcMap).ParseFiles("templates/index.html", "templates/home.html"))
	vars := mux.Vars(r)
	page := vars["page"]

	// db params url
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	if pagenum == 0 {
		pagenum = 1
	}

	b := []model.TorrentsJson{}

	search_param, torrents, nbTorrents := searchByQuery( r, pagenum )

	for i, _ := range torrents {
		res := torrents[i].ToJson()
		b = append(b, res)
	}

	navigationTorrents := Navigation{nbTorrents, search_param.Max, pagenum, "search_page"}
	searchForm := SearchForm{
		search_param.Query,
		search_param.Status,
		search_param.Category,
		search_param.Sort,
		search_param.Order,
	}
	htv := HomeTemplateVariables{b, torrentService.GetAllCategories(false), searchForm, navigationTorrents, r.URL, mux.CurrentRoute(r)}

	err := templates.ExecuteTemplate(w, "index.html", htv)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func searchByQuery(r *http.Request, pagenum int) (SearchParam, []model.Torrents, int) {
	maxPerPage, errConv := strconv.Atoi(r.URL.Query().Get("max"))
	if errConv != nil {
		maxPerPage = 50 // default Value maxPerPage
	}

	search_param := SearchParam{}
	search_param.Max = maxPerPage
	search_param.Query = r.URL.Query().Get("q")
	search_param.Category = r.URL.Query().Get("c")
	search_param.Status = r.URL.Query().Get("s")
	search_param.Sort = r.URL.Query().Get("sort")
	search_param.Order = r.URL.Query().Get("order")

	catsSplit := strings.Split(search_param.Category, "_")
	// need this to prevent out of index panics
	var searchCatId, searchSubCatId string
	if len(catsSplit) == 2 {

		searchCatId = html.EscapeString(catsSplit[0])
		searchSubCatId = html.EscapeString(catsSplit[1])
	}
	if search_param.Sort == "" {
		search_param.Sort = "torrent_id"
	}
	if search_param.Order == "" {
		search_param.Order = "desc"
	}
	order_by := search_param.Sort + " " + search_param.Order

	parameters := torrentService.WhereParams{}
	conditions := []string{}
	if searchCatId != "" {
		conditions = append(conditions, "category_id = ?")
		parameters.Params = append(parameters.Params, searchCatId)
	}
	if searchSubCatId != "" {
		conditions = append(conditions, "sub_category_id = ?")
		parameters.Params = append(parameters.Params, searchSubCatId)
	}
	if search_param.Status != "" {
		conditions = append(conditions, "status_id = ?")
		parameters.Params = append(parameters.Params, search_param.Status)
	}
	searchQuerySplit := strings.Split(search_param.Query, " ")
	for i, _ := range searchQuerySplit {
		conditions = append(conditions, "torrent_name LIKE ?")
		parameters.Params = append(parameters.Params, "%"+searchQuerySplit[i]+"%")
	}

	parameters.Conditions = strings.Join(conditions[:], " AND ")
	log.Infof("SQL query is :: %s\n", parameters.Conditions)
	torrents, n := torrentService.GetTorrentsOrderBy(&parameters, order_by, maxPerPage, maxPerPage*(pagenum-1))
	return search_param, torrents, n
}

func faqHandler(w http.ResponseWriter, r *http.Request) {
	var templates = template.Must(template.New("FAQ").Funcs(funcMap).ParseFiles("templates/index.html", "templates/FAQ.html"))
	err := templates.ExecuteTemplate(w, "index.html", FaqTemplateVariables{Navigation{}, NewSearchForm(), r.URL, mux.CurrentRoute(r)})
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

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

	_, torrents, _ := searchByQuery( r, 1 )
	created_as_time := time.Now()

	if len(torrents) > 0 {
		created_as_time = time.Unix(torrents[0].Date, 0)
	}
	feed := &feeds.Feed{
		Title:   "Nyaa Pantsu",
		Link:    &feeds.Link{Href: "https://nyaa.pantsu.cat/"},
		Created: created_as_time,
	}
	feed.Items = []*feeds.Item{}
	feed.Items = make([]*feeds.Item, len(torrents))

	for i, _ := range torrents {
		timestamp_as_time := time.Unix(torrents[0].Date, 0)
		torrent_json := torrents[i].ToJson()
		feed.Items[i] = &feeds.Item{
			// need a torrent view first
			//Id:		URL + torrents[i].Hash,
			Title:       torrents[i].Name,
			Link:        &feeds.Link{Href: string(torrent_json.Magnet)},
			Description: "",
			Created:     timestamp_as_time,
			Updated:     timestamp_as_time,
		}
	}

	rss, err := feed.ToRss()
	if err == nil {
		w.Write([]byte(rss))
	} else {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func viewHandler(w http.ResponseWriter, r *http.Request) {
	var templates = template.Must(template.ParseFiles("templates/index.html", "templates/view.html"))
	vars := mux.Vars(r)
	id := vars["id"]

	torrent, err := torrentService.GetTorrentById(id)
	b := torrent.ToJson()

	htv := ViewTemplateVariables{b, NewSearchForm(), Navigation{}, r.URL, mux.CurrentRoute(r)}

	err = templates.ExecuteTemplate(w, "index.html", htv)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	var templates = template.Must(template.New("home").Funcs(funcMap).ParseFiles("templates/index.html", "templates/home.html"))
	vars := mux.Vars(r)
	page := vars["page"]

	// db params url
	maxPerPage, errConv := strconv.Atoi(r.URL.Query().Get("max"))
	if errConv != nil {
		maxPerPage = 50 // default Value maxPerPage
	}

	nbTorrents := 0
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	if pagenum == 0 {
		pagenum = 1
	}

	b := []model.TorrentsJson{}
	torrents, nbTorrents := torrentService.GetAllTorrents(maxPerPage, maxPerPage*(pagenum-1))

	for i, _ := range torrents {
		res := torrents[i].ToJson()
		b = append(b, res)
	}

	navigationTorrents := Navigation{nbTorrents, maxPerPage, pagenum, "search_page"}
	htv := HomeTemplateVariables{b, torrentService.GetAllCategories(false), NewSearchForm(), navigationTorrents, r.URL, mux.CurrentRoute(r)}

	err := templates.ExecuteTemplate(w, "index.html", htv)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}

func RunServer(conf *config.Config) {
	router = mux.NewRouter()

	cssHandler := http.FileServer(http.Dir("./css/"))
	jsHandler := http.FileServer(http.Dir("./js/"))
	imgHandler := http.FileServer(http.Dir("./img/"))
	http.Handle("/css/", http.StripPrefix("/css/", cssHandler))
	http.Handle("/js/", http.StripPrefix("/js/", jsHandler))
	http.Handle("/img/", http.StripPrefix("/img/", imgHandler))

	// Routes,
	router.HandleFunc("/", rootHandler).Name("home")
	router.HandleFunc("/page/{page:[0-9]+}", rootHandler).Name("home_page")
	router.HandleFunc("/search", searchHandler).Name("search")
	router.HandleFunc("/search/{page}", searchHandler).Name("search_page")
	router.HandleFunc("/api/{page}", apiHandler).Methods("GET")
	router.HandleFunc("/api/view/{id}", apiViewHandler).Methods("GET")
	router.HandleFunc("/faq", faqHandler).Name("faq")
	router.HandleFunc("/feed.xml", rssHandler)
	router.HandleFunc("/view/{id}", viewHandler).Name("view_torrent")

	http.Handle("/", router)

	// Set up server,
	srv := &http.Server{
		Addr:         fmt.Sprintf("%s:%d", conf.Host, conf.Port),
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}

	err := srv.ListenAndServe()
	log.CheckError(err)
}

func main() {

	conf := config.NewConfig()
	conf_bind := conf.BindFlags()
	defaults := flag.Bool("print-defaults", false, "print the default configuration file on stdout")
	flag.Parse()
	if *defaults {
		stdout := bufio.NewWriter(os.Stdout)
		conf.Pretty(stdout)
		stdout.Flush()
		os.Exit(0)
	} else {
		conf_bind()
		RunServer(conf)
	}
}
<commit_msg>Re added templates files function for search<commit_after>package main

import (
"bufio"
	"encoding/json"
	"fmt"
	"flag"
	"github.com/gorilla/feeds"
	"github.com/gorilla/mux"

	"github.com/ewhal/nyaa/model"
	"github.com/ewhal/nyaa/service/torrent"
	"github.com/ewhal/nyaa/util/log"
	"github.com/ewhal/nyaa/config"

	"html"
	"html/template"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

var router *mux.Router
type SearchParam struct {
	Category   string
	Order      string
	Query      string
	Max        int
	Status     string
	Sort       string
}

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

	vars := mux.Vars(r)
	page := vars["page"]
	pagenum, _ := strconv.Atoi(html.EscapeString(page))

	b := model.CategoryJson{Torrents: []model.TorrentsJson{}}
	maxPerPage := 50
	nbTorrents := 0

	torrents, nbTorrents := torrentService.GetAllTorrents(maxPerPage, maxPerPage*(pagenum-1))
	for i, _ := range torrents {
		res := torrents[i].ToJson()
		b.Torrents = append(b.Torrents, res)
	}

	b.QueryRecordCount = maxPerPage
	b.TotalRecordCount = nbTorrents
	w.Header().Set("Content-Type", "application/json")
	err := json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

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

	vars := mux.Vars(r)
	id := vars["id"]
	b := model.CategoryJson{Torrents: []model.TorrentsJson{}}

	torrent, err := torrentService.GetTorrentById(id)
	res := torrent.ToJson()
	b.Torrents = append(b.Torrents, res)

	b.QueryRecordCount = 1
	b.TotalRecordCount = 1
	w.Header().Set("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(b)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
	var templates = template.Must(template.New("home").Funcs(funcMap).ParseFiles("templates/index.html", "templates/home.html"))
 	templates.ParseGlob("templates/_*.html") // common
	vars := mux.Vars(r)
	page := vars["page"]

	// db params url
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	if pagenum == 0 {
		pagenum = 1
	}

	b := []model.TorrentsJson{}

	search_param, torrents, nbTorrents := searchByQuery( r, pagenum )

	for i, _ := range torrents {
		res := torrents[i].ToJson()
		b = append(b, res)
	}

	navigationTorrents := Navigation{nbTorrents, search_param.Max, pagenum, "search_page"}
	searchForm := SearchForm{
		search_param.Query,
		search_param.Status,
		search_param.Category,
		search_param.Sort,
		search_param.Order,
	}
	htv := HomeTemplateVariables{b, torrentService.GetAllCategories(false), searchForm, navigationTorrents, r.URL, mux.CurrentRoute(r)}

	err := templates.ExecuteTemplate(w, "index.html", htv)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func searchByQuery(r *http.Request, pagenum int) (SearchParam, []model.Torrents, int) {
	maxPerPage, errConv := strconv.Atoi(r.URL.Query().Get("max"))
	if errConv != nil {
		maxPerPage = 50 // default Value maxPerPage
	}

	search_param := SearchParam{}
	search_param.Max = maxPerPage
	search_param.Query = r.URL.Query().Get("q")
	search_param.Category = r.URL.Query().Get("c")
	search_param.Status = r.URL.Query().Get("s")
	search_param.Sort = r.URL.Query().Get("sort")
	search_param.Order = r.URL.Query().Get("order")

	catsSplit := strings.Split(search_param.Category, "_")
	// need this to prevent out of index panics
	var searchCatId, searchSubCatId string
	if len(catsSplit) == 2 {

		searchCatId = html.EscapeString(catsSplit[0])
		searchSubCatId = html.EscapeString(catsSplit[1])
	}
	if search_param.Sort == "" {
		search_param.Sort = "torrent_id"
	}
	if search_param.Order == "" {
		search_param.Order = "desc"
	}
	order_by := search_param.Sort + " " + search_param.Order

	parameters := torrentService.WhereParams{}
	conditions := []string{}
	if searchCatId != "" {
		conditions = append(conditions, "category_id = ?")
		parameters.Params = append(parameters.Params, searchCatId)
	}
	if searchSubCatId != "" {
		conditions = append(conditions, "sub_category_id = ?")
		parameters.Params = append(parameters.Params, searchSubCatId)
	}
	if search_param.Status != "" {
		conditions = append(conditions, "status_id = ?")
		parameters.Params = append(parameters.Params, search_param.Status)
	}
	searchQuerySplit := strings.Split(search_param.Query, " ")
	for i, _ := range searchQuerySplit {
		conditions = append(conditions, "torrent_name LIKE ?")
		parameters.Params = append(parameters.Params, "%"+searchQuerySplit[i]+"%")
	}

	parameters.Conditions = strings.Join(conditions[:], " AND ")
	log.Infof("SQL query is :: %s\n", parameters.Conditions)
	torrents, n := torrentService.GetTorrentsOrderBy(&parameters, order_by, maxPerPage, maxPerPage*(pagenum-1))
	return search_param, torrents, n
}

func faqHandler(w http.ResponseWriter, r *http.Request) {
	var templates = template.Must(template.New("FAQ").Funcs(funcMap).ParseFiles("templates/index.html", "templates/FAQ.html"))
 	templates.ParseGlob("templates/_*.html") // common
	err := templates.ExecuteTemplate(w, "index.html", FaqTemplateVariables{Navigation{}, NewSearchForm(), r.URL, mux.CurrentRoute(r)})
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

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

	_, torrents, _ := searchByQuery( r, 1 )
	created_as_time := time.Now()

	if len(torrents) > 0 {
		created_as_time = time.Unix(torrents[0].Date, 0)
	}
	feed := &feeds.Feed{
		Title:   "Nyaa Pantsu",
		Link:    &feeds.Link{Href: "https://nyaa.pantsu.cat/"},
		Created: created_as_time,
	}
	feed.Items = []*feeds.Item{}
	feed.Items = make([]*feeds.Item, len(torrents))

	for i, _ := range torrents {
		timestamp_as_time := time.Unix(torrents[0].Date, 0)
		torrent_json := torrents[i].ToJson()
		feed.Items[i] = &feeds.Item{
			// need a torrent view first
			//Id:		URL + torrents[i].Hash,
			Title:       torrents[i].Name,
			Link:        &feeds.Link{Href: string(torrent_json.Magnet)},
			Description: "",
			Created:     timestamp_as_time,
			Updated:     timestamp_as_time,
		}
	}

	rss, err := feed.ToRss()
	if err == nil {
		w.Write([]byte(rss))
	} else {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func viewHandler(w http.ResponseWriter, r *http.Request) {
	var templates = template.Must(template.ParseFiles("templates/index.html", "templates/view.html"))
 	templates.ParseGlob("templates/_*.html") // common
	vars := mux.Vars(r)
	id := vars["id"]

	torrent, err := torrentService.GetTorrentById(id)
	b := torrent.ToJson()

	htv := ViewTemplateVariables{b, NewSearchForm(), Navigation{}, r.URL, mux.CurrentRoute(r)}

	err = templates.ExecuteTemplate(w, "index.html", htv)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
var templates = template.Must(template.New("home").Funcs(funcMap).ParseFiles("templates/index.html", "templates/home.html"))
	templates.ParseGlob("templates/_*.html") // common
 	vars := mux.Vars(r)
	page := vars["page"]

	// db params url
	maxPerPage, errConv := strconv.Atoi(r.URL.Query().Get("max"))
	if errConv != nil {
		maxPerPage = 50 // default Value maxPerPage
	}

	nbTorrents := 0
	pagenum, _ := strconv.Atoi(html.EscapeString(page))
	if pagenum == 0 {
		pagenum = 1
	}

	b := []model.TorrentsJson{}
	torrents, nbTorrents := torrentService.GetAllTorrents(maxPerPage, maxPerPage*(pagenum-1))

	for i, _ := range torrents {
		res := torrents[i].ToJson()
		b = append(b, res)
	}

	navigationTorrents := Navigation{nbTorrents, maxPerPage, pagenum, "search_page"}
	htv := HomeTemplateVariables{b, torrentService.GetAllCategories(false), NewSearchForm(), navigationTorrents, r.URL, mux.CurrentRoute(r)}

	err := templates.ExecuteTemplate(w, "index.html", htv)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}

func RunServer(conf *config.Config) {
	router = mux.NewRouter()

	cssHandler := http.FileServer(http.Dir("./css/"))
	jsHandler := http.FileServer(http.Dir("./js/"))
	imgHandler := http.FileServer(http.Dir("./img/"))
	http.Handle("/css/", http.StripPrefix("/css/", cssHandler))
	http.Handle("/js/", http.StripPrefix("/js/", jsHandler))
	http.Handle("/img/", http.StripPrefix("/img/", imgHandler))

	// Routes,
	router.HandleFunc("/", rootHandler).Name("home")
	router.HandleFunc("/page/{page:[0-9]+}", rootHandler).Name("home_page")
	router.HandleFunc("/search", searchHandler).Name("search")
	router.HandleFunc("/search/{page}", searchHandler).Name("search_page")
	router.HandleFunc("/api/{page}", apiHandler).Methods("GET")
	router.HandleFunc("/api/view/{id}", apiViewHandler).Methods("GET")
	router.HandleFunc("/faq", faqHandler).Name("faq")
	router.HandleFunc("/feed.xml", rssHandler)
	router.HandleFunc("/view/{id}", viewHandler).Name("view_torrent")

	http.Handle("/", router)

	// Set up server,
	srv := &http.Server{
		Addr:         fmt.Sprintf("%s:%d", conf.Host, conf.Port),
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}

	err := srv.ListenAndServe()
	log.CheckError(err)
}

func main() {

	conf := config.NewConfig()
	conf_bind := conf.BindFlags()
	defaults := flag.Bool("print-defaults", false, "print the default configuration file on stdout")
	flag.Parse()
	if *defaults {
		stdout := bufio.NewWriter(os.Stdout)
		conf.Pretty(stdout)
		stdout.Flush()
		os.Exit(0)
	} else {
		conf_bind()
		RunServer(conf)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strings"

	"github.com/drone/drone-plugin-go/plugin"
)

var netrcFile = `
machine %s
login %s
password %s
`

func main() {
	v := struct {
		Path  string `json:"path"`
		Depth int    `json:"depth"`
	}{}

	c := new(plugin.Clone)
	plugin.Param("clone", c)
	plugin.Param("vargs", &v)
	if err := plugin.Parse(); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	if v.Depth == 0 {
		v.Depth = 50
	}
	if len(v.Path) != 0 {
		c.Dir = filepath.Join("/drone/src", v.Path)
	}

	err := os.MkdirAll(c.Dir, 0777)
	if err != nil {
		fmt.Printf("Error creating directory %s. %s\n", c.Dir, err)
		os.Exit(2)
	}

	// generate the .netrc file
	if err := writeNetrc(c); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(3)
	}

	// write the rsa private key if provided
	if err := writeKey(c); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(4)
	}

	var cmds []*exec.Cmd
	// check for a .git directory and whether it's empty
  if isDirEmpty(filepath.Join(c.Dir, ".git")) {
		cmds = append(cmds, initGit())
		cmds = append(cmds, remote(c))
	}

	cmds = append(cmds, fetch(c))

	if isPR(c) {
		//cmds = append(cmds, clone(c))
		//cmds = append(cmds, fetch(c))
		cmds = append(cmds, checkoutHead(c))
	} else {
		//cmds = append(cmds, cloneBranch(c))
		cmds = append(cmds, checkoutSha(c))
	}

	for _, cmd := range cmds {
		cmd.Dir = c.Dir
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		trace(cmd)
		err := cmd.Run()
		if err != nil {
			os.Exit(1)
		}
	}
}

// Returns true if cloning a pull request.
func isPR(c *plugin.Clone) bool {
	return strings.HasPrefix(c.Ref, "refs/pull/")
}

func isTag(c *plugin.Clone) bool {
	return strings.HasPrefix(c.Ref, "refs/tags/")
}

// Creates an empty git repository.
func initGit() *exec.Cmd {
	return exec.Command(
		"git",
		"init",
	)
}

// Sets the remote origin for the repository.
func remote(c *plugin.Clone) *exec.Cmd {
	return exec.Command(
		"git",
		"remote",
		"add",
		"origin",
		c.Origin,
	)
}

// Checkout executes a git checkout command.
func checkoutSha(c *plugin.Clone) *exec.Cmd {
	return exec.Command(
		"git",
		"checkout",
		"-qf",
		c.Sha,
	)
}

// Checkout executes a git checkout command.
func checkoutHead(c *plugin.Clone) *exec.Cmd {
	return exec.Command(
		"git",
		"checkout",
		"-qf",
		"FETCH_HEAD",
	)
}

// Fetch executes a git fetch to origin.
func fetch(c *plugin.Clone) *exec.Cmd {
	return exec.Command(
		"git",
		"fetch",
		"origin",
		fmt.Sprintf("+%s:", c.Ref),
	)
}

// Trace writes each command to standard error (preceded by a ‘$ ’) before it
// is executed. Used for debugging your build.
func trace(cmd *exec.Cmd) {
	fmt.Println("$", strings.Join(cmd.Args, " "))
}

// Writes the netrc file.
func writeNetrc(in *plugin.Clone) error {
	if len(in.Netrc.Machine) == 0 {
		return nil
	}
	out := fmt.Sprintf(
		netrcFile,
		in.Netrc.Machine,
		in.Netrc.Login,
		in.Netrc.Password,
	)
	home := "/root"
	u, err := user.Current()
	if err == nil {
		home = u.HomeDir
	}
	path := filepath.Join(home, ".netrc")
	return ioutil.WriteFile(path, []byte(out), 0600)
}

// Writes the RSA private key
func writeKey(in *plugin.Clone) error {
	if len(in.Keypair.Private) == 0 {
		return nil
	}
	home := "/root"
	u, err := user.Current()
	if err == nil {
		home = u.HomeDir
	}
	sshpath := filepath.Join(home, ".ssh")
	if err := os.MkdirAll(sshpath, 0700); err != nil {
		return err
	}
	confpath := filepath.Join(sshpath, "config")
	privpath := filepath.Join(sshpath, "id_rsa")
	ioutil.WriteFile(confpath, []byte("StrictHostKeyChecking no\n"), 0700)
	return ioutil.WriteFile(privpath, []byte(in.Keypair.Private), 0600)
}

func isDirEmpty(name string) bool {
	f, err := os.Open(name)
	if err != nil {
		return true;
	}
	defer f.Close()

	_, err = f.Readdir(1)
	if err == io.EOF {
	  return true
	}
	return false
}
<commit_msg>Removing appending of /drone/src to v.Path as its already included<commit_after>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strings"

	"github.com/drone/drone-plugin-go/plugin"
)

var netrcFile = `
machine %s
login %s
password %s
`

func main() {
	v := struct {
		Path  string `json:"path"`
		Depth int    `json:"depth"`
	}{}

	c := new(plugin.Clone)
	plugin.Param("clone", c)
	plugin.Param("vargs", &v)
	if err := plugin.Parse(); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	if v.Depth == 0 {
		v.Depth = 50
	}
	if len(v.Path) != 0 {
		c.Dir = v.Path
	}

	err := os.MkdirAll(c.Dir, 0777)
	if err != nil {
		fmt.Printf("Error creating directory %s. %s\n", c.Dir, err)
		os.Exit(2)
	}

	// generate the .netrc file
	if err := writeNetrc(c); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(3)
	}

	// write the rsa private key if provided
	if err := writeKey(c); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(4)
	}

	var cmds []*exec.Cmd
	// check for a .git directory and whether it's empty
  if isDirEmpty(filepath.Join(c.Dir, ".git")) {
		cmds = append(cmds, initGit())
		cmds = append(cmds, remote(c))
	}

	cmds = append(cmds, fetch(c))

	if isPR(c) {
		//cmds = append(cmds, clone(c))
		//cmds = append(cmds, fetch(c))
		cmds = append(cmds, checkoutHead(c))
	} else {
		//cmds = append(cmds, cloneBranch(c))
		cmds = append(cmds, checkoutSha(c))
	}

	for _, cmd := range cmds {
		cmd.Dir = c.Dir
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		trace(cmd)
		err := cmd.Run()
		if err != nil {
			os.Exit(1)
		}
	}
}

// Returns true if cloning a pull request.
func isPR(c *plugin.Clone) bool {
	return strings.HasPrefix(c.Ref, "refs/pull/")
}

func isTag(c *plugin.Clone) bool {
	return strings.HasPrefix(c.Ref, "refs/tags/")
}

// Creates an empty git repository.
func initGit() *exec.Cmd {
	return exec.Command(
		"git",
		"init",
	)
}

// Sets the remote origin for the repository.
func remote(c *plugin.Clone) *exec.Cmd {
	return exec.Command(
		"git",
		"remote",
		"add",
		"origin",
		c.Origin,
	)
}

// Checkout executes a git checkout command.
func checkoutSha(c *plugin.Clone) *exec.Cmd {
	return exec.Command(
		"git",
		"checkout",
		"-qf",
		c.Sha,
	)
}

// Checkout executes a git checkout command.
func checkoutHead(c *plugin.Clone) *exec.Cmd {
	return exec.Command(
		"git",
		"checkout",
		"-qf",
		"FETCH_HEAD",
	)
}

// Fetch executes a git fetch to origin.
func fetch(c *plugin.Clone) *exec.Cmd {
	return exec.Command(
		"git",
		"fetch",
		"origin",
		fmt.Sprintf("+%s:", c.Ref),
	)
}

// Trace writes each command to standard error (preceded by a ‘$ ’) before it
// is executed. Used for debugging your build.
func trace(cmd *exec.Cmd) {
	fmt.Println("$", strings.Join(cmd.Args, " "))
}

// Writes the netrc file.
func writeNetrc(in *plugin.Clone) error {
	if len(in.Netrc.Machine) == 0 {
		return nil
	}
	out := fmt.Sprintf(
		netrcFile,
		in.Netrc.Machine,
		in.Netrc.Login,
		in.Netrc.Password,
	)
	home := "/root"
	u, err := user.Current()
	if err == nil {
		home = u.HomeDir
	}
	path := filepath.Join(home, ".netrc")
	return ioutil.WriteFile(path, []byte(out), 0600)
}

// Writes the RSA private key
func writeKey(in *plugin.Clone) error {
	if len(in.Keypair.Private) == 0 {
		return nil
	}
	home := "/root"
	u, err := user.Current()
	if err == nil {
		home = u.HomeDir
	}
	sshpath := filepath.Join(home, ".ssh")
	if err := os.MkdirAll(sshpath, 0700); err != nil {
		return err
	}
	confpath := filepath.Join(sshpath, "config")
	privpath := filepath.Join(sshpath, "id_rsa")
	ioutil.WriteFile(confpath, []byte("StrictHostKeyChecking no\n"), 0700)
	return ioutil.WriteFile(privpath, []byte(in.Keypair.Private), 0600)
}

func isDirEmpty(name string) bool {
	f, err := os.Open(name)
	if err != nil {
		return true;
	}
	defer f.Close()

	_, err = f.Readdir(1)
	if err == io.EOF {
	  return true
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/dr4ke616/go_method/server"
	"log"
	"os"
)

func main() {
	var err error
	proxy := server.Proxy{}

	err = server.LoadFromConfig(&proxy)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	err = server.StartProxy(&proxy)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
}
<commit_msg>Fixed import<commit_after>package main

import (
	"github.com/dr4ke616/GoProxy/server"
	"log"
	"os"
)

func main() {
	var err error
	proxy := server.Proxy{}

	err = server.LoadFromConfig(&proxy)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	err = server.StartProxy(&proxy)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

type Service struct {
	Name    string
	Address string
	Port    int
}

func (s Service) AddressAndPort() string {
	return fmt.Sprintf("%s:%d", s.Address, s.Port)
}

var timeout = flag.Int64("timeout", 60, "time to wait for all services to be up (seconds)")

func main() {
	flag.Parse()

	services := loadServicesFromEnv()
	log.Printf("Services: %#v", services)

	var wg sync.WaitGroup
	cancel := make(chan struct{})

	for _, service := range services {
		wg.Add(1)
		go func(service Service) {
			waitForTcpConn(service, cancel)
			wg.Done()
		}(service)
	}

	timer := time.AfterFunc(time.Duration(*timeout)*time.Second, func() {
		close(cancel)
	})

	wg.Wait()

	// There's a race here that might result in assuming that a timeout happend
	// although none happend. It appears when the timer fires after the connection
	// succeeded, but before the check via Stop() below.
	// That shouldn't happen very often and the service was pretty short of timing out
	// anyway, so I guess that's ok for now.
	if !timer.Stop() {
		log.Printf("Error: One or more services timed out after %d second(s)", *timeout)
		os.Exit(1)
	}
	log.Printf("All services are up!")
}

func loadServicesFromEnv() []Service {
	services := make([]Service, 0)
	for _, line := range os.Environ() {
		keyAndValue := strings.SplitN(line, "=", 2)
		addrKey := keyAndValue[0]
		if strings.HasSuffix(addrKey, "_TCP_ADDR") {
			addr := os.Getenv(addrKey)
			name := addrKey[:len(addrKey)-9] // cut off "_TCP_ADDR"

			portKey := name + "_TCP_PORT"
			portStr := os.Getenv(portKey)
			port, err := strconv.Atoi(portStr)
			if err != nil {
				log.Printf("Failed to convert '%v' to int, value: '%v' - skipping service '%v'",
					portKey, portStr, name)
				continue
			}
			services = append(services, Service{Name: name, Address: addr, Port: port})
		}
	}
	return services
}

func waitForTcpConn(service Service, cancel <-chan struct{}) {
	var cancelled int32 = 0
	go func() {
		<-cancel
		atomic.StoreInt32(&cancelled, 1)
	}()

	var conn net.Conn
	err := errors.New("init")
	for err != nil {
		conn, err = net.DialTimeout("tcp", service.AddressAndPort(), 1*time.Second)

		if cancelled == 1 && err != nil {
			log.Printf("Service %v (%v) timed out. Last error: %v",
				service.Name, service.AddressAndPort(), err)
			return
		}
	}
	conn.Close()
	log.Printf("Service %v (%v) is up", service.Name, service.AddressAndPort())
}
<commit_msg>Support waiting for an HTTP request<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

type Service struct {
	Name    string
	Address string
	Port    int
}

func (s Service) AddressAndPort() string {
	return fmt.Sprintf("%s:%d", s.Address, s.Port)
}

var timeout = flag.Int64("timeout", 60, "time to wait for all services to be up (seconds)")
var httpPort = flag.Int("httpport", 0, "wait for an http request if target port is given port")

func main() {
	flag.Parse()

	services := loadServicesFromEnv()
	log.Printf("Services: %#v", services)

	var wg sync.WaitGroup
	cancel := make(chan struct{})

	for _, service := range services {
		wg.Add(1)
		go func(service Service) {
			waitForTcpConn(service, cancel)
			if *httpPort == service.Port {
				waitForHttpRequest(service, cancel)
			}
			wg.Done()
		}(service)
	}

	timer := time.AfterFunc(time.Duration(*timeout)*time.Second, func() {
		close(cancel)
	})

	wg.Wait()

	// There's a race here that might result in assuming that a timeout happend
	// although none happend. It appears when the timer fires after the connection
	// succeeded, but before the check via Stop() below.
	// That shouldn't happen very often and the service was pretty short of timing out
	// anyway, so I guess that's ok for now.
	if !timer.Stop() {
		log.Printf("Error: One or more services timed out after %d second(s)", *timeout)
		os.Exit(1)
	}
	log.Printf("All services are up!")
}

func loadServicesFromEnv() []Service {
	services := make([]Service, 0)
	for _, line := range os.Environ() {
		keyAndValue := strings.SplitN(line, "=", 2)
		addrKey := keyAndValue[0]
		if strings.HasSuffix(addrKey, "_TCP_ADDR") {
			addr := os.Getenv(addrKey)
			name := addrKey[:len(addrKey)-9] // cut off "_TCP_ADDR"

			portKey := name + "_TCP_PORT"
			portStr := os.Getenv(portKey)
			port, err := strconv.Atoi(portStr)
			if err != nil {
				log.Printf("Failed to convert '%v' to int, value: '%v' - skipping service '%v'",
					portKey, portStr, name)
				continue
			}
			services = append(services, Service{Name: name, Address: addr, Port: port})
		}
	}
	return services
}

func waitForTcpConn(service Service, cancel <-chan struct{}) {
	var cancelled int32 = 0
	go func() {
		<-cancel
		atomic.StoreInt32(&cancelled, 1)
	}()

	var conn net.Conn
	err := errors.New("init")
	for err != nil {
		conn, err = net.DialTimeout("tcp", service.AddressAndPort(), 1*time.Second)

		if cancelled == 1 && err != nil {
			log.Printf("TCP: Service %v (%v) timed out. Last error: %v",
				service.Name, service.AddressAndPort(), err)
			return
		}

		time.Sleep(200 * time.Millisecond)
	}
	conn.Close()
	log.Printf("TCP: Service %v (%v) is up", service.Name, service.AddressAndPort())
}

func waitForHttpRequest(service Service, cancel <-chan struct{}) {
	url := url.URL{
		Scheme: "http",
		Host:   service.AddressAndPort(),
		Path:   "/",
	}

	err := errors.New("init")
	for err != nil {
		req, reqErr := http.NewRequest("GET", url.String(), nil)
		if reqErr != nil {
			log.Printf("Warning: Failed to create request for URL '%s' -  skipping service '%s'",
				url.String(), service.Name)
			return
		}

		tr := &http.Transport{}
		client := &http.Client{Transport: tr}
		c := make(chan error, 1)
		go func() {
			_, err := client.Do(req)
			c <- err
		}()

		select {
		case <-cancel:
			tr.CancelRequest(req)
			log.Printf("HTTP: Service %v (%v) timed out. Last error: %v",
				service.Name, service.AddressAndPort(), err)
			<-c
			return
		case err = <-c:
		}
		time.Sleep(200 * time.Millisecond)
	}

	log.Printf("HTTP: Service %v (%v) is up", service.Name, service.AddressAndPort())
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/valep27/GChip8/emu"
	"github.com/valep27/GChip8/io"
)

func main() {
	fmt.Println("Starting emulator...")

	chip8 := emu.New()
	front := io.NewSdlFrontend()

	front.Initialize()
	defer front.Close()

	front.Draw(chip8)
}
<commit_msg>Add simple game loop logic<commit_after>package main

import (
	"fmt"
	"time"

	"github.com/valep27/GChip8/emu"
	"github.com/valep27/GChip8/io"
)

func main() {
	fmt.Println("Starting emulator...")

	chip8 := emu.New()
	front := io.NewSdlFrontend()

	input := io.NewSdlInput()

	front.Initialize()

	defer front.Close()

	front.Draw(&chip8)

	running := true
	for running {
		k := input.Poll()

		if k == io.KEY_QUIT {
			running = false
		}

		time.Sleep(33 * time.Millisecond)
	}
}
<|endoftext|>


<commit_before>// pollen, the stupid file watcher
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

type paths struct {
	files []string
	dirs  []string
}

type set struct {
	entries map[string]struct{}
}

func newSet(keys []string) *set {
	s := &set{entries: make(map[string]struct{})}
	s.addAll(keys)
	return s
}

func (s *set) addAll(keys []string) {
	for _, k := range keys {
		s.add(k)
	}
}

func (s *set) add(key string) {
	s.entries[key] = struct{}{}
}

func (s *set) del(key string) {
	delete(s.entries, key)
}

func (s set) exists(key string) bool {
	_, ok := s.entries[key]
	return ok
}

func main() {
	buildCmd := os.Args[1]
	restartCmd := os.Args[2]
	ignore := os.Args[3:]

	action := func() {
		{
			fmt.Println("building...")
			o, err := exec.Command("/bin/sh", "-c", buildCmd).CombinedOutput()
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Println(string(o))
		}
		{
			fmt.Println("restarting...")
			o, err := exec.Command("/bin/sh", "-c", restartCmd).CombinedOutput()
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Println(string(o))
		}
	}

	state := make(chan *paths)
	go func() {
		tick := time.NewTicker(3 * time.Second)
		defer tick.Stop()
		for {
			select {
			case <-tick.C:
				var files []string
				var dirs []string

				filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
					if err != nil {
						fmt.Println(path, err)
						// don't stop walking
						return nil
					}
					if info.IsDir() {
						dirs = append(dirs, path)
					} else {
						files = append(files, path)
					}
					return nil
				})
				state <- &paths{files: files, dirs: dirs}
			}
		}
	}()

	go func() {
		previous := &paths{}
		for {
			select {
			case p := <-state:
				filtered := &paths{}
				for _, v := range p.dirs {
					if ignored(v, ignore) {
						continue
					}
					filtered.dirs = append(filtered.dirs, v)
				}
				for _, v := range p.files {
					if ignored(v, ignore) {
						continue
					}
					filtered.files = append(filtered.files, v)
				}

				//fmt.Printf("%#v\n", filtered)
				if needsAction(previous, filtered) {
					go action()
				}

				previous = filtered
			}
		}
	}()

	<-(chan bool)(nil)
}

func needsAction(previous *paths, current *paths) bool {
	if len(previous.dirs) != len(current.dirs) {
		return true
	}

	if len(previous.files) != len(current.files) {
		return true
	}

	uniondirs := newSet(previous.dirs)
	uniondirs.addAll(current.dirs)

	if len(uniondirs.entries) != len(previous.dirs) {
		return true
	}

	unionfiles := newSet(previous.files)
	unionfiles.addAll(current.files)

	if len(unionfiles.entries) != len(previous.files) {
		return true
	}

	for _, entry := range current.files {
		if info, err := os.Stat(entry); err == nil {
			// check if file has been modified in the last couple of seconds
			since := time.Now().Add(-3 * time.Second)
			if since.Before(info.ModTime()) {
				fmt.Println("changed:", entry)
				return true
			}
		}
	}

	return false
}

func ignored(v string, ignore []string) bool {
	for _, ignore := range ignore {
		if strings.HasPrefix(v, ignore) {
			return true
		}
	}
	return false
}
<commit_msg>specify dir to poll<commit_after>// pollen, the stupid file watcher
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

type paths struct {
	files []string
	dirs  []string
}

type set struct {
	entries map[string]struct{}
}

func newSet(keys []string) *set {
	s := &set{entries: make(map[string]struct{})}
	s.addAll(keys)
	return s
}

func (s *set) addAll(keys []string) {
	for _, k := range keys {
		s.add(k)
	}
}

func (s *set) add(key string) {
	s.entries[key] = struct{}{}
}

func (s *set) del(key string) {
	delete(s.entries, key)
}

func (s set) exists(key string) bool {
	_, ok := s.entries[key]
	return ok
}

func main() {
	dir := os.Args[1]
	buildCmd := os.Args[2]
	restartCmd := os.Args[3]
	ignore := os.Args[4:]

	action := func() {
		{
			fmt.Println("building...")
			o, err := exec.Command("/bin/sh", "-c", buildCmd).CombinedOutput()
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Println(string(o))
		}
		{
			fmt.Println("restarting...")
			o, err := exec.Command("/bin/sh", "-c", restartCmd).CombinedOutput()
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Println(string(o))
		}
	}

	state := make(chan *paths)
	go func() {
		tick := time.NewTicker(3 * time.Second)
		defer tick.Stop()
		for {
			select {
			case <-tick.C:
				var files []string
				var dirs []string

				filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
					if err != nil {
						fmt.Println(path, err)
						// don't stop walking
						return nil
					}
					if info.IsDir() {
						dirs = append(dirs, path)
					} else {
						files = append(files, path)
					}
					return nil
				})
				state <- &paths{files: files, dirs: dirs}
			}
		}
	}()

	go func() {
		previous := &paths{}
		for {
			select {
			case p := <-state:
				filtered := &paths{}
				for _, v := range p.dirs {
					if ignored(v, ignore) {
						continue
					}
					filtered.dirs = append(filtered.dirs, v)
				}
				for _, v := range p.files {
					if ignored(v, ignore) {
						continue
					}
					filtered.files = append(filtered.files, v)
				}

				//fmt.Printf("%#v\n", filtered)
				if needsAction(previous, filtered) {
					go action()
				}

				previous = filtered
			}
		}
	}()

	<-(chan bool)(nil)
}

func needsAction(previous *paths, current *paths) bool {
	if len(previous.dirs) != len(current.dirs) {
		return true
	}

	if len(previous.files) != len(current.files) {
		return true
	}

	uniondirs := newSet(previous.dirs)
	uniondirs.addAll(current.dirs)

	if len(uniondirs.entries) != len(previous.dirs) {
		return true
	}

	unionfiles := newSet(previous.files)
	unionfiles.addAll(current.files)

	if len(unionfiles.entries) != len(previous.files) {
		return true
	}

	for _, entry := range current.files {
		if info, err := os.Stat(entry); err == nil {
			// check if file has been modified in the last couple of seconds
			since := time.Now().Add(-3 * time.Second)
			if since.Before(info.ModTime()) {
				fmt.Println("changed:", entry)
				return true
			}
		}
	}

	return false
}

func ignored(v string, ignore []string) bool {
	for _, ignore := range ignore {
		if strings.HasPrefix(v, ignore) {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
)

const (
	version = "0.01"
)

var config_path = flag.String("config_path", "config.json", "Path to configuration file.")

func main() {
	log.Printf("Tesla Go version %v\n", version)

	config := LoadConfig(*config_path)
	client := NewTeslaClient()

	if err := client.Authenticate(config); err != nil {
		log.Fatalf("Failed to authenticate: %s", err)
	} else {
		log.Println("Authentication complete.")
	}

	vehicles, err := client.ListVehicles()
	if err != nil {
		log.Fatalf("Operation failed: %s", err)
	}

	for _, vehicle := range vehicles {
		resp, err := client.GetVehicleState(vehicle)
		if err != nil {
			log.Fatalf("Error while getting drive state of vehicle %s: %s", vehicle.ID, err)
		}
		log.Printf("%d: %+v\n", vehicle.ID, resp)
	}
}
<commit_msg>Add metric collection via Prometheus.<commit_after>package main

import (
	"flag"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/push"
	"log"
	"strconv"
)

const (
	version = "0.01"
	jobName = "tesla_collector"
)

var (
	configPath      = flag.String("configPath", "config.json", "Path to configuration file.")
	pushgatewayAddr = flag.String("pushgateway_address", "", "URL of pushgateway.")
	odometerMetric  = prometheus.NewGaugeVec(prometheus.GaugeOpts{
		Name: "odometric_metric",
		Help: "Current odometer value per vehicle.",
	}, []string{"vehicle_id", "vehicle_name"})
)

func main() {
	log.Printf("Tesla Go version %v\n", version)

	config := LoadConfig(*configPath)
	client := NewTeslaClient()

	if err := client.Authenticate(config); err != nil {
		log.Fatalf("Failed to authenticate: %s", err)
	} else {
		log.Println("Authentication complete.")
	}

	vehicles, err := client.ListVehicles()
	if err != nil {
		log.Fatalf("ListVehicles operation failed: %s", err)
	}

	for _, v := range vehicles {
		resp, err := client.GetVehicleState(v)
		if err != nil {
			log.Fatalf("Error while getting drive state of v %s: %s", v.ID, err)
		}
		odometerMetric.WithLabelValues(strconv.FormatInt(v.ID, 10), v.DisplayName).Set(resp.Odometer)
	}

	if err := push.Collectors(jobName, nil, *pushgatewayAddr, odometerMetric); err != nil {
		log.Fatalf("Failed to push metrics: %s", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	machinery "github.com/RichardKnop/machinery/v1"
	machinery_config "github.com/RichardKnop/machinery/v1/config"
	signatures "github.com/RichardKnop/machinery/v1/signatures"
	"github.com/dokterbob/ipfs-search/crawler"
	"github.com/dokterbob/ipfs-search/indexer"
	"gopkg.in/ipfs/go-ipfs-api.v1"
	"gopkg.in/olivere/elastic.v3"
	"gopkg.in/urfave/cli.v1"
	"os"
)

func main() {
	app := cli.NewApp()
	app.Name = "ipfs-search"
	app.Usage = "IPFS search engine."

	app.Commands = []cli.Command{
		{
			Name:    "crawl",
			Aliases: []string{"c"},
			Usage:   "start crawling at `HASH`",
			Action:  crawl,
		},
	}

	app.Run(os.Args)
}

func get_elastic() (*elastic.Client, error) {
	el, err := elastic.NewClient()
	if err != nil {
		return nil, err
	}
	exists, err := el.IndexExists("ipfs").Do()
	if err != nil {
		return nil, err
	}
	if !exists {
		// Index does not exist yet, create
		el.CreateIndex("ipfs")
	}

	return el, nil
}

func get_machinery() (*machinery.Server, error) {
	cnf := machinery_config.Config{
		Broker:        "redis://127.0.0.1:6379",
		ResultBackend: "redis://127.0.0.1:6379",
		// 	Exchange:      *exchange,
		// 	ExchangeType:  *exchangeType,
		// 	DefaultQueue:  *defaultQueue,
		// 	BindingKey:    *bindingKey,
	}
	server, err := machinery.NewServer(&cnf)
	if err != nil {
		return nil, err
	}

	return server, nil
}

func crawl(c *cli.Context) error {
	if c.NArg() != 1 {
		return cli.NewExitError("Please supply one hash as argument.", 1)
	}

	start_hash := c.Args().Get(0)

	fmt.Printf("Starting crawling with %s\n", start_hash)

	// For now, assume gateway running on default host:port
	sh := shell.NewShell("localhost:5001")

	el, err := get_elastic()
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	server, err := get_machinery()
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	id := indexer.NewIndexer(el)
	crawli := crawler.NewCrawler(sh, id, server)

	server.RegisterTask("crawl", func(hash string) error {
		return crawli.CrawlHash(hash)
	})

	task := signatures.TaskSignature{
		Name: "crawl",
		Args: []signatures.TaskArg{
			signatures.TaskArg{
				Type:  "string",
				Value: start_hash,
			},
		},
	}

	asyncResult, err := server.SendTask(&task)
	if err != nil {
		// failed to send the task
		return cli.NewExitError(err.Error(), 1)
	}

	taskState := asyncResult.GetState()
	fmt.Printf("Current state of %v task is:\n", taskState.TaskUUID)
	fmt.Println(taskState.State)

	worker := server.NewWorker("cli_worker")
	err = worker.Launch()
	if err != nil {
		// do something with the error
		return cli.NewExitError(err.Error(), 1)
	}

	// No error
	return nil
}
<commit_msg>Seperate crawler/seeder.<commit_after>package main

import (
	"fmt"
	machinery "github.com/RichardKnop/machinery/v1"
	machinery_config "github.com/RichardKnop/machinery/v1/config"
	signatures "github.com/RichardKnop/machinery/v1/signatures"
	"github.com/dokterbob/ipfs-search/crawler"
	"github.com/dokterbob/ipfs-search/indexer"
	"gopkg.in/ipfs/go-ipfs-api.v1"
	"gopkg.in/olivere/elastic.v3"
	"gopkg.in/urfave/cli.v1"
	"os"
)

func main() {
	app := cli.NewApp()
	app.Name = "ipfs-search"
	app.Usage = "IPFS search engine."

	app.Commands = []cli.Command{
		{
			Name:    "add",
			Aliases: []string{"a"},
			Usage:   "add `HASH` to crawler queue",
			Action:  add,
		},
		{
			Name:    "crawl",
			Aliases: []string{"c"},
			Usage:   "start crawler",
			Action:  crawl,
		},
	}

	app.Run(os.Args)
}

func get_elastic() (*elastic.Client, error) {
	el, err := elastic.NewClient()
	if err != nil {
		return nil, err
	}
	exists, err := el.IndexExists("ipfs").Do()
	if err != nil {
		return nil, err
	}
	if !exists {
		// Index does not exist yet, create
		el.CreateIndex("ipfs")
	}

	return el, nil
}

func get_machinery() (*machinery.Server, error) {
	cnf := machinery_config.Config{
		Broker:        "redis://127.0.0.1:6379",
		ResultBackend: "redis://127.0.0.1:6379",
		// 	Exchange:      *exchange,
		// 	ExchangeType:  *exchangeType,
		// 	DefaultQueue:  *defaultQueue,
		// 	BindingKey:    *bindingKey,
	}
	server, err := machinery.NewServer(&cnf)
	if err != nil {
		return nil, err
	}

	return server, nil
}

func add(c *cli.Context) error {
	if c.NArg() != 1 {
		return cli.NewExitError("Please supply one hash as argument.", 1)
	}

	hash := c.Args().Get(0)

	fmt.Printf("Adding hash '%s' to queue\n", hash)

	server, err := get_machinery()
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	task := signatures.TaskSignature{
		Name: "crawl",
		Args: []signatures.TaskArg{
			signatures.TaskArg{
				Type:  "string",
				Value: hash,
			},
		},
	}
	asyncResult, err := server.SendTask(&task)
	if err != nil {
		// failed to send the task
		return cli.NewExitError(err.Error(), 1)
	}

	taskState := asyncResult.GetState()
	fmt.Printf("Current state of %v task is:\n", taskState.TaskUUID)
	fmt.Println(taskState.State)

	return nil
}

func crawl(c *cli.Context) error {
	// For now, assume gateway running on default host:port
	sh := shell.NewShell("localhost:5001")

	el, err := get_elastic()
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	server, err := get_machinery()
	if err != nil {
		return cli.NewExitError(err.Error(), 1)
	}

	id := indexer.NewIndexer(el)
	crawli := crawler.NewCrawler(sh, id, server)

	server.RegisterTask("crawl", func(hash string) error {
		return crawli.CrawlHash(hash)
	})

	worker := server.NewWorker("crawler")
	err = worker.Launch()
	if err != nil {
		// do something with the error
		return cli.NewExitError(err.Error(), 1)
	}

	// No error
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"archive/zip"
	"bufio"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"rsc.io/letsencrypt"

	"github.com/beevik/etree"
	"github.com/gorilla/mux"
	"github.com/urfave/negroni"
)

// Metadata metadata struct
type Metadata struct {
	Title      string    `json:"title"`
	Author     string    `json:"author"`
	Identifier string    `json:"identifier"`
	Language   string    `json:"language"`
	Modified   time.Time `json:"modified"`
}

// Link link struct
type Link struct {
	Rel      string `json:"rel,omitempty"`
	Href     string `json:"href"`
	TypeLink string `json:"type"`
	Height   int    `json:"height,omitempty"`
	Width    int    `json:"width,omitempty"`
}

// Manifest manifest struct
type Manifest struct {
	Metadata  Metadata `json:"metadata"`
	Links     []Link   `json:"links"`
	Spine     []Link   `json:"spine,omitempty"`
	Resources []Link   `json:"resources"`
}

// Icon icon struct for AppInstall
type Icon struct {
	Src       string `json:"src"`
	Size      string `json:"size"`
	MediaType string `json:"type"`
}

// AppInstall struct for app install banner
type AppInstall struct {
	ShortName string `json:"short_name"`
	Name      string `json:"name"`
	StartURL  string `json:"start_url"`
	Display   string `json:"display"`
	Icons     Icon   `json:"icons"`
}

func main() {

	n := negroni.Classic()
	n.Use(negroni.NewStatic(http.Dir("public")))
	n.UseHandler(loanHandler(false))

	var m letsencrypt.Manager
	if err := m.CacheFile("letsencrypt.cache"); err != nil {
		log.Fatal(err)
	}

	if len(os.Args) > 1 && os.Args[1] == "dev" {
		s := &http.Server{
			Handler:        n,
			ReadTimeout:    10 * time.Second,
			WriteTimeout:   10 * time.Second,
			MaxHeaderBytes: 1 << 20,
			Addr:           ":8080",
		}

		//		log.Fatal(s.ListenAndServeTLS("test.cert", "test.key"))
		log.Fatal(s.ListenAndServe())
	} else {

		s := &http.Server{
			Handler:        n,
			ReadTimeout:    10 * time.Second,
			WriteTimeout:   10 * time.Second,
			MaxHeaderBytes: 1 << 20,
			Addr:           ":443",
			TLSConfig: &tls.Config{
				GetCertificate: m.GetCertificate,
			},
		}

		log.Fatal(s.ListenAndServeTLS("", ""))
	}
}

func loanHandler(test bool) http.Handler {
	serv := mux.NewRouter()

	serv.HandleFunc("/index.html", getBooks)
	serv.HandleFunc("/", getBooks)
	serv.HandleFunc("/viewer.js", viewer)
	serv.HandleFunc("/sw.js", sw)
	serv.HandleFunc("/{filename}/", bookIndex)
	serv.HandleFunc("/{filename}/manifest.json", getManifest)
	serv.HandleFunc("/{filename}/webapp.webmanifest", getWebAppManifest)
	serv.HandleFunc("/{filename}/index.html", bookIndex)
	serv.HandleFunc("/{filename}/{asset:.*}", getAsset)
	return serv
}

func getManifest(w http.ResponseWriter, req *http.Request) {
	var opfFileName string
	var manifestStruct Manifest
	var metaStruct Metadata

	metaStruct.Modified = time.Now()

	vars := mux.Vars(req)
	filename := vars["filename"]
	filename_path := "books/" + filename

	self := Link{
		Rel:      "self",
		Href:     "http://" + req.Host + "/" + filename + "/manifest.json",
		TypeLink: "application/json",
	}
	manifestStruct.Links = make([]Link, 1)
	manifestStruct.Resources = make([]Link, 0)
	manifestStruct.Resources = make([]Link, 0)
	manifestStruct.Links[0] = self

	zipReader, err := zip.OpenReader(filename_path)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, f := range zipReader.File {
		if f.Name == "META-INF/container.xml" {
			rc, errOpen := f.Open()
			if errOpen != nil {
				fmt.Println("error openging " + f.Name)
			}
			doc := etree.NewDocument()
			_, err = doc.ReadFrom(rc)
			if err == nil {
				root := doc.SelectElement("container")
				rootFiles := root.SelectElements("rootfiles")
				for _, rootFileTag := range rootFiles {
					rootFile := rootFileTag.SelectElement("rootfile")
					if rootFile != nil {
						opfFileName = rootFile.SelectAttrValue("full-path", "")
					}
				}
			} else {
				fmt.Println(err)
			}
			rc.Close()
		}
	}

	if opfFileName != "" {
		for _, f := range zipReader.File {
			if f.Name == opfFileName {
				rc, errOpen := f.Open()
				if errOpen != nil {
					fmt.Println("error openging " + f.Name)
				}
				doc := etree.NewDocument()
				_, err = doc.ReadFrom(rc)
				if err == nil {
					root := doc.SelectElement("package")
					meta := root.SelectElement("metadata")

					titleTag := meta.SelectElement("title")
					metaStruct.Title = titleTag.Text()

					langTag := meta.SelectElement("language")
					metaStruct.Language = langTag.Text()

					identifierTag := meta.SelectElement("identifier")
					metaStruct.Identifier = identifierTag.Text()

					creatorTag := meta.SelectElement("creator")
					metaStruct.Author = creatorTag.Text()

					bookManifest := root.SelectElement("manifest")
					itemsManifest := bookManifest.SelectElements("item")
					for _, item := range itemsManifest {
						linkItem := Link{}
						linkItem.TypeLink = item.SelectAttrValue("media-type", "")
						linkItem.Href = item.SelectAttrValue("href", "")
						if linkItem.TypeLink == "application/xhtml+xml" {
							manifestStruct.Spine = append(manifestStruct.Spine, linkItem)
						} else {
							manifestStruct.Resources = append(manifestStruct.Resources, linkItem)
						}
					}

					manifestStruct.Metadata = metaStruct
					j, _ := json.Marshal(manifestStruct)
					w.Header().Set("Content-Type", "application/json")
					w.Header().Set("Access-Control-Allow-Origin", "*")
					w.Write(j)
					return
				}
			}
		}
	}

}

func getAsset(w http.ResponseWriter, req *http.Request) {
	var opfFileName string
	var buff string

	vars := mux.Vars(req)
	filename := "books/" + vars["filename"]
	assetname := vars["asset"]
	jsInject := req.URL.Query().Get("js")

	zipReader, err := zip.OpenReader(filename)
	if err != nil {
		fmt.Println(err)
	}

	for _, f := range zipReader.File {
		if f.Name == "META-INF/container.xml" {
			rc, errOpen := f.Open()
			if errOpen != nil {
				fmt.Println("error openging " + f.Name)
			}
			doc := etree.NewDocument()
			_, err = doc.ReadFrom(rc)
			if err == nil {
				root := doc.SelectElement("container")
				rootFiles := root.SelectElements("rootfiles")
				for _, rootFileTag := range rootFiles {
					rootFile := rootFileTag.SelectElement("rootfile")
					if rootFile != nil {
						opfFileName = rootFile.SelectAttrValue("full-path", "")
					}
				}
			} else {
				fmt.Println(err)
			}
			rc.Close()
		}
	}

	resourcePath := strings.Split(opfFileName, "/")[0]

	for _, f := range zipReader.File {
		//fmt.Println(f.Name)
		if f.Name == resourcePath+"/"+assetname {
			rc, errOpen := f.Open()
			if errOpen != nil {
				fmt.Println("error openging " + f.Name)
			}
			defer rc.Close()

			extension := filepath.Ext(f.Name)
			if extension == ".css" {
				w.Header().Set("Content-Type", "text/css")
			}
			if extension == ".xml" {
				w.Header().Set("Content-Type", "application/xhtml+xml")
			}
			if extension == ".js" {
				w.Header().Set("Content-Type", "text/javascript")
			}
			w.Header().Set("Access-Control-Allow-Origin", "*")

			if jsInject != "" {
				scanner := bufio.NewScanner(rc)
				for scanner.Scan() {
					if strings.Contains(scanner.Text(), "") {
						buff += strings.Replace(scanner.Text(), "", "'", 1) + "\n"
					} else {
						buff += scanner.Text() + "\n"
					}
				}
			} else {
				buffByte, _ := ioutil.ReadAll(rc)
				buff = string(buffByte)
			}

			buffReader := strings.NewReader(string(buff))
			http.ServeContent(w, req, assetname, f.ModTime(), buffReader)
			return
		}
	}

}

func getWebAppManifest(w http.ResponseWriter, req *http.Request) {
	var opfFileName string
	var webapp AppInstall

	vars := mux.Vars(req)
	filename := "books/" + vars["filename"]

	webapp.Display = "standalone"
	webapp.StartURL = "index.html"
	webapp.Icons = Icon{
		Size:      "144x144",
		Src:       "/logo.png",
		MediaType: "image/png",
	}

	zipReader, err := zip.OpenReader(filename)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, f := range zipReader.File {
		if f.Name == "META-INF/container.xml" {
			rc, errOpen := f.Open()
			if errOpen != nil {
				fmt.Println("error openging " + f.Name)
			}
			doc := etree.NewDocument()
			_, err = doc.ReadFrom(rc)
			if err == nil {
				root := doc.SelectElement("container")
				rootFiles := root.SelectElements("rootfiles")
				for _, rootFileTag := range rootFiles {
					rootFile := rootFileTag.SelectElement("rootfile")
					if rootFile != nil {
						opfFileName = rootFile.SelectAttrValue("full-path", "")
					}
				}
			} else {
				fmt.Println(err)
			}
			rc.Close()
		}
	}

	if opfFileName != "" {
		for _, f := range zipReader.File {
			if f.Name == opfFileName {
				rc, errOpen := f.Open()
				if errOpen != nil {
					fmt.Println("error openging " + f.Name)
				}
				doc := etree.NewDocument()
				_, err = doc.ReadFrom(rc)
				if err == nil {
					root := doc.SelectElement("package")
					meta := root.SelectElement("metadata")

					titleTag := meta.SelectElement("title")
					webapp.Name = titleTag.Text()
					webapp.ShortName = titleTag.Text()

					j, _ := json.Marshal(webapp)
					w.Header().Set("Content-Type", "application/json")
					w.Header().Set("Access-Control-Allow-Origin", "*")
					w.Write(j)
					return
				}
			}
		}
	}

}

func bookIndex(w http.ResponseWriter, req *http.Request) {
	var err error

	vars := mux.Vars(req)
	filename := "books/" + vars["filename"]

	t, err := template.ParseFiles("index.html") // Parse template file.
	if err != nil {
		fmt.Println(err)
	}
	t.Execute(w, filename) // merge.
}

func getBooks(w http.ResponseWriter, req *http.Request) {
	var books []string

	files, _ := ioutil.ReadDir("books")
	for _, f := range files {
		fmt.Println(f.Name())
		books = append(books, f.Name())
	}

	t, err := template.ParseFiles("book_index.html") // Parse template file.
	if err != nil {
		fmt.Println(err)
	}
	t.Execute(w, books)
}

func viewer(w http.ResponseWriter, req *http.Request) {

	f, _ := os.OpenFile("public/viewer.js", os.O_RDONLY, 666)
	buff, _ := ioutil.ReadAll(f)

	w.Header().Set("Content-Type", "text/javascript")
	w.Write(buff)
}

func sw(w http.ResponseWriter, req *http.Request) {

	f, _ := os.OpenFile("public/sw.js", os.O_RDONLY, 666)
	buff, _ := ioutil.ReadAll(f)

	w.Header().Set("Content-Type", "text/javascript")
	w.Write(buff)
}
<commit_msg>can insert javascript in html source, fix typo<commit_after>package main

import (
	"archive/zip"
	"bufio"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"rsc.io/letsencrypt"

	"github.com/beevik/etree"
	"github.com/gorilla/mux"
	"github.com/urfave/negroni"
)

// Metadata metadata struct
type Metadata struct {
	Title      string    `json:"title"`
	Author     string    `json:"author"`
	Identifier string    `json:"identifier"`
	Language   string    `json:"language"`
	Modified   time.Time `json:"modified"`
}

// Link link struct
type Link struct {
	Rel      string `json:"rel,omitempty"`
	Href     string `json:"href"`
	TypeLink string `json:"type"`
	Height   int    `json:"height,omitempty"`
	Width    int    `json:"width,omitempty"`
}

// Manifest manifest struct
type Manifest struct {
	Metadata  Metadata `json:"metadata"`
	Links     []Link   `json:"links"`
	Spine     []Link   `json:"spine,omitempty"`
	Resources []Link   `json:"resources"`
}

// Icon icon struct for AppInstall
type Icon struct {
	Src       string `json:"src"`
	Size      string `json:"size"`
	MediaType string `json:"type"`
}

// AppInstall struct for app install banner
type AppInstall struct {
	ShortName string `json:"short_name"`
	Name      string `json:"name"`
	StartURL  string `json:"start_url"`
	Display   string `json:"display"`
	Icons     Icon   `json:"icons"`
}

func main() {

	n := negroni.Classic()
	n.Use(negroni.NewStatic(http.Dir("public")))
	n.UseHandler(loanHandler(false))

	var m letsencrypt.Manager
	if err := m.CacheFile("letsencrypt.cache"); err != nil {
		log.Fatal(err)
	}

	if len(os.Args) > 1 && os.Args[1] == "dev" {
		s := &http.Server{
			Handler:        n,
			ReadTimeout:    10 * time.Second,
			WriteTimeout:   10 * time.Second,
			MaxHeaderBytes: 1 << 20,
			Addr:           ":8080",
		}

		//		log.Fatal(s.ListenAndServeTLS("test.cert", "test.key"))
		log.Fatal(s.ListenAndServe())
	} else {

		s := &http.Server{
			Handler:        n,
			ReadTimeout:    10 * time.Second,
			WriteTimeout:   10 * time.Second,
			MaxHeaderBytes: 1 << 20,
			Addr:           ":443",
			TLSConfig: &tls.Config{
				GetCertificate: m.GetCertificate,
			},
		}

		log.Fatal(s.ListenAndServeTLS("", ""))
	}
}

func loanHandler(test bool) http.Handler {
	serv := mux.NewRouter()

	serv.HandleFunc("/index.html", getBooks)
	serv.HandleFunc("/", getBooks)
	serv.HandleFunc("/viewer.js", viewer)
	serv.HandleFunc("/sw.js", sw)
	serv.HandleFunc("/{filename}/", bookIndex)
	serv.HandleFunc("/{filename}/manifest.json", getManifest)
	serv.HandleFunc("/{filename}/webapp.webmanifest", getWebAppManifest)
	serv.HandleFunc("/{filename}/index.html", bookIndex)
	serv.HandleFunc("/{filename}/{asset:.*}", getAsset)
	return serv
}

func getManifest(w http.ResponseWriter, req *http.Request) {
	var opfFileName string
	var manifestStruct Manifest
	var metaStruct Metadata

	metaStruct.Modified = time.Now()

	vars := mux.Vars(req)
	filename := vars["filename"]
	filename_path := "books/" + filename

	self := Link{
		Rel:      "self",
		Href:     "http://" + req.Host + "/" + filename + "/manifest.json",
		TypeLink: "application/json",
	}
	manifestStruct.Links = make([]Link, 1)
	manifestStruct.Resources = make([]Link, 0)
	manifestStruct.Resources = make([]Link, 0)
	manifestStruct.Links[0] = self

	zipReader, err := zip.OpenReader(filename_path)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, f := range zipReader.File {
		if f.Name == "META-INF/container.xml" {
			rc, errOpen := f.Open()
			if errOpen != nil {
				fmt.Println("error openging " + f.Name)
			}
			doc := etree.NewDocument()
			_, err = doc.ReadFrom(rc)
			if err == nil {
				root := doc.SelectElement("container")
				rootFiles := root.SelectElements("rootfiles")
				for _, rootFileTag := range rootFiles {
					rootFile := rootFileTag.SelectElement("rootfile")
					if rootFile != nil {
						opfFileName = rootFile.SelectAttrValue("full-path", "")
					}
				}
			} else {
				fmt.Println(err)
			}
			rc.Close()
		}
	}

	if opfFileName != "" {
		for _, f := range zipReader.File {
			if f.Name == opfFileName {
				rc, errOpen := f.Open()
				if errOpen != nil {
					fmt.Println("error openging " + f.Name)
				}
				doc := etree.NewDocument()
				_, err = doc.ReadFrom(rc)
				if err == nil {
					root := doc.SelectElement("package")
					meta := root.SelectElement("metadata")

					titleTag := meta.SelectElement("title")
					metaStruct.Title = titleTag.Text()

					langTag := meta.SelectElement("language")
					metaStruct.Language = langTag.Text()

					identifierTag := meta.SelectElement("identifier")
					metaStruct.Identifier = identifierTag.Text()

					creatorTag := meta.SelectElement("creator")
					metaStruct.Author = creatorTag.Text()

					bookManifest := root.SelectElement("manifest")
					itemsManifest := bookManifest.SelectElements("item")
					for _, item := range itemsManifest {
						linkItem := Link{}
						linkItem.TypeLink = item.SelectAttrValue("media-type", "")
						linkItem.Href = item.SelectAttrValue("href", "")
						if linkItem.TypeLink == "application/xhtml+xml" {
							manifestStruct.Spine = append(manifestStruct.Spine, linkItem)
						} else {
							manifestStruct.Resources = append(manifestStruct.Resources, linkItem)
						}
					}

					manifestStruct.Metadata = metaStruct
					j, _ := json.Marshal(manifestStruct)
					w.Header().Set("Content-Type", "application/json")
					w.Header().Set("Access-Control-Allow-Origin", "*")
					w.Write(j)
					return
				}
			}
		}
	}

}

func getAsset(w http.ResponseWriter, req *http.Request) {
	var opfFileName string
	var buff string

	vars := mux.Vars(req)
	filename := "books/" + vars["filename"]
	assetname := vars["asset"]
	jsInject := req.URL.Query().Get("js")

	zipReader, err := zip.OpenReader(filename)
	if err != nil {
		fmt.Println(err)
	}

	for _, f := range zipReader.File {
		if f.Name == "META-INF/container.xml" {
			rc, errOpen := f.Open()
			if errOpen != nil {
				fmt.Println("error openging " + f.Name)
			}
			doc := etree.NewDocument()
			_, err = doc.ReadFrom(rc)
			if err == nil {
				root := doc.SelectElement("container")
				rootFiles := root.SelectElements("rootfiles")
				for _, rootFileTag := range rootFiles {
					rootFile := rootFileTag.SelectElement("rootfile")
					if rootFile != nil {
						opfFileName = rootFile.SelectAttrValue("full-path", "")
					}
				}
			} else {
				fmt.Println(err)
			}
			rc.Close()
		}
	}

	resourcePath := strings.Split(opfFileName, "/")[0]

	for _, f := range zipReader.File {
		//fmt.Println(f.Name)
		if f.Name == resourcePath+"/"+assetname {
			rc, errOpen := f.Open()
			if errOpen != nil {
				fmt.Println("error openging " + f.Name)
			}
			defer rc.Close()

			extension := filepath.Ext(f.Name)
			if extension == ".css" {
				w.Header().Set("Content-Type", "text/css")
			}
			if extension == ".xml" {
				w.Header().Set("Content-Type", "application/xhtml+xml")
			}
			if extension == ".js" {
				w.Header().Set("Content-Type", "text/javascript")
			}
			w.Header().Set("Access-Control-Allow-Origin", "*")

			if jsInject != "" {
				scanner := bufio.NewScanner(rc)
				for scanner.Scan() {
					if strings.Contains(scanner.Text(), "") {
						buff += strings.Replace(scanner.Text(), "", "'", 1) + "\n"
					} else {
						buff += scanner.Text() + "\n"
					}
				}
			} else {
				buffByte, _ := ioutil.ReadAll(rc)
				buff = string(buffByte)
			}

			buffReader := strings.NewReader(string(buff))
			http.ServeContent(w, req, assetname, f.ModTime(), buffReader)
			return
		}
	}

}

func getWebAppManifest(w http.ResponseWriter, req *http.Request) {
	var opfFileName string
	var webapp AppInstall

	vars := mux.Vars(req)
	filename := "books/" + vars["filename"]

	webapp.Display = "standalone"
	webapp.StartURL = "index.html"
	webapp.Icons = Icon{
		Size:      "144x144",
		Src:       "/logo.png",
		MediaType: "image/png",
	}

	zipReader, err := zip.OpenReader(filename)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, f := range zipReader.File {
		if f.Name == "META-INF/container.xml" {
			rc, errOpen := f.Open()
			if errOpen != nil {
				fmt.Println("error openging " + f.Name)
			}
			doc := etree.NewDocument()
			_, err = doc.ReadFrom(rc)
			if err == nil {
				root := doc.SelectElement("container")
				rootFiles := root.SelectElements("rootfiles")
				for _, rootFileTag := range rootFiles {
					rootFile := rootFileTag.SelectElement("rootfile")
					if rootFile != nil {
						opfFileName = rootFile.SelectAttrValue("full-path", "")
					}
				}
			} else {
				fmt.Println(err)
			}
			rc.Close()
		}
	}

	if opfFileName != "" {
		for _, f := range zipReader.File {
			if f.Name == opfFileName {
				rc, errOpen := f.Open()
				if errOpen != nil {
					fmt.Println("error openging " + f.Name)
				}
				doc := etree.NewDocument()
				_, err = doc.ReadFrom(rc)
				if err == nil {
					root := doc.SelectElement("package")
					meta := root.SelectElement("metadata")

					titleTag := meta.SelectElement("title")
					webapp.Name = titleTag.Text()
					webapp.ShortName = titleTag.Text()

					j, _ := json.Marshal(webapp)
					w.Header().Set("Content-Type", "application/json")
					w.Header().Set("Access-Control-Allow-Origin", "*")
					w.Write(j)
					return
				}
			}
		}
	}

}

func bookIndex(w http.ResponseWriter, req *http.Request) {
	var err error

	vars := mux.Vars(req)
	filename := "books/" + vars["filename"]

	t, err := template.ParseFiles("index.html") // Parse template file.
	if err != nil {
		fmt.Println(err)
	}
	t.Execute(w, filename) // merge.
}

func getBooks(w http.ResponseWriter, req *http.Request) {
	var books []string

	files, _ := ioutil.ReadDir("books")
	for _, f := range files {
		fmt.Println(f.Name())
		books = append(books, f.Name())
	}

	t, err := template.ParseFiles("book_index.html") // Parse template file.
	if err != nil {
		fmt.Println(err)
	}
	t.Execute(w, books)
}

func viewer(w http.ResponseWriter, req *http.Request) {

	f, _ := os.OpenFile("public/viewer.js", os.O_RDONLY, 666)
	buff, _ := ioutil.ReadAll(f)

	w.Header().Set("Content-Type", "text/javascript")
	w.Write(buff)
}

func sw(w http.ResponseWriter, req *http.Request) {

	f, _ := os.OpenFile("public/sw.js", os.O_RDONLY, 666)
	buff, _ := ioutil.ReadAll(f)

	w.Header().Set("Content-Type", "text/javascript")
	w.Write(buff)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/christoph-k/go-fsevents"
)

func main() {
	var pids []int
	var pidslock sync.Mutex
	var command []string
	var exclude []string

	for i, arg := range os.Args {
		if arg == "--" {
			command = os.Args[i+1:]
		}
		if arg == "-exclude" {
			excludestr := os.Args[i+1]
			exclude = strings.Split(excludestr, ",")
			for idx, e := range exclude {
				exclude[idx] = strings.Trim(e, " ")
			}
		}
		exclude = append(exclude, "/.git/")
		exclude = append(exclude, "/.svn/")
		exclude = append(exclude, "/.tmp/")
	}
	if len(command) == 0 {
		usage()
		os.Exit(1)
	}

	// intercept SIGINT and kill childprocesses
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		<-c
		kill(&pids, &pidslock)
		os.Exit(0)
	}()

	w, err := fsevents.NewWatcher(".", time.Millisecond*200)
	if err != nil {
		panic(err)
	}
	go run(&pids, &pidslock, command)
	for {
		e := <-w.EventChan
		excluded := false
		for _, excl := range exclude {
			if strings.Contains(e.Path, excl) {
				excluded = true
			}
		}
		if e.FileInfo == nil || e.FileInfo.IsDir() || excluded {
			continue
		}
		fmt.Printf("%v has changed\n", e.Path)
		kill(&pids, &pidslock)
		w.Stop()
		w, err = fsevents.NewWatcher(".", time.Millisecond*200)
		if err != nil {
			panic(err)
		}
		go run(&pids, &pidslock, command)
	}
}

func run(pids *[]int, pidslock *sync.Mutex, command []string) {
	fmt.Printf("running %v\n", command)
	cmd := exec.Command(command[0], command[1:]...)
	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Start()

	p := cmd.Process
	if p != nil {
		pidslock.Lock()
		*pids = append(*pids, p.Pid)
		pidslock.Unlock()
	}
	cmd.Wait()
}

func kill(pids *[]int, pidslock *sync.Mutex) {
	pidslock.Lock()
	defer pidslock.Unlock()
	for _, pid := range *pids {
		fmt.Printf("killing %v\n", pid)
		syscall.Kill(-pid, syscall.SIGTERM)
		time.Sleep(time.Millisecond * 100)
		syscall.Kill(-pid, syscall.SIGKILL)
	}
	*pids = make([]int, 0)
}

func usage() {
	fmt.Printf("usage: wr [-exclude \"file1, file2\"] -- <command with args>\n")
}
<commit_msg>add debug option<commit_after>package main

import (
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/christoph-k/go-fsevents"
)

var debug = false

func main() {
	var pids []int
	var pidslock sync.Mutex
	var command []string
	var exclude []string

	for i, arg := range os.Args {
		switch arg {
		case "--":
			command = os.Args[i+1:]
			break
		case "-exclude":
			excludestr := os.Args[i+1]
			exclude = strings.Split(excludestr, ",")
			for idx, e := range exclude {
				exclude[idx] = strings.Trim(e, " ")
			}
		case "-debug":
			debug = true
		}
		exclude = append(exclude, "/.git/")
		exclude = append(exclude, "/.svn/")
		exclude = append(exclude, "/.tmp/")
	}
	if len(command) == 0 {
		usage()
		os.Exit(1)
	}

	logDebugf("running in debug mode\n")
	// intercept SIGINT and kill childprocesses
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		<-c
		kill(&pids, &pidslock)
		os.Exit(0)
	}()

	w, err := fsevents.NewWatcher(".", time.Millisecond*200)
	if err != nil {
		panic(err)
	}
	go run(&pids, &pidslock, command)
	for {
		e := <-w.EventChan
		excluded := false
		for _, excl := range exclude {
			if strings.Contains(e.Path, excl) {
				excluded = true
			}
		}
		if e.FileInfo == nil || e.FileInfo.IsDir() || excluded {
			continue
		}
		fmt.Printf("%v has changed\n", e.Path)
		kill(&pids, &pidslock)
		logDebugf("stopping watcher\n")
		w.Stop()
		w, err = fsevents.NewWatcher(".", time.Millisecond*200)
		if err != nil {
			panic(err)
		}
		go run(&pids, &pidslock, command)
	}
}

func run(pids *[]int, pidslock *sync.Mutex, command []string) {
	fmt.Printf("running %v\n", command)
	cmd := exec.Command(command[0], command[1:]...)
	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Start()

	p := cmd.Process
	if p != nil {
		pidslock.Lock()
		*pids = append(*pids, p.Pid)
		pidslock.Unlock()
	}
	cmd.Wait()
}

func kill(pids *[]int, pidslock *sync.Mutex) {
	logDebugf("locking pidslock\n")
	pidslock.Lock()
	defer pidslock.Unlock()
	logDebugf("locked pidslock\n")
	for _, pid := range *pids {
		fmt.Printf("killing %v\n", pid)
		logDebugf("sending SIGTERM to %v\n", -pid)
		syscall.Kill(-pid, syscall.SIGTERM)
		time.Sleep(time.Millisecond * 100)
		logDebugf("sending SIGKILL to %v\n", -pid)
		syscall.Kill(-pid, syscall.SIGKILL)
	}
	*pids = make([]int, 0)
}

func usage() {
	fmt.Printf("usage: wr [-exclude \"file1, file2\"] -- <command with args>\n")
}

func logDebugf(str string, v ...interface{}) {
	if debug {
		fmt.Printf(str, v...)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"flag"
	"fmt"
	"net/http"

	"strings"
	"syscall"

	"github.com/bitly/go-nsq"
	"github.com/garyburd/redigo/redis"
	"github.com/op/go-logging"
	"github.com/pressly/gohttpware/auth"
	"github.com/pressly/gohttpware/route"
	"github.com/zenazn/goji/graceful"
	"github.com/zenazn/goji/web"
	"github.com/zenazn/goji/web/middleware"
)

var (
	configPath = flag.String("config-file", "./config.toml", "path to qmd config file")
	log        = logging.MustGetLogger("qmd")

	config   Config
	producer *nsq.Producer
	consumer *nsq.Consumer
	redisDB  *redis.Pool
)

const (
	VERSION = "0.1.0"
)

func main() {
	var err error

	flag.Parse()

	// Server config
	err = config.Load(*configPath)
	if err != nil {
		log.Fatal(err)
	}

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

	log.Info("=====> [ QMD v%s ] <=====", VERSION)

	// Setup facilities
	producer, err = nsq.NewProducer(config.QueueAddr, nsq.NewConfig())
	if err != nil {
		log.Fatal(err)
	}
	redisDB = newRedisPool(config.RedisAddr)

	// Script processing worker
	worker, err := NewWorker(config)
	if err != nil {
		log.Fatal(err)
	}
	go worker.Run()

	// Http server
	w := web.New()

	w.Use(middleware.Logger)
	w.Use(middleware.Recoverer)
	w.Use(Heartbeat)
	if config.Auth.Enabled {
		basicAuthWithRedis := func(r *http.Request, s []string) bool {
			user, pass := s[0], s[1]
			check, err := checkRedisUser(user)
			if err != nil {
				log.Error(err.Error())
				return false
			}
			if check != true {
				log.Error("User: %s is blocked", user)
				return false
			}

			authString := fmt.Sprintf("%s:%s", user, pass)
			auth := r.Header.Get("Authorization")
			if !strings.HasPrefix(auth, "Basic ") {
				return false
			}
			p, err := base64.StdEncoding.DecodeString(auth[6:])
			if err != nil || string(p) != authString {
				err = failRedisUser(user)
				if err != nil {
					log.Error(err.Error())
				}
				return false
			}
			return true
		}

		authFunc := auth.Wrap(
			basicAuthWithRedis,
			"Restricted",
			config.Auth.Username,
			config.Auth.Password,
		)
		w.Use(authFunc)
	}
	w.Use(route.AllowSlash)

	w.Get("/scripts", GetAllScripts)
	w.Put("/scripts", ReloadScripts)
	w.Post("/scripts/:name", RunScript)
	w.Get("/scripts/:name/logs", GetAllLogs)
	w.Get("/scripts/:name/logs/:id", GetLog)
	w.Handle("/*", AdminProxy)

	// Spin up the server with graceful hooks
	graceful.PreHook(func() {
		log.Info("Stopping queue producer")
		producer.Stop()

		log.Info("Stopping queue workers")
		worker.Stop()

		log.Info("Closing redis connections")
		redisDB.Close()
	})

	graceful.AddSignal(syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

	err = graceful.ListenAndServe(config.ListenOnAddr, w)
	if err != nil {
		log.Fatal(err)
	}
	graceful.Wait()
}
<commit_msg>Fix auth logic.<commit_after>package main

import (
	"encoding/base64"
	"flag"
	"fmt"
	"net/http"

	"strings"
	"syscall"

	"github.com/bitly/go-nsq"
	"github.com/garyburd/redigo/redis"
	"github.com/op/go-logging"
	"github.com/pressly/gohttpware/auth"
	"github.com/pressly/gohttpware/route"
	"github.com/zenazn/goji/graceful"
	"github.com/zenazn/goji/web"
	"github.com/zenazn/goji/web/middleware"
)

var (
	configPath = flag.String("config-file", "./config.toml", "path to qmd config file")
	log        = logging.MustGetLogger("qmd")

	config   Config
	producer *nsq.Producer
	consumer *nsq.Consumer
	redisDB  *redis.Pool
)

const (
	VERSION = "0.1.0"
)

func main() {
	var err error

	flag.Parse()

	// Server config
	err = config.Load(*configPath)
	if err != nil {
		log.Fatal(err)
	}

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

	log.Info("=====> [ QMD v%s ] <=====", VERSION)

	// Setup facilities
	producer, err = nsq.NewProducer(config.QueueAddr, nsq.NewConfig())
	if err != nil {
		log.Fatal(err)
	}
	redisDB = newRedisPool(config.RedisAddr)

	// Script processing worker
	worker, err := NewWorker(config)
	if err != nil {
		log.Fatal(err)
	}
	go worker.Run()

	// Http server
	w := web.New()

	w.Use(middleware.Logger)
	w.Use(middleware.Recoverer)
	w.Use(Heartbeat)
	if config.Auth.Enabled {
		basicAuthWithRedis := func(r *http.Request, secrets []string) bool {
			var err error
			secret := fmt.Sprintf("%s:%s", secrets[0], secrets[1])

			auth := r.Header.Get("Authorization")
			prefix := "Basic "
			if !strings.HasPrefix(auth, prefix) {
				return false
			}
			givenSecret := auth[len(prefix):]
			decodedSecret, err := base64.StdEncoding.DecodeString(givenSecret)
			if err != nil {
				log.Error(err.Error())
				return false
			}

			user := strings.Split(string(decodedSecret), ":")[0]
			check, err := checkRedisUser(user)
			if err != nil {
				log.Error(err.Error())
				return false
			}
			if check != true {
				log.Error("User: %s is blocked", user)
				return false
			}

			if string(decodedSecret) == secret {
				return true
			}
			if err := failRedisUser(user); err != nil {
				log.Error(err.Error())
			}
			return false
		}

		authFunc := auth.Wrap(
			basicAuthWithRedis,
			"Restricted",
			config.Auth.Username,
			config.Auth.Password,
		)
		w.Use(authFunc)
	}
	w.Use(route.AllowSlash)

	w.Get("/scripts", GetAllScripts)
	w.Put("/scripts", ReloadScripts)
	w.Post("/scripts/:name", RunScript)
	w.Get("/scripts/:name/logs", GetAllLogs)
	w.Get("/scripts/:name/logs/:id", GetLog)
	w.Handle("/*", AdminProxy)

	// Spin up the server with graceful hooks
	graceful.PreHook(func() {
		log.Info("Stopping queue producer")
		producer.Stop()

		log.Info("Stopping queue workers")
		worker.Stop()

		log.Info("Closing redis connections")
		redisDB.Close()
	})

	graceful.AddSignal(syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

	err = graceful.ListenAndServe(config.ListenOnAddr, w)
	if err != nil {
		log.Fatal(err)
	}
	graceful.Wait()
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/csv"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	humanize "github.com/dustin/go-humanize"
	"github.com/lannonbr/MirrorBandwidthStats/models"
)

func cleanupBytes(str string) string {
	return strings.TrimSuffix(str, ".0")
}

func loadBandwidthCSV(filename string) []models.BandwidthEntry {
	csvfile, _ := os.Open(filename)
	reader := csv.NewReader(bufio.NewReader(csvfile))
	reader.Comment = '"'

	entries := []models.BandwidthEntry{}

	for {
		line, err := reader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatalln("Error reading csv line", err)
		}

		recv, _ := strconv.ParseUint(cleanupBytes(line[0]), 10, 64)
		send, _ := strconv.ParseUint(cleanupBytes(line[1]), 10, 64)

		entries = append(entries, models.BandwidthEntry{
			Recv:      recv,
			Send:      send,
			Timestamp: line[2],
		})
	}

	return entries
}

func humanizeBits(bits uint64) string {
	str := humanize.Bytes(bits)
	strArr := strings.Split(str, " ")
	str = strArr[0] + string([]rune(strArr[1])[0]) + "b"
	return str
}

func analyzeFile(filename string, fullPrint bool) (uint64, uint64, uint64, uint64) {
	entries := loadBandwidthCSV(filename)

	var totalRecv, totalSend uint64

	for _, entry := range entries {
		totalRecv += entry.Recv
		totalSend += entry.Send
	}

	if fullPrint {
		fmt.Println("Filename:", filename)
	}

	humanRecv := humanize.Bytes(totalRecv)
	humanSend := humanize.Bytes(totalSend)

	totalOverall := totalRecv + totalSend
	humanOverall := humanize.Bytes(totalOverall)

	rate := ((totalRecv + totalSend) * 8) / 3550

	if fullPrint {
		fmt.Println("Total Received:", humanRecv)
		fmt.Println("Total Sent:", humanSend)
		fmt.Println("Total overall:", humanOverall)
		fmt.Println("Rate:", humanizeBits(rate)+"/sec")
		fmt.Println("------")
	}

	return totalRecv, totalSend, totalOverall, rate
}

func main() {

	files := os.Args[1:]

	var counter int

	var totalRecv, totalSend, totalOverall, totalRate, avgRate uint64

	for _, arg := range files {
		recv, send, overall, rate := analyzeFile(arg, false)
		counter++

		totalRecv += recv
		totalSend += send
		totalOverall += overall

		totalRate += rate
	}

	avgRate = totalRate / uint64(counter)

	fmt.Println("Recieved:", humanize.Bytes(totalRecv))
	fmt.Println("Sent:", humanize.Bytes(totalSend))
	fmt.Println("Overall:", humanize.Bytes(totalOverall))
	fmt.Println("Rate:", humanizeBits(avgRate)+"/sec")

}
<commit_msg>Added different formats<commit_after>package main

import (
	"bufio"
	"encoding/csv"
	"fmt"
	"io"
	"log"
	"os"
	"regexp"
	"strconv"
	"strings"

	humanize "github.com/dustin/go-humanize"
	"github.com/lannonbr/MirrorBandwidthStats/models"
)

func cleanupBytes(str string) string {
	return strings.TrimSuffix(str, ".0")
}

func loadBandwidthCSV(filename string) []models.BandwidthEntry {
	csvfile, _ := os.Open(filename)
	reader := csv.NewReader(bufio.NewReader(csvfile))
	reader.Comment = '"'

	entries := []models.BandwidthEntry{}

	for {
		line, err := reader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatalln("Error reading csv line", err)
		}

		recv, _ := strconv.ParseUint(cleanupBytes(line[0]), 10, 64)
		send, _ := strconv.ParseUint(cleanupBytes(line[1]), 10, 64)

		entries = append(entries, models.BandwidthEntry{
			Recv:      recv,
			Send:      send,
			Timestamp: line[2],
		})
	}

	return entries
}

func humanizeBits(bits uint64) string {
	str := humanize.Bytes(bits)
	strArr := strings.Split(str, " ")
	str = strArr[0] + string([]rune(strArr[1])[0]) + "b"
	return str
}

func analyzeFile(filename string, fullPrint bool) (uint64, uint64, uint64, uint64) {
	entries := loadBandwidthCSV(filename)

	var totalRecv, totalSend uint64

	for _, entry := range entries {
		totalRecv += entry.Recv
		totalSend += entry.Send
	}

	totalOverall := totalRecv + totalSend

	rate := ((totalRecv + totalSend) * 8) / 3550

	if fullPrint {
		humanRecv := humanize.Bytes(totalRecv)
		humanSend := humanize.Bytes(totalSend)
		humanOverall := humanize.Bytes(totalOverall)

		fmt.Println("Filename:", filename)

		fmt.Println("Total Received:", humanRecv)
		fmt.Println("Total Sent:", humanSend)
		fmt.Println("Total overall:", humanOverall)
		fmt.Println("Rate:", humanizeBits(rate)+"/sec")
		fmt.Println("------")
	}

	return totalRecv, totalSend, totalOverall, rate
}

func prettyPrint(date string, totalRecv, totalSend, totalOverall, avgRate uint64) {
	fmt.Printf("Timestamp: %v\n", date)
	fmt.Println("------------")
	fmt.Println("Recieved:", humanize.Bytes(totalRecv))
	fmt.Println("Sent:", humanize.Bytes(totalSend))
	fmt.Println("Overall:", humanize.Bytes(totalOverall))
	fmt.Println("Rate:", humanizeBits(avgRate)+"/sec")
}

func csvPrint(date string, totalRecv, totalSend, totalOverall, avgRate uint64) {
	fmt.Printf("%s,%s,%s,%s,%s\n", date, humanize.Bytes(totalRecv), humanize.Bytes(totalSend), humanize.Bytes(totalOverall), humanizeBits(avgRate)+"/sec")
}

func csvPrintRaw(date string, totalRecv, totalSend, totalOverall, avgRate uint64) {
	fmt.Printf("%s,%d,%d,%d,%d", date, totalRecv, totalSend, totalOverall, avgRate)
}

func main() {

	format := os.Args[1]
	files := os.Args[2:]

	dateRegex, _ := regexp.Compile("([A-Z][a-z]{2,3})-([\\d]{1,2})-([\\d]{4})_([\\d]{2})")

	arr := dateRegex.FindStringSubmatch(files[0])

	month, day, year, hour := arr[1], arr[2], arr[3], arr[4]

	date := fmt.Sprintf("%s/%s/%s", month, day, year)
	dateWithHour := fmt.Sprintf("%s/%s/%s %s:00", month, day, year, hour)
	dateMonth := fmt.Sprintf("%s/%s", month, year)

	var counter int

	var totalRecv, totalSend, totalOverall, totalRate, avgRate uint64

	for _, arg := range files {
		recv, send, overall, rate := analyzeFile(arg, false)
		counter++

		totalRecv += recv
		totalSend += send
		totalOverall += overall

		totalRate += rate
	}

	avgRate = totalRate / uint64(counter)

	switch format {
	//Pretty Printed Formats
	case "pretty_month":
		prettyPrint(dateMonth, totalRecv, totalSend, totalOverall, avgRate)
	case "pretty_day":
		prettyPrint(date, totalRecv, totalSend, totalOverall, avgRate)
	case "pretty_hour":
		prettyPrint(dateWithHour, totalRecv, totalSend, totalOverall, avgRate)
	// CSV Formats
	case "csv_month":
		csvPrint(dateMonth, totalRecv, totalSend, totalOverall, avgRate)
	case "csv_day":
		csvPrint(date, totalRecv, totalSend, totalOverall, avgRate)
	case "csv_hour":
		csvPrint(dateWithHour, totalRecv, totalSend, totalOverall, avgRate)
	// Raw CSV (No humanized entries)
	case "csv_month_raw":
		csvPrintRaw(dateMonth, totalRecv, totalSend, totalOverall, avgRate)
	case "csv_day_raw":
		csvPrintRaw(date, totalRecv, totalSend, totalOverall, avgRate)
	case "csv_hour_raw":
		csvPrintRaw(dateWithHour, totalRecv, totalSend, totalOverall, avgRate)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"compress/gzip"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"time"

	"github.com/daaku/go.httpgzip"
	"github.com/gorilla/mux"
)

var listen = flag.String("listen", "localhost:8080", "host and port to listen on")
var db = flag.String("db", "purchases.db", "sqlite3 database file")

func backup() error {
	src, err := os.Open(*db)
	defer src.Close()
	if err != nil {
		return errors.New("could not open database to backup")
	}

	backupPath := path.Join(filepath.Dir(*db), "backup")
	err = os.MkdirAll(backupPath, 0755)
	if err != nil {
		return errors.New("could not create backup")
	}

	destFile := path.Join(backupPath, filepath.Base(*db)+".gz")
	dest, err := os.Create(destFile)
	defer dest.Close()
	if err != nil {
		return err
	}

	gzipWriter := gzip.NewWriter(dest)
	_, err = io.Copy(gzipWriter, src)
	if err != nil {
		return err
	}

	return gzipWriter.Close()
}

func logger(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		handler.ServeHTTP(w, r)
		log.Printf(
			"%s\t%s\t%s",
			r.Method,
			r.RequestURI,
			time.Since(start),
		)
	})
}

func main() {
	flag.Parse()

	err := backup()
	if err != nil {
		log.Panicln(err)
	}
	log.Println("backup complete")

	app := newApp()
	defer app.destroy()
	log.Println("database opened")

	r := mux.NewRouter()
	r.HandleFunc("/purchases", app.handlePurchases).Methods("GET")
	r.HandleFunc("/purchases/{id:[0-9]+}", app.handlePurchase).Methods("GET")
	r.HandleFunc("/purchases/{id:[0-9]+}", app.handleDelete).Methods("DELETE")
	r.HandleFunc("/purchases", app.handleAddPurchase).Methods("POST")

	http.Handle("/", logger(httpgzip.NewHandler(r)))

	log.Printf("Serving on %s\n", *listen)
	log.Fatal(http.ListenAndServe(*listen, nil))
}
<commit_msg>cleanup<commit_after>package main

import (
	"compress/gzip"
	"errors"
	"flag"
	"io"
	"log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"time"

	"github.com/daaku/go.httpgzip"
	"github.com/gorilla/mux"
)

var listen = flag.String("listen", "localhost:8080", "host and port to listen on")
var db = flag.String("db", "purchases.db", "sqlite3 database file")

func backup() error {
	src, err := os.Open(*db)
	defer src.Close()
	if err != nil {
		return errors.New("could not open database to backup")
	}

	backupPath := path.Join(filepath.Dir(*db), "backup")
	err = os.MkdirAll(backupPath, 0755)
	if err != nil {
		return errors.New("could not create backup")
	}

	destFile := path.Join(backupPath, filepath.Base(*db)+".gz")
	dest, err := os.Create(destFile)
	defer dest.Close()
	if err != nil {
		return err
	}

	gzipWriter := gzip.NewWriter(dest)
	_, err = io.Copy(gzipWriter, src)
	if err != nil {
		return err
	}

	return gzipWriter.Close()
}

func logger(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		handler.ServeHTTP(w, r)
		log.Printf(
			"%s\t%s\t%s",
			r.Method,
			r.RequestURI,
			time.Since(start),
		)
	})
}

func main() {
	flag.Parse()

	err := backup()
	if err != nil {
		log.Panicln(err)
	}
	log.Println("backup complete")

	app := newApp()
	defer app.destroy()
	log.Println("database opened")

	r := mux.NewRouter()
	r.HandleFunc("/purchases", app.handlePurchases).Methods("GET")
	r.HandleFunc("/purchases/{id:[0-9]+}", app.handlePurchase).Methods("GET")
	r.HandleFunc("/purchases/{id:[0-9]+}", app.handleDelete).Methods("DELETE")
	r.HandleFunc("/purchases", app.handleAddPurchase).Methods("POST")

	http.Handle("/", logger(httpgzip.NewHandler(r)))

	log.Printf("Serving on %s\n", *listen)
	log.Fatal(http.ListenAndServe(*listen, nil))
}
<|endoftext|>