<commit_before>package internal

import (
	"math"
)

// Threshold is an adaptive error threshold.
type Threshold struct {
	Values []float64 // Threshold

	lower []float64
	upper []float64

	no uint
	εa float64
	εr float64
}

// NewThreshold creates an Threshold.
func NewThreshold(outputs uint, absolute, relative float64) *Threshold {
	return &Threshold{
		Values: make([]float64, outputs),

		lower: repeat(math.Inf(1.0), outputs),
		upper: repeat(math.Inf(-1.0), outputs),

		no: outputs,
		εa: absolute,
		εr: relative,
	}
}

// Reset resets the threshold.
func (self *Threshold) Reset() {
	*self = *NewThreshold(self.no, self.εa, self.εr)
}

// Update updates the threshold.
func (self *Threshold) Update(values []float64) {
	no := self.no
	for i, m := uint(0), uint(len(values)); i < m; i++ {
		j := i % no
		self.lower[j] = math.Min(self.lower[j], values[i])
		self.upper[j] = math.Max(self.upper[j], values[i])
	}
	for i := uint(0); i < no; i++ {
		self.Values[i] = math.Max(self.εa, self.εr*(self.upper[i]-self.lower[i]))
	}
}

func repeat(value float64, times uint) []float64 {
	values := make([]float64, times)
	for i := uint(0); i < times; i++ {
		values[i] = value
	}
	return values
}
<commit_msg>a/internal: fix a typo<commit_after>package internal

import (
	"math"
)

// Threshold is an adaptive error threshold.
type Threshold struct {
	Values []float64 // Threshold

	lower []float64
	upper []float64

	no uint
	εa float64
	εr float64
}

// NewThreshold creates a Threshold.
func NewThreshold(outputs uint, absolute, relative float64) *Threshold {
	return &Threshold{
		Values: make([]float64, outputs),

		lower: repeat(math.Inf(1.0), outputs),
		upper: repeat(math.Inf(-1.0), outputs),

		no: outputs,
		εa: absolute,
		εr: relative,
	}
}

// Reset resets the threshold.
func (self *Threshold) Reset() {
	*self = *NewThreshold(self.no, self.εa, self.εr)
}

// Update updates the threshold.
func (self *Threshold) Update(values []float64) {
	no := self.no
	for i, m := uint(0), uint(len(values)); i < m; i++ {
		j := i % no
		self.lower[j] = math.Min(self.lower[j], values[i])
		self.upper[j] = math.Max(self.upper[j], values[i])
	}
	for i := uint(0); i < no; i++ {
		self.Values[i] = math.Max(self.εa, self.εr*(self.upper[i]-self.lower[i]))
	}
}

func repeat(value float64, times uint) []float64 {
	values := make([]float64, times)
	for i := uint(0); i < times; i++ {
		values[i] = value
	}
	return values
}
<|endoftext|>


<commit_before>/*
Package traq implements helper methods for time tracking.
*/
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"regexp"
	"strings"
	"time"
)

// FilePath returns the path to a traq tracking file, taking the current
// env into account.
func FilePath(project string, date time.Time) (path string) {
	return fmt.Sprintf("%s/%s/%d/%d-%02d-%02d", os.Getenv("TRAQ_DATA_DIR"), project, date.Year(), date.Year(), date.Month(), date.Day())
}

// DatesInMonth calculates the days of a given month and year.
func DatesInMonth(year int, month int) []time.Time {
	var dates []time.Time = make([]time.Time, 0)
	var date time.Time = time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.UTC)

	for {
		dates = append(dates, date)
		date = date.Add(time.Hour * 24)
		if int(date.Month()) != month {
			break
		}
	}

	return dates
}

type LogLoader func(string) ([]string, error)

func ContentLoader(filePath string) ([]string, error) {
	content, err := ioutil.ReadFile(filePath)
	return strings.Split(string(content), "\n"), err
}

var stopLine = regexp.MustCompile(`;stop;`)

func RunningLoader(filePath string) ([]string, error) {
	content, err := ContentLoader(filePath)

	if err == nil {
		if stopLine.MatchString(content[len(content)-1]) {
			return content, err
		}

		var line = Entry(time.Now(), "stop")
		n := len(content)
		newContent := make([]string, n+1)
		copy(newContent, content)
		newContent[n] = line

		return newContent, err
	}

	return content, err
}

// SumFile evaluates the content of a traq tracking file.
// The returned map contains every tag contained in the file as well as the
// tracked duration in seconds.
func SumFile(lines []string) (map[string]int64, error) {
	var totalled map[string]int64 = make(map[string]int64)

	var currentTag string = ""
	var currentTime time.Time

	for _, line := range lines {
		if line != "" {
			var parts []string = strings.Split(line, ";")

			var t, error = time.Parse("Mon Jan 2 15:04:05 -0700 2006", parts[0])
			if error == nil {
				if parts[1] == "" {
					currentTag = parts[1]
					totalled[currentTag] = 0
				} else if parts[1] == "stop" {
					var diff = t.Unix() - currentTime.Unix()
					totalled[currentTag] = totalled[currentTag] + diff
					currentTag = ""
				} else if currentTag != parts[1] {
					var diff = t.Unix() - currentTime.Unix()
					totalled[currentTag] = totalled[currentTag] + diff
					currentTag = parts[1]
				}

				currentTime = t
			} else {
				return totalled, error
			}
		}
	}

	delete(totalled, "")

	return totalled, nil
}

type TraqHandler func(string, ...time.Time)

// PrintDate prints the content of a single traqfile, identified by the project identifer
// and its date
func PrintDate(project string, dates ...time.Time) {
	for _, date := range dates {
		content, err := ioutil.ReadFile(FilePath(project, date))

		if err == nil {
			fmt.Print(string(content))
			fmt.Println("%%")
		}
	}
}

func SummarizeDate(project string, dates ...time.Time) {
	var tags map[string]int64 = make(map[string]int64)
	for _, date := range dates {
		content, err := ioutil.ReadFile(FilePath(project, date))

		if err == nil {
			var totalled, _ = SumFile(strings.Split(string(content), "\n"))

			for key, value := range totalled {
				current, ok := tags[key]
				if !ok {
					tags[key] = value
				} else {
					tags[key] = value + current
				}
			}
		}
	}

	fmt.Printf("%4d-%02d-%02d\n", year, month, day)
	for key, value := range tags {
		fmt.Printf("%s:%2.4f\n", key, float64(value)/60.0/60.0)
	}
}

// EvaluateDate prints the evaluation of a single traqfile, identified by the project identifier
// and its date
func EvaluateDate(contentLoader LogLoader, project string, dates ...time.Time) {
	for _, date := range dates {
		var content, error = contentLoader(FilePath(project, date))

		if error == nil {
			fmt.Printf("%d-%02d-%02d\n", date.Year(), date.Month(), date.Day())
			var totalled, _ = SumFile(content)
			// TODO handle errors
			for key, value := range totalled {
				fmt.Printf("%s:%2.4f\n", key, float64(value)/60.0/60.0)
			}

			fmt.Println("%%")
		}
	}
}

func Entry(date time.Time, command string) string {
	return fmt.Sprintf("%s;%s;%s\n", date.Format("Mon Jan 2 15:04:05 -0700 2006"), command, "")
}

// WriteToFile writes a given command to a traq file, converting it into a tag
// if it's no known command.
func WriteToFile(project string, date time.Time, command string) {
	if command != "stop" {
		command = "#" + command
	}

	var traqFile string = FilePath(project, date)
	var projectDir string = path.Dir(traqFile)

	_ = os.MkdirAll(projectDir, os.ModeDir|os.ModePerm)
	var file, error = os.OpenFile(traqFile, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660)
	if error == nil {
		file.WriteString(Entry(date, command))
		file.Close()
	}
}

var (
	month    int
	year     int
	day      int
	project  string = "timestamps"
	date     string
	evaluate bool
	running  bool
	summary  bool
)

func main() {
	flag.BoolVar(&evaluate, "e", false, "evaluate tracked times")
	flag.BoolVar(&running, "r", false, "add fake stop entry to evaluate if stop is missing")
	flag.BoolVar(&summary, "s", false, "summaries the given timeframe")

	flag.IntVar(&year, "y", 0, "print tracked times for a given year")
	flag.IntVar(&month, "m", 0, "print tracked times for a given month")

	flag.StringVar(&date, "d", "", "print tracked times for a given date")
	flag.StringVar(&project, "p", "", "print data for a given project")

	flag.Parse()

	var now = time.Now()
	var t, error = time.Parse("2006-01-02", date)
	if error == nil {
		year = t.Year()
		month = int(t.Month())
		day = t.Day()
	} else {
		if month == 0 && year == 0 {
			day = now.Day()
		} else {
			day = 1
		}
		if year == 0 {
			year = now.Year()
		}
		if month == 0 {
			month = int(now.Month())
		}
	}

	var loader LogLoader = ContentLoader

	if running {
		loader = RunningLoader
	}

	if evaluate {
		if date == "" {
			EvaluateDate(loader, project, DatesInMonth(year, month)...)
		} else {
			EvaluateDate(loader, project, t)
		}
		return
	}

	var command string = flag.Arg(0)

	var handler TraqHandler = PrintDate
	if summary {
		handler = SummarizeDate
	}

	if command == "" {
		if date == "" {
			handler(project, DatesInMonth(year, month)...)
		} else {
			handler(project, t)
		}
	} else {
		WriteToFile(project, now, command)
	}
}
<commit_msg>use flags into func main<commit_after>/*
Package traq implements helper methods for time tracking.
*/
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"regexp"
	"strings"
	"time"
)

// FilePath returns the path to a traq tracking file, taking the current
// env into account.
func FilePath(project string, date time.Time) (path string) {
	return fmt.Sprintf("%s/%s/%d/%d-%02d-%02d", os.Getenv("TRAQ_DATA_DIR"), project, date.Year(), date.Year(), date.Month(), date.Day())
}

// DatesInMonth calculates the days of a given month and year.
func DatesInMonth(year int, month int) []time.Time {
	var dates []time.Time = make([]time.Time, 0)
	var date time.Time = time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.UTC)

	for {
		dates = append(dates, date)
		date = date.Add(time.Hour * 24)
		if int(date.Month()) != month {
			break
		}
	}

	return dates
}

type LogLoader func(string) ([]string, error)

func ContentLoader(filePath string) ([]string, error) {
	content, err := ioutil.ReadFile(filePath)
	return strings.Split(string(content), "\n"), err
}

var stopLine = regexp.MustCompile(`;stop;`)

func RunningLoader(filePath string) ([]string, error) {
	content, err := ContentLoader(filePath)

	if err == nil {
		if stopLine.MatchString(content[len(content)-1]) {
			return content, err
		}

		var line = Entry(time.Now(), "stop")
		n := len(content)
		newContent := make([]string, n+1)
		copy(newContent, content)
		newContent[n] = line

		return newContent, err
	}

	return content, err
}

// SumFile evaluates the content of a traq tracking file.
// The returned map contains every tag contained in the file as well as the
// tracked duration in seconds.
func SumFile(lines []string) (map[string]int64, error) {
	var totalled map[string]int64 = make(map[string]int64)

	var currentTag string = ""
	var currentTime time.Time

	for _, line := range lines {
		if line != "" {
			var parts []string = strings.Split(line, ";")

			var t, error = time.Parse("Mon Jan 2 15:04:05 -0700 2006", parts[0])
			if error == nil {
				if parts[1] == "" {
					currentTag = parts[1]
					totalled[currentTag] = 0
				} else if parts[1] == "stop" {
					var diff = t.Unix() - currentTime.Unix()
					totalled[currentTag] = totalled[currentTag] + diff
					currentTag = ""
				} else if currentTag != parts[1] {
					var diff = t.Unix() - currentTime.Unix()
					totalled[currentTag] = totalled[currentTag] + diff
					currentTag = parts[1]
				}

				currentTime = t
			} else {
				return totalled, error
			}
		}
	}

	delete(totalled, "")

	return totalled, nil
}

type TraqHandler func(string, ...time.Time)

// PrintDate prints the content of a single traqfile, identified by the project identifer
// and its date
func PrintDate(project string, dates ...time.Time) {
	for _, date := range dates {
		content, err := ioutil.ReadFile(FilePath(project, date))

		if err == nil {
			fmt.Print(string(content))
			fmt.Println("%%")
		}
	}
}

func SummarizeDate(project string, dates ...time.Time) {
	var tags map[string]int64 = make(map[string]int64)
	for _, date := range dates {
		content, err := ioutil.ReadFile(FilePath(project, date))

		if err == nil {
			var totalled, _ = SumFile(strings.Split(string(content), "\n"))

			for key, value := range totalled {
				current, ok := tags[key]
				if !ok {
					tags[key] = value
				} else {
					tags[key] = value + current
				}
			}
		}
	}

	date := dates[0]
	fmt.Printf("%4d-%02d-%02d\n", date.Year(), date.Month(), date.Day())
	for key, value := range tags {
		fmt.Printf("%s:%2.4f\n", key, float64(value)/60.0/60.0)
	}
}

// EvaluateDate prints the evaluation of a single traqfile, identified by the project identifier
// and its date
func EvaluateDate(contentLoader LogLoader, project string, dates ...time.Time) {
	for _, date := range dates {
		var content, error = contentLoader(FilePath(project, date))

		if error == nil {
			fmt.Printf("%d-%02d-%02d\n", date.Year(), date.Month(), date.Day())
			var totalled, _ = SumFile(content)
			// TODO handle errors
			for key, value := range totalled {
				fmt.Printf("%s:%2.4f\n", key, float64(value)/60.0/60.0)
			}

			fmt.Println("%%")
		}
	}
}

func Entry(date time.Time, command string) string {
	return fmt.Sprintf("%s;%s;%s\n", date.Format("Mon Jan 2 15:04:05 -0700 2006"), command, "")
}

// WriteToFile writes a given command to a traq file, converting it into a tag
// if it's no known command.
func WriteToFile(project string, date time.Time, command string) {
	if command != "stop" {
		command = "#" + command
	}

	var traqFile string = FilePath(project, date)
	var projectDir string = path.Dir(traqFile)

	_ = os.MkdirAll(projectDir, os.ModeDir|os.ModePerm)
	var file, error = os.OpenFile(traqFile, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660)
	if error == nil {
		file.WriteString(Entry(date, command))
		file.Close()
	}
}

func main() {
	var (
		month    = flag.Int("m", 0, "print tracked times for a given month")
		year     = flag.Int("y", 0, "print tracked times for a given year")
		project  = flag.String("p", "timestamps", "print data for a given project")
		date     = flag.String("d", "", "print tracked times for a given date")
		evaluate = flag.Bool("e", false, "evaluate tracked times")
		running  = flag.Bool("r", false, "add fake stop entry to evaluate if stop is missing")
		summary  = flag.Bool("s", false, "summaries the given timeframe")
	)

	flag.Parse()

	var now = time.Now()
	var t, error = time.Parse("2006-01-02", *date)
	if error == nil {
		*year = t.Year()
		*month = int(t.Month())
	} else {
		if *year == 0 {
			*year = now.Year()
		}
		if *month == 0 {
			*month = int(now.Month())
		}
	}

	var loader LogLoader = ContentLoader

	if *running {
		loader = RunningLoader
	}

	if *evaluate {
		if *date == "" {
			EvaluateDate(loader, *project, DatesInMonth(*year, *month)...)
		} else {
			EvaluateDate(loader, *project, t)
		}
		return
	}

	var command string = flag.Arg(0)

	var handler TraqHandler = PrintDate
	if *summary {
		handler = SummarizeDate
	}

	if command == "" {
		if *date == "" {
			handler(*project, DatesInMonth(*year, *month)...)
		} else {
			handler(*project, t)
		}
	} else {
		WriteToFile(*project, now, command)
	}
}
<|endoftext|>


<commit_before>// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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 trie implements a byte trie with edge compression.
package trie

import (
	"bytes"
	"fmt"
)

// A trie maintains a sorted collection of values keyed on a string.
///Insertion is O(len(key)). Unlike Go's built-in map there is no
// distinction between a nil and a non-existent value.
// The zero value for Trie is an empty trie ready to use.
type Trie struct {
	suffix   string
	value    interface{}
	children []Trie
	base     byte
}

// Find the largest i such that a[:i] == b[:i]
func commonPrefix(a, b string) int {
	l := len(a)
	if l > len(b) {
		l = len(b)
	}
	for i := 0; i < l; i++ {
		if a[i] != b[i] {
			return i
		}
	}
	return l
}

// Put inserts or replaces a value in the trie.  To remove a value
// insert nil.
func (t *Trie) Put(key string, value interface{}) {
	if t.children == nil && t.value == nil { // empty node
		t.suffix = key
		t.value = value
		return
	}

	s := commonPrefix(t.suffix, key)

	if s < len(t.suffix) {
		// split on s: turn t into a node with suffix[:s]
		// and move the contents to child[suffix[s]-t.base] with suffix[s+1:]
		*t = Trie{t.suffix[:s], nil, []Trie{{t.suffix[s+1:], t.value, t.children, t.base}}, t.suffix[s]}
	}

	if s == len(key) {
		t.value = value
		return
	}

	if len(t.children) == 0 {
		t.children = make([]Trie, 1)
		t.base = key[s]
	} else {
		newbase := t.base
		newlen := len(t.children)
		for key[s] < newbase || int(key[s]) >= int(newbase)+newlen {
			newlen *= 2
			newbase &= ^byte(newlen - 1)
		}
		if newlen != len(t.children) {
			newch := make([]Trie, newlen)
			copy(newch[t.base-newbase:], t.children)
			t.children = newch
			t.base = newbase
		}
	}

	t.children[key[s]-t.base].Put(key[s+1:], value)

	return
}

// Get retrieves an element from the trie if it exists, or nil if it does not.
func (t *Trie) Get(key string) interface{} {
	s := commonPrefix(t.suffix, key)

	if s < len(t.suffix) {
		return nil
	}

	if s == len(key) {
		return t.value
	}

	if key[s] < t.base || int(key[s]) > int(t.base)+len(t.children) {
		return nil
	}

	return t.children[key[s]-t.base].Get(key[s+1:])
}

func (t *Trie) forEach(f func(string, interface{}) bool, buf *bytes.Buffer) bool {
	if t.value == nil && t.children == nil {
		return true
	}

	pfx := buf.Len()
	buf.WriteString(t.suffix)

	if t.value != nil && !f(buf.String(), t.value) {
		return false
	}

	if t.children != nil {
		l := buf.Len()
		buf.WriteByte(t.base)
		for _, v := range t.children {
			if !v.forEach(f, buf) {
				return false
			}
			buf.Bytes()[l]++
		}
	}

	buf.Truncate(pfx)

	return true
}

// ForEach will apply the function f to each key, value pair in the
// Trie in sorted (depth-first pre-)order.  if f returns false, the
// iteration will stop.
func (t *Trie) ForEach(f func(string, interface{}) bool) {
	var buf bytes.Buffer
	t.forEach(f, &buf)
}

// String returns a multiline string representation of the trie
// in the form
//    trie[
//       key1: value1
//       key2: value2
//       ....
//    ]
func (t *Trie) String() string {
	var buf bytes.Buffer
	buf.WriteString("trie{\n")
	t.ForEach(func(key string, val interface{}) bool {
		fmt.Fprintf(&buf, "\t%s:%v\n", key, val)
		return true
	})
	buf.WriteString("}")
	return buf.String()
}

// debug
const spaces = "                                                                                "

func (t *Trie) dump(level int) {
	if level > len(spaces) {
		level = len(spaces)
	}
	fmt.Printf("%s: %v\n", t.suffix, t.value)
	if t.children != nil {
		fmt.Printf("%s<%d>\n", spaces[:4*level], len(t.children))
	}
	c := t.base
	for _, ch := range t.children {
		if ch.value != nil || ch.children != nil {
			if c >= 32 && c < 128 {
				fmt.Printf("%s['%c']", spaces[:4*level], c)
			} else {
				fmt.Printf("%s[%d]", spaces[:4*level], c)
			}
			ch.dump(level + 1)
		}
		c++
	}
}

func (t *Trie) shape() (ln, sz int) {
	if t.value != nil {
		ln++
	}
	sz++
	for _, c := range t.children {
		l, s := c.shape()
		ln += l
		sz += s
	}
	return
}
<commit_msg>remove stray slash in comment.<commit_after>// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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 trie implements a byte trie with edge compression.
package trie

import (
	"bytes"
	"fmt"
)

// A trie maintains a sorted collection of values keyed on a string.
// Insertion is O(len(key)). Unlike Go's built-in map there is no
// distinction between a nil and a non-existent value.
// The zero value for Trie is an empty trie ready to use.
type Trie struct {
	suffix   string
	value    interface{}
	children []Trie
	base     byte
}

// Find the largest i such that a[:i] == b[:i]
func commonPrefix(a, b string) int {
	l := len(a)
	if l > len(b) {
		l = len(b)
	}
	for i := 0; i < l; i++ {
		if a[i] != b[i] {
			return i
		}
	}
	return l
}

// Put inserts or replaces a value in the trie.  To remove a value
// insert nil.
func (t *Trie) Put(key string, value interface{}) {
	if t.children == nil && t.value == nil { // empty node
		t.suffix = key
		t.value = value
		return
	}

	s := commonPrefix(t.suffix, key)

	if s < len(t.suffix) {
		// split on s: turn t into a node with suffix[:s]
		// and move the contents to child[suffix[s]-t.base] with suffix[s+1:]
		*t = Trie{t.suffix[:s], nil, []Trie{{t.suffix[s+1:], t.value, t.children, t.base}}, t.suffix[s]}
	}

	if s == len(key) {
		t.value = value
		return
	}

	if len(t.children) == 0 {
		t.children = make([]Trie, 1)
		t.base = key[s]
	} else {
		newbase := t.base
		newlen := len(t.children)
		for key[s] < newbase || int(key[s]) >= int(newbase)+newlen {
			newlen *= 2
			newbase &= ^byte(newlen - 1)
		}
		if newlen != len(t.children) {
			newch := make([]Trie, newlen)
			copy(newch[t.base-newbase:], t.children)
			t.children = newch
			t.base = newbase
		}
	}

	t.children[key[s]-t.base].Put(key[s+1:], value)

	return
}

// Get retrieves an element from the trie if it exists, or nil if it does not.
func (t *Trie) Get(key string) interface{} {
	s := commonPrefix(t.suffix, key)

	if s < len(t.suffix) {
		return nil
	}

	if s == len(key) {
		return t.value
	}

	if key[s] < t.base || int(key[s]) > int(t.base)+len(t.children) {
		return nil
	}

	return t.children[key[s]-t.base].Get(key[s+1:])
}

func (t *Trie) forEach(f func(string, interface{}) bool, buf *bytes.Buffer) bool {
	if t.value == nil && t.children == nil {
		return true
	}

	pfx := buf.Len()
	buf.WriteString(t.suffix)

	if t.value != nil && !f(buf.String(), t.value) {
		return false
	}

	if t.children != nil {
		l := buf.Len()
		buf.WriteByte(t.base)
		for _, v := range t.children {
			if !v.forEach(f, buf) {
				return false
			}
			buf.Bytes()[l]++
		}
	}

	buf.Truncate(pfx)

	return true
}

// ForEach will apply the function f to each key, value pair in the
// Trie in sorted (depth-first pre-)order.  if f returns false, the
// iteration will stop.
func (t *Trie) ForEach(f func(string, interface{}) bool) {
	var buf bytes.Buffer
	t.forEach(f, &buf)
}

// String returns a multiline string representation of the trie
// in the form
//    trie[
//       key1: value1
//       key2: value2
//       ....
//    ]
func (t *Trie) String() string {
	var buf bytes.Buffer
	buf.WriteString("trie{\n")
	t.ForEach(func(key string, val interface{}) bool {
		fmt.Fprintf(&buf, "\t%s:%v\n", key, val)
		return true
	})
	buf.WriteString("}")
	return buf.String()
}

// debug
const spaces = "                                                                                "

func (t *Trie) dump(level int) {
	if level > len(spaces) {
		level = len(spaces)
	}
	fmt.Printf("%s: %v\n", t.suffix, t.value)
	if t.children != nil {
		fmt.Printf("%s<%d>\n", spaces[:4*level], len(t.children))
	}
	c := t.base
	for _, ch := range t.children {
		if ch.value != nil || ch.children != nil {
			if c >= 32 && c < 128 {
				fmt.Printf("%s['%c']", spaces[:4*level], c)
			} else {
				fmt.Printf("%s[%d]", spaces[:4*level], c)
			}
			ch.dump(level + 1)
		}
		c++
	}
}

func (t *Trie) shape() (ln, sz int) {
	if t.value != nil {
		ln++
	}
	sz++
	for _, c := range t.children {
		l, s := c.shape()
		ln += l
		sz += s
	}
	return
}
<|endoftext|>


<commit_before>package main

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

	"github.com/PuerkitoBio/goquery"
)

var (
	tunefindBaseUrl = "https://www.tunefind.com"
)

type TunefindSearcResult struct {
	RelUrl string
}

type TunefindSearcResults struct {
	Results []TunefindSearcResult
}

func (searchResult TunefindSearcResult) LinkType() string {
	urlTypeRegex, _ := regexp.Compile("^/([A-Za-z]*)/")
	urlType := urlTypeRegex.FindStringSubmatch(searchResult.RelUrl)[1]
	if urlType == "show" {
		return "tv"
	}
	return urlType
}

func LinkExists(url string) bool {
	var netClient = &http.Client{
		Timeout: time.Second * 10,
	}
	response, err := netClient.Get(url)
	if err != nil || response.StatusCode > 399 {
		return false
	}
	return true
}

func TunefindUrlFor(urlType string, queryItem string) string {
	urlType = strings.ToLower(urlType)
	queryItem = strings.ToLower(queryItem)

	if urlType == "movie" {
		return fmt.Sprintf("%s/movies/%s", tunefindBaseUrl, queryItem)
	} else if urlType == "tv" {
		return fmt.Sprintf("%s/show/%s", tunefindBaseUrl, queryItem)
	} else if urlType == "artist" {
		return fmt.Sprintf("%s/artist/%s", tunefindBaseUrl, queryItem)
	} else if urlType == "search" {
		return fmt.Sprintf("%s/search/site?q=%s", tunefindBaseUrl, queryItem)
	}
	return ""
}

func IsMovieOnTunefind(movie string) bool {
	movieUrl := TunefindUrlFor("movie", movie)
	return LinkExists(movieUrl)
}

func IsTvOnTunefind(show string) bool {
	showUrl := TunefindUrlFor("tv", show)
	return LinkExists(showUrl)
}

func IsArtistOnTunefind(artist string) bool {
	artistUrl := TunefindUrlFor("artist", artist)
	return LinkExists(artistUrl)
}

func GoqueryDocument(url string) *goquery.Document {
	doc, err := goquery.NewDocument(url)
	if err != nil {
		log.Fatal(err)
	}
	return doc
}

func GoqueryAttrsFrom(url string, goquerySelector string, attr string) (results TunefindSearcResults) {
	doc := GoqueryDocument(url)

	a_nodes := doc.Find(goquerySelector)
	results.Results = make([]TunefindSearcResult, a_nodes.Size())
	a_nodes.Each(func(i int, s *goquery.Selection) {
		var attrValue string
		var attrPresent bool
		if attr == "text" {
			attrValue = s.Text()
			attrPresent = (attrValue != "")
		} else {
			attrValue, attrPresent = s.Attr(attr)
		}
		if !attrPresent {
			s_html, _ := s.Html()
			log.Printf("[warn] %s\n", s_html)
		}

		results.Results[i] = TunefindSearcResult{RelUrl: attrValue}
	})
	return
}

func GoqueryHrefsFrom(url string, goquerySelector string) (results TunefindSearcResults) {
	return GoqueryAttrsFrom(url, goquerySelector, "href")
}

func GoqueryTextFrom(url string, goquerySelector string) (results TunefindSearcResults) {
	return GoqueryAttrsFrom(url, goquerySelector, "text")
}

func TunefindSearch(searchQuery string, searchType string) {
	fullUrl := TunefindUrlFor("search", searchQuery)
	goquerySelector := "div.row.tf-search-results a"
	for _, result := range GoqueryHrefsFrom(fullUrl, goquerySelector).Results {
		if searchType != result.LinkType() && searchType != "all" {
			continue
		}

		fmt.Println("[*]", result.RelUrl)
		if result.LinkType() == "tv" {
			TunefindTv(result.RelUrl)
		} else if result.LinkType() == "movie" {
			TunefindMovie(result.RelUrl)
		} else if result.LinkType() == "artist" {
			TunefindArtist(result.RelUrl)
		}
	}
}

func TunefindMovie(relUrl string) {
	fullUrl := fmt.Sprintf("%s%s", tunefindBaseUrl, relUrl)

	goquerySelector := "div.Tunefind__Content div.SongRow__center___1I0Cg h4.SongTitle__heading___3kxXK a"
	for _, result := range GoqueryHrefsFrom(fullUrl, goquerySelector).Results {
		fmt.Println(result.RelUrl)
	}
}

func TunefindTv(relUrl string) {
	fullUrl := fmt.Sprintf("%s%s", tunefindBaseUrl, relUrl)

	goquerySelector := "div.Tunefind__Content ul[aria-labelledby='season-dropdown'] a[role='menuitem']"
	for _, result := range GoqueryHrefsFrom(fullUrl, goquerySelector).Results {
		fmt.Println(result.RelUrl)
	}
}

func TunefindArtist(relUrl string) {
	fullUrl := fmt.Sprintf("%s%s", tunefindBaseUrl, relUrl)

	goquerySelector := "div.Tunefind__Content div.AppearanceRow__songInfoTitleBlock___3woDL div.AppearanceRow__songInfoTitle___38aKt"
	for _, result := range GoqueryTextFrom(fullUrl, goquerySelector).Results {
		fmt.Println(result.RelUrl)
	}
}

func main() {
	searchQuery := flag.String("search", "", "Item to search. (Required)")
	searchType := flag.String("type", "all", "default:all|movie|tv|artist")
	/*
		seasonIndex := flag.Int("season", 1, "which season if it's a tv type")
		episodeIndex := flag.Int("episode", 1, "which episode if it's a movie type")
	*/

	flag.Parse()

	if *searchQuery == "" {
		flag.PrintDefaults()
		os.Exit(1)
	}

	TunefindSearch(*searchQuery, *searchType)
}
<commit_msg>[tunefind] tv to season to episode to songs call with relUrl listing<commit_after>package main

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

	"github.com/PuerkitoBio/goquery"
)

var (
	tunefindBaseUrl = "https://www.tunefind.com"
)

type TunefindSearcResult struct {
	RelUrl string
}

type TunefindSearcResults struct {
	Results []TunefindSearcResult
}

func (searchResult TunefindSearcResult) LinkType() string {
	urlTypeRegex, _ := regexp.Compile("^/([A-Za-z]*)/")
	urlType := urlTypeRegex.FindStringSubmatch(searchResult.RelUrl)[1]
	if urlType == "show" {
		return "tv"
	}
	return urlType
}

func LinkExists(url string) bool {
	var netClient = &http.Client{
		Timeout: time.Second * 10,
	}
	response, err := netClient.Get(url)
	if err != nil || response.StatusCode > 399 {
		return false
	}
	return true
}

func TunefindUrlFor(urlType string, queryItem string) string {
	urlType = strings.ToLower(urlType)
	queryItem = strings.ToLower(queryItem)

	if urlType == "movie" {
		return fmt.Sprintf("%s/movies/%s", tunefindBaseUrl, queryItem)
	} else if urlType == "tv" {
		return fmt.Sprintf("%s/show/%s", tunefindBaseUrl, queryItem)
	} else if urlType == "artist" {
		return fmt.Sprintf("%s/artist/%s", tunefindBaseUrl, queryItem)
	} else if urlType == "search" {
		return fmt.Sprintf("%s/search/site?q=%s", tunefindBaseUrl, queryItem)
	}
	return ""
}

func IsMovieOnTunefind(movie string) bool {
	movieUrl := TunefindUrlFor("movie", movie)
	return LinkExists(movieUrl)
}

func IsTvOnTunefind(show string) bool {
	showUrl := TunefindUrlFor("tv", show)
	return LinkExists(showUrl)
}

func IsArtistOnTunefind(artist string) bool {
	artistUrl := TunefindUrlFor("artist", artist)
	return LinkExists(artistUrl)
}

func GoqueryDocument(url string) *goquery.Document {
	doc, err := goquery.NewDocument(url)
	if err != nil {
		log.Fatal(err)
	}
	return doc
}

func GoqueryAttrsFrom(url string, goquerySelector string, attr string) (results TunefindSearcResults) {
	doc := GoqueryDocument(url)

	a_nodes := doc.Find(goquerySelector)
	results.Results = make([]TunefindSearcResult, a_nodes.Size())
	a_nodes.Each(func(i int, s *goquery.Selection) {
		var attrValue string
		var attrPresent bool
		if attr == "text" {
			attrValue = s.Text()
			attrPresent = (attrValue != "")
		} else {
			attrValue, attrPresent = s.Attr(attr)
		}
		if !attrPresent {
			s_html, _ := s.Html()
			log.Printf("[warn] %s\n", s_html)
		}

		results.Results[i] = TunefindSearcResult{RelUrl: attrValue}
	})
	return
}

func GoqueryHrefsFrom(url string, goquerySelector string) (results TunefindSearcResults) {
	return GoqueryAttrsFrom(url, goquerySelector, "href")
}

func GoqueryTextFrom(url string, goquerySelector string) (results TunefindSearcResults) {
	return GoqueryAttrsFrom(url, goquerySelector, "text")
}

func TunefindSearch(searchQuery string, searchType string) {
	fullUrl := TunefindUrlFor("search", searchQuery)
	goquerySelector := "div.row.tf-search-results a"
	for _, result := range GoqueryHrefsFrom(fullUrl, goquerySelector).Results {
		if searchType != result.LinkType() && searchType != "all" {
			continue
		}

		fmt.Println("[*]", result.RelUrl)
		if result.LinkType() == "tv" {
			TunefindTv(result.RelUrl)
		} else if result.LinkType() == "movie" {
			TunefindMovie(result.RelUrl)
		} else if result.LinkType() == "artist" {
			TunefindArtist(result.RelUrl)
		}
	}
}

func TunefindMovie(relUrl string) {
	fullUrl := fmt.Sprintf("%s%s", tunefindBaseUrl, relUrl)

	goquerySelector := "div.Tunefind__Content div.SongRow__center___1I0Cg h4.SongTitle__heading___3kxXK a"
	for _, result := range GoqueryHrefsFrom(fullUrl, goquerySelector).Results {
		fmt.Println(result.RelUrl)
	}
}

func TunefindTvEpisodeSongs(relUrl string) {
	fullUrl := fmt.Sprintf("%s%s", tunefindBaseUrl, relUrl)

	goquerySelector := "div.Tunefind__Content div.SongRow__center___1I0Cg h4.SongTitle__heading___3kxXK a"
	for _, result := range GoqueryHrefsFrom(fullUrl, goquerySelector).Results {
		fmt.Println(result.RelUrl)
	}
}

func TunefindTvEpisodes(relUrl string) {
	fullUrl := fmt.Sprintf("%s%s", tunefindBaseUrl, relUrl)

	goquerySelector := "div.Tunefind__Content li.MainList__item___fZ13_ h3.EpisodeListItem__title___32XUR a"
	for _, result := range GoqueryHrefsFrom(fullUrl, goquerySelector).Results {
		TunefindTvEpisodeSongs(result.RelUrl)
	}
}

func TunefindTv(relUrl string) {
	fullUrl := fmt.Sprintf("%s%s", tunefindBaseUrl, relUrl)

	goquerySelector := "div.Tunefind__Content ul[aria-labelledby='season-dropdown'] a[role='menuitem']"
	for _, result := range GoqueryHrefsFrom(fullUrl, goquerySelector).Results {
		TunefindTvEpisodes(result.RelUrl)
	}
}

func TunefindArtist(relUrl string) {
	fullUrl := fmt.Sprintf("%s%s", tunefindBaseUrl, relUrl)

	goquerySelector := "div.Tunefind__Content div.AppearanceRow__songInfoTitleBlock___3woDL div.AppearanceRow__songInfoTitle___38aKt"
	for _, result := range GoqueryTextFrom(fullUrl, goquerySelector).Results {
		fmt.Println(result.RelUrl)
	}
}

func main() {
	searchQuery := flag.String("search", "", "Item to search. (Required)")
	searchType := flag.String("type", "all", "default:all|movie|tv|artist")
	/*
		seasonIndex := flag.Int("season", 1, "which season if it's a tv type")
		episodeIndex := flag.Int("episode", 1, "which episode if it's a movie type")
	*/

	flag.Parse()

	if *searchQuery == "" {
		flag.PrintDefaults()
		os.Exit(1)
	}

	TunefindSearch(*searchQuery, *searchType)
}
<|endoftext|>


<commit_before>package gompatible

import (
	_ "golang.org/x/tools/go/gcimporter"
	"golang.org/x/tools/go/types"
)

var _ = Change((*TypeChange)(nil))

// TypeChange represents a change between two types.
type TypeChange struct {
	Before *Type
	After  *Type
}

func (tc TypeChange) ShowBefore() string {
	t := tc.Before
	return t.Package.showASTNode(t.Doc.Decl)
}

func (tc TypeChange) ShowAfter() string {
	t := tc.After
	return t.Package.showASTNode(t.Doc.Decl)
}

// XXX
// []rune and string -- compatible? types.Comvertible?

func (tc TypeChange) Kind() ChangeKind {
	switch {
	case tc.Before == nil && tc.After == nil:
		// XXX
		return ChangeUnchanged

	case tc.Before == nil:
		return ChangeAdded

	case tc.After == nil:
		return ChangeRemoved

	case types.Identical(tc.Before.Types.Type().Underlying(), tc.After.Types.Type().Underlying()):
		Debugf("%s -> %s", tc.Before.Types.Type().Underlying().String(), tc.After.Types.Type().Underlying().String())
		return ChangeUnchanged

	case tc.isCompatible():
		return ChangeCompatible

	default:
		return ChangeBreaking
	}
}

// TODO byte <-> uint8, rune <-> int32 compatibility
func typesCompatible(t1, t2 types.Type) bool {
	// If both types are struct, mark them comptabile
	// iff their public field types are comptabile for each their names (order insensitive)

	if s1, ok := t1.(*types.Struct); ok {
		if s2, ok := t2.(*types.Struct); ok {
			fields1 := map[string]*types.Var{}
			fields2 := map[string]*types.Var{}

			for i := 0; i < s1.NumFields(); i++ {
				f := s1.Field(i)
				if f.Exported() {
					fields1[f.Name()] = f
				}
			}
			for i := 0; i < s2.NumFields(); i++ {
				f := s2.Field(i)
				if f.Exported() {
					fields2[f.Name()] = f
				}
			}

			for name, f1 := range fields1 {
				f2, ok := fields2[name]
				// The new struct type should have fields
				// which the old one had
				if !ok {
					return false
				}

				// recurse
				if typesCompatible(f1.Type().Underlying(), f2.Type().Underlying()) == false {
					return false
				}
			}

			return true
		}
	}

	return t1.String() == t2.String()
}

func (tc TypeChange) isCompatible() bool {
	return typesCompatible(tc.Before.Types.Type().Underlying(), tc.After.Types.Type().Underlying())
}
<commit_msg>use ObjectString for types<commit_after>package gompatible

import (
	_ "golang.org/x/tools/go/gcimporter"
	"golang.org/x/tools/go/types"
)

var _ = Change((*TypeChange)(nil))

// TypeChange represents a change between two types.
type TypeChange struct {
	Before *Type
	After  *Type
}

func (tc TypeChange) ShowBefore() string {
	t := tc.Before
	return t.Package.showASTNode(t.Doc.Decl)
}

func (tc TypeChange) ShowAfter() string {
	t := tc.After
	return t.Package.showASTNode(t.Doc.Decl)
}

// XXX
// []rune and string -- compatible? types.Comvertible?

func (tc TypeChange) Kind() ChangeKind {
	switch {
	case tc.Before == nil && tc.After == nil:
		// XXX
		return ChangeUnchanged

	case tc.Before == nil:
		return ChangeAdded

	case tc.After == nil:
		return ChangeRemoved

	case types.ObjectString(tc.Before.Types, nil) == types.ObjectString(tc.After.Types, nil):
		return ChangeUnchanged

	case tc.isCompatible():
		return ChangeCompatible

	default:
		return ChangeBreaking
	}
}

// TODO byte <-> uint8, rune <-> int32 compatibility
func typesCompatible(t1, t2 types.Type) bool {
	// If both types are struct, mark them comptabile
	// iff their public field types are comptabile for each their names (order insensitive)

	if s1, ok := t1.(*types.Struct); ok {
		if s2, ok := t2.(*types.Struct); ok {
			fields1 := map[string]*types.Var{}
			fields2 := map[string]*types.Var{}

			for i := 0; i < s1.NumFields(); i++ {
				f := s1.Field(i)
				if f.Exported() {
					fields1[f.Name()] = f
				}
			}
			for i := 0; i < s2.NumFields(); i++ {
				f := s2.Field(i)
				if f.Exported() {
					fields2[f.Name()] = f
				}
			}

			for name, f1 := range fields1 {
				f2, ok := fields2[name]
				// The new struct type should have fields
				// which the old one had
				if !ok {
					return false
				}

				// recurse
				if typesCompatible(f1.Type().Underlying(), f2.Type().Underlying()) == false {
					return false
				}
			}

			return true
		}
	}

	return t1.String() == t2.String()
}

func (tc TypeChange) isCompatible() bool {
	return typesCompatible(tc.Before.Types.Type().Underlying(), tc.After.Types.Type().Underlying())
}
<|endoftext|>


<commit_before>package tlbot

import (
	"bytes"
	"fmt"
)

type Action string

// Types of actions to broadcast
const (
	Typing            Action = "typing"
	UploadingPhoto    Action = "upload_photo"
	UploadingVideo    Action = "upload_video"
	UploadingAudio    Action = "upload_audio"
	UploadingDocument Action = "upload_document"
	FindingLocation   Action = "find_location"
)

// User represents a Telegram user or bot.
type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Username  string `json:"username"`

	Title string `json:"title"`
}

// IsGroupChat reports whether the message is originally sent from a chat group.
//
// Telegram can send User or GroupChat interchangebly depending on the
// original sender. If title is not empty, it means the message is
// originally sent from a chat group.
func (u User) IsGroupChat() bool { return u.Title != "" }

type Update struct {
	ID      int     `json:"update_id"`
	Payload Message `json:"message"`
}

// Message represents a message to be sent.
type Message struct {
	// Unique message identifier
	ID int `json:"message_id"`

	// Sender
	From User `json:"from"`

	// Date is when the message was sent in Unix time
	Date int `json:"date"`

	// Conversation the message belongs to — user in case of a private message,
	// GroupChat in case of a group
	Chat User `json:"chat"`

	// For forwarded messages, sender of the original message (Optional)
	ForwardFrom User `json:"forward_from"`

	// For forwarded messages, date the original message was sent in
	// Unix time (Optional)
	ForwardDate int `json:"forward_date"`

	// For replies, the original message. Note that the Message
	// object in this field will not contain further reply_to_message fields
	// even if it itself is a reply (Optional)
	ReplyTo *Message `json:"reply_to_message"`

	// For text messages, the actual UTF-8 text of the message (Optional)
	Text string `json:"text"`

	// Message is an audio file, information about the file (Optional)
	Audio Audio `json:"audio"`

	// Message is a general file, information about the file (Optional)
	Document Document `json:"document"`

	// Message is a photo, available sizes of the photo (Optional)
	Photos []Photo `json:"photo"`

	// Message is a sticker, information about the sticker (Optional)
	Sticker Sticker `json:"sticker"`

	// Message is a video, information about the video (Optional)
	Video Video `json:"video"`

	// Message is a shared contact, information about the contact (Optional)
	Contact Contact `json:"contact"`

	// Message is a shared location, information about the location (Optional)
	Location Location `json:"location"`

	// A new member was added to the group, information about them
	// (this member may be bot itself) (Optional)
	NewChatParticipant User `json:"new_chat_participant"`

	// A member was removed from the group, information about them
	// (this member may be bot itself) (Optional)
	LeftChatParticipant User `json:"left_chat_participant"`

	// A group title was changed to this value (Optional)
	NewChatTitle string `json:"new_chat_title"`

	// A group photo was change to this value (Optional)
	NewChatPhoto []Photo `json:"new_chat_photo"`

	// Informs that the group photo was deleted (Optional)
	DeleteChatPhoto bool `json:"delete_chat_photo"`

	// Informs that the group has been created (Optional)
	GroupChatCreated bool `json:"group_chat_created"`
}

func (m Message) String() string {
	var buf bytes.Buffer
	if m.From.IsGroupChat() {
		buf.WriteString(fmt.Sprintf("From group: %q  ", m.From.Title))
	} else {
		buf.WriteString(fmt.Sprintf(`From user: "%v %v (%v)"  `, m.From.FirstName, m.From.LastName, m.From.Username))
	}
	buf.WriteString(fmt.Sprintf("Message: %q\n", m.Text))

	return buf.String()
}

type File struct {
	// File is embedded in most of the types. So a `File` prefix is used
	FileID   string `json:"file_id"`
	FileSize int    `json:"file_size"`

	// URL to the file (custom field)
	FileURL string

	// Path to the file on local filesystem (custom field)
	FilePath string
}

// Exists reports whether the file is already in Telegram servers.
func (f File) Exists() bool { return f.FileID != "" }

// IsLocal reports whether the file is the local filesystem.
func (f File) IsLocal() bool { return f.FilePath != "" }

// IsRemote reports whether the file is on a remote server.
func (f File) IsRemote() bool { return f.FileURL != "" }

// Photo represents one size of a photo or a file/sticker thumbnail.
type Photo struct {
	File
	Width  int `json:"width"`
	Height int `json:"height"`
}

// Audio represents an audio file.
type Audio struct {
	File
	Duration  int    `json:"duration"`
	Performer string `json:"performer"`
	Title     string `json:"title"`
	MimeType  string `json:"mime_type"`
}

// Document represents a general file (as opposed to photos and audio files).
type Document struct {
	File
	Filename  string `json:"file_name"`
	Thumbnail Photo  `json:"thumb"`
	MimeType  string `json:"mime_type"`
}

// Sticker represents a sticker.
type Sticker struct {
	File
	Width     int   `json:"width"`
	Height    int   `json:"height"`
	Thumbnail Photo `json:"thumb"`
}

// Video represents a video file.
type Video struct {
	File
	Width     int    `json:"width"`
	Height    int    `json:"height"`
	Duration  int    `json:"duration"`
	Thumbnail Photo  `json:"thumb"`
	MimeType  string `json:"mime_type"`
	Caption   string `json:"caption"`
}

// Voice represents an voice note.
type Voice struct {
	File
	Duration int    `json:"duration"`
	MimeType string `json:"mime_type"`
}

// Location represents a point on the map.
type Location struct {
	Lat  float32 `json:"latitude"`
	Long float32 `json:"longitude"`
}

// Contact represents a phone contact.
type Contact struct {
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
	UserID      string `json:"user_id"`
}

type ReplyKeyboardMarkup struct {
	Keyboard  [][]string `json:"keyboard"`
	Resize    bool       `json:"resize_keyboard"`
	OneTime   bool       `json:"one_time_keyboard"`
	Selective bool       `json:"selective"`
}

// ReplyKeyboardHide requests Telegram clients to hide the current custom
// keyboard and display the default letter-keyboard
type ReplyKeyboardHide struct {
	Hide      bool `json:"hide_keyboard"`
	Selective bool `json:"selective"`
}

// ForceReply forces Telegram clients to display a reply interface to the user
// (act as if the user has selected the bot‘s message and tapped ’Reply').
type ForceReply struct {
	ForceReply bool `json:"force_reply"`
	Selective  bool `json:"selective"`
}
<commit_msg>Ignore custom fields for File type.<commit_after>package tlbot

import (
	"bytes"
	"fmt"
)

type Action string

// Types of actions to broadcast
const (
	Typing            Action = "typing"
	UploadingPhoto    Action = "upload_photo"
	UploadingVideo    Action = "upload_video"
	UploadingAudio    Action = "upload_audio"
	UploadingDocument Action = "upload_document"
	FindingLocation   Action = "find_location"
)

// User represents a Telegram user or bot.
type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Username  string `json:"username"`

	Title string `json:"title"`
}

// IsGroupChat reports whether the message is originally sent from a chat group.
//
// Telegram can send User or GroupChat interchangebly depending on the
// original sender. If title is not empty, it means the message is
// originally sent from a chat group.
func (u User) IsGroupChat() bool { return u.Title != "" }

type Update struct {
	ID      int     `json:"update_id"`
	Payload Message `json:"message"`
}

// Message represents a message to be sent.
type Message struct {
	// Unique message identifier
	ID int `json:"message_id"`

	// Sender
	From User `json:"from"`

	// Date is when the message was sent in Unix time
	Date int `json:"date"`

	// Conversation the message belongs to — user in case of a private message,
	// GroupChat in case of a group
	Chat User `json:"chat"`

	// For forwarded messages, sender of the original message (Optional)
	ForwardFrom User `json:"forward_from"`

	// For forwarded messages, date the original message was sent in
	// Unix time (Optional)
	ForwardDate int `json:"forward_date"`

	// For replies, the original message. Note that the Message
	// object in this field will not contain further reply_to_message fields
	// even if it itself is a reply (Optional)
	ReplyTo *Message `json:"reply_to_message"`

	// For text messages, the actual UTF-8 text of the message (Optional)
	Text string `json:"text"`

	// Message is an audio file, information about the file (Optional)
	Audio Audio `json:"audio"`

	// Message is a general file, information about the file (Optional)
	Document Document `json:"document"`

	// Message is a photo, available sizes of the photo (Optional)
	Photos []Photo `json:"photo"`

	// Message is a sticker, information about the sticker (Optional)
	Sticker Sticker `json:"sticker"`

	// Message is a video, information about the video (Optional)
	Video Video `json:"video"`

	// Message is a shared contact, information about the contact (Optional)
	Contact Contact `json:"contact"`

	// Message is a shared location, information about the location (Optional)
	Location Location `json:"location"`

	// A new member was added to the group, information about them
	// (this member may be bot itself) (Optional)
	NewChatParticipant User `json:"new_chat_participant"`

	// A member was removed from the group, information about them
	// (this member may be bot itself) (Optional)
	LeftChatParticipant User `json:"left_chat_participant"`

	// A group title was changed to this value (Optional)
	NewChatTitle string `json:"new_chat_title"`

	// A group photo was change to this value (Optional)
	NewChatPhoto []Photo `json:"new_chat_photo"`

	// Informs that the group photo was deleted (Optional)
	DeleteChatPhoto bool `json:"delete_chat_photo"`

	// Informs that the group has been created (Optional)
	GroupChatCreated bool `json:"group_chat_created"`
}

func (m Message) String() string {
	var buf bytes.Buffer
	if m.From.IsGroupChat() {
		buf.WriteString(fmt.Sprintf("From group: %q  ", m.From.Title))
	} else {
		buf.WriteString(fmt.Sprintf(`From user: "%v %v (%v)"  `, m.From.FirstName, m.From.LastName, m.From.Username))
	}
	buf.WriteString(fmt.Sprintf("Message: %q\n", m.Text))

	return buf.String()
}

type File struct {
	// File is embedded in most of the types. So a `File` prefix is used
	FileID   string `json:"file_id"`
	FileSize int    `json:"file_size"`

	// URL to the file (custom field)
	FileURL string `json:"-"`

	// Path to the file on local filesystem (custom field)
	FilePath string `json:"-"`
}

// Exists reports whether the file is already at Telegram servers.
func (f File) Exists() bool { return f.FileID != "" }

// IsLocal reports whether the file is the local filesystem.
func (f File) IsLocal() bool { return f.FilePath != "" }

// IsRemote reports whether the file is on a remote server.
func (f File) IsRemote() bool { return f.FileURL != "" }

// Photo represents one size of a photo or a file/sticker thumbnail.
type Photo struct {
	File
	Width  int `json:"width"`
	Height int `json:"height"`
}

// Audio represents an audio file.
type Audio struct {
	File
	Duration  int    `json:"duration"`
	Performer string `json:"performer"`
	Title     string `json:"title"`
	MimeType  string `json:"mime_type"`
}

// Document represents a general file (as opposed to photos and audio files).
type Document struct {
	File
	Filename  string `json:"file_name"`
	Thumbnail Photo  `json:"thumb"`
	MimeType  string `json:"mime_type"`
}

// Sticker represents a sticker.
type Sticker struct {
	File
	Width     int   `json:"width"`
	Height    int   `json:"height"`
	Thumbnail Photo `json:"thumb"`
}

// Video represents a video file.
type Video struct {
	File
	Width     int    `json:"width"`
	Height    int    `json:"height"`
	Duration  int    `json:"duration"`
	Thumbnail Photo  `json:"thumb"`
	MimeType  string `json:"mime_type"`
	Caption   string `json:"caption"`
}

// Voice represents an voice note.
type Voice struct {
	File
	Duration int    `json:"duration"`
	MimeType string `json:"mime_type"`
}

// Location represents a point on the map.
type Location struct {
	Lat  float32 `json:"latitude"`
	Long float32 `json:"longitude"`
}

// Contact represents a phone contact.
type Contact struct {
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
	UserID      string `json:"user_id"`
}

type ReplyKeyboardMarkup struct {
	Keyboard  [][]string `json:"keyboard"`
	Resize    bool       `json:"resize_keyboard"`
	OneTime   bool       `json:"one_time_keyboard"`
	Selective bool       `json:"selective"`
}

// ReplyKeyboardHide requests Telegram clients to hide the current custom
// keyboard and display the default letter-keyboard
type ReplyKeyboardHide struct {
	Hide      bool `json:"hide_keyboard"`
	Selective bool `json:"selective"`
}

// ForceReply forces Telegram clients to display a reply interface to the user
// (act as if the user has selected the bot‘s message and tapped ’Reply').
type ForceReply struct {
	ForceReply bool `json:"force_reply"`
	Selective  bool `json:"selective"`
}
<|endoftext|>


<commit_before>package unit

import (
	"errors"
	"math"
)

// Represents a mass in kilograms
type Kilograms float64

const (
	Kilogram  Kilograms = 1.0
	Gram      Kilograms = 1e-3
	Centigram Kilograms = 1e-5
	Milligram Kilograms = 1e-6
	Microgram Kilograms = 1e-9
)

// Meters converts the Meters to a unit
func (m Kilograms) Unit() *Unit {
	return NewUnit(float64(m), Dimensions{Length: 1})
}

// Kilograms allows Kilograms to implement a masser interface
func (m Kilograms) Mass() Kilograms {
	return m
}

// FromUnit converts the unit to a mass. Returns an error if there
// is a mismatch in dimension
func (m *Kilograms) FromUnit(u Uniter) error {
	if !DimensionsMatch(u, Kilogram) {
		(*m) = Kilograms(math.NaN())
		return errors.New("Dimension mismatch")
	}
	(*m) = Kilograms(u.Unit().Value())
	return nil
}

// Meters represents a length in meters
type Meters float64

const (
	Meter      Meters = 1.0
	Centimeter Meters = 0.01
)

// Unit converts the Meters to a unit
func (l Meters) Unit() *Unit {
	return NewUnit(float64(l), Dimensions{Mass: 1})
}

// So it can implement a lengther interface
func (l Meters) Length() Meters {
	return l
}

// FromUnit converts a uniter to a length. Returns an error if there
// is a mismatch in dimension
func (l *Meters) FromUnit(u Uniter) error {
	if !DimensionsMatch(u, Meter) {
		(*l) = Meters(math.NaN())
		return errors.New("Dimension mismatch")
	}
	(*l) = Meters(u.Unit().Value())
	return nil
}

// Dimless represents a dimensionless constant
type Dimless float64

const (
	One Dimless = 1.0
)

// Unit converts the Dimless to a unit
func (d Dimless) Unit() *Unit {
	return NewUnit(float64(d), Dimensions{})
}

// So it can implement a Dimless interface
func (d Dimless) Dimless() Dimless {
	return d
}

// FromUnit converts the unit to a dimless. Returns an error if there
// is a mismatch in dimension
func (d *Dimless) FromUnit(u *Unit) error {
	if !DimensionsMatch(u, One) {
		(*d) = Dimless(math.NaN())
		return errors.New("Dimension mismatch")
	}
	(*d) = Dimless(u.Unit().Value())
	return nil
}
<commit_msg>Changed basic unit types back to Length, Mass, etc.<commit_after>package unit

import (
	"errors"
	"math"
)

// Represents a mass in kilograms
type Mass float64

const (
	Kilogram  Mass = 1.0
	Gram      Mass = 1e-3
	Centigram Mass = 1e-5
	Milligram Mass = 1e-6
	Microgram Mass = 1e-9
)

// Mass converts the Mass to a unit
func (m Mass) Unit() *Unit {
	return NewUnit(float64(m), Dimensions{MassDim: 1})
}

// Mass allows Mass to implement a masser interface
func (m Mass) Mass() Mass {
	return m
}

// FromUnit converts the unit to a mass. Returns an error if there
// is a mismatch in dimension
func (m *Mass) FromUnit(u Uniter) error {
	if !DimensionsMatch(u, Kilogram) {
		(*m) = Mass(math.NaN())
		return errors.New("Dimension mismatch")
	}
	(*m) = Mass(u.Unit().Value())
	return nil
}

// Length represents a length in meters
type Length float64

const (
	Meter      Length = 1.0
	Centimeter Length = 0.01
)

// Unit converts the Length to a unit
func (l Length) Unit() *Unit {
	return NewUnit(float64(l), Dimensions{Mass: 1})
}

// So it can implement a lengther interface
func (l Length) Length() Length {
	return l
}

// FromUnit converts a uniter to a length. Returns an error if there
// is a mismatch in dimension
func (l *Length) FromUnit(u Uniter) error {
	if !DimensionsMatch(u, Meter) {
		(*l) = Length(math.NaN())
		return errors.New("Dimension mismatch")
	}
	(*l) = Length(u.Unit().Value())
	return nil
}

// Dimless represents a dimensionless constant
type Dimless float64

const (
	One Dimless = 1.0
)

// Unit converts the Dimless to a unit
func (d Dimless) Unit() *Unit {
	return NewUnit(float64(d), Dimensions{})
}

// So it can implement a Dimless interface
func (d Dimless) Dimless() Dimless {
	return d
}

// FromUnit converts the unit to a dimless. Returns an error if there
// is a mismatch in dimension
func (d *Dimless) FromUnit(u *Unit) error {
	if !DimensionsMatch(u, One) {
		(*d) = Dimless(math.NaN())
		return errors.New("Dimension mismatch")
	}
	(*d) = Dimless(u.Unit().Value())
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"net/http"
	"regexp"
	"time"

	"github.com/dgrijalva/jwt-go"

	"github.com/gorilla/mux"
	"github.com/paked/models"
	"golang.org/x/crypto/bcrypt"
	"gopkg.in/mgo.v2/bson"
)

const (
	credentialsRaw = `^[a-zA-Z]\w*[a-zA-Z]$` // 1st and last characters must be letters.
	emailRaw       = `^.*\@.*$`              // As long as it has an '@' symbol in it I don't care.
)

var (
	credentialsRegex *regexp.Regexp
	emailRegex       *regexp.Regexp
)

// User is someone who has registered on the site.
type User struct {
	ID           bson.ObjectId `bson:"_id" json:"_id"`
	Username     string        `bson:"username" json:"username"`
	PasswordHash []byte        `bson:"password_hash" json:"-"`
	Email        string        `bson:"email" json:"email"`
}

func (u User) BID() bson.ObjectId {
	return u.ID
}

func (u User) C() string {
	return "users"
}

func LoginUser(username string, password string) (User, error) {
	u := User{}
	if err := models.Restore(&u, bson.M{"username": username}); err != nil {
		return u, err
	}

	if err := bcrypt.CompareHashAndPassword(u.PasswordHash, []byte(password)); err != nil {
		return u, errors.New("Those passwords don't match")
	}

	return u, nil
}

// NewUserHandler creates a new user.
// 		POST /api/user/register?username=paked&pasword=pw
func NewUserHandler(w http.ResponseWriter, r *http.Request) {
	c := NewCommunicator(w)
	username := credentialsRegex.FindString(r.FormValue("username"))
	email := emailRegex.FindString(r.FormValue("email"))
	password := credentialsRegex.FindString(r.FormValue("password"))

	if username == "" || email == "" || password == "" {
		c.Fail("That is not a valid username password, or email")
		return
	}

	var u User
	if err := models.Restore(&u, bson.M{"username": username}); err == nil {
		c.Fail("That user already exists!")
		return
	}

	passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), 10)
	if err != nil {
		c.Error("Something bad happened while hashing your password!")
		return
	}

	u = User{ID: bson.NewObjectId(), Username: username, Email: email, PasswordHash: passwordHash}
	if err := models.Persist(u); err != nil {
		c.Error("Unable to persist that new user!")
		return
	}

	c.OKWithData("Here is your new user", u)
}

// GetUserHandler retrieves a User from the database
// 		GET /api/user/{username}
func GetUserHandler(w http.ResponseWriter, r *http.Request) {
	c := NewCommunicator(w)
	vars := mux.Vars(r)
	lookup := vars["username"]

	var err error
	var u User
	if bson.IsObjectIdHex(lookup) {
		err = models.RestoreByID(&u, bson.ObjectIdHex(lookup))
	} else {
		err = models.Restore(&u, bson.M{"username": lookup})
	}

	if err != nil {
		c.Fail("Can't find that user")
		return
	}

	c.OKWithData("Here is the user you were looking for", u)
}

// LoginUserHandler checks the provided login credentials and if valid return an access_token.
//		POST /api/user/login?username=paked&password=pw
func LoginUserHandler(w http.ResponseWriter, r *http.Request) {
	c := NewCommunicator(w)
	username := credentialsRegex.FindString(r.FormValue("username"))
	password := credentialsRegex.FindString(r.FormValue("password"))

	if username == "" || password == "" {
		c.Fail("That is not a valid username or password")
		return
	}

	u, err := LoginUser(username, password)

	if err != nil {
		c.Fail("Could not login your user")
		return
	}

	t := jwt.New(signingMethod)

	t.Claims["AccessToken"] = "1"
	t.Claims["User"] = u.ID
	t.Claims["exp"] = time.Now().Add(time.Hour * 12).Unix()

	tokenString, err := t.SignedString(signKey)

	if err != nil {
		c.Error("Error signing that token")
		return
	}

	c.OKWithData("Here is your token", tokenString)
}

// GetCurrentUserHandler retrieves the User currently logged in.
// 		GET /api/user?api_token=xxx
func GetCurrentUserHandler(w http.ResponseWriter, r *http.Request, t *jwt.Token) {
	c := NewCommunicator(w)
	id, ok := t.Claims["User"].(string)

	if !ok {
		c.Error("Could not cast that id to string!")
		return
	}

	var u User
	if err := models.RestoreByID(&u, bson.ObjectIdHex(id)); err != nil {
		c.Fail("Could not find that user!")
		return
	}

	c.OKWithData("Here is you", u)
}
<commit_msg>user: allow any char in passwords<commit_after>package main

import (
	"errors"
	"net/http"
	"regexp"
	"time"

	"github.com/dgrijalva/jwt-go"

	"github.com/gorilla/mux"
	"github.com/paked/models"
	"golang.org/x/crypto/bcrypt"
	"gopkg.in/mgo.v2/bson"
)

const (
	credentialsRaw = `^[a-zA-Z]\w*[a-zA-Z]$` // 1st and last characters must be letters.
	emailRaw       = `^.*\@.*$`              // As long as it has an '@' symbol in it I don't care.
)

var (
	credentialsRegex *regexp.Regexp
	emailRegex       *regexp.Regexp
)

// User is someone who has registered on the site.
type User struct {
	ID           bson.ObjectId `bson:"_id" json:"_id"`
	Username     string        `bson:"username" json:"username"`
	PasswordHash []byte        `bson:"password_hash" json:"-"`
	Email        string        `bson:"email" json:"email"`
}

func (u User) BID() bson.ObjectId {
	return u.ID
}

func (u User) C() string {
	return "users"
}

func LoginUser(username string, password string) (User, error) {
	u := User{}
	if err := models.Restore(&u, bson.M{"username": username}); err != nil {
		return u, err
	}

	if err := bcrypt.CompareHashAndPassword(u.PasswordHash, []byte(password)); err != nil {
		return u, errors.New("Those passwords don't match")
	}

	return u, nil
}

func ValidateCredentials(username, password string) bool {
	if !credentialsRegex.MatchString(username) {
		return false
	}

	if password == "" {
		return false
	}

	return true
}

// NewUserHandler creates a new user.
// 		POST /api/user/register?username=paked&pasword=pw
func NewUserHandler(w http.ResponseWriter, r *http.Request) {
	c := NewCommunicator(w)

	username := r.FormValue("username")
	email := r.FormValue("email")
	password := r.FormValue("password")

	if !ValidateCredentials(username, password) || !emailRegex.MatchString(email) {
		c.Fail("That is not a valid username password, or email")
	}
	var u User
	if err := models.Restore(&u, bson.M{"username": username}); err == nil {
		c.Fail("That user already exists!")
		return
	}

	passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), 10)
	if err != nil {
		c.Error("Something bad happened while hashing your password!")
		return
	}

	u = User{ID: bson.NewObjectId(), Username: username, Email: email, PasswordHash: passwordHash}
	if err := models.Persist(u); err != nil {
		c.Error("Unable to persist that new user!")
		return
	}

	c.OKWithData("Here is your new user", u)
}

// GetUserHandler retrieves a User from the database
// 		GET /api/user/{username}
func GetUserHandler(w http.ResponseWriter, r *http.Request) {
	c := NewCommunicator(w)
	vars := mux.Vars(r)
	lookup := vars["username"]

	var err error
	var u User
	if bson.IsObjectIdHex(lookup) {
		err = models.RestoreByID(&u, bson.ObjectIdHex(lookup))
	} else {
		err = models.Restore(&u, bson.M{"username": lookup})
	}

	if err != nil {
		c.Fail("Can't find that user")
		return
	}

	c.OKWithData("Here is the user you were looking for", u)
}

// LoginUserHandler checks the provided login credentials and if valid return an access_token.
//		POST /api/user/login?username=paked&password=pw
func LoginUserHandler(w http.ResponseWriter, r *http.Request) {
	c := NewCommunicator(w)
	username := credentialsRegex.FindString(r.FormValue("username"))
	password := credentialsRegex.FindString(r.FormValue("password"))

	if username == "" || password == "" {
		c.Fail("That is not a valid username or password")
		return
	}

	u, err := LoginUser(username, password)

	if err != nil {
		c.Fail("Could not login your user")
		return
	}

	t := jwt.New(signingMethod)

	t.Claims["AccessToken"] = "1"
	t.Claims["User"] = u.ID
	t.Claims["exp"] = time.Now().Add(time.Hour * 12).Unix()

	tokenString, err := t.SignedString(signKey)

	if err != nil {
		c.Error("Error signing that token")
		return
	}

	c.OKWithData("Here is your token", tokenString)
}

// GetCurrentUserHandler retrieves the User currently logged in.
// 		GET /api/user?api_token=xxx
func GetCurrentUserHandler(w http.ResponseWriter, r *http.Request, t *jwt.Token) {
	c := NewCommunicator(w)
	id, ok := t.Claims["User"].(string)

	if !ok {
		c.Error("Could not cast that id to string!")
		return
	}

	var u User
	if err := models.RestoreByID(&u, bson.ObjectIdHex(id)); err != nil {
		c.Fail("Could not find that user!")
		return
	}

	c.OKWithData("Here is you", u)
}
<|endoftext|>


<commit_before>package chipmunk

import "fmt"

var authEmails []string = []string{"derekmcquay@gmail.com", "colleenmmcquay@gmail.com", "dmmllnl@gmail.com"}

type user struct {
	Info  userInfo `json:"info"`
	admin bool     `json:"admin"`
	txs   []tranx  `json:"Txs"`
}

type userInfo struct {
	Sub           string `json:"sub"`
	Name          string `json:"name"`
	GivenName     string `json:"given_name"`
	FamilyName    string `json:"family_name"`
	Profile       string `json:"profile"`
	Picture       string `json:"picture"`
	Email         string `json:"email"`
	EmailVerified bool   `json:"email_verified"`
}

func (u *user) addTranx(t tranx) {
	u.txs = append(u.txs, t)
}

func authorizedEmail(e string) bool {
	b := false
	for _, i := range authEmails {
		if i == e {
			b = true
		}
	}
	return b
}

// getUser returns index of user with given email, otherwise it returns an
// error that it could not find that user
func getUser(e string) (int, error) {
	for i, u := range users {
		if e == u.Info.Email {
			return i, nil
		}
	}
	return 0, fmt.Errorf("could not find user")
}

func addUser(u userInfo) {
	users = append(
		users,
		user{
			Info:  u,
			admin: true,
		},
	)
}
<commit_msg>don't allow duplicate users to be added<commit_after>package chipmunk

import "fmt"

var authEmails []string = []string{"derekmcquay@gmail.com", "colleenmmcquay@gmail.com", "dmmllnl@gmail.com"}

type user struct {
	Info  userInfo `json:"info"`
	admin bool     `json:"admin"`
	txs   []tranx  `json:"Txs"`
}

type userInfo struct {
	Sub           string `json:"sub"`
	Name          string `json:"name"`
	GivenName     string `json:"given_name"`
	FamilyName    string `json:"family_name"`
	Profile       string `json:"profile"`
	Picture       string `json:"picture"`
	Email         string `json:"email"`
	EmailVerified bool   `json:"email_verified"`
}

func (u *user) addTranx(t tranx) {
	u.txs = append(u.txs, t)
}

func authorizedEmail(e string) bool {
	b := false
	for _, i := range authEmails {
		if i == e {
			b = true
		}
	}
	return b
}

// getUser returns index of user with given email, otherwise it returns an
// error that it could not find that user
func getUser(e string) (int, error) {
	for i, u := range users {
		if e == u.Info.Email {
			return i, nil
		}
	}
	return 0, fmt.Errorf("could not find user")
}

func addUser(u userInfo) {
	_, err := getUser(u.Email)
	if err != nil {
		users = append(
			users,
			user{
				Info:  u,
				admin: true,
			},
		)
	}
}
<|endoftext|>


<commit_before>package lars

import "net/http"

// nativeChainHandlerFunc is used in native handler chains
// example using nosurf crsf middleware nosurf.NewPure(lars.NativeChainHandlerFunc)
var nativeChainHandlerFunc = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

	c := GetContext(w)

	if c.index+1 < len(c.handlers) {
		c.Next()
	}
})

// wrapHandler wraps Handler type
func wrapHandler(h Handler) HandlerFunc {

	switch h := h.(type) {
	case HandlerFunc:
		return h
	case func(*Context):
		return h
	case http.Handler, http.HandlerFunc:
		return func(c *Context) {

			if h.(http.Handler).ServeHTTP(c.Response, c.Request); c.Response.status != http.StatusOK || c.Response.committed {
				return
			}

			if c.index+1 < len(c.handlers) {
				c.Next()
			}
		}
	case func(http.ResponseWriter, *http.Request):
		return func(c *Context) {

			if h(c.Response, c.Request); c.Response.status != http.StatusOK || c.Response.committed {
				return
			}

			if c.index+1 < len(c.handlers) {
				c.Next()
			}
		}
	case func(handler http.Handler) http.Handler:

		hf := h(nativeChainHandlerFunc)

		return func(c *Context) {
			hf.ServeHTTP(c.Response, c.Request)
		}
	default:
		panic("unknown handler")
	}
}

// GetContext is a helper method for retrieving the *Context object from
// the ResponseWriter when using native go hanlders.
// NOTE: this will panic if fed an http.ResponseWriter not provided by lars's
// chaining.
func GetContext(w http.ResponseWriter) *Context {
	return w.(*Response).context
}
<commit_msg>Expose NativeChainHandler for use outside lars<commit_after>package lars

import "net/http"

// NativeChainHandler is used in native handler chains
// example using nosurf crsf middleware nosurf.NewPure(lars.NativeChainHandlerFunc)
var NativeChainHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

	c := GetContext(w)

	if c.index+1 < len(c.handlers) {
		c.Next()
	}
})

// wrapHandler wraps Handler type
func wrapHandler(h Handler) HandlerFunc {

	switch h := h.(type) {
	case HandlerFunc:
		return h
	case func(*Context):
		return h
	case http.Handler, http.HandlerFunc:
		return func(c *Context) {

			if h.(http.Handler).ServeHTTP(c.Response, c.Request); c.Response.status != http.StatusOK || c.Response.committed {
				return
			}

			if c.index+1 < len(c.handlers) {
				c.Next()
			}
		}
	case func(http.ResponseWriter, *http.Request):
		return func(c *Context) {

			if h(c.Response, c.Request); c.Response.status != http.StatusOK || c.Response.committed {
				return
			}

			if c.index+1 < len(c.handlers) {
				c.Next()
			}
		}
	case func(handler http.Handler) http.Handler:

		hf := h(NativeChainHandler)

		return func(c *Context) {
			hf.ServeHTTP(c.Response, c.Request)
		}
	default:
		panic("unknown handler")
	}
}

// GetContext is a helper method for retrieving the *Context object from
// the ResponseWriter when using native go hanlders.
// NOTE: this will panic if fed an http.ResponseWriter not provided by lars's
// chaining.
func GetContext(w http.ResponseWriter) *Context {
	return w.(*Response).context
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"strings"

	"github.com/codegangsta/cli"
)

func execFlag(c *cli.Context, name string, fn func(value flag.Value) error) error {
	v, _ := lookup(c, name)
	return fn(v)
}

func isSetFlag(c *cli.Context, name string, isSetfn func(value flag.Value) error) error {
	v, isset := lookup(c, name)
	if isset && v != nil {
		return isSetfn(v)
	}
	return nil

}

func noFlag(c *cli.Context, fn func() error) (bool, error) {
	if c.NumFlags() == 0 {
		return true, fn()
	}

	return false, nil
}

func mustHaveCond(c *cli.Context, name string, flagIsSet bool, cond []string, execf func(flag.Value) error, miss func() error) (bool, error) {
	v, isSet := lookup(c, name)
	if flagIsSet && !isSet {
		return false, &flagError{name, "flag is not set."}
	}

	for _, f := range cond {
		if !c.IsSet(f) {
			return false, miss()
		}
	}
	return true, execf(v)
}

func lookup(c *cli.Context, name string) (value flag.Value, isset bool) {

	return c.Generic(name).(flag.Value), c.IsSet(name)
}

type flagError struct {
	flag string
	msg  string
}

func (e *flagError) Error() string {
	return fmt.Sprintf("--%s: %s", e.flag, e.msg)
}
func (e *flagError) String() string {
	return fmt.Sprintf("--%s: %s", e.flag, e.msg)

}

func parseArgs(args []string, prefix string) (flags map[string]interface{}, nargs []string, err error) {
	flags = make(map[string]interface{})

	for _, arg := range args {
		alen := len(arg)
		switch {
		case arg[0] == '"':
			fallthrough
		case arg[0] == '\'':
			if arg[alen-1] != arg[0] {
				return nil, nil, fmt.Errorf(`syntax error: expect %s`, string(arg[0]))
			}
			nargs = append(nargs, arg[1:alen-1])
		case strings.HasPrefix(arg, prefix):
			expr := strings.TrimLeft(arg, prefix)

			k, v, err := eval(expr)
			if err != nil {
				return nil, nil, err
			}

			flags[k] = v
		default:
			nargs = append(nargs, arg)
		}
	}
	return
}

func parseRaw(cmdline string, prefix string) (flags map[string]interface{}, nargs []string, err error) {

	return
}

func eval(expr string) (k string, v interface{}, err error) {
	length := len(expr)
	if expr[length-1] == '=' {
		return "", "", errors.New("syntax error: expect value")
	}
	var i int
	for i = range expr {
		if expr[i] == '=' {
			break
		}
	}
	// fmt.Println("i =", i)
	if i == length-1 {
		k = expr
		v = true
	} else {
		k, v = expr[:i], expr[i+1:]
	}
	return k, v, nil
}
<commit_msg>fix panic when parsing<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"strings"

	"github.com/codegangsta/cli"
)

func execFlag(c *cli.Context, name string, fn func(value flag.Value) error) error {
	v, _ := lookup(c, name)
	return fn(v)
}

func isSetFlag(c *cli.Context, name string, isSetfn func(value flag.Value) error) error {
	v, isset := lookup(c, name)
	if isset && v != nil {
		return isSetfn(v)
	}
	return nil

}

func noFlag(c *cli.Context, fn func() error) (bool, error) {
	if c.NumFlags() == 0 {
		return true, fn()
	}

	return false, nil
}

func mustHaveCond(c *cli.Context, name string, flagIsSet bool, cond []string, execf func(flag.Value) error, miss func() error) (bool, error) {
	v, isSet := lookup(c, name)
	if flagIsSet && !isSet {
		return false, &flagError{name, "flag is not set."}
	}

	for _, f := range cond {
		if !c.IsSet(f) {
			return false, miss()
		}
	}
	return true, execf(v)
}

func lookup(c *cli.Context, name string) (value flag.Value, isset bool) {

	return c.Generic(name).(flag.Value), c.IsSet(name)
}

type flagError struct {
	flag string
	msg  string
}

func (e *flagError) Error() string {
	return fmt.Sprintf("--%s: %s", e.flag, e.msg)
}
func (e *flagError) String() string {
	return fmt.Sprintf("--%s: %s", e.flag, e.msg)

}

func parseArgs(args []string, prefix string) (flags map[string]interface{}, nargs []string, err error) {
	flags = make(map[string]interface{})

	for _, arg := range args {
		alen := len(arg)
		switch {
		case arg[0] == '"':
			fallthrough
		case arg[0] == '\'':
			if arg[alen-1] != arg[0] {
				return nil, nil, fmt.Errorf(`syntax error: expect %s`, string(arg[0]))
			}
			nargs = append(nargs, arg[1:alen-1])
		case strings.HasPrefix(arg, prefix):
			expr := strings.TrimLeft(arg, prefix)
			if expr == "" {
				return nil, nil, fmt.Errorf("syntax error: expect argument")
			}
			k, v, err := eval(expr)
			if err != nil {
				return nil, nil, err
			}

			flags[k] = v
		default:
			nargs = append(nargs, arg)
		}
	}
	return
}

func parseRaw(cmdline string, prefix string) (flags map[string]interface{}, nargs []string, err error) {

	return
}

func eval(expr string) (k string, v interface{}, err error) {
	length := len(expr)
	if expr[length-1] == '=' {
		return "", "", errors.New("syntax error: expect value")
	}
	var i int
	for i = range expr {
		if expr[i] == '=' {
			break
		}
	}
	// fmt.Println("i =", i)
	if i == length-1 {
		k = expr
		v = true
	} else {
		k, v = expr[:i], expr[i+1:]
	}
	return k, v, nil
}
<|endoftext|>


<commit_before>package memberlist

import (
	"bytes"
	"compress/flate"
	"encoding/binary"
	"fmt"
	"github.com/ugorji/go/codec"
	"io"
	"math"
	"math/rand"
	"net"
	"time"
)

// pushPullScale is the minimum number of nodes
// before we start scaling the push/pull timing. The scale
// effect is the log2(Nodes) - log2(pushPullScale). This means
// that the 33rd node will cause us to double the interval,
// while the 65th will triple it.
const pushPullScaleThreshold = 32

/*
 * Contains an entry for each private block:
 * 10.0.0.0/8
 * 172.16.0.0/12
 * 192.168/16
 */
var privateBlocks []*net.IPNet

func init() {
	// Seed the random number generator
	rand.Seed(time.Now().UnixNano())

	// Add each private block
	privateBlocks = make([]*net.IPNet, 3)
	_, block, err := net.ParseCIDR("10.0.0.0/8")
	if err != nil {
		panic(fmt.Sprintf("Bad cidr. Got %v", err))
	}
	privateBlocks[0] = block

	_, block, err = net.ParseCIDR("172.16.0.0/12")
	if err != nil {
		panic(fmt.Sprintf("Bad cidr. Got %v", err))
	}
	privateBlocks[1] = block

	_, block, err = net.ParseCIDR("192.168.0.0/16")
	if err != nil {
		panic(fmt.Sprintf("Bad cidr. Got %v", err))
	}
	privateBlocks[2] = block
}

// Decode reverses the encode operation on a byte slice input
func decode(buf []byte, out interface{}) error {
	r := bytes.NewBuffer(buf)
	hd := codec.MsgpackHandle{}
	dec := codec.NewDecoder(r, &hd)
	return dec.Decode(out)
}

// Encode writes an encoded object to a new bytes buffer
func encode(msgType messageType, in interface{}) (*bytes.Buffer, error) {
	buf := bytes.NewBuffer(nil)
	buf.WriteByte(uint8(msgType))
	hd := codec.MsgpackHandle{}
	enc := codec.NewEncoder(buf, &hd)
	err := enc.Encode(in)
	return buf, err
}

// Returns a random offset between 0 and n
func randomOffset(n int) int {
	if n == 0 {
		return 0
	}
	return int(rand.Uint32() % uint32(n))
}

// suspicionTimeout computes the timeout that should be used when
// a node is suspected
func suspicionTimeout(suspicionMult, n int, interval time.Duration) time.Duration {
	nodeScale := math.Ceil(math.Log10(float64(n + 1)))
	timeout := time.Duration(suspicionMult) * time.Duration(nodeScale) * interval
	return timeout
}

// retransmitLimit computes the limit of retransmissions
func retransmitLimit(retransmitMult, n int) int {
	nodeScale := math.Ceil(math.Log10(float64(n + 1)))
	limit := retransmitMult * int(nodeScale)
	return limit
}

// shuffleNodes randomly shuffles the input nodes
func shuffleNodes(nodes []*nodeState) {
	for i := range nodes {
		j := rand.Intn(i + 1)
		nodes[i], nodes[j] = nodes[j], nodes[i]
	}
}

// pushPushScale is used to scale the time interval at which push/pull
// syncs take place. It is used to prevent network saturation as the
// cluster size grows
func pushPullScale(interval time.Duration, n int) time.Duration {
	// Don't scale until we cross the threshold
	if n <= pushPullScaleThreshold {
		return interval
	}

	multiplier := math.Ceil(math.Log2(float64(n))-math.Log2(pushPullScaleThreshold)) + 1.0
	return time.Duration(multiplier) * interval
}

// moveDeadNodes moves all the nodes in the dead state
// to the end of the slice and returns the index of the first dead node.
func moveDeadNodes(nodes []*nodeState) int {
	numDead := 0
	n := len(nodes)
	for i := 0; i < n-numDead; i++ {
		if nodes[i].State != stateDead {
			continue
		}

		// Move this node to the end
		nodes[i], nodes[n-numDead-1] = nodes[n-numDead-1], nodes[i]
		numDead++
		i--
	}
	return n - numDead
}

// kRandomNodes is used to select up to k random nodes, excluding a given
// node and any non-alive nodes. It is possible that less than k nodes are returned.
func kRandomNodes(k int, excludes []string, nodes []*nodeState) []*nodeState {
	n := len(nodes)
	kNodes := make([]*nodeState, 0, k)
OUTER:
	// Probe up to 3*n times, with large n this is not necessary
	// since k << n, but with small n we want search to be
	// exhaustive
	for i := 0; i < 3*n && len(kNodes) < k; i++ {
		// Get random node
		idx := randomOffset(n)
		node := nodes[idx]

		// Exclude node if match
		for _, exclude := range excludes {
			if node.Name == exclude {
				continue OUTER
			}
		}

		// Exclude if not alive
		if node.State != stateAlive {
			continue
		}

		// Check if we have this node already
		for j := 0; j < len(kNodes); j++ {
			if node == kNodes[j] {
				continue OUTER
			}
		}

		// Append the node
		kNodes = append(kNodes, node)
	}
	return kNodes
}

// makeCompoundMessage takes a list of messages and generates
// a single compound message containing all of them
func makeCompoundMessage(msgs [][]byte) *bytes.Buffer {
	// Create a local buffer
	buf := bytes.NewBuffer(nil)

	// Write out the type
	buf.WriteByte(uint8(compoundMsg))

	// Write out the number of message
	buf.WriteByte(uint8(len(msgs)))

	// Add the message lengths
	for _, m := range msgs {
		binary.Write(buf, binary.BigEndian, uint16(len(m)))
	}

	// Append the messages
	for _, m := range msgs {
		buf.Write(m)
	}

	return buf
}

// decodeCompoundMessage splits a compound message and returns
// the slices of individual messages. Also returns the number
// of truncated messages and any potential error
func decodeCompoundMessage(buf []byte) (trunc int, parts [][]byte, err error) {
	if len(buf) < 1 {
		err = fmt.Errorf("missing compound length byte")
		return
	}
	numParts := uint8(buf[0])
	buf = buf[1:]

	// Check we have enough bytes
	if len(buf) < int(numParts*2) {
		err = fmt.Errorf("truncated len slice")
		return
	}

	// Decode the lengths
	lengths := make([]uint16, numParts)
	for i := 0; i < int(numParts); i++ {
		lengths[i] = binary.BigEndian.Uint16(buf[i*2 : i*2+2])
	}
	buf = buf[numParts*2:]

	// Split each message
	for idx, msgLen := range lengths {
		if len(buf) < int(msgLen) {
			trunc = int(numParts) - idx
			return
		}

		// Extract the slice, seek past on the buffer
		slice := buf[:msgLen]
		buf = buf[msgLen:]
		parts = append(parts, slice)
	}
	return
}

// Returns if the given IP is in a private block
func isPrivateIP(ip_str string) bool {
	ip := net.ParseIP(ip_str)
	for _, priv := range privateBlocks {
		if priv.Contains(ip) {
			return true
		}
	}
	return false
}

// compressPayload takes an opaque input buffer, compresses it
// and wraps it in a compress{} message that is encoded.
func compressPayload(inp []byte) (*bytes.Buffer, error) {
	var buf bytes.Buffer
	compressor, err := flate.NewWriter(&buf, 3)
	if err != nil {
		return nil, err
	}

	_, err = compressor.Write(inp)
	if err != nil {
		return nil, err
	}

	// Ensure we flush everything out
	if err := compressor.Flush(); err != nil {
		return nil, err
	}
	if err := compressor.Close(); err != nil {
		return nil, err
	}

	// Create a compressed message
	c := compress{
		Algo: deflateAlgo,
		Buf:  buf.Bytes(),
	}
	return encode(compressMsg, &c)
}

// decompressPayload is used to unpack an encoded compress{}
// message and return its payload uncompressed
func decompressPayload(msg []byte) ([]byte, error) {
	// Decode the message
	var c compress
	if err := decode(msg, &c); err != nil {
		return nil, err
	}
	return decompressBuffer(&c)
}

// decompressBuffer is used to decompress the buffer of
// a single compress message, handling multiple algorithms
func decompressBuffer(c *compress) ([]byte, error) {
	// Verify the algorithm
	if c.Algo != deflateAlgo {
		return nil, fmt.Errorf("Cannot decompress unknown algorithm %d", c.Algo)
	}

	// Create a uncompressor
	uncomp := flate.NewReader(bytes.NewReader(c.Buf))
	defer uncomp.Close()

	// Read all the data
	var b bytes.Buffer
	_, err := io.Copy(&b, uncomp)
	if err != nil {
		return nil, err
	}

	// Return the uncompressed bytes
	return b.Bytes(), nil
}
<commit_msg>Move compression level into a constant<commit_after>package memberlist

import (
	"bytes"
	"compress/flate"
	"encoding/binary"
	"fmt"
	"github.com/ugorji/go/codec"
	"io"
	"math"
	"math/rand"
	"net"
	"time"
)

// pushPullScale is the minimum number of nodes
// before we start scaling the push/pull timing. The scale
// effect is the log2(Nodes) - log2(pushPullScale). This means
// that the 33rd node will cause us to double the interval,
// while the 65th will triple it.
const pushPullScaleThreshold = 32

/*
 * Contains an entry for each private block:
 * 10.0.0.0/8
 * 172.16.0.0/12
 * 192.168/16
 */
var privateBlocks []*net.IPNet

const (
	// Constant compression level, between 1-9
	flateCompressLevel = 3
)

func init() {
	// Seed the random number generator
	rand.Seed(time.Now().UnixNano())

	// Add each private block
	privateBlocks = make([]*net.IPNet, 3)
	_, block, err := net.ParseCIDR("10.0.0.0/8")
	if err != nil {
		panic(fmt.Sprintf("Bad cidr. Got %v", err))
	}
	privateBlocks[0] = block

	_, block, err = net.ParseCIDR("172.16.0.0/12")
	if err != nil {
		panic(fmt.Sprintf("Bad cidr. Got %v", err))
	}
	privateBlocks[1] = block

	_, block, err = net.ParseCIDR("192.168.0.0/16")
	if err != nil {
		panic(fmt.Sprintf("Bad cidr. Got %v", err))
	}
	privateBlocks[2] = block
}

// Decode reverses the encode operation on a byte slice input
func decode(buf []byte, out interface{}) error {
	r := bytes.NewBuffer(buf)
	hd := codec.MsgpackHandle{}
	dec := codec.NewDecoder(r, &hd)
	return dec.Decode(out)
}

// Encode writes an encoded object to a new bytes buffer
func encode(msgType messageType, in interface{}) (*bytes.Buffer, error) {
	buf := bytes.NewBuffer(nil)
	buf.WriteByte(uint8(msgType))
	hd := codec.MsgpackHandle{}
	enc := codec.NewEncoder(buf, &hd)
	err := enc.Encode(in)
	return buf, err
}

// Returns a random offset between 0 and n
func randomOffset(n int) int {
	if n == 0 {
		return 0
	}
	return int(rand.Uint32() % uint32(n))
}

// suspicionTimeout computes the timeout that should be used when
// a node is suspected
func suspicionTimeout(suspicionMult, n int, interval time.Duration) time.Duration {
	nodeScale := math.Ceil(math.Log10(float64(n + 1)))
	timeout := time.Duration(suspicionMult) * time.Duration(nodeScale) * interval
	return timeout
}

// retransmitLimit computes the limit of retransmissions
func retransmitLimit(retransmitMult, n int) int {
	nodeScale := math.Ceil(math.Log10(float64(n + 1)))
	limit := retransmitMult * int(nodeScale)
	return limit
}

// shuffleNodes randomly shuffles the input nodes
func shuffleNodes(nodes []*nodeState) {
	for i := range nodes {
		j := rand.Intn(i + 1)
		nodes[i], nodes[j] = nodes[j], nodes[i]
	}
}

// pushPushScale is used to scale the time interval at which push/pull
// syncs take place. It is used to prevent network saturation as the
// cluster size grows
func pushPullScale(interval time.Duration, n int) time.Duration {
	// Don't scale until we cross the threshold
	if n <= pushPullScaleThreshold {
		return interval
	}

	multiplier := math.Ceil(math.Log2(float64(n))-math.Log2(pushPullScaleThreshold)) + 1.0
	return time.Duration(multiplier) * interval
}

// moveDeadNodes moves all the nodes in the dead state
// to the end of the slice and returns the index of the first dead node.
func moveDeadNodes(nodes []*nodeState) int {
	numDead := 0
	n := len(nodes)
	for i := 0; i < n-numDead; i++ {
		if nodes[i].State != stateDead {
			continue
		}

		// Move this node to the end
		nodes[i], nodes[n-numDead-1] = nodes[n-numDead-1], nodes[i]
		numDead++
		i--
	}
	return n - numDead
}

// kRandomNodes is used to select up to k random nodes, excluding a given
// node and any non-alive nodes. It is possible that less than k nodes are returned.
func kRandomNodes(k int, excludes []string, nodes []*nodeState) []*nodeState {
	n := len(nodes)
	kNodes := make([]*nodeState, 0, k)
OUTER:
	// Probe up to 3*n times, with large n this is not necessary
	// since k << n, but with small n we want search to be
	// exhaustive
	for i := 0; i < 3*n && len(kNodes) < k; i++ {
		// Get random node
		idx := randomOffset(n)
		node := nodes[idx]

		// Exclude node if match
		for _, exclude := range excludes {
			if node.Name == exclude {
				continue OUTER
			}
		}

		// Exclude if not alive
		if node.State != stateAlive {
			continue
		}

		// Check if we have this node already
		for j := 0; j < len(kNodes); j++ {
			if node == kNodes[j] {
				continue OUTER
			}
		}

		// Append the node
		kNodes = append(kNodes, node)
	}
	return kNodes
}

// makeCompoundMessage takes a list of messages and generates
// a single compound message containing all of them
func makeCompoundMessage(msgs [][]byte) *bytes.Buffer {
	// Create a local buffer
	buf := bytes.NewBuffer(nil)

	// Write out the type
	buf.WriteByte(uint8(compoundMsg))

	// Write out the number of message
	buf.WriteByte(uint8(len(msgs)))

	// Add the message lengths
	for _, m := range msgs {
		binary.Write(buf, binary.BigEndian, uint16(len(m)))
	}

	// Append the messages
	for _, m := range msgs {
		buf.Write(m)
	}

	return buf
}

// decodeCompoundMessage splits a compound message and returns
// the slices of individual messages. Also returns the number
// of truncated messages and any potential error
func decodeCompoundMessage(buf []byte) (trunc int, parts [][]byte, err error) {
	if len(buf) < 1 {
		err = fmt.Errorf("missing compound length byte")
		return
	}
	numParts := uint8(buf[0])
	buf = buf[1:]

	// Check we have enough bytes
	if len(buf) < int(numParts*2) {
		err = fmt.Errorf("truncated len slice")
		return
	}

	// Decode the lengths
	lengths := make([]uint16, numParts)
	for i := 0; i < int(numParts); i++ {
		lengths[i] = binary.BigEndian.Uint16(buf[i*2 : i*2+2])
	}
	buf = buf[numParts*2:]

	// Split each message
	for idx, msgLen := range lengths {
		if len(buf) < int(msgLen) {
			trunc = int(numParts) - idx
			return
		}

		// Extract the slice, seek past on the buffer
		slice := buf[:msgLen]
		buf = buf[msgLen:]
		parts = append(parts, slice)
	}
	return
}

// Returns if the given IP is in a private block
func isPrivateIP(ip_str string) bool {
	ip := net.ParseIP(ip_str)
	for _, priv := range privateBlocks {
		if priv.Contains(ip) {
			return true
		}
	}
	return false
}

// compressPayload takes an opaque input buffer, compresses it
// and wraps it in a compress{} message that is encoded.
func compressPayload(inp []byte) (*bytes.Buffer, error) {
	var buf bytes.Buffer
	compressor, err := flate.NewWriter(&buf, flateCompressLevel)
	if err != nil {
		return nil, err
	}

	_, err = compressor.Write(inp)
	if err != nil {
		return nil, err
	}

	// Ensure we flush everything out
	if err := compressor.Flush(); err != nil {
		return nil, err
	}
	if err := compressor.Close(); err != nil {
		return nil, err
	}

	// Create a compressed message
	c := compress{
		Algo: deflateAlgo,
		Buf:  buf.Bytes(),
	}
	return encode(compressMsg, &c)
}

// decompressPayload is used to unpack an encoded compress{}
// message and return its payload uncompressed
func decompressPayload(msg []byte) ([]byte, error) {
	// Decode the message
	var c compress
	if err := decode(msg, &c); err != nil {
		return nil, err
	}
	return decompressBuffer(&c)
}

// decompressBuffer is used to decompress the buffer of
// a single compress message, handling multiple algorithms
func decompressBuffer(c *compress) ([]byte, error) {
	// Verify the algorithm
	if c.Algo != deflateAlgo {
		return nil, fmt.Errorf("Cannot decompress unknown algorithm %d", c.Algo)
	}

	// Create a uncompressor
	uncomp := flate.NewReader(bytes.NewReader(c.Buf))
	defer uncomp.Close()

	// Read all the data
	var b bytes.Buffer
	_, err := io.Copy(&b, uncomp)
	if err != nil {
		return nil, err
	}

	// Return the uncompressed bytes
	return b.Bytes(), nil
}
<|endoftext|>


<commit_before>package sendgrid

import (
	"bytes"
	"encoding/json"
	"net/url"
)

// appendArray adds a list in url format.
func addArray(v *url.Values, name string, list []string) {
	for _, value := range list {
		v.Add(name, value)
	}
}

// appendMap adds a key value pairing map to the uri
func addMap(v *url.Values, name string, data map[string]string) error {
	if len(data) == 0 {
		return nil
	}
	b, err := json.Marshal(data)
	if err != nil {
		return err
	}
	v.Add(name, bytes.NewBuffer(b).String())
	return nil
}
<commit_msg>commenting<commit_after>package sendgrid

import (
	"bytes"
	"encoding/json"
	"net/url"
)

// addArray adds a list in url format.
func addArray(v *url.Values, name string, list []string) {
	for _, value := range list {
		v.Add(name, value)
	}
}

// addMap adds a key value pairing map to the uri
func addMap(v *url.Values, name string, data map[string]string) error {
	if len(data) == 0 {
		return nil
	}
	b, err := json.Marshal(data)
	if err != nil {
		return err
	}
	v.Add(name, bytes.NewBuffer(b).String())
	return nil
}
<|endoftext|>


<commit_before>package heartbleed_dtls

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

var logClientHello *log.Logger

func init() {
	// yes, this is ugly. I am to lazy to comment out my includes
	logClientHello = log.New(os.Stdout, "[ClientHello] ", 0)
	logClientHello = log.New(ioutil.Discard, "[ClientHello] ", 0)
}

func VisuallyCompareByteArray(a, b []byte) (hda, hdb, hddiff, places string) {
	var smaller, larger []byte
	lenA := len(a)
	lenB := len(b)
	if lenA > lenB {
		smaller = b
		larger = a
	} else {
		smaller = a
		larger = b
	}

	dOffsets := make([]int, len(larger))
	numDiffs := 0
	var diffMap bytes.Buffer

	for i, _ := range smaller {
		if smaller[i] == larger[i] {
			diffMap.Write([]byte{0x00})
		} else {
			diffMap.Write([]byte{0x58})
			dOffsets[numDiffs] = i
			numDiffs += 1
		}
	}
	for _, _ = range larger[len(smaller):] {
		diffMap.Write([]byte{0x2a})
	}

	diffDetails := bytes.NewBufferString("Offset (hex/dec): Value a   | Values b\n")
	for _, v := range dOffsets[:numDiffs] {
		diffDetails.WriteString(fmt.Sprintf("0x%04x (%04d)   : 0x%02x (%02d) | 0x%02x (%02d)\n", v, v, a[v], a[v], b[v], b[v]))
	}

	return hex.Dump(a), hex.Dump(b), hex.Dump(diffMap.Bytes()), diffDetails.String()
}
<commit_msg>Added comments to util.go.<commit_after>package heartbleed_dtls

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

var logClientHello *log.Logger

// crate a logger logClientHello which is used unconditionally. Switch the two
// lines to toggle between "debug" and "silent".
// Yes, this is ugly. I am to lazy to comment out my includes and I don't care about
// performance at this point.
// FIXME: make this a NOOP in production.
func init() {
	logClientHello = log.New(os.Stdout, "[ClientHello] ", 0)
	logClientHello = log.New(ioutil.Discard, "[ClientHello] ", 0)
}

// compare two byte arrays; returns hexdumps, a hexdump showing differences
// (X = difference, * = only present in one array) and a list showing place
// and nature of difference.
func VisuallyCompareByteArray(a, b []byte) (hda, hdb, hddiff, places string) {
	var smaller, larger []byte
	lenA := len(a)
	lenB := len(b)
	if lenA > lenB {
		smaller = b
		larger = a
	} else {
		smaller = a
		larger = b
	}

	dOffsets := make([]int, len(larger))
	numDiffs := 0
	var diffMap bytes.Buffer

	for i, _ := range smaller {
		if smaller[i] == larger[i] {
			diffMap.Write([]byte{0x00})
		} else {
			diffMap.Write([]byte{0x58})
			dOffsets[numDiffs] = i
			numDiffs += 1
		}
	}
	for _, _ = range larger[len(smaller):] {
		diffMap.Write([]byte{0x2a})
	}

	diffDetails := bytes.NewBufferString("Offset (hex/dec): Value a   | Values b\n")
	for _, v := range dOffsets[:numDiffs] {
		diffDetails.WriteString(fmt.Sprintf("0x%04x (%04d)   : 0x%02x (%02d) | 0x%02x (%02d)\n", v, v, a[v], a[v], b[v], b[v]))
	}

	return hex.Dump(a), hex.Dump(b), hex.Dump(diffMap.Bytes()), diffDetails.String()
}
<|endoftext|>


<commit_before>package wca

func StringifyState(state uint32) string {
	switch state {
	case DEVICE_STATE_ACTIVE:
		return "active"
	case DEVICE_STATE_DISABLED:
		return "disabled"
	default:
		return ""
	}
}
<commit_msg>Remove<commit_after><|endoftext|>


<commit_before>// Collection of small, useful utility functions
package main

import (
	"bufio"
	"flag"
	"io"
	"net"
	"os"
	"strings"
	"time"

	"github.com/davidnarayan/go-logging"
)

// TimeoutDialer creates a Dialer that can timeout after a connection timeout
// or a read timeout
func TimeoutDialer(connTimeout, rwTimeout time.Duration) func(netw, addr string) (c net.Conn, err error) {
	return func(netw, addr string) (net.Conn, error) {
		conn, err := net.DialTimeout(netw, addr, connTimeout)

		if err != nil {
			return nil, err
		}

		conn.SetDeadline(time.Now().Add(rwTimeout))

		return conn, nil
	}
}

// ExitWhenOrphaned checks if the current process becomes orphaned and
// immediately kills the script. This prevents multiple instances of the
// script running indefinitely when it's being launched by some external
// process (e.g. Splunk).
func ExitWhenOrphaned() {
	tick1s := time.NewTicker(time.Second * 1).C

	// Check for orphaned process
	go func() {
		for {
			select {
			case <-tick1s:
				if os.Getppid() == 1 {
					logging.Fatal("Orphaned process! Exiting!")
				}
			}
		}
	}()
}

// Collect args from files or stdin
func GetArgs() (args []string) {
	var inputs []io.Reader

	// Check for files first and use stdin if no files are specified
	files := flag.Args()

	if len(files) > 0 {
		for _, file := range files {
			input, err := os.Open(file)

			if err != nil {
				logging.Warn(err.Error())
				continue
			}

			inputs = append(inputs, input)
		}
	} else {
		inputs = append(inputs, os.Stdin)
	}

	// Scan all inputs for arguments
	for _, input := range inputs {
		scanner := bufio.NewScanner(input)

		for scanner.Scan() {
			line := scanner.Text()
			// Skip empty lines and comments
			arg := strings.TrimSpace(line)

			if arg == "" || strings.HasPrefix(arg, "#") {
				continue
			}

			args = append(args, arg)
			logging.Trace("Adding arg: %s", arg)
		}

		if err := scanner.Err(); err != nil {
			logging.Error("Unable to add line: %s", err)
		}
	}

	return args
}
<commit_msg>rename package to util<commit_after>// Collection of small, useful utility functions
package util

import (
	"bufio"
	"flag"
	"io"
	"net"
	"os"
	"strings"
	"time"

	"github.com/davidnarayan/go-logging"
)

// TimeoutDialer creates a Dialer that can timeout after a connection timeout
// or a read timeout
func TimeoutDialer(connTimeout, rwTimeout time.Duration) func(netw, addr string) (c net.Conn, err error) {
	return func(netw, addr string) (net.Conn, error) {
		conn, err := net.DialTimeout(netw, addr, connTimeout)

		if err != nil {
			return nil, err
		}

		conn.SetDeadline(time.Now().Add(rwTimeout))

		return conn, nil
	}
}

// ExitWhenOrphaned checks if the current process becomes orphaned and
// immediately kills the script. This prevents multiple instances of the
// script running indefinitely when it's being launched by some external
// process (e.g. Splunk).
func ExitWhenOrphaned() {
	tick1s := time.NewTicker(time.Second * 1).C

	// Check for orphaned process
	go func() {
		for {
			select {
			case <-tick1s:
				if os.Getppid() == 1 {
					logging.Fatal("Orphaned process! Exiting!")
				}
			}
		}
	}()
}

// Collect args from files or stdin
func GetArgs() (args []string) {
	var inputs []io.Reader

	// Check for files first and use stdin if no files are specified
	files := flag.Args()

	if len(files) > 0 {
		for _, file := range files {
			input, err := os.Open(file)

			if err != nil {
				logging.Warn(err.Error())
				continue
			}

			inputs = append(inputs, input)
		}
	} else {
		inputs = append(inputs, os.Stdin)
	}

	// Scan all inputs for arguments
	for _, input := range inputs {
		scanner := bufio.NewScanner(input)

		for scanner.Scan() {
			line := scanner.Text()
			// Skip empty lines and comments
			arg := strings.TrimSpace(line)

			if arg == "" || strings.HasPrefix(arg, "#") {
				continue
			}

			args = append(args, arg)
			logging.Trace("Adding arg: %s", arg)
		}

		if err := scanner.Err(); err != nil {
			logging.Error("Unable to add line: %s", err)
		}
	}

	return args
}
<|endoftext|>