<commit_before>package xorm

import (
	"crypto/md5"
	"crypto/rand"
	"crypto/sha1"
	"encoding/binary"
	"fmt"
	"hash"
	"net"
	"time"
)

// The UUID represents Universally Unique IDentifier (which is 128 bit long).
type UUID [16]byte

var (
	// NIL is defined in RFC 4122 section 4.1.7.
	// The nil UUID is special form of UUID that is specified to have all 128 bits set to zero.
	NIL = &UUID{
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}
	// NameSpaceDNS assume name to be a fully-qualified domain name.
	// Declared in RFC 4122 Appendix C.
	NameSpaceDNS = &UUID{
		0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// NameSpaceURL assume name to be a URL.
	// Declared in RFC 4122 Appendix C.
	NameSpaceURL = &UUID{
		0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// NameSpaceOID assume name to be an ISO OID.
	// Declared in RFC 4122 Appendix C.
	NameSpaceOID = &UUID{
		0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// NameSpaceX500 assume name to be a X.500 DN (in DER or a text output format).
	// Declared in RFC 4122 Appendix C.
	NameSpaceX500 = &UUID{
		0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
)

// Version of the UUID represents a kind of subtype specifier.
func (u *UUID) Version() int {
	return int(binary.BigEndian.Uint16(u[6:8]) >> 12)
}

// String returns the human readable form of the UUID.
func (u *UUID) String() string {
	return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
}

func (u *UUID) variantRFC4122() {
	u[8] = (u[8] & 0x3f) | 0x80
}

// NewV3 creates a new UUID with variant 3 as described in RFC 4122.
// Variant 3 based namespace-uuid and name and MD-5 hash calculation.
func NewV3(namespace *UUID, name []byte) *UUID {
	uuid := newByHash(md5.New(), namespace, name)
	uuid[6] = (uuid[6] & 0x0f) | 0x30
	return uuid
}

func newByHash(hash hash.Hash, namespace *UUID, name []byte) *UUID {
	hash.Write(namespace[:])
	hash.Write(name[:])

	var uuid UUID
	copy(uuid[:], hash.Sum(nil)[:16])
	uuid.variantRFC4122()
	return &uuid
}

type stamp [10]byte

var (
	mac      []byte
	requests chan bool
	answers  chan stamp
)

const gregorianUnix = 122192928000000000 // nanoseconds between gregorion zero and unix zero

func init() {
	mac = make([]byte, 6)
	rand.Read(mac)
	requests = make(chan bool)
	answers = make(chan stamp)
	go unique()
	i, err := net.Interfaces()
	if err != nil {
		return
	}
	for _, d := range i {
		if len(d.HardwareAddr) == 6 {
			mac = d.HardwareAddr[:6]
			return
		}
	}
}

// NewV1 creates a new UUID with variant 1 as described in RFC 4122.
// Variant 1 is based on hosts MAC address and actual timestamp (as count of 100-nanosecond intervals since
// 00:00:00.00, 15 October 1582 (the date of Gregorian reform to the Christian calendar).
func NewV1() *UUID {
	var uuid UUID
	requests <- true
	s := <-answers
	copy(uuid[:4], s[4:])
	copy(uuid[4:6], s[2:4])
	copy(uuid[6:8], s[:2])
	uuid[6] = (uuid[6] & 0x0f) | 0x10
	copy(uuid[8:10], s[8:])
	copy(uuid[10:], mac)
	uuid.variantRFC4122()
	return &uuid
}

func unique() {
	var (
		lastNanoTicks uint64
		clockSequence [2]byte
	)
	rand.Read(clockSequence[:])

	for range requests {
		var s stamp
		nanoTicks := uint64((time.Now().UTC().UnixNano() / 100) + gregorianUnix)
		if nanoTicks < lastNanoTicks {
			lastNanoTicks = nanoTicks
			rand.Read(clockSequence[:])
		} else if nanoTicks == lastNanoTicks {
			lastNanoTicks = nanoTicks + 1
		} else {
			lastNanoTicks = nanoTicks
		}
		binary.BigEndian.PutUint64(s[:], lastNanoTicks)
		copy(s[8:], clockSequence[:])
		answers <- s
	}
}

// NewV4 creates a new UUID with variant 4 as described in RFC 4122. Variant 4 based on pure random bytes.
func NewV4() *UUID {
	buf := make([]byte, 16)
	rand.Read(buf)
	buf[6] = (buf[6] & 0x0f) | 0x40
	var uuid UUID
	copy(uuid[:], buf[:])
	uuid.variantRFC4122()
	return &uuid
}

// NewV5 creates a new UUID with variant 5 as described in RFC 4122.
// Variant 5 based namespace-uuid and name and SHA-1 hash calculation.
func NewV5(namespaceUUID *UUID, name []byte) *UUID {
	uuid := newByHash(sha1.New(), namespaceUUID, name)
	uuid[6] = (uuid[6] & 0x0f) | 0x50
	return uuid
}

// NewNamespaceUUID creates a namespace UUID by using the namespace name in the NIL name space.
// This is a different approach as the 4 "standard" namespace UUIDs which are timebased UUIDs (V1).
func NewNamespaceUUID(namespace string) *UUID {
	return NewV5(NIL, []byte(namespace))
}
<commit_msg>add WithoutDashString() method<commit_after>package xorm

import (
	"crypto/md5"
	"crypto/rand"
	"crypto/sha1"
	"encoding/binary"
	"fmt"
	"hash"
	"net"
	"time"
)

// The UUID represents Universally Unique IDentifier (which is 128 bit long).
type UUID [16]byte

var (
	// NIL is defined in RFC 4122 section 4.1.7.
	// The nil UUID is special form of UUID that is specified to have all 128 bits set to zero.
	NIL = &UUID{
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}
	// NameSpaceDNS assume name to be a fully-qualified domain name.
	// Declared in RFC 4122 Appendix C.
	NameSpaceDNS = &UUID{
		0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// NameSpaceURL assume name to be a URL.
	// Declared in RFC 4122 Appendix C.
	NameSpaceURL = &UUID{
		0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// NameSpaceOID assume name to be an ISO OID.
	// Declared in RFC 4122 Appendix C.
	NameSpaceOID = &UUID{
		0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// NameSpaceX500 assume name to be a X.500 DN (in DER or a text output format).
	// Declared in RFC 4122 Appendix C.
	NameSpaceX500 = &UUID{
		0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
)

// Version of the UUID represents a kind of subtype specifier.
func (u *UUID) Version() int {
	return int(binary.BigEndian.Uint16(u[6:8]) >> 12)
}

// String returns the human readable form of the UUID.
func (u *UUID) String() string {
	return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
}

func (u *UUID) WithoutDashString() string {
	return fmt.Sprintf("%x", u[:])
}

func (u *UUID) variantRFC4122() {
	u[8] = (u[8] & 0x3f) | 0x80
}

// NewV3 creates a new UUID with variant 3 as described in RFC 4122.
// Variant 3 based namespace-uuid and name and MD-5 hash calculation.
func NewV3(namespace *UUID, name []byte) *UUID {
	uuid := newByHash(md5.New(), namespace, name)
	uuid[6] = (uuid[6] & 0x0f) | 0x30
	return uuid
}

func newByHash(hash hash.Hash, namespace *UUID, name []byte) *UUID {
	hash.Write(namespace[:])
	hash.Write(name[:])

	var uuid UUID
	copy(uuid[:], hash.Sum(nil)[:16])
	uuid.variantRFC4122()
	return &uuid
}

type stamp [10]byte

var (
	mac      []byte
	requests chan bool
	answers  chan stamp
)

const gregorianUnix = 122192928000000000 // nanoseconds between gregorion zero and unix zero

func init() {
	mac = make([]byte, 6)
	rand.Read(mac)
	requests = make(chan bool)
	answers = make(chan stamp)
	go unique()
	i, err := net.Interfaces()
	if err != nil {
		return
	}
	for _, d := range i {
		if len(d.HardwareAddr) == 6 {
			mac = d.HardwareAddr[:6]
			return
		}
	}
}

// NewV1 creates a new UUID with variant 1 as described in RFC 4122.
// Variant 1 is based on hosts MAC address and actual timestamp (as count of 100-nanosecond intervals since
// 00:00:00.00, 15 October 1582 (the date of Gregorian reform to the Christian calendar).
func NewV1() *UUID {
	var uuid UUID
	requests <- true
	s := <-answers
	copy(uuid[:4], s[4:])
	copy(uuid[4:6], s[2:4])
	copy(uuid[6:8], s[:2])
	uuid[6] = (uuid[6] & 0x0f) | 0x10
	copy(uuid[8:10], s[8:])
	copy(uuid[10:], mac)
	uuid.variantRFC4122()
	return &uuid
}

func unique() {
	var (
		lastNanoTicks uint64
		clockSequence [2]byte
	)
	rand.Read(clockSequence[:])

	for range requests {
		var s stamp
		nanoTicks := uint64((time.Now().UTC().UnixNano() / 100) + gregorianUnix)
		if nanoTicks < lastNanoTicks {
			lastNanoTicks = nanoTicks
			rand.Read(clockSequence[:])
		} else if nanoTicks == lastNanoTicks {
			lastNanoTicks = nanoTicks + 1
		} else {
			lastNanoTicks = nanoTicks
		}
		binary.BigEndian.PutUint64(s[:], lastNanoTicks)
		copy(s[8:], clockSequence[:])
		answers <- s
	}
}

// NewV4 creates a new UUID with variant 4 as described in RFC 4122. Variant 4 based on pure random bytes.
func NewV4() *UUID {
	buf := make([]byte, 16)
	rand.Read(buf)
	buf[6] = (buf[6] & 0x0f) | 0x40
	var uuid UUID
	copy(uuid[:], buf[:])
	uuid.variantRFC4122()
	return &uuid
}

// NewV5 creates a new UUID with variant 5 as described in RFC 4122.
// Variant 5 based namespace-uuid and name and SHA-1 hash calculation.
func NewV5(namespaceUUID *UUID, name []byte) *UUID {
	uuid := newByHash(sha1.New(), namespaceUUID, name)
	uuid[6] = (uuid[6] & 0x0f) | 0x50
	return uuid
}

// NewNamespaceUUID creates a namespace UUID by using the namespace name in the NIL name space.
// This is a different approach as the 4 "standard" namespace UUIDs which are timebased UUIDs (V1).
func NewNamespaceUUID(namespace string) *UUID {
	return NewV5(NIL, []byte(namespace))
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"github.com/bioothod/bucket-load/reader"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"runtime"
	"strings"
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	path := flag.String("path", "", "Path to log file to parse")
	max_requests := flag.Int("requests", 1024, "Maximum number of pending reqeusts to remote server")
	addr := flag.String("addr", "", "Remote backrunner proxy address (format: address:port)")

	flag.Parse()

	if *path == "" {
		log.Fatalf("You must specify log file to parse")
	}

	if *addr == "" {
		log.Fatalf("You must specify remote backrunner proxy address to test")
	}

	f, err := os.Open(*path)
	if err != nil {
		log.Fatalf("Could not open log file '%s' to parse: %v\n", *path, err)
	}

	br := bufio.NewReaderSize(f, 10240)

	re, err := reader.NewReader()
	if err != nil {
		log.Fatalf("Could not initialize regex: %v\n", err)
	}

	ch := make(chan *reader.Entry, *max_requests)

	for i := 0; i < *max_requests; i++ {
		go func(i int) {
			client := &http.Client {}

			for entry := range ch {
				if strings.HasPrefix(entry.Path, "/nobucket_upload/") {
					continue
				}
				if strings.HasPrefix(entry.Path, "/upload/") {
					entry.Path = strings.Replace(entry.Path, "/upload/", "/get/", 1)
					continue
				}

				url := fmt.Sprintf("http://%s%s", *addr, entry.Path)

				res, err := client.Get(url)
				if err != nil {
					log.Fatalf("%d: url: %s: get error: %v\n", i, url, err)
				}

				data, err := ioutil.ReadAll(res.Body)
				res.Body.Close()
				if err != nil {
					log.Fatalf("%d: url: %s: could not read response: %v\n", i, url, err)
				}

				fmt.Printf("%d: url: %s, data-size: %d, log-data-size: %d\n", i, url, len(data), entry.Size)
			}
		}(i)
	}

	for {
		line, _, err := br.ReadLine()
		if err != nil {
			log.Fatalf("Completed reading log file '%s': %v", *path, err)
		}

		entry, err := re.Run(string(line))
		if err != nil {
			continue
		}

		ch <- entry
	}
}
<commit_msg>bucket-load: replace /delete/ with /get/, it should generate 404 errors<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"github.com/bioothod/bucket-load/reader"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"runtime"
	"strings"
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	path := flag.String("path", "", "Path to log file to parse")
	max_requests := flag.Int("requests", 1024, "Maximum number of pending reqeusts to remote server")
	addr := flag.String("addr", "", "Remote backrunner proxy address (format: address:port)")

	flag.Parse()

	if *path == "" {
		log.Fatalf("You must specify log file to parse")
	}

	if *addr == "" {
		log.Fatalf("You must specify remote backrunner proxy address to test")
	}

	f, err := os.Open(*path)
	if err != nil {
		log.Fatalf("Could not open log file '%s' to parse: %v\n", *path, err)
	}

	br := bufio.NewReaderSize(f, 10240)

	re, err := reader.NewReader()
	if err != nil {
		log.Fatalf("Could not initialize regex: %v\n", err)
	}

	ch := make(chan *reader.Entry, *max_requests)

	for i := 0; i < *max_requests; i++ {
		go func(i int) {
			client := &http.Client {}

			for entry := range ch {
				if strings.HasPrefix(entry.Path, "/nobucket_upload/") {
					continue
				}
				if strings.HasPrefix(entry.Path, "/upload/") {
					entry.Path = strings.Replace(entry.Path, "/upload/", "/get/", 1)
					continue
				}
				if strings.HasPrefix(entry.Path, "/delete/") {
					entry.Path = strings.Replace(entry.Path, "/delete/", "/get/", 1)
					continue
				}

				url := fmt.Sprintf("http://%s%s", *addr, entry.Path)

				res, err := client.Get(url)
				if err != nil {
					log.Fatalf("%d: url: %s: get error: %v\n", i, url, err)
				}

				data, err := ioutil.ReadAll(res.Body)
				res.Body.Close()
				if err != nil {
					log.Fatalf("%d: url: %s: could not read response: %v\n", i, url, err)
				}

				fmt.Printf("%d: url: %s, data-size: %d, log-data-size: %d\n", i, url, len(data), entry.Size)
			}
		}(i)
	}

	for {
		line, _, err := br.ReadLine()
		if err != nil {
			log.Fatalf("Completed reading log file '%s': %v", *path, err)
		}

		entry, err := re.Run(string(line))
		if err != nil {
			continue
		}

		ch <- entry
	}
}
<|endoftext|>


<commit_before>package buffer

import (
	"bytes"
	"crypto/rand"
	"fmt"
	"io"
	"io/ioutil"
	"lib/test"
	"os"
	"testing"
)

func TestIO(t *testing.T) {
	buf := NewPartition(1024, NewFile)
	buf.Write([]byte("Hello world\n"))

	try := 2

	w := test.NewBadWriter(os.Stdout, try)

	var err error
	_, err = io.Copy(w, buf)
	for i := 0; i < try && err != nil; i++ {
		fmt.Println("Retrying...", err.Error())
		_, err = io.Copy(w, buf)
	}

	if err != nil {
		t.Error("Write failed.", err.Error())
	}
}

func TestFile(t *testing.T) {
	buf := NewFile(1024)
	checkCap(t, buf, 1024)
	runPerfectSeries(t, buf)
}

func TestMem(t *testing.T) {
	buf := New(1024)
	checkCap(t, buf, 1024)
	runPerfectSeries(t, buf)
}

func TestFilePartition(t *testing.T) {
	buf := NewPartition(1024, NewFile)
	checkCap(t, buf, MaxCap())
	runPerfectSeries(t, buf)
}

func TestMulti(t *testing.T) {
	buf := NewMulti(New(5), New(5), NewFile(500), NewPartition(1024, New))
	checkCap(t, buf, MaxCap())
	runPerfectSeries(t, buf)
	isPerfectMatch(t, buf, 1024*1024)
}

func runPerfectSeries(t *testing.T, buf Buffer) {
	checkEmpty(t, buf)
	simple(t, buf)

	max := LimitAlloc(buf.Cap())
	isPerfectMatch(t, buf, 0)
	for i := int64(1); i < max; i *= 2 {
		isPerfectMatch(t, buf, i)
	}
	isPerfectMatch(t, buf, max)
}

func simple(t *testing.T, buf Buffer) {
	buf.Write([]byte("hello world"))
	data, _ := ioutil.ReadAll(buf)
	if !bytes.Equal([]byte("hello world"), data) {
		t.Error("Hello world failed.")
	}

	buf.Write([]byte("hello world"))
	data = make([]byte, 3)
	buf.Read(data)
	buf.Write([]byte(" yolo"))
	data, _ = ioutil.ReadAll(buf)
	if !bytes.Equal([]byte("lo world yolo"), data) {
		t.Error("Buffer crossing error :(")
	}
}

func backAndForth(t *testing.T, buf Buffer, size int64) {

	r := io.LimitReader(rand.Reader, size)
	tee := io.TeeReader(r, buf)

	wrote, _ := ioutil.ReadAll(tee)

	half := int64(512)
	halfRead := make([]byte, half)

	n, _ := buf.Read(halfRead)
	halfRead = halfRead[:n]
	halfWrote := wrote[:n]

	if !bytes.Equal(halfWrote, halfRead) {
		t.Error("Back and forth error")
	}

	buf.Write(wrote[n:])

	fullRead, _ := ioutil.ReadAll(buf)

	if !bytes.Equal(append(wrote[n:], wrote[n:]...), fullRead) {
		t.Error("Back and forth error 2")
	}

}

func buildOutputs(t *testing.T, buf Buffer, size int64) (wrote []byte, read []byte) {
	r := io.LimitReader(rand.Reader, size)
	tee := io.TeeReader(r, buf)

	wrote, _ = ioutil.ReadAll(tee)
	read, _ = ioutil.ReadAll(buf)

	return wrote, read
}

func isPerfectMatch(t *testing.T, buf Buffer, size int64) {
	wrote, read := buildOutputs(t, buf, size)
	if !bytes.Equal(wrote, read) {
		t.Error("Buffer should have matched")
	}

	backAndForth(t, buf, size)
}

func checkEmpty(t *testing.T, buf Buffer) {
	if buf.Len() != 0 {
		t.Error("Buffer should start empty!")
	}
}

func checkCap(t *testing.T, buf Buffer, correctCap int64) {
	if buf.Cap() != correctCap {
		t.Error("Buffer cap is incorrect", buf.Cap(), correctCap)
	}
}
<commit_msg>Updated BadWriter test<commit_after>package buffer

import (
	"bytes"
	"crypto/rand"
	"fmt"
	"io"
	"io/ioutil"
	"lib/test"
	"os"
	"testing"
)

func TestIO(t *testing.T) {
	buf := NewPartition(1024, NewFile)
	buf.Write([]byte("Hello world\n"))

	try := 2

	w := test.NewBadWriter(os.Stdout, test.CountDown(try))

	var err error
	_, err = io.Copy(w, buf)
	for i := 0; i < try && err != nil; i++ {
		fmt.Println("Retrying...", err.Error())
		_, err = io.Copy(w, buf)
	}

	if err != nil {
		t.Error("Write failed.", err.Error())
	}
}

func TestFile(t *testing.T) {
	buf := NewFile(1024)
	checkCap(t, buf, 1024)
	runPerfectSeries(t, buf)
}

func TestMem(t *testing.T) {
	buf := New(1024)
	checkCap(t, buf, 1024)
	runPerfectSeries(t, buf)
}

func TestFilePartition(t *testing.T) {
	buf := NewPartition(1024, NewFile)
	checkCap(t, buf, MaxCap())
	runPerfectSeries(t, buf)
}

func TestMulti(t *testing.T) {
	buf := NewMulti(New(5), New(5), NewFile(500), NewPartition(1024, New))
	checkCap(t, buf, MaxCap())
	runPerfectSeries(t, buf)
	isPerfectMatch(t, buf, 1024*1024)
}

func runPerfectSeries(t *testing.T, buf Buffer) {
	checkEmpty(t, buf)
	simple(t, buf)

	max := LimitAlloc(buf.Cap())
	isPerfectMatch(t, buf, 0)
	for i := int64(1); i < max; i *= 2 {
		isPerfectMatch(t, buf, i)
	}
	isPerfectMatch(t, buf, max)
}

func simple(t *testing.T, buf Buffer) {
	buf.Write([]byte("hello world"))
	data, _ := ioutil.ReadAll(buf)
	if !bytes.Equal([]byte("hello world"), data) {
		t.Error("Hello world failed.")
	}

	buf.Write([]byte("hello world"))
	data = make([]byte, 3)
	buf.Read(data)
	buf.Write([]byte(" yolo"))
	data, _ = ioutil.ReadAll(buf)
	if !bytes.Equal([]byte("lo world yolo"), data) {
		t.Error("Buffer crossing error :(")
	}
}

func backAndForth(t *testing.T, buf Buffer, size int64) {

	r := io.LimitReader(rand.Reader, size)
	tee := io.TeeReader(r, buf)

	wrote, _ := ioutil.ReadAll(tee)

	half := int64(512)
	halfRead := make([]byte, half)

	n, _ := buf.Read(halfRead)
	halfRead = halfRead[:n]
	halfWrote := wrote[:n]

	if !bytes.Equal(halfWrote, halfRead) {
		t.Error("Back and forth error")
	}

	buf.Write(wrote[n:])

	fullRead, _ := ioutil.ReadAll(buf)

	if !bytes.Equal(append(wrote[n:], wrote[n:]...), fullRead) {
		t.Error("Back and forth error 2")
	}

}

func buildOutputs(t *testing.T, buf Buffer, size int64) (wrote []byte, read []byte) {
	r := io.LimitReader(rand.Reader, size)
	tee := io.TeeReader(r, buf)

	wrote, _ = ioutil.ReadAll(tee)
	read, _ = ioutil.ReadAll(buf)

	return wrote, read
}

func isPerfectMatch(t *testing.T, buf Buffer, size int64) {
	wrote, read := buildOutputs(t, buf, size)
	if !bytes.Equal(wrote, read) {
		t.Error("Buffer should have matched")
	}

	backAndForth(t, buf, size)
}

func checkEmpty(t *testing.T, buf Buffer) {
	if !Empty(buf) {
		t.Error("Buffer should start empty!")
	}
}

func checkCap(t *testing.T, buf Buffer, correctCap int64) {
	if buf.Cap() != correctCap {
		t.Error("Buffer cap is incorrect", buf.Cap(), correctCap)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	//"strings"
	//"path/filepath"
)

func main() {
	http.HandleFunc("/", http_handler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func http_handler(w http.ResponseWriter, r *http.Request) {
	document_root := "/home/gmorin/git/gingx"
	target_file := fmt.Sprint(document_root, r.URL.Path)
	fmt.Fprintln(w, fmt.Sprint("Requested file : ", target_file))
	if file_stat, err := os.Stat(target_file); err == nil {
		fmt.Fprintln(w, file_stat)
	} else {
		fmt.Fprintln(w, "404 File not found")
	}
	// FileMode
	//files, _ := filepath.Glob("*")
	//fmt.Fprintln(w, files)
}
<commit_msg>Content of directories, files, 404 handling<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
)

func main() {
	http.HandleFunc("/", http_handler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func http_handler(w http.ResponseWriter, r *http.Request) {
	document_root := os.Args[1]
	target_file := fmt.Sprint(document_root, r.URL.Path)
	if file_stat, err := os.Stat(target_file); err == nil {
		if file_stat.IsDir() {
			files, _ := filepath.Glob(fmt.Sprint(target_file, "/*"))
			fmt.Fprintln(w, fmt.Sprint("Content of directory : ", r.URL.Path))
			for _, element := range files {
				fmt.Fprintln(w, element)
			}
		} else {
			file, _ := os.Open(target_file)
			scanner := bufio.NewScanner(file)
			for scanner.Scan() {
				fmt.Fprintln(w, scanner.Text())
			}
		}
	} else {
		http.Error(w, fmt.Sprint("No such file or directory : ", r.URL.Path), http.StatusNotFound)
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Christian Gärtner. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.

package build

import (
	"errors"
	"fmt"
	"github.com/achtern/kluver/lexer"
)

type BuildStream struct {
	Err      chan error
	Request  chan LexRequest
	Response chan Shader
}

type LexRequest struct {
	Path   string
	Answer chan lexer.Token
}

type Shader struct {
	version  string
	vertex   Tokens
	fragment Tokens
	global   Tokens
	compiled GLSL
}

type GLSL struct {
	vertex   string
	fragment string
	provides []Tokens
	requests []Tokens
}

type varDef struct {
	typ  string
	name string
}

type Tokens []lexer.Token

const providePlaceholder = "___PROVIDE___REPLACE___HERE___\n"

func (s *Shader) String() string {
	return fmt.Sprintf("Shader(%s, vertex=%q, fragment=%q, global=%q)", s.version, s.vertex, s.fragment, s.global)
}

func (s *Shader) GetVertex() string {
	return s.compiled.vertex
}

func (s *Shader) GetFragment() string {
	return s.compiled.fragment
}

func New(tokenStream <-chan lexer.Token) BuildStream {
	buildStream := BuildStream{
		make(chan error),
		make(chan LexRequest),
		make(chan Shader),
	}
	go build(tokenStream, buildStream)
	return buildStream
}

func build(tokenStream <-chan lexer.Token, buildStream BuildStream) {
	var shader Shader

	done := make(chan Shader)
	reqPath := make(chan string)
	go buildShader(tokenStream, reqPath, done, buildStream.Err)

	shadersPending := 1

loop:
	for {
		select {
		case s := <-done:
			shadersPending -= 1
			shader = s
			if shadersPending == 0 {
				break loop
			}
		case path := <-reqPath:
			shadersPending += 1
			libStream := make(chan lexer.Token)
			buildStream.Request <- LexRequest{path, libStream}
			go buildShader(libStream, reqPath, done, buildStream.Err)
		}
	}

	shader.buildVertex()
	shader.buildFragment()

	for _, request := range shader.compiled.requests {
		if !contains(shader.compiled.provides, request) {
			buildStream.Err <- errors.New("Missing @provide statement for <" + request[0].Val + " " + request[1].Val + ">")
			return
		}
	}

	buildStream.Response <- shader
}

func buildShader(tokenStream <-chan lexer.Token, reqPath chan string, done chan Shader, err chan error) {
	shader := Shader{}

	shader.global = make(Tokens, 0)
	shader.vertex = make(Tokens, 0)
	shader.fragment = make(Tokens, 0)

	// phase 0 : global
	// phase 1 : vertex
	// phase 2 : fragment
	phase := 0
	for token := range tokenStream {
		if token.Typ == lexer.TokenError {
			err <- errors.New(token.Val)
			return
		}

		if token.Typ == lexer.TokenImportPath {
			reqPath <- token.Val
		}

		switch token.Typ {
		case lexer.TokenVertex:
			phase = 1
			continue
		case lexer.TokenFragment:
			phase = 2
			continue
		case lexer.TokenEnd:
			phase = 0
			continue
		case lexer.TokenVoid:
			continue
		}

		if token.Typ == lexer.TokenVersionNumber {
			shader.version = token.Val
			continue
		}

		if token.Typ == lexer.TokenAction {
			// we do need the action tokens after lexing
			continue
		}

		switch phase {
		case 0:
			shader.global = append(shader.global, token)
		case 1:
			shader.vertex = append(shader.vertex, token)
		case 2:
			shader.fragment = append(shader.fragment, token)
		default:
			panic("unknow phase")
		}
	}

	done <- shader
}

func (shader *Shader) buildVertex() {

	// vertex shader can only provide data to the fragment shader
	s, p, _ := buildGeneric(shader.vertex, shader.version)
	shader.compiled.vertex = s
	shader.compiled.provides = p
}

func (shader *Shader) buildFragment() {

	// fragment shader can only request data from the vertex shader
	s, _, r := buildGeneric(shader.fragment, shader.version)
	shader.compiled.fragment = s
	shader.compiled.requests = r
}
<commit_msg>improved libs support<commit_after>// Copyright 2015 Christian Gärtner. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.

package build

import (
	"errors"
	"fmt"
	"github.com/achtern/kluver/lexer"
)

type BuildStream struct {
	Err      chan error
	Request  chan LexRequest
	Response chan Shader
}

type LexRequest struct {
	Path   string
	Answer chan lexer.Token
}

type Shader struct {
	version  string
	vertex   Tokens
	fragment Tokens
	global   Tokens
	compiled GLSL
}

type GLSL struct {
	vertex   string
	fragment string
	provides []Tokens
	requests []Tokens
}

type varDef struct {
	typ  string
	name string
}

type Tokens []lexer.Token

const providePlaceholder = "___PROVIDE___REPLACE___HERE___\n"

func (s *Shader) String() string {
	return fmt.Sprintf("Shader(%s, vertex=%q, fragment=%q, global=%q)", s.version, s.vertex, s.fragment, s.global)
}

func (s *Shader) GetVertex() string {
	return s.compiled.vertex
}

func (s *Shader) GetFragment() string {
	return s.compiled.fragment
}

func New(tokenStream <-chan lexer.Token) BuildStream {
	buildStream := BuildStream{
		make(chan error),
		make(chan LexRequest),
		make(chan Shader),
	}
	go build(tokenStream, buildStream)
	return buildStream
}

func build(tokenStream <-chan lexer.Token, buildStream BuildStream) {
	var shader *Shader
	var libs []Shader

	done := make(chan Shader)
	lib := make(chan Shader)
	reqPath := make(chan string)
	go buildShader(tokenStream, reqPath, done, buildStream.Err)

	libsPending := 0

loop:
	for {
		select {
		case s := <-done:
			shader = &s
			if libsPending == 0 {
				break loop
			}
		case l := <-lib:
			libsPending -= 1
			libs = append(libs, l)
			if libsPending == 0 && shader != nil {
				break loop
			}
		case path := <-reqPath:
			libsPending += 1
			libStream := make(chan lexer.Token)
			buildStream.Request <- LexRequest{path, libStream}
			go buildShader(libStream, reqPath, lib, buildStream.Err)
		}
	}

	shader.buildVertex()
	shader.buildFragment()

	for _, request := range shader.compiled.requests {
		if !contains(shader.compiled.provides, request) {
			buildStream.Err <- errors.New("Missing @provide statement for <" + request[0].Val + " " + request[1].Val + ">")
			return
		}
	}

	buildStream.Response <- *shader
}

func buildShader(tokenStream <-chan lexer.Token, reqPath chan string, done chan Shader, err chan error) {
	shader := Shader{}

	shader.global = make(Tokens, 0)
	shader.vertex = make(Tokens, 0)
	shader.fragment = make(Tokens, 0)

	// phase 0 : global
	// phase 1 : vertex
	// phase 2 : fragment
	phase := 0
	for token := range tokenStream {
		if token.Typ == lexer.TokenError {
			err <- errors.New(token.Val)
			return
		}

		if token.Typ == lexer.TokenImportPath {
			reqPath <- token.Val
		}

		switch token.Typ {
		case lexer.TokenVertex:
			phase = 1
			continue
		case lexer.TokenFragment:
			phase = 2
			continue
		case lexer.TokenEnd:
			phase = 0
			continue
		case lexer.TokenVoid:
			continue
		}

		if token.Typ == lexer.TokenVersionNumber {
			shader.version = token.Val
			continue
		}

		if token.Typ == lexer.TokenAction {
			// we do need the action tokens after lexing
			continue
		}

		switch phase {
		case 0:
			shader.global = append(shader.global, token)
		case 1:
			shader.vertex = append(shader.vertex, token)
		case 2:
			shader.fragment = append(shader.fragment, token)
		default:
			panic("unknow phase")
		}
	}

	done <- shader
}

func (shader *Shader) buildVertex() {

	// vertex shader can only provide data to the fragment shader
	s, p, _ := buildGeneric(shader.vertex, shader.version)
	shader.compiled.vertex = s
	shader.compiled.provides = p
}

func (shader *Shader) buildFragment() {

	// fragment shader can only request data from the vertex shader
	s, _, r := buildGeneric(shader.fragment, shader.version)
	shader.compiled.fragment = s
	shader.compiled.requests = r
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// Version is the current version of the buffalo binary
const Version = "0.8.1"

func init() {
	RootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of buffalo",
	Long:  `All software has versions.  This is buffalo's.`,
	Run: func(c *cobra.Command, args []string) {
		fmt.Printf("Buffalo version is: %s\n", Version)
	},
	// needed to override the root level pre-run func
	PersistentPreRun: func(c *cobra.Command, args []string) {
	},
}
<commit_msg>set development version 0.8.2.dev<commit_after>package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// Version is the current version of the buffalo binary
const Version = "0.8.2.dev"

func init() {
	RootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of buffalo",
	Long:  `All software has versions.  This is buffalo's.`,
	Run: func(c *cobra.Command, args []string) {
		fmt.Printf("Buffalo version is: %s\n", Version)
	},
	// needed to override the root level pre-run func
	PersistentPreRun: func(c *cobra.Command, args []string) {
	},
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tchannel

import (
	"regexp"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestErrorMetricKeys(t *testing.T) {
	codes := []SystemErrCode{
		ErrCodeInvalid,
		ErrCodeTimeout,
		ErrCodeCancelled,
		ErrCodeBusy,
		ErrCodeDeclined,
		ErrCodeUnexpected,
		ErrCodeBadRequest,
		ErrCodeNetwork,
		ErrCodeProtocol,
	}

	// Metrics keys should be all lowercase letters and dashes. No spaces,
	// underscores, or other characters.
	expected := regexp.MustCompile(`^[[:lower:]-]+$`)
	for _, c := range codes {
		assert.True(t, expected.MatchString(c.MetricsKey()), "Expected metrics key for code %s to be well-formed.", c.String())
	}

	// Unexpected codes may have poorly-formed keys.
	assert.Equal(t, "SystemErrCode(13)", SystemErrCode(13).MetricsKey(), "Expected invalid error codes to use a fallback metrics key format.")
}
<commit_msg>Validate GetSystemErrorCode<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tchannel

import (
	"io"
	"regexp"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestErrorMetricKeys(t *testing.T) {
	codes := []SystemErrCode{
		ErrCodeInvalid,
		ErrCodeTimeout,
		ErrCodeCancelled,
		ErrCodeBusy,
		ErrCodeDeclined,
		ErrCodeUnexpected,
		ErrCodeBadRequest,
		ErrCodeNetwork,
		ErrCodeProtocol,
	}

	// Metrics keys should be all lowercase letters and dashes. No spaces,
	// underscores, or other characters.
	expected := regexp.MustCompile(`^[[:lower:]-]+$`)
	for _, c := range codes {
		assert.True(t, expected.MatchString(c.MetricsKey()), "Expected metrics key for code %s to be well-formed.", c.String())
	}

	// Unexpected codes may have poorly-formed keys.
	assert.Equal(t, "SystemErrCode(13)", SystemErrCode(13).MetricsKey(), "Expected invalid error codes to use a fallback metrics key format.")
}

func TestInvalidError(t *testing.T) {
	code := GetSystemErrorCode(nil)
	assert.Equal(t, ErrCodeInvalid, code, "nil error should produce ErrCodeInvalid")
}

func TestUnexpectedError(t *testing.T) {
	code := GetSystemErrorCode(io.EOF)
	assert.Equal(t, ErrCodeUnexpected, code, "non-tchannel SystemError should produce ErrCodeUnexpected")
}

func TestSystemError(t *testing.T) {
	code := GetSystemErrorCode(ErrTimeout)
	assert.Equal(t, ErrCodeTimeout, code, "tchannel timeout error produces ErrCodeTimeout")
}
<|endoftext|>


<commit_before><commit_msg>Rename the parent of CollectionPage object so we avoid conflict with CollectionInterface<commit_after><|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"github.com/alexaandru/utils"
	"io/ioutil"
	"launchpad.net/goamz/aws"
	"launchpad.net/goamz/s3"
	"mime"
	"os"
	"path/filepath"
	"runtime"
	"sync"
)

// RequestTimeoutError is a frequent error received when there are too many threads.
// If you encounter this too often, reduce the number of workers.
const RequestTimeoutError = "Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed."

// Various exit codes
const (
	Success = iota
	CachingFailed
	LoadingCacheFailed
	S3Failed
	S3AuthError
	FileReadFailed
	CmdLineOptionError
)

type options struct {
	workersCount int
	bucketName, source,
	cacheFile string
	dryRun, verbose, quiet, doCache, doUpload bool
}

var auth aws.Auth

// s3put puts one file to S3 and tries to recover from RequestTimeoutError
func s3put(bucket *s3.Bucket, fname string, opts *options) (err error) {
	fullName := filepath.Join(opts.source, fname)
	if data, err := ioutil.ReadFile(fullName); err == nil {
		if err = bucket.Put(fname, data, betterMime(fname), s3.PublicRead); err != nil {
			if err.Error() == RequestTimeoutError {
				if opts.verbose || opts.quiet {
					fmt.Println("Warn: upload failed, retrying:", fname)
				} else {
					fmt.Print("r")
				}
				bucket = s3.New(auth, aws.EUWest).Bucket(opts.bucketName)
				return s3put(bucket, fname, opts)
			}

			fmt.Println("S3 error:", err)
			os.Exit(S3Failed)
		} else {
			if opts.verbose {
				fmt.Println("Uploaded", fname)
			} else if !opts.quiet {
				fmt.Print(".")
			}
		}
	} else {
		fmt.Println("Read error:", err)
		os.Exit(FileReadFailed)
	}

	return
}

func uploadWorker(bucket *s3.Bucket, linkChan chan string, wg *sync.WaitGroup, opts *options) {
	defer wg.Done()

	for fname := range linkChan {
		if opts.dryRun {
			if opts.verbose {
				fmt.Println("Pretending to upload", fname)
			} else if !opts.quiet {
				fmt.Print(".")
			}
		} else {
			s3put(bucket, fname, opts)
		}
	}
}

func prepareUploadList(opts *options) (current utils.FileHashes, diff []string) {
	var old utils.FileHashes
	current, old = utils.FileHashesNew(opts.source), utils.FileHashes{}
	old.Load(opts.cacheFile)
	diff = current.Diff(old)

	if len(diff) == 0 {
		if !opts.quiet {
			fmt.Println("Nothing to upload.")
		}
		os.Exit(Success)
	} else if opts.verbose {
		fmt.Printf("List of changes ready, there are %d files to be uploaded to %s:\n", len(diff), opts.bucketName)
	}

	return
}

func upload(diff []string, opts *options) {
	var err error
	if auth, err = aws.EnvAuth(); err != nil {
		fmt.Println(err)
		os.Exit(S3AuthError)
	}
	bucket := s3.New(auth, aws.EUWest).Bucket(opts.bucketName)

	wg := new(sync.WaitGroup)
	defer wg.Wait()
	comm := make(chan string)
	defer close(comm)

	wg.Add(opts.workersCount)
	for i := 0; i < opts.workersCount; i++ {
		go uploadWorker(bucket, comm, wg, opts)
	}

	for _, fname := range diff {
		comm <- fname
	}
}

func handleUpload(diff []string, opts *options) {
	if opts.doUpload {
		if !(opts.quiet || opts.verbose) {
			fmt.Printf("Uploading to %s ", opts.bucketName)
		}

		upload(diff, opts)

		if !opts.quiet {
			fmt.Println("done!")
		}
	} else if opts.verbose {
		fmt.Println("Skipping upload")
	}
}

func handleCache(current utils.FileHashes, opts *options) {
	if opts.doCache {
		if !opts.dryRun {
			if err := current.Dump(opts.cacheFile); err != nil {
				fmt.Println(err)
				os.Exit(CachingFailed)
			}
			if opts.verbose {
				fmt.Println("Updated cache. All done!")
			}
		} else if opts.verbose {
			fmt.Println("Pretending to update cache. All done!")
		}
	} else if opts.verbose {
		fmt.Println("Skipping cache")
	}
}

func processCmdLineFlags() (opts *options) {
	opts = new(options)

	flag.IntVar(&opts.workersCount, "workers", 42, "No. of workers/threads to use for S3 uploads")
	flag.StringVar(&opts.bucketName, "bucket", "", "S3 bucket to upload files to")
	flag.StringVar(&opts.source, "source", "output", "Source folder for files to be uploaded to S3")
	flag.StringVar(&opts.cacheFile, "cachefile", filepath.Join(".go3up.txt"), "Location of the cache file")
	flag.BoolVar(&opts.dryRun, "dry", false, "Dry run (no upload/cache update)")
	flag.BoolVar(&opts.verbose, "verbose", false, "Print the name of the files as they are uploaded")
	flag.BoolVar(&opts.quiet, "quiet", false, "Print only warnings and errors")
	flag.BoolVar(&opts.doUpload, "upload", true, "Do perform an upload")
	flag.BoolVar(&opts.doCache, "cache", true, "Do update the cache")

	flag.Parse()
	validateCmdLineFlags(opts)

	return
}

func validateCmdLineFlags(opts *options) (err error) {
	// FIXME: More checks: if source is a folder, if hash file is a file, if bucket exists, etc.
	flags := map[string]string{
		"Bucket Name": opts.bucketName,
		"Source":      opts.source,
		"Cache file":  opts.cacheFile,
	}

	for label, val := range flags {
		if err = validateCmdLineFlag(label, val); err != nil {
			fmt.Printf("%s should be set. Please use 'go3up -h' for help.\n", label)
			os.Exit(CmdLineOptionError)
		}
	}

	return
}

// NOTE: currently it is limited to just checking paths (if set and if they exist)
func validateCmdLineFlag(label, val string) (err error) {
	switch label {
	case "Bucket Name":
		if val == "" {
			err = errors.New(label + " is not set")
		}
		return
	default:
		_, err = os.Stat(val)
		return

	}
}

func betterMime(fname string) (mt string) {
	ext := filepath.Ext(fname)
	if mt = mime.TypeByExtension(ext); mt != "" {
		return
	} else if ext == ".JPG" {
		mt = "image/jpeg"
	} else if ext == ".ttf" {
		mt = "binary/octet-stream"
	}

	return
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	opts := processCmdLineFlags()
	current, diff := prepareUploadList(opts)
	handleUpload(diff, opts)
	handleCache(current, opts)
}
<commit_msg>Added package documentation<commit_after>/*
Go3Up (Go S3 Uploader) is a small S3 uploader tool.

It was created in order to speed up S3 uploads by employing a little meta data caching about
what was already uploaded. The tool can remember what files where uploaded (and their md5 sum)
and on subsequent runs only upload the files that actually changed since the last run.

The initial use case, was a large static site (with 10k+ files) that needed to change frequently
only some of the files (about ~100 routinely). In that particular case, the time reduction by
switching from s3cmd to go3up was quite significant.

On uploads with empty cache there may not be any benefit.

The current focus of the tool is just one way uploads (without deleting things that were removed
locally, yet). That may (or not) change in the future.
*/
package main

import (
	"errors"
	"flag"
	"fmt"
	"github.com/alexaandru/utils"
	"io/ioutil"
	"launchpad.net/goamz/aws"
	"launchpad.net/goamz/s3"
	"mime"
	"os"
	"path/filepath"
	"runtime"
	"sync"
)

// RequestTimeoutError is a frequent error received when there are too many threads.
// If you encounter this too often, reduce the number of workers.
const RequestTimeoutError = "Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed."

// Go3up exit codes
const (
	Success = iota
	CachingFailed
	LoadingCacheFailed
	S3Failed
	S3AuthError
	FileReadFailed
	CmdLineOptionError
)

type options struct {
	workersCount int
	bucketName, source,
	cacheFile string
	dryRun, verbose, quiet, doCache, doUpload bool
}

var auth aws.Auth

// s3put puts one file to S3 and tries to recover from RequestTimeoutError
func s3put(bucket *s3.Bucket, fname string, opts *options) (err error) {
	fullName := filepath.Join(opts.source, fname)
	if data, err := ioutil.ReadFile(fullName); err == nil {
		if err = bucket.Put(fname, data, betterMime(fname), s3.PublicRead); err != nil {
			if err.Error() == RequestTimeoutError {
				if opts.verbose || opts.quiet {
					fmt.Println("Warn: upload failed, retrying:", fname)
				} else {
					fmt.Print("r")
				}
				bucket = s3.New(auth, aws.EUWest).Bucket(opts.bucketName)
				return s3put(bucket, fname, opts)
			}

			fmt.Println("S3 error:", err)
			os.Exit(S3Failed)
		} else {
			if opts.verbose {
				fmt.Println("Uploaded", fname)
			} else if !opts.quiet {
				fmt.Print(".")
			}
		}
	} else {
		fmt.Println("Read error:", err)
		os.Exit(FileReadFailed)
	}

	return
}

func uploadWorker(bucket *s3.Bucket, linkChan chan string, wg *sync.WaitGroup, opts *options) {
	defer wg.Done()

	for fname := range linkChan {
		if opts.dryRun {
			if opts.verbose {
				fmt.Println("Pretending to upload", fname)
			} else if !opts.quiet {
				fmt.Print(".")
			}
		} else {
			s3put(bucket, fname, opts)
		}
	}
}

func prepareUploadList(opts *options) (current utils.FileHashes, diff []string) {
	var old utils.FileHashes
	current, old = utils.FileHashesNew(opts.source), utils.FileHashes{}
	old.Load(opts.cacheFile)
	diff = current.Diff(old)

	if len(diff) == 0 {
		if !opts.quiet {
			fmt.Println("Nothing to upload.")
		}
		os.Exit(Success)
	} else if opts.verbose {
		fmt.Printf("List of changes ready, there are %d files to be uploaded to %s:\n", len(diff), opts.bucketName)
	}

	return
}

func upload(diff []string, opts *options) {
	var err error
	if auth, err = aws.EnvAuth(); err != nil {
		fmt.Println(err)
		os.Exit(S3AuthError)
	}
	bucket := s3.New(auth, aws.EUWest).Bucket(opts.bucketName)

	wg := new(sync.WaitGroup)
	defer wg.Wait()
	comm := make(chan string)
	defer close(comm)

	wg.Add(opts.workersCount)
	for i := 0; i < opts.workersCount; i++ {
		go uploadWorker(bucket, comm, wg, opts)
	}

	for _, fname := range diff {
		comm <- fname
	}
}

func handleUpload(diff []string, opts *options) {
	if opts.doUpload {
		if !(opts.quiet || opts.verbose) {
			fmt.Printf("Uploading to %s ", opts.bucketName)
		}

		upload(diff, opts)

		if !opts.quiet {
			fmt.Println("done!")
		}
	} else if opts.verbose {
		fmt.Println("Skipping upload")
	}
}

func handleCache(current utils.FileHashes, opts *options) {
	if opts.doCache {
		if !opts.dryRun {
			if err := current.Dump(opts.cacheFile); err != nil {
				fmt.Println(err)
				os.Exit(CachingFailed)
			}
			if opts.verbose {
				fmt.Println("Updated cache. All done!")
			}
		} else if opts.verbose {
			fmt.Println("Pretending to update cache. All done!")
		}
	} else if opts.verbose {
		fmt.Println("Skipping cache")
	}
}

func processCmdLineFlags() (opts *options) {
	opts = new(options)

	flag.IntVar(&opts.workersCount, "workers", 42, "No. of workers/threads to use for S3 uploads")
	flag.StringVar(&opts.bucketName, "bucket", "", "S3 bucket to upload files to")
	flag.StringVar(&opts.source, "source", "output", "Source folder for files to be uploaded to S3")
	flag.StringVar(&opts.cacheFile, "cachefile", filepath.Join(".go3up.txt"), "Location of the cache file")
	flag.BoolVar(&opts.dryRun, "dry", false, "Dry run (no upload/cache update)")
	flag.BoolVar(&opts.verbose, "verbose", false, "Print the name of the files as they are uploaded")
	flag.BoolVar(&opts.quiet, "quiet", false, "Print only warnings and errors")
	flag.BoolVar(&opts.doUpload, "upload", true, "Do perform an upload")
	flag.BoolVar(&opts.doCache, "cache", true, "Do update the cache")

	flag.Parse()
	validateCmdLineFlags(opts)

	return
}

func validateCmdLineFlags(opts *options) (err error) {
	// FIXME: More checks: if source is a folder, if hash file is a file, if bucket exists, etc.
	flags := map[string]string{
		"Bucket Name": opts.bucketName,
		"Source":      opts.source,
		"Cache file":  opts.cacheFile,
	}

	for label, val := range flags {
		if err = validateCmdLineFlag(label, val); err != nil {
			fmt.Printf("%s should be set. Please use 'go3up -h' for help.\n", label)
			os.Exit(CmdLineOptionError)
		}
	}

	return
}

// NOTE: currently it is limited to just checking paths (if set and if they exist)
func validateCmdLineFlag(label, val string) (err error) {
	switch label {
	case "Bucket Name":
		if val == "" {
			err = errors.New(label + " is not set")
		}
		return
	default:
		_, err = os.Stat(val)
		return

	}
}

func betterMime(fname string) (mt string) {
	ext := filepath.Ext(fname)
	if mt = mime.TypeByExtension(ext); mt != "" {
		return
	} else if ext == ".JPG" {
		mt = "image/jpeg"
	} else if ext == ".ttf" {
		mt = "binary/octet-stream"
	}

	return
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	opts := processCmdLineFlags()
	current, diff := prepareUploadList(opts)
	handleUpload(diff, opts)
	handleCache(current, opts)
}
<|endoftext|>


<commit_before>package gobay

import (
    "fmt"
)

type ShipToLocation string
type PictureDetail string
type PaymentMethod string
type ShippingServiceOption struct {
    Service string
    Cost string
    Priority string
}
type Product struct {
    SKU string
    Title string
    Price string
    []ShipToLocations ShipToLocation
    []PictureDetails PictureDetail
    []PaymentMethods PaymentMethod
}
type EbayCall struct {
    DevID string
    AppID string
    CertID string
    CompatLevel string
    SiteID string
    EndPoint string
    EbayAuthToken string
    Country string
    Currency string
    PaypalEmailAddress string
    Headers map[string]string
    TheProduct Product
}

func NewEbayCall(compatLevel, devID, appID, certID, siteID, callName string) EbayCall {
    var e EbayCall
    e.Headers = {
      fmt.Sprintf('X-EBAY-API-COMPATIBILITY-LEVEL:%s',compatLevel),
      fmt.Sprintf('X-EBAY-API-DEV-NAME:%s' , devID,
      fmt.Sprintf('X-EBAY-API-APP-NAME:%s', appID,
      fmt.Sprintf('X-EBAY-API-CERT-NAME:%s', certID,
      fmt.Sprintf('X-EBAY-API-CALL-NAME:%s', callName,
      fmt.Sprintf('X-EBAY-API-SITEID:%s',siteID,
    }
}<commit_msg>Adding Files<commit_after>package gobay

import (
    "fmt"
    "net/http"
)

type ShipToLocation string
type PictureDetail string
type PaymentMethod string
type ShippingServiceOption struct {
    Service string
    Cost string
    Priority string
}
type Product struct {
    SKU string
    Title string
    Price string
    []ShipToLocations ShipToLocation
    []PictureDetails PictureDetail
    []PaymentMethods PaymentMethod
}
type EbayCall struct {
    DevID string
    AppID string
    CertID string
    CompatLevel string
    SiteID string
    EndPoint string
    EbayAuthToken string
    Country string
    Currency string
    PaypalEmailAddress string
    Headers map[string]string
    TheProduct Product
    TheRequest http.Request
}

func NewEbayCall(endPoint, compatLevel, devID, appID, certID, siteID, callName string, p Product) *EbayCall {
    var e EbayCall
    m := make(map[string]string)
    m["X-EBAY-API-COMPATIBILITY-LEVEL"] = fmt.Sprintf("%s",compatLevel)
    m["X-EBAY-API-DEV-NAME"] = fmt.Sprintf("%s",devID)
    m["X-EBAY-API-APP-NAME"] = fmt.Sprintf("%s", appID)
    m["X-EBAY-API-CERT-NAME"] = fmt.Sprintf("%s", certID)
    m["X-EBAY-API-CALL-NAME"] = fmt.Sprintf("%s", callName)
    m["X-EBAY-API-SITEID"] = fmt.Sprintf("%s",siteID)
    e.Headers = m
    e.DevID = devID
    e.AppID = appID
    e.CertID = certID
    e.SiteID = siteID
    e.TheProduct = p
    // need to decide body from io.reader...so we need to compile the template
    e.TheRequest = NewRequest("POST",endPoint)
    return &e
}<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"runtime/debug"
	"strings"
	"time"
)

const (
	PANIC_MAX = 5
	INTERVAL  = 5 //Minute
)

var (
	configuration Settings
	optConf       = flag.String("c", "./config.json", "config file")
	optCommand    = flag.String("s", "", "send signal to a master process: stop, quit, reopen, reload")
	optHelp       = flag.Bool("h", false, "this help")
	panicCount    = 0
)

func usage() {
	log.Println("[command] -c=[config file path]")
	flag.PrintDefaults()
}
func main() {
	flag.Parse()
	if *optHelp {
		usage()
		return
	}

	var err error
	configuration, err = LoadSettings(*optConf)

	err = InitLogger(configuration.Log_Path, configuration.Log_Size, configuration.Log_Num)
	if err != nil {
		log.Println("InitLogger error:", err)
		return
	}

	if err != nil {
		fmt.Println(err.Error())
		log.Println(err.Error())
		os.Exit(1)
	}

	dnsLoop()
}

func dnsLoop() {
	defer func() {
		if err := recover(); err != nil {
			panicCount++
			log.Printf("Recovered in %v: %v\n", err, debug.Stack())
			if panicCount < PANIC_MAX {
				log.Println("Got panic in goroutine, will start a new one... :", panicCount)
				go dnsLoop()
			}
		}
	}()

	for {

		domainID := getDomain(configuration.Domain)

		if domainID == -1 {
			continue
		}

		currentIP, err := getCurrentIP(configuration.IP_Url)

		if err != nil {
			log.Println("get_currentIP:", err)
			continue
		}

		subDomainID, ip := getSubDomain(domainID, configuration.Sub_domain)

		if subDomainID == "" || ip == "" {
			log.Println("sub_domain:", subDomainID, ip)
			continue
		}

		log.Println("currentIp is:", currentIP)

		//Continue to check the IP of sub-domain
		if len(ip) > 0 && !strings.Contains(currentIP, ip) {
			log.Println("Start to update record IP...")
			updateIP(domainID, subDomainID, configuration.Sub_domain, currentIP)
		} else {
			log.Println("Current IP is same as domain IP, no need to update...")
		}

		//Interval is 5 minutes
		time.Sleep(time.Minute * INTERVAL)
	}
}
<commit_msg>Output panic function and line in recover func<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"runtime"
	"runtime/debug"
	"strings"
	"time"
)

const (
	PANIC_MAX = 5
	INTERVAL  = 5 //Minute
)

var (
	configuration Settings
	optConf       = flag.String("c", "./config.json", "config file")
	optCommand    = flag.String("s", "", "send signal to a master process: stop, quit, reopen, reload")
	optHelp       = flag.Bool("h", false, "this help")
	panicCount    = 0
)

func identifyPanic() string {
	var name, file string
	var line int
	var pc [16]uintptr

	n := runtime.Callers(3, pc[:])
	for _, pc := range pc[:n] {
		fn := runtime.FuncForPC(pc)
		if fn == nil {
			continue
		}
		file, line = fn.FileLine(pc)
		name = fn.Name()
		if !strings.HasPrefix(name, "runtime.") {
			break
		}
	}

	switch {
	case name != "":
		return fmt.Sprintf("%v:%v", name, line)
	case file != "":
		return fmt.Sprintf("%v:%v", file, line)
	}

	return fmt.Sprintf("pc:%x", pc)
}

func usage() {
	log.Println("[command] -c=[config file path]")
	flag.PrintDefaults()
}

func main() {
	flag.Parse()
	if *optHelp {
		usage()
		return
	}

	var err error
	configuration, err = LoadSettings(*optConf)

	err = InitLogger(configuration.Log_Path, configuration.Log_Size, configuration.Log_Num)
	if err != nil {
		log.Println("InitLogger error:", err)
		return
	}

	if err != nil {
		fmt.Println(err.Error())
		log.Println(err.Error())
		os.Exit(1)
	}

	dnsLoop()
}

func dnsLoop() {
	defer func() {
		if err := recover(); err != nil {
			panicCount++
			log.Printf("Recovered in %v: %v\n", err, debug.Stack())
			fmt.Println(identifyPanic())
			if panicCount < PANIC_MAX {
				log.Println("Got panic in goroutine, will start a new one... :", panicCount)
				go dnsLoop()
			}
		}
	}()

	for {

		domainID := getDomain(configuration.Domain)

		if domainID == -1 {
			continue
		}

		currentIP, err := getCurrentIP(configuration.IP_Url)

		if err != nil {
			log.Println("get_currentIP:", err)
			continue
		}

		subDomainID, ip := getSubDomain(domainID, configuration.Sub_domain)

		if subDomainID == "" || ip == "" {
			log.Println("sub_domain:", subDomainID, ip)
			continue
		}

		log.Println("currentIp is:", currentIP)

		//Continue to check the IP of sub-domain
		if len(ip) > 0 && !strings.Contains(currentIP, ip) {
			log.Println("Start to update record IP...")
			updateIP(domainID, subDomainID, configuration.Sub_domain, currentIP)
		} else {
			log.Println("Current IP is same as domain IP, no need to update...")
		}

		//Interval is 5 minutes
		time.Sleep(time.Minute * INTERVAL)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"time"
)

func main() {
	var cmdAppend bool

	cmd := flag.NewFlagSet("gotee", flag.ExitOnError)
	cmd.BoolVar(&cmdAppend, "a", false, "Append to FILE. Do not overwrite.")
	cmd.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: gotee [options] FILE\n")
		cmd.PrintDefaults()
	}
	cmd.Parse(os.Args[1:])

	filePath := cmd.Arg(0)
	if filePath == "" {
		cmd.Usage()
		os.Exit(2)
	}

	openFlags := os.O_WRONLY|os.O_CREATE|os.O_TRUNC
	if cmdAppend {
		openFlags = os.O_WRONLY|os.O_CREATE|os.O_APPEND
	}

	file, err := os.OpenFile(filePath, openFlags, 0666)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	buffer := make([]byte, 4096)
	writer := io.MultiWriter(file, os.Stdout)
	nextVanishCheck := time.Now().Add(5 * time.Second)

	for {
		bytesRead, err := os.Stdin.Read(buffer)
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		now := time.Now()
		if now.After(nextVanishCheck) {
			nextVanishCheck = now.Add(5 * time.Second)
			if _, err := os.Stat(filePath); err != nil {
				file.Close()
				file, err = os.OpenFile(filePath, openFlags, 0666)
				if err != nil {
					fmt.Fprintln(os.Stderr, err)
					os.Exit(1)
				}
				writer = io.MultiWriter(file, os.Stdout)
				fmt.Fprintln(os.Stderr, "log file re-opened")
			}
		}

		_, err = writer.Write(buffer[:bytesRead])
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
	}
}
<commit_msg>Gofmt<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"time"
)

func main() {
	var cmdAppend bool

	cmd := flag.NewFlagSet("gotee", flag.ExitOnError)
	cmd.BoolVar(&cmdAppend, "a", false, "Append to FILE. Do not overwrite.")
	cmd.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage: gotee [options] FILE")
		cmd.PrintDefaults()
	}
	cmd.Parse(os.Args[1:])

	filePath := cmd.Arg(0)
	if filePath == "" {
		cmd.Usage()
		os.Exit(2)
	}

	openFlags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC
	if cmdAppend {
		openFlags = os.O_WRONLY | os.O_CREATE | os.O_APPEND
	}

	file, err := os.OpenFile(filePath, openFlags, 0666)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	buffer := make([]byte, 4096)
	writer := io.MultiWriter(file, os.Stdout)
	nextVanishCheck := time.Now().Add(5 * time.Second)

	for {
		bytesRead, err := os.Stdin.Read(buffer)
		if err == io.EOF {
			break
		}
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		now := time.Now()
		if now.After(nextVanishCheck) {
			nextVanishCheck = now.Add(5 * time.Second)
			if _, err := os.Stat(filePath); err != nil {
				file.Close()
				file, err = os.OpenFile(filePath, openFlags, 0666)
				if err != nil {
					fmt.Fprintln(os.Stderr, err)
					os.Exit(1)
				}
				writer = io.MultiWriter(file, os.Stdout)
				fmt.Fprintln(os.Stderr, "log file re-opened")
			}
		}

		_, err = writer.Write(buffer[:bytesRead])
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/elasticache"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsElasticacheCluster() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsElasticacheClusterCreate,
		Read:   resourceAwsElasticacheClusterRead,
		Delete: resourceAwsElasticacheClusterDelete,

		Schema: map[string]*schema.Schema{
			"cluster_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"engine": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"node_type": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"num_cache_nodes": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},
			"parameter_group_name": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"port": &schema.Schema{
				Type:     schema.TypeInt,
				Default:  11211,
				Optional: true,
				ForceNew: true,
			},
			"engine_version": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"subnet_group_name": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"security_group_names": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				Computed: true,
				ForceNew: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},
			"security_group_ids": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				Computed: true,
				ForceNew: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},
		},
	}
}

func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).elasticacheconn

	clusterId := d.Get("cluster_id").(string)
	nodeType := d.Get("node_type").(string)           // e.g) cache.m1.small
	numNodes := int64(d.Get("num_cache_nodes").(int)) // 2
	engine := d.Get("engine").(string)                // memcached
	engineVersion := d.Get("engine_version").(string) // 1.4.14
	port := int64(d.Get("port").(int))                // 11211
	subnetGroupName := d.Get("subnet_group_name").(string)
	securityNameSet := d.Get("security_group_names").(*schema.Set)
	securityIdSet := d.Get("security_group_ids").(*schema.Set)
	paramGroupName := d.Get("parameter_group_name").(string) // default.memcached1.4

	securityNames := expandStringList(securityNameSet.List())
	securityIds := expandStringList(securityIdSet.List())

	req := &elasticache.CreateCacheClusterInput{
		CacheClusterID:          aws.String(clusterId),
		CacheNodeType:           aws.String(nodeType),
		NumCacheNodes:           aws.Long(numNodes),
		Engine:                  aws.String(engine),
		EngineVersion:           aws.String(engineVersion),
		Port:                    aws.Long(port),
		CacheSubnetGroupName:    aws.String(subnetGroupName),
		CacheSecurityGroupNames: securityNames,
		SecurityGroupIDs:        securityIds,
		CacheParameterGroupName: aws.String(paramGroupName),
	}

	_, err := conn.CreateCacheCluster(req)
	if err != nil {
		return fmt.Errorf("Error creating Elasticache: %s", err)
	}

	pending := []string{"creating"}
	stateConf := &resource.StateChangeConf{
		Pending:    pending,
		Target:     "available",
		Refresh:    CacheClusterStateRefreshFunc(conn, d.Id(), "available", pending),
		Timeout:    10 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	log.Printf("[DEBUG] Waiting for state to become available: %v", d.Id())
	_, sterr := stateConf.WaitForState()
	if sterr != nil {
		return fmt.Errorf("Error waiting for elasticache (%s) to be created: %s", d.Id(), sterr)
	}

	d.SetId(clusterId)

	return nil
}

func resourceAwsElasticacheClusterRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).elasticacheconn
	req := &elasticache.DescribeCacheClustersInput{
		CacheClusterID: aws.String(d.Id()),
	}

	res, err := conn.DescribeCacheClusters(req)
	if err != nil {
		return err
	}

	if len(res.CacheClusters) == 1 {
		c := res.CacheClusters[0]
		d.Set("cluster_id", c.CacheClusterID)
		d.Set("node_type", c.CacheNodeType)
		d.Set("num_cache_nodes", c.NumCacheNodes)
		d.Set("engine", c.Engine)
		d.Set("engine_version", c.EngineVersion)
		if c.ConfigurationEndpoint != nil {
			d.Set("port", c.ConfigurationEndpoint.Port)
		}
		d.Set("subnet_group_name", c.CacheSubnetGroupName)
		d.Set("security_group_names", c.CacheSecurityGroups)
		d.Set("security_group_ids", c.SecurityGroups)
		d.Set("parameter_group_name", c.CacheParameterGroup)
	}

	return nil
}

func resourceAwsElasticacheClusterDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).elasticacheconn

	req := &elasticache.DeleteCacheClusterInput{
		CacheClusterID: aws.String(d.Id()),
	}
	_, err := conn.DeleteCacheCluster(req)
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Waiting for deletion: %v", d.Id())
	stateConf := &resource.StateChangeConf{
		Pending:    []string{"creating", "available", "deleting", "incompatible-parameters", "incompatible-network", "restore-failed"},
		Target:     "",
		Refresh:    CacheClusterStateRefreshFunc(conn, d.Id(), "", []string{}),
		Timeout:    10 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	_, sterr := stateConf.WaitForState()
	if sterr != nil {
		return fmt.Errorf("Error waiting for elasticache (%s) to delete: %s", d.Id(), sterr)
	}

	d.SetId("")

	return nil
}

func CacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, givenState string, pending []string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		resp, err := conn.DescribeCacheClusters(&elasticache.DescribeCacheClustersInput{
			CacheClusterID: aws.String(clusterID),
		})
		if err != nil {
			apierr := err.(aws.APIError)
			log.Printf("[DEBUG] message: %v, code: %v", apierr.Message, apierr.Code)
			if apierr.Message == fmt.Sprintf("CacheCluster not found: %v", clusterID) {
				log.Printf("[DEBUG] Detect deletion")
				return nil, "", nil
			}

			log.Printf("[ERROR] CacheClusterStateRefreshFunc: %s", err)
			return nil, "", err
		}

		c := resp.CacheClusters[0]
		log.Printf("[DEBUG] status: %v", *c.CacheClusterStatus)

		// return the current state if it's in the pending array
		for _, p := range pending {
			s := *c.CacheClusterStatus
			if p == s {
				log.Printf("[DEBUG] Return with status: %v", *c.CacheClusterStatus)
				return c, p, nil
			}
		}

		// return given state if it's not in pending
		if givenState != "" {
			return c, givenState, nil
		}
		log.Printf("[DEBUG] current status: %v", *c.CacheClusterStatus)
		return c, *c.CacheClusterStatus, nil
	}
}
<commit_msg>provider/aws: elasticache_cluster engine_version is computed<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/elasticache"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsElasticacheCluster() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsElasticacheClusterCreate,
		Read:   resourceAwsElasticacheClusterRead,
		Delete: resourceAwsElasticacheClusterDelete,

		Schema: map[string]*schema.Schema{
			"cluster_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"engine": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"node_type": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"num_cache_nodes": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},
			"parameter_group_name": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"port": &schema.Schema{
				Type:     schema.TypeInt,
				Default:  11211,
				Optional: true,
				ForceNew: true,
			},
			"engine_version": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"subnet_group_name": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"security_group_names": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				Computed: true,
				ForceNew: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},
			"security_group_ids": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				Computed: true,
				ForceNew: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},
		},
	}
}

func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).elasticacheconn

	clusterId := d.Get("cluster_id").(string)
	nodeType := d.Get("node_type").(string)           // e.g) cache.m1.small
	numNodes := int64(d.Get("num_cache_nodes").(int)) // 2
	engine := d.Get("engine").(string)                // memcached
	engineVersion := d.Get("engine_version").(string) // 1.4.14
	port := int64(d.Get("port").(int))                // 11211
	subnetGroupName := d.Get("subnet_group_name").(string)
	securityNameSet := d.Get("security_group_names").(*schema.Set)
	securityIdSet := d.Get("security_group_ids").(*schema.Set)
	paramGroupName := d.Get("parameter_group_name").(string) // default.memcached1.4

	securityNames := expandStringList(securityNameSet.List())
	securityIds := expandStringList(securityIdSet.List())

	req := &elasticache.CreateCacheClusterInput{
		CacheClusterID:          aws.String(clusterId),
		CacheNodeType:           aws.String(nodeType),
		NumCacheNodes:           aws.Long(numNodes),
		Engine:                  aws.String(engine),
		EngineVersion:           aws.String(engineVersion),
		Port:                    aws.Long(port),
		CacheSubnetGroupName:    aws.String(subnetGroupName),
		CacheSecurityGroupNames: securityNames,
		SecurityGroupIDs:        securityIds,
		CacheParameterGroupName: aws.String(paramGroupName),
	}

	_, err := conn.CreateCacheCluster(req)
	if err != nil {
		return fmt.Errorf("Error creating Elasticache: %s", err)
	}

	pending := []string{"creating"}
	stateConf := &resource.StateChangeConf{
		Pending:    pending,
		Target:     "available",
		Refresh:    CacheClusterStateRefreshFunc(conn, d.Id(), "available", pending),
		Timeout:    10 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	log.Printf("[DEBUG] Waiting for state to become available: %v", d.Id())
	_, sterr := stateConf.WaitForState()
	if sterr != nil {
		return fmt.Errorf("Error waiting for elasticache (%s) to be created: %s", d.Id(), sterr)
	}

	d.SetId(clusterId)

	return nil
}

func resourceAwsElasticacheClusterRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).elasticacheconn
	req := &elasticache.DescribeCacheClustersInput{
		CacheClusterID: aws.String(d.Id()),
	}

	res, err := conn.DescribeCacheClusters(req)
	if err != nil {
		return err
	}

	if len(res.CacheClusters) == 1 {
		c := res.CacheClusters[0]
		d.Set("cluster_id", c.CacheClusterID)
		d.Set("node_type", c.CacheNodeType)
		d.Set("num_cache_nodes", c.NumCacheNodes)
		d.Set("engine", c.Engine)
		d.Set("engine_version", c.EngineVersion)
		if c.ConfigurationEndpoint != nil {
			d.Set("port", c.ConfigurationEndpoint.Port)
		}
		d.Set("subnet_group_name", c.CacheSubnetGroupName)
		d.Set("security_group_names", c.CacheSecurityGroups)
		d.Set("security_group_ids", c.SecurityGroups)
		d.Set("parameter_group_name", c.CacheParameterGroup)
	}

	return nil
}

func resourceAwsElasticacheClusterDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).elasticacheconn

	req := &elasticache.DeleteCacheClusterInput{
		CacheClusterID: aws.String(d.Id()),
	}
	_, err := conn.DeleteCacheCluster(req)
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Waiting for deletion: %v", d.Id())
	stateConf := &resource.StateChangeConf{
		Pending:    []string{"creating", "available", "deleting", "incompatible-parameters", "incompatible-network", "restore-failed"},
		Target:     "",
		Refresh:    CacheClusterStateRefreshFunc(conn, d.Id(), "", []string{}),
		Timeout:    10 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	_, sterr := stateConf.WaitForState()
	if sterr != nil {
		return fmt.Errorf("Error waiting for elasticache (%s) to delete: %s", d.Id(), sterr)
	}

	d.SetId("")

	return nil
}

func CacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, givenState string, pending []string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		resp, err := conn.DescribeCacheClusters(&elasticache.DescribeCacheClustersInput{
			CacheClusterID: aws.String(clusterID),
		})
		if err != nil {
			apierr := err.(aws.APIError)
			log.Printf("[DEBUG] message: %v, code: %v", apierr.Message, apierr.Code)
			if apierr.Message == fmt.Sprintf("CacheCluster not found: %v", clusterID) {
				log.Printf("[DEBUG] Detect deletion")
				return nil, "", nil
			}

			log.Printf("[ERROR] CacheClusterStateRefreshFunc: %s", err)
			return nil, "", err
		}

		c := resp.CacheClusters[0]
		log.Printf("[DEBUG] status: %v", *c.CacheClusterStatus)

		// return the current state if it's in the pending array
		for _, p := range pending {
			s := *c.CacheClusterStatus
			if p == s {
				log.Printf("[DEBUG] Return with status: %v", *c.CacheClusterStatus)
				return c, p, nil
			}
		}

		// return given state if it's not in pending
		if givenState != "" {
			return c, givenState, nil
		}
		log.Printf("[DEBUG] current status: %v", *c.CacheClusterStatus)
		return c, *c.CacheClusterStatus, nil
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/ec2"
)

func TestAccAwsSecurityGroup(t *testing.T) {
	testAccPreCheck(t)

	resource.Test(t, resource.TestCase{
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSSecurityGroupConfig,
				Check:  testAccCheckAWSSecurityGroupExists("aws_security_group.web"),
			},
		},
	})
}

func testAccCheckAWSSecurityGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.ec2conn

	for _, rs := range s.Resources {
		if rs.Type != "aws_security_group" {
			continue
		}

		sgs := []ec2.SecurityGroup{
			ec2.SecurityGroup{
				Id: rs.ID,
			},
		}

		// Retrieve our group
		resp, err := conn.SecurityGroups(sgs, nil)
		if err == nil {
			if len(resp.Groups) > 0 && resp.Groups[0].Id == rs.ID {
				return fmt.Errorf("Security Group (%s) still exists.", rs.ID)
			}

			return nil
		}

		ec2err, ok := err.(*ec2.Error)
		if !ok {
			return err
		}
		// Confirm error code is what we want
		if ec2err.Code != "InvalidGroup.NotFound" {
			return err
		}
	}

	return nil
}

func testAccCheckAWSSecurityGroupExists(n string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.ID == "" {
			return fmt.Errorf("No Security Group is set")
		}

		conn := testAccProvider.ec2conn
		sgs := []ec2.SecurityGroup{
			ec2.SecurityGroup{
				Id: rs.ID,
			},
		}
		resp, err := conn.SecurityGroups(sgs, nil)
		if err != nil {
			return err
		}

		if len(resp.Groups) > 0 && resp.Groups[0].Id == rs.ID {
			return nil
		} else {
			return fmt.Errorf("Security Group not found")
		}

		return nil
	}
}

const testAccAWSSecurityGroupConfig = `
resource "aws_security_group" "web" {
    name = "terraform_acceptance_test_example"
    description = "Used in the terraform acceptance tests"
}
`
<commit_msg>providers/aws: use precheck for security group<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/ec2"
)

func TestAccAwsSecurityGroup(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSSecurityGroupConfig,
				Check:  testAccCheckAWSSecurityGroupExists("aws_security_group.web"),
			},
		},
	})
}

func testAccCheckAWSSecurityGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.ec2conn

	for _, rs := range s.Resources {
		if rs.Type != "aws_security_group" {
			continue
		}

		sgs := []ec2.SecurityGroup{
			ec2.SecurityGroup{
				Id: rs.ID,
			},
		}

		// Retrieve our group
		resp, err := conn.SecurityGroups(sgs, nil)
		if err == nil {
			if len(resp.Groups) > 0 && resp.Groups[0].Id == rs.ID {
				return fmt.Errorf("Security Group (%s) still exists.", rs.ID)
			}

			return nil
		}

		ec2err, ok := err.(*ec2.Error)
		if !ok {
			return err
		}
		// Confirm error code is what we want
		if ec2err.Code != "InvalidGroup.NotFound" {
			return err
		}
	}

	return nil
}

func testAccCheckAWSSecurityGroupExists(n string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.ID == "" {
			return fmt.Errorf("No Security Group is set")
		}

		conn := testAccProvider.ec2conn
		sgs := []ec2.SecurityGroup{
			ec2.SecurityGroup{
				Id: rs.ID,
			},
		}
		resp, err := conn.SecurityGroups(sgs, nil)
		if err != nil {
			return err
		}

		if len(resp.Groups) > 0 && resp.Groups[0].Id == rs.ID {
			return nil
		} else {
			return fmt.Errorf("Security Group not found")
		}

		return nil
	}
}

const testAccAWSSecurityGroupConfig = `
resource "aws_security_group" "web" {
    name = "terraform_acceptance_test_example"
    description = "Used in the terraform acceptance tests"
}
`
<|endoftext|>


<commit_before>package mym

import (
	"math"
)

// Vneg3 -- returns -u.
func Vneg3(u [3]float64) [3]float64 {
	return [3]float64{-u[0], -u[1], -u[2]}
}

// Vadd3 -- returns u+v.
func Vadd3(u, v [3]float64) [3]float64 {
	return [3]float64{u[0] + v[0], u[1] + v[1], u[2] + v[2]}
}

// Vsub3 -- returns u-v.
func Vsub3(u, v [3]float64) [3]float64 {
	return [3]float64{u[0] - v[0], u[1] - v[1], u[2] - v[2]}
}

// Vmul3 -- returns s·u.
func Vmul3(u [3]float64, s float64) [3]float64 {
	return [3]float64{s * u[0], s * u[1], s * u[2]}
}

// Vdiv3 -- returns u/s.
func Vdiv3(u [3]float64, s float64) [3]float64 {
	return [3]float64{u[0] / s, u[1] / s, u[2] / s}
}

// Vdot3 -- returns u·v (scalar, or dot product).
func Vdot3(u, v [3]float64) float64 {
	return u[0]*v[0] + u[1]*v[1] + u[2]*v[2]
}

// Vcrs3 -- returns u⨯v (vector, or cross product).
func Vcrs3(u, v [3]float64) [3]float64 {
	x := u[1]*v[2] - u[2]*v[1]
	y := u[2]*v[0] - u[0]*v[2]
	z := u[0]*v[1] - u[1]*v[0]
	return [3]float64{x, y, z}
}

// Vabs3 -- returns |u| (L2 norm).
func Vabs3(u [3]float64) float64 {
	return math.Hypot(math.Hypot(u[0], u[1]), u[2])
}

// Vhat3 -- returns u/|u|. Returns a zero vector when |u|<ε.
func Vhat3(u [3]float64) [3]float64 {
	s := math.Hypot(math.Hypot(u[0], u[1]), u[2])
	if s >= Epsilon {
		return [3]float64{u[0] / s, u[1] / s, u[2] / s}
	}
	return [3]float64{0, 0, 0}
}
<commit_msg>Implement the function `Vmean3`.<commit_after>package mym

import (
	"math"
)

// Vneg3 -- returns -u.
func Vneg3(u [3]float64) [3]float64 {
	return [3]float64{-u[0], -u[1], -u[2]}
}

// Vadd3 -- returns u+v.
func Vadd3(u, v [3]float64) [3]float64 {
	return [3]float64{u[0] + v[0], u[1] + v[1], u[2] + v[2]}
}

// Vsub3 -- returns u-v.
func Vsub3(u, v [3]float64) [3]float64 {
	return [3]float64{u[0] - v[0], u[1] - v[1], u[2] - v[2]}
}

// Vmul3 -- returns s·u.
func Vmul3(u [3]float64, s float64) [3]float64 {
	return [3]float64{s * u[0], s * u[1], s * u[2]}
}

// Vdiv3 -- returns u/s.
func Vdiv3(u [3]float64, s float64) [3]float64 {
	return [3]float64{u[0] / s, u[1] / s, u[2] / s}
}

// Vdot3 -- returns u·v (scalar, or dot product).
func Vdot3(u, v [3]float64) float64 {
	return u[0]*v[0] + u[1]*v[1] + u[2]*v[2]
}

// Vcrs3 -- returns u⨯v (vector, or cross product).
func Vcrs3(u, v [3]float64) [3]float64 {
	x := u[1]*v[2] - u[2]*v[1]
	y := u[2]*v[0] - u[0]*v[2]
	z := u[0]*v[1] - u[1]*v[0]
	return [3]float64{x, y, z}
}

// Vabs3 -- returns |u| (L2 norm).
func Vabs3(u [3]float64) float64 {
	return math.Hypot(math.Hypot(u[0], u[1]), u[2])
}

// Vhat3 -- returns u/|u|. Returns a zero vector when |u|<ε.
func Vhat3(u [3]float64) [3]float64 {
	s := math.Hypot(math.Hypot(u[0], u[1]), u[2])
	if s >= Epsilon {
		return [3]float64{u[0] / s, u[1] / s, u[2] / s}
	}
	return [3]float64{0, 0, 0}
}

// Vmean3 -- returns the mean vector of u[0],u[1],...,u[len(u)-1].
func Vmean3(u [][3]float64) [3]float64 {
	n := len(u)
	if n == 0 {
		return [3]float64{0, 0, 0}
	}
	xs := AccuSum(n, func(i int) float64 { return u[i][0] })
	ys := AccuSum(n, func(i int) float64 { return u[i][1] })
	zs := AccuSum(n, func(i int) float64 { return u[i][2] })
	return [3]float64{xs / float64(n), ys / float64(n), zs / float64(n)}
}
<|endoftext|>


<commit_before>package peco

import (
	"fmt"
	"time"
	"unicode/utf8"

	"github.com/mattn/go-runewidth"
	"github.com/nsf/termbox-go"
)

// View handles the drawing/updating the screen
type View struct {
	*Ctx
	clearTimer *time.Timer
}

// PagingRequest can be sent to move the selection cursor
type PagingRequest int

const (
	// ToNextLine moves the selection to the next line
	ToNextLine PagingRequest = iota
	// ToNextPage moves the selection to the next page
	ToNextPage
	// ToPrevLine moves the selection to the previous line
	ToPrevLine
	// ToPrevPage moves the selection to the previous page
	ToPrevPage
)

// Loop receives requests to update the screen
func (v *View) Loop() {
	defer v.ReleaseWaitGroup()
	for {
		select {
		case <-v.LoopCh():
			return
		case m := <-v.StatusMsgCh():
			v.printStatus(m.DataString())
			m.Done()
		case m := <-v.ClearStatusCh():
			v.clearStatus(m.DataInterface().(time.Duration))
			m.Done()
		case r := <-v.PagingCh():
			v.movePage(r.DataInterface().(PagingRequest))
			r.Done()
		case lines := <-v.DrawCh():
			v.drawScreen(lines.DataInterface().([]Match))
			lines.Done()
		}
	}
}

func (v *View) clearStatus(d time.Duration) {
	if t := v.clearTimer; t != nil {
		t.Stop()
	}

	v.clearTimer = time.AfterFunc(d, func() {
		v.printStatus("")
	})
}

func (v *View) printStatus(msg string) {
	if t := v.clearTimer; t != nil {
		t.Stop()
	}

	w, h := termbox.Size()

	width := runewidth.StringWidth(msg)
	for width > w {
		_, rw := utf8.DecodeRuneInString(msg)
		width = width - rw
		msg = msg[rw:]
	}

	var pad []byte
	if w > width {
		pad = make([]byte, w-width)
		for i := 0; i < w-width; i++ {
			pad[i] = ' '
		}
	}

	fgAttr := v.config.Style.Basic.fg
	bgAttr := v.config.Style.Basic.bg

	if w > width {
		printTB(0, h-2, fgAttr, bgAttr, string(pad))
	}

	if width > 0 {
		printTB(w-width, h-2, fgAttr|termbox.AttrReverse|termbox.AttrBold, bgAttr|termbox.AttrReverse, msg)
	}
	termbox.Flush()
}

func printTB(x, y int, fg, bg termbox.Attribute, msg string) {
	for len(msg) > 0 {
		c, w := utf8.DecodeRuneInString(msg)
		if c == utf8.RuneError {
			c = '?'
			w = 1
		}
		msg = msg[w:]
		termbox.SetCell(x, y, c, fg, bg)
		x += runewidth.RuneWidth(c)
	}

	width, _ := termbox.Size()
	for ; x < width; x++ {
		termbox.SetCell(x, y, ' ', fg, bg)
	}
}

func (v *View) movePage(p PagingRequest) {
	_, height := termbox.Size()
	perPage := height - 4

	switch p {
	case ToPrevLine:
		v.currentLine--
	case ToNextLine:
		v.currentLine++
	case ToPrevPage, ToNextPage:
		if p == ToPrevPage {
			v.currentLine -= perPage
		} else {
			v.currentLine += perPage
		}
	}

	if v.currentLine < 1 {
		if v.current != nil {
			// Go to last page, if possible
			v.currentLine = len(v.current)
		} else {
			v.currentLine = 1
		}
	} else if v.current != nil && v.currentLine > len(v.current) {
		v.currentLine = 1
	}
	v.drawScreen(nil)
}

func (v *View) drawScreen(targets []Match) {
	v.mutex.Lock()
	defer v.mutex.Unlock()

	fgAttr := v.config.Style.Basic.fg
	bgAttr := v.config.Style.Basic.bg

	if err := termbox.Clear(fgAttr, bgAttr); err != nil {
		return
	}

	if targets == nil {
		if current := v.Ctx.current; current != nil {
			targets = v.Ctx.current
		} else {
			targets = v.Ctx.lines
		}
	}
	if v.Ctx.currentLine > len(targets) && len(targets) > 0 {
		v.Ctx.currentLine = len(targets)
	}

	width, height := termbox.Size()
	perPage := height - 4

CALCULATE_PAGE:
	currentPage := &v.Ctx.currentPage
	currentPage.index = ((v.Ctx.currentLine - 1) / perPage) + 1
	if currentPage.index <= 0 {
		currentPage.index = 1
	}
	currentPage.offset = (currentPage.index - 1) * perPage
	currentPage.perPage = perPage
	var maxPage int
	if len(targets) == 0 {
		maxPage = 1
	} else {
		maxPage = ((len(targets) + perPage - 1) / perPage)
	}

	if maxPage < currentPage.index {
		if len(targets) == 0 && len(v.Ctx.query) == 0 {
			// wait for targets
			return
		}
		v.Ctx.currentLine = currentPage.offset
		goto CALCULATE_PAGE
	}

	fgAttr = v.config.Style.Query.fg
	bgAttr = v.config.Style.Query.bg

	var prompt string
	if len(v.Ctx.prompt) > 0 {
		prompt = string(v.Ctx.prompt)
	} else {
		prompt = v.config.Prompt
	}
	promptLen := runewidth.StringWidth(prompt)
	printTB(0, 0, fgAttr, bgAttr, prompt)

	if v.caretPos <= 0 {
		v.caretPos = 0 // sanity
	}
	if v.caretPos > len(v.query) {
		v.caretPos = len(v.query)
	}

	if v.caretPos == len(v.query) {
		// the entire string + the caret after the string
		printTB(promptLen+1, 0, fgAttr, bgAttr, string(v.query))
		termbox.SetCell(promptLen+1+runewidth.StringWidth(string(v.query)), 0, ' ', fgAttr|termbox.AttrReverse, bgAttr|termbox.AttrReverse)
	} else {
		// the caret is in the middle of the string
		prev := 0
		for i, r := range v.query {
			fg := v.config.Style.Query.fg
			bg := v.config.Style.Query.bg
			if i == v.caretPos {
				fg |= termbox.AttrReverse
				bg |= termbox.AttrReverse
			}
			termbox.SetCell(promptLen+1+prev, 0, r, fg, bg)
			prev += runewidth.RuneWidth(r)
		}
	}

	pmsg := fmt.Sprintf("%s [%d/%d]", v.Ctx.Matcher().String(), currentPage.index, maxPage)

	printTB(width-runewidth.StringWidth(pmsg), 0, fgAttr, bgAttr, pmsg)

	for n := 1; n <= perPage; n++ {
		fgAttr = v.config.Style.Basic.fg
		bgAttr = v.config.Style.Basic.bg
		if n+currentPage.offset == v.currentLine {
			fgAttr = v.config.Style.Selected.fg
			bgAttr = v.config.Style.Selected.bg
		} else if v.selection.Has(n+currentPage.offset) || v.SelectedRange().Has(n+currentPage.offset) {
			fgAttr = v.config.Style.SavedSelection.fg
			bgAttr = v.config.Style.SavedSelection.bg
		}

		targetIdx := currentPage.offset + n - 1
		if targetIdx >= len(targets) {
			break
		}

		target := targets[targetIdx]
		line := target.Line()
		matches := target.Indices()
		if matches == nil {
			printTB(0, n, fgAttr, bgAttr, line)
		} else {
			prev := 0
			index := 0
			for _, m := range matches {
				if m[0] > index {
					c := line[index:m[0]]
					printTB(prev, n, fgAttr, bgAttr, c)
					prev += runewidth.StringWidth(c)
					index += len(c)
				}
				c := line[m[0]:m[1]]
				printTB(prev, n, v.config.Style.Matched.fg, bgAttr|v.config.Style.Matched.bg, c)
				prev += runewidth.StringWidth(c)
				index += len(c)
			}

			m := matches[len(matches)-1]
			if m[0] > index {
				printTB(prev, n, v.config.Style.Query.fg, bgAttr|v.config.Style.Query.bg, line[m[0]:m[1]])
			} else if len(line) > m[1] {
				printTB(prev, n, fgAttr, bgAttr, line[m[1]:len(line)])
			}
		}
	}

	if err := termbox.Flush(); err != nil {
		return
	}

	// FIXME
	v.current = targets
}
<commit_msg>fix bgcolor mixing<commit_after>package peco

import (
	"fmt"
	"time"
	"unicode/utf8"

	"github.com/mattn/go-runewidth"
	"github.com/nsf/termbox-go"
)

// View handles the drawing/updating the screen
type View struct {
	*Ctx
	clearTimer *time.Timer
}

// PagingRequest can be sent to move the selection cursor
type PagingRequest int

const (
	// ToNextLine moves the selection to the next line
	ToNextLine PagingRequest = iota
	// ToNextPage moves the selection to the next page
	ToNextPage
	// ToPrevLine moves the selection to the previous line
	ToPrevLine
	// ToPrevPage moves the selection to the previous page
	ToPrevPage
)

// Loop receives requests to update the screen
func (v *View) Loop() {
	defer v.ReleaseWaitGroup()
	for {
		select {
		case <-v.LoopCh():
			return
		case m := <-v.StatusMsgCh():
			v.printStatus(m.DataString())
			m.Done()
		case m := <-v.ClearStatusCh():
			v.clearStatus(m.DataInterface().(time.Duration))
			m.Done()
		case r := <-v.PagingCh():
			v.movePage(r.DataInterface().(PagingRequest))
			r.Done()
		case lines := <-v.DrawCh():
			v.drawScreen(lines.DataInterface().([]Match))
			lines.Done()
		}
	}
}

func (v *View) clearStatus(d time.Duration) {
	if t := v.clearTimer; t != nil {
		t.Stop()
	}

	v.clearTimer = time.AfterFunc(d, func() {
		v.printStatus("")
	})
}

func (v *View) printStatus(msg string) {
	if t := v.clearTimer; t != nil {
		t.Stop()
	}

	w, h := termbox.Size()

	width := runewidth.StringWidth(msg)
	for width > w {
		_, rw := utf8.DecodeRuneInString(msg)
		width = width - rw
		msg = msg[rw:]
	}

	var pad []byte
	if w > width {
		pad = make([]byte, w-width)
		for i := 0; i < w-width; i++ {
			pad[i] = ' '
		}
	}

	fgAttr := v.config.Style.Basic.fg
	bgAttr := v.config.Style.Basic.bg

	if w > width {
		printTB(0, h-2, fgAttr, bgAttr, string(pad))
	}

	if width > 0 {
		printTB(w-width, h-2, fgAttr|termbox.AttrReverse|termbox.AttrBold, bgAttr|termbox.AttrReverse, msg)
	}
	termbox.Flush()
}

func printTB(x, y int, fg, bg termbox.Attribute, msg string) {
	for len(msg) > 0 {
		c, w := utf8.DecodeRuneInString(msg)
		if c == utf8.RuneError {
			c = '?'
			w = 1
		}
		msg = msg[w:]
		termbox.SetCell(x, y, c, fg, bg)
		x += runewidth.RuneWidth(c)
	}

	width, _ := termbox.Size()
	for ; x < width; x++ {
		termbox.SetCell(x, y, ' ', fg, bg)
	}
}

func (v *View) movePage(p PagingRequest) {
	_, height := termbox.Size()
	perPage := height - 4

	switch p {
	case ToPrevLine:
		v.currentLine--
	case ToNextLine:
		v.currentLine++
	case ToPrevPage, ToNextPage:
		if p == ToPrevPage {
			v.currentLine -= perPage
		} else {
			v.currentLine += perPage
		}
	}

	if v.currentLine < 1 {
		if v.current != nil {
			// Go to last page, if possible
			v.currentLine = len(v.current)
		} else {
			v.currentLine = 1
		}
	} else if v.current != nil && v.currentLine > len(v.current) {
		v.currentLine = 1
	}
	v.drawScreen(nil)
}

func (v *View) drawScreen(targets []Match) {
	v.mutex.Lock()
	defer v.mutex.Unlock()

	fgAttr := v.config.Style.Basic.fg
	bgAttr := v.config.Style.Basic.bg

	if err := termbox.Clear(fgAttr, bgAttr); err != nil {
		return
	}

	if targets == nil {
		if current := v.Ctx.current; current != nil {
			targets = v.Ctx.current
		} else {
			targets = v.Ctx.lines
		}
	}
	if v.Ctx.currentLine > len(targets) && len(targets) > 0 {
		v.Ctx.currentLine = len(targets)
	}

	width, height := termbox.Size()
	perPage := height - 4

CALCULATE_PAGE:
	currentPage := &v.Ctx.currentPage
	currentPage.index = ((v.Ctx.currentLine - 1) / perPage) + 1
	if currentPage.index <= 0 {
		currentPage.index = 1
	}
	currentPage.offset = (currentPage.index - 1) * perPage
	currentPage.perPage = perPage
	var maxPage int
	if len(targets) == 0 {
		maxPage = 1
	} else {
		maxPage = ((len(targets) + perPage - 1) / perPage)
	}

	if maxPage < currentPage.index {
		if len(targets) == 0 && len(v.Ctx.query) == 0 {
			// wait for targets
			return
		}
		v.Ctx.currentLine = currentPage.offset
		goto CALCULATE_PAGE
	}

	fgAttr = v.config.Style.Query.fg
	bgAttr = v.config.Style.Query.bg

	var prompt string
	if len(v.Ctx.prompt) > 0 {
		prompt = string(v.Ctx.prompt)
	} else {
		prompt = v.config.Prompt
	}
	promptLen := runewidth.StringWidth(prompt)
	printTB(0, 0, fgAttr, bgAttr, prompt)

	if v.caretPos <= 0 {
		v.caretPos = 0 // sanity
	}
	if v.caretPos > len(v.query) {
		v.caretPos = len(v.query)
	}

	if v.caretPos == len(v.query) {
		// the entire string + the caret after the string
		printTB(promptLen+1, 0, fgAttr, bgAttr, string(v.query))
		termbox.SetCell(promptLen+1+runewidth.StringWidth(string(v.query)), 0, ' ', fgAttr|termbox.AttrReverse, bgAttr|termbox.AttrReverse)
	} else {
		// the caret is in the middle of the string
		prev := 0
		for i, r := range v.query {
			fg := v.config.Style.Query.fg
			bg := v.config.Style.Query.bg
			if i == v.caretPos {
				fg |= termbox.AttrReverse
				bg |= termbox.AttrReverse
			}
			termbox.SetCell(promptLen+1+prev, 0, r, fg, bg)
			prev += runewidth.RuneWidth(r)
		}
	}

	pmsg := fmt.Sprintf("%s [%d/%d]", v.Ctx.Matcher().String(), currentPage.index, maxPage)

	printTB(width-runewidth.StringWidth(pmsg), 0, fgAttr, bgAttr, pmsg)

	for n := 1; n <= perPage; n++ {
		fgAttr = v.config.Style.Basic.fg
		bgAttr = v.config.Style.Basic.bg
		if n+currentPage.offset == v.currentLine {
			fgAttr = v.config.Style.Selected.fg
			bgAttr = v.config.Style.Selected.bg
		} else if v.selection.Has(n+currentPage.offset) || v.SelectedRange().Has(n+currentPage.offset) {
			fgAttr = v.config.Style.SavedSelection.fg
			bgAttr = v.config.Style.SavedSelection.bg
		}

		targetIdx := currentPage.offset + n - 1
		if targetIdx >= len(targets) {
			break
		}

		target := targets[targetIdx]
		line := target.Line()
		matches := target.Indices()
		if matches == nil {
			printTB(0, n, fgAttr, bgAttr, line)
		} else {
			prev := 0
			index := 0
			for _, m := range matches {
				if m[0] > index {
					c := line[index:m[0]]
					printTB(prev, n, fgAttr, bgAttr, c)
					prev += runewidth.StringWidth(c)
					index += len(c)
				}
				c := line[m[0]:m[1]]
				printTB(prev, n, v.config.Style.Matched.fg, mergeAttribute(bgAttr, v.config.Style.Matched.bg), c)
				prev += runewidth.StringWidth(c)
				index += len(c)
			}

			m := matches[len(matches)-1]
			if m[0] > index {
				printTB(prev, n, v.config.Style.Query.fg, mergeAttribute(bgAttr, v.config.Style.Query.bg), line[m[0]:m[1]])
			} else if len(line) > m[1] {
				printTB(prev, n, fgAttr, bgAttr, line[m[1]:len(line)])
			}
		}
	}

	if err := termbox.Flush(); err != nil {
		return
	}

	// FIXME
	v.current = targets
}

func mergeAttribute(a, b termbox.Attribute) termbox.Attribute {
	if a&0x0F == 0 || b&0x0F == 0 {
		return a | b
	} else {
		return ((a - 1) | (b - 1)) + 1
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"
)

type Numverify struct {
	Valid               bool   `json:"valid"`
	Number              string `json:"number"`
	LocalFormat         string `json:"local_format"`
	InternationalFormat string `json:"international_format"`
	CountryCode         string `json:"country_code"`
	CountryName         string `json:"country_name"`
	Location            string `json:"location"`
	Carrier             string `json:"carrier"`
	LineType            string `json:"line_type"`
}

func main() {
  fmt.Printf("Hello, Word!")
}
<commit_msg>add main func<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"
)

type Numverify struct {
	Valid               bool   `json:"valid"`
	Number              string `json:"number"`
	LocalFormat         string `json:"local_format"`
	InternationalFormat string `json:"international_format"`
	CountryCode         string `json:"country_code"`
	CountryName         string `json:"country_name"`
	Location            string `json:"location"`
	Carrier             string `json:"carrier"`
	LineType            string `json:"line_type"`
}

func main() {
	phone := "14158586273"
	// QueryEscape escapes the phone string so
	// it can be safely placed inside a URL query
	safePhone := url.QueryEscape(phone)

	url := fmt.Sprintf("http://apilayer.net/api/validate?access_key=YOUR_ACCESS_KEY&number=%s", safePhone)

	// Build the request
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Fatal("NewRequest: ", err)
		return
	}

	// For control over HTTP client headers,
	// redirect policy, and other settings,
	// create a Client
	// A Client is an HTTP client
	client := &http.Client{}

	// Send the request via a client
	// Do sends an HTTP request and
	// returns an HTTP response
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal("Do: ", err)
		return
	}

	// Callers should close resp.Body
	// when done reading from it
	// Defer the closing of the body
	defer resp.Body.Close()

	// Fill the record with the data from the JSON
	var record Numverify

	// Use json.Decode for reading streams of JSON data
	if err := json.NewDecoder(resp.Body).Decode(&record); err != nil {
		log.Println(err)
	}

	fmt.Println("Phone No. = ", record.InternationalFormat)
	fmt.Println("Country   = ", record.CountryName)
	fmt.Println("Location  = ", record.Location)
	fmt.Println("Carrier   = ", record.Carrier)
	fmt.Println("LineType  = ", record.LineType)

}
<|endoftext|>