<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"

	"github.com/icecrime/octostats/repository"

	gh "github.com/crosbymichael/octokat"
)

func githubAuthToken(config *GitHubConfig) string {
	if config.AuthToken != "" {
		return config.AuthToken
	}

	fileContent, err := ioutil.ReadFile(config.AuthTokenFile)
	if err != nil {
		logger.WithField("error", err).WithField("filename", config.AuthTokenFile).Fatal("failed to load github auth token file")
	}
	return string(fileContent)
}

func logProgress(item, state string, page int) {
	logger.WithField("page", page).WithField("page", page).Debugf("loading %s", item)
}

func parseRepository(repo string) (*gh.Repo, error) {
	if splitRepos := strings.Split(repo, "/"); len(splitRepos) == 2 {
		return &gh.Repo{Name: splitRepos[1], UserName: splitRepos[0]}, nil
	}
	return nil, fmt.Errorf("bad repo format %s (expected username/repo)", repo)
}

func NewGitHubRepository(config *GitHubConfig) repository.Repository {
	ghClient := gh.NewClient()
	ghClient.Token = githubAuthToken(config)

	repoId, err := parseRepository(config.Repository)
	if err != nil {
		logger.Fatal(err)
	}
	return &gitHubRepository{id: repoId, client: ghClient}
}

type gitHubRepository struct {
	id     *gh.Repo
	client *gh.Client
}

func (repo *gitHubRepository) Id() gh.Repo {
	return *repo.id
}

func (repo *gitHubRepository) Issues(state, sort string) ([]*gh.Issue, error) {
	o := &gh.Options{}
	o.QueryParams = map[string]string{
		"sort":      sort,
		"direction": "asc",
		"state":     state,
		"per_page":  "100",
	}

	prevSize := -1
	allIssues := []*gh.Issue{}
	for page := 1; len(allIssues) != prevSize; page++ {
		logProgress("issues", state, page)
		o.QueryParams["page"] = strconv.Itoa(page)
		if issues, err := repo.client.Issues(*repo.id, o); err != nil {
			return nil, err
		} else {
			prevSize = len(allIssues)
			allIssues = append(allIssues, issues...)
		}
	}
	logger.Debugf("Loaded %d %s issues", len(allIssues), state)
	return allIssues, nil
}

func (repo *gitHubRepository) PullRequests(state, sort string) ([]*gh.PullRequest, error) {
	o := &gh.Options{}
	o.QueryParams = map[string]string{
		"sort":      sort,
		"direction": "asc",
		"state":     state,
		"per_page":  "100",
	}

	prevSize := -1
	allPullRequests := []*gh.PullRequest{}
	for page := 1; len(allPullRequests) != prevSize; page++ {
		logProgress("issues", state, page)
		o.QueryParams["page"] = strconv.Itoa(page)
		if prs, err := repo.client.PullRequests(*repo.id, o); err != nil {
			return nil, err
		} else {
			prevSize = len(allPullRequests)
			allPullRequests = append(allPullRequests, prs...)
		}
	}
	logger.Debugf("Loaded %d %s pull requests", len(allPullRequests), state)
	return allPullRequests, nil
}
<commit_msg>Fix log progress key.<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"

	"github.com/icecrime/octostats/repository"

	gh "github.com/crosbymichael/octokat"
)

func githubAuthToken(config *GitHubConfig) string {
	if config.AuthToken != "" {
		return config.AuthToken
	}

	fileContent, err := ioutil.ReadFile(config.AuthTokenFile)
	if err != nil {
		logger.WithField("error", err).WithField("filename", config.AuthTokenFile).Fatal("failed to load github auth token file")
	}
	return string(fileContent)
}

func logProgress(item, state string, page int) {
	logger.WithField("page", page).WithField("page", page).Debugf("loading %s", item)
}

func parseRepository(repo string) (*gh.Repo, error) {
	if splitRepos := strings.Split(repo, "/"); len(splitRepos) == 2 {
		return &gh.Repo{Name: splitRepos[1], UserName: splitRepos[0]}, nil
	}
	return nil, fmt.Errorf("bad repo format %s (expected username/repo)", repo)
}

func NewGitHubRepository(config *GitHubConfig) repository.Repository {
	ghClient := gh.NewClient()
	ghClient.Token = githubAuthToken(config)

	repoId, err := parseRepository(config.Repository)
	if err != nil {
		logger.Fatal(err)
	}
	return &gitHubRepository{id: repoId, client: ghClient}
}

type gitHubRepository struct {
	id     *gh.Repo
	client *gh.Client
}

func (repo *gitHubRepository) Id() gh.Repo {
	return *repo.id
}

func (repo *gitHubRepository) Issues(state, sort string) ([]*gh.Issue, error) {
	o := &gh.Options{}
	o.QueryParams = map[string]string{
		"sort":      sort,
		"direction": "asc",
		"state":     state,
		"per_page":  "100",
	}

	prevSize := -1
	allIssues := []*gh.Issue{}
	for page := 1; len(allIssues) != prevSize; page++ {
		logProgress("issues", state, page)
		o.QueryParams["page"] = strconv.Itoa(page)
		if issues, err := repo.client.Issues(*repo.id, o); err != nil {
			return nil, err
		} else {
			prevSize = len(allIssues)
			allIssues = append(allIssues, issues...)
		}
	}
	logger.Debugf("Loaded %d %s issues", len(allIssues), state)
	return allIssues, nil
}

func (repo *gitHubRepository) PullRequests(state, sort string) ([]*gh.PullRequest, error) {
	o := &gh.Options{}
	o.QueryParams = map[string]string{
		"sort":      sort,
		"direction": "asc",
		"state":     state,
		"per_page":  "100",
	}

	prevSize := -1
	allPullRequests := []*gh.PullRequest{}
	for page := 1; len(allPullRequests) != prevSize; page++ {
		logProgress("pull-requests", state, page)
		o.QueryParams["page"] = strconv.Itoa(page)
		if prs, err := repo.client.PullRequests(*repo.id, o); err != nil {
			return nil, err
		} else {
			prevSize = len(allPullRequests)
			allPullRequests = append(allPullRequests, prs...)
		}
	}
	logger.Debugf("Loaded %d %s pull requests", len(allPullRequests), state)
	return allPullRequests, nil
}
<|endoftext|>


<commit_before>package main

import "fmt"

//import "reflect"
import "net/http"
import "io/ioutil"

import "os"

func main() {
	resp, err := http.Get("https://api.github.com/users/cdale77/repos")

	if err != nil {
		fmt.Println("%s", err)
		os.Exit(1)
	} else {
		defer resp.Body.Close()
		contents, err := ioutil.ReadAll(resp.Body)

		if err != nil {
			fmt.Println("%s", err)
			os.Exit(1)
		}

		fmt.Println("%s\n", string(contents))

	}
}
<commit_msg>wip-working download github archive file<commit_after>package main

import (
	//"compress/gzip"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"reflect"
	//"strconv"
)

func main() {
	getData()
}

func getData() {
	url := "http://data.githubarchive.org/2015-01-01-12.json.gz"

	resp, err := http.Get(url)

	if err != nil {
		fmt.Println("%s", err)
		os.Exit(1)
	} else {
		defer resp.Body.Close()
		contents, err := ioutil.ReadAll(resp.Body)

		if err != nil {
			fmt.Println("%s", err)
			os.Exit(1)
		}

		ioutil.WriteFile("dat1.gz", contents, 0644)

		fmt.Println("completed")
		fmt.Println(reflect.TypeOf(contents))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"strconv"
	"exec"
	"rpc"
	"flag"
	"time"
	"path"
	"fmt"
	"os"
)

var (
	server = flag.Bool("s", false, "run a server instead of a client")
	format = flag.String("f", "nice", "output format (vim | emacs | nice | csv)")
	input  = flag.String("in", "", "use this file instead of stdin input")
	sock   = CreateSockFlag("sock", "socket type (unix | tcp)")
	addr   = flag.String("addr", "localhost:37373", "address for tcp socket")
)

//-------------------------------------------------------------------------
// Formatter interfaces
//-------------------------------------------------------------------------

type FormatterEmpty interface {
	WriteEmpty()
}

type FormatterCandidates interface {
	WriteCandidates(names, types, classes []string, num int)
}

//-------------------------------------------------------------------------
// NiceFormatter (just for testing, simple textual output)
//-------------------------------------------------------------------------

type NiceFormatter struct{}

func (*NiceFormatter) WriteEmpty() {
	fmt.Printf("Nothing to complete.\n")
}

func (*NiceFormatter) WriteCandidates(names, types, classes []string, num int) {
	fmt.Printf("Found %d candidates:\n", len(names))
	for i := 0; i < len(names); i++ {
		abbr := fmt.Sprintf("%s %s %s", classes[i], names[i], types[i])
		if classes[i] == "func" {
			abbr = fmt.Sprintf("%s %s%s", classes[i], names[i], types[i][len("func"):])
		}
		fmt.Printf("  %s\n", abbr)
	}
}

//-------------------------------------------------------------------------
// VimFormatter
//-------------------------------------------------------------------------

type VimFormatter struct{}

func (*VimFormatter) WriteEmpty() {
	fmt.Print("[0, []]")
}

func (*VimFormatter) WriteCandidates(names, types, classes []string, num int) {
	fmt.Printf("[%d, [", num)
	for i := 0; i < len(names); i++ {
		word := names[i]
		if classes[i] == "func" {
			word += "("
		}

		abbr := fmt.Sprintf("%s %s %s", classes[i], names[i], types[i])
		if classes[i] == "func" {
			abbr = fmt.Sprintf("%s %s%s", classes[i], names[i], types[i][len("func"):])
		}
		fmt.Printf("{'word': '%s', 'abbr': '%s'}", word, abbr)
		if i != len(names)-1 {
			fmt.Printf(", ")
		}

	}
	fmt.Printf("]]")
}

//-------------------------------------------------------------------------
// EmacsFormatter
//-------------------------------------------------------------------------

type EmacsFormatter struct{}

func (*EmacsFormatter) WriteCandidates(names, types, classes []string, num int) {
	for i := 0; i < len(names); i++ {
		name := names[i]
		hint := classes[i] + " " + types[i]
		if classes[i] == "func" {
			hint = types[i]
		}
		fmt.Printf("%s,,%s\n", name, hint)
	}
}

//-------------------------------------------------------------------------
// CSVFormatter
//-------------------------------------------------------------------------

type CSVFormatter struct{}

func (*CSVFormatter) WriteCandidates(names, types, classes []string, num int) {
	for i := 0; i < len(names); i++ {
		fmt.Printf("%s,,%s,,%s\n", classes[i], names[i], types[i])
	}
}

//-------------------------------------------------------------------------

func getFormatter() interface{} {
	switch *format {
	case "vim":
		return new(VimFormatter)
	case "emacs":
		return new(EmacsFormatter)
	case "nice":
		return new(NiceFormatter)
	case "csv":
		return new(CSVFormatter)
	}
	return new(VimFormatter)
}

func getSocketFilename() string {
	user := os.Getenv("USER")
	if user == "" {
		user = "all"
	}
	return fmt.Sprintf("%s/acrserver.%s", os.TempDir(), user)
}

func fileExists(filename string) bool {
	_, err := os.Stat(filename)
	if err != nil {
		return false
	}
	return true
}

func serverFunc() int {
	readConfig(&Config)

	addr := *addr
	if *sock == "unix" {
		addr = getSocketFilename()
		if fileExists(addr) {
			fmt.Printf("unix socket: '%s' already exists\n", addr)
			return 1
		}
	}
	daemon = NewDaemon(*sock, addr)
	if *sock == "unix" {
		// cleanup unix socket file
		defer os.Remove(addr)
	}

	rpcremote := new(RPCRemote)
	rpc.Register(rpcremote)

	daemon.acr.Loop()
	return 0
}

func cmdStatus(c *rpc.Client) {
	fmt.Printf("%s\n", Client_Status(c, 0))
}

func cmdAutoComplete(c *rpc.Client) {
	var file []byte
	var err os.Error

	if *input != "" {
		file, err = ioutil.ReadFile(*input)
	} else {
		file, err = ioutil.ReadAll(os.Stdin)
	}

	if err != nil {
		panic(err.String())
	}

	filename := ""
	cursor := -1

	switch flag.NArg() {
	case 2:
		cursor, _ = strconv.Atoi(flag.Arg(1))
	case 3:
		filename = flag.Arg(1)
		cursor, _ = strconv.Atoi(flag.Arg(2))
	}

	if filename != "" && !IsAbsPath(filename) {
		cwd, _ := os.Getwd()
		filename = path.Join(cwd, filename)
	}

	formatter := getFormatter()
	names, types, classes, partial := Client_AutoComplete(c, file, filename, cursor)
	if names == nil {
		if f, ok := formatter.(FormatterEmpty); ok {
			f.WriteEmpty()
		}
		return
	}

	if f, ok := formatter.(FormatterCandidates); ok {
		f.WriteCandidates(names, types, classes, partial)
	}
}

func cmdClose(c *rpc.Client) {
	Client_Close(c, 0)
}

func cmdDropCache(c *rpc.Client) {
	Client_DropCache(c, 0)
}

func cmdSet(c *rpc.Client) {
	switch flag.NArg() {
	case 1:
		fmt.Print(Client_Set(c, "", ""))
	case 2:
		fmt.Print(Client_Set(c, flag.Arg(1), ""))
	case 3:
		fmt.Print(Client_Set(c, flag.Arg(1), flag.Arg(2)))
	}
}

func tryRunServer() os.Error {
	path, err := exec.LookPath("gocode")
	if err != nil {
		return err
	}

	args := []string{"gocode", "-s", "-sock", *sock, "-addr", *addr}
	_, err = os.ForkExec(path, args, os.Environ(), "", []*os.File{nil, nil, nil})
	if err != nil {
		return err
	}
	return nil
}

func tryToConnect(network, address string) (client *rpc.Client, err os.Error) {
	t := 0
	for {
		client, err = rpc.Dial(network, address)
		if err != nil && t < 1000 {
			time.Sleep(10e6) // wait 10 milliseconds
			t += 10
			continue
		}
		break
	}

	return
}

func clientFunc() int {
	addr := *addr
	if *sock == "unix" {
		addr = getSocketFilename()
	}

	// client
	client, err := rpc.Dial(*sock, addr)
	if err != nil {
		err = tryRunServer()
		if err != nil {
			fmt.Printf("%s\n", err.String())
			return 1
		}
		client, err = tryToConnect(*sock, addr)
		if err != nil {
			fmt.Printf("%s\n", err.String())
			return 1
		}
	}
	defer client.Close()

	if flag.NArg() > 0 {
		switch flag.Arg(0) {
		case "autocomplete":
			cmdAutoComplete(client)
		case "close":
			cmdClose(client)
		case "status":
			cmdStatus(client)
		case "drop-cache":
			cmdDropCache(client)
		case "set":
			cmdSet(client)
		}
	}
	return 0
}

func main() {
	flag.Parse()

	var retval int
	if *server {
		retval = serverFunc()
	} else {
		retval = clientFunc()
	}
	os.Exit(retval)
}
<commit_msg>Add JSON formatter.<commit_after>package main

import (
	"io/ioutil"
	"strconv"
	"exec"
	"rpc"
	"flag"
	"time"
	"path"
	"fmt"
	"os"
)

var (
	server = flag.Bool("s", false, "run a server instead of a client")
	format = flag.String("f", "nice", "output format (vim | emacs | nice | csv | json)")
	input  = flag.String("in", "", "use this file instead of stdin input")
	sock   = CreateSockFlag("sock", "socket type (unix | tcp)")
	addr   = flag.String("addr", "localhost:37373", "address for tcp socket")
)

//-------------------------------------------------------------------------
// Formatter interfaces
//-------------------------------------------------------------------------

type FormatterEmpty interface {
	WriteEmpty()
}

type FormatterCandidates interface {
	WriteCandidates(names, types, classes []string, num int)
}

//-------------------------------------------------------------------------
// NiceFormatter (just for testing, simple textual output)
//-------------------------------------------------------------------------

type NiceFormatter struct{}

func (*NiceFormatter) WriteEmpty() {
	fmt.Printf("Nothing to complete.\n")
}

func (*NiceFormatter) WriteCandidates(names, types, classes []string, num int) {
	fmt.Printf("Found %d candidates:\n", len(names))
	for i := 0; i < len(names); i++ {
		abbr := fmt.Sprintf("%s %s %s", classes[i], names[i], types[i])
		if classes[i] == "func" {
			abbr = fmt.Sprintf("%s %s%s", classes[i], names[i], types[i][len("func"):])
		}
		fmt.Printf("  %s\n", abbr)
	}
}

//-------------------------------------------------------------------------
// VimFormatter
//-------------------------------------------------------------------------

type VimFormatter struct{}

func (*VimFormatter) WriteEmpty() {
	fmt.Print("[0, []]")
}

func (*VimFormatter) WriteCandidates(names, types, classes []string, num int) {
	fmt.Printf("[%d, [", num)
	for i := 0; i < len(names); i++ {
		word := names[i]
		if classes[i] == "func" {
			word += "("
		}

		abbr := fmt.Sprintf("%s %s %s", classes[i], names[i], types[i])
		if classes[i] == "func" {
			abbr = fmt.Sprintf("%s %s%s", classes[i], names[i], types[i][len("func"):])
		}
		fmt.Printf("{'word': '%s', 'abbr': '%s'}", word, abbr)
		if i != len(names)-1 {
			fmt.Printf(", ")
		}

	}
	fmt.Printf("]]")
}

//-------------------------------------------------------------------------
// EmacsFormatter
//-------------------------------------------------------------------------

type EmacsFormatter struct{}

func (*EmacsFormatter) WriteCandidates(names, types, classes []string, num int) {
	for i := 0; i < len(names); i++ {
		name := names[i]
		hint := classes[i] + " " + types[i]
		if classes[i] == "func" {
			hint = types[i]
		}
		fmt.Printf("%s,,%s\n", name, hint)
	}
}

//-------------------------------------------------------------------------
// CSVFormatter
//-------------------------------------------------------------------------

type CSVFormatter struct{}

func (*CSVFormatter) WriteCandidates(names, types, classes []string, num int) {
	for i := 0; i < len(names); i++ {
		fmt.Printf("%s,,%s,,%s\n", classes[i], names[i], types[i])
	}
}

//-------------------------------------------------------------------------
// JSONFormatter
//-------------------------------------------------------------------------

type JSONFormatter struct{}

func (*JSONFormatter) WriteEmpty() {
	fmt.Print("[]")
}

func (*JSONFormatter) WriteCandidates(names, types, classes []string, num int) {
	fmt.Printf(`[%d, [`, num)
	for i := 0; i < len(names); i++ {
		fmt.Printf(`{"class": "%s", "name": "%s", "type": "%s"}`,
			classes[i], names[i], types[i])
		if i != len(names)-1 {
			fmt.Printf(", ")
		}
	}
	fmt.Print("]]")
}

//-------------------------------------------------------------------------

func getFormatter() interface{} {
	switch *format {
	case "vim":
		return new(VimFormatter)
	case "emacs":
		return new(EmacsFormatter)
	case "nice":
		return new(NiceFormatter)
	case "csv":
		return new(CSVFormatter)
	case "json":
		return new(JSONFormatter)
	}
	return new(VimFormatter)
}

func getSocketFilename() string {
	user := os.Getenv("USER")
	if user == "" {
		user = "all"
	}
	return fmt.Sprintf("%s/acrserver.%s", os.TempDir(), user)
}

func fileExists(filename string) bool {
	_, err := os.Stat(filename)
	if err != nil {
		return false
	}
	return true
}

func serverFunc() int {
	readConfig(&Config)

	addr := *addr
	if *sock == "unix" {
		addr = getSocketFilename()
		if fileExists(addr) {
			fmt.Printf("unix socket: '%s' already exists\n", addr)
			return 1
		}
	}
	daemon = NewDaemon(*sock, addr)
	if *sock == "unix" {
		// cleanup unix socket file
		defer os.Remove(addr)
	}

	rpcremote := new(RPCRemote)
	rpc.Register(rpcremote)

	daemon.acr.Loop()
	return 0
}

func cmdStatus(c *rpc.Client) {
	fmt.Printf("%s\n", Client_Status(c, 0))
}

func cmdAutoComplete(c *rpc.Client) {
	var file []byte
	var err os.Error

	if *input != "" {
		file, err = ioutil.ReadFile(*input)
	} else {
		file, err = ioutil.ReadAll(os.Stdin)
	}

	if err != nil {
		panic(err.String())
	}

	filename := ""
	cursor := -1

	switch flag.NArg() {
	case 2:
		cursor, _ = strconv.Atoi(flag.Arg(1))
	case 3:
		filename = flag.Arg(1)
		cursor, _ = strconv.Atoi(flag.Arg(2))
	}

	if filename != "" && !IsAbsPath(filename) {
		cwd, _ := os.Getwd()
		filename = path.Join(cwd, filename)
	}

	formatter := getFormatter()
	names, types, classes, partial := Client_AutoComplete(c, file, filename, cursor)
	if names == nil {
		if f, ok := formatter.(FormatterEmpty); ok {
			f.WriteEmpty()
		}
		return
	}

	if f, ok := formatter.(FormatterCandidates); ok {
		f.WriteCandidates(names, types, classes, partial)
	}
}

func cmdClose(c *rpc.Client) {
	Client_Close(c, 0)
}

func cmdDropCache(c *rpc.Client) {
	Client_DropCache(c, 0)
}

func cmdSet(c *rpc.Client) {
	switch flag.NArg() {
	case 1:
		fmt.Print(Client_Set(c, "", ""))
	case 2:
		fmt.Print(Client_Set(c, flag.Arg(1), ""))
	case 3:
		fmt.Print(Client_Set(c, flag.Arg(1), flag.Arg(2)))
	}
}

func tryRunServer() os.Error {
	path, err := exec.LookPath("gocode")
	if err != nil {
		return err
	}

	args := []string{"gocode", "-s", "-sock", *sock, "-addr", *addr}
	_, err = os.ForkExec(path, args, os.Environ(), "", []*os.File{nil, nil, nil})
	if err != nil {
		return err
	}
	return nil
}

func tryToConnect(network, address string) (client *rpc.Client, err os.Error) {
	t := 0
	for {
		client, err = rpc.Dial(network, address)
		if err != nil && t < 1000 {
			time.Sleep(10e6) // wait 10 milliseconds
			t += 10
			continue
		}
		break
	}

	return
}

func clientFunc() int {
	addr := *addr
	if *sock == "unix" {
		addr = getSocketFilename()
	}

	// client
	client, err := rpc.Dial(*sock, addr)
	if err != nil {
		err = tryRunServer()
		if err != nil {
			fmt.Printf("%s\n", err.String())
			return 1
		}
		client, err = tryToConnect(*sock, addr)
		if err != nil {
			fmt.Printf("%s\n", err.String())
			return 1
		}
	}
	defer client.Close()

	if flag.NArg() > 0 {
		switch flag.Arg(0) {
		case "autocomplete":
			cmdAutoComplete(client)
		case "close":
			cmdClose(client)
		case "status":
			cmdStatus(client)
		case "drop-cache":
			cmdDropCache(client)
		case "set":
			cmdSet(client)
		}
	}
	return 0
}

func main() {
	flag.Parse()

	var retval int
	if *server {
		retval = serverFunc()
	} else {
		retval = clientFunc()
	}
	os.Exit(retval)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"sync"
)

func init() {
	//log.SetFlags(log.Lshortfile)
}

var (
	gVerbose = flag.Bool("v", false, "be verbose")
	gDebug   = flag.Bool("d", false, "debug mode")
	gCPUNum  = flag.Int("c", runtime.NumCPU(), "number of cpus to run simultaneously")
)

func showUsage() {
	fmt.Printf("Usage %s [-v][-d][-c cpu_number] json_config_file\n\n", os.Args[0])
	fmt.Printf("Flags:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = showUsage
	flag.Parse()

	args := flag.Args()
	if 0 == len(args) || 1 < len(args) {
		flag.Usage()
		return
	}

	// check flag values
	if *gCPUNum > runtime.NumCPU() {
		log.Printf("[WARN] cpu number %d too big, wil be set to actual number of your cpus: %d", *gCPUNum, runtime.NumCPU())
		*gCPUNum = runtime.NumCPU()
	}

	// debug mode is verbose
	if *gDebug {
		*gVerbose = true
	}

	// parse json configuration first
	feedTargets := ParseJsonConfig(args[0])
	cacheDB := feedTargets[0].CacheDB

	var err error

	// create cache db if not exists
	if *gVerbose {
		log.Printf("creating cache database %s", cacheDB)
	}

	if _, err = os.Stat(cacheDB); nil != err && os.IsNotExist(err) {
		err = CreateDBScheme(cacheDB)
		if nil != err {
			log.Fatalf("[ERROR] failed to create cache database %s", cacheDB)
		}
	} else {
		log.Printf("found cache database %s", cacheDB)
	}

	var wg sync.WaitGroup

	for _, feedTar := range feedTargets {
		wg.Add(1)

		go func(feedTar *FeedTarget) {
			defer wg.Done()
			// parse feed entry title and link
			feed, ok := ParseIndexHtml(feedTar)
			if !ok {
				log.Printf("[ERROR] failed to parse feed target %s", feedTar.FeedPath)
			}

			// parse feed entry description
			if !ParseContentHtml(feedTar, feed) {
				log.Printf("[ERROR] failed to parse content html for feed target %s", feedTar.FeedPath)
			}

			// generate rss2 feed
			rss2FeedStr, err := GenerateRss2Feed(feed)
			if nil != err {
				log.Printf("[ERROR] failed to generate rss %s", feedTar.FeedPath)
			} else {
				err = ioutil.WriteFile(feedTar.FeedPath, rss2FeedStr, 0644)
				if nil != err {
					log.Printf("[ERROR] failed to save feed at %s", feedTar.FeedPath)
				}
				if *gVerbose {
					log.Printf("[DONE] saving feed at %s", feedTar.FeedPath)
				}
			}
		}(feedTar)
	}

	wg.Wait()
}
<commit_msg>fix log description when creating cache database<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"sync"
)

func init() {
	//log.SetFlags(log.Lshortfile)
}

var (
	gVerbose = flag.Bool("v", false, "be verbose")
	gDebug   = flag.Bool("d", false, "debug mode")
	gCPUNum  = flag.Int("c", runtime.NumCPU(), "number of cpus to run simultaneously")
)

func showUsage() {
	fmt.Printf("Usage %s [-v][-d][-c cpu_number] json_config_file\n\n", os.Args[0])
	fmt.Printf("Flags:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = showUsage
	flag.Parse()

	args := flag.Args()
	if 0 == len(args) || 1 < len(args) {
		flag.Usage()
		return
	}

	// check flag values
	if *gCPUNum > runtime.NumCPU() {
		log.Printf("[WARN] cpu number %d too big, wil be set to actual number of your cpus: %d", *gCPUNum, runtime.NumCPU())
		*gCPUNum = runtime.NumCPU()
	}

	// debug mode is verbose
	if *gDebug {
		*gVerbose = true
	}

	// parse json configuration first
	feedTargets := ParseJsonConfig(args[0])
	cacheDB := feedTargets[0].CacheDB

	var err error

	// create cache db if not exists
	if _, err = os.Stat(cacheDB); nil != err && os.IsNotExist(err) {
		log.Printf("creating cache database %s", cacheDB)
		err = CreateDBScheme(cacheDB)
		if nil != err {
			log.Fatalf("[ERROR] failed to create cache database %s", cacheDB)
		}
	} else {
		log.Printf("found cache database %s", cacheDB)
	}

	var wg sync.WaitGroup

	for _, feedTar := range feedTargets {
		wg.Add(1)

		go func(feedTar *FeedTarget) {
			defer wg.Done()
			// parse feed entry title and link
			feed, ok := ParseIndexHtml(feedTar)
			if !ok {
				log.Printf("[ERROR] failed to parse feed target %s", feedTar.FeedPath)
			}

			// parse feed entry description
			if !ParseContentHtml(feedTar, feed) {
				log.Printf("[ERROR] failed to parse content html for feed target %s", feedTar.FeedPath)
			}

			// generate rss2 feed
			rss2FeedStr, err := GenerateRss2Feed(feed)
			if nil != err {
				log.Printf("[ERROR] failed to generate rss %s", feedTar.FeedPath)
			} else {
				err = ioutil.WriteFile(feedTar.FeedPath, rss2FeedStr, 0644)
				if nil != err {
					log.Printf("[ERROR] failed to save feed at %s", feedTar.FeedPath)
				}
				if *gVerbose {
					log.Printf("[DONE] saving feed at %s", feedTar.FeedPath)
				}
			}
		}(feedTar)
	}

	wg.Wait()
}
<|endoftext|>


<commit_before>package goober

/*
 * Funky fresh library brought to you by:
 *   Cole Brown
 *
 */

import  (
  "net/http"
  "strings"
  "io"
  "time"
  "fmt"
)

// Main goober struct. Abides the handler interface.
type Goober struct {
  head map[string]*routeTreeNode
  ErrorPages map[int]string
}

// Goober handlers, for simplicity, are just functions with a given
// signature.
type Handler func(http.ResponseWriter, *Request)
type PipeHandler func(http.ResponseWriter, *Request) (error)

// We use this a few places, so we can give it a type as well.
type RouteMap map[string]*routeTreeNode

// Our parse tree structure for routes
type routeTreeNode struct {
  handler Handler // Handler if a node is a terminal
  pre []PipeHandler
  post []PipeHandler
  children RouteMap // Static children
  variables RouteMap // Dynamic/variable children
}

// Chaining for pre/post handlers

func (n *routeTreeNode) AddPreFunc(f PipeHandler) (*routeTreeNode) {
  n.pre = append(n.pre[:], f)
  return n
}

func (n *routeTreeNode) AddPostFunc(f PipeHandler) (*routeTreeNode) {
  n.post = append(n.post[:], f)
  return n
}

// Augment http.Request with URLParams that will be grabbed
// from the request in the form of /:variables/
type Request struct {
  http.Request
  URLParams map[string]string
}

// A quick initializer for routeTreeNodes
func newRouteTreeNode() (node *routeTreeNode) {
  node = &routeTreeNode{
    children: make(RouteMap),
    variables: make(RouteMap),
  }

  return
}

// Initialize our Goober object
func New() (* Goober) {
  var head = make(RouteMap)
  head["GET"] = newRouteTreeNode()
  head["HEAD"] = newRouteTreeNode()
  head["POST"] = newRouteTreeNode()
  head["PUT"] = newRouteTreeNode()
  head["DELETE"] = newRouteTreeNode()

  g := &Goober{
    head: head,
    ErrorPages: make(map[int]string),
  }

  return g
}

// Simple helper to allow us to trim leading and trailing /'s
func isSlash(s rune) (bool) {
  return s == '/'
}

type BadRouteError struct {
  Route string
  Reason string
}

func (e BadRouteError) Error() string {
  return "\"" + e.Route + "\" is an invalid route because " + e.Reason + "."
}

// Adds a handler to our route tree
func (g *Goober) AddHandler(method string, route string, handler Handler) (cur *routeTreeNode){
  route = strings.TrimFunc(route, isSlash)
  var parts = strings.Split(route, "/")

  // Iterate through the bits of our path and add to the tree
  cur = g.head[method]

  // check to see if it's the root
  if len(route) > 0 {
    for i := range parts {
      var part = parts[i]

      // No // empty paths
      if len(part) == 0 {
        return nil
      }

      // Check for variables
      if strings.HasPrefix(part, ":") {
        // dynamic
        if (cur.variables[part] != nil) {
          cur = cur.variables[part]
        } else {
          cur.variables[part] = newRouteTreeNode()
          cur = cur.variables[part]
        }
      } else {
        // static
        if (cur.children[part] != nil) {
          cur = cur.children[part]
        } else {
          cur.children[part] = newRouteTreeNode()
          cur = cur.children[part]
        }
      }
    }
  }

  // add handler
  cur.handler = handler
  return
}

// Wrapper functions for common types of request
func (g *Goober) Get(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("GET", route, handler)
}

func (g *Goober) Head(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("HEAD", route, handler)
}

func (g *Goober) Post(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("POST", route, handler)
}

func (g *Goober) Put(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("PUT", route, handler)
}

func (g *Goober) Delete(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("DELETE", route, handler)
}

type RouteNotFoundError struct {
  Route string
}

func (e RouteNotFoundError) Error() string {
  return "Route \"" + e.Route + "\" was not found."
}

func walkTree(node *routeTreeNode, parts []string, r *Request) (*routeTreeNode, error) {
  var err error = nil
  if len(parts) == 0 {
    // if we've reached a terminal state, return node
    if node.handler == nil {
      err = &RouteNotFoundError{Route: r.URL.Path}
    }
    return node, err
  } else {
    // else, look for it
    var part = parts[0]

    if child, ok := node.children["*"]; ok {
      node = child
      r.URLParams["*"] = strings.Join(parts, "/")
    } else if node.children[part] != nil {
      // check static routes first, they have priority
      return walkTree(node.children[part], parts[1:], r)
    } else {
      for k, v := range node.variables {
        // check all dynamic routes, taking first match
        node, err = walkTree(v, parts[1:], r)
        if err == nil {
          // goofy recursive way to build up params
          r.URLParams[k] = part
          return node, err
        }
      }

      // if we don't find any dynamic matches, there was an error
      err = &RouteNotFoundError{Route: r.URL.Path}
    }
  }

  return node, err
}

// Given a request, find the appropriate handler
func (g *Goober) GetHandler(r *Request) (node *routeTreeNode, err error) {
  path := strings.TrimFunc(r.URL.Path, isSlash)

  // root case
  if len(path) == 0 {
    return g.head[r.Method], nil
  }

  parts := strings.Split(path, "/")
  return walkTree(g.head[r.Method], parts, r)
}

// A simple function to handle error pages for us
func (g *Goober) errorHandler(w http.ResponseWriter, r *Request, code int) {
  if page, ok := g.ErrorPages[code]; ok {
    w.Header().Set("Content-Type", "text/html; charset=utf-8")
    w.WriteHeader(code)
    io.WriteString(w, page)
  }
}

// Borrowed from web.go
func webTime(t time.Time) string {
  ftime := t.Format(time.RFC1123)
  if strings.HasSuffix(ftime, "UTC") {
    ftime = ftime[0:len(ftime)-3] + "GMT"
  }
  return ftime
}

// Routes requests
func (g *Goober) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  var startTime = time.Now()
  defer func() {
    fmt.Printf("[%s] %s - took %s\n", r.Method, r.URL.Path, time.Since(startTime))
    r.Body.Close()
  }()

  // create augmented request object
  var request = &Request{
    Request: *r,
    URLParams: make(map[string]string),
  }

  // get the handler for the request
  node, err := g.GetHandler(request)
  if err == nil {
    // user response. pad with content-type.
    w.Header().Set("Content-Type", "text/html; charset=utf-8")
    w.Header().Set("Server", "goober.go")
    w.Header().Set("Date", webTime(time.Now().UTC()))

    // Run prefunctions
    for _, f := range node.pre {
      if e := f(w, request); e != nil {
        // if there is an error, print, 404 and exit out
        fmt.Println("[ERROR] " + e.Error())
        g.errorHandler(w, request, 404)
        return
      }
    }

    // Run the handler
    node.handler(w, request)

    // Run all postfunctions
    for _, f := range node.post {
      if e := f(w, request); e != nil {
        // if there is an error, print and exit out
        fmt.Println("[ERROR] " + e.Error())
        return
      }
    }
  } else {
    fmt.Println("[ERROR] " + err.Error())
    g.errorHandler(w, request, 404)
  }

}

// shortcut to start serving a goober service
func (g *Goober) ListenAndServe(addr string) (err error)  {
  http.Handle("/", g)
  return http.ListenAndServe(addr, nil)
}

<commit_msg>Fixed a bug with root handlers<commit_after>package goober

/*
 * Funky fresh library brought to you by:
 *   Cole Brown
 *
 */

import  (
  "net/http"
  "strings"
  "io"
  "time"
  "fmt"
)

// Main goober struct. Abides the handler interface.
type Goober struct {
  head map[string]*routeTreeNode
  ErrorPages map[int]string
}

// Goober handlers, for simplicity, are just functions with a given
// signature.
type Handler func(http.ResponseWriter, *Request)
type PipeHandler func(http.ResponseWriter, *Request) (error)

// We use this a few places, so we can give it a type as well.
type RouteMap map[string]*routeTreeNode

// Our parse tree structure for routes
type routeTreeNode struct {
  handler Handler // Handler if a node is a terminal
  pre []PipeHandler
  post []PipeHandler
  children RouteMap // Static children
  variables RouteMap // Dynamic/variable children
}

// Chaining for pre/post handlers

func (n *routeTreeNode) AddPreFunc(f PipeHandler) (*routeTreeNode) {
  n.pre = append(n.pre[:], f)
  return n
}

func (n *routeTreeNode) AddPostFunc(f PipeHandler) (*routeTreeNode) {
  n.post = append(n.post[:], f)
  return n
}

// Augment http.Request with URLParams that will be grabbed
// from the request in the form of /:variables/
type Request struct {
  http.Request
  URLParams map[string]string
}

// A quick initializer for routeTreeNodes
func newRouteTreeNode() (node *routeTreeNode) {
  node = &routeTreeNode{
    children: make(RouteMap),
    variables: make(RouteMap),
    pre: []PipeHandler{},
    post: []PipeHandler{},
  }

  return
}

// Initialize our Goober object
func New() (* Goober) {
  var head = make(RouteMap)
  head["GET"] = newRouteTreeNode()
  head["HEAD"] = newRouteTreeNode()
  head["POST"] = newRouteTreeNode()
  head["PUT"] = newRouteTreeNode()
  head["DELETE"] = newRouteTreeNode()

  g := &Goober{
    head: head,
    ErrorPages: make(map[int]string),
  }

  return g
}

// Simple helper to allow us to trim leading and trailing /'s
func isSlash(s rune) (bool) {
  return s == '/'
}

type BadRouteError struct {
  Route string
  Reason string
}

func (e BadRouteError) Error() string {
  return "\"" + e.Route + "\" is an invalid route because " + e.Reason + "."
}

// Adds a handler to our route tree
func (g *Goober) AddHandler(method string, route string, handler Handler) (cur *routeTreeNode){
  route = strings.TrimFunc(route, isSlash)
  var parts = strings.Split(route, "/")

  // Iterate through the bits of our path and add to the tree
  cur = g.head[method]

  // check to see if it's the root
  if len(route) > 0 {
    for i := range parts {
      var part = parts[i]

      // No // empty paths
      if len(part) == 0 {
        return nil
      }

      // Check for variables
      if strings.HasPrefix(part, ":") {
        // dynamic
        if (cur.variables[part] != nil) {
          cur = cur.variables[part]
        } else {
          cur.variables[part] = newRouteTreeNode()
          cur = cur.variables[part]
        }
      } else {
        // static
        if (cur.children[part] != nil) {
          cur = cur.children[part]
        } else {
          cur.children[part] = newRouteTreeNode()
          cur = cur.children[part]
        }
      }
    }
  }

  // add handler
  cur.handler = handler
  return
}

// Wrapper functions for common types of request
func (g *Goober) Get(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("GET", route, handler)
}

func (g *Goober) Head(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("HEAD", route, handler)
}

func (g *Goober) Post(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("POST", route, handler)
}

func (g *Goober) Put(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("PUT", route, handler)
}

func (g *Goober) Delete(route string, handler Handler) (node *routeTreeNode) {
  return g.AddHandler("DELETE", route, handler)
}

type RouteNotFoundError struct {
  Route string
}

func (e RouteNotFoundError) Error() string {
  return "Route \"" + e.Route + "\" was not found."
}

func walkTree(node *routeTreeNode, parts []string, r *Request) (*routeTreeNode, error) {
  var err error = nil
  if len(parts) == 0 {
    // if we've reached a terminal state, return node
    if node.handler == nil {
      err = &RouteNotFoundError{Route: r.URL.Path}
    }
    return node, err
  } else {
    // else, look for it
    var part = parts[0]

    if child, ok := node.children["*"]; ok {
      node = child
      r.URLParams["*"] = strings.Join(parts, "/")
    } else if node.children[part] != nil {
      // check static routes first, they have priority
      return walkTree(node.children[part], parts[1:], r)
    } else {
      for k, v := range node.variables {
        // check all dynamic routes, taking first match
        node, err = walkTree(v, parts[1:], r)
        if err == nil {
          // goofy recursive way to build up params
          r.URLParams[k] = part
          return node, err
        }
      }

      // if we don't find any dynamic matches, there was an error
      err = &RouteNotFoundError{Route: r.URL.Path}
    }
  }

  return node, err
}

// Given a request, find the appropriate handler
func (g *Goober) GetHandler(r *Request) (node *routeTreeNode, err error) {
  path := strings.TrimFunc(r.URL.Path, isSlash)

  // root case
  if len(path) == 0 {
    if g.head[r.Method].handler == nil {
      err := &RouteNotFoundError{Route: r.URL.Path}
      return g.head[r.Method], err
    } else {
      return g.head[r.Method], nil
    }
  }

  parts := strings.Split(path, "/")
  return walkTree(g.head[r.Method], parts, r)
}

// A simple function to handle error pages for us
func (g *Goober) errorHandler(w http.ResponseWriter, r *Request, code int) {
  if page, ok := g.ErrorPages[code]; ok {
    w.Header().Set("Content-Type", "text/html; charset=utf-8")
    w.WriteHeader(code)
    io.WriteString(w, page)
  }
}

// Borrowed from web.go
func webTime(t time.Time) string {
  ftime := t.Format(time.RFC1123)
  if strings.HasSuffix(ftime, "UTC") {
    ftime = ftime[0:len(ftime)-3] + "GMT"
  }
  return ftime
}

// Routes requests
func (g *Goober) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  var startTime = time.Now()
  defer func() {
    fmt.Printf("[%s] %s - took %s\n", r.Method, r.URL.Path, time.Since(startTime))
    r.Body.Close()
  }()

  // create augmented request object
  var request = &Request{
    Request: *r,
    URLParams: make(map[string]string),
  }

  // get the handler for the request
  node, err := g.GetHandler(request)
  if err == nil {
    // user response. pad with content-type.
    w.Header().Set("Content-Type", "text/html; charset=utf-8")
    w.Header().Set("Server", "goober.go")
    w.Header().Set("Date", webTime(time.Now().UTC()))

    // Run prefunctions
    for _, f := range node.pre {
      if e := f(w, request); e != nil {
        // if there is an error, print, 404 and exit out
        fmt.Println("[ERROR] " + e.Error())
        g.errorHandler(w, request, 404)
        return
      }
    }

    // Run the handler
    node.handler(w, request)

    // Run all postfunctions
    for _, f := range node.post {
      if e := f(w, request); e != nil {
        // if there is an error, print and exit out
        fmt.Println("[ERROR] " + e.Error())
        return
      }
    }
  } else {
    fmt.Println("[ERROR] " + err.Error())
    g.errorHandler(w, request, 404)
  }

}

// shortcut to start serving a goober service
func (g *Goober) ListenAndServe(addr string) (err error)  {
  http.Handle("/", g)
  return http.ListenAndServe(addr, nil)
}

<|endoftext|>


<commit_before>package gopher

import (
	. "github.com/gopherlabs/gopher-framework"
	"github.com/gopherlabs/gopher-services"
)

//const (
//	LOGGER   = framework.LOGGER
//	ROUTER   = framework.ROUTER
//	RENDERER = framework.RENDERER
//	PARAMS   = framework.PARAMS
//	SAMPLE   = framework.SAMPLE
//)

var (
	Log     Loggable
	Router  Routable
	Context Mappable
)

func init() {
	initialize()
}

func initialize(config ...Config) *Container {
	appConf := Config{}
	if len(config) > 0 {
		appConf = config[0]
	}
	container := NewContainer(appConf)
	container.Use(LoggerMiddleware)
	registerProviders(container)
	return container
}

func registerProviders(c *Container) {

	c.RegisterProvider(new(services.LogProvider))
	Log = c.Log

	c.RegisterProvider(new(services.MapProvider))
	Context = c.Context

	c.RegisterProvider(new(services.RouteProvider))
	Router = c.Router

	c.RegisterProvider(new(services.ParameterProvider))

	c.RegisterProvider(new(services.RenderProvider))
}

func ListenAndServe() {
	Router.Serve()
}
<commit_msg>Adder Render APIs<commit_after>package gopher

import (
	. "github.com/gopherlabs/gopher-framework"
	"github.com/gopherlabs/gopher-services"
)

//const (
//	LOGGER   = framework.LOGGER
//	ROUTER   = framework.ROUTER
//	RENDERER = framework.RENDERER
//	PARAMS   = framework.PARAMS
//	SAMPLE   = framework.SAMPLE
//)

var (
	Log     Loggable
	Router  Routable
	Context Mappable
	Render  Renderable
)

func init() {
	initialize()
}

func initialize(config ...Config) *Container {
	appConf := Config{}
	if len(config) > 0 {
		appConf = config[0]
	}
	container := NewContainer(appConf)
	container.Use(LoggerMiddleware)
	registerProviders(container)
	return container
}

func registerProviders(c *Container) {

	c.RegisterProvider(new(services.LogProvider))
	Log = c.Log

	c.RegisterProvider(new(services.MapProvider))
	Context = c.Context

	c.RegisterProvider(new(services.RouteProvider))
	Router = c.Router

	c.RegisterProvider(new(services.ParameterProvider))

	c.RegisterProvider(new(services.RenderProvider))
	Render = c.Render
}

func ListenAndServe() {
	Router.Serve()
}
<|endoftext|>


<commit_before>package command

import (
	"fmt"
	"reflect"
)

// gopkgs.go: v1

// NOTE: This file is autogenerated by gopkgs.com.
const (
	goPkgsSrcPath = "github.com/rainycape/command"
	goPkgsName    = "command"
	goPkgsErrFmt  = "invalid import path %s - please use gopkgs.com/%s.v1 or see http://gopkgs.com/%s"
)

type goPkgsCheck struct{}

func init() {
	typ := reflect.TypeOf(goPkgsCheck{})
	if typ.PkgPath() == goPkgsSrcPath {
		panic(fmt.Errorf(goPkgsErrFmt, typ.PkgPath(), goPkgsName, goPkgsName))
	}
}
<commit_msg>Don't enforce gopkgs.com import path<commit_after><|endoftext|>


<commit_before>package gotree

const (
	newLine      = "\n"
	emptySpace   = "    "
	middleItem   = "├── "
	continueItem = "│   "
	lastItem     = "└── "
)

type (
	tree struct {
		text  string
		items []Tree
	}

	Tree interface {
		Add(text string) Tree
		AddTree(tree Tree)
		Items() []Tree
		Text() string
		Print() string
	}

	printer struct {
	}

	Printer interface {
		Print(Tree) string
	}
)

func New(text string) Tree {
	return &tree{
		text:  text,
		items: []Tree{},
	}
}

func (t *tree) Add(text string) Tree {
	n := New(text)
	t.items = append(t.items, n)
	return n
}

func (t *tree) AddTree(tree Tree) {
	t.items = append(t.items, tree)
}

func (t *tree) Text() string {
	return t.text
}

func (t *tree) Items() []Tree {
	return t.items
}

func (t *tree) Print() string {
	return newPrinter().Print(t)
}

func newPrinter() Printer {
	return &printer{}
}

func (p *printer) Print(t Tree) string {
	return t.Text() + newLine + p.printItems(t.Items(), []bool{})
}

func (p *printer) printText(text string, spaces []bool, last bool) string {
	var result string
	for _, space := range spaces {
		if space {
			result += emptySpace
		} else {
			result += continueItem
		}
	}

	indicator := middleItem
	if last {
		indicator = lastItem
	}

	return result + indicator + text + newLine
}

func (p *printer) printItems(t []Tree, spaces []bool) string {
	var result string
	for i, f := range t {
		last := i == len(t)-1
		result += p.printText(f.Text(), spaces, last)
		if len(f.Items()) > 0 {
			spacesChild := append(spaces, last)
			result += p.printItems(f.Items(), spacesChild)
		}
	}
	return result
}
<commit_msg>add export comments<commit_after>// Package gotree create and print tree.
package gotree

const (
	newLine      = "\n"
	emptySpace   = "    "
	middleItem   = "├── "
	continueItem = "│   "
	lastItem     = "└── "
)

type (
	tree struct {
		text  string
		items []Tree
	}

	// Tree is tree inteface
	Tree interface {
		Add(text string) Tree
		AddTree(tree Tree)
		Items() []Tree
		Text() string
		Print() string
	}

	printer struct {
	}

	// Printer is printer interface
	Printer interface {
		Print(Tree) string
	}
)

// New returns a new GoTree.Tree
func New(text string) Tree {
	return &tree{
		text:  text,
		items: []Tree{},
	}
}

// Add node in tree
func (t *tree) Add(text string) Tree {
	n := New(text)
	t.items = append(t.items, n)
	return n
}

// AddTree is add tree in present tree
func (t *tree) AddTree(tree Tree) {
	t.items = append(t.items, tree)
}

// Text return text of root name
func (t *tree) Text() string {
	return t.text
}

// Items return slice of tree nodes
func (t *tree) Items() []Tree {
	return t.items
}

// Print return string of tree
func (t *tree) Print() string {
	return newPrinter().Print(t)
}

func newPrinter() Printer {
	return &printer{}
}

func (p *printer) Print(t Tree) string {
	return t.Text() + newLine + p.printItems(t.Items(), []bool{})
}

func (p *printer) printText(text string, spaces []bool, last bool) string {
	var result string
	for _, space := range spaces {
		if space {
			result += emptySpace
		} else {
			result += continueItem
		}
	}

	indicator := middleItem
	if last {
		indicator = lastItem
	}

	return result + indicator + text + newLine
}

func (p *printer) printItems(t []Tree, spaces []bool) string {
	var result string
	for i, f := range t {
		last := i == len(t)-1
		result += p.printText(f.Text(), spaces, last)
		if len(f.Items()) > 0 {
			spacesChild := append(spaces, last)
			result += p.printItems(f.Items(), spacesChild)
		}
	}
	return result
}
<|endoftext|>


<commit_before>package gounit

import (
	"fmt"
	"testing"
)

type T struct {
	delegate *testing.T
}

func wrapT(t *testing.T) *T {
	return &T{t}
}

func (c *T) Error(args ...interface{}) {
	c.delegate.Error(args)
}

func (c *T) Assert(ok bool) {
	if !ok {
		c.Error("assert fail")
	}
}

func (c *T) Assert2(ok bool, msg string) {
	if !ok {
		c.Error(msg)
	}
}

// Mimic JUnit's TestRule
type TestRule interface {
	Apply(t *testing.T, f func(t *T)) func(t *T)
}

// Mimic Junit's RuleChain
type _RuleChain struct {
	rules []TestRule
}

var testRuleChain *_RuleChain

func TestRuleChain(rule TestRule) *_RuleChain {
	testRuleChain = &_RuleChain{[]TestRule{rule}}
	return testRuleChain
}

func (rc *_RuleChain) Around(rule TestRule) *_RuleChain {
	rc.rules = append(rc.rules, rule)
	return rc
}

func (rc *_RuleChain) Apply(t *testing.T, f func(t *T)) func(t *T) {
	for _, rule := range rc.rules {
		f = rule.Apply(t, f)
	}
	return f
}

func Test(t *testing.T, f func(t *T)) {
	testRuleChain.Apply(t, f)(wrapT(t))
}

// Workaround Junit's TestRule for class
type ClassTestRule interface {
	Before() error
	After() error
}

type _ClassRuleChain struct {
	rules []ClassTestRule
}

var classRuleChain *_ClassRuleChain

func ClassRuleChain(rule ClassTestRule) *_ClassRuleChain {
	classRuleChain = &_ClassRuleChain{[]ClassTestRule{rule}}
	return classRuleChain
}

var classRuleChainErrors []error

func BeforeSuite(t *testing.T) {
	for _, rule := range classRuleChain.rules {
		classRuleChainErrors = append(classRuleChainErrors, rule.Before())
	}
}

var suiteClosers []func() error

// Registers a Closeable resource that shold be closed after the suite completes.
func CloseAfterSuite(closer func() error) {
	suiteClosers = append(suiteClosers, closer)
}

func AfterSuite(t *testing.T) {
	for i := len(classRuleChain.rules) - 1; i >= 0; i-- {
		classRuleChainErrors = append(classRuleChainErrors, classRuleChain.rules[i].After())
	}
	if len(classRuleChainErrors) > 0 {
		panic(fmt.Sprintf("Errors during afterSuite(): %v", classRuleChainErrors))
	}
	for _, closer := range suiteClosers {
		closer() // ignore error
	}
}
<commit_msg>fix empty test rule case<commit_after>package gounit

import (
	"fmt"
	"testing"
)

type T struct {
	delegate *testing.T
}

func wrapT(t *testing.T) *T {
	return &T{t}
}

func (c *T) Error(args ...interface{}) {
	c.delegate.Error(args)
}

func (c *T) Assert(ok bool) {
	if !ok {
		c.Error("assert fail")
	}
}

func (c *T) Assert2(ok bool, msg string) {
	if !ok {
		c.Error(msg)
	}
}

// Mimic JUnit's TestRule
type TestRule interface {
	Apply(t *testing.T, f func(t *T)) func(t *T)
}

// Mimic Junit's RuleChain
type _RuleChain struct {
	rules []TestRule
}

var testRuleChain *_RuleChain

func TestRuleChain(rule TestRule) *_RuleChain {
	testRuleChain = &_RuleChain{[]TestRule{rule}}
	return testRuleChain
}

func (rc *_RuleChain) Around(rule TestRule) *_RuleChain {
	rc.rules = append(rc.rules, rule)
	return rc
}

func (rc *_RuleChain) Apply(t *testing.T, f func(t *T)) func(t *T) {
	for _, rule := range rc.rules {
		f = rule.Apply(t, f)
	}
	return f
}

func Test(t *testing.T, f func(t *T)) {
	if testRuleChain == nil {
		f(wrapT(t))
	} else {
		testRuleChain.Apply(t, f)(wrapT(t))
	}
}

// Workaround Junit's TestRule for class
type ClassTestRule interface {
	Before() error
	After() error
}

type _ClassRuleChain struct {
	rules []ClassTestRule
}

var classRuleChain *_ClassRuleChain

func ClassRuleChain(rule ClassTestRule) *_ClassRuleChain {
	if rule == nil {
		panic("initial rule cannot be nil")
	}
	classRuleChain = &_ClassRuleChain{[]ClassTestRule{rule}}
	return classRuleChain
}

var classRuleChainErrors []error

func BeforeSuite(t *testing.T) {
	for _, rule := range classRuleChain.rules {
		classRuleChainErrors = append(classRuleChainErrors, rule.Before())
	}
}

var suiteClosers []func() error

// Registers a Closeable resource that shold be closed after the suite completes.
func CloseAfterSuite(closer func() error) {
	suiteClosers = append(suiteClosers, closer)
}

func AfterSuite(t *testing.T) {
	for i := len(classRuleChain.rules) - 1; i >= 0; i-- {
		classRuleChainErrors = append(classRuleChainErrors, classRuleChain.rules[i].After())
	}
	if len(classRuleChainErrors) > 0 {
		panic(fmt.Sprintf("Errors during afterSuite(): %v", classRuleChainErrors))
	}
	for _, closer := range suiteClosers {
		closer() // ignore error
	}
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"sync"
	"github.com/BurntSushi/toml"
	"fmt"
	"net"
)

type Config struct {
	ClientSendInterval int
	MaxMetrics int
	GraphiteAddr string // Think about multiple servers
	LocalBind string
	Log string
	MetricDir string
	RetryFile string
	SumPrefix string
	SumInterval int
	GrafsyPrefix string
	GrafsySuffix string
	AllowedMetrics string
}

const monitorMetrics  = 6
func main() {
	var conf Config
	if _, err := toml.DecodeFile("/etc/grafsy/grafsy.toml", &conf); err != nil {
		fmt.Println("Failed to parse config file", err.Error())
	}

	var wg sync.WaitGroup

	f, err := os.OpenFile(conf.Log, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0660)
	if err != nil {
		log.Println("Can not open file "+ conf.Log, err.Error())
		os.Exit(1)
	}
	lg := log.New(f, "", log.Ldate|log.Lmicroseconds|log.Lshortfile)

	graphiteAdrrTCP, err := net.ResolveTCPAddr("tcp", conf.GraphiteAddr)
	if err != nil {
		lg.Println("This is not a valid address:", err.Error())
		os.Exit(1)
	}

	/*
		This is a main buffer
		It does not make any sense to have it too big cause metrics will be dropped during saving to file
		This buffer is ready to take maxMetric*sumInterval. Which gives you the rule, than bigger interval you have or
		amount of metric in interval, than more metric it can take in memory.
	 */
	var ch chan string = make(chan string, conf.MaxMetrics*conf.ClientSendInterval + monitorMetrics)
	/*
		This is a sum buffer. I assume it make total sense to have maximum buf = maxMetric*sumInterval.
		For example up to 10000 sums per second
	*/
	var chS chan string = make(chan string, conf.MaxMetrics*conf.SumInterval + monitorMetrics)

	/*
		Monitoring channel. Must be independent. Limited by maximum amount of monitoring metrics (6 for now)
	 */
	var chM chan string = make(chan string, monitorMetrics)

	mon := &Monitoring{
		conf, Source{},
		0,
		0,
		0,
		chM}

	cli := Client{
		conf,
		mon,
		*graphiteAdrrTCP,
		*lg,
		ch,
		chM}
	srv := Server{
		conf,
		mon,
		*lg,
		ch,
		chS}

	go srv.runServer()
	go cli.runClient()
	go mon.runMonitoring()

	wg.Add(1)
	wg.Wait()
}<commit_msg>Made check for suffix and prefix to not run monitoring routine if it is not needed.<commit_after>package main

import (
	"log"
	"os"
	"sync"
	"github.com/BurntSushi/toml"
	"fmt"
	"net"
)

type Config struct {
	ClientSendInterval int
	MaxMetrics int
	GraphiteAddr string // Think about multiple servers
	LocalBind string
	Log string
	MetricDir string
	RetryFile string
	SumPrefix string
	SumInterval int
	GrafsyPrefix string
	GrafsySuffix string
	AllowedMetrics string
}

const monitorMetrics  = 6
func main() {
	var conf Config
	if _, err := toml.DecodeFile("/etc/grafsy/grafsy.toml", &conf); err != nil {
		fmt.Println("Failed to parse config file", err.Error())
	}

	var wg sync.WaitGroup

	f, err := os.OpenFile(conf.Log, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0660)
	if err != nil {
		log.Println("Can not open file "+ conf.Log, err.Error())
		os.Exit(1)
	}
	lg := log.New(f, "", log.Ldate|log.Lmicroseconds|log.Lshortfile)

	graphiteAdrrTCP, err := net.ResolveTCPAddr("tcp", conf.GraphiteAddr)
	if err != nil {
		lg.Println("This is not a valid address:", err.Error())
		os.Exit(1)
	}

	/*
		This is a main buffer
		It does not make any sense to have it too big cause metrics will be dropped during saving to file
		This buffer is ready to take maxMetric*sumInterval. Which gives you the rule, than bigger interval you have or
		amount of metric in interval, than more metric it can take in memory.
	 */
	var ch chan string = make(chan string, conf.MaxMetrics*conf.ClientSendInterval + monitorMetrics)
	/*
		This is a sum buffer. I assume it make total sense to have maximum buf = maxMetric*sumInterval.
		For example up to 10000 sums per second
	*/
	var chS chan string = make(chan string, conf.MaxMetrics*conf.SumInterval + monitorMetrics)

	/*
		Monitoring channel. Must be independent. Limited by maximum amount of monitoring metrics (6 for now)
	 */
	var chM chan string = make(chan string, monitorMetrics)

	mon := &Monitoring{
		conf, Source{},
		0,
		0,
		0,
		chM}

	cli := Client{
		conf,
		mon,
		*graphiteAdrrTCP,
		*lg,
		ch,
		chM}
	srv := Server{
		conf,
		mon,
		*lg,
		ch,
		chS}

	go srv.runServer()
	go cli.runClient()
	if conf.GrafsyPrefix == "null" || conf.GrafsySuffix == "null" {
		go mon.runMonitoring()
	}

	wg.Add(1)
	wg.Wait()
}<|endoftext|>


<commit_before>package test

import (
	"github.com/stephenalexbrowne/zoom"
)

// File contains support code for tests.
// e.g. type declarations, constructors,
// and other methods.

// The Person struct
type Person struct {
	Name string
	Age  int
	*zoom.Model
}

// A convenient constructor for the Person struct
func NewPerson(name string, age int) *Person {
	p := &Person{
		Name:  name,
		Age:   age,
		Model: new(zoom.Model),
	}
	return p
}

// The Pet struct
type Pet struct {
	Name string
	Kind string
	*zoom.Model
}

// A convenient constructor for the Pet struct
func NewPet(name, kind string) *Pet {
	p := &Pet{
		Name:  name,
		Kind:  kind,
		Model: new(zoom.Model),
	}
	return p
}

// The AllTypes struct
// A struct containing all supported types
type AllTypes struct {
	Uint    uint
	Uint8   uint8
	Uint16  uint16
	Uint32  uint32
	Uint64  uint64
	Int     int
	Int8    int8
	Int16   int16
	Int32   int32
	Int64   int64
	Float32 float32
	Float64 float64
	Byte    byte
	Rune    rune
	String  string
	*zoom.Model
}

// Database helper functions
// setUp() and tearDown()
func setUp() error {
	zoom.Init(&zoom.Configuration{Database: 9})

	conn := zoom.GetConn()
	defer conn.Close()

	n, err := redis.Int(conn.Do("DBSIZE"))
	if err != nil {
		return err
	}

	if n != 0 {
		return errors.New("Database #9 is not empty, test can not continue")
	}

	zoom.Register(&Person{}, "person")
	return nil
}

func tearDown() {
	conn := zoom.GetConn()
	_, err := conn.Do("flushdb")
	if err != nil {
		log.Fatal(err)
	}
	conn.Close()
	zoom.Close()
}
<commit_msg>Fix bug in test_support. Didnt need those functions<commit_after>package test

import (
	"github.com/stephenalexbrowne/zoom"
)

// File contains support code for tests.
// e.g. type declarations, constructors,
// and other methods.

// The Person struct
type Person struct {
	Name string
	Age  int
	*zoom.Model
}

// A convenient constructor for the Person struct
func NewPerson(name string, age int) *Person {
	p := &Person{
		Name:  name,
		Age:   age,
		Model: new(zoom.Model),
	}
	return p
}

// The Pet struct
type Pet struct {
	Name string
	Kind string
	*zoom.Model
}

// A convenient constructor for the Pet struct
func NewPet(name, kind string) *Pet {
	p := &Pet{
		Name:  name,
		Kind:  kind,
		Model: new(zoom.Model),
	}
	return p
}

// The AllTypes struct
// A struct containing all supported types
type AllTypes struct {
	Uint    uint
	Uint8   uint8
	Uint16  uint16
	Uint32  uint32
	Uint64  uint64
	Int     int
	Int8    int8
	Int16   int16
	Int32   int32
	Int64   int64
	Float32 float32
	Float64 float64
	Byte    byte
	Rune    rune
	String  string
	*zoom.Model
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"sort"
	"strconv"
	"strings"

	flag "github.com/spf13/pflag"
)

var (
	fieldDelim  = flag.StringP("field-delim", "F", "", "field delimeter for tabular input (default whitespace)")
	colSelector = flag.StringP("cols", "c", "", "columns to un-flatten (1-based indexing)")
	targetCol   = flag.IntP("target", "t", 0, "target data column (1-based indexing)")
	noHead      = flag.BoolP("no-header", "H", false, "data has header row")
)

const desc = `
unflat can be used to convert data of the form key1,key2,key3,kind,val into a
format like key1,key2,key3,kind1val,kind2val,kind3val (assuming that 3 kinds
exist).

To do this, run unflat -F, -c 4 -t 5.

To select multiple columns, separate the values by commas. You can select
ranges using -. For example, 3-4,6 would select columns 3, 4, and 6.`

func parseSelector(s string) (indiv []int, err error) {
	defer func() {
		if e := recover(); e != nil {
			if ee, ok := e.(error); ok {
				err = ee
			} else {
				panic(e)
			}
		}
	}()

	groups := strings.Split(s, ",")
	for _, g := range groups {
		fs := strings.Split(g, "-")
		if len(fs) == 1 {
			indiv = append(indiv, indSingle(fs[0]))
		} else if len(fs) == 2 {
			indiv = append(indiv, indRange(fs[0], fs[1])...)
		} else {
			panic(fmt.Errorf("too many fields in range: %s", g))
		}
	}

	indiv = indMulti(indiv)
	return
}

func indSingle(s string) int {
	v, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	if v < 1 {
		panic(errors.New("bad column index"))
	}
	return v - 1
}

func indRange(start, end string) []int {
	vs, err := strconv.Atoi(start)
	if err != nil {
		panic(err)
	}
	if vs < 1 {
		panic(errors.New("bad column start"))
	}
	ve, err := strconv.Atoi(end)
	if err != nil {
		panic(err)
	}
	if ve < 1 {
		panic(errors.New("bad column end"))
	}
	var inds []int
	for i := vs - 1; i < ve; i++ {
		inds = append(inds, i)
	}
	return inds
}

func indMulti(inds []int) []int {
	sort.Ints(inds)
	prev := -1
	for i := 0; i < len(inds); {
		if inds[i] == prev {
			inds = append(inds[:i], inds[i+1:]...)
		} else {
			prev = inds[i]
			i++
		}
	}

	return inds
}

func usage() {
	fmt.Fprintln(os.Stderr, "usage: unflat -c COL_SELECTOR -t TARGET_COL")
	flag.PrintDefaults()
	fmt.Fprintln(os.Stderr, desc)
	os.Exit(2)
}

func main() {
	log.SetPrefix("unflat: ")
	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	if *colSelector == "" || *targetCol <= 0 {
		usage()
	}

	colSel, err := parseSelector(*colSelector)
	if err != nil {
		log.Fatal(err)
	}

	res, err := slurp(os.Stdin, !*noHead, *fieldDelim, colSel, *targetCol-1)
	if err != nil {
		log.Fatal(err)
	}

	print(os.Stderr, res, colSel, *targetCol-1, *fieldDelim)
}

func print(w io.Writer, res slurpResult, colSet []int, targetCol int, delim string) error {
	if delim == "" {
		delim = "\t"
	}

	var buf bytes.Buffer
	for i, h := range res.Header {
		if i == targetCol || contains(colSet, i) {
			continue
		}
		buf.WriteString(h)
		buf.WriteString(delim)
	}
	for _, k := range res.KindOrder {
		buf.WriteString(k)
		buf.WriteString(delim)
	}
	if _, err := w.Write(bufDone(&buf, len(delim))); err != nil {
		return err
	}

	for _, static := range res.StaticOrder {
		buf.Reset()
		buf.WriteString(static)

		for _, kind := range res.KindOrder {
			buf.WriteString(delim)
			buf.WriteString(res.Vals[staticKind{static, kind}])
		}
		buf.WriteString("\n")

		if _, err := w.Write(buf.Bytes()); err != nil {
			return err
		}
	}
	return nil
}

func bufDone(buf *bytes.Buffer, dlen int) []byte {
	b := buf.Bytes()
	b = b[:len(b)-dlen]
	return append(b, '\n')
}

type staticKind struct {
	Static string
	Kind   string
}

type slurpResult struct {
	Header      []string
	StaticOrder []string
	KindOrder   []string
	Vals        map[staticKind]string
}

func slurp(r io.Reader, hasHead bool, delim string, colSel []int, targetCol int) (slurpResult, error) {
	var (
		staticOrder StringSet
		kindOrder   StringSet
		header      []string
		vals        = make(map[staticKind]string)

		first = true

		// reused every iteration
		static []string
		kind   []string
	)

	writeDelim := delim
	if writeDelim == "" {
		writeDelim = "\t"
	}

	s := bufio.NewScanner(os.Stdin)

	for s.Scan() {
		var fs []string
		if delim == "" {
			fs = strings.Fields(s.Text())
		} else {
			fs = strings.Split(s.Text(), delim)
		}
		if !first && len(header) != len(fs) {
			return slurpResult{}, fmt.Errorf("malformed data: varying number of cols: %d != %d", len(header), len(fs))
		}
		if first {
			first = false
			if hasHead {
				header = fs
				continue
			} else {
				header = make([]string, len(fs))
				for i := range header {
					header[i] = "Col." + strconv.Itoa(i)
				}
			}
		}

		var val maybeString
		static = static[:0]
		kind = kind[:0]

		for i, f := range fs {
			switch {
			case i == targetCol:
				val.Set(f)
			case contains(colSel, i):
				kind = append(kind, f)
			default:
				static = append(static, f)
			}
		}

		if len(colSel) != len(kind) {
			return slurpResult{}, errors.New("selected columns do not exist")
		}

		if !val.OK {
			return slurpResult{}, errors.New("target column does not exist")
		}

		staticKey := strings.Join(static, writeDelim)
		kindKey := strings.Join(kind, ".")

		staticOrder.Add(staticKey)
		kindOrder.Add(kindKey)

		sk := staticKind{staticKey, kindKey}
		if _, ok := vals[sk]; ok {
			return slurpResult{}, fmt.Errorf("duplicate value for %v", sk)
		}
		vals[sk] = val.Val
	}

	res := slurpResult{
		Header:      header,
		StaticOrder: staticOrder.Order(),
		KindOrder:   kindOrder.Order(),
		Vals:        vals,
	}

	return res, nil
}

type maybeString struct {
	Val string
	OK  bool
}

func (ms *maybeString) Set(s string) {
	ms.OK = true
	ms.Val = s
}

func contains(vs []int, v int) bool {
	for _, v2 := range vs {
		if v2 == v {
			return true
		}
	}
	return false
}

type StringSet struct {
	order []string
	has   map[string]bool
}

func (ss *StringSet) Add(s string) {
	if ss.has == nil {
		ss.has = make(map[string]bool)
	}
	if ss.has[s] {
		return
	}
	ss.has[s] = true
	ss.order = append(ss.order, s)
}

func (ss *StringSet) Order() []string {
	return ss.order
}
<commit_msg>unflat: write to stdout<commit_after>package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"sort"
	"strconv"
	"strings"

	flag "github.com/spf13/pflag"
)

var (
	fieldDelim  = flag.StringP("field-delim", "F", "", "field delimeter for tabular input (default whitespace)")
	colSelector = flag.StringP("cols", "c", "", "columns to un-flatten (1-based indexing)")
	targetCol   = flag.IntP("target", "t", 0, "target data column (1-based indexing)")
	noHead      = flag.BoolP("no-header", "H", false, "data has header row")
)

const desc = `
unflat can be used to convert data of the form key1,key2,key3,kind,val into a
format like key1,key2,key3,kind1val,kind2val,kind3val (assuming that 3 kinds
exist).

To do this, run unflat -F, -c 4 -t 5.

To select multiple columns, separate the values by commas. You can select
ranges using -. For example, 3-4,6 would select columns 3, 4, and 6.`

func parseSelector(s string) (indiv []int, err error) {
	defer func() {
		if e := recover(); e != nil {
			if ee, ok := e.(error); ok {
				err = ee
			} else {
				panic(e)
			}
		}
	}()

	groups := strings.Split(s, ",")
	for _, g := range groups {
		fs := strings.Split(g, "-")
		if len(fs) == 1 {
			indiv = append(indiv, indSingle(fs[0]))
		} else if len(fs) == 2 {
			indiv = append(indiv, indRange(fs[0], fs[1])...)
		} else {
			panic(fmt.Errorf("too many fields in range: %s", g))
		}
	}

	indiv = indMulti(indiv)
	return
}

func indSingle(s string) int {
	v, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	if v < 1 {
		panic(errors.New("bad column index"))
	}
	return v - 1
}

func indRange(start, end string) []int {
	vs, err := strconv.Atoi(start)
	if err != nil {
		panic(err)
	}
	if vs < 1 {
		panic(errors.New("bad column start"))
	}
	ve, err := strconv.Atoi(end)
	if err != nil {
		panic(err)
	}
	if ve < 1 {
		panic(errors.New("bad column end"))
	}
	var inds []int
	for i := vs - 1; i < ve; i++ {
		inds = append(inds, i)
	}
	return inds
}

func indMulti(inds []int) []int {
	sort.Ints(inds)
	prev := -1
	for i := 0; i < len(inds); {
		if inds[i] == prev {
			inds = append(inds[:i], inds[i+1:]...)
		} else {
			prev = inds[i]
			i++
		}
	}

	return inds
}

func usage() {
	fmt.Fprintln(os.Stderr, "usage: unflat -c COL_SELECTOR -t TARGET_COL")
	flag.PrintDefaults()
	fmt.Fprintln(os.Stderr, desc)
	os.Exit(2)
}

func main() {
	log.SetPrefix("unflat: ")
	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	if *colSelector == "" || *targetCol <= 0 {
		usage()
	}

	colSel, err := parseSelector(*colSelector)
	if err != nil {
		log.Fatal(err)
	}

	res, err := slurp(os.Stdin, !*noHead, *fieldDelim, colSel, *targetCol-1)
	if err != nil {
		log.Fatal(err)
	}

	print(os.Stdout, res, colSel, *targetCol-1, *fieldDelim)
}

func print(w io.Writer, res slurpResult, colSet []int, targetCol int, delim string) error {
	if delim == "" {
		delim = "\t"
	}

	var buf bytes.Buffer
	for i, h := range res.Header {
		if i == targetCol || contains(colSet, i) {
			continue
		}
		buf.WriteString(h)
		buf.WriteString(delim)
	}
	for _, k := range res.KindOrder {
		buf.WriteString(k)
		buf.WriteString(delim)
	}
	if _, err := w.Write(bufDone(&buf, len(delim))); err != nil {
		return err
	}

	for _, static := range res.StaticOrder {
		buf.Reset()
		buf.WriteString(static)

		for _, kind := range res.KindOrder {
			buf.WriteString(delim)
			buf.WriteString(res.Vals[staticKind{static, kind}])
		}
		buf.WriteString("\n")

		if _, err := w.Write(buf.Bytes()); err != nil {
			return err
		}
	}
	return nil
}

func bufDone(buf *bytes.Buffer, dlen int) []byte {
	b := buf.Bytes()
	b = b[:len(b)-dlen]
	return append(b, '\n')
}

type staticKind struct {
	Static string
	Kind   string
}

type slurpResult struct {
	Header      []string
	StaticOrder []string
	KindOrder   []string
	Vals        map[staticKind]string
}

func slurp(r io.Reader, hasHead bool, delim string, colSel []int, targetCol int) (slurpResult, error) {
	var (
		staticOrder StringSet
		kindOrder   StringSet
		header      []string
		vals        = make(map[staticKind]string)

		first = true

		// reused every iteration
		static []string
		kind   []string
	)

	writeDelim := delim
	if writeDelim == "" {
		writeDelim = "\t"
	}

	s := bufio.NewScanner(os.Stdin)

	for s.Scan() {
		var fs []string
		if delim == "" {
			fs = strings.Fields(s.Text())
		} else {
			fs = strings.Split(s.Text(), delim)
		}
		if !first && len(header) != len(fs) {
			return slurpResult{}, fmt.Errorf("malformed data: varying number of cols: %d != %d", len(header), len(fs))
		}
		if first {
			first = false
			if hasHead {
				header = fs
				continue
			} else {
				header = make([]string, len(fs))
				for i := range header {
					header[i] = "Col." + strconv.Itoa(i)
				}
			}
		}

		var val maybeString
		static = static[:0]
		kind = kind[:0]

		for i, f := range fs {
			switch {
			case i == targetCol:
				val.Set(f)
			case contains(colSel, i):
				kind = append(kind, f)
			default:
				static = append(static, f)
			}
		}

		if len(colSel) != len(kind) {
			return slurpResult{}, errors.New("selected columns do not exist")
		}

		if !val.OK {
			return slurpResult{}, errors.New("target column does not exist")
		}

		staticKey := strings.Join(static, writeDelim)
		kindKey := strings.Join(kind, ".")

		staticOrder.Add(staticKey)
		kindOrder.Add(kindKey)

		sk := staticKind{staticKey, kindKey}
		if _, ok := vals[sk]; ok {
			return slurpResult{}, fmt.Errorf("duplicate value for %v", sk)
		}
		vals[sk] = val.Val
	}

	res := slurpResult{
		Header:      header,
		StaticOrder: staticOrder.Order(),
		KindOrder:   kindOrder.Order(),
		Vals:        vals,
	}

	return res, nil
}

type maybeString struct {
	Val string
	OK  bool
}

func (ms *maybeString) Set(s string) {
	ms.OK = true
	ms.Val = s
}

func contains(vs []int, v int) bool {
	for _, v2 := range vs {
		if v2 == v {
			return true
		}
	}
	return false
}

type StringSet struct {
	order []string
	has   map[string]bool
}

func (ss *StringSet) Add(s string) {
	if ss.has == nil {
		ss.has = make(map[string]bool)
	}
	if ss.has[s] {
		return
	}
	ss.has[s] = true
	ss.order = append(ss.order, s)
}

func (ss *StringSet) Order() []string {
	return ss.order
}
<|endoftext|>


<commit_before>package rpc

import (
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/miner"
)

type Agent struct {
	work        *types.Block
	currentWork *types.Block

	quit     chan struct{}
	workCh   chan *types.Block
	returnCh chan<- miner.Work
}

func NewAgent() *Agent {
	agent := &Agent{}
	go agent.run()

	return agent
}

func (a *Agent) Work() chan<- *types.Block {
	return a.workCh
}

func (a *Agent) SetWorkCh(returnCh chan<- miner.Work) {
	a.returnCh = returnCh
}

func (a *Agent) Start() {
	a.quit = make(chan struct{})
	a.workCh = make(chan *types.Block, 1)
}

func (a *Agent) Stop() {
	close(a.quit)
	close(a.workCh)
}

func (a *Agent) GetHashRate() int64 { return 0 }

func (a *Agent) run() {
out:
	for {
		select {
		case <-a.quit:
			break out
		case work := <-a.workCh:
			a.work = work
		}
	}
}

func (a *Agent) GetWork() [3]string {
	// TODO return HashNoNonce, DAGSeedHash, Difficulty
	var res [3]string

	// XXX Wait here untill work != nil ?.
	if a.work != nil {
		res[0] = a.work.HashNoNonce().Hex() // Header Hash No Nonce
		res[1] = common.Hash{}.Hex()        // DAG Seed
		res[2] = common.Hash{}.Hex()        // Difficulty
	}

	return res
}

func (a *Agent) SetResult(nonce uint64, mixDigest, seedHash common.Hash) bool {
	// Return true or false, but does not indicate if the PoW was correct

	// Make sure the external miner was working on the right hash
	if a.currentWork != nil && a.work != nil && a.currentWork.Hash() == a.work.Hash() {
		a.returnCh <- miner.Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()}
		return true
	}

	return false
}
<commit_msg>go away!<commit_after><|endoftext|>


<commit_before>package lidar

import (
	"errors"
	"log"
	"time"

	"github.com/dasfoo/i2c"
)

// TODO: ADD Mutex
// TODO Check grammar

// Lidar is structure to access basic functions of LidarLite
// LidarLite_V2 blue label
// Model LL-905-PIN-02
// Documentation on http://lidarlite.com/docs/v2/specs_and_hardware
type Lidar struct {
	bus            *i2c.Bus
	address        byte
	continuousMode bool
}

// MaxAttemptNumber - maximum number of attempts to do operation
const MaxAttemptNumber = 50

const (
	// NotReady - Ready status. 0 - ready for a new command, 1 - busy
	// with acquisition.
	NotReady = 1 << iota

	// RefOverflow - Overflow detected in correlation process assotieted with
	// a reference acquisition. Signal overflow flag and Reference overflow flag
	// are set when automatic limiting occurs.
	RefOverflow = 1 << iota

	// SignalOverflow - Overflow detected in correlation process assotieted with a signal
	// acquisition
	SignalOverflow = 1 << iota

	// SignalNotValid - Indicates that the signal correlation peak is equal to or below
	// correlation record threshold
	SignalNotValid = 1 << iota

	// SecondaryReturn - Secondary return detected above correlation noise floor threshold
	SecondaryReturn = 1 << iota

	// Health - 1 if is good, 0 if is bad
	Health = 1 << iota

	// ErrorDetection - Process error detected/measurement invalid
	ErrorDetection = 1 << iota

	// EyeSafe - This bit will go high if eye-safety protection has been activated
	EyeSafe = 1 << iota
)

// NewLidar sets the configuration for the sensor and return all registers in
// default values before using
func NewLidar(i2cbus, addr byte) *Lidar {
	bus, err := i2c.NewBus(i2cbus) // TODO: check error
	if err != nil {
		log.Panic(err)
	}
	lSensor := Lidar{
		bus:            bus,
		address:        addr,
		continuousMode: false,
	}
	lSensor.Reset()
	log.Println("Initialization is done")
	return &lSensor
}

// Reset writes 0x00 to Register 0x00 reset FPGA. Re-loads FPGA from internal Flash
// memory: all registers return to default values
// During initialization the microcontroller goes *throw* a self-test followed by
// initialization of the internal control registers with default values. After that
// processor goes into sleep state reducing overall power consumption to under
// 10 mA. Initiation of a user command, throw external trigger or I2C command,
// awakes a processor allowing subsequent opetation.
func (ls *Lidar) Reset() {
	if e := ls.bus.WriteByteToReg(ls.address, 0x00, 0x00); e != nil {
		log.Panic("Write ", e)
	}
	time.Sleep(1 * time.Second) // TODO: remove if it is possible
}

// Read reads from the register and the same time check status of controller.
// If Status is bad or error was detectec, it tries again
func (ls *Lidar) Read(register byte) (byte, error) {
	for i := 0; i < MaxAttemptNumber; i++ {
		st, errSt := ls.GetStatus()
		switch {
		case errSt != nil:
			log.Println(errSt)
		case st&Health == 0:
			log.Println("Bad Health of controller")
			val, rErr := ls.bus.ReadByteFromReg(ls.address, register)
			if rErr == nil {
				return val, nil
			}
		case st&ErrorDetection != 0:
			log.Println("Error detected")
		case st&SignalOverflow == 0:
			log.Println("Automatic limiting doesn't occurs ")
		default:
			val, rErr := ls.bus.ReadByteFromReg(ls.address, register)
			if rErr == nil {
				return val, nil
			}
		}
		//if ask Status often, Health status is bad
		time.Sleep(1 * time.Second)
	}
	return 0, errors.New("Read limit occurs")
}

// WriteByteToRegister - write value(byte) to register(reg)
// Read register 0x01(this is handled in the GetStatus() command)
// TODO remove words
//  - if the first bit is "1"(it checks in NotReady) then sensor is busy, loop
//    until the first bit is 0 or i = MaxAttemptNumber
//  - if the first bit is "0"(it checks in NotReady) then the sensor is ready
//    for a new command
func (ls *Lidar) WriteByteToRegister(register, value byte) error {
	for i := 0; i < MaxAttemptNumber; i++ {
		st, errSt := ls.GetStatus()
		switch {
		case errSt != nil:
			log.Println(errSt)
		case st&NotReady != 0:
			log.Println("Not ready to start new command")
		default:
			return ls.bus.WriteByteToReg(ls.address, register, value)
		}
		time.Sleep(1 * time.Second)
	}
	return errors.New("Write limit occurs")
}

// Close closes releases the resources associated with the bus
func (ls *Lidar) Close() {
	// Reset FPGA. All registers return to default values
	ls.Reset()
	if err := ls.bus.Close(); err != nil {
		log.Println(err)
	}
	log.Println("Closing sensor is done")
}

// GetStatus gets Mode/Status of sensor
func (ls *Lidar) GetStatus() (byte, error) {
	val, err := ls.bus.ReadByteFromReg(ls.address, 0x01)
	if err != nil {
		log.Println("GetStatus", err)
		return 0, err
	}
	log.Printf("Status: %.8b\n", val)
	return val, nil
}

// Distance reads the distance from LidarLite
// stablizePreampFlag - true - take aquisition with DC stabilisation/correction.
// false - it will read faster, but you will need to stabilize DC every once in
// awhile(ex. 1 out of every 100 readings is typically good)
// Autoincrement: A note about 0x8f vs 0x0f
// Set the highest bit of any register to "1" if you set the high byte of a
// register and then take succesive readings from that register, then LIDAR-
// Lite automatically increments the register one for each read. An example: If
// we want to read the high and low bytes for the distance, we could take two
// single readings from 0x0f and 0x10, or we could take 2 byte read from reg-
// ister 0x8f. 0x8f = 10001111 and 0x0f = 00001111, meaning that 0x8f is 0x0f
// with the high byte set to "1", ergo it autoincrements.
func (ls *Lidar) Distance(stablizePreampFlag bool) (int, error) {
	if ls.continuousMode { //TODO if not distance continuous, 1 return
		log.Println("stablizePreampFlag doesn't work. It is continuous mode")
		return ls.distanceContinuous()
	}

	var wErr error // Write error

	if stablizePreampFlag {
		wErr = ls.WriteByteToRegister(0x00, 0x04)
	} else {
		wErr = ls.WriteByteToRegister(0x00, 0x03)
	}
	if wErr != nil {
		log.Println("Write ", wErr)
		return -1, wErr
	}

	// The total acquisition time for the reference and signal acquisition is
	// typically between 5 and 20 ms depending on the desired number of integrated
	// pulses and the length of the correlation record. The acquisition time
	// plus the required 1 msec to download measurement parameters establish a
	// a roughly 100Hz maximum measurement rate.
	time.Sleep(250 * time.Millisecond)

	return ls.distanceContinuous()
}

// Velocity is measured by observing the change in distance over a fixed time
// of period
// It reads in 0.1 meters/sec. See Mode Control, Register 0x04 for information
// on changing the scale factor to 1m/sec
// TODO 0x04 Check Mode Control
func (ls *Lidar) Velocity() (int, error) {
	// Write 0xa0 to 0x04 to switch on velocity mode
	// Before changing mode we need to check status
	log.Println("Starting velocity mode") //
	if wErr := ls.WriteByteToRegister(0x04, 0xa0); wErr != nil {
		log.Println("Write ", wErr)
		return -1, wErr
	}

	// Write 0x04 to register 0x00 to start getting distance readings
	if wErr := ls.bus.WriteByteToReg(ls.address, 0x00, 0x04); wErr != nil {
		log.Println("Write ", wErr)
		return -1, wErr
	}
	log.Println("Velocity  reading....")

	//Read 1 byte from register 0x09 to get velocity measurement
	val, e := ls.Read(0x09)
	if e != nil {
		log.Println(e)
		return -1, e
	}
	return int(val), nil
}

// BeginContinuous allows to tell the sensor to take a certain number of (or
// infinite) readings allowing you to read from it at a continuous rate.
// - modePinLow - tells the mode pin to go low when a new reading is available. TODO:Test it.
// - interval - set the time between measurements, default is 0x04. TODO Add time.Duration
//   0xc8 corresponds to 10Hz while 0x13 corresponds to 100Hz. Maximum
//   value is 0x02 for proper operations
// - numberOfReadings - set the number of readings to take before stopping TODO mere ditails
func (ls *Lidar) BeginContinuous(modePinLow bool, interval, numberOfReadings byte) error {
	// Register 0x45 sets the time between measurements. Min val os 0x02
	// for proper operations.
	if wErr := ls.bus.WriteByteToReg(ls.address, 0x45, interval); wErr != nil {
		log.Println(wErr)
		return wErr
	}

	if modePinLow {
		if wErr := ls.bus.WriteByteToReg(ls.address, 0x04, 0x21); wErr != nil {
			log.Print(wErr) // TODO remove duplicate
			return wErr
		}

	} else {
		// Set register 0x04 to 0x20 to look at "NON-default" value of velocity
		if wErr := ls.bus.WriteByteToReg(ls.address, 0x04, 0x20); wErr != nil {
			log.Print(wErr)
			return wErr
		}
	}
	// Set the number of readings, 0xfe = 254 readings, 0x01 = 1 reading and
	// 0xff = continuous readings
	if wErr := ls.bus.WriteByteToReg(ls.address, 0x11, numberOfReadings); wErr != nil {
		log.Println(wErr)
		return wErr
	}

	// Initiate reading distance
	if wErr := ls.bus.WriteByteToReg(ls.address, 0x00, 0x04); wErr != nil {
		log.Println(wErr)
		return wErr
	}

	log.Println("Continuous mode has started...")
	ls.continuousMode = true
	time.Sleep(1 * time.Second) // Time is to do acquisition before reading
	return nil
}

// StopContinuous stops continuous mode and sensor is ready to get new command,
// for ex. distance of velocity mode. This method returns to default values.
func (ls *Lidar) StopContinuous() {
	ls.Reset()
	ls.continuousMode = false
	log.Println("Continuous mode has stopped")
}

// TODO rename function
// distanceContinuous reads in continuous mode
func (ls *Lidar) distanceContinuous() (int, error) {

	status, err := ls.GetStatus()
	switch {
	case err != nil:
		log.Println(err)
		return -1, err
	case status&Health == 0:
		val, rErr := ls.bus.ReadWordFromReg(ls.address, 0x8f)
		log.Println("Bad health of sensor")
		if rErr != nil {
			log.Println("Read", rErr)
			return -1, rErr
		}
		return int(val), nil
	case status&ErrorDetection != 0:
		return -1, errors.New("Error in counting detected")
	case status&SignalOverflow == 0:
		return -1, errors.New("Automatic limiting doesn't occurs")
	default:
		val, rErr := ls.bus.ReadWordFromReg(ls.address, 0x8f)
		if rErr != nil {
			log.Println("Read", rErr)
			return -1, rErr
		}
		return int(val), nil
	}
}
<commit_msg>Rewrite comments for WriteByteToRegister method<commit_after>package lidar

import (
	"errors"
	"log"
	"time"

	"github.com/dasfoo/i2c"
)

// TODO: ADD Mutex
// TODO Check grammar

// Lidar is structure to access basic functions of LidarLite
// LidarLite_V2 blue label
// Model LL-905-PIN-02
// Documentation on http://lidarlite.com/docs/v2/specs_and_hardware
type Lidar struct {
	bus            *i2c.Bus
	address        byte
	continuousMode bool
}

// MaxAttemptNumber - maximum number of attempts to do operation
const MaxAttemptNumber = 50

const (
	// NotReady - Ready status. 0 - ready for a new command, 1 - busy
	// with acquisition.
	NotReady = 1 << iota

	// RefOverflow - Overflow detected in correlation process assotieted with
	// a reference acquisition. Signal overflow flag and Reference overflow flag
	// are set when automatic limiting occurs.
	RefOverflow = 1 << iota

	// SignalOverflow - Overflow detected in correlation process assotieted with a signal
	// acquisition
	SignalOverflow = 1 << iota

	// SignalNotValid - Indicates that the signal correlation peak is equal to or below
	// correlation record threshold
	SignalNotValid = 1 << iota

	// SecondaryReturn - Secondary return detected above correlation noise floor threshold
	SecondaryReturn = 1 << iota

	// Health - 1 if is good, 0 if is bad
	Health = 1 << iota

	// ErrorDetection - Process error detected/measurement invalid
	ErrorDetection = 1 << iota

	// EyeSafe - This bit will go high if eye-safety protection has been activated
	EyeSafe = 1 << iota
)

// NewLidar sets the configuration for the sensor and return all registers in
// default values before using
func NewLidar(i2cbus, addr byte) *Lidar {
	bus, err := i2c.NewBus(i2cbus)
	if err != nil {
		log.Panic(err)
	}
	lSensor := Lidar{
		bus:            bus,
		address:        addr,
		continuousMode: false,
	}
	lSensor.Reset()
	log.Println("Initialization is done")
	return &lSensor
}

// Reset writes 0x00 to Register 0x00 reset FPGA. Re-loads FPGA from internal Flash
// memory: all registers return to default values
// During initialization the microcontroller goes *throw* a self-test followed by
// initialization of the internal control registers with default values. After that
// processor goes into sleep state reducing overall power consumption to under
// 10 mA. Initiation of a user command, throw external trigger or I2C command,
// awakes a processor allowing subsequent opetation.
func (ls *Lidar) Reset() {
	if e := ls.bus.WriteByteToReg(ls.address, 0x00, 0x00); e != nil {
		log.Panic("Write ", e)
	}
	time.Sleep(1 * time.Second) // TODO: remove if it is possible
}

// Read reads from the register and the same time check status of controller.
// If Status is bad or error was detectec, it tries again
func (ls *Lidar) Read(register byte) (byte, error) {
	for i := 0; i < MaxAttemptNumber; i++ {
		st, errSt := ls.GetStatus()
		switch {
		case errSt != nil:
			log.Println(errSt)
		case st&Health == 0:
			log.Println("Bad Health of controller")
			val, rErr := ls.bus.ReadByteFromReg(ls.address, register)
			if rErr == nil {
				return val, nil
			}
		case st&ErrorDetection != 0:
			log.Println("Error detected")
		case st&SignalOverflow == 0:
			log.Println("Automatic limiting doesn't occurs ")
		default:
			val, rErr := ls.bus.ReadByteFromReg(ls.address, register)
			if rErr == nil {
				return val, nil
			}
		}
		//if ask Status often, Health status is bad
		time.Sleep(1 * time.Second)
	}
	return 0, errors.New("Read limit occurs")
}

// WriteByteToRegister - write value(byte) to register
// Read register 0x01(this is handled in the GetStatus() command)
// if sensor is NotReady for new command, loop tries again until MaxAttemptNumber
// occurs or sensor is ready
func (ls *Lidar) WriteByteToRegister(register, value byte) error {
	for i := 0; i < MaxAttemptNumber; i++ {
		st, errSt := ls.GetStatus()
		switch {
		case errSt != nil:
			log.Println(errSt)
		case st&NotReady != 0:
			log.Println("Not ready to start new command")
		default:
			return ls.bus.WriteByteToReg(ls.address, register, value)
		}
		time.Sleep(1 * time.Second)
	}
	return errors.New("Write limit occurs")
}

// Close closes releases the resources associated with the bus
func (ls *Lidar) Close() {
	// Reset FPGA. All registers return to default values
	ls.Reset()
	if err := ls.bus.Close(); err != nil {
		log.Println(err)
	}
	log.Println("Closing sensor is done")
}

// GetStatus gets Mode/Status of sensor
func (ls *Lidar) GetStatus() (byte, error) {
	val, err := ls.bus.ReadByteFromReg(ls.address, 0x01)
	if err != nil {
		log.Println("GetStatus", err)
		return 0, err
	}
	log.Printf("Status: %.8b\n", val)
	return val, nil
}

// Distance reads the distance from LidarLite
// stablizePreampFlag - true - take aquisition with DC stabilisation/correction.
// false - it will read faster, but you will need to stabilize DC every once in
// awhile(ex. 1 out of every 100 readings is typically good)
// Autoincrement: A note about 0x8f vs 0x0f
// Set the highest bit of any register to "1" if you set the high byte of a
// register and then take succesive readings from that register, then LIDAR-
// Lite automatically increments the register one for each read. An example: If
// we want to read the high and low bytes for the distance, we could take two
// single readings from 0x0f and 0x10, or we could take 2 byte read from reg-
// ister 0x8f. 0x8f = 10001111 and 0x0f = 00001111, meaning that 0x8f is 0x0f
// with the high byte set to "1", ergo it autoincrements.
func (ls *Lidar) Distance(stablizePreampFlag bool) (int, error) {
	if ls.continuousMode { //TODO if not distance continuous, 1 return
		log.Println("stablizePreampFlag doesn't work. It is continuous mode")
		return ls.distanceContinuous()
	}

	var wErr error // Write error

	if stablizePreampFlag {
		wErr = ls.WriteByteToRegister(0x00, 0x04)
	} else {
		wErr = ls.WriteByteToRegister(0x00, 0x03)
	}
	if wErr != nil {
		log.Println("Write ", wErr)
		return -1, wErr
	}

	// The total acquisition time for the reference and signal acquisition is
	// typically between 5 and 20 ms depending on the desired number of integrated
	// pulses and the length of the correlation record. The acquisition time
	// plus the required 1 msec to download measurement parameters establish a
	// a roughly 100Hz maximum measurement rate.
	time.Sleep(250 * time.Millisecond)

	return ls.distanceContinuous()
}

// Velocity is measured by observing the change in distance over a fixed time
// of period
// It reads in 0.1 meters/sec. See Mode Control, Register 0x04 for information
// on changing the scale factor to 1m/sec
// TODO 0x04 Check Mode Control
func (ls *Lidar) Velocity() (int, error) {
	// Write 0xa0 to 0x04 to switch on velocity mode
	// Before changing mode we need to check status
	log.Println("Starting velocity mode") //
	if wErr := ls.WriteByteToRegister(0x04, 0xa0); wErr != nil {
		log.Println("Write ", wErr)
		return -1, wErr
	}

	// Write 0x04 to register 0x00 to start getting distance readings
	if wErr := ls.bus.WriteByteToReg(ls.address, 0x00, 0x04); wErr != nil {
		log.Println("Write ", wErr)
		return -1, wErr
	}
	log.Println("Velocity  reading....")

	//Read 1 byte from register 0x09 to get velocity measurement
	val, e := ls.Read(0x09)
	if e != nil {
		log.Println(e)
		return -1, e
	}
	return int(val), nil
}

// BeginContinuous allows to tell the sensor to take a certain number of (or
// infinite) readings allowing you to read from it at a continuous rate.
// - modePinLow - tells the mode pin to go low when a new reading is available. TODO:Test it.
// - interval - set the time between measurements, default is 0x04. TODO Add time.Duration
//   0xc8 corresponds to 10Hz while 0x13 corresponds to 100Hz. Maximum
//   value is 0x02 for proper operations
// - numberOfReadings - set the number of readings to take before stopping TODO mere ditails
func (ls *Lidar) BeginContinuous(modePinLow bool, interval, numberOfReadings byte) error {
	// Register 0x45 sets the time between measurements. Min val os 0x02
	// for proper operations.
	if wErr := ls.bus.WriteByteToReg(ls.address, 0x45, interval); wErr != nil {
		log.Println(wErr)
		return wErr
	}

	if modePinLow {
		if wErr := ls.bus.WriteByteToReg(ls.address, 0x04, 0x21); wErr != nil {
			log.Print(wErr) // TODO remove duplicate
			return wErr
		}

	} else {
		// Set register 0x04 to 0x20 to look at "NON-default" value of velocity
		if wErr := ls.bus.WriteByteToReg(ls.address, 0x04, 0x20); wErr != nil {
			log.Print(wErr)
			return wErr
		}
	}
	// Set the number of readings, 0xfe = 254 readings, 0x01 = 1 reading and
	// 0xff = continuous readings
	if wErr := ls.bus.WriteByteToReg(ls.address, 0x11, numberOfReadings); wErr != nil {
		log.Println(wErr)
		return wErr
	}

	// Initiate reading distance
	if wErr := ls.bus.WriteByteToReg(ls.address, 0x00, 0x04); wErr != nil {
		log.Println(wErr)
		return wErr
	}

	log.Println("Continuous mode has started...")
	ls.continuousMode = true
	time.Sleep(1 * time.Second) // Time is to do acquisition before reading
	return nil
}

// StopContinuous stops continuous mode and sensor is ready to get new command,
// for ex. distance of velocity mode. This method returns to default values.
func (ls *Lidar) StopContinuous() {
	ls.Reset()
	ls.continuousMode = false
	log.Println("Continuous mode has stopped")
}

// TODO rename function
// distanceContinuous reads in continuous mode
func (ls *Lidar) distanceContinuous() (int, error) {

	status, err := ls.GetStatus()
	switch {
	case err != nil:
		log.Println(err)
		return -1, err
	case status&Health == 0:
		val, rErr := ls.bus.ReadWordFromReg(ls.address, 0x8f)
		log.Println("Bad health of sensor")
		if rErr != nil {
			log.Println("Read", rErr)
			return -1, rErr
		}
		return int(val), nil
	case status&ErrorDetection != 0:
		return -1, errors.New("Error in counting detected")
	case status&SignalOverflow == 0:
		return -1, errors.New("Automatic limiting doesn't occurs")
	default:
		val, rErr := ls.bus.ReadWordFromReg(ls.address, 0x8f)
		if rErr != nil {
			log.Println("Read", rErr)
			return -1, rErr
		}
		return int(val), nil
	}
}
<|endoftext|>


<commit_before>package utils

import (
	"io/ioutil"
	"math"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	log "github.com/sirupsen/logrus"
)

const (
	// Pathsep is the path separator for the current platform
	Pathsep = string(filepath.Separator)

	// EveryInstance can be used when replacing strings
	EveryInstance = -1

	// KiB is a kilobyte (kibibyte)
	KiB = 1024

	// MiB is a megabyte (mibibyte)
	MiB = 1024 * 1024
)

// URL2filename translates a given URL path to a probable full filename
func URL2filename(dirname, urlpath string) string {
	if strings.Contains(urlpath, "..") {
		log.Warn("Someone was trying to access a directory with .. in the URL")
		return dirname + Pathsep
	}
	if strings.HasPrefix(urlpath, "/") {
		if strings.HasSuffix(dirname, Pathsep) {
			return dirname + urlpath[1:]
		}
		return dirname + Pathsep + urlpath[1:]
	}
	return dirname + "/" + urlpath
}

// GetFilenames retrieves a list of filenames from a given directory name (that must exist)
func GetFilenames(dirname string) []string {
	dir, err := os.Open(dirname)
	if err != nil {
		log.WithFields(log.Fields{
			"dirname": dirname,
			"error":   err.Error(),
		}).Error("Could not open directory")
		return []string{}
	}
	defer dir.Close()
	filenames, err := dir.Readdirnames(-1)
	if err != nil {
		log.WithFields(log.Fields{
			"dirname": dirname,
			"error":   err.Error(),
		}).Error("Could not read filenames from directory")

		return []string{}
	}
	return filenames
}

// DurationToMS converts time.Duration to milliseconds, as a string,
// (just the number as a string, no "ms" suffix).
func DurationToMS(d time.Duration, multiplier float64) string {
	return strconv.Itoa(int(d.Seconds() * 1000.0 * multiplier))
}

// DescribeBytes converts bytes to KiB or MiB. Returns a string.
func DescribeBytes(size int64) string {
	if size < MiB {
		return strconv.Itoa(int(round(float64(size)*100.0/KiB)/100)) + " KiB"
	}
	return strconv.Itoa(int(round(float64(size)*100.0/MiB)/100)) + " MiB"
}

// Round a float64 to the nearest integer and return as a float64
func roundf(x float64) float64 {
	return math.Floor(0.5 + x)
}

// Round a float64 to the nearest integer
func round(x float64) int64 {
	return int64(roundf(x))
}

// ReadString returns the contents of the given filename as a string.
// Does not use the cache.  Returns an empty string if there were errors.
func ReadString(filename string) string {
	data, err := ioutil.ReadFile(filename)
	if err == nil {
		// No error, return the file as a string
		return string(data)
	}
	// There were errors, return an empty string
	return ""
}
<commit_msg>Add a utility function<commit_after>package utils

import (
	"io"
	"io/ioutil"
	"math"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	log "github.com/sirupsen/logrus"
)

const (
	// Pathsep is the path separator for the current platform
	Pathsep = string(filepath.Separator)

	// EveryInstance can be used when replacing strings
	EveryInstance = -1

	// KiB is a kilobyte (kibibyte)
	KiB = 1024

	// MiB is a megabyte (mibibyte)
	MiB = 1024 * 1024
)

// URL2filename translates a given URL path to a probable full filename
func URL2filename(dirname, urlpath string) string {
	if strings.Contains(urlpath, "..") {
		log.Warn("Someone was trying to access a directory with .. in the URL")
		return dirname + Pathsep
	}
	if strings.HasPrefix(urlpath, "/") {
		if strings.HasSuffix(dirname, Pathsep) {
			return dirname + urlpath[1:]
		}
		return dirname + Pathsep + urlpath[1:]
	}
	return dirname + "/" + urlpath
}

// GetFilenames retrieves a list of filenames from a given directory name (that must exist)
func GetFilenames(dirname string) []string {
	dir, err := os.Open(dirname)
	if err != nil {
		log.WithFields(log.Fields{
			"dirname": dirname,
			"error":   err.Error(),
		}).Error("Could not open directory")
		return []string{}
	}
	defer dir.Close()
	filenames, err := dir.Readdirnames(-1)
	if err != nil {
		log.WithFields(log.Fields{
			"dirname": dirname,
			"error":   err.Error(),
		}).Error("Could not read filenames from directory")

		return []string{}
	}
	return filenames
}

// DurationToMS converts time.Duration to milliseconds, as a string,
// (just the number as a string, no "ms" suffix).
func DurationToMS(d time.Duration, multiplier float64) string {
	return strconv.Itoa(int(d.Seconds() * 1000.0 * multiplier))
}

// DescribeBytes converts bytes to KiB or MiB. Returns a string.
func DescribeBytes(size int64) string {
	if size < MiB {
		return strconv.Itoa(int(round(float64(size)*100.0/KiB)/100)) + " KiB"
	}
	return strconv.Itoa(int(round(float64(size)*100.0/MiB)/100)) + " MiB"
}

// Round a float64 to the nearest integer and return as a float64
func roundf(x float64) float64 {
	return math.Floor(0.5 + x)
}

// Round a float64 to the nearest integer
func round(x float64) int64 {
	return int64(roundf(x))
}

// ReadString returns the contents of the given filename as a string.
// Does not use the cache.  Returns an empty string if there were errors.
func ReadString(filename string) string {
	data, err := ioutil.ReadFile(filename)
	if err == nil {
		// No error, return the file as a string
		return string(data)
	}
	// There were errors, return an empty string
	return ""
}

// CanRead checks if 1 byte can actually be read from the given filename
func CanRead(filename string) bool {
	f, err := os.Open(filename)
	if err != nil {
		return false
	}
	defer f.Close()
	var onebyte [1]byte
	n, err := io.ReadFull(f, onebyte[:])
	if err != nil {
		return false
	}
	if n != 1 {
		return false
	}
	return true
}
<|endoftext|>