<commit_before>package main

import (
	"flag"
	"log"
	"os"
	"os/user"
	"strconv"
	"strings"
	"time"

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

const (
	nameEnv       = "LICENSE_FULL_NAME"
	versionString = "2.0.0"

	usageString = `Usage: license [flags] <license-name>

Flags:
       -help     print help information
       -list     print list of available licenses
   -n, -name     full name to use on license (default %q)
   -o, -output   path to output file (prints to stdout if unspecified)
       -version  print version
   -y, -year     year to use on license (default %q)

Examples:
  license mit
  license -name "Alice L" -year 2013 bsd-3-clause
  license -o LICENSE.txt mpl-2.0`
)

var (
	stdout = log.New(os.Stdout, "", 0)
	stderr = log.New(os.Stderr, "", 0)
)

var (
	fName    string
	fYear    string
	fOutput  string
	fVersion bool
	fHelp    bool
	fList    bool
)

func main() {
	flag.StringVar(&fName, "name", "", "name on license")
	flag.StringVar(&fName, "n", "", "name on license")
	flag.StringVar(&fYear, "year", "", "year on license")
	flag.StringVar(&fYear, "y", "", "year on license")
	flag.StringVar(&fOutput, "output", "", "path to output file")
	flag.StringVar(&fOutput, "o", "", "path to output file")
	flag.BoolVar(&fVersion, "version", false, "print version")
	flag.BoolVar(&fHelp, "help", false, "print help")
	flag.BoolVar(&fList, "list", false, "print available licenses")

	flag.Usage = func() {
		printUsage()
		os.Exit(1)
	}
	flag.Parse()

	run()
}

func run() {
	if flag.NArg() != 1 && !(fVersion || fHelp || fList) {
		printUsage()
		os.Exit(1)
	}

	switch {
	case fVersion:
		printVersion()
		os.Exit(0)

	case fHelp:
		printUsage()
		os.Exit(0)

	case fList:
		printList()
		os.Exit(0)

	default:
		license := strings.ToLower(flag.Arg(0))
		printLicense(license, fOutput, getName(), getYear()) // internally calls os.Exit() on failure
	}
}

func printVersion() {
	stdout.Printf("%s", versionString)
	os.Exit(0)
}

func printUsage() {
	stderr.Printf(usageString, getName(), getYear())
	os.Exit(0)
}

func getName() string {
	if fName != "" {
		return fName
	}
	n := os.Getenv(nameEnv)
	if n != "" {
		return n
	}
	n, err := gitconfig.Username()
	if err == nil {
		return n
	}
	n, err = gitconfig.Global("user.name")
	if err == nil {
		return n
	}
	n, err = hgconfig.Username()
	if err == nil {
		return n
	}
	usr, err := user.Current()
	if err == nil {
		return usr.Name
	}
	return ""
}

func getYear() string {
	if fYear != "" {
		return fYear
	}
	return strconv.Itoa(time.Now().Year())
}
<commit_msg>extra os.Exit<commit_after>package main

import (
	"flag"
	"log"
	"os"
	"os/user"
	"strconv"
	"strings"
	"time"

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

const (
	nameEnv       = "LICENSE_FULL_NAME"
	versionString = "2.0.0"

	usageString = `Usage: license [flags] <license-name>

Flags:
       -help     print help information
       -list     print list of available licenses
   -n, -name     full name to use on license (default %q)
   -o, -output   path to output file (prints to stdout if unspecified)
       -version  print version
   -y, -year     year to use on license (default %q)

Examples:
  license mit
  license -name "Alice L" -year 2013 bsd-3-clause
  license -o LICENSE.txt mpl-2.0`
)

var (
	stdout = log.New(os.Stdout, "", 0)
	stderr = log.New(os.Stderr, "", 0)
)

var (
	fName    string
	fYear    string
	fOutput  string
	fVersion bool
	fHelp    bool
	fList    bool
)

func main() {
	flag.StringVar(&fName, "name", "", "name on license")
	flag.StringVar(&fName, "n", "", "name on license")
	flag.StringVar(&fYear, "year", "", "year on license")
	flag.StringVar(&fYear, "y", "", "year on license")
	flag.StringVar(&fOutput, "output", "", "path to output file")
	flag.StringVar(&fOutput, "o", "", "path to output file")
	flag.BoolVar(&fVersion, "version", false, "print version")
	flag.BoolVar(&fHelp, "help", false, "print help")
	flag.BoolVar(&fList, "list", false, "print available licenses")

	flag.Usage = func() {
		printUsage()
		os.Exit(1)
	}
	flag.Parse()

	run()
}

func run() {
	if flag.NArg() != 1 && !(fVersion || fHelp || fList) {
		printUsage()
		os.Exit(1)
	}

	switch {
	case fVersion:
		printVersion()
		os.Exit(0)

	case fHelp:
		printUsage()
		os.Exit(0)

	case fList:
		printList()
		os.Exit(0)

	default:
		license := strings.ToLower(flag.Arg(0))
		printLicense(license, fOutput, getName(), getYear()) // internally calls os.Exit() on failure
	}
}

func printVersion() {
	stdout.Printf("%s", versionString)
}

func printUsage() {
	stderr.Printf(usageString, getName(), getYear())
}

func getName() string {
	if fName != "" {
		return fName
	}
	n := os.Getenv(nameEnv)
	if n != "" {
		return n
	}
	n, err := gitconfig.Username()
	if err == nil {
		return n
	}
	n, err = gitconfig.Global("user.name")
	if err == nil {
		return n
	}
	n, err = hgconfig.Username()
	if err == nil {
		return n
	}
	usr, err := user.Current()
	if err == nil {
		return usr.Name
	}
	return ""
}

func getYear() string {
	if fYear != "" {
		return fYear
	}
	return strconv.Itoa(time.Now().Year())
}
<|endoftext|>


<commit_before>package router

import (
	"context"
	"net/http"
	"path"
	"strings"
)

// node represents each path part in a route and constructs a tree
type node struct {
	path     string
	handler  http.Handler
	parent   *node
	children []*node
}

// rootNode is a helper function to initialize the root "/" node for any tree.
func rootNode(route string, handler http.Handler) *node {
	n := &node{
		path:     "/",
		children: make([]*node, 0),
	}

	n.add(route, handler)

	return n
}

// add constructs the children tree for the current node matching the route provided.
// It sets the http.Handler to the final element.
func (n *node) add(route string, handler http.Handler) {
	// Root and matches
	if route == n.path || n.path == "*" {
		n.handler = handler
		return
	}

	// Remove starting and trailing "/"
	for len(route) > 1 && route[0] == '/' {
		route = route[1:]
	}
	for len(route) > 1 && route[len(route)-1] == '/' {
		route = route[:len(route)-1]
	}

	// Lookup as far as possible
	nn, remain := n.walk(strings.Split(route, "/"))

	// Add pending parts if any and stop adding after catch-all
	if len(remain) > 0 {
		if nn.path != "*" {
			// Create child
			ch := &node{
				path:     remain[0],
				children: make([]*node, 0),
				parent:   nn,
			}

			// Go deeper
			if len(remain) > 1 {
				ch.add(strings.Join(remain[1:], "/"), handler)
			} else {
				ch.handler = handler
			}

			// Save route
			nn.children = append(nn.children, ch)
			return
		}
	}
}

// walk moves through nodes for a given path until no further match is found.
func (n *node) walk(parts []string) (*node, []string) {
	// End at empty
	if len(parts) == 0 {
		return n, parts
	}

	// Search for first match in children
	for _, ch := range n.children {
		if parts[0] == ch.path {
			return ch.walk(parts[1:])
		}
	}

	// If no match, return current node and path
	return n, parts
}

// match searches for a matching route to the current request.
// If found, it adds the route params to the request context and return the corresponding handler.
func (n *node) match(r *http.Request) http.Handler {
	// Validate root node match
	if n.path != "/" {
		return nil
	}

	if r.URL.Path == "/" || r.URL.Path == "" {
		return n.handler
	}

	// Look for children match, skip first and last '/'
	i := 0
	for r.URL.Path[len(r.URL.Path)-1-i] == '/' {
		i++
	}

	// Create parameters storage
	params := make(map[string]string)

	// Get handler
	h := n.matchChild(r.URL.Path[1:len(r.URL.Path)-i], r, params)

	// Set params if needed
	if h != nil && len(params) > 0 {
		*r = *r.WithContext(context.WithValue(
			r.Context(),
			routeParamsKey{},
			params))
	}

	return h
}

// matchChild does the recursive work of matching the tree parts and try to find the correct path for a route.
func (n *node) matchChild(part string, r *http.Request, params map[string]string) http.Handler {
	// Invalid route parts
	if part == "" {
		return nil
	}

	// Remove trailing slashes
	for len(part) > 0 && part[len(part)-1] == '/' {
		n.matchChild(part[:len(part)-1], r, params)
	}

	// Split parts
	for i := range part {
		if part[i] != '/' && len(part) != (i+1) {
			continue
		}

		// Look for matches
		for _, ch := range n.children {
			// It's a parameter?
			if ch.path[0] == ':' {
				// Are we done?
				if len(part) == (i + 1) {
					// Set last param and return
					params[ch.path[1:]] = part[:i+1]
					return ch.handler
				}

				// Set param
				params[ch.path[1:]] = part[:i]

				// Go deeper
				h := ch.matchChild(part[i+1:], r, params)
				if h != nil {
					return h
				}
			}

			// Last route part
			if len(part) == (i + 1) {
				if part[:i+1] == ch.path {
					return ch.handler
				}
			}

			// Match current
			if part[:i] == ch.path {
				// Go deeper
				h := ch.matchChild(part[i+1:], r, params)
				if h != nil {
					return h
				}
			}
		}

		// Check for catch-all routes.
		for _, ch := range n.children {
			if ch.path == "*" {
				return ch.handler
			}
		}

		// No match found so far
		return nil
	}

	// No match found
	return nil
}

// buildPath returns a string representing the entire path
// from the root to the current node.
func (n *node) buildPath() string {
	if n.parent == nil {
		return n.path
	}

	return path.Join(n.parent.buildPath(), n.path)
}
<commit_msg>Use filepath.Clean to cleanup request URL Path before matching.<commit_after>package router

import (
	"context"
	"net/http"
	"path"
	"path/filepath"
	"strings"
)

// node represents each path part in a route and constructs a tree
type node struct {
	path     string
	handler  http.Handler
	parent   *node
	children []*node
}

// rootNode is a helper function to initialize the root "/" node for any tree.
func rootNode(route string, handler http.Handler) *node {
	n := &node{
		path:     "/",
		children: make([]*node, 0),
	}

	n.add(route, handler)

	return n
}

// add constructs the children tree for the current node matching the route provided.
// It sets the http.Handler to the final element.
func (n *node) add(route string, handler http.Handler) {
	// Root and matches
	if route == n.path || n.path == "*" {
		n.handler = handler
		return
	}

	// Remove starting and trailing "/"
	for len(route) > 1 && route[0] == '/' {
		route = route[1:]
	}
	for len(route) > 1 && route[len(route)-1] == '/' {
		route = route[:len(route)-1]
	}

	// Lookup as far as possible
	nn, remain := n.walk(strings.Split(route, "/"))

	// Add pending parts if any and stop adding after catch-all
	if len(remain) > 0 {
		if nn.path != "*" {
			// Create child
			ch := &node{
				path:     remain[0],
				children: make([]*node, 0),
				parent:   nn,
			}

			// Go deeper
			if len(remain) > 1 {
				ch.add(strings.Join(remain[1:], "/"), handler)
			} else {
				ch.handler = handler
			}

			// Save route
			nn.children = append(nn.children, ch)
			return
		}
	}
}

// walk moves through nodes for a given path until no further match is found.
func (n *node) walk(parts []string) (*node, []string) {
	// End at empty
	if len(parts) == 0 {
		return n, parts
	}

	// Search for first match in children
	for _, ch := range n.children {
		if parts[0] == ch.path {
			return ch.walk(parts[1:])
		}
	}

	// If no match, return current node and path
	return n, parts
}

// match searches for a matching route to the current request.
// If found, it adds the route params to the request context and return the corresponding handler.
func (n *node) match(r *http.Request) http.Handler {
	// Validate root node match
	if n.path != "/" {
		return nil
	}

	if r.URL.Path == "/" || r.URL.Path == "" {
		return n.handler
	}

	// Create parameters storage
	params := make(map[string]string)

	// Cleanup path
	r.URL.Path = filepath.Clean(r.URL.Path)

	// Get handler
	h := n.matchChild(r.URL.Path[1:], r, params)

	// Set params if needed
	if h != nil && len(params) > 0 {
		*r = *r.WithContext(context.WithValue(
			r.Context(),
			routeParamsKey{},
			params))
	}

	return h
}

// matchChild does the recursive work of matching the tree parts and try to find the correct path for a route.
func (n *node) matchChild(part string, r *http.Request, params map[string]string) http.Handler {
	// Invalid route parts
	if part == "" {
		return nil
	}

	// Remove trailing slashes
	for len(part) > 0 && part[len(part)-1] == '/' {
		n.matchChild(part[:len(part)-1], r, params)
	}

	// Split parts
	for i := range part {
		if part[i] != '/' && len(part) != (i+1) {
			continue
		}

		// Look for matches
		for _, ch := range n.children {
			// It's a parameter?
			if ch.path[0] == ':' {
				// Are we done?
				if len(part) == (i + 1) {
					// Set last param and return
					params[ch.path[1:]] = part[:i+1]
					return ch.handler
				}

				// Set param
				params[ch.path[1:]] = part[:i]

				// Go deeper
				h := ch.matchChild(part[i+1:], r, params)
				if h != nil {
					return h
				}
			}

			// Last route part
			if len(part) == (i + 1) {
				if part[:i+1] == ch.path {
					return ch.handler
				}
			}

			// Match current
			if part[:i] == ch.path {
				// Go deeper
				h := ch.matchChild(part[i+1:], r, params)
				if h != nil {
					return h
				}
			}
		}

		// Check for catch-all routes.
		for _, ch := range n.children {
			if ch.path == "*" {
				return ch.handler
			}
		}

		// No match found so far
		return nil
	}

	// No match found
	return nil
}

// buildPath returns a string representing the entire path
// from the root to the current node.
func (n *node) buildPath() string {
	if n.parent == nil {
		return n.path
	}

	return path.Join(n.parent.buildPath(), n.path)
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
  "io/ioutil"
  "github.com/google/go-github/github"
  "encoding/json"
  "log"
  "os/user"
)

func main() {
	config := loadConfiguration()
	fmt.Println(config)

	return

  fmt.Printf("Hello, world.\n")
  client := github.NewClient(nil)

  // opt := &github.ListOptions{Type: "public"}
	users, _, _ := client.Activity.ListStargazers("danoctavian", "bluntly", nil)
	fmt.Printf("%v", len(users))
}

type Configuration struct {
	githubAPIToken string
}

type Repository struct {
	stargazers []github.User
}

type ConfigJSON map[string]string

func loadConfiguration() Configuration {
  usr, err := user.Current()
  if err != nil {
      log.Fatal( err )
  }

  var configJSON ConfigJSON
  file, err := ioutil.ReadFile(usr.HomeDir + "/.go-git-me/githubAPIAuth.json")
  if err != nil {
      log.Fatal(err)
  }
  err = json.Unmarshal(file, &configJSON)
  if err != nil {
      log.Fatal(err)
  }

  return Configuration{githubAPIToken: configJSON["APIToken"]}
}

// computes
// * popularity rank
//
// * stargazer stats:
// 		-- distribution by location
//    -- distribution by expertise
// *
func computeRepoStats() {
}

<commit_msg>aded some random UI code to see how that plays out<commit_after>package main

import (
  "fmt"
  "bufio"
  "io/ioutil"
  "github.com/google/go-github/github"
  "encoding/json"
  "log"
  "os"
  "os/user"
  "golang.org/x/oauth2"
  ui "github.com/gizak/termui"
)

func main() {
	runUI()
	config := loadConfiguration()
	fmt.Println(config)

  fmt.Printf("Hello, world.\n")

	ts := oauth2.StaticTokenSource(
    &oauth2.Token{AccessToken: config.githubAPIToken},
  )

  tc := oauth2.NewClient(oauth2.NoContext, ts)

  client := github.NewClient(tc)

  opt := &github.ListOptions{Page: 1, PerPage: 200}
	users, _, _ := client.Activity.ListStargazers("danoctavian", "bluntly", opt)

	fmt.Printf("%v", len(users))

	computeRepoStats(Repository{stargazers: users})
}

type Configuration struct {
	githubAPIToken string
}

type Repository struct {
	stargazers []github.User
}

type ConfigJSON map[string]string

func loadConfiguration() Configuration {
  usr, err := user.Current()
  if err != nil {
      log.Fatal( err )
  }

  var configJSON ConfigJSON
  file, err := ioutil.ReadFile(usr.HomeDir + "/.go-git-me/githubAPIAuth.json")
  if err != nil {
      log.Fatal(err)
  }
  err = json.Unmarshal(file, &configJSON)
  if err != nil {
      log.Fatal(err)
  }

  return Configuration{githubAPIToken: configJSON["APIToken"]}
}

// computes
// * popularity rank
//
// * stargazer stats:
// 		-- distribution by location
//    -- distribution by expertise
// *
func computeRepoStats(repo Repository) {
	fmt.Println("computing...")
	fmt.Println(repo.stargazers)

}

func runUI() {
	 err := ui.Init()
	  if err != nil {
	      panic(err)
	  }
	  defer ui.Close()

	  p := ui.NewPar(":PRESS q TO QUIT DEMO")
	  p.Height = 3
	  p.Width = 50
	  p.TextFgColor = ui.ColorWhite
	  p.Border.Label = "Text Box"
	  p.Border.FgColor = ui.ColorCyan

	bc := ui.NewBarChart()
	data := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6}
	bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"}
	bc.Border.Label = "Bar Chart"
	bc.Data = data
	bc.Width = 26
	bc.Height = 10
	bc.DataLabels = bclabels
	bc.TextColor = ui.ColorGreen
	bc.BarColor = ui.ColorRed
	bc.NumColor = ui.ColorYellow

	  ui.Render(p, bc)

	  reader := bufio.NewReader(os.Stdin)
		fmt.Print("Enter text: ")
		text, _ := reader.ReadString('\n')
		fmt.Println(text)
}

<|endoftext|>


<commit_before>package main

import (
	"github.com/go-martini/martini"
	"github.com/martini-contrib/binding"
	"github.com/martini-contrib/render"
	"github.com/martini-contrib/sessions"
	"github.com/martini-contrib/strict"
	"html"
	"html/template"
	"os"
	"time"
)

func main() {

	helpers := template.FuncMap{
		// Unescape unescapes and parses HTML from database objects.
		// Used in templates such as "/post/display.tmpl"
		"unescape": func(s string) template.HTML {
			return template.HTML(html.UnescapeString(s))
		},
		// Title renders post name as a page title.
		// Otherwise it defaults to Vertigo.
		"title": func(t interface{}) string {
			post, exists := t.(Post)
			if exists {
				return post.Title
			}
			return "Vertigo"
		},
		// Date helper returns unix date as more readable one in string format.
		"date": func(d int64) string {
			return time.Unix(d, 0).String()
		},
	}

	m := martini.Classic()
	store := sessions.NewCookieStore([]byte(os.Getenv("vertigo_hash")))
	m.Use(sessions.Sessions("user", store))
	m.Use(middleware())
	m.Use(strict.Strict)
	m.Use(render.Renderer(render.Options{
		Layout: "layout",
		Funcs:  []template.FuncMap{helpers}, // Specify helper function maps for templates to access.
	}))

	m.Get("/", Homepage)

	m.Group("/feeds", func(r martini.Router) {
		r.Get("", func(res render.Render) {
			res.Redirect("/feeds/rss", 302)
		})
		r.Get("/atom", ReadFeed)
		r.Get("/rss", ReadFeed)
	})

	m.Group("/post", func(r martini.Router) {

		// Please note that `/new` route has to be before the `/:title` route. Otherwise the program will try
		// to fetch for Post named "new".
		// For now I'll keep it this way to streamline route naming.
		r.Get("/new", ProtectedPage, func(res render.Render) {
			res.HTML(200, "post/new", nil)
		})
		r.Get("/:title", ReadPost)
		r.Get("/:title/edit", EditPost)
		r.Post("/:title/edit", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Post{}), binding.ErrorHandler, UpdatePost)
		r.Get("/:title/delete", DeletePost)
		r.Get("/:title/publish", PublishPost)
		r.Post("/new", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Post{}), binding.ErrorHandler, CreatePost)
		r.Post("/search", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Search{}), binding.ErrorHandler, SearchPost)

	})

	m.Group("/user", func(r martini.Router) {

		r.Get("", ProtectedPage, ReadUser)
		//r.Post("/delete", strict.ContentType("application/x-www-form-urlencoded"), ProtectedPage, binding.Form(Person{}), DeleteUser)

		r.Get("/register", SessionRedirect, func(res render.Render) {
			res.HTML(200, "user/register", nil)
		})
		r.Post("/register", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Person{}), binding.ErrorHandler, CreateUser)

		r.Get("/login", SessionRedirect, func(res render.Render) {
			res.HTML(200, "user/login", nil)
		})
		r.Post("/login", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Person{}), LoginUser)
		r.Get("/logout", LogoutUser)

	})

	m.Group("/api", func(r martini.Router) {

		r.Get("", func(res render.Render) {
			res.HTML(200, "api/index", nil)
		})
		r.Get("/users", ReadUsers)
		r.Get("/user/:id", ReadUser)
		//r.Delete("/user", DeleteUser)
		r.Post("/user", strict.ContentType("application/json"), binding.Json(Person{}), binding.ErrorHandler, CreateUser)
		r.Post("/user/login", strict.ContentType("application/json"), binding.Json(Person{}), binding.ErrorHandler, LoginUser)
		r.Get("/user/logout", LogoutUser)

		r.Get("/posts", ReadPosts)
		r.Get("/post/:title", ReadPost)
		r.Post("/post", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, CreatePost)
		r.Get("/post/:title/publish")
		r.Post("/post/:title/edit", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, UpdatePost)
		r.Get("/post/:title/delete", DeletePost)
		r.Post("/post", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, CreatePost)
		r.Post("/post/search/:query", strict.ContentType("application/json"), binding.Json(Search{}), binding.ErrorHandler, SearchPost)

	})

	m.Router.NotFound(strict.MethodNotAllowed, strict.NotFound)
	m.Run()

}
<commit_msg>add static resource caching<commit_after>package main

import (
	"html"
	"html/template"
	"os"
	"time"

	"github.com/go-martini/martini"
	"github.com/martini-contrib/binding"
	"github.com/martini-contrib/render"
	"github.com/martini-contrib/sessions"
	"github.com/martini-contrib/strict"
)

func main() {

	helpers := template.FuncMap{
		// Unescape unescapes and parses HTML from database objects.
		// Used in templates such as "/post/display.tmpl"
		"unescape": func(s string) template.HTML {
			return template.HTML(html.UnescapeString(s))
		},
		// Title renders post name as a page title.
		// Otherwise it defaults to Vertigo.
		"title": func(t interface{}) string {
			post, exists := t.(Post)
			if exists {
				return post.Title
			}
			return "Vertigo"
		},
		// Date helper returns unix date as more readable one in string format.
		"date": func(d int64) string {
			return time.Unix(d, 0).String()
		},
	}

	m := martini.Classic()
	store := sessions.NewCookieStore([]byte(os.Getenv("vertigo_hash")))
	m.Use(sessions.Sessions("user", store))
	m.Use(middleware())
	m.Use(strict.Strict)
	m.Use(martini.Static("public", martini.StaticOptions{
		SkipLogging: true,
		Expires: func() string {
			return "Cache-Control: max-age=31536000"
		},
	}))
	m.Use(render.Renderer(render.Options{
		Layout: "layout",
		Funcs:  []template.FuncMap{helpers}, // Specify helper function maps for templates to access.
	}))

	m.Get("/", Homepage)

	m.Group("/feeds", func(r martini.Router) {
		r.Get("", func(res render.Render) {
			res.Redirect("/feeds/rss", 302)
		})
		r.Get("/atom", ReadFeed)
		r.Get("/rss", ReadFeed)
	})

	m.Group("/post", func(r martini.Router) {

		// Please note that `/new` route has to be before the `/:title` route. Otherwise the program will try
		// to fetch for Post named "new".
		// For now I'll keep it this way to streamline route naming.
		r.Get("/new", ProtectedPage, func(res render.Render) {
			res.HTML(200, "post/new", nil)
		})
		r.Get("/:title", ReadPost)
		r.Get("/:title/edit", EditPost)
		r.Post("/:title/edit", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Post{}), binding.ErrorHandler, UpdatePost)
		r.Get("/:title/delete", DeletePost)
		r.Get("/:title/publish", PublishPost)
		r.Post("/new", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Post{}), binding.ErrorHandler, CreatePost)
		r.Post("/search", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Search{}), binding.ErrorHandler, SearchPost)

	})

	m.Group("/user", func(r martini.Router) {

		r.Get("", ProtectedPage, ReadUser)
		//r.Post("/delete", strict.ContentType("application/x-www-form-urlencoded"), ProtectedPage, binding.Form(Person{}), DeleteUser)

		r.Get("/register", SessionRedirect, func(res render.Render) {
			res.HTML(200, "user/register", nil)
		})
		r.Post("/register", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Person{}), binding.ErrorHandler, CreateUser)

		r.Get("/login", SessionRedirect, func(res render.Render) {
			res.HTML(200, "user/login", nil)
		})
		r.Post("/login", strict.ContentType("application/x-www-form-urlencoded"), binding.Form(Person{}), LoginUser)
		r.Get("/logout", LogoutUser)

	})

	m.Group("/api", func(r martini.Router) {

		r.Get("", func(res render.Render) {
			res.HTML(200, "api/index", nil)
		})
		r.Get("/users", ReadUsers)
		r.Get("/user/:id", ReadUser)
		//r.Delete("/user", DeleteUser)
		r.Post("/user", strict.ContentType("application/json"), binding.Json(Person{}), binding.ErrorHandler, CreateUser)
		r.Post("/user/login", strict.ContentType("application/json"), binding.Json(Person{}), binding.ErrorHandler, LoginUser)
		r.Get("/user/logout", LogoutUser)

		r.Get("/posts", ReadPosts)
		r.Get("/post/:title", ReadPost)
		r.Post("/post", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, CreatePost)
		r.Get("/post/:title/publish")
		r.Post("/post/:title/edit", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, UpdatePost)
		r.Get("/post/:title/delete", DeletePost)
		r.Post("/post", strict.ContentType("application/json"), binding.Json(Post{}), binding.ErrorHandler, CreatePost)
		r.Post("/post/search/:query", strict.ContentType("application/json"), binding.Json(Search{}), binding.ErrorHandler, SearchPost)

	})

	m.Router.NotFound(strict.MethodNotAllowed, strict.NotFound)
	m.Run()

}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/alecthomas/kingpin"
)

type Severity string

// Linter message severity levels.
const (
	Warning Severity = "warning"
	Error   Severity = "error"
)

type Linter string

func (l Linter) Command() string {
	return string(l[0:strings.Index(string(l), ":")])
}

func (l Linter) Pattern() string {
	return string(l[strings.Index(string(l), ":"):])
}

var (
	predefinedPatterns = map[string]string{
		"PATH:LINE:COL:MESSAGE": `(?P<path>[^:]+):(?P<line>\d+):(?P<col>\d+):\s*(?P<message>.*)`,
		"PATH:LINE:MESSAGE":     `(?P<path>[^:]+):(?P<line>\d+):\s*(?P<message>.*)`,
	}
	lintersFlag = map[string]string{
		// main.go:8:10: should omit type map[string]string from declaration of var linters; it will be inferred from the right-hand side
		"golint": "golint {path}:PATH:LINE:COL:MESSAGE",
		// test/stutter.go:19: missing argument for Printf("%d"): format reads arg 1, have only 0 args
		"vet":         "go tool vet {path}:PATH:LINE:MESSAGE",
		"gotype":      "gotype {path}:PATH:LINE:COL:MESSAGE",
		"errcheck":    `errcheck {path}:(?P<path>[^:]+):(?P<line>\d+):(?P<col>\d+)\t(?P<message>.*)`,
		"varcheck":    "varcheck {path}:PATH:LINE:MESSAGE",
		"structcheck": "structcheck {path}:PATH:LINE:MESSAGE",
		"defercheck":  "defercheck {path}:PATH:LINE:MESSAGE",
	}
	linterMessageOverrideFlag = map[string]string{
		"errcheck":    "error return value not checked ({message})",
		"varcheck":    "unused global variable {message}",
		"structcheck": "unused struct field {message}",
	}
	linterSeverityFlag = map[string]string{
		"errcheck":    "warning",
		"golint":      "warning",
		"varcheck":    "warning",
		"structcheck": "warning",
	}
	installMap = map[string]string{
		"golint":      "go get github.com/golang/lint/golint",
		"gotype":      "go get code.google.com/p/go.tools/cmd/gotype",
		"errcheck":    "go get github.com/kisielk/errcheck",
		"defercheck":  "go get github.com/opennota/check/cmd/defercheck",
		"varcheck":    "go get github.com/opennota/check/cmd/varcheck",
		"structcheck": "go get github.com/opennota/check/cmd/structcheck",
	}
	pathArg            = kingpin.Arg("path", "Directory to lint.").Default(".").String()
	fastFlag           = kingpin.Flag("fast", "Only run fast linters.").Bool()
	installFlag        = kingpin.Flag("install", "Attempt to install all known linters.").Bool()
	disableLintersFlag = kingpin.Flag("disable", "List of linters to disable.").PlaceHolder("LINTER").Short('D').Strings()
	debugFlag          = kingpin.Flag("debug", "Display messages for failed linters, etc.").Short('d').Bool()
	concurrencyFlag    = kingpin.Flag("concurrency", "Number of concurrent linters to run.").Default("16").Short('j').Int()
)

func init() {
	kingpin.Flag("linter", "Specify a linter.").PlaceHolder("NAME:COMMAND:PATTERN").StringMapVar(&lintersFlag)
	kingpin.Flag("message-overrides", "Override message from linter. {message} will be expanded to the original message.").PlaceHolder("LINTER:MESSAGE").StringMapVar(&linterMessageOverrideFlag)
	kingpin.Flag("severity", "Map of linter severities.").PlaceHolder("LINTER:SEVERITY").StringMapVar(&linterSeverityFlag)
}

type Issue struct {
	severity Severity
	path     string
	line     int
	col      int
	message  string
}

func (m *Issue) String() string {
	col := ""
	if m.col != 0 {
		col = fmt.Sprintf("%d", m.col)
	}
	return fmt.Sprintf("%s:%d:%s:%s: %s", m.path, m.line, col, m.severity, m.message)
}

type Issues []*Issue

func (m Issues) Len() int      { return len(m) }
func (m Issues) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
func (m Issues) Less(i, j int) bool {
	return m[i].path < m[j].path || m[i].line < m[j].line || m[i].col < m[j].col
}

func debug(format string, args ...interface{}) {
	if *debugFlag {
		fmt.Fprintf(os.Stderr, "DEBUG: "+format+"\n", args...)
	}
}

func formatLinters() string {
	w := bytes.NewBuffer(nil)
	for command, description := range lintersFlag {
		linter := Linter(description)
		fmt.Fprintf(w, "    %s -> %s -> %s\n", command, linter.Command(), linter.Pattern())
	}
	return w.String()
}

func formatSeverity() string {
	w := bytes.NewBuffer(nil)
	for name, severity := range linterSeverityFlag {
		fmt.Fprintf(w, "    %s -> %s\n", name, severity)
	}
	return w.String()
}

func exArgs() (arg0 string, arg1 string) {
	if runtime.GOOS == "windows" {
		arg0 = "cmd"
		arg1 = "/C"
	} else {
		arg0 = "/bin/sh"
		arg1 = "-c"
	}
	return
}

func main() {
	kingpin.CommandLine.Help = fmt.Sprintf(`Aggregate and normalise the output of a whole bunch of Go linters.

Default linters:

%s

Severity override map (default is "error"):

%s
`, formatLinters(), formatSeverity())
	kingpin.Parse()

	if *fastFlag {
		*disableLintersFlag = append(*disableLintersFlag, "structcheck", "varcheck", "errcheck")
	}

	if *installFlag {
		for name, cmd := range installMap {
			fmt.Printf("Installing %s -> %s\n", name, cmd)
			arg0, arg1 := exArgs()
			c := exec.Command(arg0, arg1, cmd)
			c.Stdout = os.Stdout
			c.Stderr = os.Stderr
			err := c.Run()
			if err != nil {
				kingpin.CommandLine.Errorf(os.Stderr, "failed to install %s: %s", name, err)
			}
		}
		return
	}

	runtime.GOMAXPROCS(*concurrencyFlag)

	disable := map[string]bool{}
	for _, linter := range *disableLintersFlag {
		disable[linter] = true
	}

	start := time.Now()
	paths := *pathArg
	concurrency := make(chan bool, *concurrencyFlag)
	issues := make(chan *Issue, 1000)
	wg := &sync.WaitGroup{}
	for name, description := range lintersFlag {
		if _, ok := disable[name]; ok {
			debug("linter %s disabled", name)
			continue
		}
		parts := strings.SplitN(description, ":", 2)
		command := parts[0]
		pattern := parts[1]

		wg.Add(1)
		go func(name, command, pattern string) {
			concurrency <- true
			executeLinter(issues, name, command, pattern, paths)
			<-concurrency
			wg.Done()
		}(name, command, pattern)
	}

	wg.Wait()
	close(issues)
	for issue := range issues {
		fmt.Printf("%s\n", issue)
	}
	elapsed := time.Now().Sub(start)
	debug("total elapsed time %s", elapsed)
}

func executeLinter(issues chan *Issue, name, command, pattern, paths string) {
	debug("linting with %s: %s", name, command)

	start := time.Now()
	if p, ok := predefinedPatterns[pattern]; ok {
		pattern = p
	}
	re, err := regexp.Compile(pattern)
	kingpin.FatalIfError(err, "invalid pattern for '"+command+"'")

	command = strings.Replace(command, "{path}", paths, -1)
	debug("executing %s", command)
	arg0, arg1 := exArgs()
	cmd := exec.Command(arg0, arg1, command)
	out, err := cmd.CombinedOutput()
	if err != nil {
		if _, ok := err.(*exec.ExitError); !ok {
			debug("warning: %s failed: %s", command, err)
			return
		}
		debug("warning: %s returned %s", command, err)
	}
	for _, line := range bytes.Split(out, []byte("\n")) {
		groups := re.FindAllSubmatch(line, -1)
		if groups == nil {
			continue
		}
		issue := &Issue{}
		for i, name := range re.SubexpNames() {
			part := string(groups[0][i])
			switch name {
			case "path":
				issue.path = part

			case "line":
				n, err := strconv.ParseInt(part, 10, 32)
				kingpin.FatalIfError(err, "line matched invalid integer")
				issue.line = int(n)

			case "col":
				n, err := strconv.ParseInt(part, 10, 32)
				kingpin.FatalIfError(err, "col matched invalid integer")
				issue.col = int(n)

			case "message":
				issue.message = part

			case "":

			default:
				kingpin.Fatalf("invalid subgroup %s", name)
			}
		}
		if m, ok := linterMessageOverrideFlag[name]; ok {
			issue.message = strings.Replace(m, "{message}", issue.message, -1)
		}
		if sev, ok := linterSeverityFlag[name]; ok {
			issue.severity = Severity(sev)
		} else {
			issue.severity = "error"
		}
		issues <- issue
	}

	elapsed := time.Now().Sub(start)
	debug("%s linter took %s", name, elapsed)
}
<commit_msg>Add --exclude flag.<commit_after>package main

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/alecthomas/kingpin"
)

type Severity string

// Linter message severity levels.
const (
	Warning Severity = "warning"
	Error   Severity = "error"
)

type Linter string

func (l Linter) Command() string {
	return string(l[0:strings.Index(string(l), ":")])
}

func (l Linter) Pattern() string {
	return string(l[strings.Index(string(l), ":"):])
}

var (
	predefinedPatterns = map[string]string{
		"PATH:LINE:COL:MESSAGE": `(?P<path>[^:]+):(?P<line>\d+):(?P<col>\d+):\s*(?P<message>.*)`,
		"PATH:LINE:MESSAGE":     `(?P<path>[^:]+):(?P<line>\d+):\s*(?P<message>.*)`,
	}
	lintersFlag = map[string]string{
		// main.go:8:10: should omit type map[string]string from declaration of var linters; it will be inferred from the right-hand side
		"golint": "golint {path}:PATH:LINE:COL:MESSAGE",
		// test/stutter.go:19: missing argument for Printf("%d"): format reads arg 1, have only 0 args
		"vet":         "go tool vet {path}:PATH:LINE:MESSAGE",
		"gotype":      "gotype {path}:PATH:LINE:COL:MESSAGE",
		"errcheck":    `errcheck {path}:(?P<path>[^:]+):(?P<line>\d+):(?P<col>\d+)\t(?P<message>.*)`,
		"varcheck":    "varcheck {path}:PATH:LINE:MESSAGE",
		"structcheck": "structcheck {path}:PATH:LINE:MESSAGE",
		"defercheck":  "defercheck {path}:PATH:LINE:MESSAGE",
	}
	linterMessageOverrideFlag = map[string]string{
		"errcheck":    "error return value not checked ({message})",
		"varcheck":    "unused global variable {message}",
		"structcheck": "unused struct field {message}",
	}
	linterSeverityFlag = map[string]string{
		"errcheck":    "warning",
		"golint":      "warning",
		"varcheck":    "warning",
		"structcheck": "warning",
	}
	installMap = map[string]string{
		"golint":      "go get github.com/golang/lint/golint",
		"gotype":      "go get code.google.com/p/go.tools/cmd/gotype",
		"errcheck":    "go get github.com/kisielk/errcheck",
		"defercheck":  "go get github.com/opennota/check/cmd/defercheck",
		"varcheck":    "go get github.com/opennota/check/cmd/varcheck",
		"structcheck": "go get github.com/opennota/check/cmd/structcheck",
	}
	pathArg            = kingpin.Arg("path", "Directory to lint.").Default(".").String()
	fastFlag           = kingpin.Flag("fast", "Only run fast linters.").Bool()
	installFlag        = kingpin.Flag("install", "Attempt to install all known linters.").Bool()
	disableLintersFlag = kingpin.Flag("disable", "List of linters to disable.").PlaceHolder("LINTER").Short('D').Strings()
	debugFlag          = kingpin.Flag("debug", "Display messages for failed linters, etc.").Short('d').Bool()
	concurrencyFlag    = kingpin.Flag("concurrency", "Number of concurrent linters to run.").Default("16").Short('j').Int()
	excludeFlag        = kingpin.Flag("exclude", "Exclude messages matching this regular expression.").PlaceHolder("REGEXP").String()
)

func init() {
	kingpin.Flag("linter", "Specify a linter.").PlaceHolder("NAME:COMMAND:PATTERN").StringMapVar(&lintersFlag)
	kingpin.Flag("message-overrides", "Override message from linter. {message} will be expanded to the original message.").PlaceHolder("LINTER:MESSAGE").StringMapVar(&linterMessageOverrideFlag)
	kingpin.Flag("severity", "Map of linter severities.").PlaceHolder("LINTER:SEVERITY").StringMapVar(&linterSeverityFlag)
}

type Issue struct {
	severity Severity
	path     string
	line     int
	col      int
	message  string
}

func (m *Issue) String() string {
	col := ""
	if m.col != 0 {
		col = fmt.Sprintf("%d", m.col)
	}
	return fmt.Sprintf("%s:%d:%s:%s: %s", m.path, m.line, col, m.severity, m.message)
}

type Issues []*Issue

func (m Issues) Len() int      { return len(m) }
func (m Issues) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
func (m Issues) Less(i, j int) bool {
	return m[i].path < m[j].path || m[i].line < m[j].line || m[i].col < m[j].col
}

func debug(format string, args ...interface{}) {
	if *debugFlag {
		fmt.Fprintf(os.Stderr, "DEBUG: "+format+"\n", args...)
	}
}

func formatLinters() string {
	w := bytes.NewBuffer(nil)
	for command, description := range lintersFlag {
		linter := Linter(description)
		fmt.Fprintf(w, "    %s -> %s -> %s\n", command, linter.Command(), linter.Pattern())
	}
	return w.String()
}

func formatSeverity() string {
	w := bytes.NewBuffer(nil)
	for name, severity := range linterSeverityFlag {
		fmt.Fprintf(w, "    %s -> %s\n", name, severity)
	}
	return w.String()
}

func exArgs() (arg0 string, arg1 string) {
	if runtime.GOOS == "windows" {
		arg0 = "cmd"
		arg1 = "/C"
	} else {
		arg0 = "/bin/sh"
		arg1 = "-c"
	}
	return
}

func main() {
	kingpin.CommandLine.Help = fmt.Sprintf(`Aggregate and normalise the output of a whole bunch of Go linters.

Default linters:

%s

Severity override map (default is "error"):

%s
`, formatLinters(), formatSeverity())
	kingpin.Parse()
	var filter *regexp.Regexp
	if *excludeFlag != "" {
		filter = regexp.MustCompile(*excludeFlag)
	}

	if *fastFlag {
		*disableLintersFlag = append(*disableLintersFlag, "structcheck", "varcheck", "errcheck")
	}

	if *installFlag {
		for name, cmd := range installMap {
			fmt.Printf("Installing %s -> %s\n", name, cmd)
			arg0, arg1 := exArgs()
			c := exec.Command(arg0, arg1, cmd)
			c.Stdout = os.Stdout
			c.Stderr = os.Stderr
			err := c.Run()
			if err != nil {
				kingpin.CommandLine.Errorf(os.Stderr, "failed to install %s: %s", name, err)
			}
		}
		return
	}

	runtime.GOMAXPROCS(*concurrencyFlag)

	disable := map[string]bool{}
	for _, linter := range *disableLintersFlag {
		disable[linter] = true
	}

	start := time.Now()
	paths := *pathArg
	concurrency := make(chan bool, *concurrencyFlag)
	issues := make(chan *Issue, 1000)
	wg := &sync.WaitGroup{}
	for name, description := range lintersFlag {
		if _, ok := disable[name]; ok {
			debug("linter %s disabled", name)
			continue
		}
		parts := strings.SplitN(description, ":", 2)
		command := parts[0]
		pattern := parts[1]

		wg.Add(1)
		go func(name, command, pattern string) {
			concurrency <- true
			executeLinter(issues, name, command, pattern, paths)
			<-concurrency
			wg.Done()
		}(name, command, pattern)
	}

	wg.Wait()
	close(issues)
	for issue := range issues {
		if filter != nil && filter.MatchString(issue.String()) {
			continue
		}
		fmt.Printf("%s\n", issue)
	}
	elapsed := time.Now().Sub(start)
	debug("total elapsed time %s", elapsed)
}

func executeLinter(issues chan *Issue, name, command, pattern, paths string) {
	debug("linting with %s: %s", name, command)

	start := time.Now()
	if p, ok := predefinedPatterns[pattern]; ok {
		pattern = p
	}
	re, err := regexp.Compile(pattern)
	kingpin.FatalIfError(err, "invalid pattern for '"+command+"'")

	command = strings.Replace(command, "{path}", paths, -1)
	debug("executing %s", command)
	arg0, arg1 := exArgs()
	cmd := exec.Command(arg0, arg1, command)
	out, err := cmd.CombinedOutput()
	if err != nil {
		if _, ok := err.(*exec.ExitError); !ok {
			debug("warning: %s failed: %s", command, err)
			return
		}
		debug("warning: %s returned %s", command, err)
	}
	for _, line := range bytes.Split(out, []byte("\n")) {
		groups := re.FindAllSubmatch(line, -1)
		if groups == nil {
			continue
		}
		issue := &Issue{}
		for i, name := range re.SubexpNames() {
			part := string(groups[0][i])
			switch name {
			case "path":
				issue.path = part

			case "line":
				n, err := strconv.ParseInt(part, 10, 32)
				kingpin.FatalIfError(err, "line matched invalid integer")
				issue.line = int(n)

			case "col":
				n, err := strconv.ParseInt(part, 10, 32)
				kingpin.FatalIfError(err, "col matched invalid integer")
				issue.col = int(n)

			case "message":
				issue.message = part

			case "":

			default:
				kingpin.Fatalf("invalid subgroup %s", name)
			}
		}
		if m, ok := linterMessageOverrideFlag[name]; ok {
			issue.message = strings.Replace(m, "{message}", issue.message, -1)
		}
		if sev, ok := linterSeverityFlag[name]; ok {
			issue.severity = Severity(sev)
		} else {
			issue.severity = "error"
		}
		issues <- issue
	}

	elapsed := time.Now().Sub(start)
	debug("%s linter took %s", name, elapsed)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	log "github.com/Sirupsen/logrus"
	"io/ioutil"
	"strings"
	"os"
	"os/exec"
)

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

	log.WithField("requestURi", r.RequestURI).Info("HTTP")

	if strings.HasPrefix(r.RequestURI, "/play") {
		handlePlay(w, r)
	} else if strings.HasPrefix(r.RequestURI, "/images") {
		handleImage(w, r)
	} else {
		handleIndex(w, r)
	}

}

func handleImage(w http.ResponseWriter, r *http.Request) {
	filename := "sounds/" + r.RequestURI[8:]
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		log.Error(filename)
		w.WriteHeader(404)
		return
	}
	image, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Error(err)
		w.WriteHeader(500)
	}
	w.Write(image)
}

func handlePlay(w http.ResponseWriter, r *http.Request) {
	filename := "sounds/" + r.RequestURI[6:]
	log.WithField("filename", filename).Info("playing sound")
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		log.Error(filename)
		w.WriteHeader(404)
		return
	}
	cmd := exec.Command("omxplayer", "-o", "hdmi", filename)
	err := cmd.Run()
	if err != nil {
		log.Error(err)
	}
	http.Redirect(w, r, "/", 307)
}

func handleIndex(w http.ResponseWriter, r *http.Request) {
	dir, err := ioutil.ReadDir("sounds")
	if err != nil {
		log.Error(err)
	}

	for _, v := range dir {
		if !v.IsDir() {
			filename := v.Name()
			if (strings.HasSuffix(filename, ".mp3")) {

				fmt.Fprintf(w, "")

				filenameWithoutExt := filename[:len(filename)-4]

				pngFilename := filenameWithoutExt + ".png"
				if _, err := os.Stat("sounds/" + pngFilename); os.IsNotExist(err) {
					jpgFilename := filenameWithoutExt + ".jpg"
					if _, err := os.Stat("sounds/" + jpgFilename); os.IsNotExist(err) {
						fmt.Fprintf(w, filename)
					} else {
						fmt.Fprintf(w, "")
					}
				} else {
					fmt.Fprintf(w, "")
				}

				fmt.Fprintf(w, "")
			}
		}
	}
}

func main() {
	http.HandleFunc("/", handler)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal(err)
	}
}<commit_msg>counter<commit_after>package main

import (
	"fmt"
	"net/http"
	log "github.com/Sirupsen/logrus"
	"io/ioutil"
	"strings"
	"os"
	"os/exec"
	"strconv"
	"sync"
)

var mutex = &sync.Mutex{}

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

	log.WithField("requestURi", r.RequestURI).Info("HTTP")

	if strings.HasPrefix(r.RequestURI, "/play") {
		handlePlay(w, r)
	} else if strings.HasPrefix(r.RequestURI, "/images") {
		handleImage(w, r)
	} else {
		handleIndex(w, r)
	}

}

func handleImage(w http.ResponseWriter, r *http.Request) {
	filename := "sounds/" + r.RequestURI[8:]
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		log.Error(filename)
		w.WriteHeader(404)
		return
	}
	image, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Error(err)
		w.WriteHeader(500)
	}
	w.Write(image)
}

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

	filename := "sounds/" + r.RequestURI[6:]

	if strings.HasSuffix(filename, ".mp3") {

		incCounter(filename)

		log.WithField("filename", filename).Info("playing sound")
		if _, err := os.Stat(filename); os.IsNotExist(err) {
			log.Error(filename)
			w.WriteHeader(404)
			return
		}
		cmd := exec.Command("omxplayer", "-o", "hdmi", filename)
		err := cmd.Run()
		if err != nil {
			log.Error(err)
		}
	} else {
		log.Error("no .mp3 suffix")
	}
	http.Redirect(w, r, "/", 307)
}

func incCounter(filename string) {

	log.WithField("filename", filename).Info("Increasing counter")

	mutex.Lock()
	intCount := getCounter(filename)
	log.WithField("count", intCount).Info("Old count")
	intCount++

	ioutil.WriteFile(filename + ".count", []byte(fmt.Sprintf("%d", intCount)), 0644)
	mutex.Unlock()
}

func getCounter(filename string) int {

	countfile := filename + ".count"

	if _, err := os.Stat(countfile); os.IsNotExist(err) {
		return 0
	}

	count, err := ioutil.ReadFile(countfile)
	intCount, err := strconv.Atoi(string(count))
	if err != nil {
		log.Error(err)
	}
	return intCount
}

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

	fmt.Fprint(w, "")

	dir, err := ioutil.ReadDir("sounds")
	if err != nil {
		log.Error(err)
	}

	for _, v := range dir {
		if !v.IsDir() {
			filename := v.Name()
			if (strings.HasSuffix(filename, ".mp3")) {
				fmt.Fprintf(w, "

")

				filenameWithoutExt := filename[:len(filename)-4]

				pngFilename := filenameWithoutExt + ".png"
				if _, err := os.Stat("sounds/" + pngFilename); os.IsNotExist(err) {
					jpgFilename := filenameWithoutExt + ".jpg"
					if _, err := os.Stat("sounds/" + jpgFilename); os.IsNotExist(err) {
						fmt.Fprintf(w, filename)
					} else {
						fmt.Fprintf(w, "")
					}
				} else {
					fmt.Fprintf(w, "")
				}

				fmt.Fprintf(w, "

played %d times

", getCounter("sounds/" + filename))
			}
		}
	}

	fmt.Fprint(w, "")
}

func main() {
	http.HandleFunc("/", handler)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal(err)
	}
}<|endoftext|>


<commit_before>package main

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

	"github.com/davecgh/go-spew/spew"
)

func main() {
	switches := [...]statusSwitch{
		statusSwitch{os.Getenv("ONEON"), os.Getenv("ONEOFF"), "🛏"},
		statusSwitch{os.Getenv("TWOON"), os.Getenv("TWOOFF"), "📚)"},
		statusSwitch{os.Getenv("FOURAON"), os.Getenv("FOURAOFF"), "🛋"},
	}
	switchMap := make(map[string]switcher)

	for _, s := range switches {
		spew.Dump(s)
		switchMap[s.name] = s
	}
	switchMap["all"] = multiswitch{switches[:]}
	//spew.Dump(switchMap)

	key := os.Getenv("RFKEY")

	switchHandler := func(w http.ResponseWriter, r *http.Request) {
		var dat struct {
			Switch string
			Action string
		}
		secret := r.Header.Get("badlykeptsecret")

		if secret != key {
			fmt.Fprintln(w, "⛔")
			return
		}
		d := json.NewDecoder(r.Body)
		d.Decode(&dat)
		fmt.Println(dat)
		s, exists := switchMap[dat.Switch]
		if !exists {
			fmt.Println(w, dat.Switch)
			fmt.Fprintln(w, "🔕")
			return
		}
		if dat.Action == "on" {
			go s.On()
			fmt.Fprintln(w, "👍💡")
			return
		}
		if dat.Action == "off" {
			go s.Off()
			fmt.Fprintln(w, "👍🌆")
			return
		}
		fmt.Fprintln(w, "👾")
		return
	}
	listSwitchesHandler := func(w http.ResponseWriter, r *http.Request) {
		s, _ := json.Marshal(switchMap)
		fmt.Fprint(w, string(s))
	}

	http.HandleFunc("/switch/", switchHandler)
	http.HandleFunc("/list/", listSwitchesHandler)
	http.Handle("/", http.FileServer(http.Dir("./public/")))
	fmt.Println("HANDLING HTTP")
	http.ListenAndServe(":8080", nil)
}
<commit_msg>typo.<commit_after>package main

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

	"github.com/davecgh/go-spew/spew"
)

func main() {
	switches := [...]statusSwitch{
		statusSwitch{os.Getenv("ONEON"), os.Getenv("ONEOFF"), "🛏"},
		statusSwitch{os.Getenv("TWOON"), os.Getenv("TWOOFF"), "📚"},
		statusSwitch{os.Getenv("FOURAON"), os.Getenv("FOURAOFF"), "🛋"},
	}
	switchMap := make(map[string]switcher)

	for _, s := range switches {
		spew.Dump(s)
		switchMap[s.name] = s
	}
	switchMap["all"] = multiswitch{switches[:]}
	//spew.Dump(switchMap)

	key := os.Getenv("RFKEY")

	switchHandler := func(w http.ResponseWriter, r *http.Request) {
		var dat struct {
			Switch string
			Action string
		}
		secret := r.Header.Get("badlykeptsecret")

		if secret != key {
			fmt.Fprintln(w, "⛔")
			return
		}
		d := json.NewDecoder(r.Body)
		d.Decode(&dat)
		fmt.Println(dat)
		s, exists := switchMap[dat.Switch]
		if !exists {
			fmt.Println(w, dat.Switch)
			fmt.Fprintln(w, "🔕")
			return
		}
		if dat.Action == "on" {
			go s.On()
			fmt.Fprintln(w, "👍💡")
			return
		}
		if dat.Action == "off" {
			go s.Off()
			fmt.Fprintln(w, "👍🌆")
			return
		}
		fmt.Fprintln(w, "👾")
		return
	}
	listSwitchesHandler := func(w http.ResponseWriter, r *http.Request) {
		s, _ := json.Marshal(switchMap)
		fmt.Fprint(w, string(s))
	}

	http.HandleFunc("/switch/", switchHandler)
	http.HandleFunc("/list/", listSwitchesHandler)
	http.Handle("/", http.FileServer(http.Dir("./public/")))
	fmt.Println("HANDLING HTTP")
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"html/template"
	"net/http"
	"os"
	"time"

	log "github.com/sirupsen/logrus"
	"github.com/skibish/ddns/conf"
	"github.com/skibish/ddns/do"
	"github.com/skibish/ddns/ipprovider"
	"github.com/skibish/ddns/notifier"
)

var (
	digio   do.DigitalOceanInterface
	cf      *conf.Configuration
	storage *conf.Configuration
	periodC <-chan time.Time
)

var (
	reqTimeouts = flag.Duration("req-timeout", 10*time.Second, "Request timeout to external resources")
	checkPeriod = flag.Duration("check-period", 5*time.Minute, "Check if IP has been changed period")
	confFile    = flag.String("conf-file", "$HOME/.ddns.yml", "Location of the configuration file")
)

// current remembered IP
var currentIP string

func init() {
	log.SetFormatter(&log.TextFormatter{
		DisableColors: true,
	})
	log.SetLevel(log.DebugLevel)
	log.SetOutput(os.Stdout)

	// initialize storage
	storage = &conf.Configuration{}
}

func main() {
	flag.Parse()

	// read configuration
	var errConf error
	cf, errConf = conf.NewConfiguration(*confFile)
	if errConf != nil {
		log.Fatal(errConf.Error())
	}
	*storage = *cf

	// try to register all provided hooks
	for k, v := range cf.Notify {
		hook, errGet := notifier.GetHook(k, v)
		if errGet != nil {
			log.Debugf("Notifier %q not added: %s", k, errGet.Error())
			continue
		}
		log.AddHook(hook)
	}

	// setup http client
	hc := &http.Client{
		Timeout: *reqTimeouts,
	}

	// initialte digital ocean client
	digio = do.NewDigitalOcean(cf.Domain, cf.Token, hc)

	// register providers
	ipprovider.Register(hc)

	// get current IP
	currentIP = ipprovider.GetIP()
	if currentIP == "" {
		log.Fatal("IP can't be empty in the beginning... Do you have internet connection?")
	}
	log.Infof("Current IP is %q", currentIP)

	// do request to the digital ocean API for list of records
	allRecords, errGetDR := digio.GetDomainRecords()
	if errGetDR != nil {
		log.Fatal(errGetDR.Error())
	}

	// do initial sync of records
	var errSync error
	errSync = syncRecords(storage, cf, allRecords)
	if errSync != nil {
		log.Fatal(errSync.Error())
	}

	periodC = time.NewTicker(*checkPeriod).C

	// start main proceess
	go func(storage *conf.Configuration) {
		// for defined period of time, perform IP check
		for {
			select {
			case <-periodC:
				errCheck := checkAndUpdate(storage, cf, ipprovider.GetIP)
				if errCheck != nil {
					log.Errorf("Failed to update: %s", errCheck.Error())
				}
			}
		}

	}(storage)

	select {}
}

// syncRecords perform initial sync between what we provided
// in configuration and what already exist in DNS records
func syncRecords(storage *conf.Configuration, cf *conf.Configuration, allRecords []do.Record) error {
	cRec := len(storage.Records)
	cAllRec := len(allRecords)
	for i := 0; i < cRec; i++ {
		for j := 0; j < cAllRec; j++ {

			// we are only interested in those who have full match
			// by `type AND name`
			if storage.Records[i].Type == allRecords[j].Type &&
				storage.Records[i].Name == allRecords[j].Name {
				storage.Records[i] = allRecords[j]
				break
			}
		}

		// if there was no match, we should create new DNS record
		// and updatee current configuration
		if storage.Records[i].ID == 0 {
			// if there is not template in configuration, set current IP as data,
			// otherwise parse data and fill template with provided params
			if cf.Records[i].Data == "" {
				storage.Records[i].Data = currentIP
			} else {
				storage.Params["IP"] = currentIP
				t := template.Must(template.New("t1").Parse(cf.Records[i].Data))
				buf := new(bytes.Buffer)
				errExec := t.Execute(buf, storage.Params)
				if errExec != nil {
					return errExec
				}
				storage.Records[i].Data = buf.String()
			}

			newR, errCreate := digio.CreateRecord(storage.Records[i])
			if errCreate != nil {
				return errCreate
			}

			storage.Records[i] = *newR
		}

		// if IPs are different, update record
		if storage.Records[i].Data != currentIP {
			if cf.Records[i].Data == "" {
				storage.Records[i].Data = currentIP
			} else {
				storage.Params["IP"] = currentIP
				t := template.Must(template.New("t1").Parse(cf.Records[i].Data))
				buf := new(bytes.Buffer)
				errExec := t.Execute(buf, storage.Params)
				if errExec != nil {
					return errExec
				}
				storage.Records[i].Data = buf.String()
			}

			newR, errUpdate := digio.UpdateRecord(storage.Records[i])
			if errUpdate != nil {
				return errUpdate
			}

			storage.Records[i] = *newR
		}
	}

	return nil
}

// checkAndUpdate check for new IP and if it has been changed,
// trigger the update of the DNS records
func checkAndUpdate(storage *conf.Configuration, cf *conf.Configuration, getIP ipprovider.FGetIP) error {
	log.Debug("IP check")
	newIP := getIP()

	if currentIP != newIP {
		log.Infof("IP has changed from %q to %q", currentIP, newIP)
		currentIP = newIP

		cRec := len(storage.Records)
		for i := 0; i < cRec; i++ {
			if cf.Records[i].Data == "" {
				storage.Records[i].Data = currentIP
			} else {
				storage.Params["IP"] = currentIP
				t := template.Must(template.New("t1").Parse(cf.Records[i].Data))
				buf := new(bytes.Buffer)
				errExec := t.Execute(buf, storage.Params)
				if errExec != nil {
					return errExec
				}
				storage.Records[i].Data = buf.String()
			}

			newR, errUpdate := digio.UpdateRecord(storage.Records[i])
			if errUpdate != nil {
				return errUpdate
			}

			storage.Records[i] = *newR
		}
	}

	return nil
}
<commit_msg>little refactoring<commit_after>package main

import (
	"bytes"
	"flag"
	"html/template"
	"net/http"
	"os"
	"time"

	log "github.com/sirupsen/logrus"
	"github.com/skibish/ddns/conf"
	"github.com/skibish/ddns/do"
	"github.com/skibish/ddns/ipprovider"
	"github.com/skibish/ddns/notifier"
)

var (
	digio   do.DigitalOceanInterface
	cf      *conf.Configuration
	storage *conf.Configuration
	periodC <-chan time.Time
)

var (
	reqTimeouts = flag.Duration("req-timeout", 10*time.Second, "Request timeout to external resources")
	checkPeriod = flag.Duration("check-period", 5*time.Minute, "Check if IP has been changed period")
	confFile    = flag.String("conf-file", "$HOME/.ddns.yml", "Location of the configuration file")
)

// current remembered IP
var currentIP string

func init() {
	log.SetFormatter(&log.TextFormatter{
		DisableColors: true,
	})
	log.SetLevel(log.DebugLevel)
	log.SetOutput(os.Stdout)

	// initialize storage
	storage = &conf.Configuration{}
}

func main() {
	flag.Parse()

	// read configuration
	var errConf error
	cf, errConf = conf.NewConfiguration(*confFile)
	if errConf != nil {
		log.Fatal(errConf.Error())
	}
	*storage = *cf

	// try to register all provided hooks
	for k, v := range cf.Notify {
		hook, errGet := notifier.GetHook(k, v)
		if errGet != nil {
			log.Debugf("Notifier %q not added: %s", k, errGet.Error())
			continue
		}
		log.AddHook(hook)
	}

	// setup http client
	hc := &http.Client{
		Timeout: *reqTimeouts,
	}

	// initialte digital ocean client
	digio = do.NewDigitalOcean(cf.Domain, cf.Token, hc)

	// register providers
	ipprovider.Register(hc)

	// get current IP
	currentIP = ipprovider.GetIP()
	if currentIP == "" {
		log.Fatal("IP can't be empty in the beginning... Do you have internet connection?")
	}
	log.Infof("Current IP is %q", currentIP)

	// do request to the digital ocean API for list of records
	allRecords, errGetDR := digio.GetDomainRecords()
	if errGetDR != nil {
		log.Fatal(errGetDR.Error())
	}

	// do initial sync of records
	var errSync error
	errSync = syncRecords(storage, cf, allRecords)
	if errSync != nil {
		log.Fatal(errSync.Error())
	}

	periodC = time.NewTicker(*checkPeriod).C

	// start main proceess
	go func(storage *conf.Configuration) {
		// for defined period of time, perform IP check
		for {
			select {
			case <-periodC:
				errCheck := checkAndUpdate(storage, cf, ipprovider.GetIP)
				if errCheck != nil {
					log.Errorf("Failed to update: %s", errCheck.Error())
				}
			}
		}

	}(storage)

	select {}
}

// syncRecords perform initial sync between what we provided
// in configuration and what already exist in DNS records
func syncRecords(storage *conf.Configuration, cf *conf.Configuration, allRecords []do.Record) error {
	cRec := len(storage.Records)
	cAllRec := len(allRecords)
	for i := 0; i < cRec; i++ {
		for j := 0; j < cAllRec; j++ {

			// we are only interested in those who have full match
			// by `type AND name`
			if storage.Records[i].Type == allRecords[j].Type &&
				storage.Records[i].Name == allRecords[j].Name {
				storage.Records[i] = allRecords[j]
				break
			}
		}

		// if there was no match, we should create new DNS record
		// and updatee current configuration
		if storage.Records[i].ID == 0 {
			// if there is not template in configuration, set current IP as data,
			// otherwise parse data and fill template with provided params
			errUpdStorage := updateStorage(storage.Records[i], cf.Records[i], storage.Params)
			if errUpdStorage != nil {
				return errUpdStorage
			}

			newR, errCreate := digio.CreateRecord(storage.Records[i])
			if errCreate != nil {
				return errCreate
			}

			storage.Records[i] = *newR
		}

		// if IPs are different, update record
		if storage.Records[i].Data != currentIP {
			errUpdStorage := updateStorage(storage.Records[i], cf.Records[i], storage.Params)
			if errUpdStorage != nil {
				return errUpdStorage
			}

			newR, errUpdate := digio.UpdateRecord(storage.Records[i])
			if errUpdate != nil {
				return errUpdate
			}

			storage.Records[i] = *newR
		}
	}

	return nil
}

// checkAndUpdate check for new IP and if it has been changed,
// trigger the update of the DNS records
func checkAndUpdate(storage *conf.Configuration, cf *conf.Configuration, getIP ipprovider.FGetIP) error {
	log.Debug("IP check")
	newIP := getIP()

	if currentIP != newIP {
		log.Infof("IP has changed from %q to %q", currentIP, newIP)
		currentIP = newIP

		cRec := len(storage.Records)
		for i := 0; i < cRec; i++ {
			errUpdStorage := updateStorage(storage.Records[i], cf.Records[i], storage.Params)
			if errUpdStorage != nil {
				return errUpdStorage
			}

			newR, errUpdate := digio.UpdateRecord(storage.Records[i])
			if errUpdate != nil {
				return errUpdate
			}

			storage.Records[i] = *newR
		}
	}

	return nil
}

// updateStorage updates the storage based on data in configuration
func updateStorage(storageRecord, configRecord do.Record, params map[string]string) (err error) {
	if configRecord.Data == "" {
		storageRecord.Data = currentIP
	} else {
		params["IP"] = currentIP
		t := template.Must(template.New("t1").Parse(configRecord.Data))
		buf := new(bytes.Buffer)
		err = t.Execute(buf, params)
		if err != nil {
			return
		}
		storageRecord.Data = buf.String()
	}
	return
}
<|endoftext|>


<commit_before>package main

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

	"github.com/foursquare/gohfile"
)

type SettingDefs struct {
	port  int
	debug bool

	configJsonUrl string

	hdfsPathPrefix string
	hdfsCachePath  string
}

var Settings SettingDefs

func readSettings() []string {
	s := SettingDefs{}
	flag.IntVar(&s.port, "port", 9999, "listen port")
	flag.BoolVar(&s.debug, "debug", false, "print debug output")

	flag.StringVar(&s.configJsonUrl, "config-json", "", "URL of collection configuration json")

	flag.StringVar(&s.hdfsPathPrefix, "hdfs-prefix", "", "path-prefix indicating a file must be fetched from hdfs")
	flag.StringVar(&s.hdfsCachePath, "hdfs-cache", "/tmp", "local path to write files fetch from hdfs (*not* cleaned up automatically)")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr,
			`
Usage: %s [options] col1@path1 col2@path2 ...

	By default, collections are mmaped and locked into memory.
	Use 'col=path' to serve directly off disk.

	You may need to set 'ulimit -Hl' and 'ulimit -Sl' to allow locking.

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

	flag.Parse()
	Settings = s

	if len(flag.Args()) < 1 && Settings.configJsonUrl == "" {
		log.Println("bah!", Settings)
		flag.Usage()
		os.Exit(-1)
	}

	return flag.Args()
}

func getCollectionConfig(args []string) []hfile.CollectionConfig {
	if Settings.configJsonUrl != "" {
		if len(args) > 0 {
			log.Fatalln("Only one of command-line collection specs or json config may be used.")
		}
		configs, err := LoadFromUrl(Settings.configJsonUrl)
		if err != nil {
			log.Fatalln(err)
		}
		return configs
	} else {
		collections := make([]hfile.CollectionConfig, len(args))
		for i, pair := range flag.Args() {
			parts := strings.SplitN(pair, "=", 2)
			mlock := true
			if len(parts) != 2 {
				mlock = false
				parts = strings.SplitN(pair, "@", 2)
			}
			if len(parts) != 2 {
				log.Fatal("collections must be specified in the form 'name=path' or 'name@path'")
			}
			collections[i] = hfile.CollectionConfig{parts[0], parts[1], mlock}
		}
		return collections
	}
}

func main() {
	args := readSettings()

	configs := getCollectionConfig(args)

	log.Println("Loading collections...")
	cs, err := hfile.LoadCollections(configs, Settings.debug)
	if err != nil {
		log.Fatal(err)
	}

	name, err := os.Hostname()
	if err != nil {
		name = "localhost"
	}
	log.Printf("Serving on http://%s:%d/ \n", name, Settings.port)

	http.Handle("/rpc/HFileService", NewHttpRpcHandler(cs))
	http.Handle("/", &DebugHandler{cs})

	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", Settings.port), nil))
}
<commit_msg>allow overriding per-col mlock with server-level flag<commit_after>package main

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

	"github.com/foursquare/gohfile"
)

type SettingDefs struct {
	port  int
	debug bool
	mlock bool

	configJsonUrl string

	hdfsPathPrefix string
	hdfsCachePath  string
}

var Settings SettingDefs

func readSettings() []string {
	s := SettingDefs{}
	flag.IntVar(&s.port, "port", 9999, "listen port")
	flag.BoolVar(&s.debug, "debug", false, "print debug output")

	flag.BoolVar(&s.mlock, "mem", false, "mlock ALL mapped files to keep them im memory (ignores = vs @ specs).")

	flag.StringVar(&s.configJsonUrl, "config-json", "", "URL of collection configuration json")

	flag.StringVar(&s.hdfsPathPrefix, "hdfs-prefix", "", "path-prefix indicating a file must be fetched from hdfs")
	flag.StringVar(&s.hdfsCachePath, "hdfs-cache", "/tmp", "local path to write files fetch from hdfs (*not* cleaned up automatically)")

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr,
			`
Usage: %s [options] col1=path1 col2=path2 ...

	By default, collections are mmaped and locked into memory.
	Use 'col@path' to serve directly off disk.

	You may need to set 'ulimit -Hl' and 'ulimit -Sl' to allow locking.

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

	flag.Parse()
	Settings = s

	if len(flag.Args()) < 1 && Settings.configJsonUrl == "" {
		log.Println("bah!", Settings)
		flag.Usage()
		os.Exit(-1)
	}

	return flag.Args()
}

func getCollectionConfig(args []string) []hfile.CollectionConfig {
	var configs []hfile.CollectionConfig
	var err error

	if Settings.configJsonUrl != "" {
		if len(args) > 0 {
			log.Fatalln("Only one of command-line collection specs or json config may be used.")
		}
		configs, err = LoadFromUrl(Settings.configJsonUrl)
		if err != nil {
			log.Fatalln(err)
		}
	} else {
		configs := make([]hfile.CollectionConfig, len(args))
		for i, pair := range flag.Args() {
			parts := strings.SplitN(pair, "=", 2)
			mlock := true
			if len(parts) != 2 {
				mlock = false
				parts = strings.SplitN(pair, "@", 2)
			}
			if len(parts) != 2 {
				log.Fatal("collections must be specified in the form 'name=path' or 'name@path'")
			}
			configs[i] = hfile.CollectionConfig{parts[0], parts[1], mlock}
		}
	}
	if Settings.mlock {
		for i, _ := range configs {
			if Settings.debug && !configs[i].Mlock {
				log.Printf("[getCollectionConfig] Forcing %s to be in-memory", configs[i].Name)
			}
			configs[i].Mlock = true
		}
	}
	return configs
}

func main() {
	args := readSettings()

	configs := getCollectionConfig(args)

	log.Println("Loading collections...")
	cs, err := hfile.LoadCollections(configs, Settings.debug)
	if err != nil {
		log.Fatal(err)
	}

	name, err := os.Hostname()
	if err != nil {
		name = "localhost"
	}
	log.Printf("Serving on http://%s:%d/ \n", name, Settings.port)

	http.Handle("/rpc/HFileService", NewHttpRpcHandler(cs))
	http.Handle("/", &DebugHandler{cs})

	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", Settings.port), nil))
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package main

import (
	"code.google.com/p/go.net/websocket"
	"mozilla.org/simplepush"
	"mozilla.org/util"

	"flag"
	"fmt"
	"log"
	"net/http"
)

var logger *util.HekaLogger

// -- main
func main() {

	var configFile string

	flag.StringVar(&configFile, "config", "config.ini", "Configuration File")
	flag.Parse()
	log.Printf("Using config %s", configFile)
	config := util.MzGetConfig(configFile)

    config = simplepush.FixConfig(config)
	log.Printf("CurrentHost: %s", config["shard.current_host"])

	logger = util.NewHekaLogger(config)
    log.Printf("#### token_key: %s\n", config["token_key"])

	simplepush.Clients = make(map[string]*simplepush.Client)

	// Initialize the common server.
	simplepush.InitServer(config, logger)
    handlers := simplepush.NewHandler(config, logger)

	// Register the handlers
	// each websocket gets it's own handler.
	http.HandleFunc("/update/", handlers.UpdateHandler)
	http.HandleFunc("/status/", handlers.StatusHandler)
	http.Handle("/", websocket.Handler(handlers.PushSocketHandler))

	// Config the server
	host := util.MzGet(config, "host", "localhost")
	port := util.MzGet(config, "port", "8080")

	// Hoist the main sail
	logger.Info("main",
		fmt.Sprintf("listening on %s:%s", host, port), nil)
	err := http.ListenAndServe(fmt.Sprintf("%s:%s", host, port), nil)
	if err != nil {
		panic("ListenAndServe: " + err.Error())
	}
}

// 04fs
// vim: set tabstab=4 softtabstop=4 shiftwidth=4 noexpandtab
<commit_msg>removed extra debug statement<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package main

import (
	"code.google.com/p/go.net/websocket"
	"mozilla.org/simplepush"
	"mozilla.org/util"

	"flag"
	"fmt"
	"log"
	"net/http"
)

var logger *util.HekaLogger

// -- main
func main() {

	var configFile string

	flag.StringVar(&configFile, "config", "config.ini", "Configuration File")
	flag.Parse()
	config := util.MzGetConfig(configFile)

    config = simplepush.FixConfig(config)
	log.Printf("CurrentHost: %s", config["shard.current_host"])

	logger = util.NewHekaLogger(config)

	simplepush.Clients = make(map[string]*simplepush.Client)

	// Initialize the common server.
	simplepush.InitServer(config, logger)
    handlers := simplepush.NewHandler(config, logger)

	// Register the handlers
	// each websocket gets it's own handler.
	http.HandleFunc("/update/", handlers.UpdateHandler)
	http.HandleFunc("/status/", handlers.StatusHandler)
	http.Handle("/", websocket.Handler(handlers.PushSocketHandler))

	// Config the server
	host := util.MzGet(config, "host", "localhost")
	port := util.MzGet(config, "port", "8080")

	// Hoist the main sail
	logger.Info("main",
		fmt.Sprintf("listening on %s:%s", host, port), nil)
	err := http.ListenAndServe(fmt.Sprintf("%s:%s", host, port), nil)
	if err != nil {
		panic("ListenAndServe: " + err.Error())
	}
}

// 04fs
// vim: set tabstab=4 softtabstop=4 shiftwidth=4 noexpandtab
<|endoftext|>


<commit_before>package main

import (
	"github.com/codegangsta/cli"
	"github.com/fgrehm/devstep-cli/commands"
	"github.com/fgrehm/devstep-cli/devstep"
)

func main() {
	app := cli.NewApp()
	app.Name = "devstep"
	app.Author = "Fábio Rehm"
	app.Email = "fgrehm@gmail.com"
	app.Usage = "development environments made easy"
	app.Version = "0.3.1"
	app.EnableBashCompletion = true
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "log-level, l", Value: "warning", Usage: "log level", EnvVar: "DEVSTEP_LOG"},
	}
	app.Before = func(c *cli.Context) error {
		return devstep.SetLogLevel(c.GlobalString("log-level"))
	}
	app.Commands = []cli.Command{
		commands.HackCmd,
		commands.BuildCmd,
		commands.BootstrapCmd,
		commands.InfoCmd,
		commands.ExecCmd,
		commands.RunCmd,
		commands.BinstubsCmd,
		commands.CleanCmd,
		commands.PristineCmd,
		commands.InitCmd,
	}

	app.RunAndExitOnError()
}
<commit_msg>Bump dev version<commit_after>package main

import (
	"github.com/codegangsta/cli"
	"github.com/fgrehm/devstep-cli/commands"
	"github.com/fgrehm/devstep-cli/devstep"
)

func main() {
	app := cli.NewApp()
	app.Name = "devstep"
	app.Author = "Fábio Rehm"
	app.Email = "fgrehm@gmail.com"
	app.Usage = "development environments made easy"
	app.Version = "0.3.2.dev"
	app.EnableBashCompletion = true
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "log-level, l", Value: "warning", Usage: "log level", EnvVar: "DEVSTEP_LOG"},
	}
	app.Before = func(c *cli.Context) error {
		return devstep.SetLogLevel(c.GlobalString("log-level"))
	}
	app.Commands = []cli.Command{
		commands.HackCmd,
		commands.BuildCmd,
		commands.BootstrapCmd,
		commands.InfoCmd,
		commands.ExecCmd,
		commands.RunCmd,
		commands.BinstubsCmd,
		commands.CleanCmd,
		commands.PristineCmd,
		commands.InitCmd,
	}

	app.RunAndExitOnError()
}
<|endoftext|>


<commit_before>// Copyright 2013 The Prometheus Authors
// 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 (
	"bufio"
	"net"
	"net/http"
	"os"
	"strconv"

	"github.com/howeyc/fsnotify"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
	"github.com/prometheus/common/version"
	"gopkg.in/alecthomas/kingpin.v2"

	"github.com/prometheus/statsd_exporter/pkg/mapper"
)

func init() {
	prometheus.MustRegister(version.NewCollector("statsd_exporter"))
}

func serveHTTP(listenAddress, metricsEndpoint string) {
	//lint:ignore SA1019 prometheus.Handler() is deprecated.
	http.Handle(metricsEndpoint, prometheus.Handler())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
			<title>StatsD Exporter</title>

StatsD Exporter

<a href="` + metricsEndpoint + `">Metrics

			`))
	})
	log.Fatal(http.ListenAndServe(listenAddress, nil))
}

func ipPortFromString(addr string) (*net.IPAddr, int) {
	host, portStr, err := net.SplitHostPort(addr)
	if err != nil {
		log.Fatal("Bad StatsD listening address", addr)
	}

	if host == "" {
		host = "0.0.0.0"
	}
	ip, err := net.ResolveIPAddr("ip", host)
	if err != nil {
		log.Fatalf("Unable to resolve %s: %s", host, err)
	}

	port, err := strconv.Atoi(portStr)
	if err != nil || port < 0 || port > 65535 {
		log.Fatalf("Bad port %s: %s", portStr, err)
	}

	return ip, port
}

func udpAddrFromString(addr string) *net.UDPAddr {
	ip, port := ipPortFromString(addr)
	return &net.UDPAddr{
		IP:   ip.IP,
		Port: port,
		Zone: ip.Zone,
	}
}

func tcpAddrFromString(addr string) *net.TCPAddr {
	ip, port := ipPortFromString(addr)
	return &net.TCPAddr{
		IP:   ip.IP,
		Port: port,
		Zone: ip.Zone,
	}
}

func watchConfig(fileName string, mapper *mapper.MetricMapper) {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}

	err = watcher.WatchFlags(fileName, fsnotify.FSN_MODIFY)
	if err != nil {
		log.Fatal(err)
	}

	for {
		select {
		case ev := <-watcher.Event:
			log.Infof("Config file changed (%s), attempting reload", ev)
			err = mapper.InitFromFile(fileName)
			if err != nil {
				log.Errorln("Error reloading config:", err)
				configLoads.WithLabelValues("failure").Inc()
			} else {
				log.Infoln("Config reloaded successfully")
				configLoads.WithLabelValues("success").Inc()
			}
			// Re-add the file watcher since it can get lost on some changes. E.g.
			// saving a file with vim results in a RENAME-MODIFY-DELETE event
			// sequence, after which the newly written file is no longer watched.
			_ = watcher.WatchFlags(fileName, fsnotify.FSN_MODIFY)
		case err := <-watcher.Error:
			log.Errorln("Error watching config:", err)
		}
	}
}

func dumpFSM(mapper *mapper.MetricMapper, dumpFilename string) error {
	f, err := os.Create(dumpFilename)
	if err != nil {
		return err
	}
	log.Infoln("Start dumping FSM to", dumpFilename)
	w := bufio.NewWriter(f)
	mapper.FSM.DumpFSM(w)
	w.Flush()
	f.Close()
	log.Infoln("Finish dumping FSM")
	return nil
}

func main() {
	var (
		listenAddress   = kingpin.Flag("web.listen-address", "The address on which to expose the web interface and generated Prometheus metrics.").Default(":9102").String()
		metricsEndpoint = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String()
		statsdListenUDP = kingpin.Flag("statsd.listen-udp", "The UDP address on which to receive statsd metric lines. \"\" disables it.").Default(":9125").String()
		statsdListenTCP = kingpin.Flag("statsd.listen-tcp", "The TCP address on which to receive statsd metric lines. \"\" disables it.").Default(":9125").String()
		mappingConfig   = kingpin.Flag("statsd.mapping-config", "Metric mapping configuration file name.").String()
		readBuffer      = kingpin.Flag("statsd.read-buffer", "Size (in bytes) of the operating system's transmit read buffer associated with the UDP connection. Please make sure the kernel parameters net.core.rmem_max is set to a value greater than the value specified.").Int()
		dumpFSMPath     = kingpin.Flag("debug.dump-fsm", "The path to dump internal FSM generated for glob matching as Dot file.").Default("").String()
	)

	log.AddFlags(kingpin.CommandLine)
	kingpin.Version(version.Print("statsd_exporter"))
	kingpin.HelpFlag.Short('h')
	kingpin.Parse()

	if *statsdListenUDP == "" && *statsdListenTCP == "" {
		log.Fatalln("At least one of UDP/TCP listeners must be specified.")
	}

	log.Infoln("Starting StatsD -> Prometheus Exporter", version.Info())
	log.Infoln("Build context", version.BuildContext())
	log.Infof("Accepting StatsD Traffic: UDP %v, TCP %v", *statsdListenUDP, *statsdListenTCP)
	log.Infoln("Accepting Prometheus Requests on", *listenAddress)

	go serveHTTP(*listenAddress, *metricsEndpoint)

	events := make(chan Events, 1024)
	defer close(events)

	if *statsdListenUDP != "" {
		udpListenAddr := udpAddrFromString(*statsdListenUDP)
		uconn, err := net.ListenUDP("udp", udpListenAddr)
		if err != nil {
			log.Fatal(err)
		}

		if *readBuffer != 0 {
			err = uconn.SetReadBuffer(*readBuffer)
			if err != nil {
				log.Fatal("Error setting UDP read buffer:", err)
			}
		}

		ul := &StatsDUDPListener{conn: uconn}
		go ul.Listen(events)
	}

	if *statsdListenTCP != "" {
		tcpListenAddr := tcpAddrFromString(*statsdListenTCP)
		tconn, err := net.ListenTCP("tcp", tcpListenAddr)
		if err != nil {
			log.Fatal(err)
		}
		defer tconn.Close()

		tl := &StatsDTCPListener{conn: tconn}
		go tl.Listen(events)
	}

	mapper := &mapper.MetricMapper{MappingsCount: mappingsCount}
	if *mappingConfig != "" {
		err := mapper.InitFromFile(*mappingConfig)
		if err != nil {
			log.Fatal("Error loading config:", err)
		}
		if *dumpFSMPath != "" {
			err := dumpFSM(mapper, *dumpFSMPath)
			if err != nil {
				log.Fatal("Error dumping FSM:", err)
			}
		}
		go watchConfig(*mappingConfig, mapper)
	}
	exporter := NewExporter(mapper)
	exporter.Listen(events)
}
<commit_msg>Add pprof for profiling<commit_after>// Copyright 2013 The Prometheus Authors
// 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 (
	"bufio"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"strconv"

	"github.com/howeyc/fsnotify"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
	"github.com/prometheus/common/version"
	"gopkg.in/alecthomas/kingpin.v2"

	"github.com/prometheus/statsd_exporter/pkg/mapper"
)

func init() {
	prometheus.MustRegister(version.NewCollector("statsd_exporter"))
}

func serveHTTP(listenAddress, metricsEndpoint string) {
	//lint:ignore SA1019 prometheus.Handler() is deprecated.
	http.Handle(metricsEndpoint, prometheus.Handler())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
			<title>StatsD Exporter</title>

StatsD Exporter

<a href="` + metricsEndpoint + `">Metrics

			`))
	})
	log.Fatal(http.ListenAndServe(listenAddress, nil))
}

func ipPortFromString(addr string) (*net.IPAddr, int) {
	host, portStr, err := net.SplitHostPort(addr)
	if err != nil {
		log.Fatal("Bad StatsD listening address", addr)
	}

	if host == "" {
		host = "0.0.0.0"
	}
	ip, err := net.ResolveIPAddr("ip", host)
	if err != nil {
		log.Fatalf("Unable to resolve %s: %s", host, err)
	}

	port, err := strconv.Atoi(portStr)
	if err != nil || port < 0 || port > 65535 {
		log.Fatalf("Bad port %s: %s", portStr, err)
	}

	return ip, port
}

func udpAddrFromString(addr string) *net.UDPAddr {
	ip, port := ipPortFromString(addr)
	return &net.UDPAddr{
		IP:   ip.IP,
		Port: port,
		Zone: ip.Zone,
	}
}

func tcpAddrFromString(addr string) *net.TCPAddr {
	ip, port := ipPortFromString(addr)
	return &net.TCPAddr{
		IP:   ip.IP,
		Port: port,
		Zone: ip.Zone,
	}
}

func watchConfig(fileName string, mapper *mapper.MetricMapper) {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}

	err = watcher.WatchFlags(fileName, fsnotify.FSN_MODIFY)
	if err != nil {
		log.Fatal(err)
	}

	for {
		select {
		case ev := <-watcher.Event:
			log.Infof("Config file changed (%s), attempting reload", ev)
			err = mapper.InitFromFile(fileName)
			if err != nil {
				log.Errorln("Error reloading config:", err)
				configLoads.WithLabelValues("failure").Inc()
			} else {
				log.Infoln("Config reloaded successfully")
				configLoads.WithLabelValues("success").Inc()
			}
			// Re-add the file watcher since it can get lost on some changes. E.g.
			// saving a file with vim results in a RENAME-MODIFY-DELETE event
			// sequence, after which the newly written file is no longer watched.
			_ = watcher.WatchFlags(fileName, fsnotify.FSN_MODIFY)
		case err := <-watcher.Error:
			log.Errorln("Error watching config:", err)
		}
	}
}

func dumpFSM(mapper *mapper.MetricMapper, dumpFilename string) error {
	f, err := os.Create(dumpFilename)
	if err != nil {
		return err
	}
	log.Infoln("Start dumping FSM to", dumpFilename)
	w := bufio.NewWriter(f)
	mapper.FSM.DumpFSM(w)
	w.Flush()
	f.Close()
	log.Infoln("Finish dumping FSM")
	return nil
}

func main() {
	var (
		listenAddress   = kingpin.Flag("web.listen-address", "The address on which to expose the web interface and generated Prometheus metrics.").Default(":9102").String()
		metricsEndpoint = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String()
		statsdListenUDP = kingpin.Flag("statsd.listen-udp", "The UDP address on which to receive statsd metric lines. \"\" disables it.").Default(":9125").String()
		statsdListenTCP = kingpin.Flag("statsd.listen-tcp", "The TCP address on which to receive statsd metric lines. \"\" disables it.").Default(":9125").String()
		mappingConfig   = kingpin.Flag("statsd.mapping-config", "Metric mapping configuration file name.").String()
		readBuffer      = kingpin.Flag("statsd.read-buffer", "Size (in bytes) of the operating system's transmit read buffer associated with the UDP connection. Please make sure the kernel parameters net.core.rmem_max is set to a value greater than the value specified.").Int()
		dumpFSMPath     = kingpin.Flag("debug.dump-fsm", "The path to dump internal FSM generated for glob matching as Dot file.").Default("").String()
	)

	log.AddFlags(kingpin.CommandLine)
	kingpin.Version(version.Print("statsd_exporter"))
	kingpin.HelpFlag.Short('h')
	kingpin.Parse()

	if *statsdListenUDP == "" && *statsdListenTCP == "" {
		log.Fatalln("At least one of UDP/TCP listeners must be specified.")
	}

	log.Infoln("Starting StatsD -> Prometheus Exporter", version.Info())
	log.Infoln("Build context", version.BuildContext())
	log.Infof("Accepting StatsD Traffic: UDP %v, TCP %v", *statsdListenUDP, *statsdListenTCP)
	log.Infoln("Accepting Prometheus Requests on", *listenAddress)

	go serveHTTP(*listenAddress, *metricsEndpoint)

	events := make(chan Events, 1024)
	defer close(events)

	if *statsdListenUDP != "" {
		udpListenAddr := udpAddrFromString(*statsdListenUDP)
		uconn, err := net.ListenUDP("udp", udpListenAddr)
		if err != nil {
			log.Fatal(err)
		}

		if *readBuffer != 0 {
			err = uconn.SetReadBuffer(*readBuffer)
			if err != nil {
				log.Fatal("Error setting UDP read buffer:", err)
			}
		}

		ul := &StatsDUDPListener{conn: uconn}
		go ul.Listen(events)
	}

	if *statsdListenTCP != "" {
		tcpListenAddr := tcpAddrFromString(*statsdListenTCP)
		tconn, err := net.ListenTCP("tcp", tcpListenAddr)
		if err != nil {
			log.Fatal(err)
		}
		defer tconn.Close()

		tl := &StatsDTCPListener{conn: tconn}
		go tl.Listen(events)
	}

	mapper := &mapper.MetricMapper{MappingsCount: mappingsCount}
	if *mappingConfig != "" {
		err := mapper.InitFromFile(*mappingConfig)
		if err != nil {
			log.Fatal("Error loading config:", err)
		}
		if *dumpFSMPath != "" {
			err := dumpFSM(mapper, *dumpFSMPath)
			if err != nil {
				log.Fatal("Error dumping FSM:", err)
			}
		}
		go watchConfig(*mappingConfig, mapper)
	}
	exporter := NewExporter(mapper)
	exporter.Listen(events)
}
<|endoftext|>


<commit_before>package main

import (
	"io"
	"log"
	"os"

	"github.com/amoghe/dedup/codec"
	"github.com/pkg/profile"

	"gopkg.in/alecthomas/kingpin.v2"
)

const (
	// DefaultWindowSize is the window over which to compute rolling fingerprint
	DefaultWindowSize = "64"
	// DefaultZeroBits specifies the bitbank which must be 0 to identify a segment boundary
	DefaultZeroBits = "16"
)

var (
	zeroBits = kingpin.Flag("zerobits", "Number of 0 bits to identify segment").
			Default(DefaultZeroBits).
			Uint64()
	windowSize = kingpin.Flag("window", "Fingerprint window size (bytes)").
			Default(DefaultWindowSize).
			Uint64()
	reduplicate = kingpin.Flag("decompress", "Recover original file (redup)").
			Short('d').
			Bool()
	memProfile = kingpin.Flag("memprofile", "Enable memory profiling").
			Bool()
	// toStdout = kingpin.Flag("stdout", "Write to stdout").
	// 		Short('c').
	// 		Bool()
	// TODO: Add positional arg, then deal appropriately with toStdout
	// inputFile = kingpin.Arg("infile", "File to be deduplicated").
	// 		File()
	makeSig = kingpin.Flag("signature", "Make a signature file").
		Short('s').
		Bool()
)

func main() {
	parseArgsOrDie()
	if *memProfile {
		defer profile.Start(profile.MemProfile).Stop()
	}
	if *makeSig {
		doSignatures(os.Stdin, os.Stdout)
	} else if *reduplicate {
		doRedup(os.Stdin, os.Stdout)
	} else {
		doDedup(os.Stdin, os.Stdout)
	}
}

// Parse and validate command line arguments, fail on bad args
func parseArgsOrDie() {
	kingpin.Parse()

	if *windowSize <= 1 {
		log.Fatalln("Window too small (<=1)")
	}

	if *zeroBits <= 1 {
		log.Fatalln("Mask size too small (<=1)")
	}
}

// Performs deduplication (compression)
func doDedup(in io.ReadCloser, out io.WriteCloser) {
	dedup := NewDeduplicator(*windowSize, uint64((1<<*zeroBits)-1), out)
	if err := dedup.Do(in); err != nil {
		log.Fatalln("Failed to parse file:", err)
	}
	// Print stats (TODO: make this optional)
	_ = dedup.stats.Print(os.Stderr)
	//dedup.stats.PrintSegLengths(os.Stderr)
}

// Performs reduplication (decompression)
func doRedup(in io.ReadCloser, out io.WriteCloser) {
	if err := codec.NewGobReader(in, out).Reduplicate(); err != nil {
		log.Fatalln("Failed to redup", err)
	}
}

// Makes a signature file
func doSignatures(in io.ReadCloser, out io.WriteCloser) {
	sm := NewSigMaker(*windowSize, uint64((1<<*zeroBits)-1), out)
	if err := sm.Do(in); err != nil {
		log.Fatalln("Failed to generate signatures:", err)
	}
}
<commit_msg>Accept input file as positional argument<commit_after>package main

import (
	"io"
	"log"
	"os"

	"github.com/amoghe/dedup/codec"
	"github.com/pkg/profile"

	"gopkg.in/alecthomas/kingpin.v2"
)

const (
	// DefaultWindowSize is the window over which to compute rolling fingerprint
	DefaultWindowSize = "64"
	// DefaultZeroBits specifies the bitbank which must be 0 to identify a segment boundary
	DefaultZeroBits = "16"
)

var (
	zeroBits = kingpin.Flag("zerobits", "Number of 0 bits to identify segment").
			Default(DefaultZeroBits).
			Uint64()
	windowSize = kingpin.Flag("window", "Fingerprint window size (bytes)").
			Default(DefaultWindowSize).
			Uint64()
	reduplicate = kingpin.Flag("decompress", "Recover original file (redup)").
			Short('d').
			Bool()
	memProfile = kingpin.Flag("memprofile", "Enable memory profiling").
			Bool()
	// toStdout = kingpin.Flag("stdout", "Write to stdout").
	// 		Short('c').
	// 		Bool()
	//TODO: Add positional arg, then deal appropriately with toStdout
	inputFile = kingpin.Arg("infile", "File to be deduplicated").
			File()
	makeSig = kingpin.Flag("signature", "Make a signature file").
		Short('s').
		Bool()

	inFile  io.ReadCloser  = os.Stdin
	outFile io.WriteCloser = os.Stdout
)

func main() {
	parseArgsOrDie()
	if *memProfile {
		defer profile.Start(profile.MemProfile).Stop()
	}
	if *makeSig {
		doSignatures(os.Stdin, os.Stdout)
	} else if *reduplicate {
		doRedup(os.Stdin, os.Stdout)
	} else {
		doDedup(inFile, outFile)
	}
}

// Parse and validate command line arguments, fail on bad args
func parseArgsOrDie() {
	kingpin.Parse()

	if *windowSize <= 1 {
		log.Fatalln("Window too small (<=1)")
	}

	if *zeroBits <= 1 {
		log.Fatalln("Mask size too small (<=1)")
	}

	if *inputFile != nil {
		inFile = *inputFile
	}
}

// Performs deduplication (compression)
func doDedup(in io.ReadCloser, out io.WriteCloser) {
	dedup := NewDeduplicator(*windowSize, uint64((1<<*zeroBits)-1), out)
	if err := dedup.Do(in); err != nil {
		log.Fatalln("Failed to parse file:", err)
	}
	// Print stats (TODO: make this optional)
	_ = dedup.stats.Print(os.Stderr)
	//dedup.stats.PrintSegLengths(os.Stderr)
}

// Performs reduplication (decompression)
func doRedup(in io.ReadCloser, out io.WriteCloser) {
	if err := codec.NewGobReader(in, out).Reduplicate(); err != nil {
		log.Fatalln("Failed to redup", err)
	}
}

// Makes a signature file
func doSignatures(in io.ReadCloser, out io.WriteCloser) {
	sm := NewSigMaker(*windowSize, uint64((1<<*zeroBits)-1), out)
	if err := sm.Do(in); err != nil {
		log.Fatalln("Failed to generate signatures:", err)
	}
}
<|endoftext|>


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

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"

	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client
var eggyoID = "ufa92a3a52f197e19bfddeb5ca0595e93"
var logNof = "open"

type GeoContent struct {
	LatLong string `json:"latLon"`
	Utm     string `json:"utm"`
	Mgrs    string `json:"mgrs"`
}

type ResultGeoLoc struct {
	Results GeoContent `json:"result"`
}

func getGeoLoc(body []byte) (*ResultGeoLoc, error) {
	var s = new(ResultGeoLoc)
	err := json.Unmarshal(body, &s)
	if err != nil {
		fmt.Println("whoops:", err)
	}
	return s, err
}

func main() {
	getAllUser()
	// line bot
	strID := os.Getenv("ChannelID")
	numID, err := strconv.ParseInt(strID, 10, 64)
	if err != nil {
		log.Fatal("Wrong environment setting about ChannelID")
	}

	bot, err = linebot.NewClient(numID, os.Getenv("ChannelSecret"), os.Getenv("MID"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
	//test

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

	received, err := bot.ParseRequest(r)
	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	for _, result := range received.Results {
		content := result.Content()
		log.Println("-->", content)

		//Log detail receive content
		if content != nil {
			log.Println("RECEIVE Msg:", content.IsMessage, " OP:", content.IsOperation, " type:", content.ContentType, " from:", content.From, "to:", content.To, " ID:", content.ID)
		}
		// user add friend
		if content != nil && content.IsOperation && content.OpType == linebot.OpTypeAddedAsFriend {
			out := fmt.Sprintf("Bot แปลงพิกัด Eggyo\nวิธีใช้\nเพียงแค่กดแชร์ Location ที่ต้องการ ระบบจะทำการแปลง Location เป็นพิกัดระบบต่างๆ และหาความสูงจากระดับน้ำทะเลให้\n\nหรือจะพูดคุยกับ bot ก็ได้\nกด #help เพื่อดูวิธีใช้อื่นๆ \nติดต่อผู้พัฒนา LINE ID : eggyo")
			//result.RawContent.Params[0] is who send your bot friend added operation, otherwise you cannot get in content or operation content.
			_, err = bot.SendText([]string{content.From}, out)
			if logNof == "open" {
				bot.SendText([]string{eggyoID}, "bot has a new friend :"+content.From)
			}

			addNewUser(content.From)

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

		if content != nil && content.IsMessage && content.ContentType == linebot.ContentTypeText {

			text, err := content.TextContent()
			if logNof == "open" {
				bot.SendText([]string{eggyoID}, "bot get msg:"+text.Text+"\nfrom :"+content.From)
			}
			// reply message
			var processedText = messageCheck(text.Text)
			_, err = bot.SendText([]string{content.From}, processedText)

			if err != nil {
				log.Println(err)
			}
		}
		if content != nil && content.ContentType == linebot.ContentTypeLocation {
			_, err = bot.SendText([]string{content.From}, "ระบบกำลังประมวลผล...")

			loc, err := content.LocationContent()

			// add eggyo geo test
			resp, err := http.Get("http://eggyo-geo-node.herokuapp.com/geo/" + FloatToString(loc.Latitude) + "/" + FloatToString(loc.Longitude))
			if err != nil {
				println(err.Error())
				return
			}
			defer resp.Body.Close()
			body, err := ioutil.ReadAll(resp.Body)
			log.Println(string(body))

			var elev = callGoogleElev(loc.Latitude, loc.Longitude)
			geo, err := getGeoLoc([]byte(body))
			_, err = bot.SendText([]string{content.From}, "LatLong :"+geo.Results.LatLong)
			_, err = bot.SendText([]string{content.From}, "Utm :"+geo.Results.Utm+"\n\nMgrs :"+geo.Results.Mgrs+"\n\nAltitude :"+elev)
			if logNof == "open" {
				bot.SendText([]string{eggyoID}, "bot get loc:"+geo.Results.Mgrs+"\nfrom :"+content.From)
			}
			if err != nil {
				log.Println(err)
			}
		}
	}
}
<commit_msg>change geo node call curl data form "/" to ","<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"

	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client
var eggyoID = "ufa92a3a52f197e19bfddeb5ca0595e93"
var logNof = "open"

type GeoContent struct {
	LatLong string `json:"latLon"`
	Utm     string `json:"utm"`
	Mgrs    string `json:"mgrs"`
}

type ResultGeoLoc struct {
	Results GeoContent `json:"result"`
}

func getGeoLoc(body []byte) (*ResultGeoLoc, error) {
	var s = new(ResultGeoLoc)
	err := json.Unmarshal(body, &s)
	if err != nil {
		fmt.Println("whoops:", err)
	}
	return s, err
}

func main() {
	getAllUser()
	// line bot
	strID := os.Getenv("ChannelID")
	numID, err := strconv.ParseInt(strID, 10, 64)
	if err != nil {
		log.Fatal("Wrong environment setting about ChannelID")
	}

	bot, err = linebot.NewClient(numID, os.Getenv("ChannelSecret"), os.Getenv("MID"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
	//test

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

	received, err := bot.ParseRequest(r)
	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}
	for _, result := range received.Results {
		content := result.Content()
		log.Println("-->", content)

		//Log detail receive content
		if content != nil {
			log.Println("RECEIVE Msg:", content.IsMessage, " OP:", content.IsOperation, " type:", content.ContentType, " from:", content.From, "to:", content.To, " ID:", content.ID)
		}
		// user add friend
		if content != nil && content.IsOperation && content.OpType == linebot.OpTypeAddedAsFriend {
			out := fmt.Sprintf("Bot แปลงพิกัด Eggyo\nวิธีใช้\nเพียงแค่กดแชร์ Location ที่ต้องการ ระบบจะทำการแปลง Location เป็นพิกัดระบบต่างๆ และหาความสูงจากระดับน้ำทะเลให้\n\nหรือจะพูดคุยกับ bot ก็ได้\nกด #help เพื่อดูวิธีใช้อื่นๆ \nติดต่อผู้พัฒนา LINE ID : eggyo")
			//result.RawContent.Params[0] is who send your bot friend added operation, otherwise you cannot get in content or operation content.
			_, err = bot.SendText([]string{content.From}, out)
			if logNof == "open" {
				bot.SendText([]string{eggyoID}, "bot has a new friend :"+content.From)
			}

			addNewUser(content.From)

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

		if content != nil && content.IsMessage && content.ContentType == linebot.ContentTypeText {

			text, err := content.TextContent()
			if logNof == "open" {
				bot.SendText([]string{eggyoID}, "bot get msg:"+text.Text+"\nfrom :"+content.From)
			}
			// reply message
			var processedText = messageCheck(text.Text)
			_, err = bot.SendText([]string{content.From}, processedText)

			if err != nil {
				log.Println(err)
			}
		}
		if content != nil && content.ContentType == linebot.ContentTypeLocation {
			_, err = bot.SendText([]string{content.From}, "ระบบกำลังประมวลผล...")

			loc, err := content.LocationContent()

			// add eggyo geo test
			resp, err := http.Get("http://eggyo-geo-node.herokuapp.com/geo/" + FloatToString(loc.Latitude) + "," + FloatToString(loc.Longitude))
			if err != nil {
				println(err.Error())
				return
			}
			defer resp.Body.Close()
			body, err := ioutil.ReadAll(resp.Body)
			log.Println(string(body))

			var elev = callGoogleElev(loc.Latitude, loc.Longitude)
			geo, err := getGeoLoc([]byte(body))
			_, err = bot.SendText([]string{content.From}, "LatLong :"+geo.Results.LatLong)
			_, err = bot.SendText([]string{content.From}, "Utm :"+geo.Results.Utm+"\n\nMgrs :"+geo.Results.Mgrs+"\n\nAltitude :"+elev)
			if logNof == "open" {
				bot.SendText([]string{eggyoID}, "bot get loc:"+geo.Results.Mgrs+"\nfrom :"+content.From)
			}
			if err != nil {
				log.Println(err)
			}
		}
	}
}
<|endoftext|>