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

package main

import (
	"github.com/jacobsa/comeback/state"
	"log"
	"os"
	"sync"
)

var g_stateOnce sync.Once
var g_state state.State

func initState() {
	cfg := getConfig()
	var err error

	// Open the specified file.
	f, err := os.Open(cfg.StateFile)

	// Special case: if the error is that the file doesn't exist, initialize a
	// new one.
	if err != nil && os.IsNotExist(err) {
		g_state = state.State{
			ExistingScores: nil,
			ExistingScoresVersion: 0,
		}
	} else {
		// Handle other Open errors.
		if err != nil {
			log.Fatalln("Opening state file:", err)
		}

		defer f.Close()

		// Load the state struct.
		g_state, err = state.LoadState(f)
		if err != nil {
			log.Fatalln("LoadState:", err)
		}
	}

	// Throw out the existing scores set if it's out of date.
	reg := getRegistry()
	currentVersion, err := reg.GetCurrentScoreSetVersion()
	if err != nil {
		log.Fatalln("GetCurrentScoreSetVersion:", err)
	}

	if g_state.ExistingScoresVersion != currentVersion {
		g_state.ExistingScores = nil
		g_state.ExistingScoresVersion = currentVersion
	}
}

func getState() *state.State {
	g_stateOnce.Do(initState)
	return &g_state
}

func saveState() {
	var err error

	cfg := getConfig()
	stateStruct := getState()
	randSrc := getRandSrc()
	reg := getRegistry()

	// Assign a new random version for the existing scores.
	lastVersion := g_state.ExistingScoresVersion
	g_state.ExistingScoresVersion = randUint64(randSrc)

	// Update the registry.
	err = reg.UpdateScoreSetVersion(g_state.ExistingScoresVersion, lastVersion)
	if err != nil {
		log.Fatalln("UpdateScoreSetVersion:", err)
	}

	// Write out the state.
	f, err := os.Create(cfg.StateFile)
	if err != nil {
		log.Fatalln("Creating state file:", err)
	}

	defer f.Close()

	if err = state.SaveState(f, *stateStruct); err != nil {
		log.Fatalln("SaveState:", err)
	}
}
<commit_msg>Added some logging.<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"github.com/jacobsa/comeback/state"
	"log"
	"os"
	"sync"
)

var g_stateOnce sync.Once
var g_state state.State

func initState() {
	cfg := getConfig()
	var err error

	// Open the specified file.
	f, err := os.Open(cfg.StateFile)

	// Special case: if the error is that the file doesn't exist, initialize a
	// new one.
	if err != nil && os.IsNotExist(err) {
		log.Println("No state file found. Using fresh state.")
		g_state = state.State{
			ExistingScores: nil,
			ExistingScoresVersion: 0,
		}
	} else {
		// Handle other Open errors.
		if err != nil {
			log.Fatalln("Opening state file:", err)
		}

		defer f.Close()

		// Load the state struct.
		log.Println("Loading from state file.")

		g_state, err = state.LoadState(f)
		if err != nil {
			log.Fatalln("LoadState:", err)
		}
	}

	// Throw out the existing scores set if it's out of date.
	reg := getRegistry()
	currentVersion, err := reg.GetCurrentScoreSetVersion()
	if err != nil {
		log.Fatalln("GetCurrentScoreSetVersion:", err)
	}

	if g_state.ExistingScoresVersion != currentVersion {
		log.Println("Scores in state file are stale. Throwing out.")
		g_state.ExistingScores = nil
		g_state.ExistingScoresVersion = currentVersion
	}
}

func getState() *state.State {
	g_stateOnce.Do(initState)
	return &g_state
}

func saveState() {
	var err error

	cfg := getConfig()
	stateStruct := getState()
	randSrc := getRandSrc()
	reg := getRegistry()

	// Assign a new random version for the existing scores.
	lastVersion := g_state.ExistingScoresVersion
	g_state.ExistingScoresVersion = randUint64(randSrc)

	// Update the registry.
	err = reg.UpdateScoreSetVersion(g_state.ExistingScoresVersion, lastVersion)
	if err != nil {
		log.Fatalln("UpdateScoreSetVersion:", err)
	}

	// Write out the state.
	f, err := os.Create(cfg.StateFile)
	if err != nil {
		log.Fatalln("Creating state file:", err)
	}

	defer f.Close()

	if err = state.SaveState(f, *stateStruct); err != nil {
		log.Fatalln("SaveState:", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/rubyist/circuitbreaker"
	"net/http"
	"path"
)

var (
	Client = &httpClient{
		cb: circuit.NewRateBreaker(0.20, 100),
	}
)

type httpClient struct {
	cb *circuit.Breaker
	http.Client
}

func (c *httpClient) Do(r *http.Request) (resp *http.Response, err error) {
	if c.cb.Ready() {
		resp, err = c.Client.Do(r)
		if err != nil {
			c.cb.Fail()
			return
		}

		if resp.StatusCode >= 500 {
			c.cb.Fail()
			return
		}

		c.cb.Success()
		return
	} else {
		logger.Log(D{"fn": "Client.Do", "err": "tripped"})
	}

	return
}

// S3Redirector implements the ContentStorer interface to serve content via redirecting to S3.
type S3Redirector struct {
}

// Get will use the provided object Meta data to write a redirect Location and status to
// the Response Writer. It generates a signed S3 URL that is valid for 5 minutes.
func (s *S3Redirector) Get(meta *Meta, w http.ResponseWriter, r *http.Request) int {
	token := S3SignQuery("GET", path.Join("/", meta.PathPrefix, oidPath(meta.Oid)), 300)
	w.Header().Set("Location", token.Location)
	w.WriteHeader(302)
	return 302
}

// PutLink generates an signed S3 link that will allow the client to PUT data into S3. This
// link includes the x-amz-content-sha256 header which will ensure that the client uploads only
// data that will match the OID.
func (s *S3Redirector) PutLink(meta *Meta) *link {
	token := S3SignHeader("PUT", path.Join("/", meta.PathPrefix, oidPath(meta.Oid)), meta.Oid)
	header := make(map[string]string)
	header["Authorization"] = token.Token
	header["x-amz-content-sha256"] = meta.Oid
	header["x-amz-date"] = token.Time.Format(isoLayout)

	return &link{Href: token.Location, Header: header}
}

// Exists checks to see if an object exists on S3.
func (s *S3Redirector) Exists(meta *Meta) (bool, error) {
	token := S3SignQuery("HEAD", path.Join("/", meta.PathPrefix, oidPath(meta.Oid)), 30)
	req, err := http.NewRequest("HEAD", token.Location, nil)
	if err != nil {
		return false, err
	}

	res, err := Client.Do(req)
	if err != nil {
		return false, err
	}

	if res.StatusCode != 200 {
		return false, err
	}

	return true, nil
}

func oidPath(oid string) string {
	dir := path.Join(oid[0:2], oid[2:4])

	return path.Join("/", dir, oid)
}

// MetaStore implements the MetaStorer interface to provide metadata from an external HTTP API.
type MetaStore struct {
}

// MetaLink generates a URI path using the configured MetaEndpoint.
func (s *MetaStore) MetaLink(v *RequestVars) string {
	return Config.MetaEndpoint + "/" + path.Join(v.User, v.Repo, "media", "blobs", v.Oid)
}

// Get retrieves metadata from the backend API.
func (s *MetaStore) Get(v *RequestVars) (*Meta, error) {
	req, err := http.NewRequest("GET", s.MetaLink(v), nil)
	if err != nil {
		logger.Log(D{"fn": "meta.Get", "err": err})
		return nil, err
	}
	req.Header.Set("Accept", Config.ApiMediaType)
	if v.Authorization != "" {
		req.Header.Set("Authorization", v.Authorization)
	}
	if v.RequestId != "" {
		req.Header.Set("X-GitHub-Request-Id", v.RequestId)
	}

	res, err := Client.Do(req)
	if err != nil {
		logger.Log(D{"fn": "meta.Get", "err": err})
		return nil, err
	}

	defer res.Body.Close()
	if res.StatusCode == 200 {
		var m Meta
		dec := json.NewDecoder(res.Body)
		err := dec.Decode(&m)
		if err != nil {
			logger.Log(D{"fn": "meta.Get", "err": err})
			return nil, err
		}

		logger.Log(D{"fn": "meta.Get", "status": res.StatusCode})
		return &m, nil
	}

	if res.StatusCode == 204 {
		return &Meta{Oid: v.Oid, Size: v.Size, PathPrefix: v.PathPrefix}, nil
	}

	logger.Log(D{"fn": "meta.Get", "status": res.StatusCode})
	return nil, fmt.Errorf("status: %d", res.StatusCode)
}

// Send POSTs metadata to the backend API.
func (s *MetaStore) Send(v *RequestVars) (*Meta, error) {
	req, err := signedApiPost(s.MetaLink(v), v)

	if v.RequestId != "" {
		req.Header.Set("X-GitHub-Request-Id", v.RequestId)
	}

	res, err := Client.Do(req)
	if err != nil {
		logger.Log(D{"fn": "meta.Send", "err": err})
		return nil, err
	}

	defer res.Body.Close()

	if res.StatusCode == 403 {
		logger.Log(D{"fn": "meta.Send", "status": 403})
		return nil, apiAuthError
	}

	if res.StatusCode == 200 || res.StatusCode == 201 {
		var m Meta
		dec := json.NewDecoder(res.Body)
		err := dec.Decode(&m)
		if err != nil {
			logger.Log(D{"fn": "meta.Send", "err": err})
			return nil, err
		}
		m.existing = res.StatusCode == 200
		logger.Log(D{"fn": "meta.Send", "status": res.StatusCode})
		return &m, nil
	}

	logger.Log(D{"fn": "meta.Send", "status": res.StatusCode})
	return nil, fmt.Errorf("status: %d", res.StatusCode)
}

// Verify is used during the callback phase to indicate to the backend API that the
// object has been received.
func (s *MetaStore) Verify(v *RequestVars) error {
	url := Config.MetaEndpoint + "/" + path.Join(v.User, v.Repo, "media", "blobs", v.Oid, "verify")

	req, err := signedApiPost(url, v)
	if err != nil {
		return err
	}
	if v.RequestId != "" {
		req.Header.Set("X-GitHub-Request-Id", v.RequestId)
	}

	res, err := Client.Do(req)
	if err != nil {
		logger.Log(D{"fn": "meta.Verify", "err": err})
		return err
	}

	defer res.Body.Close()

	if res.StatusCode == 403 {
		logger.Log(D{"fn": "meta.Verify", "err": 403})
		return apiAuthError
	}

	logger.Log(D{"fn": "meta.Verify", "status": res.StatusCode})
	if res.StatusCode == 200 {
		return nil
	}
	return fmt.Errorf("status: %d", res.StatusCode)
}

func signedApiPost(url string, v *RequestVars) (*http.Request, error) {
	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	enc.Encode(&Meta{Oid: v.Oid, Size: v.Size})

	req, err := http.NewRequest("POST", url, &buf)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Accept", Config.ApiMediaType)
	if v.Authorization != "" {
		req.Header.Set("Authorization", v.Authorization)
	}

	if Config.HmacKey != "" {
		mac := hmac.New(sha256.New, []byte(Config.HmacKey))
		mac.Write(buf.Bytes())
		req.Header.Set("Content-Hmac", "sha256 "+hex.EncodeToString(mac.Sum(nil)))
	}

	return req, nil
}
<commit_msg>Simplify logic<commit_after>package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/rubyist/circuitbreaker"
	"net/http"
	"path"
)

var (
	Client = &httpClient{
		cb: circuit.NewRateBreaker(0.20, 100),
	}
)

type httpClient struct {
	cb *circuit.Breaker
	http.Client
}

func (c *httpClient) Do(r *http.Request) (resp *http.Response, err error) {
	if c.cb.Ready() {
		resp, err = c.Client.Do(r)
		if err != nil || resp.StatusCode >= 500 {
			c.cb.Fail()
			return
		}

		c.cb.Success()
		return
	} else {
		logger.Log(D{"fn": "Client.Do", "err": "tripped"})
	}

	return
}

// S3Redirector implements the ContentStorer interface to serve content via redirecting to S3.
type S3Redirector struct {
}

// Get will use the provided object Meta data to write a redirect Location and status to
// the Response Writer. It generates a signed S3 URL that is valid for 5 minutes.
func (s *S3Redirector) Get(meta *Meta, w http.ResponseWriter, r *http.Request) int {
	token := S3SignQuery("GET", path.Join("/", meta.PathPrefix, oidPath(meta.Oid)), 300)
	w.Header().Set("Location", token.Location)
	w.WriteHeader(302)
	return 302
}

// PutLink generates an signed S3 link that will allow the client to PUT data into S3. This
// link includes the x-amz-content-sha256 header which will ensure that the client uploads only
// data that will match the OID.
func (s *S3Redirector) PutLink(meta *Meta) *link {
	token := S3SignHeader("PUT", path.Join("/", meta.PathPrefix, oidPath(meta.Oid)), meta.Oid)
	header := make(map[string]string)
	header["Authorization"] = token.Token
	header["x-amz-content-sha256"] = meta.Oid
	header["x-amz-date"] = token.Time.Format(isoLayout)

	return &link{Href: token.Location, Header: header}
}

// Exists checks to see if an object exists on S3.
func (s *S3Redirector) Exists(meta *Meta) (bool, error) {
	token := S3SignQuery("HEAD", path.Join("/", meta.PathPrefix, oidPath(meta.Oid)), 30)
	req, err := http.NewRequest("HEAD", token.Location, nil)
	if err != nil {
		return false, err
	}

	res, err := Client.Do(req)
	if err != nil {
		return false, err
	}

	if res.StatusCode != 200 {
		return false, err
	}

	return true, nil
}

func oidPath(oid string) string {
	dir := path.Join(oid[0:2], oid[2:4])

	return path.Join("/", dir, oid)
}

// MetaStore implements the MetaStorer interface to provide metadata from an external HTTP API.
type MetaStore struct {
}

// MetaLink generates a URI path using the configured MetaEndpoint.
func (s *MetaStore) MetaLink(v *RequestVars) string {
	return Config.MetaEndpoint + "/" + path.Join(v.User, v.Repo, "media", "blobs", v.Oid)
}

// Get retrieves metadata from the backend API.
func (s *MetaStore) Get(v *RequestVars) (*Meta, error) {
	req, err := http.NewRequest("GET", s.MetaLink(v), nil)
	if err != nil {
		logger.Log(D{"fn": "meta.Get", "err": err})
		return nil, err
	}
	req.Header.Set("Accept", Config.ApiMediaType)
	if v.Authorization != "" {
		req.Header.Set("Authorization", v.Authorization)
	}
	if v.RequestId != "" {
		req.Header.Set("X-GitHub-Request-Id", v.RequestId)
	}

	res, err := Client.Do(req)
	if err != nil {
		logger.Log(D{"fn": "meta.Get", "err": err})
		return nil, err
	}

	defer res.Body.Close()
	if res.StatusCode == 200 {
		var m Meta
		dec := json.NewDecoder(res.Body)
		err := dec.Decode(&m)
		if err != nil {
			logger.Log(D{"fn": "meta.Get", "err": err})
			return nil, err
		}

		logger.Log(D{"fn": "meta.Get", "status": res.StatusCode})
		return &m, nil
	}

	if res.StatusCode == 204 {
		return &Meta{Oid: v.Oid, Size: v.Size, PathPrefix: v.PathPrefix}, nil
	}

	logger.Log(D{"fn": "meta.Get", "status": res.StatusCode})
	return nil, fmt.Errorf("status: %d", res.StatusCode)
}

// Send POSTs metadata to the backend API.
func (s *MetaStore) Send(v *RequestVars) (*Meta, error) {
	req, err := signedApiPost(s.MetaLink(v), v)

	if v.RequestId != "" {
		req.Header.Set("X-GitHub-Request-Id", v.RequestId)
	}

	res, err := Client.Do(req)
	if err != nil {
		logger.Log(D{"fn": "meta.Send", "err": err})
		return nil, err
	}

	defer res.Body.Close()

	if res.StatusCode == 403 {
		logger.Log(D{"fn": "meta.Send", "status": 403})
		return nil, apiAuthError
	}

	if res.StatusCode == 200 || res.StatusCode == 201 {
		var m Meta
		dec := json.NewDecoder(res.Body)
		err := dec.Decode(&m)
		if err != nil {
			logger.Log(D{"fn": "meta.Send", "err": err})
			return nil, err
		}
		m.existing = res.StatusCode == 200
		logger.Log(D{"fn": "meta.Send", "status": res.StatusCode})
		return &m, nil
	}

	logger.Log(D{"fn": "meta.Send", "status": res.StatusCode})
	return nil, fmt.Errorf("status: %d", res.StatusCode)
}

// Verify is used during the callback phase to indicate to the backend API that the
// object has been received.
func (s *MetaStore) Verify(v *RequestVars) error {
	url := Config.MetaEndpoint + "/" + path.Join(v.User, v.Repo, "media", "blobs", v.Oid, "verify")

	req, err := signedApiPost(url, v)
	if err != nil {
		return err
	}
	if v.RequestId != "" {
		req.Header.Set("X-GitHub-Request-Id", v.RequestId)
	}

	res, err := Client.Do(req)
	if err != nil {
		logger.Log(D{"fn": "meta.Verify", "err": err})
		return err
	}

	defer res.Body.Close()

	if res.StatusCode == 403 {
		logger.Log(D{"fn": "meta.Verify", "err": 403})
		return apiAuthError
	}

	logger.Log(D{"fn": "meta.Verify", "status": res.StatusCode})
	if res.StatusCode == 200 {
		return nil
	}
	return fmt.Errorf("status: %d", res.StatusCode)
}

func signedApiPost(url string, v *RequestVars) (*http.Request, error) {
	var buf bytes.Buffer
	enc := json.NewEncoder(&buf)
	enc.Encode(&Meta{Oid: v.Oid, Size: v.Size})

	req, err := http.NewRequest("POST", url, &buf)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Accept", Config.ApiMediaType)
	if v.Authorization != "" {
		req.Header.Set("Authorization", v.Authorization)
	}

	if Config.HmacKey != "" {
		mac := hmac.New(sha256.New, []byte(Config.HmacKey))
		mac.Write(buf.Bytes())
		req.Header.Set("Content-Hmac", "sha256 "+hex.EncodeToString(mac.Sum(nil)))
	}

	return req, nil
}
<|endoftext|>


<commit_before>package gocli

import (
	"fmt"
	"regexp"
	"strings"
)

func NewTable() *Table {
	return &Table{
		Columns:   [][]string{},
		Lengths:   map[int]int{},
		Separator: "\t",
	}
}

type Table struct {
	Columns   [][]string
	Lengths   map[int]int
	Separator string
}

func (self *Table) String() string {
	lines := []string{}
	for _, line := range self.Lines() {
		lines = append(lines, line)
	}
	return strings.Join(lines, "\n")
}

var uncolorRegexp = regexp.MustCompile("\033\\[38;5;\\d+m")

func stringLength(s string) int {
	return len(strings.Replace(uncolorRegexp.ReplaceAllString(s, ""), "\033[0m", "", -1))
}

func (self *Table) Lines() (lines []string) {
	for _, col := range self.Columns {
		cl := []string{}
		for i, v := range col {
			cl = append(cl, fmt.Sprintf("%-*s", self.Lengths[i], v))
		}
		lines = append(lines, strings.Join(cl, self.Separator))
	}
	return
}

func (t *Table) AddStrings(s []string) {
	var ret = make([]interface{}, len(s))

	for i, v := range s {
		ret[i] = v
	}
	t.Add(ret...)
}

// Add adds a column to the table
func (self *Table) Add(cols ...interface{}) {
	converted := make([]string, len(cols))
	for i, v := range cols {
		s := fmt.Sprint(v)
		converted[i] = s
		if self.Lengths[i] < stringLength(s) {
			self.Lengths[i] = len(s)
		}
	}
	self.Columns = append(self.Columns, converted)
}
<commit_msg>Consistently use t instead of self<commit_after>package gocli

import (
	"fmt"
	"regexp"
	"strings"
)

func NewTable() *Table {
	return &Table{
		Columns:   [][]string{},
		Lengths:   map[int]int{},
		Separator: "\t",
	}
}

type Table struct {
	Columns   [][]string
	Lengths   map[int]int
	Separator string
}

func (t *Table) String() string {
	lines := []string{}
	for _, line := range t.Lines() {
		lines = append(lines, line)
	}
	return strings.Join(lines, "\n")
}

var uncolorRegexp = regexp.MustCompile("\033\\[38;5;\\d+m")

func stringLength(s string) int {
	return len(strings.Replace(uncolorRegexp.ReplaceAllString(s, ""), "\033[0m", "", -1))
}

func (t *Table) Lines() (lines []string) {
	for _, col := range t.Columns {
		cl := []string{}
		for i, v := range col {
			cl = append(cl, fmt.Sprintf("%-*s", t.Lengths[i], v))
		}
		lines = append(lines, strings.Join(cl, t.Separator))
	}
	return
}

func (t *Table) AddStrings(s []string) {
	var ret = make([]interface{}, len(s))

	for i, v := range s {
		ret[i] = v
	}
	t.Add(ret...)
}

// Add adds a column to the table
func (t *Table) Add(cols ...interface{}) {
	converted := make([]string, len(cols))
	for i, v := range cols {
		s := fmt.Sprint(v)
		converted[i] = s
		if t.Lengths[i] < stringLength(s) {
			t.Lengths[i] = len(s)
		}
	}
	t.Columns = append(t.Columns, converted)
}
<|endoftext|>


<commit_before>// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

// This module is a Table Writer  API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems

// Create & Generate text based table
package tablewriter

import (
	"fmt"
	"io"
	"regexp"
	"strings"
)

const (
	MAX_ROW_WIDTH = 30
)

const (
	CENTER = "+"
	ROW    = "-"
	COLUMN = "|"
	SPACE  = " "
)

const (
	ALIGN_DEFAULT = iota
	ALIGN_CENTER
	ALIGN_RIGHT
	ALIGN_LEFT
)

var (
	decimal = regexp.MustCompile(`^\d*\.?\d*$`)
	percent = regexp.MustCompile(`^\d*\.?\d*$%$`)
)

type Border struct {
	Left   bool
	Right  bool
	Top    bool
	Bottom bool
}

type Table struct {
	out      io.Writer
	rows     [][]string
	lines    [][][]string
	cs       map[int]int
	rs       map[int]int
	headers  []string
	footers  []string
	autoFmt  bool
	autoWrap bool
	mW       int
	pCenter  string
	pRow     string
	pColumn  string
	tColumn  int
	tRow     int
	hAlign   int
	fAlign   int
	align    int
	rowLine  bool
	hdrLine  bool
	borders  Border
	colSize  int
}

// Start New Table
// Take io.Writer Directly
func NewWriter(writer io.Writer) *Table {
	t := &Table{
		out:      writer,
		rows:     [][]string{},
		lines:    [][][]string{},
		cs:       make(map[int]int),
		rs:       make(map[int]int),
		headers:  []string{},
		footers:  []string{},
		autoFmt:  true,
		autoWrap: true,
		mW:       MAX_ROW_WIDTH,
		pCenter:  CENTER,
		pRow:     ROW,
		pColumn:  COLUMN,
		tColumn:  -1,
		tRow:     -1,
		hAlign:   ALIGN_DEFAULT,
		fAlign:   ALIGN_DEFAULT,
		align:    ALIGN_DEFAULT,
		rowLine:  false,
		hdrLine:  true,
		borders:  Border{Left: true, Right: true, Bottom: true, Top: true},
		colSize:  -1}
	return t
}

// Render table output
func (t Table) Render() {
	if t.borders.Top {
		t.printLine(true)
	}
	t.printHeading()
	t.printRows()

	if !t.rowLine && t.borders.Bottom {
		t.printLine(true)
	}
	t.printFooter()

}

// Set table header
func (t *Table) SetHeader(keys []string) {
	t.colSize = len(keys)
	for i, v := range keys {
		t.parseDimension(v, i, -1)
		t.headers = append(t.headers, v)
	}
}

// Set table Footer
func (t *Table) SetFooter(keys []string) {
	//t.colSize = len(keys)
	for i, v := range keys {
		t.parseDimension(v, i, -1)
		t.footers = append(t.footers, v)
	}
}

// Turn header autoformatting on/off. Default is on (true).
func (t *Table) SetAutoFormatHeaders(auto bool) {
	t.autoFmt = auto
}

// Turn automatic multiline text adjustment on/off. Default is on (true).
func (t *Table) SetAutoWrapText(auto bool) {
	t.autoWrap = auto
}

// Set the Default column width
func (t *Table) SetColWidth(width int) {
	t.mW = width
}

// Set the Column Separator
func (t *Table) SetColumnSeparator(sep string) {
	t.pColumn = sep
}

// Set the Row Separator
func (t *Table) SetRowSeparator(sep string) {
	t.pRow = sep
}

// Set the center Separator
func (t *Table) SetCenterSeparator(sep string) {
	t.pCenter = sep
}

// Set Header Alignment
func (t *Table) SetHeaderAlignment(hAlign int) {
	t.hAlign = hAlign
}

// Set Footer Alignment
func (t *Table) SetFooterAlignment(fAlign int) {
	t.fAlign = fAlign
}

// Set Table Alignment
func (t *Table) SetAlignment(align int) {
	t.align = align
}

// Set Header Line
// This would enable / disable a line after the header
func (t *Table) SetHeaderLine(line bool) {
	t.hdrLine = line
}

// Set Row Line
// This would enable / disable a line on each row of the table
func (t *Table) SetRowLine(line bool) {
	t.rowLine = line
}

// Set Table Border
// This would enable / disable line around the table
func (t *Table) SetBorder(border bool) {
	t.SetBorders(Border{border, border, border, border})
}

func (t *Table) SetBorders(border Border) {
	t.borders = border
}

// Append row to table
func (t *Table) Append(row []string) {
	rowSize := len(t.headers)
	if rowSize > t.colSize {
		t.colSize = rowSize
	}

	n := len(t.lines)
	line := [][]string{}
	for i, v := range row {

		// Detect string  width
		// Detect String height
		// Break strings into words
		out := t.parseDimension(v, i, n)

		// Append broken words
		line = append(line, out)
	}
	t.lines = append(t.lines, line)
}

// Allow Support for Bulk Append
// Eliminates repeated for loops
func (t *Table) AppendBulk(rows [][]string) {
	for _, row := range rows {
		t.Append(row)
	}
}

// Print line based on row width
func (t Table) printLine(nl bool) {
	fmt.Fprint(t.out, t.pCenter)
	for i := 0; i < len(t.cs); i++ {
		v := t.cs[i]
		fmt.Fprintf(t.out, "%s%s%s%s",
			t.pRow,
			strings.Repeat(string(t.pRow), v),
			t.pRow,
			t.pCenter)
	}
	if nl {
		fmt.Fprintln(t.out)
	}
}

// Return the PadRight function if align is left, PadLeft if align is right,
// and Pad by default
func pad(align int) func(string, string, int) string {
	padFunc := Pad
	switch align {
	case ALIGN_LEFT:
		padFunc = PadRight
	case ALIGN_RIGHT:
		padFunc = PadLeft
	}
	return padFunc
}

// Print heading information
func (t Table) printHeading() {
	// Check if headers is available
	if len(t.headers) < 1 {
		return
	}

	// Check if border is set
	// Replace with space if not set
	fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE))

	// Identify last column
	end := len(t.cs) - 1

	// Get pad function
	padFunc := pad(t.hAlign)

	// Print Heading column
	for i := 0; i <= end; i++ {
		v := t.cs[i]
		h := t.headers[i]
		if t.autoFmt {
			h = Title(h)
		}
		pad := ConditionString((i == end && !t.borders.Left), SPACE, t.pColumn)
		fmt.Fprintf(t.out, " %s %s",
			padFunc(h, SPACE, v),
			pad)
	}
	// Next line
	fmt.Fprintln(t.out)
	if t.hdrLine {
		t.printLine(true)
	}
}

// Print heading information
func (t Table) printFooter() {
	// Check if headers is available
	if len(t.footers) < 1 {
		return
	}

	// Only print line if border is not set
	if !t.borders.Bottom {
		t.printLine(true)
	}
	// Check if border is set
	// Replace with space if not set
	fmt.Fprint(t.out, ConditionString(t.borders.Bottom, t.pColumn, SPACE))

	// Identify last column
	end := len(t.cs) - 1

	// Get pad function
	padFunc := pad(t.fAlign)

	// Print Heading column
	for i := 0; i <= end; i++ {
		v := t.cs[i]
		f := t.footers[i]
		if t.autoFmt {
			f = Title(f)
		}
		pad := ConditionString((i == end && !t.borders.Top), SPACE, t.pColumn)

		if len(t.footers[i]) == 0 {
			pad = SPACE
		}
		fmt.Fprintf(t.out, " %s %s",
			padFunc(f, SPACE, v),
			pad)
	}
	// Next line
	fmt.Fprintln(t.out)
	//t.printLine(true)

	hasPrinted := false

	for i := 0; i <= end; i++ {
		v := t.cs[i]
		pad := t.pRow
		center := t.pCenter
		length := len(t.footers[i])

		if length > 0 {
			hasPrinted = true
		}

		// Set center to be space if length is 0
		if length == 0 && !t.borders.Right {
			center = SPACE
		}

		// Print first junction
		if i == 0 {
			fmt.Fprint(t.out, center)
		}

		// Pad With space of length is 0
		if length == 0 {
			pad = SPACE
		}
		// Ignore left space of it has printed before
		if hasPrinted || t.borders.Left {
			pad = t.pRow
			center = t.pCenter
		}

		// Change Center start position
		if center == SPACE {
			if i < end && len(t.footers[i+1]) != 0 {
				center = t.pCenter
			}
		}

		// Print the footer
		fmt.Fprintf(t.out, "%s%s%s%s",
			pad,
			strings.Repeat(string(pad), v),
			pad,
			center)

	}

	fmt.Fprintln(t.out)

}

func (t Table) printRows() {
	for i, lines := range t.lines {
		t.printRow(lines, i)
	}

}

// Print Row Information
// Adjust column alignment based on type

func (t Table) printRow(columns [][]string, colKey int) {
	// Get Maximum Height
	max := t.rs[colKey]
	total := len(columns)

	// TODO Fix uneven col size
	// if total < t.colSize {
	//	for n := t.colSize - total; n < t.colSize ; n++ {
	//		columns = append(columns, []string{SPACE})
	//		t.cs[n] = t.mW
	//	}
	//}

	// Pad Each Height
	// pads := []int{}
	pads := []int{}

	for i, line := range columns {
		length := len(line)
		pad := max - length
		pads = append(pads, pad)
		for n := 0; n < pad; n++ {
			columns[i] = append(columns[i], "  ")
		}
	}
	//fmt.Println(max, "\n")
	for x := 0; x < max; x++ {
		for y := 0; y < total; y++ {

			// Check if border is set
			fmt.Fprint(t.out, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn))

			fmt.Fprintf(t.out, SPACE)
			str := columns[y][x]

			// This would print alignment
			// Default alignment  would use multiple configuration
			switch t.align {
			case ALIGN_CENTER: //
				fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y]))
			case ALIGN_RIGHT:
				fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y]))
			case ALIGN_LEFT:
				fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))
			default:
				if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) {
					fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y]))
				} else {
					fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))

					// TODO Custom alignment per column
					//if max == 1 || pads[y] > 0 {
					//	fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y]))
					//} else {
					//	fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))
					//}

				}
			}
			fmt.Fprintf(t.out, SPACE)
		}
		// Check if border is set
		// Replace with space if not set
		fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE))
		fmt.Fprintln(t.out)
	}

	if t.rowLine {
		t.printLine(true)
	}

}

func (t *Table) parseDimension(str string, colKey, rowKey int) []string {
	var (
		raw []string
		max int
	)
	w := DisplayWidth(str)
	// Calculate Width
	// Check if with is grater than maximum width
	if w > t.mW {
		w = t.mW
	}

	// Check if width exists
	v, ok := t.cs[colKey]
	if !ok || v < w || v == 0 {
		t.cs[colKey] = w
	}

	if rowKey == -1 {
		return raw
	}
	// Calculate Height
	if t.autoWrap {
		raw, _ = WrapString(str, t.cs[colKey])
	} else {
		raw = getLines(str)
	}

	for _, line := range raw {
		if w := DisplayWidth(line); w > max {
			max = w
		}
	}

	// Make sure the with is the same length as maximum word
	// Important for cases where the width is smaller than maxu word
	if max > t.cs[colKey] {
		t.cs[colKey] = max
	}

	h := len(raw)
	v, ok = t.rs[rowKey]

	if !ok || v < h || v == 0 {
		t.rs[rowKey] = h
	}
	//fmt.Printf("Raw %+v %d\n", raw, len(raw))
	return raw
}
<commit_msg>Updated regexps to support right aligned negative values.<commit_after>// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

// This module is a Table Writer  API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems

// Create & Generate text based table
package tablewriter

import (
	"fmt"
	"io"
	"regexp"
	"strings"
)

const (
	MAX_ROW_WIDTH = 30
)

const (
	CENTER = "+"
	ROW    = "-"
	COLUMN = "|"
	SPACE  = " "
)

const (
	ALIGN_DEFAULT = iota
	ALIGN_CENTER
	ALIGN_RIGHT
	ALIGN_LEFT
)

var (
	decimal = regexp.MustCompile(`^-*\d*\.?\d*$`)
	percent = regexp.MustCompile(`^-*\d*\.?\d*$%$`)
)

type Border struct {
	Left   bool
	Right  bool
	Top    bool
	Bottom bool
}

type Table struct {
	out      io.Writer
	rows     [][]string
	lines    [][][]string
	cs       map[int]int
	rs       map[int]int
	headers  []string
	footers  []string
	autoFmt  bool
	autoWrap bool
	mW       int
	pCenter  string
	pRow     string
	pColumn  string
	tColumn  int
	tRow     int
	hAlign   int
	fAlign   int
	align    int
	rowLine  bool
	hdrLine  bool
	borders  Border
	colSize  int
}

// Start New Table
// Take io.Writer Directly
func NewWriter(writer io.Writer) *Table {
	t := &Table{
		out:      writer,
		rows:     [][]string{},
		lines:    [][][]string{},
		cs:       make(map[int]int),
		rs:       make(map[int]int),
		headers:  []string{},
		footers:  []string{},
		autoFmt:  true,
		autoWrap: true,
		mW:       MAX_ROW_WIDTH,
		pCenter:  CENTER,
		pRow:     ROW,
		pColumn:  COLUMN,
		tColumn:  -1,
		tRow:     -1,
		hAlign:   ALIGN_DEFAULT,
		fAlign:   ALIGN_DEFAULT,
		align:    ALIGN_DEFAULT,
		rowLine:  false,
		hdrLine:  true,
		borders:  Border{Left: true, Right: true, Bottom: true, Top: true},
		colSize:  -1}
	return t
}

// Render table output
func (t Table) Render() {
	if t.borders.Top {
		t.printLine(true)
	}
	t.printHeading()
	t.printRows()

	if !t.rowLine && t.borders.Bottom {
		t.printLine(true)
	}
	t.printFooter()

}

// Set table header
func (t *Table) SetHeader(keys []string) {
	t.colSize = len(keys)
	for i, v := range keys {
		t.parseDimension(v, i, -1)
		t.headers = append(t.headers, v)
	}
}

// Set table Footer
func (t *Table) SetFooter(keys []string) {
	//t.colSize = len(keys)
	for i, v := range keys {
		t.parseDimension(v, i, -1)
		t.footers = append(t.footers, v)
	}
}

// Turn header autoformatting on/off. Default is on (true).
func (t *Table) SetAutoFormatHeaders(auto bool) {
	t.autoFmt = auto
}

// Turn automatic multiline text adjustment on/off. Default is on (true).
func (t *Table) SetAutoWrapText(auto bool) {
	t.autoWrap = auto
}

// Set the Default column width
func (t *Table) SetColWidth(width int) {
	t.mW = width
}

// Set the Column Separator
func (t *Table) SetColumnSeparator(sep string) {
	t.pColumn = sep
}

// Set the Row Separator
func (t *Table) SetRowSeparator(sep string) {
	t.pRow = sep
}

// Set the center Separator
func (t *Table) SetCenterSeparator(sep string) {
	t.pCenter = sep
}

// Set Header Alignment
func (t *Table) SetHeaderAlignment(hAlign int) {
	t.hAlign = hAlign
}

// Set Footer Alignment
func (t *Table) SetFooterAlignment(fAlign int) {
	t.fAlign = fAlign
}

// Set Table Alignment
func (t *Table) SetAlignment(align int) {
	t.align = align
}

// Set Header Line
// This would enable / disable a line after the header
func (t *Table) SetHeaderLine(line bool) {
	t.hdrLine = line
}

// Set Row Line
// This would enable / disable a line on each row of the table
func (t *Table) SetRowLine(line bool) {
	t.rowLine = line
}

// Set Table Border
// This would enable / disable line around the table
func (t *Table) SetBorder(border bool) {
	t.SetBorders(Border{border, border, border, border})
}

func (t *Table) SetBorders(border Border) {
	t.borders = border
}

// Append row to table
func (t *Table) Append(row []string) {
	rowSize := len(t.headers)
	if rowSize > t.colSize {
		t.colSize = rowSize
	}

	n := len(t.lines)
	line := [][]string{}
	for i, v := range row {

		// Detect string  width
		// Detect String height
		// Break strings into words
		out := t.parseDimension(v, i, n)

		// Append broken words
		line = append(line, out)
	}
	t.lines = append(t.lines, line)
}

// Allow Support for Bulk Append
// Eliminates repeated for loops
func (t *Table) AppendBulk(rows [][]string) {
	for _, row := range rows {
		t.Append(row)
	}
}

// Print line based on row width
func (t Table) printLine(nl bool) {
	fmt.Fprint(t.out, t.pCenter)
	for i := 0; i < len(t.cs); i++ {
		v := t.cs[i]
		fmt.Fprintf(t.out, "%s%s%s%s",
			t.pRow,
			strings.Repeat(string(t.pRow), v),
			t.pRow,
			t.pCenter)
	}
	if nl {
		fmt.Fprintln(t.out)
	}
}

// Return the PadRight function if align is left, PadLeft if align is right,
// and Pad by default
func pad(align int) func(string, string, int) string {
	padFunc := Pad
	switch align {
	case ALIGN_LEFT:
		padFunc = PadRight
	case ALIGN_RIGHT:
		padFunc = PadLeft
	}
	return padFunc
}

// Print heading information
func (t Table) printHeading() {
	// Check if headers is available
	if len(t.headers) < 1 {
		return
	}

	// Check if border is set
	// Replace with space if not set
	fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE))

	// Identify last column
	end := len(t.cs) - 1

	// Get pad function
	padFunc := pad(t.hAlign)

	// Print Heading column
	for i := 0; i <= end; i++ {
		v := t.cs[i]
		h := t.headers[i]
		if t.autoFmt {
			h = Title(h)
		}
		pad := ConditionString((i == end && !t.borders.Left), SPACE, t.pColumn)
		fmt.Fprintf(t.out, " %s %s",
			padFunc(h, SPACE, v),
			pad)
	}
	// Next line
	fmt.Fprintln(t.out)
	if t.hdrLine {
		t.printLine(true)
	}
}

// Print heading information
func (t Table) printFooter() {
	// Check if headers is available
	if len(t.footers) < 1 {
		return
	}

	// Only print line if border is not set
	if !t.borders.Bottom {
		t.printLine(true)
	}
	// Check if border is set
	// Replace with space if not set
	fmt.Fprint(t.out, ConditionString(t.borders.Bottom, t.pColumn, SPACE))

	// Identify last column
	end := len(t.cs) - 1

	// Get pad function
	padFunc := pad(t.fAlign)

	// Print Heading column
	for i := 0; i <= end; i++ {
		v := t.cs[i]
		f := t.footers[i]
		if t.autoFmt {
			f = Title(f)
		}
		pad := ConditionString((i == end && !t.borders.Top), SPACE, t.pColumn)

		if len(t.footers[i]) == 0 {
			pad = SPACE
		}
		fmt.Fprintf(t.out, " %s %s",
			padFunc(f, SPACE, v),
			pad)
	}
	// Next line
	fmt.Fprintln(t.out)
	//t.printLine(true)

	hasPrinted := false

	for i := 0; i <= end; i++ {
		v := t.cs[i]
		pad := t.pRow
		center := t.pCenter
		length := len(t.footers[i])

		if length > 0 {
			hasPrinted = true
		}

		// Set center to be space if length is 0
		if length == 0 && !t.borders.Right {
			center = SPACE
		}

		// Print first junction
		if i == 0 {
			fmt.Fprint(t.out, center)
		}

		// Pad With space of length is 0
		if length == 0 {
			pad = SPACE
		}
		// Ignore left space of it has printed before
		if hasPrinted || t.borders.Left {
			pad = t.pRow
			center = t.pCenter
		}

		// Change Center start position
		if center == SPACE {
			if i < end && len(t.footers[i+1]) != 0 {
				center = t.pCenter
			}
		}

		// Print the footer
		fmt.Fprintf(t.out, "%s%s%s%s",
			pad,
			strings.Repeat(string(pad), v),
			pad,
			center)

	}

	fmt.Fprintln(t.out)

}

func (t Table) printRows() {
	for i, lines := range t.lines {
		t.printRow(lines, i)
	}

}

// Print Row Information
// Adjust column alignment based on type

func (t Table) printRow(columns [][]string, colKey int) {
	// Get Maximum Height
	max := t.rs[colKey]
	total := len(columns)

	// TODO Fix uneven col size
	// if total < t.colSize {
	//	for n := t.colSize - total; n < t.colSize ; n++ {
	//		columns = append(columns, []string{SPACE})
	//		t.cs[n] = t.mW
	//	}
	//}

	// Pad Each Height
	// pads := []int{}
	pads := []int{}

	for i, line := range columns {
		length := len(line)
		pad := max - length
		pads = append(pads, pad)
		for n := 0; n < pad; n++ {
			columns[i] = append(columns[i], "  ")
		}
	}
	//fmt.Println(max, "\n")
	for x := 0; x < max; x++ {
		for y := 0; y < total; y++ {

			// Check if border is set
			fmt.Fprint(t.out, ConditionString((!t.borders.Left && y == 0), SPACE, t.pColumn))

			fmt.Fprintf(t.out, SPACE)
			str := columns[y][x]

			// This would print alignment
			// Default alignment  would use multiple configuration
			switch t.align {
			case ALIGN_CENTER: //
				fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y]))
			case ALIGN_RIGHT:
				fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y]))
			case ALIGN_LEFT:
				fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))
			default:
				if decimal.MatchString(strings.TrimSpace(str)) || percent.MatchString(strings.TrimSpace(str)) {
					fmt.Fprintf(t.out, "%s", PadLeft(str, SPACE, t.cs[y]))
				} else {
					fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))

					// TODO Custom alignment per column
					//if max == 1 || pads[y] > 0 {
					//	fmt.Fprintf(t.out, "%s", Pad(str, SPACE, t.cs[y]))
					//} else {
					//	fmt.Fprintf(t.out, "%s", PadRight(str, SPACE, t.cs[y]))
					//}

				}
			}
			fmt.Fprintf(t.out, SPACE)
		}
		// Check if border is set
		// Replace with space if not set
		fmt.Fprint(t.out, ConditionString(t.borders.Left, t.pColumn, SPACE))
		fmt.Fprintln(t.out)
	}

	if t.rowLine {
		t.printLine(true)
	}

}

func (t *Table) parseDimension(str string, colKey, rowKey int) []string {
	var (
		raw []string
		max int
	)
	w := DisplayWidth(str)
	// Calculate Width
	// Check if with is grater than maximum width
	if w > t.mW {
		w = t.mW
	}

	// Check if width exists
	v, ok := t.cs[colKey]
	if !ok || v < w || v == 0 {
		t.cs[colKey] = w
	}

	if rowKey == -1 {
		return raw
	}
	// Calculate Height
	if t.autoWrap {
		raw, _ = WrapString(str, t.cs[colKey])
	} else {
		raw = getLines(str)
	}

	for _, line := range raw {
		if w := DisplayWidth(line); w > max {
			max = w
		}
	}

	// Make sure the with is the same length as maximum word
	// Important for cases where the width is smaller than maxu word
	if max > t.cs[colKey] {
		t.cs[colKey] = max
	}

	h := len(raw)
	v, ok = t.rs[rowKey]

	if !ok || v < h || v == 0 {
		t.rs[rowKey] = h
	}
	//fmt.Printf("Raw %+v %d\n", raw, len(raw))
	return raw
}
<|endoftext|>


<commit_before>package main

import (
	// "encoding/hex"
	"fmt"
	"time"
	"math/big"
	"github.com/PointCoin/btcutil"
	"github.com/PointCoin/btcwire"
	"github.com/PointCoin/btcrpcclient"
	"github.com/PointCoin/btcjson"

	// "strings"
	// "regexp"
	// "math/rand"
	// "log"
)
// func workerWork() {
// 	for {
// 		fmt.Println("hashing")
// 		time.Sleep(time.Second * 3)

// 	}
// }
func main() {

	// var maxNonce uint32 = 4294967294
	// _ = maxNonce
	client := GetClient()
	for {
		template := GetTemplate(client)
		block,difficulty := SetUpBlock(template)

		newTemplateChan := make(chan bool, 1)
		done := make(chan bool, 1)
		go FindValidBlock(newTemplateChan, done, block,difficulty,client)
		go TemplateChecker(newTemplateChan, template, client)

		<- done
	}

}

func TemplateChecker(newTemplateChan chan bool, template *btcjson.GetBlockTemplateResult, client *btcrpcclient.Client) {
	prevHash := template.PreviousHash
	var sleepTime time.Duration = 30

	for i := 0; i < 100000000; i++ {
		time.Sleep(time.Second * sleepTime)
		otherTemplate := GetTemplate(client)
		if prevHash != otherTemplate.PreviousHash {
			fmt.Println("New Template, sending reset signal")
			newTemplateChan <- true
			return
		}
	}

}

func FindValidBlock(newTemplateChan chan bool, done chan bool, block *btcwire.MsgBlock, difficulty big.Int, client *btcrpcclient.Client) {
	hashesThenCheck := 1000000
	loops := 0
	for {
		select {
		case <- newTemplateChan:
			fmt.Println("New Template detected before we found block. Resetting...")
			done <- true
			return
		default:
			for i := 0; i < hashesThenCheck; i++ {
				blockSha, _ := block.Header.BlockSha()

				if lessThanDiff(blockSha, difficulty) {
					// submit block
					print("Valid hash found. Submitting.")
					err := client.SubmitBlock(btcutil.NewBlock(block), nil)
					print(err)
					done <- true
					return
				} else {
					if block.Header.Nonce == 4294967294 {
						block.Header.Nonce = 0
					} else {
						block.Header.Nonce += 1
					}
				}
			}
			loops += 1
			fmt.Println(hashesThenCheck*loops, "hashes done. Checking for new template")
		}

	}
}

<commit_msg>timer added<commit_after>package main

import (
	// "encoding/hex"
	"fmt"
	"time"
	"math/big"
	"github.com/PointCoin/btcutil"
	"github.com/PointCoin/btcwire"
	"github.com/PointCoin/btcrpcclient"
	"github.com/PointCoin/btcjson"

	// "strings"
	// "regexp"
	// "math/rand"
	// "log"
)
// func workerWork() {
// 	for {
// 		fmt.Println("hashing")
// 		time.Sleep(time.Second * 3)

// 	}
// }
func main() {

	// var maxNonce uint32 = 4294967294
	// _ = maxNonce
	client := GetClient()
	for {
		template := GetTemplate(client)
		block,difficulty := SetUpBlock(template)

		newTemplateChan := make(chan bool, 1)
		done := make(chan bool, 1)
		go FindValidBlock(newTemplateChan, done, block,difficulty,client)
		go TemplateChecker(newTemplateChan, template, client)

		<- done
	}

}

func TemplateChecker(newTemplateChan chan bool, template *btcjson.GetBlockTemplateResult, client *btcrpcclient.Client) {
	prevHash := template.PreviousHash
	var sleepTime time.Duration = 30

	for i := 0; i < 100000000; i++ {
		time.Sleep(time.Second * sleepTime)
		otherTemplate := GetTemplate(client)
		if prevHash != otherTemplate.PreviousHash {
			fmt.Println("New Template, sending reset signal")
			newTemplateChan <- true
			return
		}
	}

}

func FindValidBlock(newTemplateChan chan bool, done chan bool, block *btcwire.MsgBlock, difficulty big.Int, client *btcrpcclient.Client) {
	hashesThenCheck := 1000000
	loops := 0
	for {
		select {
		case <- newTemplateChan:
			fmt.Println("New Template detected before we found block. Resetting...")
			done <- true
			return
		default:
			timeStart := time.Now().Nanosecond()
			for i := 0; i < hashesThenCheck; i++ {
				blockSha, _ := block.Header.BlockSha()

				if lessThanDiff(blockSha, difficulty) {
					// submit block
					print("Valid hash found. Submitting.")
					err := client.SubmitBlock(btcutil.NewBlock(block), nil)
					print(err)
					done <- true
					return
				} else {
					if block.Header.Nonce == 4294967294 {
						block.Header.Nonce = 0
					} else {
						block.Header.Nonce += 1
					}
				}
			}
			timeFinish := time.Now().Nanosecond()
			elapsedTime := timeFinish - timeStart

			nanoSecondsPerHash := elapsedTime / hashesThenCheck

			fmt.Println("nanoseconds per hash:", nanoSecondsPerHash)

			loops += 1
			fmt.Println(hashesThenCheck*loops, "hashes done. Checking for new template")
		}

	}
}

<|endoftext|>


<commit_before>package cruncy

import (
	"fmt"
	"sync"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/renstrom/shortuuid"
)

// TimerData containes run time data
type TimerData struct {
	Title          string
	Uuid           string
	StartTimeRun   time.Time
	StartTimeBatch time.Time
	EndTimeRun     time.Time

	BatchSize  int64
	PrevRows   int64
	Index      int64
	ErrorCount int64
	mu         sync.RWMutex
	muShow     sync.RWMutex
}

// NewTimer creates a new timer struct
func NewTimer(title string) *TimerData {
	timer := &TimerData{}
	timer.Title = title
	timer.Uuid = shortuuid.New()
	timer.StartTimeRun = time.Now()
	timer.StartTimeBatch = timer.StartTimeRun
	timer.PrevRows = 0
	timer.ErrorCount = 0
	return timer
}

// BatchDuractionSeconds returns durection in seconds
func (timer TimerData) BatchDuractionSeconds() int64 {
	t1 := time.Now()
	var duration time.Duration = t1.Sub(timer.StartTimeBatch)
	return int64(duration.Seconds())
}

func (timer TimerData) TotalDuractionSeconds() int64 {
	t1 := time.Now()
	var duration time.Duration = t1.Sub(timer.StartTimeRun)
	return int64(duration.Seconds())
}

func (timer TimerData) TotalDuration() time.Duration {
	t1 := time.Now()
	return t1.Sub(timer.StartTimeRun)
}

func (timer TimerData) ShowTotalDuration() {
	duration := timer.TotalDuration()
	ds := timer.TotalDuractionSeconds()
	if ds > 0 {
		msg := fmt.Sprintf("Total duration:, %v rows =%d row time=%d rows/sec ", duration, timer.Index, timer.Index/ds)
		log.WithFields(log.Fields{
			"uuid":       timer.Uuid,
			"title":      timer.Title,
			"index":      timer.Index,
			"total_flow": timer.Index / ds,
			"State":      "stopped",
		}).Info(msg)
	} else {
		log.WithFields(log.Fields{
			"uuid":       timer.Uuid,
			"title":      timer.Title,
			"index":      timer.Index,
			"total_flow": timer.Index,
			"State":      "stopped",
		}).Infof("Total duration:, %v rows =%d  SUPER FAST", duration, timer.Index)

	}
}

func (timer *TimerData) ShowBatchTime() {
	timer.muShow.RLock() // Claim the mutex as a RLock - allowing multiple go routines to log simultaneously
	defer timer.muShow.RUnlock()

	diff := timer.Index - timer.PrevRows

	t1 := time.Now()
	var duration time.Duration = t1.Sub(timer.StartTimeBatch)
	var d2 time.Duration = timer.TotalDuration()

	ds := int64(d2.Seconds())
	ds_batch := int64(duration.Seconds())

	if ds > 0 && ds_batch > 0 {
		msg := fmt.Sprintf("%d rows avg flow %d/s - batch time %v batch size %d batch_flow %d \n", timer.Index, timer.Index/ds, duration, diff, diff/ds_batch)
		log.WithFields(log.Fields{
			"uuid":       timer.Uuid,
			"title":      timer.Title,
			"index":      timer.Index,
			"total_flow": timer.Index / ds,
			"batch_time": duration,
			"batch_size": diff,
			"batch_flow": diff / ds_batch,
			"State":      "in_batch",
		}).Info(msg)
	} else {
		log.Printf("%d rows - batch time %v \n", timer.Index, duration)
	}
	timer.PrevRows = timer.Index
	timer.StartTimeBatch = time.Now()

}

func (timer *TimerData) Tick() {
	timer.mu.RLock() // Claim the mutex as a RLock - allowing multiple go routines to log simultaneously
	defer timer.mu.RUnlock()

	timer.Index++

	if timer.Index%100000 == 0 {
		timer.ShowBatchTime()
	}
}

func (timer *TimerData) Stop() time.Time {
	timer.EndTimeRun = time.Now()
	return timer.EndTimeRun
}

func (timer *TimerData) IncError() int64 {
	timer.ErrorCount++
	return timer.ErrorCount
}
<commit_msg>Moving to lowercase sirupsen<commit_after>package cruncy

import (
	"fmt"
	"sync"
	"time"

	"github.com/renstrom/shortuuid"
	log "github.com/sirupsen/logrus"
)

// TimerData containes run time data
type TimerData struct {
	Title          string
	Uuid           string
	StartTimeRun   time.Time
	StartTimeBatch time.Time
	EndTimeRun     time.Time

	BatchSize  int64
	PrevRows   int64
	Index      int64
	ErrorCount int64
	mu         sync.RWMutex
	muShow     sync.RWMutex
}

// NewTimer creates a new timer struct
func NewTimer(title string) *TimerData {
	timer := &TimerData{}
	timer.Title = title
	timer.Uuid = shortuuid.New()
	timer.StartTimeRun = time.Now()
	timer.StartTimeBatch = timer.StartTimeRun
	timer.PrevRows = 0
	timer.ErrorCount = 0
	return timer
}

// BatchDuractionSeconds returns durection in seconds
func (timer TimerData) BatchDuractionSeconds() int64 {
	t1 := time.Now()
	var duration time.Duration = t1.Sub(timer.StartTimeBatch)
	return int64(duration.Seconds())
}

func (timer TimerData) TotalDuractionSeconds() int64 {
	t1 := time.Now()
	var duration time.Duration = t1.Sub(timer.StartTimeRun)
	return int64(duration.Seconds())
}

func (timer TimerData) TotalDuration() time.Duration {
	t1 := time.Now()
	return t1.Sub(timer.StartTimeRun)
}

func (timer TimerData) ShowTotalDuration() {
	duration := timer.TotalDuration()
	ds := timer.TotalDuractionSeconds()
	if ds > 0 {
		msg := fmt.Sprintf("Total duration:, %v rows =%d row time=%d rows/sec ", duration, timer.Index, timer.Index/ds)
		log.WithFields(log.Fields{
			"uuid":       timer.Uuid,
			"title":      timer.Title,
			"index":      timer.Index,
			"total_flow": timer.Index / ds,
			"State":      "stopped",
		}).Info(msg)
	} else {
		log.WithFields(log.Fields{
			"uuid":       timer.Uuid,
			"title":      timer.Title,
			"index":      timer.Index,
			"total_flow": timer.Index,
			"State":      "stopped",
		}).Infof("Total duration:, %v rows =%d  SUPER FAST", duration, timer.Index)

	}
}

func (timer *TimerData) ShowBatchTime() {
	timer.muShow.RLock() // Claim the mutex as a RLock - allowing multiple go routines to log simultaneously
	defer timer.muShow.RUnlock()

	diff := timer.Index - timer.PrevRows

	t1 := time.Now()
	var duration time.Duration = t1.Sub(timer.StartTimeBatch)
	var d2 time.Duration = timer.TotalDuration()

	ds := int64(d2.Seconds())
	ds_batch := int64(duration.Seconds())

	if ds > 0 && ds_batch > 0 {
		msg := fmt.Sprintf("%d rows avg flow %d/s - batch time %v batch size %d batch_flow %d \n", timer.Index, timer.Index/ds, duration, diff, diff/ds_batch)
		log.WithFields(log.Fields{
			"uuid":       timer.Uuid,
			"title":      timer.Title,
			"index":      timer.Index,
			"total_flow": timer.Index / ds,
			"batch_time": duration,
			"batch_size": diff,
			"batch_flow": diff / ds_batch,
			"State":      "in_batch",
		}).Info(msg)
	} else {
		log.Printf("%d rows - batch time %v \n", timer.Index, duration)
	}
	timer.PrevRows = timer.Index
	timer.StartTimeBatch = time.Now()

}

func (timer *TimerData) Tick() {
	timer.mu.RLock() // Claim the mutex as a RLock - allowing multiple go routines to log simultaneously
	defer timer.mu.RUnlock()

	timer.Index++

	if timer.Index%100000 == 0 {
		timer.ShowBatchTime()
	}
}

func (timer *TimerData) Stop() time.Time {
	timer.EndTimeRun = time.Now()
	return timer.EndTimeRun
}

func (timer *TimerData) IncError() int64 {
	timer.ErrorCount++
	return timer.ErrorCount
}
<|endoftext|>


<commit_before>package eparser

type tokenType int

const (
	ILLEGAL tokenType = iota
	EOL

	literalsBegin
	IDENT // x
	INT   // 3
	FLOAT // 3.14
	literalsEnd

	operatorsBegin
	ADD // +
	SUB // -
	DIV // /
	MUL // *
	POW // **
	REM // %

	AND // &
	OR  // |
	XOR // ^
	LSH // <<
	RSH // >>
	NOT // ~

	EQ     // =
	ADD_EQ // +=
	SUB_EQ // -=
	DIV_EQ // /=
	MUL_EQ // *=
	POW_EQ // **=
	REM_EQ // %=

	AND_EQ // &=
	OR_EQ  // |=
	XOR_EQ // ^=
	LSH_EQ // <<=
	RSH_EQ // >>=
	operatorsEnd

	LPAREN // (
	RPAREN // )

	TOKEN_COUNT
)

var tokens = [...]string{
	ILLEGAL: "ILLEGAL",
	EOL:     "EOL",

	IDENT: "IDENT",
	INT:   "INT",
	FLOAT: "FLOAT",

	ADD: "+",
	SUB: "-",
	DIV: "/",
	MUL: "*",
	POW: "**",
	REM: "%",

	AND: "&",
	OR:  "|",
	XOR: "^",
	LSH: "<<",
	RSH: ">>",
	NOT: "~",

	EQ:     "=",
	ADD_EQ: "+=",
	SUB_EQ: "-=",
	DIV_EQ: "/=",
	MUL_EQ: "*=",
	POW_EQ: "**=",
	REM_EQ: "%=",

	LPAREN: "(",
	RPAREN: ")",
}

// Token is an entity in an expression
type Token struct {
	Type  tokenType
	Value string
	Pos   int
}

func newToken(toktype tokenType, val string, pos int) *Token {
	return &Token{
		Type:  toktype,
		Value: val,
		Pos:   pos,
	}
}

func (tok *Token) String() string {
	if tok.Type < TOKEN_COUNT {
		return tokens[tok.Type]
	}

	return "???"
}

// IsOperator checks if the token is an operator
func (tok *Token) IsOperator() bool {
	return tok.Type > operatorsBegin && tok.Type < operatorsEnd
}

// IsLiteral checks if the token is a literal
func (tok *Token) IsLiteral() bool {
	return tok.Type > literalsBegin && tok.Type < literalsEnd
}
<commit_msg>Add strings for new equal operators<commit_after>package eparser

type tokenType int

const (
	ILLEGAL tokenType = iota
	EOL

	literalsBegin
	IDENT // x
	INT   // 3
	FLOAT // 3.14
	literalsEnd

	operatorsBegin
	ADD // +
	SUB // -
	DIV // /
	MUL // *
	POW // **
	REM // %

	AND // &
	OR  // |
	XOR // ^
	LSH // <<
	RSH // >>
	NOT // ~

	EQ     // =
	ADD_EQ // +=
	SUB_EQ // -=
	DIV_EQ // /=
	MUL_EQ // *=
	POW_EQ // **=
	REM_EQ // %=

	AND_EQ // &=
	OR_EQ  // |=
	XOR_EQ // ^=
	LSH_EQ // <<=
	RSH_EQ // >>=
	operatorsEnd

	LPAREN // (
	RPAREN // )

	TOKEN_COUNT
)

var tokens = [...]string{
	ILLEGAL: "ILLEGAL",
	EOL:     "EOL",

	IDENT: "IDENT",
	INT:   "INT",
	FLOAT: "FLOAT",

	ADD: "+",
	SUB: "-",
	DIV: "/",
	MUL: "*",
	POW: "**",
	REM: "%",

	AND: "&",
	OR:  "|",
	XOR: "^",
	LSH: "<<",
	RSH: ">>",
	NOT: "~",

	EQ:     "=",
	ADD_EQ: "+=",
	SUB_EQ: "-=",
	DIV_EQ: "/=",
	MUL_EQ: "*=",
	POW_EQ: "**=",
	REM_EQ: "%=",

	AND_EQ: "&=",
	OR_EQ:  "|=",
	XOR_EQ: "^=",
	LSH_EQ: "<<=",
	RSH_EQ: ">>=",

	LPAREN: "(",
	RPAREN: ")",
}

// Token is an entity in an expression
type Token struct {
	Type  tokenType
	Value string
	Pos   int
}

func newToken(toktype tokenType, val string, pos int) *Token {
	return &Token{
		Type:  toktype,
		Value: val,
		Pos:   pos,
	}
}

func (tok *Token) String() string {
	if tok.Type < TOKEN_COUNT {
		return tokens[tok.Type]
	}

	return "???"
}

// IsOperator checks if the token is an operator
func (tok *Token) IsOperator() bool {
	return tok.Type > operatorsBegin && tok.Type < operatorsEnd
}

// IsLiteral checks if the token is a literal
func (tok *Token) IsLiteral() bool {
	return tok.Type > literalsBegin && tok.Type < literalsEnd
}
<|endoftext|>


<commit_before>/*
Copyright 2015 Gravitational, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package trace implements utility functions for capturing debugging
// information about file and line in error reports and logs.
package trace

import (
	"encoding/json"
	"fmt"
	"path/filepath"
	"runtime"
	"strings"
	"sync/atomic"
)

var debug int32

// SetDebug turns on/off debugging mode, that causes Fatalf to panic
func SetDebug(enabled bool) {
	if enabled {
		atomic.StoreInt32(&debug, 1)
	} else {
		atomic.StoreInt32(&debug, 0)
	}
}

// IsDebug returns true if debug mode is on, false otherwize
func IsDebug() bool {
	return atomic.LoadInt32(&debug) == 1
}

// Wrap takes the original error and wraps it into the Trace struct
// memorizing the context of the error.
func Wrap(err error, args ...interface{}) Error {
	return wrap(err, 2, args...)
}

// Unwrap unwraps error to it's original error
func Unwrap(err error) error {
	if terr, ok := err.(Error); ok {
		return terr.OrigError()
	}
	return err
}

func wrap(err error, depth int, args ...interface{}) Error {
	if err == nil {
		return nil
	}

	t := newTrace(runtime.Caller(depth))
	if s, ok := err.(TraceSetter); ok {
		s.SetTraces(t.Traces...)
		return s
	}
	t.Err = err
	if len(args) != 0 {
		t.Message = fmt.Sprintf(fmt.Sprintf("%v", args[0]), args[1:]...)
	}
	return t
}

// Errorf is similar to fmt.Errorf except that it captures
// more information about the origin of error, such as
// callee, line number and function that simplifies debugging
func Errorf(format string, args ...interface{}) error {
	t := newTrace(runtime.Caller(1))
	t.Err = fmt.Errorf(format, args...)
	return t
}

// Fatalf - If debug is false Fatalf calls Errorf. If debug is
// true Fatalf calls panic
func Fatalf(format string, args ...interface{}) error {
	if IsDebug() {
		panic(fmt.Sprintf(format, args))
	} else {
		return Errorf(format, args)
	}
}

func newTrace(pc uintptr, filePath string, line int, ok bool) *TraceErr {
	if !ok {
		return &TraceErr{
			nil,
			Traces{
				{
					Path: "unknown_path",
					Func: "unknown_func",
					Line: 0,
				}},
			"",
		}
	}
	return &TraceErr{
		nil,
		Traces{{
			Path: filePath,
			Func: runtime.FuncForPC(pc).Name(),
			Line: line,
		}},
		"",
	}
}

// Traces is a list of trace entries
type Traces []Trace

// SetTraces adds new traces to the list
func (s *Traces) SetTraces(traces ...Trace) {
	*s = append(*s, traces...)
}

// Func returns first function in trace list
func (s *Traces) Func() string {
	if len(*s) == 0 {
		return ""
	}
	return (*s)[0].Func
}

// String returns debug-friendly representaton of traces
func (s Traces) String() string {
	if len(s) == 0 {
		return ""
	}
	out := make([]string, len(s))
	for i, t := range s {
		out[i] = t.String()
	}
	return strings.Join(out, ",")
}

// Trace stores structured trace entry, including file line and path
type Trace struct {
	// Path is a full file path
	Path string `json:"path"`
	// Func is a function name
	Func string `json:"func"`
	// Line is a code line number
	Line int `json:"line"`
}

// String returns debug-friendly representation of this trace
func (t *Trace) String() string {
	dir, file := filepath.Split(t.Path)
	dirs := strings.Split(filepath.ToSlash(filepath.Clean(dir)), "/")
	if len(dirs) != 0 {
		file = filepath.Join(dirs[len(dirs)-1], file)
	}
	return fmt.Sprintf("%v:%v", file, t.Line)
}

// TraceErr contains error message and some additional
// information about the error origin
type TraceErr struct {
	Err     error `json:"error"`
	Traces  `json:"traces"`
	Message string `json:"message"`
}

type rawTrace struct {
	Err     json.RawMessage `json:"error"`
	Traces  `json:"traces"`
	Message string `json:"message"`
}

func (e *TraceErr) Error() string {
	if IsDebug() {
		return fmt.Sprintf("[%v] %v %v", e.Traces.String(), e.Message, e.Err.Error())
	}
	return e.Err.Error()
}

// OrigError returns original wrapped error
func (e *TraceErr) OrigError() error {
	err := e.Err
	// this is not an endless loop because I'm being
	// paranoid, this is a safe protection against endless
	// loops
	for i := 0; i < maxHops; i++ {
		newerr, ok := err.(Error)
		if !ok {
			break
		}
		if newerr.OrigError() != err {
			err = newerr.OrigError()
		}
	}
	return err
}

// maxHops is a max supported nested depth for errors
const maxHops = 50

// Error is an interface that helps to adapt usage of trace in the code
// When applications define new error types, they can implement the interface
// So error handlers can use OrigError() to retrieve error from the wrapper
type Error interface {
	error
	OrigError() error
}

// TraceSetter indicates that this error can store traces
type TraceSetter interface {
	Error
	SetTraces(...Trace)
}
<commit_msg>make sure message contains original error<commit_after>/*
Copyright 2015 Gravitational, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package trace implements utility functions for capturing debugging
// information about file and line in error reports and logs.
package trace

import (
	"encoding/json"
	"fmt"
	"path/filepath"
	"runtime"
	"strings"
	"sync/atomic"
)

var debug int32

// SetDebug turns on/off debugging mode, that causes Fatalf to panic
func SetDebug(enabled bool) {
	if enabled {
		atomic.StoreInt32(&debug, 1)
	} else {
		atomic.StoreInt32(&debug, 0)
	}
}

// IsDebug returns true if debug mode is on, false otherwize
func IsDebug() bool {
	return atomic.LoadInt32(&debug) == 1
}

// Wrap takes the original error and wraps it into the Trace struct
// memorizing the context of the error.
func Wrap(err error, args ...interface{}) Error {
	return wrap(err, 2, args...)
}

// Unwrap unwraps error to it's original error
func Unwrap(err error) error {
	if terr, ok := err.(Error); ok {
		return terr.OrigError()
	}
	return err
}

func wrap(err error, depth int, args ...interface{}) Error {
	if err == nil {
		return nil
	}

	t := newTrace(runtime.Caller(depth))
	if s, ok := err.(TraceSetter); ok {
		s.SetTraces(t.Traces...)
		return s
	}
	t.Err = err
	t.Message = err.Error()
	if len(args) != 0 {
		t.DebugMessage = fmt.Sprintf(fmt.Sprintf("%v", args[0]), args[1:]...)
	}
	return t
}

// Errorf is similar to fmt.Errorf except that it captures
// more information about the origin of error, such as
// callee, line number and function that simplifies debugging
func Errorf(format string, args ...interface{}) error {
	t := newTrace(runtime.Caller(1))
	t.Err = fmt.Errorf(format, args...)
	return t
}

// Fatalf - If debug is false Fatalf calls Errorf. If debug is
// true Fatalf calls panic
func Fatalf(format string, args ...interface{}) error {
	if IsDebug() {
		panic(fmt.Sprintf(format, args))
	} else {
		return Errorf(format, args)
	}
}

func newTrace(pc uintptr, filePath string, line int, ok bool) *TraceErr {
	if !ok {
		return &TraceErr{
			nil,
			Traces{
				{
					Path: "unknown_path",
					Func: "unknown_func",
					Line: 0,
				}},
			"",
			"",
		}
	}
	return &TraceErr{
		nil,
		Traces{{
			Path: filePath,
			Func: runtime.FuncForPC(pc).Name(),
			Line: line,
		}},
		"",
		"",
	}
}

// Traces is a list of trace entries
type Traces []Trace

// SetTraces adds new traces to the list
func (s *Traces) SetTraces(traces ...Trace) {
	*s = append(*s, traces...)
}

// Func returns first function in trace list
func (s *Traces) Func() string {
	if len(*s) == 0 {
		return ""
	}
	return (*s)[0].Func
}

// String returns debug-friendly representaton of traces
func (s Traces) String() string {
	if len(s) == 0 {
		return ""
	}
	out := make([]string, len(s))
	for i, t := range s {
		out[i] = t.String()
	}
	return strings.Join(out, ",")
}

// Trace stores structured trace entry, including file line and path
type Trace struct {
	// Path is a full file path
	Path string `json:"path"`
	// Func is a function name
	Func string `json:"func"`
	// Line is a code line number
	Line int `json:"line"`
}

// String returns debug-friendly representation of this trace
func (t *Trace) String() string {
	dir, file := filepath.Split(t.Path)
	dirs := strings.Split(filepath.ToSlash(filepath.Clean(dir)), "/")
	if len(dirs) != 0 {
		file = filepath.Join(dirs[len(dirs)-1], file)
	}
	return fmt.Sprintf("%v:%v", file, t.Line)
}

// TraceErr contains error message and some additional
// information about the error origin
type TraceErr struct {
	Err          error `json:"error"`
	Traces       `json:"traces"`
	Message      string `json:"message,omitemtpy"`
	DebugMessage string `json:"debug_message"`
}

type rawTrace struct {
	Err     json.RawMessage `json:"error"`
	Traces  `json:"traces"`
	Message string `json:"message"`
}

func (e *TraceErr) Error() string {
	if IsDebug() {
		return fmt.Sprintf("[%v] %v %v", e.Traces.String(), e.DebugMessage, e.Err.Error())
	}
	return e.Err.Error()
}

// OrigError returns original wrapped error
func (e *TraceErr) OrigError() error {
	err := e.Err
	// this is not an endless loop because I'm being
	// paranoid, this is a safe protection against endless
	// loops
	for i := 0; i < maxHops; i++ {
		newerr, ok := err.(Error)
		if !ok {
			break
		}
		if newerr.OrigError() != err {
			err = newerr.OrigError()
		}
	}
	return err
}

// maxHops is a max supported nested depth for errors
const maxHops = 50

// Error is an interface that helps to adapt usage of trace in the code
// When applications define new error types, they can implement the interface
// So error handlers can use OrigError() to retrieve error from the wrapper
type Error interface {
	error
	OrigError() error
}

// TraceSetter indicates that this error can store traces
type TraceSetter interface {
	Error
	SetTraces(...Trace)
}
<|endoftext|>


<commit_before>package bittrex

// Used in getmarkethistory
type Trade struct {
	OrderUuid string  `json:"OrderUuid"`
	Timestamp jTime   `json:"TimeStamp"`
	Quantity  float64 `json:"Quantity"`
	Price     float64 `json:"Price"`
	Total     float64 `json:"Total"`
	FillType  string  `json:"FillType"`
	OrderType string  `json:"OrderType"`
}
<commit_msg>Change json Tag for Trade struct from OrderUuid to Id for matching the current API<commit_after>package bittrex

// Used in getmarkethistory
type Trade struct {
	OrderUuid int64   `json:"Id"`
	Timestamp jTime   `json:"TimeStamp"`
	Quantity  float64 `json:"Quantity"`
	Price     float64 `json:"Price"`
	Total     float64 `json:"Total"`
	FillType  string  `json:"FillType"`
	OrderType string  `json:"OrderType"`
}
<|endoftext|>


<commit_before>package access

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/boltdb/bolt"
	"github.com/nilslice/jwt"

	"github.com/ponzu-cms/ponzu/system/admin/user"
	"github.com/ponzu-cms/ponzu/system/db"
)

const (
	apiAccessStore  = "__apiAccess"
	apiAccessCookie = "_apiAccessToken"
)

// APIAccess is the data for an API access grant
type APIAccess struct {
	Email string `json:"email"`
	Hash  string `json:"hash"`
	Salt  string `json:"salt"`
	Token string `json:"token"`
}

// Config contains settings for token creation and validation
type Config struct {
	ExpireAfter    time.Duration
	ResponseWriter http.ResponseWriter
	TokenStore     interface{}
}

func init() {
	db.AddBucket(apiAccessStore)
}

// Grant creates a new APIAccess and saves it to the __apiAccess bucket in the database
// and if an existing APIAccess grant is encountered in the database, Grant attempts
// to update the grant but will fail if unauthorized
func Grant(email, password string, cfg *Config) (*APIAccess, error) {
	if email == "" {
		return nil, fmt.Errorf("failed to create new APIAccess, %s", "email must not be empty")
	}

	if password == "" {
		return nil, fmt.Errorf("failed to create new APIAccess, %s", "password must not be empty")
	}

	u, err := user.New(email, password)
	if err != nil {
		return nil, fmt.Errorf("failed to create new APIAccess, %v", err)
	}

	apiAccess := &APIAccess{
		Email: u.Email,
		Hash:  u.Hash,
		Salt:  u.Salt,
	}

	err = setToken(apiAccess, cfg)
	if err != nil {
		return nil, err
	}

	err = db.Store().Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(apiAccessStore))
		if b == nil {
			return fmt.Errorf("failed to get bucket %s", apiAccessStore)
		}

		if b.Get([]byte(u.Email)) != nil {
			err := updateGrant(email, password, cfg)
			if err != nil {
				return fmt.Errorf("failed to update APIAccess grant for %s", u.Email)
			}
		}

		j, err := json.Marshal(u)
		if err != nil {
			return fmt.Errorf("failed to marshal APIAccess to json, %v", err)
		}

		return b.Put([]byte(u.Email), j)
	})

	if err != nil {
		return nil, err
	}

	return apiAccess, nil
}

// IsGranted checks if the user request is authenticated by the token held within
// the provided tokenStore (should be a http.Cookie or http.Header)
func IsGranted(req *http.Request, tokenStore interface{}) bool {
	token, err := getToken(req, tokenStore)
	if err != nil {
		log.Println("failed to get token to check API access grant")
		return false
	}

	return jwt.Passes(token)
}

// IsOwner validates the access token and checks the claims within the
// authenticated request's JWT for the email associated with the grant.
func IsOwner(req *http.Request, tokenStore interface{}, email string) bool {
	token, err := getToken(req, tokenStore)
	if err != nil {
		log.Println("failed to get token to check API access owner")
		return false
	}

	if !jwt.Passes(token) {
		return false
	}

	claims := jwt.GetClaims(token)
	if claims["email"].(string) != email {
		return false
	}

	return true
}

func updateGrant(email, password string, cfg *Config) error {
	var apiAccess *APIAccess
	err := db.Store().View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(apiAccessStore))
		if b == nil {
			return fmt.Errorf("failed to get %s bucket to update grant", apiAccessStore)
		}

		j := b.Get([]byte(email))
		return json.Unmarshal(j, apiAccess)
	})
	if err != nil {
		return fmt.Errorf("failed to get access grant to update grant, %v", err)
	}

	usr := &user.User{
		Email: apiAccess.Email,
		Hash:  apiAccess.Hash,
		Salt:  apiAccess.Salt,
	}

	if !user.IsUser(usr, password) {
		return fmt.Errorf(
			"unauthorized attempt to update grant for %s", apiAccess.Email,
		)
	}

	return nil
}

func getToken(req *http.Request, tokenStore interface{}) (string, error) {
	switch tokenStore.(type) {
	case http.Cookie:
		cookie, err := req.Cookie(apiAccessCookie)
		if err != nil {
			return "", err
		}

		return cookie.Value, nil

	case http.Header:
		bearer := req.Header.Get("Authorization")
		return strings.TrimPrefix(bearer, "Bearer "), nil

	default:
		return "", fmt.Errorf("failed to get token, %s", "unrecognized token store")
	}
}

func setToken(a *APIAccess, cfg *Config) error {
	exp := time.Now().Add(cfg.ExpireAfter)
	claims := map[string]interface{}{
		"exp":    exp.Unix(),
		"access": a.Email,
	}

	token, err := jwt.New(claims)
	if err != nil {
		return err
	}

	a.Token = token

	switch cfg.TokenStore.(type) {
	case http.Header:
		cfg.ResponseWriter.Header().Add("Authorization", "Bearer "+token)

	case http.Cookie:
		http.SetCookie(cfg.ResponseWriter, &http.Cookie{
			Name:    apiAccessCookie,
			Value:   token,
			Expires: exp,
			Path:    "/",
		})

	default:
		return fmt.Errorf("failed to set token, %s", "unrecognized token store")
	}

	return nil
}
<commit_msg>update interface name to be more useful<commit_after>package access

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/boltdb/bolt"
	"github.com/nilslice/jwt"

	"github.com/ponzu-cms/ponzu/system/admin/user"
	"github.com/ponzu-cms/ponzu/system/db"
)

const (
	apiAccessStore  = "__apiAccess"
	apiAccessCookie = "_apiAccessToken"
)

// APIAccess is the data for an API access grant
type APIAccess struct {
	Email string `json:"email"`
	Hash  string `json:"hash"`
	Salt  string `json:"salt"`
	Token string `json:"token"`
}

// Config contains settings for token creation and validation
type Config struct {
	ExpireAfter    time.Duration
	ResponseWriter http.ResponseWriter
	TokenStore     interface{}
}

type reqHeaderOrHTTPCookie interface{}

func init() {
	db.AddBucket(apiAccessStore)
}

// Grant creates a new APIAccess and saves it to the __apiAccess bucket in the database
// and if an existing APIAccess grant is encountered in the database, Grant attempts
// to update the grant but will fail if unauthorized
func Grant(email, password string, cfg *Config) (*APIAccess, error) {
	if email == "" {
		return nil, fmt.Errorf("failed to create new APIAccess, %s", "email must not be empty")
	}

	if password == "" {
		return nil, fmt.Errorf("failed to create new APIAccess, %s", "password must not be empty")
	}

	u, err := user.New(email, password)
	if err != nil {
		return nil, fmt.Errorf("failed to create new APIAccess, %v", err)
	}

	apiAccess := &APIAccess{
		Email: u.Email,
		Hash:  u.Hash,
		Salt:  u.Salt,
	}

	err = setToken(apiAccess, cfg)
	if err != nil {
		return nil, err
	}

	err = db.Store().Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(apiAccessStore))
		if b == nil {
			return fmt.Errorf("failed to get bucket %s", apiAccessStore)
		}

		if b.Get([]byte(u.Email)) != nil {
			err := updateGrant(email, password, cfg)
			if err != nil {
				return fmt.Errorf("failed to update APIAccess grant for %s", u.Email)
			}
		}

		j, err := json.Marshal(u)
		if err != nil {
			return fmt.Errorf("failed to marshal APIAccess to json, %v", err)
		}

		return b.Put([]byte(u.Email), j)
	})

	if err != nil {
		return nil, err
	}

	return apiAccess, nil
}

// IsGranted checks if the user request is authenticated by the token held within
// the provided tokenStore (should be a http.Cookie or http.Header)
func IsGranted(req *http.Request, tokenStore reqHeaderOrHTTPCookie) bool {
	token, err := getToken(req, tokenStore)
	if err != nil {
		log.Println("failed to get token to check API access grant")
		return false
	}

	return jwt.Passes(token)
}

// IsOwner validates the access token and checks the claims within the
// authenticated request's JWT for the email associated with the grant.
func IsOwner(req *http.Request, tokenStore reqHeaderOrHTTPCookie, email string) bool {
	token, err := getToken(req, tokenStore)
	if err != nil {
		log.Println("failed to get token to check API access owner")
		return false
	}

	if !jwt.Passes(token) {
		return false
	}

	claims := jwt.GetClaims(token)
	if claims["access"].(string) != email {
		return false
	}

	return true
}

func updateGrant(email, password string, cfg *Config) error {
	var apiAccess *APIAccess
	err := db.Store().View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(apiAccessStore))
		if b == nil {
			return fmt.Errorf("failed to get %s bucket to update grant", apiAccessStore)
		}

		j := b.Get([]byte(email))
		return json.Unmarshal(j, apiAccess)
	})
	if err != nil {
		return fmt.Errorf("failed to get access grant to update grant, %v", err)
	}

	usr := &user.User{
		Email: apiAccess.Email,
		Hash:  apiAccess.Hash,
		Salt:  apiAccess.Salt,
	}

	if !user.IsUser(usr, password) {
		return fmt.Errorf(
			"unauthorized attempt to update grant for %s", apiAccess.Email,
		)
	}

	return nil
}

func getToken(req *http.Request, tokenStore reqHeaderOrHTTPCookie) (string, error) {
	switch tokenStore.(type) {
	case http.Cookie:
		cookie, err := req.Cookie(apiAccessCookie)
		if err != nil {
			return "", err
		}

		return cookie.Value, nil

	case http.Header:
		bearer := req.Header.Get("Authorization")
		return strings.TrimPrefix(bearer, "Bearer "), nil

	default:
		return "", fmt.Errorf("failed to get token, %s", "unrecognized token store")
	}
}

func setToken(a *APIAccess, cfg *Config) error {
	exp := time.Now().Add(cfg.ExpireAfter)
	claims := map[string]interface{}{
		"exp":    exp.Unix(),
		"access": a.Email,
	}

	token, err := jwt.New(claims)
	if err != nil {
		return err
	}

	a.Token = token

	switch cfg.TokenStore.(type) {
	case http.Header:
		cfg.ResponseWriter.Header().Add("Authorization", "Bearer "+token)

	case http.Cookie:
		http.SetCookie(cfg.ResponseWriter, &http.Cookie{
			Name:    apiAccessCookie,
			Value:   token,
			Expires: exp,
			Path:    "/",
		})

	default:
		return fmt.Errorf("failed to set token, %s", "unrecognized token store")
	}

	return nil
}
<|endoftext|>


<commit_before>package rogue

import log "github.com/Sirupsen/logrus"

// Action ...
type Action interface {
	// returns true when finished performing action
	Perform(npc *Npc) bool
}

// Doing states
const (
	doingNothing = 0
	doingSleeping
	doingEating
	doingDrinking
	doingMoving
	doingForaging
)

type sleep struct {
}

func (a *sleep) Perform(n *Npc) bool {
	energyGain := 4

	log.Printf("%s is sleeping. tiredness = %d", n.Name, n.Tiredness)
	n.Tiredness -= energyGain
	if n.Tiredness < 0 {
		//log.Printf("%s woke up. tiredness = %d", n.Name, n.Tiredness)
		n.Tiredness = 0
		return true
	}
	return false
}

type lookForFood struct {
	timeSpentLooking int
}

func (a *lookForFood) Perform(n *Npc) bool {

	log.Println(n.Name, "is looking for food", a.timeSpentLooking)

	// TODO something more advanced for looking for food
	a.timeSpentLooking++
	if a.timeSpentLooking > 5 {

		// XXX?!?!  how to return a generic object ?!
		//food := getRandomFoodFrom(&n.Position)
		//var food sweetPotato

		food := island.randomItemOfType("food")
		log.Printf("%s found a %s", n.Name, food.Name)
		n.Inventory = append(n.Inventory, food)
		return true
	}

	return false
}

type lookForWater struct {
	timeSpentLooking int
}

func (a *lookForWater) Perform(n *Npc) bool {
	log.Println(n.Name, "is looking for water", a.timeSpentLooking)
	// TODO something more advanced for looking for food
	a.timeSpentLooking++
	if a.timeSpentLooking > 5 {
		// XXX reduce thirst by some amount from the water drunk
		n.Thirst = 0
		return true
	}

	return false
}
<commit_msg>minor tweaks<commit_after>package rogue

import log "github.com/Sirupsen/logrus"

// Action ...
type Action interface {
	// returns true when finished performing action
	Perform(npc *Npc) bool
}

// Doing states
const (
	doingNothing = 0
	doingSleeping
	doingEating
	doingDrinking
	doingMoving
	doingForaging
)

type sleep struct {
	timeSpent int
}

func (a *sleep) Perform(n *Npc) bool {
	energyGain := 4

	log.Printf("%s is sleeping. tiredness = %d", n.Name, n.Tiredness)
	a.timeSpent++
	n.Tiredness -= energyGain

	if n.Tiredness <= 0 {
		//log.Printf("%s woke up. tiredness = %d", n.Name, n.Tiredness)
		n.Tiredness = 0
		return true
	}

	if a.timeSpent > 60 {
		// never sleep more than 60 ticks
		return true
	}

	return false
}

type lookForFood struct {
	timeSpent int
}

func (a *lookForFood) Perform(n *Npc) bool {

	log.Println(n.Name, "is looking for food", a.timeSpent)

	// TODO something more advanced for looking for food
	a.timeSpent++
	if a.timeSpent > 5 {

		item := island.randomItemOfType("food")
		log.Printf("%s found a %s", n.Name, item.Name)
		n.Inventory = append(n.Inventory, item)
		return true
	}

	return false
}

type lookForWater struct {
	timeSpent int
}

func (a *lookForWater) Perform(n *Npc) bool {
	log.Println(n.Name, "is looking for water", a.timeSpent)

	// TODO something more advanced for looking for water
	a.timeSpent++
	if a.timeSpent > 5 {

		item := island.randomItemOfType("water")
		log.Printf("%s found a %s", n.Name, item.Name)
		n.Inventory = append(n.Inventory, item)

		return true
	}

	return false
}
<|endoftext|>