<commit_before>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package build

// TODO(adg): test authentication

import (
	"appengine"
	"appengine/datastore"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"time"
)

func init() {
	http.HandleFunc("/buildtest", testHandler)
}

var testEntityKinds = []string{
	"Package",
	"Commit",
	"Result",
	"Log",
}

const testPkg = "code.google.com/p/go.test"

var testPackage = &Package{Name: "Test", Kind: "subrepo", Path: testPkg}

var testPackages = []*Package{
	{Name: "Go", Path: ""},
	testPackage,
}

var tCommitTime = time.Now().Add(-time.Hour * 24 * 7)

func tCommit(hash, parentHash string) *Commit {
	tCommitTime.Add(time.Hour) // each commit should have a different time
	return &Commit{
		Hash:       hash,
		ParentHash: parentHash,
		Time:       tCommitTime,
		User:       "adg",
		Desc:       "change description",
	}
}

var testRequests = []struct {
	path string
	vals url.Values
	req  interface{}
	res  interface{}
}{
	// Packages
	{"/packages?kind=subrepo", nil, nil, []*Package{testPackage}},

	// Go repo
	{"/commit", nil, tCommit("0001", "0000"), nil},
	{"/commit", nil, tCommit("0002", "0001"), nil},
	{"/commit", nil, tCommit("0003", "0002"), nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0002", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},

	// multiple builders
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-amd64", Hash: "0003", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0002"}}},

	// branches
	{"/commit", nil, tCommit("0004", "0003"), nil},
	{"/commit", nil, tCommit("0005", "0002"), nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0005", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0004"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0004", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},

	// logs
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},
	{"/log/a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", nil, nil, "test"},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},

	// repeat failure (shouldn't re-send mail)
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},

	// non-Go repos
	{"/commit", nil, &Commit{PackagePath: testPkg, Hash: "1001", ParentHash: "1000"}, nil},
	{"/commit", nil, &Commit{PackagePath: testPkg, Hash: "1002", ParentHash: "1001"}, nil},
	{"/commit", nil, &Commit{PackagePath: testPkg, Hash: "1003", ParentHash: "1002"}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1003", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1002"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1002", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1001"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0002"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},

	// re-build Go revision for stale subrepos
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0005", OK: false, Log: "boo"}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},
}

func testHandler(w http.ResponseWriter, r *http.Request) {
	if !appengine.IsDevAppServer() {
		fmt.Fprint(w, "These tests must be run under the dev_appserver.")
		return
	}
	c := appengine.NewContext(r)
	if err := nukeEntities(c, testEntityKinds); err != nil {
		logErr(w, r, err)
		return
	}
	if r.FormValue("nukeonly") != "" {
		fmt.Fprint(w, "OK")
		return
	}

	for _, p := range testPackages {
		if _, err := datastore.Put(c, p.Key(c), p); err != nil {
			logErr(w, r, err)
			return
		}
	}

	for i, t := range testRequests {
		c.Infof("running test %d %s", i, t.path)
		errorf := func(format string, args ...interface{}) {
			fmt.Fprintf(w, "%d %s: ", i, t.path)
			fmt.Fprintf(w, format, args...)
			fmt.Fprintln(w)
		}
		var body io.ReadWriter
		if t.req != nil {
			body = new(bytes.Buffer)
			json.NewEncoder(body).Encode(t.req)
		}
		url := "http://" + domain + t.path
		if t.vals != nil {
			url += "?" + t.vals.Encode()
		}
		req, err := http.NewRequest("POST", url, body)
		if err != nil {
			logErr(w, r, err)
			return
		}
		if t.req != nil {
			req.Method = "POST"
		}
		req.Header = r.Header
		rec := httptest.NewRecorder()

		// Make the request
		http.DefaultServeMux.ServeHTTP(rec, req)

		if rec.Code != 0 && rec.Code != 200 {
			errorf(rec.Body.String())
			return
		}
		resp := new(dashResponse)

		// If we're expecting a *Todo value,
		// prime the Response field with a Todo and a Commit inside it.
		if _, ok := t.res.(*Todo); ok {
			resp.Response = &Todo{Data: &Commit{}}
		}

		if strings.HasPrefix(t.path, "/log/") {
			resp.Response = rec.Body.String()
		} else {
			err := json.NewDecoder(rec.Body).Decode(resp)
			if err != nil {
				errorf("decoding response: %v", err)
				return
			}
		}
		if e, ok := t.res.(string); ok {
			g, ok := resp.Response.(string)
			if !ok {
				errorf("Response not string: %T", resp.Response)
				return
			}
			if g != e {
				errorf("response mismatch: got %q want %q", g, e)
				return
			}
		}
		if e, ok := t.res.(*Todo); ok {
			g, ok := resp.Response.(*Todo)
			if !ok {
				errorf("Response not *Todo: %T", resp.Response)
				return
			}
			if e.Data == nil && g.Data != nil {
				errorf("Response.Data should be nil, got: %v", g.Data)
				return
			}
			if g.Data == nil {
				errorf("Response.Data is nil, want: %v", e.Data)
				return
			}
			gd, ok := g.Data.(*Commit)
			if !ok {
				errorf("Response.Data not *Commit: %T", g.Data)
				return
			}
			if eh := e.Data.(*Commit).Hash; eh != gd.Hash {
				errorf("hashes don't match: got %q, want %q", gd.Hash, eh)
				return
			}
		}
		if t.res == nil && resp.Response != nil {
			errorf("response mismatch: got %q expected <nil>",
				resp.Response)
			return
		}
	}
	fmt.Fprint(w, "PASS")
}

func nukeEntities(c appengine.Context, kinds []string) error {
	if !appengine.IsDevAppServer() {
		return errors.New("can't nuke production data")
	}
	var keys []*datastore.Key
	for _, kind := range kinds {
		q := datastore.NewQuery(kind).KeysOnly()
		for t := q.Run(c); ; {
			k, err := t.Next(nil)
			if err == datastore.Done {
				break
			}
			if err != nil {
				return err
			}
			keys = append(keys, k)
		}
	}
	return datastore.DeleteMulti(c, keys)
}
<commit_msg>misc/dashboard/app: fix tests<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package build

// TODO(adg): test authentication

import (
	"appengine"
	"appengine/datastore"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"time"
)

func init() {
	http.HandleFunc("/buildtest", testHandler)
}

var testEntityKinds = []string{
	"Package",
	"Commit",
	"Result",
	"Log",
}

const testPkg = "code.google.com/p/go.test"

var testPackage = &Package{Name: "Test", Kind: "subrepo", Path: testPkg}

var testPackages = []*Package{
	{Name: "Go", Path: ""},
	testPackage,
}

var tCommitTime = time.Now().Add(-time.Hour * 24 * 7)

func tCommit(hash, parentHash, path string) *Commit {
	tCommitTime.Add(time.Hour) // each commit should have a different time
	return &Commit{
		PackagePath: path,
		Hash:        hash,
		ParentHash:  parentHash,
		Time:        tCommitTime,
		User:        "adg",
		Desc:        "change description " + hash,
	}
}

var testRequests = []struct {
	path string
	vals url.Values
	req  interface{}
	res  interface{}
}{
	// Packages
	{"/packages?kind=subrepo", nil, nil, []*Package{testPackage}},

	// Go repo
	{"/commit", nil, tCommit("0001", "0000", ""), nil},
	{"/commit", nil, tCommit("0002", "0001", ""), nil},
	{"/commit", nil, tCommit("0003", "0002", ""), nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0002", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},

	// multiple builders
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-amd64", Hash: "0003", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0002"}}},

	// branches
	{"/commit", nil, tCommit("0004", "0003", ""), nil},
	{"/commit", nil, tCommit("0005", "0002", ""), nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0005", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0004"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0004", OK: false}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},

	// logs
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},
	{"/log/a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", nil, nil, "test"},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},

	// repeat failure (shouldn't re-send mail)
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},

	// non-Go repos
	{"/commit", nil, tCommit("1001", "1000", testPkg), nil},
	{"/commit", nil, tCommit("1002", "1001", testPkg), nil},
	{"/commit", nil, tCommit("1003", "1002", testPkg), nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1003", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1002"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1002", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1001"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0002"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},

	// re-build Go revision for stale subrepos
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0005", OK: false, Log: "boo"}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},
}

func testHandler(w http.ResponseWriter, r *http.Request) {
	if !appengine.IsDevAppServer() {
		fmt.Fprint(w, "These tests must be run under the dev_appserver.")
		return
	}
	c := appengine.NewContext(r)
	if err := nukeEntities(c, testEntityKinds); err != nil {
		logErr(w, r, err)
		return
	}
	if r.FormValue("nukeonly") != "" {
		fmt.Fprint(w, "OK")
		return
	}

	for _, p := range testPackages {
		if _, err := datastore.Put(c, p.Key(c), p); err != nil {
			logErr(w, r, err)
			return
		}
	}

	for i, t := range testRequests {
		c.Infof("running test %d %s", i, t.path)
		errorf := func(format string, args ...interface{}) {
			fmt.Fprintf(w, "%d %s: ", i, t.path)
			fmt.Fprintf(w, format, args...)
			fmt.Fprintln(w)
		}
		var body io.ReadWriter
		if t.req != nil {
			body = new(bytes.Buffer)
			json.NewEncoder(body).Encode(t.req)
		}
		url := "http://" + domain + t.path
		if t.vals != nil {
			url += "?" + t.vals.Encode()
		}
		req, err := http.NewRequest("POST", url, body)
		if err != nil {
			logErr(w, r, err)
			return
		}
		if t.req != nil {
			req.Method = "POST"
		}
		req.Header = r.Header
		rec := httptest.NewRecorder()

		// Make the request
		http.DefaultServeMux.ServeHTTP(rec, req)

		if rec.Code != 0 && rec.Code != 200 {
			errorf(rec.Body.String())
			return
		}
		resp := new(dashResponse)

		// If we're expecting a *Todo value,
		// prime the Response field with a Todo and a Commit inside it.
		if _, ok := t.res.(*Todo); ok {
			resp.Response = &Todo{Data: &Commit{}}
		}

		if strings.HasPrefix(t.path, "/log/") {
			resp.Response = rec.Body.String()
		} else {
			err := json.NewDecoder(rec.Body).Decode(resp)
			if err != nil {
				errorf("decoding response: %v", err)
				return
			}
		}
		if e, ok := t.res.(string); ok {
			g, ok := resp.Response.(string)
			if !ok {
				errorf("Response not string: %T", resp.Response)
				return
			}
			if g != e {
				errorf("response mismatch: got %q want %q", g, e)
				return
			}
		}
		if e, ok := t.res.(*Todo); ok {
			g, ok := resp.Response.(*Todo)
			if !ok {
				errorf("Response not *Todo: %T", resp.Response)
				return
			}
			if e.Data == nil && g.Data != nil {
				errorf("Response.Data should be nil, got: %v", g.Data)
				return
			}
			if g.Data == nil {
				errorf("Response.Data is nil, want: %v", e.Data)
				return
			}
			gd, ok := g.Data.(*Commit)
			if !ok {
				errorf("Response.Data not *Commit: %T", g.Data)
				return
			}
			if eh := e.Data.(*Commit).Hash; eh != gd.Hash {
				errorf("hashes don't match: got %q, want %q", gd.Hash, eh)
				return
			}
		}
		if t.res == nil && resp.Response != nil {
			errorf("response mismatch: got %q expected <nil>",
				resp.Response)
			return
		}
	}
	fmt.Fprint(w, "PASS\nYou should see only one mail notification (for 0003/linux-386) in the dev_appserver logs.")
}

func nukeEntities(c appengine.Context, kinds []string) error {
	if !appengine.IsDevAppServer() {
		return errors.New("can't nuke production data")
	}
	var keys []*datastore.Key
	for _, kind := range kinds {
		q := datastore.NewQuery(kind).KeysOnly()
		for t := q.Run(c); ; {
			k, err := t.Next(nil)
			if err == datastore.Done {
				break
			}
			if err != nil {
				return err
			}
			keys = append(keys, k)
		}
	}
	return datastore.DeleteMulti(c, keys)
}
<|endoftext|>


<commit_before>package gofakeit

import "math/rand"

// Color will generate a random color string
func Color() string {
	return color(globalFaker.Rand)
}

// Color will generate a random color string
func (f *Faker) Color() string {
	return color(f.Rand)
}

func color(r *rand.Rand) string {
	return getRandValue(r, []string{"color", "full"})
}

// SafeColor will generate a random safe color string
func SafeColor() string {
	return safeColor(globalFaker.Rand)
}

// SafeColor will generate a random safe color string
func (f *Faker) SafeColor() string {
	return safeColor(f.Rand)
}

func safeColor(r *rand.Rand) string {
	return getRandValue(r, []string{"color", "safe"})
}

// HexColor will generate a random hexadecimal color string
func HexColor() string {
	return hexColor(globalFaker.Rand)
}

// HexColor will generate a random hexadecimal color string
func (f *Faker) HexColor() string {
	return hexColor(f.Rand)
}

func hexColor(r *rand.Rand) string {
	color := make([]byte, 6)
	hashQuestion := []byte("?#")
	for i := 0; i < 6; i++ {
		color[i] = hashQuestion[r.Intn(2)]
	}

	return "#" + replaceWithHexLetters(r, replaceWithNumbers(r, string(color)))
}

// RGBColor will generate a random int slice color
func RGBColor() []int {
	return rgbColor(globalFaker.Rand)
}

// RGBColor will generate a random int slice color
func (f *Faker) RGBColor() []int {
	return rgbColor(f.Rand)
}

func rgbColor(r *rand.Rand) []int {
	return []int{randIntRange(r, 0, 255), randIntRange(r, 0, 255), randIntRange(r, 0, 255)}
}

func addColorLookup() {
	AddFuncLookup("color", Info{
		Display:     "Color",
		Category:    "color",
		Description: "Random color",
		Example:     "MediumOrchid",
		Output:      "string",
		Call: func(m *map[string][]string, info *Info) (interface{}, error) {
			return Color(), nil
		},
	})

	AddFuncLookup("safecolor", Info{
		Display:     "Safe Color",
		Category:    "color",
		Description: "Random safe color",
		Example:     "black",
		Output:      "string",
		Call: func(m *map[string][]string, info *Info) (interface{}, error) {
			return SafeColor(), nil
		},
	})

	AddFuncLookup("hexcolor", Info{
		Display:     "Hex Color",
		Category:    "color",
		Description: "Random hex color",
		Example:     "#a99fb4",
		Output:      "string",
		Call: func(m *map[string][]string, info *Info) (interface{}, error) {
			return HexColor(), nil
		},
	})

	AddFuncLookup("rgbcolor", Info{
		Display:     "RGB Color",
		Category:    "color",
		Description: "Random rgb color",
		Example:     "[152 23 53]",
		Output:      "string",
		Call: func(m *map[string][]string, info *Info) (interface{}, error) {
			return RGBColor(), nil
		},
	})
}
<commit_msg>color - tighten<commit_after>package gofakeit

import "math/rand"

// Color will generate a random color string
func Color() string { return color(globalFaker.Rand) }

// Color will generate a random color string
func (f *Faker) Color() string { return color(f.Rand) }

func color(r *rand.Rand) string { return getRandValue(r, []string{"color", "full"}) }

// SafeColor will generate a random safe color string
func SafeColor() string { return safeColor(globalFaker.Rand) }

// SafeColor will generate a random safe color string
func (f *Faker) SafeColor() string { return safeColor(f.Rand) }

func safeColor(r *rand.Rand) string { return getRandValue(r, []string{"color", "safe"}) }

// HexColor will generate a random hexadecimal color string
func HexColor() string { return hexColor(globalFaker.Rand) }

// HexColor will generate a random hexadecimal color string
func (f *Faker) HexColor() string { return hexColor(f.Rand) }

func hexColor(r *rand.Rand) string {
	color := make([]byte, 6)
	hashQuestion := []byte("?#")
	for i := 0; i < 6; i++ {
		color[i] = hashQuestion[r.Intn(2)]
	}

	return "#" + replaceWithHexLetters(r, replaceWithNumbers(r, string(color)))
}

// RGBColor will generate a random int slice color
func RGBColor() []int { return rgbColor(globalFaker.Rand) }

// RGBColor will generate a random int slice color
func (f *Faker) RGBColor() []int { return rgbColor(f.Rand) }

func rgbColor(r *rand.Rand) []int {
	return []int{randIntRange(r, 0, 255), randIntRange(r, 0, 255), randIntRange(r, 0, 255)}
}

func addColorLookup() {
	AddFuncLookup("color", Info{
		Display:     "Color",
		Category:    "color",
		Description: "Random color",
		Example:     "MediumOrchid",
		Output:      "string",
		Call: func(m *map[string][]string, info *Info) (interface{}, error) {
			return Color(), nil
		},
	})

	AddFuncLookup("safecolor", Info{
		Display:     "Safe Color",
		Category:    "color",
		Description: "Random safe color",
		Example:     "black",
		Output:      "string",
		Call: func(m *map[string][]string, info *Info) (interface{}, error) {
			return SafeColor(), nil
		},
	})

	AddFuncLookup("hexcolor", Info{
		Display:     "Hex Color",
		Category:    "color",
		Description: "Random hex color",
		Example:     "#a99fb4",
		Output:      "string",
		Call: func(m *map[string][]string, info *Info) (interface{}, error) {
			return HexColor(), nil
		},
	})

	AddFuncLookup("rgbcolor", Info{
		Display:     "RGB Color",
		Category:    "color",
		Description: "Random rgb color",
		Example:     "[152 23 53]",
		Output:      "string",
		Call: func(m *map[string][]string, info *Info) (interface{}, error) {
			return RGBColor(), nil
		},
	})
}
<|endoftext|>


<commit_before>package humanize

import (
	"bytes"
	"math/big"
	"strconv"
	"strings"
)

// Comma produces a string form of the given number in base 10 with
// commas after every three orders of magnitude.
//
// e.g. Comma(834142) -> 834,142
func Comma(v int64) string {
	sign := ""
	if v < 0 {
		sign = "-"
		v = 0 - v
	}

	parts := []string{"", "", "", "", "", "", "", ""}
	j := len(parts) - 1

	for v > 999 {
		parts[j] = strconv.FormatInt(v%1000, 10)
		switch len(parts[j]) {
		case 2:
			parts[j] = "0" + parts[j]
		case 1:
			parts[j] = "00" + parts[j]
		}
		v = v / 1000
		j--
	}
	parts[j] = strconv.Itoa(int(v))
	return sign + strings.Join(parts[j:len(parts)], ",")
}

// Commaf produces a string form of the given number in base 10 with
// commas after every three orders of magnitude.
//
// e.g. Comma(834142.32) -> 834,142.32
func Commaf(v float64) string {
	buf := &bytes.Buffer{}
	if v < 0 {
		buf.Write([]byte{'-'})
		v = 0 - v
	}

	comma := []byte{','}

	parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
	pos := 0
	if len(parts[0])%3 != 0 {
		pos += len(parts[0]) % 3
		buf.WriteString(parts[0][:pos])
		buf.Write(comma)
	}
	for ; pos < len(parts[0]); pos += 3 {
		buf.WriteString(parts[0][pos : pos+3])
		buf.Write(comma)
	}
	buf.Truncate(buf.Len() - 1)

	if len(parts) > 1 {
		buf.Write([]byte{'.'})
		buf.WriteString(parts[1])
	}
	return buf.String()
}

// BigComma produces a string form of the given big.Int in base 10
// with commas after every three orders of magnitude.
func BigComma(b *big.Int) string {
	sign := ""
	if b.Sign() < 0 {
		sign = "-"
		b.Abs(b)
	}

	athousand := big.NewInt(1000)
	c := (&big.Int{}).Set(b)
	_, m := oom(c, athousand)
	parts := make([]string, m+1)
	j := len(parts) - 1

	mod := &big.Int{}
	for b.Cmp(athousand) >= 0 {
		b.DivMod(b, athousand, mod)
		parts[j] = strconv.FormatInt(mod.Int64(), 10)
		switch len(parts[j]) {
		case 2:
			parts[j] = "0" + parts[j]
		case 1:
			parts[j] = "00" + parts[j]
		}
		j--
	}
	parts[j] = strconv.Itoa(int(b.Int64()))
	return sign + strings.Join(parts[j:len(parts)], ",")
}
<commit_msg>Running gofmt<commit_after>package humanize

import (
	"bytes"
	"math/big"
	"strconv"
	"strings"
)

// Comma produces a string form of the given number in base 10 with
// commas after every three orders of magnitude.
//
// e.g. Comma(834142) -> 834,142
func Comma(v int64) string {
	sign := ""
	if v < 0 {
		sign = "-"
		v = 0 - v
	}

	parts := []string{"", "", "", "", "", "", "", ""}
	j := len(parts) - 1

	for v > 999 {
		parts[j] = strconv.FormatInt(v%1000, 10)
		switch len(parts[j]) {
		case 2:
			parts[j] = "0" + parts[j]
		case 1:
			parts[j] = "00" + parts[j]
		}
		v = v / 1000
		j--
	}
	parts[j] = strconv.Itoa(int(v))
	return sign + strings.Join(parts[j:], ",")
}

// Commaf produces a string form of the given number in base 10 with
// commas after every three orders of magnitude.
//
// e.g. Comma(834142.32) -> 834,142.32
func Commaf(v float64) string {
	buf := &bytes.Buffer{}
	if v < 0 {
		buf.Write([]byte{'-'})
		v = 0 - v
	}

	comma := []byte{','}

	parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
	pos := 0
	if len(parts[0])%3 != 0 {
		pos += len(parts[0]) % 3
		buf.WriteString(parts[0][:pos])
		buf.Write(comma)
	}
	for ; pos < len(parts[0]); pos += 3 {
		buf.WriteString(parts[0][pos : pos+3])
		buf.Write(comma)
	}
	buf.Truncate(buf.Len() - 1)

	if len(parts) > 1 {
		buf.Write([]byte{'.'})
		buf.WriteString(parts[1])
	}
	return buf.String()
}

// BigComma produces a string form of the given big.Int in base 10
// with commas after every three orders of magnitude.
func BigComma(b *big.Int) string {
	sign := ""
	if b.Sign() < 0 {
		sign = "-"
		b.Abs(b)
	}

	athousand := big.NewInt(1000)
	c := (&big.Int{}).Set(b)
	_, m := oom(c, athousand)
	parts := make([]string, m+1)
	j := len(parts) - 1

	mod := &big.Int{}
	for b.Cmp(athousand) >= 0 {
		b.DivMod(b, athousand, mod)
		parts[j] = strconv.FormatInt(mod.Int64(), 10)
		switch len(parts[j]) {
		case 2:
			parts[j] = "0" + parts[j]
		case 1:
			parts[j] = "00" + parts[j]
		}
		j--
	}
	parts[j] = strconv.Itoa(int(b.Int64()))
	return sign + strings.Join(parts[j:], ",")
}
<|endoftext|>


<commit_before>package humanize

import (
	"bytes"
	"math/big"
	"strconv"
	"strings"
)

// Comma produces a string form of the given number in base 10 with
// commas after every three orders of magnitude.
//
// e.g. Comma(834142) -> 834,142
func Comma(v int64) string {
	sign := ""
	if v < 0 {
		sign = "-"
		v = 0 - v
	}

	parts := []string{"", "", "", "", "", "", "", ""}
	j := len(parts) - 1

	for v > 999 {
		parts[j] = strconv.FormatInt(v%1000, 10)
		switch len(parts[j]) {
		case 2:
			parts[j] = "0" + parts[j]
		case 1:
			parts[j] = "00" + parts[j]
		}
		v = v / 1000
		j--
	}
	parts[j] = strconv.Itoa(int(v))
	return sign + strings.Join(parts[j:len(parts)], ",")
}

// Commaf produces a string form of the given number in base 10 with
// commas after every three orders of magnitude.
//
// e.g. Comma(834142.32) -> 834,142.32
func Commaf(v float64) string {
	buf := &bytes.Buffer{}
	if v < 0 {
		buf.Write([]byte{'-'})
		v = 0 - v
	}

	comma := []byte{','}

	parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
	pos := 0
	if len(parts[0])%3 != 0 {
		pos += len(parts[0]) % 3
		buf.WriteString(parts[0][:pos])
		if len(parts[0]) > pos+2 {
			buf.Write(comma)
		}
	}
	for ; pos < len(parts[0]); pos += 3 {
		buf.WriteString(parts[0][pos : pos+3])
		if len(parts[0]) > pos+3 {
			buf.Write(comma)
		}
	}

	if len(parts) > 1 {
		buf.Write([]byte{'.'})
		buf.WriteString(parts[1])
	}
	return buf.String()
}

// BigComma produces a string form of the given big.Int in base 10
// with commas after every three orders of magnitude.
func BigComma(b *big.Int) string {
	sign := ""
	if b.Sign() < 0 {
		sign = "-"
		b.Abs(b)
	}

	athousand := big.NewInt(1000)
	c := (&big.Int{}).Set(b)
	_, m := oom(c, athousand)
	parts := make([]string, m+1)
	j := len(parts) - 1

	mod := &big.Int{}
	for b.Cmp(athousand) >= 0 {
		b.DivMod(b, athousand, mod)
		parts[j] = strconv.FormatInt(mod.Int64(), 10)
		switch len(parts[j]) {
		case 2:
			parts[j] = "0" + parts[j]
		case 1:
			parts[j] = "00" + parts[j]
		}
		j--
	}
	parts[j] = strconv.Itoa(int(b.Int64()))
	return sign + strings.Join(parts[j:len(parts)], ",")
}
<commit_msg>Negligble performance difference, but a lot cleaner commaf<commit_after>package humanize

import (
	"bytes"
	"math/big"
	"strconv"
	"strings"
)

// Comma produces a string form of the given number in base 10 with
// commas after every three orders of magnitude.
//
// e.g. Comma(834142) -> 834,142
func Comma(v int64) string {
	sign := ""
	if v < 0 {
		sign = "-"
		v = 0 - v
	}

	parts := []string{"", "", "", "", "", "", "", ""}
	j := len(parts) - 1

	for v > 999 {
		parts[j] = strconv.FormatInt(v%1000, 10)
		switch len(parts[j]) {
		case 2:
			parts[j] = "0" + parts[j]
		case 1:
			parts[j] = "00" + parts[j]
		}
		v = v / 1000
		j--
	}
	parts[j] = strconv.Itoa(int(v))
	return sign + strings.Join(parts[j:len(parts)], ",")
}

// Commaf produces a string form of the given number in base 10 with
// commas after every three orders of magnitude.
//
// e.g. Comma(834142.32) -> 834,142.32
func Commaf(v float64) string {
	buf := &bytes.Buffer{}
	if v < 0 {
		buf.Write([]byte{'-'})
		v = 0 - v
	}

	comma := []byte{','}

	parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
	pos := 0
	if len(parts[0])%3 != 0 {
		pos += len(parts[0]) % 3
		buf.WriteString(parts[0][:pos])
		buf.Write(comma)
	}
	for ; pos < len(parts[0]); pos += 3 {
		buf.WriteString(parts[0][pos : pos+3])
		buf.Write(comma)
	}
	buf.Truncate(buf.Len() - 1)

	if len(parts) > 1 {
		buf.Write([]byte{'.'})
		buf.WriteString(parts[1])
	}
	return buf.String()
}

// BigComma produces a string form of the given big.Int in base 10
// with commas after every three orders of magnitude.
func BigComma(b *big.Int) string {
	sign := ""
	if b.Sign() < 0 {
		sign = "-"
		b.Abs(b)
	}

	athousand := big.NewInt(1000)
	c := (&big.Int{}).Set(b)
	_, m := oom(c, athousand)
	parts := make([]string, m+1)
	j := len(parts) - 1

	mod := &big.Int{}
	for b.Cmp(athousand) >= 0 {
		b.DivMod(b, athousand, mod)
		parts[j] = strconv.FormatInt(mod.Int64(), 10)
		switch len(parts[j]) {
		case 2:
			parts[j] = "0" + parts[j]
		case 1:
			parts[j] = "00" + parts[j]
		}
		j--
	}
	parts[j] = strconv.Itoa(int(b.Int64()))
	return sign + strings.Join(parts[j:len(parts)], ",")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"sort"
	"strings"
)

// dep => version
type dependencyMap map[string]string

func depfileExists() bool {
	fi, err := os.Stat(depsFile)
	return !os.IsNotExist(err) && !fi.IsDir()
}

func readDepFile() (dependencyMap, error) {
	if !depfileExists() {
		return nil, fmt.Errorf("%s file does not exist", depsFile)
	}

	b, err := ioutil.ReadFile(depsFile)
	if err != nil {
		return nil, err
	}

	deps := make(dependencyMap, len(b))
	lines := strings.Split(string(b), "\n")
	for i, line := range lines {

		// strip comments from line
		lineAndComment := strings.SplitN(line, "#", 2)
		line = lineAndComment[0]
		line = strings.TrimSpace(line)

		// ignore empty lines
		if line == "" {
			continue
		}

		// split on whitespace
		d := strings.Fields(line)

		if len(d) != 2 {
			return nil, fmt.Errorf("Couldn't parse line %d of depfile %s", i+1, depsFile)
		}

		deps[d[0]] = d[1]
	}

	return deps, nil
}

func writeDepFile(deps dependencyMap) error {

	// sort the dep paths
	klen := 0
	var keys []string
	for k := range deps {
		keys = append(keys, k)
		if len(k) > klen {
			klen = len(k)
		}
	}
	sort.Strings(keys)

	f, err := os.OpenFile(depsFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		return err
	}
	defer f.Close()

	for _, dep := range keys {
		version := deps[dep]

		line := fmt.Sprintf("%-[3]*[1]s %[2]s", dep, version, klen+1)

		if _, err = f.WriteString(line + "\n"); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Fix spacing in Godeps<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"sort"
	"strings"
)

// dep => version
type dependencyMap map[string]string

func depfileExists() bool {
	fi, err := os.Stat(depsFile)
	return !os.IsNotExist(err) && !fi.IsDir()
}

func readDepFile() (dependencyMap, error) {
	if !depfileExists() {
		return nil, fmt.Errorf("%s file does not exist", depsFile)
	}

	b, err := ioutil.ReadFile(depsFile)
	if err != nil {
		return nil, err
	}

	deps := make(dependencyMap, len(b))
	lines := strings.Split(string(b), "\n")
	for i, line := range lines {

		// strip comments from line
		lineAndComment := strings.SplitN(line, "#", 2)
		line = lineAndComment[0]
		line = strings.TrimSpace(line)

		// ignore empty lines
		if line == "" {
			continue
		}

		// split on whitespace
		d := strings.Fields(line)

		if len(d) != 2 {
			return nil, fmt.Errorf("Couldn't parse line %d of depfile %s", i+1, depsFile)
		}

		deps[d[0]] = d[1]
	}

	return deps, nil
}

func writeDepFile(deps dependencyMap) error {

	// sort the dep paths
	klen := 0
	var keys []string
	for k := range deps {
		keys = append(keys, k)
		if len(k) > klen {
			klen = len(k)
		}
	}
	sort.Strings(keys)

	f, err := os.OpenFile(depsFile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		return err
	}
	defer f.Close()

	for _, dep := range keys {
		version := deps[dep]

		line := fmt.Sprintf("%-[3]*[1]s %[2]s", dep, version, klen)

		if _, err = f.WriteString(line + "\n"); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>// Package syslog provides the logdriver for forwarding server logs to syslog endpoints.
package syslog // import "github.com/docker/docker/daemon/logger/syslog"

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	syslog "github.com/RackSec/srslog"

	"github.com/docker/docker/daemon/logger"
	"github.com/docker/docker/daemon/logger/loggerutils"
	"github.com/docker/docker/pkg/urlutil"
	"github.com/docker/go-connections/tlsconfig"
	"github.com/sirupsen/logrus"
)

const (
	name        = "syslog"
	secureProto = "tcp+tls"
)

var facilities = map[string]syslog.Priority{
	"kern":     syslog.LOG_KERN,
	"user":     syslog.LOG_USER,
	"mail":     syslog.LOG_MAIL,
	"daemon":   syslog.LOG_DAEMON,
	"auth":     syslog.LOG_AUTH,
	"syslog":   syslog.LOG_SYSLOG,
	"lpr":      syslog.LOG_LPR,
	"news":     syslog.LOG_NEWS,
	"uucp":     syslog.LOG_UUCP,
	"cron":     syslog.LOG_CRON,
	"authpriv": syslog.LOG_AUTHPRIV,
	"ftp":      syslog.LOG_FTP,
	"local0":   syslog.LOG_LOCAL0,
	"local1":   syslog.LOG_LOCAL1,
	"local2":   syslog.LOG_LOCAL2,
	"local3":   syslog.LOG_LOCAL3,
	"local4":   syslog.LOG_LOCAL4,
	"local5":   syslog.LOG_LOCAL5,
	"local6":   syslog.LOG_LOCAL6,
	"local7":   syslog.LOG_LOCAL7,
}

type syslogger struct {
	writer *syslog.Writer
}

func init() {
	if err := logger.RegisterLogDriver(name, New); err != nil {
		logrus.Fatal(err)
	}
	if err := logger.RegisterLogOptValidator(name, ValidateLogOpt); err != nil {
		logrus.Fatal(err)
	}
}

// rsyslog uses appname part of syslog message to fill in an %syslogtag% template
// attribute in rsyslog.conf. In order to be backward compatible to rfc3164
// tag will be also used as an appname
func rfc5424formatterWithAppNameAsTag(p syslog.Priority, hostname, tag, content string) string {
	timestamp := time.Now().Format(time.RFC3339)
	pid := os.Getpid()
	msg := fmt.Sprintf("<%d>%d %s %s %s %d %s - %s",
		p, 1, timestamp, hostname, tag, pid, tag, content)
	return msg
}

// The timestamp field in rfc5424 is derived from rfc3339. Whereas rfc3339 makes allowances
// for multiple syntaxes, there are further restrictions in rfc5424, i.e., the maximum
// resolution is limited to "TIME-SECFRAC" which is 6 (microsecond resolution)
func rfc5424microformatterWithAppNameAsTag(p syslog.Priority, hostname, tag, content string) string {
	timestamp := time.Now().Format("2006-01-02T15:04:05.000000Z07:00")
	pid := os.Getpid()
	msg := fmt.Sprintf("<%d>%d %s %s %s %d %s - %s",
		p, 1, timestamp, hostname, tag, pid, tag, content)
	return msg
}

// New creates a syslog logger using the configuration passed in on
// the context. Supported context configuration variables are
// syslog-address, syslog-facility, syslog-format.
func New(info logger.Info) (logger.Logger, error) {
	tag, err := loggerutils.ParseLogTag(info, loggerutils.DefaultTemplate)
	if err != nil {
		return nil, err
	}

	proto, address, err := parseAddress(info.Config["syslog-address"])
	if err != nil {
		return nil, err
	}

	facility, err := parseFacility(info.Config["syslog-facility"])
	if err != nil {
		return nil, err
	}

	syslogFormatter, syslogFramer, err := parseLogFormat(info.Config["syslog-format"], proto)
	if err != nil {
		return nil, err
	}

	var log *syslog.Writer
	if proto == secureProto {
		tlsConfig, tlsErr := parseTLSConfig(info.Config)
		if tlsErr != nil {
			return nil, tlsErr
		}
		log, err = syslog.DialWithTLSConfig(proto, address, facility, tag, tlsConfig)
	} else {
		log, err = syslog.Dial(proto, address, facility, tag)
	}

	if err != nil {
		return nil, err
	}

	log.SetFormatter(syslogFormatter)
	log.SetFramer(syslogFramer)

	return &syslogger{
		writer: log,
	}, nil
}

func (s *syslogger) Log(msg *logger.Message) error {
	line := string(msg.Line)
	source := msg.Source
	logger.PutMessage(msg)
	if source == "stderr" {
		return s.writer.Err(line)
	}
	return s.writer.Info(line)
}

func (s *syslogger) Close() error {
	return s.writer.Close()
}

func (s *syslogger) Name() string {
	return name
}

func parseAddress(address string) (string, string, error) {
	if address == "" {
		return "", "", nil
	}
	if !urlutil.IsTransportURL(address) {
		return "", "", fmt.Errorf("syslog-address should be in form proto://address, got %v", address)
	}
	url, err := url.Parse(address)
	if err != nil {
		return "", "", err
	}

	// unix and unixgram socket validation
	if url.Scheme == "unix" || url.Scheme == "unixgram" {
		if _, err := os.Stat(url.Path); err != nil {
			return "", "", err
		}
		return url.Scheme, url.Path, nil
	}

	// here we process tcp|udp
	host := url.Host
	if _, _, err := net.SplitHostPort(host); err != nil {
		if !strings.Contains(err.Error(), "missing port in address") {
			return "", "", err
		}
		host = host + ":514"
	}

	return url.Scheme, host, nil
}

// ValidateLogOpt looks for syslog specific log options
// syslog-address, syslog-facility.
func ValidateLogOpt(cfg map[string]string) error {
	for key := range cfg {
		switch key {
		case "env":
		case "env-regex":
		case "labels":
		case "labels-regex":
		case "syslog-address":
		case "syslog-facility":
		case "syslog-tls-ca-cert":
		case "syslog-tls-cert":
		case "syslog-tls-key":
		case "syslog-tls-skip-verify":
		case "tag":
		case "syslog-format":
		default:
			return fmt.Errorf("unknown log opt '%s' for syslog log driver", key)
		}
	}
	if _, _, err := parseAddress(cfg["syslog-address"]); err != nil {
		return err
	}
	if _, err := parseFacility(cfg["syslog-facility"]); err != nil {
		return err
	}
	if _, _, err := parseLogFormat(cfg["syslog-format"], ""); err != nil {
		return err
	}
	return nil
}

func parseFacility(facility string) (syslog.Priority, error) {
	if facility == "" {
		return syslog.LOG_DAEMON, nil
	}

	if syslogFacility, valid := facilities[facility]; valid {
		return syslogFacility, nil
	}

	fInt, err := strconv.Atoi(facility)
	if err == nil && 0 <= fInt && fInt <= 23 {
		return syslog.Priority(fInt << 3), nil
	}

	return syslog.Priority(0), errors.New("invalid syslog facility")
}

func parseTLSConfig(cfg map[string]string) (*tls.Config, error) {
	_, skipVerify := cfg["syslog-tls-skip-verify"]

	opts := tlsconfig.Options{
		CAFile:             cfg["syslog-tls-ca-cert"],
		CertFile:           cfg["syslog-tls-cert"],
		KeyFile:            cfg["syslog-tls-key"],
		InsecureSkipVerify: skipVerify,
	}

	return tlsconfig.Client(opts)
}

func parseLogFormat(logFormat, proto string) (syslog.Formatter, syslog.Framer, error) {
	switch logFormat {
	case "":
		return syslog.UnixFormatter, syslog.DefaultFramer, nil
	case "rfc3164":
		return syslog.RFC3164Formatter, syslog.DefaultFramer, nil
	case "rfc5424":
		if proto == secureProto {
			return rfc5424formatterWithAppNameAsTag, syslog.RFC5425MessageLengthFramer, nil
		}
		return rfc5424formatterWithAppNameAsTag, syslog.DefaultFramer, nil
	case "rfc5424micro":
		if proto == secureProto {
			return rfc5424microformatterWithAppNameAsTag, syslog.RFC5425MessageLengthFramer, nil
		}
		return rfc5424microformatterWithAppNameAsTag, syslog.DefaultFramer, nil
	default:
		return nil, nil, errors.New("Invalid syslog format")
	}

}
<commit_msg>Fixes #41010 skip empty lines<commit_after>// Package syslog provides the logdriver for forwarding server logs to syslog endpoints.
package syslog // import "github.com/docker/docker/daemon/logger/syslog"

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	syslog "github.com/RackSec/srslog"

	"github.com/docker/docker/daemon/logger"
	"github.com/docker/docker/daemon/logger/loggerutils"
	"github.com/docker/docker/pkg/urlutil"
	"github.com/docker/go-connections/tlsconfig"
	"github.com/sirupsen/logrus"
)

const (
	name        = "syslog"
	secureProto = "tcp+tls"
)

var facilities = map[string]syslog.Priority{
	"kern":     syslog.LOG_KERN,
	"user":     syslog.LOG_USER,
	"mail":     syslog.LOG_MAIL,
	"daemon":   syslog.LOG_DAEMON,
	"auth":     syslog.LOG_AUTH,
	"syslog":   syslog.LOG_SYSLOG,
	"lpr":      syslog.LOG_LPR,
	"news":     syslog.LOG_NEWS,
	"uucp":     syslog.LOG_UUCP,
	"cron":     syslog.LOG_CRON,
	"authpriv": syslog.LOG_AUTHPRIV,
	"ftp":      syslog.LOG_FTP,
	"local0":   syslog.LOG_LOCAL0,
	"local1":   syslog.LOG_LOCAL1,
	"local2":   syslog.LOG_LOCAL2,
	"local3":   syslog.LOG_LOCAL3,
	"local4":   syslog.LOG_LOCAL4,
	"local5":   syslog.LOG_LOCAL5,
	"local6":   syslog.LOG_LOCAL6,
	"local7":   syslog.LOG_LOCAL7,
}

type syslogger struct {
	writer *syslog.Writer
}

func init() {
	if err := logger.RegisterLogDriver(name, New); err != nil {
		logrus.Fatal(err)
	}
	if err := logger.RegisterLogOptValidator(name, ValidateLogOpt); err != nil {
		logrus.Fatal(err)
	}
}

// rsyslog uses appname part of syslog message to fill in an %syslogtag% template
// attribute in rsyslog.conf. In order to be backward compatible to rfc3164
// tag will be also used as an appname
func rfc5424formatterWithAppNameAsTag(p syslog.Priority, hostname, tag, content string) string {
	timestamp := time.Now().Format(time.RFC3339)
	pid := os.Getpid()
	msg := fmt.Sprintf("<%d>%d %s %s %s %d %s - %s",
		p, 1, timestamp, hostname, tag, pid, tag, content)
	return msg
}

// The timestamp field in rfc5424 is derived from rfc3339. Whereas rfc3339 makes allowances
// for multiple syntaxes, there are further restrictions in rfc5424, i.e., the maximum
// resolution is limited to "TIME-SECFRAC" which is 6 (microsecond resolution)
func rfc5424microformatterWithAppNameAsTag(p syslog.Priority, hostname, tag, content string) string {
	timestamp := time.Now().Format("2006-01-02T15:04:05.000000Z07:00")
	pid := os.Getpid()
	msg := fmt.Sprintf("<%d>%d %s %s %s %d %s - %s",
		p, 1, timestamp, hostname, tag, pid, tag, content)
	return msg
}

// New creates a syslog logger using the configuration passed in on
// the context. Supported context configuration variables are
// syslog-address, syslog-facility, syslog-format.
func New(info logger.Info) (logger.Logger, error) {
	tag, err := loggerutils.ParseLogTag(info, loggerutils.DefaultTemplate)
	if err != nil {
		return nil, err
	}

	proto, address, err := parseAddress(info.Config["syslog-address"])
	if err != nil {
		return nil, err
	}

	facility, err := parseFacility(info.Config["syslog-facility"])
	if err != nil {
		return nil, err
	}

	syslogFormatter, syslogFramer, err := parseLogFormat(info.Config["syslog-format"], proto)
	if err != nil {
		return nil, err
	}

	var log *syslog.Writer
	if proto == secureProto {
		tlsConfig, tlsErr := parseTLSConfig(info.Config)
		if tlsErr != nil {
			return nil, tlsErr
		}
		log, err = syslog.DialWithTLSConfig(proto, address, facility, tag, tlsConfig)
	} else {
		log, err = syslog.Dial(proto, address, facility, tag)
	}

	if err != nil {
		return nil, err
	}

	log.SetFormatter(syslogFormatter)
	log.SetFramer(syslogFramer)

	return &syslogger{
		writer: log,
	}, nil
}

func (s *syslogger) Log(msg *logger.Message) error {
	if len(msg.Line) == 0 {
		return nil
	}

	line := string(msg.Line)
	source := msg.Source
	logger.PutMessage(msg)
	if source == "stderr" {
		return s.writer.Err(line)
	}
	return s.writer.Info(line)
}

func (s *syslogger) Close() error {
	return s.writer.Close()
}

func (s *syslogger) Name() string {
	return name
}

func parseAddress(address string) (string, string, error) {
	if address == "" {
		return "", "", nil
	}
	if !urlutil.IsTransportURL(address) {
		return "", "", fmt.Errorf("syslog-address should be in form proto://address, got %v", address)
	}
	url, err := url.Parse(address)
	if err != nil {
		return "", "", err
	}

	// unix and unixgram socket validation
	if url.Scheme == "unix" || url.Scheme == "unixgram" {
		if _, err := os.Stat(url.Path); err != nil {
			return "", "", err
		}
		return url.Scheme, url.Path, nil
	}

	// here we process tcp|udp
	host := url.Host
	if _, _, err := net.SplitHostPort(host); err != nil {
		if !strings.Contains(err.Error(), "missing port in address") {
			return "", "", err
		}
		host = host + ":514"
	}

	return url.Scheme, host, nil
}

// ValidateLogOpt looks for syslog specific log options
// syslog-address, syslog-facility.
func ValidateLogOpt(cfg map[string]string) error {
	for key := range cfg {
		switch key {
		case "env":
		case "env-regex":
		case "labels":
		case "labels-regex":
		case "syslog-address":
		case "syslog-facility":
		case "syslog-tls-ca-cert":
		case "syslog-tls-cert":
		case "syslog-tls-key":
		case "syslog-tls-skip-verify":
		case "tag":
		case "syslog-format":
		default:
			return fmt.Errorf("unknown log opt '%s' for syslog log driver", key)
		}
	}
	if _, _, err := parseAddress(cfg["syslog-address"]); err != nil {
		return err
	}
	if _, err := parseFacility(cfg["syslog-facility"]); err != nil {
		return err
	}
	if _, _, err := parseLogFormat(cfg["syslog-format"], ""); err != nil {
		return err
	}
	return nil
}

func parseFacility(facility string) (syslog.Priority, error) {
	if facility == "" {
		return syslog.LOG_DAEMON, nil
	}

	if syslogFacility, valid := facilities[facility]; valid {
		return syslogFacility, nil
	}

	fInt, err := strconv.Atoi(facility)
	if err == nil && 0 <= fInt && fInt <= 23 {
		return syslog.Priority(fInt << 3), nil
	}

	return syslog.Priority(0), errors.New("invalid syslog facility")
}

func parseTLSConfig(cfg map[string]string) (*tls.Config, error) {
	_, skipVerify := cfg["syslog-tls-skip-verify"]

	opts := tlsconfig.Options{
		CAFile:             cfg["syslog-tls-ca-cert"],
		CertFile:           cfg["syslog-tls-cert"],
		KeyFile:            cfg["syslog-tls-key"],
		InsecureSkipVerify: skipVerify,
	}

	return tlsconfig.Client(opts)
}

func parseLogFormat(logFormat, proto string) (syslog.Formatter, syslog.Framer, error) {
	switch logFormat {
	case "":
		return syslog.UnixFormatter, syslog.DefaultFramer, nil
	case "rfc3164":
		return syslog.RFC3164Formatter, syslog.DefaultFramer, nil
	case "rfc5424":
		if proto == secureProto {
			return rfc5424formatterWithAppNameAsTag, syslog.RFC5425MessageLengthFramer, nil
		}
		return rfc5424formatterWithAppNameAsTag, syslog.DefaultFramer, nil
	case "rfc5424micro":
		if proto == secureProto {
			return rfc5424microformatterWithAppNameAsTag, syslog.RFC5425MessageLengthFramer, nil
		}
		return rfc5424microformatterWithAppNameAsTag, syslog.DefaultFramer, nil
	default:
		return nil, nil, errors.New("Invalid syslog format")
	}

}
<|endoftext|>


<commit_before>package police

import (
	"fmt"
)

type Crime struct {
	Category        string        `json:"category"`
	PersistentID    string        `json:"persistent_id"`
	Month           string        `json:"month"`
	Location        Location      `json:"location"`
	Context         string        `json:"context"`
	ID              uint64        `json:"id"`
	LocationType    string        `json:"location_type"`
	LocationSubtype string        `json:"location_subtype"`
	Outcome         OutcomeStatus `json:"outcome_status"`
}

type Location struct {
	Latitude  string `json:"latitude"`
	Longitude string `json:"longitude"`
	Street    `json:"street"`
}

type Street struct {
	ID   uint64 `json:"id"`
	Name string `json:"name"`
}

type OutcomeStatus struct {
	Category string `json:"category"`
	Date     string `json:"date"`
}

func (c Client) StreetCrime(lat, long float64, date string, category string) ([]Crime, error) {
	if category == "" {
		category = "all-crime"
	}
	url := fmt.Sprintf("crimes-street/%s?lat=%d&lng=%d&date=%s", category, lat, long, date)
	var crimes []Crime
	if err := c.decodeJSONResponse(url, &crimes); err != nil {
		return nil, err
	}
	return crimes, nil
}
<commit_msg>add support for getting crime categories<commit_after>package police

import (
	"fmt"
)

type Crime struct {
	Category        string        `json:"category"`
	PersistentID    string        `json:"persistent_id"`
	Month           string        `json:"month"`
	Location        Location      `json:"location"`
	Context         string        `json:"context"`
	ID              uint64        `json:"id"`
	LocationType    string        `json:"location_type"`
	LocationSubtype string        `json:"location_subtype"`
	Outcome         OutcomeStatus `json:"outcome_status"`
}

type CrimeCategory struct {
	Slug string `json:"url"`
	Name string `json:"name"`
}

type Location struct {
	Latitude  string `json:"latitude"`
	Longitude string `json:"longitude"`
	Street    `json:"street"`
}

type Street struct {
	ID   uint64 `json:"id"`
	Name string `json:"name"`
}

type OutcomeStatus struct {
	Category string `json:"category"`
	Date     string `json:"date"`
}

func (c Client) Categories() ([]CrimeCategory, error) {
	var categories []CrimeCategory
	err := c.decodeJSONResponse("crime-categories", &categories)
	if err != nil {
		return nil, err
	}
	return categories, nil
}

func (c Client) StreetCrime(lat, long float64, date string, category string) ([]Crime, error) {
	if category == "" {
		category = "all-crime"
	}
	url := fmt.Sprintf("crimes-street/%s?lat=%d&lng=%d&date=%s", category, lat, long, date)
	var crimes []Crime
	if err := c.decodeJSONResponse(url, &crimes); err != nil {
		return nil, err
	}
	return crimes, nil
}
<|endoftext|>


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

package inspectkv

import (
	"io"
	"reflect"
	"strings"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/column"
	"github.com/pingcap/tidb/kv"
	"github.com/pingcap/tidb/meta"
	"github.com/pingcap/tidb/model"
	"github.com/pingcap/tidb/table"
	"github.com/pingcap/tidb/table/tables"
	"github.com/pingcap/tidb/terror"
)

// DDLInfo is for DDL information.
type DDLInfo struct {
	SchemaVer   int64
	ReorgHandle int64
	Owner       *model.Owner
	Job         *model.Job
}

// GetDDLInfo returns DDL information.
func GetDDLInfo(txn kv.Transaction) (*DDLInfo, error) {
	var err error
	info := &DDLInfo{}
	t := meta.NewMeta(txn)

	info.Owner, err = t.GetDDLOwner()
	if err != nil {
		return nil, errors.Trace(err)
	}
	info.Job, err = t.GetDDLJob(0)
	if err != nil {
		return nil, errors.Trace(err)
	}
	info.SchemaVer, err = t.GetSchemaVersion()
	if err != nil {
		return nil, errors.Trace(err)
	}
	if info.Job == nil {
		return info, nil
	}

	info.ReorgHandle, err = t.GetDDLReorgHandle(info.Job)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return info, nil
}

func nextIndexVals(data []interface{}) []interface{} {
	// Add 0x0 to the end of data.
	return append(data, nil)
}

// RecordData is the record data composed of a handle and values.
type RecordData struct {
	Handle int64
	Values []interface{}
}

// GetIndexRecordsCount returns the total number of the index records from startVals.
// If startVals = nil, returns the total number of the index records.
func GetIndexRecordsCount(txn kv.Transaction, kvIndex kv.Index, startVals []interface{}) (int64, error) {
	it, _, err := kvIndex.Seek(txn, startVals)
	if err != nil {
		return 0, errors.Trace(err)
	}
	defer it.Close()

	var cnt int64
	for {
		_, _, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		} else if err != nil {
			return 0, errors.Trace(err)
		}
		cnt++
	}

	return cnt, nil
}

// ScanIndexData scans the index handles and values in a limited number, according to the index information.
// It returns data and the next startVals until it doesn't have data, then returns data is nil and
// the next startVals is the values which can't get data. If startVals = nil and limit = -1,
// it returns the index data of the whole.
func ScanIndexData(txn kv.Transaction, kvIndex kv.Index, startVals []interface{}, limit int64) (
	[]*RecordData, []interface{}, error) {
	it, _, err := kvIndex.Seek(txn, startVals)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}
	defer it.Close()

	var idxRows []*RecordData
	var curVals []interface{}
	for limit != 0 {
		val, h, err1 := it.Next()
		if terror.ErrorEqual(err1, io.EOF) {
			return idxRows, nextIndexVals(curVals), nil
		} else if err1 != nil {
			return nil, nil, errors.Trace(err1)
		}
		idxRows = append(idxRows, &RecordData{Handle: h, Values: val})
		limit--
		curVals = val
	}

	nextVals, _, err := it.Next()
	if terror.ErrorEqual(err, io.EOF) {
		return idxRows, nextIndexVals(curVals), nil
	} else if err != nil {
		return nil, nil, errors.Trace(err)
	}

	return idxRows, nextVals, nil
}

// CompareIndexData compares index data one by one.
// It returns nil if the data from the index is equal to the data from the table columns,
// otherwise it returns an error with a different set of records.
func CompareIndexData(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	err := checkIndexAndRecord(txn, t, idx)
	if err != nil {
		return errors.Trace(err)
	}

	return checkRecordAndIndex(txn, t, idx)
}

func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique)
	it, err := kvIndex.SeekFirst(txn)
	if err != nil {
		return errors.Trace(err)
	}
	defer it.Close()

	cols := make([]*column.Col, len(idx.Columns))
	for i, col := range idx.Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	for {
		vals1, h, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		} else if err != nil {
			return errors.Trace(err)
		}

		vals2, err := t.RowWithCols(txn, h, cols)
		if terror.ErrorEqual(err, kv.ErrNotExist) {
			record := &RecordData{Handle: h, Values: vals1}
			err = errors.Errorf("index:%v != record:%v", record, nil)
		}
		if err != nil {
			return errors.Trace(err)
		}
		if !reflect.DeepEqual(vals1, vals2) {
			record1 := &RecordData{Handle: h, Values: vals1}
			record2 := &RecordData{Handle: h, Values: vals2}
			return errors.Errorf("index:%v != record:%v", record1, record2)
		}
	}

	return nil
}

func checkRecordAndIndex(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	cols := make([]*column.Col, len(idx.Columns))
	for i, col := range idx.Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	startKey := t.RecordKey(0, nil)
	kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique)
	filterFunc := func(h1 int64, vals1 []interface{}, cols []*column.Col) (bool, error) {
		isExist, h2, err := kvIndex.Exist(txn, vals1, h1)
		if terror.ErrorEqual(err, terror.ErrKeyExists) {
			record1 := &RecordData{Handle: h1, Values: vals1}
			record2 := &RecordData{Handle: h2, Values: vals1}
			return false, errors.Errorf("index:%v != record:%v", record2, record1)
		}
		if err != nil {
			return false, errors.Trace(err)
		}
		if !isExist {
			record := &RecordData{Handle: h1, Values: vals1}
			return false, errors.Errorf("index:%v != record:%v", nil, record)
		}

		return true, nil
	}
	err := t.IterRecords(txn, string(startKey), cols, filterFunc)
	if err != nil {
		return errors.Trace(err)
	}

	return nil
}

func scanTableData(retriever kv.Retriever, t table.Table, cols []*column.Col, startHandle, limit int64) (
	[]*RecordData, int64, error) {
	var records []*RecordData

	startKey := t.RecordKey(startHandle, nil)
	filterFunc := func(h int64, d []interface{}, cols []*column.Col) (bool, error) {
		if limit != 0 {
			r := &RecordData{
				Handle: h,
				Values: d,
			}
			records = append(records, r)
			limit--
			return true, nil
		}

		return false, nil
	}
	err := t.IterRecords(retriever, string(startKey), cols, filterFunc)
	if err != nil {
		return nil, 0, errors.Trace(err)
	}

	if len(records) == 0 {
		return records, startHandle, nil
	}

	nextHandle := records[len(records)-1].Handle + 1

	return records, nextHandle, nil
}

// ScanTableRecord scans table row handles and column values in a limited number.
// It returns data and the next startHandle until it doesn't have data, then returns data is nil and
// the next startHandle is the handle which can't get data. If startHandle = 0 and limit = -1,
// it returns the table data of the whole.
func ScanTableRecord(retriever kv.Retriever, t table.Table, startHandle, limit int64) (
	[]*RecordData, int64, error) {
	return scanTableData(retriever, t, t.Cols(), startHandle, limit)
}

// ScanSnapshotTableRecord scans the ver version of the table data in a limited number.
// It returns data and the next startHandle until it doesn't have data, then returns data is nil and
// the next startHandle is the handle which can't get data. If startHandle = 0 and limit = -1,
// it returns the table data of the whole.
func ScanSnapshotTableRecord(store kv.Storage, ver kv.Version, t table.Table, startHandle, limit int64) (
	[]*RecordData, int64, error) {
	snap, err := store.GetSnapshot(ver)
	if err != nil {
		return nil, 0, errors.Trace(err)
	}
	defer snap.Release()

	records, nextHandle, err := ScanTableRecord(snap, t, startHandle, limit)

	return records, nextHandle, errors.Trace(err)
}

// CompareTableRecord compares data and the corresponding table data one by one.
// It returns nil if data is equal to the data that scans from table, otherwise
// it returns an error with a different set of records. If exact is false, only compares handle.
func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, exact bool) error {
	var err error
	var vals []interface{}
	m := make(map[int64]struct{}, len(data))

	for _, r := range data {
		vals, err = t.RowWithCols(txn, r.Handle, t.Cols())
		if terror.ErrorEqual(err, kv.ErrNotExist) {
			record1 := &RecordData{Handle: r.Handle, Values: r.Values}
			err = errors.Errorf("data:%v != record:%v", record1, nil)
		}
		if err != nil {
			break
		}

		if !exact {
			m[r.Handle] = struct{}{}
			continue
		}
		if !reflect.DeepEqual(r.Values, vals) {
			record1 := &RecordData{Handle: r.Handle, Values: r.Values}
			record2 := &RecordData{Handle: r.Handle, Values: vals}
			err = errors.Errorf("data:%v != record:%v", record1, record2)
			break
		}
		m[r.Handle] = struct{}{}
	}
	if err != nil {
		return errors.Trace(err)
	}

	startKey := t.RecordKey(0, nil)
	filterFunc := func(h int64, vals []interface{}, cols []*column.Col) (bool, error) {
		if _, ok := m[h]; !ok {
			record := &RecordData{Handle: h, Values: vals}
			return false, errors.Errorf("data:%v != record:%v", nil, record)

		}

		return true, nil
	}
	err = t.IterRecords(txn, string(startKey), t.Cols(), filterFunc)

	return errors.Trace(err)
}

// GetTableRecordsCount returns the total number of table records from startHandle.
// If startHandle = 0, returns the total number of table records.
func GetTableRecordsCount(txn kv.Transaction, t table.Table, startHandle int64) (int64, error) {
	startKey := t.RecordKey(startHandle, nil)
	it, err := txn.Seek(startKey)
	if err != nil {
		return 0, errors.Trace(err)
	}

	var cnt int64
	prefix := t.KeyPrefix()
	for it.Valid() && strings.HasPrefix(it.Key(), prefix) {
		handle, err := tables.DecodeRecordKeyHandle(it.Key())
		if err != nil {
			return 0, errors.Trace(err)
		}

		it.Close()
		rk := t.RecordKey(handle+1, nil)
		it, err = txn.Seek(rk)
		if err != nil {
			return 0, errors.Trace(err)
		}

		cnt++
	}

	it.Close()

	return cnt, nil
}
<commit_msg>inspectkv: address comments<commit_after>// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package inspectkv

import (
	"io"
	"reflect"
	"strings"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/column"
	"github.com/pingcap/tidb/kv"
	"github.com/pingcap/tidb/meta"
	"github.com/pingcap/tidb/model"
	"github.com/pingcap/tidb/table"
	"github.com/pingcap/tidb/table/tables"
	"github.com/pingcap/tidb/terror"
)

// DDLInfo is for DDL information.
type DDLInfo struct {
	SchemaVer   int64
	ReorgHandle int64
	Owner       *model.Owner
	Job         *model.Job
}

// GetDDLInfo returns DDL information.
func GetDDLInfo(txn kv.Transaction) (*DDLInfo, error) {
	var err error
	info := &DDLInfo{}
	t := meta.NewMeta(txn)

	info.Owner, err = t.GetDDLOwner()
	if err != nil {
		return nil, errors.Trace(err)
	}
	info.Job, err = t.GetDDLJob(0)
	if err != nil {
		return nil, errors.Trace(err)
	}
	info.SchemaVer, err = t.GetSchemaVersion()
	if err != nil {
		return nil, errors.Trace(err)
	}
	if info.Job == nil {
		return info, nil
	}

	info.ReorgHandle, err = t.GetDDLReorgHandle(info.Job)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return info, nil
}

func nextIndexVals(data []interface{}) []interface{} {
	// Add 0x0 to the end of data.
	return append(data, nil)
}

// RecordData is the record data composed of a handle and values.
type RecordData struct {
	Handle int64
	Values []interface{}
}

// GetIndexRecordsCount returns the total number of the index records from startVals.
// If startVals = nil, returns the total number of the index records.
func GetIndexRecordsCount(txn kv.Transaction, kvIndex kv.Index, startVals []interface{}) (int64, error) {
	it, _, err := kvIndex.Seek(txn, startVals)
	if err != nil {
		return 0, errors.Trace(err)
	}
	defer it.Close()

	var cnt int64
	for {
		_, _, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		} else if err != nil {
			return 0, errors.Trace(err)
		}
		cnt++
	}

	return cnt, nil
}

// ScanIndexData scans the index handles and values in a limited number, according to the index information.
// It returns data and the next startVals until it doesn't have data, then returns data is nil and
// the next startVals is the values which can't get data. If startVals = nil and limit = -1,
// it returns the index data of the whole.
func ScanIndexData(txn kv.Transaction, kvIndex kv.Index, startVals []interface{}, limit int64) (
	[]*RecordData, []interface{}, error) {
	it, _, err := kvIndex.Seek(txn, startVals)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}
	defer it.Close()

	var idxRows []*RecordData
	var curVals []interface{}
	for limit != 0 {
		val, h, err1 := it.Next()
		if terror.ErrorEqual(err1, io.EOF) {
			return idxRows, nextIndexVals(curVals), nil
		} else if err1 != nil {
			return nil, nil, errors.Trace(err1)
		}
		idxRows = append(idxRows, &RecordData{Handle: h, Values: val})
		limit--
		curVals = val
	}

	nextVals, _, err := it.Next()
	if terror.ErrorEqual(err, io.EOF) {
		return idxRows, nextIndexVals(curVals), nil
	} else if err != nil {
		return nil, nil, errors.Trace(err)
	}

	return idxRows, nextVals, nil
}

// CompareIndexData compares index data one by one.
// It returns nil if the data from the index is equal to the data from the table columns,
// otherwise it returns an error with a different set of records.
func CompareIndexData(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	err := checkIndexAndRecord(txn, t, idx)
	if err != nil {
		return errors.Trace(err)
	}

	return checkRecordAndIndex(txn, t, idx)
}

func checkIndexAndRecord(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique)
	it, err := kvIndex.SeekFirst(txn)
	if err != nil {
		return errors.Trace(err)
	}
	defer it.Close()

	cols := make([]*column.Col, len(idx.Columns))
	for i, col := range idx.Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	for {
		vals1, h, err := it.Next()
		if terror.ErrorEqual(err, io.EOF) {
			break
		} else if err != nil {
			return errors.Trace(err)
		}

		vals2, err := t.RowWithCols(txn, h, cols)
		if terror.ErrorEqual(err, kv.ErrNotExist) {
			record := &RecordData{Handle: h, Values: vals1}
			err = errors.Errorf("index:%v != record:%v", record, nil)
		}
		if err != nil {
			return errors.Trace(err)
		}
		if !reflect.DeepEqual(vals1, vals2) {
			record1 := &RecordData{Handle: h, Values: vals1}
			record2 := &RecordData{Handle: h, Values: vals2}
			return errors.Errorf("index:%v != record:%v", record1, record2)
		}
	}

	return nil
}

func checkRecordAndIndex(txn kv.Transaction, t table.Table, idx *column.IndexedCol) error {
	cols := make([]*column.Col, len(idx.Columns))
	for i, col := range idx.Columns {
		cols[i] = t.Cols()[col.Offset]
	}

	startKey := t.RecordKey(0, nil)
	kvIndex := kv.NewKVIndex(t.IndexPrefix(), idx.Name.L, idx.ID, idx.Unique)
	filterFunc := func(h1 int64, vals1 []interface{}, cols []*column.Col) (bool, error) {
		isExist, h2, err := kvIndex.Exist(txn, vals1, h1)
		if terror.ErrorEqual(err, terror.ErrKeyExists) {
			record1 := &RecordData{Handle: h1, Values: vals1}
			record2 := &RecordData{Handle: h2, Values: vals1}
			return false, errors.Errorf("index:%v != record:%v", record2, record1)
		}
		if err != nil {
			return false, errors.Trace(err)
		}
		if !isExist {
			record := &RecordData{Handle: h1, Values: vals1}
			return false, errors.Errorf("index:%v != record:%v", nil, record)
		}

		return true, nil
	}
	err := t.IterRecords(txn, string(startKey), cols, filterFunc)
	if err != nil {
		return errors.Trace(err)
	}

	return nil
}

func scanTableData(retriever kv.Retriever, t table.Table, cols []*column.Col, startHandle, limit int64) (
	[]*RecordData, int64, error) {
	var records []*RecordData

	startKey := t.RecordKey(startHandle, nil)
	filterFunc := func(h int64, d []interface{}, cols []*column.Col) (bool, error) {
		if limit != 0 {
			r := &RecordData{
				Handle: h,
				Values: d,
			}
			records = append(records, r)
			limit--
			return true, nil
		}

		return false, nil
	}
	err := t.IterRecords(retriever, string(startKey), cols, filterFunc)
	if err != nil {
		return nil, 0, errors.Trace(err)
	}

	if len(records) == 0 {
		return records, startHandle, nil
	}

	nextHandle := records[len(records)-1].Handle + 1

	return records, nextHandle, nil
}

// ScanTableRecord scans table row handles and column values in a limited number.
// It returns data and the next startHandle until it doesn't have data, then returns data is nil and
// the next startHandle is the handle which can't get data. If startHandle = 0 and limit = -1,
// it returns the table data of the whole.
func ScanTableRecord(retriever kv.Retriever, t table.Table, startHandle, limit int64) (
	[]*RecordData, int64, error) {
	return scanTableData(retriever, t, t.Cols(), startHandle, limit)
}

// ScanSnapshotTableRecord scans the ver version of the table data in a limited number.
// It returns data and the next startHandle until it doesn't have data, then returns data is nil and
// the next startHandle is the handle which can't get data. If startHandle = 0 and limit = -1,
// it returns the table data of the whole.
func ScanSnapshotTableRecord(store kv.Storage, ver kv.Version, t table.Table, startHandle, limit int64) (
	[]*RecordData, int64, error) {
	snap, err := store.GetSnapshot(ver)
	if err != nil {
		return nil, 0, errors.Trace(err)
	}
	defer snap.Release()

	records, nextHandle, err := ScanTableRecord(snap, t, startHandle, limit)

	return records, nextHandle, errors.Trace(err)
}

// CompareTableRecord compares data and the corresponding table data one by one.
// It returns nil if data is equal to the data that scans from table, otherwise
// it returns an error with a different set of records. If exact is false, only compares handle.
func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, exact bool) error {
	var err error
	var vals []interface{}
	m := make(map[int64]struct{}, len(data))

	for _, r := range data {
		vals, err = t.RowWithCols(txn, r.Handle, t.Cols())
		if terror.ErrorEqual(err, kv.ErrNotExist) {
			record1 := &RecordData{Handle: r.Handle, Values: r.Values}
			err = errors.Errorf("data:%v != record:%v", record1, nil)
		}
		if err != nil {
			break
		}

		if !exact {
			m[r.Handle] = struct{}{}
			continue
		}
		if !reflect.DeepEqual(r.Values, vals) {
			record1 := &RecordData{Handle: r.Handle, Values: r.Values}
			record2 := &RecordData{Handle: r.Handle, Values: vals}
			err = errors.Errorf("data:%v != record:%v", record1, record2)
			break
		}
		m[r.Handle] = struct{}{}
	}
	if err != nil {
		return errors.Trace(err)
	}

	startKey := t.RecordKey(0, nil)
	filterFunc := func(h int64, vals []interface{}, cols []*column.Col) (bool, error) {
		if _, ok := m[h]; !ok {
			record := &RecordData{Handle: h, Values: vals}
			return false, errors.Errorf("data:%v != record:%v", nil, record)

		}

		return true, nil
	}
	err = t.IterRecords(txn, string(startKey), t.Cols(), filterFunc)

	return errors.Trace(err)
}

// GetTableRecordsCount returns the total number of table records from startHandle.
// If startHandle = 0, returns the total number of table records.
func GetTableRecordsCount(txn kv.Transaction, t table.Table, startHandle int64) (int64, error) {
	startKey := t.RecordKey(startHandle, nil)
	it, err := txn.Seek(startKey)
	if err != nil {
		return 0, errors.Trace(err)
	}

	var cnt int64
	prefix := t.KeyPrefix()
	for it.Valid() && strings.HasPrefix(it.Key(), prefix) {
		handle, err := tables.DecodeRecordKeyHandle(it.Key())
		if err != nil {
			it.Close()
			return 0, errors.Trace(err)
		}

		it.Close()
		rk := t.RecordKey(handle+1, nil)
		it, err = txn.Seek(rk)
		if err != nil {
			return 0, errors.Trace(err)
		}

		cnt++
	}

	it.Close()

	return cnt, nil
}
<|endoftext|>


<commit_before>package main

import "encoding/json"
import "flag"
import "io/ioutil"
import "log"
import "net/http"
import "net/url"
import "strings"
import "golang.org/x/net/context"
import "google.golang.org/grpc"
import pb "github.com/brotherlogic/cardserver/card"

func processAccessCode(client string, secret string, code string) []byte {
	urlv := "https://api.instagram.com/oauth/access_token"
	resp, err := http.PostForm(urlv, url.Values{"client_id": {client}, "client_secret": {secret}, "grant_type": {"authorization_code"}, "redirect_uri": {"http://localhost:8090"}, "code": {code}, "scope": {"public_content+likes"}})
	if err != nil {
		panic(err)
	}

	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	return body
}

func processInstagramRating(card pb.Card) string {
	pictureID := card.Text
	urlv := "https://api.instagram.com/v1/media/" + pictureID + "/likes"
	return urlv
}

func visitURL(urlv string, accessToken string) []byte {
	resp, err := http.PostForm(urlv, url.Values{"access_token": {accessToken}})

	if err != nil {
		panic(err)
	}

	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	return body
}

func readCards(client string, secret string, accessToken string) {
	conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	clientReader := pb.NewCardServiceClient(conn)
	list, err := clientReader.GetCards(context.Background(), &pb.Empty{})

	var accessCode []byte
	for _, card := range list.Cards {
		if card.Hash == "instagramauthresp" {
			code := card.Text[11:43]
			accessCode = processAccessCode(client, secret, code)
		} else if card.Action == pb.Card_RATE {
			urlv := processInstagramRating(*card) + "?access_token=" + accessToken
			resp, err := http.Post(urlv, "", nil)
			if err != nil {
				defer resp.Body.Close()
				body, _ := ioutil.ReadAll(resp.Body)
				log.Printf("Body = %v", body)
			}
		}
	}

	//Write the access card out to a file
	if len(accessCode) > 0 {
		err = ioutil.WriteFile("access_code", accessCode, 0644)
		if err != nil {
			panic(err)
		}

		conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())

		defer conn.Close()
		client := pb.NewCardServiceClient(conn)
		req := pb.DeleteRequest{Hash: "instagramauthresp"}
		_, err = client.DeleteCards(context.Background(), &req)
		if err != nil {
			log.Printf("Problem delete auth resp card %v", err)
		}

	}
}

func writeAuthCard(client string) pb.CardList {
	authURL := "https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=http://localhost:8090&response_type=code"
	newAuthURL := strings.Replace(authURL, "CLIENT-ID", client, 1)
	card := pb.Card{}
	card.Text = newAuthURL
	card.Action = pb.Card_VISITURL
	card.Hash = "instagramauth"
	cards := pb.CardList{}
	cards.Cards = append(cards.Cards, &card)

	return cards
}

func isImageLiked(mediaID string, accessToken string) bool {
	likesURL := "https://api.instagram.com/v1/media/" + mediaID + "/likes?access_token=" + accessToken
	resp, err := http.Get(likesURL)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	var dat map[string]interface{}
	err = json.Unmarshal([]byte(body), &dat)
	if err != nil {
		panic(nil)
	}

	var likes []interface{}
	likes = dat["data"].([]interface{})
	for _, persono := range likes {
		person := persono.(map[string]interface{})
		if person["username"].(string) == "brotherlogic" {
			return true
		}
	}

	return false
}

func writeInstagramCards(user string, accessCode string) pb.CardList {

	cards := pb.CardList{}

	urlv := "https://api.instagram.com/v1/users/" + user + "/media/recent/?access_token=" + accessCode + "&count=10"
	resp, err := http.Get(urlv)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		panic(err)
	}
	var dat map[string]interface{}
	err = json.Unmarshal([]byte(body), &dat)
	if err != nil {
		panic(err)
	}

	var pics []interface{}
	if dat["data"] != nil {
		pics = dat["data"].([]interface{})

		for _, pico := range pics {
			pic := pico.(map[string]interface{})
			captionObj := pic["caption"]
			caption := ""
			if captionObj != nil {
				caption = captionObj.(map[string]interface{})["text"].(string)
			}
			var images map[string]interface{}
			images = pic["images"].(map[string]interface{})
			image := images["standard_resolution"].(map[string]interface{})["url"].(string)

			liked := isImageLiked(pic["id"].(string), accessCode)

			if !liked {
				card := pb.Card{}
				card.Text = caption
				card.Image = image
				card.Priority = 20
				card.Hash = pic["id"].(string)
				cards.Cards = append(cards.Cards, &card)
			}
		}
	}
	return cards
}

func main() {
	var clientID = flag.String("client", "", "Client ID for accessing Instagram")
	var secret = flag.String("secret", "", "Secret for accessing Instagram")
	flag.Parse()
	text, err := ioutil.ReadFile("access_code")

	if err != nil {
		cards := writeAuthCard(*clientID)
		conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())

		defer conn.Close()
		client := pb.NewCardServiceClient(conn)
		_, err = client.AddCards(context.Background(), &cards)
		if err != nil {
			log.Printf("Problem adding cards %v", err)
		}

		readCards(*clientID, *secret, string(text))
	} else {
		var dat map[string]interface{}
		if err := json.Unmarshal([]byte(text), &dat); err != nil {
			log.Printf("Error unmarshalling %v with %v and %v", string(text), *clientID, *secret)
			panic(err)
		}
		if dat == nil || dat["access_token"] == nil {
			log.Printf("Cannot get access token: %v from %v given $v,%v", dat, string(text), *clientID, *secret)
		}
		cards := writeInstagramCards("50987102", dat["access_token"].(string))
		conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())

		defer conn.Close()
		client := pb.NewCardServiceClient(conn)
		_, err = client.AddCards(context.Background(), &cards)
		if err != nil {
			log.Printf("Problem adding cards %v", err)
		}

	}
}
<commit_msg>Updated for debugging<commit_after>package main

import "encoding/json"
import "flag"
import "io/ioutil"
import "log"
import "net/http"
import "net/url"
import "strings"
import "golang.org/x/net/context"
import "google.golang.org/grpc"
import pb "github.com/brotherlogic/cardserver/card"

func processAccessCode(client string, secret string, code string) []byte {
	urlv := "https://api.instagram.com/oauth/access_token"
	resp, err := http.PostForm(urlv, url.Values{"client_id": {client}, "client_secret": {secret}, "grant_type": {"authorization_code"}, "redirect_uri": {"http://localhost:8090"}, "code": {code}, "scope": {"public_content+likes"}})
	if err != nil {
		panic(err)
	}

	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	return body
}

func processInstagramRating(card pb.Card) string {
	pictureID := card.Text
	urlv := "https://api.instagram.com/v1/media/" + pictureID + "/likes"
	return urlv
}

func visitURL(urlv string, accessToken string) []byte {
	resp, err := http.PostForm(urlv, url.Values{"access_token": {accessToken}})

	if err != nil {
		panic(err)
	}

	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)

	return body
}

func readCards(client string, secret string, accessToken string) {
	conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	clientReader := pb.NewCardServiceClient(conn)
	list, err := clientReader.GetCards(context.Background(), &pb.Empty{})

	var accessCode []byte
	for _, card := range list.Cards {
		if card.Hash == "instagramauthresp" {
			code := card.Text[11:43]
			accessCode = processAccessCode(client, secret, code)
		} else if card.Action == pb.Card_RATE {
			urlv := processInstagramRating(*card) + "?access_token=" + accessToken
			resp, err := http.Post(urlv, "", nil)
			if err != nil {
				defer resp.Body.Close()
				body, _ := ioutil.ReadAll(resp.Body)
				log.Printf("Body = %v", body)
			}
		}
	}

	//Write the access card out to a file
	if len(accessCode) > 0 {
		err = ioutil.WriteFile("access_code", accessCode, 0644)
		if err != nil {
			panic(err)
		}

		conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())

		defer conn.Close()
		client := pb.NewCardServiceClient(conn)
		req := pb.DeleteRequest{Hash: "instagramauthresp"}
		_, err = client.DeleteCards(context.Background(), &req)
		if err != nil {
			log.Printf("Problem delete auth resp card %v", err)
		}

	}
}

func writeAuthCard(client string) pb.CardList {
	authURL := "https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=http://localhost:8090&response_type=code"
	newAuthURL := strings.Replace(authURL, "CLIENT-ID", client, 1)
	card := pb.Card{}
	card.Text = newAuthURL
	card.Action = pb.Card_VISITURL
	card.Hash = "instagramauth"
	cards := pb.CardList{}
	cards.Cards = append(cards.Cards, &card)

	return cards
}

func isImageLiked(mediaID string, accessToken string) bool {
	likesURL := "https://api.instagram.com/v1/media/" + mediaID + "/likes?access_token=" + accessToken
	resp, err := http.Get(likesURL)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	var dat map[string]interface{}
	err = json.Unmarshal([]byte(body), &dat)
	if err != nil {
		panic(nil)
	}

	var likes []interface{}
	likes = dat["data"].([]interface{})
	for _, persono := range likes {
		person := persono.(map[string]interface{})
		if person["username"].(string) == "brotherlogic" {
			return true
		}
	}

	return false
}

func writeInstagramCards(user string, accessCode string) pb.CardList {

	cards := pb.CardList{}

	urlv := "https://api.instagram.com/v1/users/" + user + "/media/recent/?access_token=" + accessCode + "&count=10"
	resp, err := http.Get(urlv)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		panic(err)
	}
	var dat map[string]interface{}
	err = json.Unmarshal([]byte(body), &dat)
	if err != nil {
		panic(err)
	}

	if dat == nil {
		panic("ERROR HERE = " + string(body))
	}

	var pics []interface{}
	if dat != nil && dat["data"] != nil {
		pics = dat["data"].([]interface{})

		for _, pico := range pics {
			pic := pico.(map[string]interface{})
			captionObj := pic["caption"]
			caption := ""
			if captionObj != nil {
				caption = captionObj.(map[string]interface{})["text"].(string)
			}
			var images map[string]interface{}
			images = pic["images"].(map[string]interface{})
			image := images["standard_resolution"].(map[string]interface{})["url"].(string)

			liked := isImageLiked(pic["id"].(string), accessCode)

			if !liked {
				card := pb.Card{}
				card.Text = caption
				card.Image = image
				card.Priority = 20
				card.Hash = pic["id"].(string)
				cards.Cards = append(cards.Cards, &card)
			}
		}
	}
	return cards
}

func main() {
	var clientID = flag.String("client", "", "Client ID for accessing Instagram")
	var secret = flag.String("secret", "", "Secret for accessing Instagram")
	flag.Parse()
	text, err := ioutil.ReadFile("access_code")

	if err != nil {
		cards := writeAuthCard(*clientID)
		conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())

		defer conn.Close()
		client := pb.NewCardServiceClient(conn)
		_, err = client.AddCards(context.Background(), &cards)
		if err != nil {
			log.Printf("Problem adding cards %v", err)
		}

		readCards(*clientID, *secret, string(text))
	} else {
		var dat map[string]interface{}
		if err := json.Unmarshal([]byte(text), &dat); err != nil {
			log.Printf("Error unmarshalling %v with %v and %v", string(text), *clientID, *secret)
			panic(err)
		}
		if dat == nil || dat["access_token"] == nil {
			log.Printf("Cannot get access token: %v from %v given $v,%v", dat, string(text), *clientID, *secret)
		}
		cards := writeInstagramCards("50987102", dat["access_token"].(string))
		conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())

		defer conn.Close()
		client := pb.NewCardServiceClient(conn)
		_, err = client.AddCards(context.Background(), &cards)
		if err != nil {
			log.Printf("Problem adding cards %v", err)
		}

	}
}
<|endoftext|>


<commit_before>package v4

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
	"io"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/awslabs/aws-sdk-go/aws"
)

const (
	authHeaderPrefix = "AWS4-HMAC-SHA256"
	timeFormat       = "20060102T150405Z"
	shortTimeFormat  = "20060102"
)

type signer struct {
	Request         *http.Request
	Time            time.Time
	ServiceName     string
	Region          string
	AccessKeyID     string
	SecretAccessKey string
	SessionToken    string
	Body            io.ReadSeeker
	Debug           uint

	formattedTime      string
	formattedShortTime string

	signedHeaders    string
	canonicalHeaders string
	canonicalString  string
	credentialString string
	stringToSign     string
	signature        string
	authorization    string
}

// Sign requests with signature version 4.
func Sign(req *aws.Request) {
	creds, _ := req.Service.Config.Credentials.Credentials()

	s := signer{
		Request:         req.HTTPRequest,
		Time:            req.Time,
		Body:            req.Body,
		ServiceName:     req.Service.ServiceName,
		Region:          req.Service.Config.Region,
		AccessKeyID:     creds.AccessKeyID,
		SecretAccessKey: creds.SecretAccessKey,
		SessionToken:    creds.SessionToken,
		Debug:           req.Service.Config.LogLevel,
	}
	s.sign()
}

func (v4 *signer) sign() {
	formatted := v4.Time.UTC().Format(timeFormat)

	// remove the old headers
	v4.Request.Header.Del("Date")
	v4.Request.Header.Del("Authorization")

	if v4.SessionToken != "" {
		v4.Request.Header.Set("X-Amz-Security-Token", v4.SessionToken)
	}

	v4.build()

	//v4.Debug = true
	if v4.Debug > 0 {
		fmt.Printf("---[ CANONICAL STRING  ]-----------------------------\n")
		fmt.Printf("%s\n", v4.canonicalString)
		fmt.Printf("-----------------------------------------------------\n\n")
		fmt.Printf("---[ STRING TO SIGN ]--------------------------------\n")
		fmt.Printf("%s\n", v4.stringToSign)
		fmt.Printf("-----------------------------------------------------\n")
	}

	// add the new ones
	v4.Request.Header.Add("Date", formatted)
	v4.Request.Header.Add("Authorization", v4.authorization)
}

func (v4 *signer) build() {
	v4.buildTime()
	v4.buildCanonicalHeaders()
	v4.buildCredentialString()
	v4.buildCanonicalString()
	v4.buildStringToSign()
	v4.buildSignature()
	v4.buildAuthorization()
}

func (v4 *signer) buildTime() {
	v4.formattedTime = v4.Time.UTC().Format(timeFormat)
	v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat)
}

func (v4 *signer) buildAuthorization() {
	v4.authorization = strings.Join([]string{
		authHeaderPrefix + " Credential=" + v4.AccessKeyID + "/" + v4.credentialString,
		"SignedHeaders=" + v4.signedHeaders,
		"Signature=" + v4.signature,
	}, ",")
}

func (v4 *signer) buildCredentialString() {
	v4.credentialString = strings.Join([]string{
		v4.formattedShortTime,
		v4.Region,
		v4.ServiceName,
		"aws4_request",
	}, "/")
}

func (v4 *signer) buildCanonicalHeaders() {
	headers := make([]string, 0)
	headers = append(headers, "host")
	for k, _ := range v4.Request.Header {
		if http.CanonicalHeaderKey(k) == "Content-Length" {
			continue // never sign content-length
		}
		headers = append(headers, strings.ToLower(k))
	}
	sort.Strings(headers)

	headerValues := make([]string, len(headers))
	for i, k := range headers {
		if k == "host" {
			headerValues[i] = "host:" + v4.Request.URL.Host
		} else {
			headerValues[i] = k + ":" +
				strings.Join(v4.Request.Header[http.CanonicalHeaderKey(k)], ",")
		}
	}

	v4.signedHeaders = strings.Join(headers, ";")
	v4.canonicalHeaders = strings.Join(headerValues, "\n")
}

func (v4 *signer) buildCanonicalString() {
	v4.canonicalString = strings.Join([]string{
		v4.Request.Method,
		v4.Request.URL.Path,
		v4.Request.URL.Query().Encode(),
		v4.canonicalHeaders + "\n",
		v4.signedHeaders,
		v4.bodyDigest(),
	}, "\n")
}

func (v4 *signer) buildStringToSign() {
	v4.stringToSign = strings.Join([]string{
		authHeaderPrefix,
		v4.formattedTime,
		v4.credentialString,
		hexDigest(makeSha256([]byte(v4.canonicalString))),
	}, "\n")
}

func (v4 *signer) buildSignature() {
	secret := v4.SecretAccessKey
	date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
	region := makeHmac(date, []byte(v4.Region))
	service := makeHmac(region, []byte(v4.ServiceName))
	credentials := makeHmac(service, []byte("aws4_request"))
	signature := makeHmac(credentials, []byte(v4.stringToSign))
	v4.signature = hexDigest(signature)
}

func (v4 *signer) bodyDigest() string {
	hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
	if hash == "" {
		if v4.Body == nil {
			hash = hexDigest(makeSha256([]byte{}))
		} else {
			hash = hexDigest(makeSha256Reader(v4.Body))
		}
		v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
	}
	return hash
}

func makeHmac(key []byte, data []byte) []byte {
	hash := hmac.New(sha256.New, key)
	hash.Write(data)
	return hash.Sum(nil)
}

func makeSha256(data []byte) []byte {
	hash := sha256.New()
	hash.Write(data)
	return hash.Sum(nil)
}

func makeSha256Reader(reader io.ReadSeeker) []byte {
	packet := make([]byte, 4096)
	hash := sha256.New()

	reader.Seek(0, 0)
	for {
		n, err := reader.Read(packet)
		if n > 0 {
			hash.Write(packet[0:n])
		}
		if err == io.EOF || n == 0 {
			break
		}
	}
	reader.Seek(0, 0)

	return hash.Sum(nil)
}

func hexDigest(data []byte) string {
	var buffer bytes.Buffer
	for i := range data {
		str := strconv.FormatUint(uint64(data[i]), 16)
		if len(str) < 2 {
			buffer.WriteString("0")
		}
		buffer.WriteString(str)
	}
	return buffer.String()
}
<commit_msg>Set() don't Add() new Auth/Date headers in signer<commit_after>package v4

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
	"io"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/awslabs/aws-sdk-go/aws"
)

const (
	authHeaderPrefix = "AWS4-HMAC-SHA256"
	timeFormat       = "20060102T150405Z"
	shortTimeFormat  = "20060102"
)

type signer struct {
	Request         *http.Request
	Time            time.Time
	ServiceName     string
	Region          string
	AccessKeyID     string
	SecretAccessKey string
	SessionToken    string
	Body            io.ReadSeeker
	Debug           uint

	formattedTime      string
	formattedShortTime string

	signedHeaders    string
	canonicalHeaders string
	canonicalString  string
	credentialString string
	stringToSign     string
	signature        string
	authorization    string
}

// Sign requests with signature version 4.
func Sign(req *aws.Request) {
	creds, _ := req.Service.Config.Credentials.Credentials()

	s := signer{
		Request:         req.HTTPRequest,
		Time:            req.Time,
		Body:            req.Body,
		ServiceName:     req.Service.ServiceName,
		Region:          req.Service.Config.Region,
		AccessKeyID:     creds.AccessKeyID,
		SecretAccessKey: creds.SecretAccessKey,
		SessionToken:    creds.SessionToken,
		Debug:           req.Service.Config.LogLevel,
	}
	s.sign()
}

func (v4 *signer) sign() {
	formatted := v4.Time.UTC().Format(timeFormat)

	// remove the old headers
	v4.Request.Header.Del("Date")
	v4.Request.Header.Del("Authorization")

	if v4.SessionToken != "" {
		v4.Request.Header.Set("X-Amz-Security-Token", v4.SessionToken)
	}

	v4.build()

	//v4.Debug = true
	if v4.Debug > 0 {
		fmt.Printf("---[ CANONICAL STRING  ]-----------------------------\n")
		fmt.Printf("%s\n", v4.canonicalString)
		fmt.Printf("-----------------------------------------------------\n\n")
		fmt.Printf("---[ STRING TO SIGN ]--------------------------------\n")
		fmt.Printf("%s\n", v4.stringToSign)
		fmt.Printf("-----------------------------------------------------\n")
	}

	// add the new ones
	v4.Request.Header.Set("Date", formatted)
	v4.Request.Header.Set("Authorization", v4.authorization)
}

func (v4 *signer) build() {
	v4.buildTime()
	v4.buildCanonicalHeaders()
	v4.buildCredentialString()
	v4.buildCanonicalString()
	v4.buildStringToSign()
	v4.buildSignature()
	v4.buildAuthorization()
}

func (v4 *signer) buildTime() {
	v4.formattedTime = v4.Time.UTC().Format(timeFormat)
	v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat)
}

func (v4 *signer) buildAuthorization() {
	v4.authorization = strings.Join([]string{
		authHeaderPrefix + " Credential=" + v4.AccessKeyID + "/" + v4.credentialString,
		"SignedHeaders=" + v4.signedHeaders,
		"Signature=" + v4.signature,
	}, ",")
}

func (v4 *signer) buildCredentialString() {
	v4.credentialString = strings.Join([]string{
		v4.formattedShortTime,
		v4.Region,
		v4.ServiceName,
		"aws4_request",
	}, "/")
}

func (v4 *signer) buildCanonicalHeaders() {
	headers := make([]string, 0)
	headers = append(headers, "host")
	for k, _ := range v4.Request.Header {
		if http.CanonicalHeaderKey(k) == "Content-Length" {
			continue // never sign content-length
		}
		headers = append(headers, strings.ToLower(k))
	}
	sort.Strings(headers)

	headerValues := make([]string, len(headers))
	for i, k := range headers {
		if k == "host" {
			headerValues[i] = "host:" + v4.Request.URL.Host
		} else {
			headerValues[i] = k + ":" +
				strings.Join(v4.Request.Header[http.CanonicalHeaderKey(k)], ",")
		}
	}

	v4.signedHeaders = strings.Join(headers, ";")
	v4.canonicalHeaders = strings.Join(headerValues, "\n")
}

func (v4 *signer) buildCanonicalString() {
	v4.canonicalString = strings.Join([]string{
		v4.Request.Method,
		v4.Request.URL.Path,
		v4.Request.URL.Query().Encode(),
		v4.canonicalHeaders + "\n",
		v4.signedHeaders,
		v4.bodyDigest(),
	}, "\n")
}

func (v4 *signer) buildStringToSign() {
	v4.stringToSign = strings.Join([]string{
		authHeaderPrefix,
		v4.formattedTime,
		v4.credentialString,
		hexDigest(makeSha256([]byte(v4.canonicalString))),
	}, "\n")
}

func (v4 *signer) buildSignature() {
	secret := v4.SecretAccessKey
	date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
	region := makeHmac(date, []byte(v4.Region))
	service := makeHmac(region, []byte(v4.ServiceName))
	credentials := makeHmac(service, []byte("aws4_request"))
	signature := makeHmac(credentials, []byte(v4.stringToSign))
	v4.signature = hexDigest(signature)
}

func (v4 *signer) bodyDigest() string {
	hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
	if hash == "" {
		if v4.Body == nil {
			hash = hexDigest(makeSha256([]byte{}))
		} else {
			hash = hexDigest(makeSha256Reader(v4.Body))
		}
		v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
	}
	return hash
}

func makeHmac(key []byte, data []byte) []byte {
	hash := hmac.New(sha256.New, key)
	hash.Write(data)
	return hash.Sum(nil)
}

func makeSha256(data []byte) []byte {
	hash := sha256.New()
	hash.Write(data)
	return hash.Sum(nil)
}

func makeSha256Reader(reader io.ReadSeeker) []byte {
	packet := make([]byte, 4096)
	hash := sha256.New()

	reader.Seek(0, 0)
	for {
		n, err := reader.Read(packet)
		if n > 0 {
			hash.Write(packet[0:n])
		}
		if err == io.EOF || n == 0 {
			break
		}
	}
	reader.Seek(0, 0)

	return hash.Sum(nil)
}

func hexDigest(data []byte) string {
	var buffer bytes.Buffer
	for i := range data {
		str := strconv.FormatUint(uint64(data[i]), 16)
		if len(str) < 2 {
			buffer.WriteString("0")
		}
		buffer.WriteString(str)
	}
	return buffer.String()
}
<|endoftext|>


<commit_before>package ui

import (
	"github.com/fabiofalci/sconsify/sconsify"
	"text/template"
	"io/ioutil"
	"bytes"
)

type StatusTrack struct {
	Action string
	Track  string
	Artist string
}

func ToStatusFile(fileName string, text string) {
	toFileEvents := sconsify.InitialiseEvents()

	t := template.Must(template.New("statusTemplate").Parse(text))

	ioutil.WriteFile(fileName, []byte(""), 0644)
	for {
		select {
		case track := <-toFileEvents.TrackPausedUpdates():
			var b bytes.Buffer
			t.Execute(&b, StatusTrack{Action: "Paused", Track: track.Name, Artist: track.Artist.Name})
			ioutil.WriteFile(fileName, b.Bytes(), 0644)
		case track := <-toFileEvents.TrackPlayingUpdates():
			var b bytes.Buffer
			t.Execute(&b, StatusTrack{Action: "Playing", Track: track.Name, Artist: track.Artist.Name})
			ioutil.WriteFile(fileName, b.Bytes(), 0644)
		case <-toFileEvents.ShutdownEngineUpdates():
			ioutil.WriteFile(fileName, []byte(""), 0644)
			break
		case <-toFileEvents.TrackNotAvailableUpdates():
		case <-toFileEvents.PlayTokenLostUpdates():
		case <-toFileEvents.NextPlayUpdates():
		case <-toFileEvents.PlaylistsUpdates():
		case <-toFileEvents.ArtistAlbumsUpdates():
		case <-toFileEvents.NewTrackLoadedUpdate():
		case <-toFileEvents.ShutdownSpotifyUpdates():
		case <-toFileEvents.SearchUpdates():
		case <-toFileEvents.PlayUpdates():
		case <-toFileEvents.ReplayUpdates():
		case <-toFileEvents.PauseUpdates():
		case <-toFileEvents.PlayPauseToggleUpdates():
		case <-toFileEvents.GetArtistAlbumsUpdates():
		}
	}
}

<commit_msg>Status file read only by owner<commit_after>package ui

import (
	"github.com/fabiofalci/sconsify/sconsify"
	"text/template"
	"io/ioutil"
	"bytes"
)

type StatusTrack struct {
	Action string
	Track  string
	Artist string
}

var fileName string

func toFile(content []byte) {
	ioutil.WriteFile(fileName, content, 0600)
}

func cleanStatusFile() {
	toFile([]byte(""))
}

func ToStatusFile(file string, text string) {
	fileName = file
	toFileEvents := sconsify.InitialiseEvents()

	t := template.Must(template.New("statusTemplate").Parse(text))

	cleanStatusFile()
	for {
		select {
		case track := <-toFileEvents.TrackPausedUpdates():
			var b bytes.Buffer
			t.Execute(&b, StatusTrack{Action: "Paused", Track: track.Name, Artist: track.Artist.Name})
			toFile(b.Bytes())
		case track := <-toFileEvents.TrackPlayingUpdates():
			var b bytes.Buffer
			t.Execute(&b, StatusTrack{Action: "Playing", Track: track.Name, Artist: track.Artist.Name})
			toFile(b.Bytes())
		case <-toFileEvents.ShutdownEngineUpdates():
			cleanStatusFile()
			break
		case <-toFileEvents.TrackNotAvailableUpdates():
		case <-toFileEvents.PlayTokenLostUpdates():
		case <-toFileEvents.NextPlayUpdates():
		case <-toFileEvents.PlaylistsUpdates():
		case <-toFileEvents.ArtistAlbumsUpdates():
		case <-toFileEvents.NewTrackLoadedUpdate():
		case <-toFileEvents.ShutdownSpotifyUpdates():
		case <-toFileEvents.SearchUpdates():
		case <-toFileEvents.PlayUpdates():
		case <-toFileEvents.ReplayUpdates():
		case <-toFileEvents.PauseUpdates():
		case <-toFileEvents.PlayPauseToggleUpdates():
		case <-toFileEvents.GetArtistAlbumsUpdates():
		}
	}
}

<|endoftext|>