<commit_before>package objconv

import "reflect"

// Array is an interface representing iterable sequences of values.
type Array interface {
	// Len returns the number of elements in the array.
	Len() int

	// Iter returns an iterator pointing to the first element of the array.
	Iter() ArrayIter
}

// ArrayIter is an interface allowing the application to iterate over the
// elements of an array.
type ArrayIter interface {
	// Next returns the current value, and advances the iterator. The boolean
	// will be false if there was no more values to return.
	Next() (interface{}, bool)
}

// ArrayFunc is a type alias for a function that implements the Array interface.
//
// The Array has an unknown length and only one iterator which produces values
// returned by successive calls to the function.
type ArrayFunc func() (interface{}, bool)

// Len returns -1 because the array length is unknown.
func (f ArrayFunc) Len() int { return -1 }

// Iter returns the ArrayFunc itself which is its own iterator.
func (f ArrayFunc) Iter() ArrayIter { return f }

// Next calls the function, effectively advancing the iterator to the next
// element.
func (f ArrayFunc) Next() (interface{}, bool) { return f() }

// ArraySlice is a type alias for a reflect.Value of type slice or array that
// implements the Array interface.
type ArraySlice reflect.Value

// Len returns the number of elements in the array.
func (a ArraySlice) Len() int { return reflect.Value(a).Len() }

// Iter returns an iterator pointing to the first element of the array.
func (a ArraySlice) Iter() ArrayIter {
	return &arraySliceIter{
		v: reflect.Value(a),
		n: a.Len(),
	}
}

type arraySliceIter struct {
	v reflect.Value
	n int
	i int
}

func (it *arraySliceIter) Next() (v interface{}, ok bool) {
	if ok = it.i < it.n; ok {
		v = it.v.Index(it.i).Interface()
		it.i++
	}
	return
}

// ArrayValue is a type alias for a reflect.Value of any type. The type
// implements the Array interface and represents an array returning a
// single value.
type ArrayValue reflect.Value

// Len returns the number of elements in the array, which is 1.
func (a ArrayValue) Len() int { return 1 }

// Iter returns an iterator pointing to the first element of the array.
func (a ArrayValue) Iter() ArrayIter {
	return &arrayValueIter{
		v:  reflect.Value(a),
		ok: true,
	}
}

type arrayValueIter struct {
	v  reflect.Value
	ok bool
}

func (it *arrayValueIter) Next() (v interface{}, ok bool) {
	if ok, it.ok = it.ok, false; ok {
		v = it.v.Interface()
	}
	return
}

// ArrayLen returns an Array value that wraps around the array a, but sets the
// length to n.
func ArrayLen(n int, a Array) Array { return arrayLen{a, n} }

type arrayLen struct {
	Array
	n int
}

func (a arrayLen) Len() int { return a.n }

// NewArray returns an Array that exposes the values of v.
func NewArray(v interface{}) Array {
	switch a := v.(type) {
	case Array:
		return a

	case func() (interface{}, bool):
		return ArrayFunc(a)
	}

	switch a := reflect.ValueOf(v); a.Kind() {
	case reflect.Slice, reflect.Array:
		return ArraySlice(a)

	default:
		return ArrayValue(a)
	}
}

// NewArraySlice returns an ArraySlice that wraps v, assuming v is a slice or an
// array.
func NewArraySlice(v interface{}) ArraySlice {
	if a, ok := v.(ArraySlice); ok {
		return a
	}
	return ArraySlice(reflect.ValueOf(v))
}

// NewArrayValue returns an ArrayValue that wraps v.
func NewArrayValue(v interface{}) ArrayValue {
	if a, ok := v.(ArrayValue); ok {
		return a
	}
	return ArrayValue(reflect.ValueOf(v))
}
<commit_msg>add objconv.MultiArray<commit_after>package objconv

import "reflect"

// Array is an interface representing iterable sequences of values.
type Array interface {
	// Len returns the number of elements in the array.
	Len() int

	// Iter returns an iterator pointing to the first element of the array.
	Iter() ArrayIter
}

// ArrayIter is an interface allowing the application to iterate over the
// elements of an array.
type ArrayIter interface {
	// Next returns the current value, and advances the iterator. The boolean
	// will be false if there was no more values to return.
	Next() (interface{}, bool)
}

// ArrayFunc is a type alias for a function that implements the Array interface.
//
// The Array has an unknown length and only one iterator which produces values
// returned by successive calls to the function.
type ArrayFunc func() (interface{}, bool)

// Len returns -1 because the array length is unknown.
func (f ArrayFunc) Len() int { return -1 }

// Iter returns the ArrayFunc itself which is its own iterator.
func (f ArrayFunc) Iter() ArrayIter { return f }

// Next calls the function, effectively advancing the iterator to the next
// element.
func (f ArrayFunc) Next() (interface{}, bool) { return f() }

// ArraySlice is a type alias for a reflect.Value of type slice or array that
// implements the Array interface.
type ArraySlice reflect.Value

// Len returns the number of elements in the array.
func (a ArraySlice) Len() int { return reflect.Value(a).Len() }

// Iter returns an iterator pointing to the first element of the array.
func (a ArraySlice) Iter() ArrayIter {
	return &arraySliceIter{
		v: reflect.Value(a),
		n: a.Len(),
	}
}

// NewArraySlice returns an ArraySlice that wraps v, assuming v is a slice or an
// array.
func NewArraySlice(v interface{}) ArraySlice {
	if a, ok := v.(ArraySlice); ok {
		return a
	}
	return ArraySlice(reflect.ValueOf(v))
}

type arraySliceIter struct {
	v reflect.Value
	n int
	i int
}

func (it *arraySliceIter) Next() (v interface{}, ok bool) {
	if ok = it.i < it.n; ok {
		v = it.v.Index(it.i).Interface()
		it.i++
	}
	return
}

// ArrayValue is a type alias for a reflect.Value of any type. The type
// implements the Array interface and represents an array returning a
// single value.
type ArrayValue reflect.Value

// Len returns the number of elements in the array, which is 1.
func (a ArrayValue) Len() int { return 1 }

// Iter returns an iterator pointing to the first element of the array.
func (a ArrayValue) Iter() ArrayIter {
	return &arrayValueIter{
		v:  reflect.Value(a),
		ok: true,
	}
}

// NewArrayValue returns an ArrayValue that wraps v.
func NewArrayValue(v interface{}) ArrayValue {
	if a, ok := v.(ArrayValue); ok {
		return a
	}
	return ArrayValue(reflect.ValueOf(v))
}

type arrayValueIter struct {
	v  reflect.Value
	ok bool
}

func (it *arrayValueIter) Next() (v interface{}, ok bool) {
	if ok, it.ok = it.ok, false; ok {
		v = it.v.Interface()
	}
	return
}

// ArrayLen returns an Array value that wraps around the array a, but sets the
// length to n.
func ArrayLen(n int, a Array) Array { return arrayLen{a, n} }

type arrayLen struct {
	Array
	n int
}

func (a arrayLen) Len() int { return a.n }

// NewArray returns an Array that exposes the values of v.
func NewArray(v interface{}) Array {
	switch a := v.(type) {
	case Array:
		return a

	case func() (interface{}, bool):
		return ArrayFunc(a)
	}

	switch a := reflect.ValueOf(v); a.Kind() {
	case reflect.Slice, reflect.Array:
		return ArraySlice(a)

	default:
		return ArrayValue(a)
	}
}

// MultiArray combines multiple arrays into one.
func MultiArray(a ...Array) Array { return multiArray(a) }

type multiArray []Array

func (m multiArray) Len() (n int) {
	for _, a := range m {
		n += a.Len()
	}
	return
}

func (m multiArray) Iter() ArrayIter {
	it := make([]ArrayIter, len(m))
	for i, a := range m {
		it[i] = a.Iter()
	}
	return &multiArrayIter{it}
}

type multiArrayIter struct {
	it []ArrayIter
}

func (m *multiArrayIter) Next() (v interface{}, ok bool) {
	for len(m.it) != 0 {
		if v, ok = m.it[0].Next(); ok {
			break
		}
		m.it = m.it[1:]
	}
	return
}
<|endoftext|>


<commit_before>package cbext

import (
	"encoding/json"
	"errors"
	"github.com/couchbaselabs/go-couchbase"
	"reflect"
	"strconv"
	"strings"
)

func GetCurrentDatacenter() string {
	return "ryd"
}

func GetDatacenters() []string {
	return []string{"ryd", "awsSwe", "awsNY"}
}

// TODO: make the "unique"-check field contain keys to their values in the array, for faster access

func SilentUniqueAppendToArray(bucket *couchbase.Bucket, key string, value interface{}, unique string) (string, error) {
	var arraykey string
	if err := AssertNotExists(bucket, key+":"+unique); err == nil {
		arraykey, err = AppendToArray(bucket, key, value)
		if err == nil {
			bucket.Set(key+":"+unique, 0, arraykey)
		}
	}
	return arraykey, nil
}

func AssertNotExists(bucket *couchbase.Bucket, key string) error {
	_, err := bucket.GetRaw(key)
	if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
		return nil
	} else {
		return errors.New("KEY_EXISTS")
	}
}

func AppendToArray(bucket *couchbase.Bucket, key string, value interface{}) (string, error) {
	var keyValue int
	err := bucket.Get(key+"_"+GetCurrentDatacenter(), &keyValue)
	if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
		return "", err
	}

	if err != nil && strings.Contains(err.Error(), "KEY_ENOENT") {
		bucket.Set(key+"_"+GetCurrentDatacenter(), 0, 0)
		keyValue = 0
	}

	keyValue += 1
	err = bucket.Set(key+"_"+GetCurrentDatacenter()+"_"+strconv.Itoa(keyValue), 0, value)

	if err != nil {
		return "", err
	}

	err = bucket.Set(key+"_"+GetCurrentDatacenter(), 0, keyValue)
	if err != nil {
		return "", err
	}

	return key + "_" + GetCurrentDatacenter() + "_" + strconv.Itoa(keyValue), nil
}

func FlushArray(bucket *couchbase.Bucket, key string, value interface{}) error {
	count := 0
	for _, dc := range GetDatacenters() {
		val := 0
		err := bucket.Get(key+"_"+dc, &val)
		if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
			return err
		}
		count += val
	}

	for _, dc := range GetDatacenters() {
		var keyValue int
		err := bucket.Get(key+"_"+dc, &keyValue)
		if err != nil && strings.Contains(err.Error(), "KEY_ENOENT") {
			continue
		}

		for i := 1; i <= keyValue; i += 1 {
			err = bucket.Delete(key + "_" + dc + "_" + strconv.Itoa(i))
			if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
				return err
			}
		}
	}

	for _, dc := range GetDatacenters() {
		err := bucket.Delete(key + "_" + dc)
		if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
			return err
		}
	}

	return nil
}

func DeleteUniqueArrayObject(bucket *couchbase.Bucket, key string, unique string) error {
	var arraykey string
	err := bucket.Get(key+":"+unique, &arraykey)
	if err != nil {
		return err
	}
	err = bucket.Delete(arraykey)
	if err != nil {
		return err
	}
	err = bucket.Delete(key + ":" + unique)
	if err != nil {
		return err
	}
	return nil
}

func DeleteArrayObject(bucket *couchbase.Bucket, key string, value interface{}) error {
	b, err := json.Marshal(value)
	if err != nil {
		return err
	}

	for _, dc := range GetDatacenters() {
		var keyValue int
		err = bucket.Get(key+"_"+dc, &keyValue)
		if err != nil && strings.Contains(err.Error(), "KEY_ENOENT") {
			continue
		}

		for i := 1; i <= keyValue; i += 1 {
			var v []byte
			v, err = bucket.GetRaw(key + "_" + dc + "_" + strconv.Itoa(i))
			if err == nil {
				if string(b) == string(v) {
					return bucket.Delete(key + "_" + dc + "_" + strconv.Itoa(i))
				}
			}
		}
	}

	return errors.New("OBJECT_NOT_FOUND_IN_ARRAY")
}

func GetArray(bucket *couchbase.Bucket, key string, rv interface{}) error {
	//fmt.Printf("GetArray(bucket *couchbase.Bucket, key %#v, rv %#v)+n", key, rv)
	count := 0
	for _, dc := range GetDatacenters() {
		val := 0
		err := bucket.Get(key+"_"+dc, &val)
		count += val
		if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
			return err
		}
	}

	//fmt.Println("got keys @", key)
	//time.Sleep(3 * time.Second)

	slice := reflect.ValueOf(rv).Elem()
	slice.Set(reflect.MakeSlice(slice.Type(), 0, count))

	for _, dc := range GetDatacenters() {
		var keyValue int
		err := bucket.Get(key+"_"+dc, &keyValue)
		if err != nil && strings.Contains(err.Error(), "KEY_ENOENT") {
			continue
		}

		//fmt.Println("sleeping between datacenters")
		//time.Sleep(3 * time.Second)
		for i := 1; i <= keyValue; i += 1 {
			v := reflect.New(slice.Type().Elem())
			err = bucket.Get(key+"_"+dc+"_"+strconv.Itoa(i), v.Interface())
			if err == nil {
				slice.Set(reflect.Append(slice, v.Elem()))
			}
		}
	}
	//fmt.Println("GetArray done")
	return nil
}
<commit_msg>bugfix<commit_after>package cbext

import (
	"encoding/json"
	"errors"
	"github.com/couchbaselabs/go-couchbase"
	"reflect"
	"strconv"
	"strings"
)

func GetCurrentDatacenter() string {
	return "ryd"
}

func GetDatacenters() []string {
	return []string{"ryd", "awsSwe", "awsNY"}
}

// TODO: make the "unique"-check field contain keys to their values in the array, for faster access

func SilentUniqueAppendToArray(bucket *couchbase.Bucket, key string, value interface{}, unique string) (string, error) {
	var arraykey string
	var err error
	if err = AssertNotExists(bucket, key+":"+unique); err == nil {
		arraykey, err = AppendToArray(bucket, key, value)
		if err == nil {
			err = bucket.Set(key+":"+unique, 0, arraykey)
		}
	}
	return arraykey, err
}

func AssertNotExists(bucket *couchbase.Bucket, key string) error {
	_, err := bucket.GetRaw(key)
	if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
		return nil
	} else {
		return errors.New("KEY_EXISTS")
	}
}

func AppendToArray(bucket *couchbase.Bucket, key string, value interface{}) (string, error) {
	var keyValue int
	err := bucket.Get(key+"_"+GetCurrentDatacenter(), &keyValue)
	if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
		return "", err
	}

	if err != nil && strings.Contains(err.Error(), "KEY_ENOENT") {
		bucket.Set(key+"_"+GetCurrentDatacenter(), 0, 0)
		keyValue = 0
	}

	keyValue += 1
	err = bucket.Set(key+"_"+GetCurrentDatacenter()+"_"+strconv.Itoa(keyValue), 0, value)

	if err != nil {
		return "", err
	}

	err = bucket.Set(key+"_"+GetCurrentDatacenter(), 0, keyValue)
	if err != nil {
		return "", err
	}

	return key + "_" + GetCurrentDatacenter() + "_" + strconv.Itoa(keyValue), nil
}

func FlushArray(bucket *couchbase.Bucket, key string, value interface{}) error {
	count := 0
	for _, dc := range GetDatacenters() {
		val := 0
		err := bucket.Get(key+"_"+dc, &val)
		if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
			return err
		}
		count += val
	}

	for _, dc := range GetDatacenters() {
		var keyValue int
		err := bucket.Get(key+"_"+dc, &keyValue)
		if err != nil && strings.Contains(err.Error(), "KEY_ENOENT") {
			continue
		}

		for i := 1; i <= keyValue; i += 1 {
			err = bucket.Delete(key + "_" + dc + "_" + strconv.Itoa(i))
			if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
				return err
			}
		}
	}

	for _, dc := range GetDatacenters() {
		err := bucket.Delete(key + "_" + dc)
		if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
			return err
		}
	}

	return nil
}

func DeleteUniqueArrayObject(bucket *couchbase.Bucket, key string, unique string) error {
	var arraykey string
	err := bucket.Get(key+":"+unique, &arraykey)
	if err != nil {
		return err
	}
	err = bucket.Delete(arraykey)
	if err != nil {
		return err
	}
	err = bucket.Delete(key + ":" + unique)
	if err != nil {
		return err
	}
	return nil
}

func DeleteArrayObject(bucket *couchbase.Bucket, key string, value interface{}) error {
	b, err := json.Marshal(value)
	if err != nil {
		return err
	}

	for _, dc := range GetDatacenters() {
		var keyValue int
		err = bucket.Get(key+"_"+dc, &keyValue)
		if err != nil && strings.Contains(err.Error(), "KEY_ENOENT") {
			continue
		}

		for i := 1; i <= keyValue; i += 1 {
			var v []byte
			v, err = bucket.GetRaw(key + "_" + dc + "_" + strconv.Itoa(i))
			if err == nil {
				if string(b) == string(v) {
					return bucket.Delete(key + "_" + dc + "_" + strconv.Itoa(i))
				}
			}
		}
	}

	return errors.New("OBJECT_NOT_FOUND_IN_ARRAY")
}

func GetArray(bucket *couchbase.Bucket, key string, rv interface{}) error {
	//fmt.Printf("GetArray(bucket *couchbase.Bucket, key %#v, rv %#v)+n", key, rv)
	count := 0
	for _, dc := range GetDatacenters() {
		val := 0
		err := bucket.Get(key+"_"+dc, &val)
		count += val
		if err != nil && !strings.Contains(err.Error(), "KEY_ENOENT") {
			return err
		}
	}

	//fmt.Println("got keys @", key)
	//time.Sleep(3 * time.Second)

	slice := reflect.ValueOf(rv).Elem()
	slice.Set(reflect.MakeSlice(slice.Type(), 0, count))

	for _, dc := range GetDatacenters() {
		var keyValue int
		err := bucket.Get(key+"_"+dc, &keyValue)
		if err != nil && strings.Contains(err.Error(), "KEY_ENOENT") {
			continue
		}

		//fmt.Println("sleeping between datacenters")
		//time.Sleep(3 * time.Second)
		for i := 1; i <= keyValue; i += 1 {
			v := reflect.New(slice.Type().Elem())
			err = bucket.Get(key+"_"+dc+"_"+strconv.Itoa(i), v.Interface())
			if err == nil {
				slice.Set(reflect.Append(slice, v.Elem()))
			}
		}
	}
	//fmt.Println("GetArray done")
	return nil
}
<|endoftext|>


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

package model

import (
	"runtime"
	"sync"
	"testing"
)

func TestLabelsToSignature(t *testing.T) {
	var scenarios = []struct {
		in  map[string]string
		out uint64
	}{
		{
			in:  map[string]string{},
			out: 14695981039346656037,
		},
		{
			in:  map[string]string{"name": "garland, briggs", "fear": "love is not enough"},
			out: 5799056148416392346,
		},
	}

	for i, scenario := range scenarios {
		actual := LabelsToSignature(scenario.in)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func TestMetricToFingerprint(t *testing.T) {
	var scenarios = []struct {
		in  Metric
		out Fingerprint
	}{
		{
			in:  Metric{},
			out: 14695981039346656037,
		},
		{
			in:  Metric{"name": "garland, briggs", "fear": "love is not enough"},
			out: 5799056148416392346,
		},
	}

	for i, scenario := range scenarios {
		actual := metricToFingerprint(scenario.in)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func TestMetricToFastFingerprint(t *testing.T) {
	var scenarios = []struct {
		in  Metric
		out Fingerprint
	}{
		{
			in:  Metric{},
			out: 14695981039346656037,
		},
		{
			in:  Metric{"name": "garland, briggs", "fear": "love is not enough"},
			out: 12952432476264840823,
		},
	}

	for i, scenario := range scenarios {
		actual := metricToFastFingerprint(scenario.in)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func TestSignatureForLabels(t *testing.T) {
	var scenarios = []struct {
		in     Metric
		labels LabelNames
		out    uint64
	}{
		{
			in:     Metric{},
			labels: nil,
			out:    14695981039346656037,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: LabelNames{"fear", "name"},
			out:    5799056148416392346,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"},
			labels: LabelNames{"fear", "name"},
			out:    5799056148416392346,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: LabelNames{},
			out:    14695981039346656037,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: nil,
			out:    14695981039346656037,
		},
	}

	for i, scenario := range scenarios {
		actual := SignatureForLabels(scenario.in, scenario.labels)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func TestSignatureWithoutLabels(t *testing.T) {
	var scenarios = []struct {
		in     Metric
		labels map[LabelName]struct{}
		out    uint64
	}{
		{
			in:     Metric{},
			labels: nil,
			out:    14695981039346656037,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: map[LabelName]struct{}{"fear": struct{}{}, "name": struct{}{}},
			out:    14695981039346656037,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"},
			labels: map[LabelName]struct{}{"foo": struct{}{}},
			out:    5799056148416392346,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: map[LabelName]struct{}{},
			out:    5799056148416392346,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: nil,
			out:    5799056148416392346,
		},
	}

	for i, scenario := range scenarios {
		actual := SignatureWithoutLabels(scenario.in, scenario.labels)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func benchmarkLabelToSignature(b *testing.B, l map[string]string, e uint64) {
	for i := 0; i < b.N; i++ {
		if a := LabelsToSignature(l); a != e {
			b.Fatalf("expected signature of %d for %s, got %d", e, l, a)
		}
	}
}

func BenchmarkLabelToSignatureScalar(b *testing.B) {
	benchmarkLabelToSignature(b, nil, 14695981039346656037)
}

func BenchmarkLabelToSignatureSingle(b *testing.B) {
	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value"}, 5146282821936882169)
}

func BenchmarkLabelToSignatureDouble(b *testing.B) {
	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717)
}

func BenchmarkLabelToSignatureTriple(b *testing.B) {
	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121)
}

func benchmarkMetricToFingerprint(b *testing.B, m Metric, e Fingerprint) {
	for i := 0; i < b.N; i++ {
		if a := metricToFingerprint(m); a != e {
			b.Fatalf("expected signature of %d for %s, got %d", e, m, a)
		}
	}
}

func BenchmarkMetricToFingerprintScalar(b *testing.B) {
	benchmarkMetricToFingerprint(b, nil, 14695981039346656037)
}

func BenchmarkMetricToFingerprintSingle(b *testing.B) {
	benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value"}, 5146282821936882169)
}

func BenchmarkMetricToFingerprintDouble(b *testing.B) {
	benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717)
}

func BenchmarkMetricToFingerprintTriple(b *testing.B) {
	benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121)
}

func benchmarkMetricToFastFingerprint(b *testing.B, m Metric, e Fingerprint) {
	for i := 0; i < b.N; i++ {
		if a := metricToFastFingerprint(m); a != e {
			b.Fatalf("expected signature of %d for %s, got %d", e, m, a)
		}
	}
}

func BenchmarkMetricToFastFingerprintScalar(b *testing.B) {
	benchmarkMetricToFastFingerprint(b, nil, 14695981039346656037)
}

func BenchmarkMetricToFastFingerprintSingle(b *testing.B) {
	benchmarkMetricToFastFingerprint(b, Metric{"first-label": "first-label-value"}, 5147259542624943964)
}

func BenchmarkMetricToFastFingerprintDouble(b *testing.B) {
	benchmarkMetricToFastFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value"}, 18269973311206963528)
}

func BenchmarkMetricToFastFingerprintTriple(b *testing.B) {
	benchmarkMetricToFastFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676)
}

func TestEmptyLabelSignature(t *testing.T) {
	input := []map[string]string{nil, {}}

	var ms runtime.MemStats
	runtime.ReadMemStats(&ms)

	alloc := ms.Alloc

	for _, labels := range input {
		LabelsToSignature(labels)
	}

	runtime.ReadMemStats(&ms)

	if got := ms.Alloc; alloc != got {
		t.Fatal("expected LabelsToSignature with empty labels not to perform allocations")
	}
}

func benchmarkMetricToFastFingerprintConc(b *testing.B, m Metric, e Fingerprint, concLevel int) {
	var start, end sync.WaitGroup
	start.Add(1)
	end.Add(concLevel)

	for i := 0; i < concLevel; i++ {
		go func() {
			start.Wait()
			for j := b.N / concLevel; j >= 0; j-- {
				if a := metricToFastFingerprint(m); a != e {
					b.Fatalf("expected signature of %d for %s, got %d", e, m, a)
				}
			}
			end.Done()
		}()
	}
	b.ResetTimer()
	start.Done()
	end.Wait()
}

func BenchmarkMetricToFastFingerprintTripleConc1(b *testing.B) {
	benchmarkMetricToFastFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 1)
}

func BenchmarkMetricToFastFingerprintTripleConc2(b *testing.B) {
	benchmarkMetricToFastFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 2)
}

func BenchmarkMetricToFastFingerprintTripleConc4(b *testing.B) {
	benchmarkMetricToFastFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 4)
}

func BenchmarkMetricToFastFingerprintTripleConc8(b *testing.B) {
	benchmarkMetricToFastFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 8)
}
<commit_msg>Remove runtime-dependent test.<commit_after>// Copyright 2014 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"sync"
	"testing"
)

func TestLabelsToSignature(t *testing.T) {
	var scenarios = []struct {
		in  map[string]string
		out uint64
	}{
		{
			in:  map[string]string{},
			out: 14695981039346656037,
		},
		{
			in:  map[string]string{"name": "garland, briggs", "fear": "love is not enough"},
			out: 5799056148416392346,
		},
	}

	for i, scenario := range scenarios {
		actual := LabelsToSignature(scenario.in)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func TestMetricToFingerprint(t *testing.T) {
	var scenarios = []struct {
		in  Metric
		out Fingerprint
	}{
		{
			in:  Metric{},
			out: 14695981039346656037,
		},
		{
			in:  Metric{"name": "garland, briggs", "fear": "love is not enough"},
			out: 5799056148416392346,
		},
	}

	for i, scenario := range scenarios {
		actual := metricToFingerprint(scenario.in)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func TestMetricToFastFingerprint(t *testing.T) {
	var scenarios = []struct {
		in  Metric
		out Fingerprint
	}{
		{
			in:  Metric{},
			out: 14695981039346656037,
		},
		{
			in:  Metric{"name": "garland, briggs", "fear": "love is not enough"},
			out: 12952432476264840823,
		},
	}

	for i, scenario := range scenarios {
		actual := metricToFastFingerprint(scenario.in)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func TestSignatureForLabels(t *testing.T) {
	var scenarios = []struct {
		in     Metric
		labels LabelNames
		out    uint64
	}{
		{
			in:     Metric{},
			labels: nil,
			out:    14695981039346656037,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: LabelNames{"fear", "name"},
			out:    5799056148416392346,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"},
			labels: LabelNames{"fear", "name"},
			out:    5799056148416392346,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: LabelNames{},
			out:    14695981039346656037,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: nil,
			out:    14695981039346656037,
		},
	}

	for i, scenario := range scenarios {
		actual := SignatureForLabels(scenario.in, scenario.labels)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func TestSignatureWithoutLabels(t *testing.T) {
	var scenarios = []struct {
		in     Metric
		labels map[LabelName]struct{}
		out    uint64
	}{
		{
			in:     Metric{},
			labels: nil,
			out:    14695981039346656037,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: map[LabelName]struct{}{"fear": struct{}{}, "name": struct{}{}},
			out:    14695981039346656037,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough", "foo": "bar"},
			labels: map[LabelName]struct{}{"foo": struct{}{}},
			out:    5799056148416392346,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: map[LabelName]struct{}{},
			out:    5799056148416392346,
		},
		{
			in:     Metric{"name": "garland, briggs", "fear": "love is not enough"},
			labels: nil,
			out:    5799056148416392346,
		},
	}

	for i, scenario := range scenarios {
		actual := SignatureWithoutLabels(scenario.in, scenario.labels)

		if actual != scenario.out {
			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
		}
	}
}

func benchmarkLabelToSignature(b *testing.B, l map[string]string, e uint64) {
	for i := 0; i < b.N; i++ {
		if a := LabelsToSignature(l); a != e {
			b.Fatalf("expected signature of %d for %s, got %d", e, l, a)
		}
	}
}

func BenchmarkLabelToSignatureScalar(b *testing.B) {
	benchmarkLabelToSignature(b, nil, 14695981039346656037)
}

func BenchmarkLabelToSignatureSingle(b *testing.B) {
	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value"}, 5146282821936882169)
}

func BenchmarkLabelToSignatureDouble(b *testing.B) {
	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717)
}

func BenchmarkLabelToSignatureTriple(b *testing.B) {
	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121)
}

func benchmarkMetricToFingerprint(b *testing.B, m Metric, e Fingerprint) {
	for i := 0; i < b.N; i++ {
		if a := metricToFingerprint(m); a != e {
			b.Fatalf("expected signature of %d for %s, got %d", e, m, a)
		}
	}
}

func BenchmarkMetricToFingerprintScalar(b *testing.B) {
	benchmarkMetricToFingerprint(b, nil, 14695981039346656037)
}

func BenchmarkMetricToFingerprintSingle(b *testing.B) {
	benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value"}, 5146282821936882169)
}

func BenchmarkMetricToFingerprintDouble(b *testing.B) {
	benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value"}, 3195800080984914717)
}

func BenchmarkMetricToFingerprintTriple(b *testing.B) {
	benchmarkMetricToFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 13843036195897128121)
}

func benchmarkMetricToFastFingerprint(b *testing.B, m Metric, e Fingerprint) {
	for i := 0; i < b.N; i++ {
		if a := metricToFastFingerprint(m); a != e {
			b.Fatalf("expected signature of %d for %s, got %d", e, m, a)
		}
	}
}

func BenchmarkMetricToFastFingerprintScalar(b *testing.B) {
	benchmarkMetricToFastFingerprint(b, nil, 14695981039346656037)
}

func BenchmarkMetricToFastFingerprintSingle(b *testing.B) {
	benchmarkMetricToFastFingerprint(b, Metric{"first-label": "first-label-value"}, 5147259542624943964)
}

func BenchmarkMetricToFastFingerprintDouble(b *testing.B) {
	benchmarkMetricToFastFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value"}, 18269973311206963528)
}

func BenchmarkMetricToFastFingerprintTriple(b *testing.B) {
	benchmarkMetricToFastFingerprint(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676)
}

func benchmarkMetricToFastFingerprintConc(b *testing.B, m Metric, e Fingerprint, concLevel int) {
	var start, end sync.WaitGroup
	start.Add(1)
	end.Add(concLevel)

	for i := 0; i < concLevel; i++ {
		go func() {
			start.Wait()
			for j := b.N / concLevel; j >= 0; j-- {
				if a := metricToFastFingerprint(m); a != e {
					b.Fatalf("expected signature of %d for %s, got %d", e, m, a)
				}
			}
			end.Done()
		}()
	}
	b.ResetTimer()
	start.Done()
	end.Wait()
}

func BenchmarkMetricToFastFingerprintTripleConc1(b *testing.B) {
	benchmarkMetricToFastFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 1)
}

func BenchmarkMetricToFastFingerprintTripleConc2(b *testing.B) {
	benchmarkMetricToFastFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 2)
}

func BenchmarkMetricToFastFingerprintTripleConc4(b *testing.B) {
	benchmarkMetricToFastFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 4)
}

func BenchmarkMetricToFastFingerprintTripleConc8(b *testing.B) {
	benchmarkMetricToFastFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 8)
}
<|endoftext|>


<commit_before>package redis

import (
	"fmt"
	"strings"
	"net/url"

	"github.com/garyburd/redigo/redis"
	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/helper/config"
	"github.com/mitchellh/packer/packer"
	"github.com/mitchellh/packer/template/interpolate"
)

var builtins = map[string]string{
	"mitchellh.amazonebs":       "amazonebs",
	"mitchellh.amazon.instance": "amazoninstance",
	"packer.googlecompute":      "googlecompute",
	"packer.docker":             "docker"
}

type Config struct {
	common.PackerConfig `mapstructure:",squash"`

	RedisUrl  string `mapstructure:"redis_url"`
	KeyPrefix string `mapstructure:"key_prefix"`
	ImageId   string `mapstructure:"image_id"`

	ctx interpolate.Context
}

type PostProcessor struct {
	client redis.Conn

	config Config
}

func (p *PostProcessor) Configure(raws ...interface{}) error {
	err := config.Decode(&p.config, &config.DecodeOpts{
		Interpolate: true,
		InterpolateFilter: &interpolate.RenderFilter{
			Exclude: []string{},
		},
	}, raws...)
	if err != nil {
		return err
	}

	required := map[string]*string{
		"redis_url":  &p.config.RedisUrl,
		"key_prefix": &p.config.KeyPrefix,
	}

	var errs *packer.MultiError
	for key, ptr := range required {
		if *ptr == "" {
			errs = packer.MultiErrorAppend(
				errs, fmt.Errorf("%s must be set", key))
		}
	}

	if errs != nil && len(errs.Errors) > 0 {
		return errs
	}

	return nil
}

func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	_, ok := builtins[artifact.BuilderId()]
	if !ok {
		return nil, true, fmt.Errorf(
			"Unsupported artifact type: %s", artifact.BuilderId())
	}

	ui.Say("Putting build artifacts into Redis...")

	ui.Message("Opening Redis connection...")

	// If no client is set, then we create a new one
	if p.client == nil {
		err := fmt.Errorf(
			"Error connecting to Redis")

		redisURL, err := url.Parse(p.config.RedisUrl)

		if err != nil {
			return artifact, true, fmt.Errorf(
				"Error parsing RedisUrl: %s", err)
		}

		auth := ""

		if redisURL.User != nil {
			if password, ok := redisURL.User.Password(); ok {
				auth = password
			}
		}

		p.client, err = redis.Dial(
			"tcp",
			redisURL.Host)
		if err != nil {
			return artifact, true, fmt.Errorf(
				"Error connecting to Redis: %s", err)
		}

		if len(auth) > 0 {
			_, err = p.client.Do("AUTH", auth)

			if err != nil {
				return artifact, true, fmt.Errorf(
					"Error connecting to Redis: %s", err)
			}
		}

		defer func() {
			ui.Message("Closing Redis connection...")
			if err := p.client.Close(); err != nil {
				ui.Error(fmt.Sprintf("Error closing Redis connection: %s", err))
			}
		}()
	}

	for _, regions := range strings.Split(artifact.Id(), ",") {

		parts := strings.Split(regions, ":")

		redis_key := ""
		image_id := ""

		if len(parts) == 2 {
			region := parts[0]
			if len(p.config.ImageId) > 0 {
				image_id = p.config.ImageId
			} else {
				image_id = parts[1]
			}

			redis_key = fmt.Sprintf("%s/%s", p.config.KeyPrefix, region)
		} else {
			if len(p.config.ImageId) > 0 {
				image_id = p.config.ImageId
			} else {
				image_id = parts[0]
			}

			redis_key = fmt.Sprintf("%s", p.config.KeyPrefix)
		}

		ui.Message(fmt.Sprintf("Setting key %s with value %s", redis_key, image_id))

		if _, err := p.client.Do("SET", redis_key, image_id); err != nil {
			return artifact, true, err
		}
	}
	return artifact, true, nil
}
<commit_msg>Added Docker support and ability to provide overriden ImageID to be set as the redis value<commit_after>package redis

import (
	"fmt"
	"strings"
	"net/url"

	"github.com/garyburd/redigo/redis"
	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/helper/config"
	"github.com/mitchellh/packer/packer"
	"github.com/mitchellh/packer/template/interpolate"
)

var builtins = map[string]string{
	"mitchellh.amazonebs":       "amazonebs",
	"mitchellh.amazon.instance": "amazoninstance",
	"packer.googlecompute":      "googlecompute",
	"packer.docker":             "docker",
}

type Config struct {
	common.PackerConfig `mapstructure:",squash"`

	RedisUrl  string `mapstructure:"redis_url"`
	KeyPrefix string `mapstructure:"key_prefix"`
	ImageId   string `mapstructure:"image_id"`

	ctx interpolate.Context
}

type PostProcessor struct {
	client redis.Conn

	config Config
}

func (p *PostProcessor) Configure(raws ...interface{}) error {
	err := config.Decode(&p.config, &config.DecodeOpts{
		Interpolate: true,
		InterpolateFilter: &interpolate.RenderFilter{
			Exclude: []string{},
		},
	}, raws...)
	if err != nil {
		return err
	}

	required := map[string]*string{
		"redis_url":  &p.config.RedisUrl,
		"key_prefix": &p.config.KeyPrefix,
	}

	var errs *packer.MultiError
	for key, ptr := range required {
		if *ptr == "" {
			errs = packer.MultiErrorAppend(
				errs, fmt.Errorf("%s must be set", key))
		}
	}

	if errs != nil && len(errs.Errors) > 0 {
		return errs
	}

	return nil
}

func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
	_, ok := builtins[artifact.BuilderId()]
	if !ok {
		return nil, true, fmt.Errorf(
			"Unsupported artifact type: %s", artifact.BuilderId())
	}

	ui.Say("Putting build artifacts into Redis...")

	ui.Message("Opening Redis connection...")

	// If no client is set, then we create a new one
	if p.client == nil {
		err := fmt.Errorf(
			"Error connecting to Redis")

		redisURL, err := url.Parse(p.config.RedisUrl)

		if err != nil {
			return artifact, true, fmt.Errorf(
				"Error parsing RedisUrl: %s", err)
		}

		auth := ""

		if redisURL.User != nil {
			if password, ok := redisURL.User.Password(); ok {
				auth = password
			}
		}

		p.client, err = redis.Dial(
			"tcp",
			redisURL.Host)
		if err != nil {
			return artifact, true, fmt.Errorf(
				"Error connecting to Redis: %s", err)
		}

		if len(auth) > 0 {
			_, err = p.client.Do("AUTH", auth)

			if err != nil {
				return artifact, true, fmt.Errorf(
					"Error connecting to Redis: %s", err)
			}
		}

		defer func() {
			ui.Message("Closing Redis connection...")
			if err := p.client.Close(); err != nil {
				ui.Error(fmt.Sprintf("Error closing Redis connection: %s", err))
			}
		}()
	}

	for _, regions := range strings.Split(artifact.Id(), ",") {

		parts := strings.Split(regions, ":")

		redis_key := ""
		image_id := ""

		if len(parts) == 2 {
			region := parts[0]
			if len(p.config.ImageId) > 0 {
				image_id = p.config.ImageId
			} else {
				image_id = parts[1]
			}

			redis_key = fmt.Sprintf("%s/%s", p.config.KeyPrefix, region)
		} else {
			if len(p.config.ImageId) > 0 {
				image_id = p.config.ImageId
			} else {
				image_id = parts[0]
			}

			redis_key = fmt.Sprintf("%s", p.config.KeyPrefix)
		}

		ui.Message(fmt.Sprintf("Setting key %s with value %s", redis_key, image_id))

		if _, err := p.client.Do("SET", redis_key, image_id); err != nil {
			return artifact, true, err
		}
	}
	return artifact, true, nil
}
<|endoftext|>


<commit_before>package main

func initLoginSubCmd(app *cli.App) {
}
<commit_msg>add login subcommand with -g and -n option<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/urfave/cli"
)

func initLoginSubCmd(app *cli.App) {

	loginSubCmd := cli.Command{
		Name:        "login",
		Usage:       "login <options>",
		Description: "login to one node",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:  "g,group",
				Value: "*",
				Usage: "the group's node you want to login",
			},
			cli.StringFlag{
				Name:  "n,node",
				Value: "*",
				Usage: "the node you want to login",
			},
		},
		Action: func(c *cli.Context) error {
			// 如果有 --generate-bash-completion 参数, 则不执行默认命令
			if os.Args[len(os.Args)-1] == "--generate-bash-completion" {
				bashComplete(c)
				return nil
			}

			var groupName = c.String("group")
			var nodeName = c.String("node")
			var err error
			if err = loginNode(groupName, nodeName); err != nil {
				fmt.Println(err)
			}
			return err
		},
	}

	if app.Commands == nil {
		app.Commands = cli.Commands{loginSubCmd}
	} else {
		app.Commands = append(app.Commands, loginSubCmd)
	}
}

func loginNode(groupName, nodeName string) error {

	return nil
}
<|endoftext|>


<commit_before>package ssim

import (
	"image"
	"math"

	"log"

	"github.com/disintegration/gift"
)

const (
	k1 = 0.01
	k2 = 0.03
	l  = 255
	c1 = (k1 * l) * (k1 * l)
	c2 = (k2 * l) * (k2 * l)
)

var kernel = [][]float64{
	{1.0576e-06, 7.8144e-06, 3.7022e-05, 1.1246e-04, 2.1905e-04, 2.7356e-04, 2.1905e-04, 1.1246e-04, 3.7022e-05, 7.8144e-06, 1.0576e-06},
	{7.8144e-06, 5.7741e-05, 2.7356e-04, 8.3101e-04, 1.6186e-03, 2.0214e-03, 1.6186e-03, 8.3101e-04, 2.7356e-04, 5.7741e-05, 7.8144e-06},
	{3.7022e-05, 2.7356e-04, 1.2961e-03, 3.9371e-03, 7.6684e-03, 9.5766e-03, 7.6684e-03, 3.9371e-03, 1.2961e-03, 2.7356e-04, 3.7022e-05},
	{1.1246e-04, 8.3101e-04, 3.9371e-03, 1.1960e-02, 2.3294e-02, 2.9091e-02, 2.3294e-02, 1.1960e-02, 3.9371e-03, 8.3101e-04, 1.1246e-04},
	{2.1905e-04, 1.6186e-03, 7.6684e-03, 2.3294e-02, 4.5371e-02, 5.6662e-02, 4.5371e-02, 2.3294e-02, 7.6684e-03, 1.6186e-03, 2.1905e-04},
	{2.7356e-04, 2.0214e-03, 9.5766e-03, 2.9091e-02, 5.6662e-02, 7.0762e-02, 5.6662e-02, 2.9091e-02, 9.5766e-03, 2.0214e-03, 2.7356e-04},
	{2.1905e-04, 1.6186e-03, 7.6684e-03, 2.3294e-02, 4.5371e-02, 5.6662e-02, 4.5371e-02, 2.3294e-02, 7.6684e-03, 1.6186e-03, 2.1905e-04},
	{1.1246e-04, 8.3101e-04, 3.9371e-03, 1.1960e-02, 2.3294e-02, 2.9091e-02, 2.3294e-02, 1.1960e-02, 3.9371e-03, 8.3101e-04, 1.1246e-04},
	{3.7022e-05, 2.7356e-04, 1.2961e-03, 3.9371e-03, 7.6684e-03, 9.5766e-03, 7.6684e-03, 3.9371e-03, 1.2961e-03, 2.7356e-04, 3.7022e-05},
	{7.8144e-06, 5.7741e-05, 2.7356e-04, 8.3101e-04, 1.6186e-03, 2.0214e-03, 1.6186e-03, 8.3101e-04, 2.7356e-04, 5.7741e-05, 7.8144e-06},
	{1.0576e-06, 7.8144e-06, 3.7022e-05, 1.1246e-04, 2.1905e-04, 2.7356e-04, 2.1905e-04, 1.1246e-04, 3.7022e-05, 7.8144e-06, 1.0576e-06},
}

func SsimWithAlpha(img1 *image.Gray, img2 *image.Gray, alpha *image.Alpha) float64 {
	boundsMin := img1.Bounds().Min
	boundsMax := img1.Bounds().Max

	const windowSize = 11

	var sum float64
	var totalWindows uint
	var numWindows uint
	var numTransparentWindows uint
	for y := boundsMin.Y; y < boundsMax.Y-windowSize; y++ {
		for x := boundsMin.X; x < boundsMax.X-windowSize; x++ {
			totalWindows += 1
			rect := image.Rect(x, y, x+windowSize, y+windowSize)
			alphaWindow := alpha.SubImage(rect).(*image.Alpha)
			if isFullyTransparent(alphaWindow) {
				numTransparentWindows += 1
				continue
			}
			img1Window := img1.SubImage(rect).(*image.Gray)
			img2Window := img2.SubImage(rect).(*image.Gray)
			sum += ssimWindow(img1Window, img2Window)
			numWindows++
		}
	}

	log.Printf("Number of windows: %d Transparent: %d Total: %d", numWindows, numTransparentWindows, totalWindows)

	return sum / float64(numWindows)
}

func isFullyTransparent(img *image.Alpha) bool {
	boundsMin := img.Bounds().Min
	boundsMax := img.Bounds().Max

	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			if img.AlphaAt(x, y).A > 0 {
				return false
			}
		}
	}
	return true
}

func Ssim(img1 *image.Gray, img2 *image.Gray) float64 {
	boundsMin := img1.Bounds().Min
	boundsMax := img1.Bounds().Max

	const windowSize = 11

	var sum float64
	var numWindows uint
	for y := boundsMin.Y; y < boundsMax.Y-windowSize; y++ {
		for x := boundsMin.X; x < boundsMax.X-windowSize; x++ {
			rect := image.Rect(x, y, x+windowSize, y+windowSize)
			img1Window := img1.SubImage(rect).(*image.Gray)
			img2Window := img2.SubImage(rect).(*image.Gray)
			sum += ssimWindow(img1Window, img2Window)
			numWindows++
		}
	}

	return sum / float64(numWindows)
}

func ssimWindow(img1 *image.Gray, img2 *image.Gray) float64 {
	mean1 := mean(img1)
	mean2 := mean(img2)

	variance1 := stdev(mean1, img1)
	variance2 := stdev(mean2, img2)

	covar := covariance(mean1, img1, mean2, img2)

	a := (2*mean1*mean2 + c1) * (2*covar + c2)
	b := (mean1*mean1 + mean2*mean2 + c1) * (variance1*variance1 + variance2*variance2 + c2)

	return a / b
}

func mean(img *image.Gray) float64 {
	boundsMin := img.Bounds().Min
	boundsMax := img.Bounds().Max

	var sum float64
	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			sum += kernel[y-boundsMin.Y][x-boundsMin.X] * float64(img.GrayAt(x, y).Y)
		}
	}

	return sum
}

func stdev(mean float64, img *image.Gray) float64 {
	boundsMin := img.Bounds().Min
	boundsMax := img.Bounds().Max

	var sum float64
	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			val := float64(img.GrayAt(x, y).Y) - mean
			sum += kernel[y-boundsMin.Y][x-boundsMin.X] * (val * val)
		}
	}

	return math.Pow(sum, 0.5)
}

func covariance(mean1 float64, img1 *image.Gray, mean2 float64, img2 *image.Gray) float64 {
	boundsMin := img1.Bounds().Min
	boundsMax := img2.Bounds().Max

	var sum float64
	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			val1 := float64(img1.GrayAt(x, y).Y) - mean1
			val2 := float64(img2.GrayAt(x, y).Y) - mean2
			sum += kernel[y-boundsMin.Y][x-boundsMin.X] * val1 * val2
		}
	}

	return sum
}

type segmentedImage struct {
	edges           *image.Gray
	smoothRegions   *image.Gray
	texturedRegions *image.Gray
}

func segmentImage(img1 *image.Gray, sobel1 *image.Gray, img2 *image.Gray, sobel2 *image.Gray) (segmentedImage, segmentedImage) {
	boundsMin := sobel1.Bounds().Min
	boundsMax := sobel1.Bounds().Max

	var gmax uint8
	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			value := sobel1.GrayAt(x, y).Y
			if value > gmax {
				gmax = value
			}
		}
	}

	th1 := 0.12 * float64(gmax)
	th2 := 0.06 * float64(gmax)

	edges1 := image.NewGray(sobel1.Bounds())
	edges2 := image.NewGray(sobel1.Bounds())
	smoothRegions1 := image.NewGray(sobel1.Bounds())
	smoothRegions2 := image.NewGray(sobel1.Bounds())
	texturedRegions1 := image.NewGray(sobel1.Bounds())
	texturedRegions2 := image.NewGray(sobel1.Bounds())

	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			if float64(sobel1.GrayAt(x, y).Y) > th1 || float64(sobel2.GrayAt(x, y).Y) > th1 {
				edges1.SetGray(x, y, img1.GrayAt(x, y))
				edges2.SetGray(x, y, img2.GrayAt(x, y))
			} else if float64(sobel1.GrayAt(x, y).Y) < th2 || float64(sobel2.GrayAt(x, y).Y) <= th1 {
				smoothRegions1.SetGray(x, y, img1.GrayAt(x, y))
				smoothRegions2.SetGray(x, y, img2.GrayAt(x, y))
			} else {
				texturedRegions1.SetGray(x, y, img1.GrayAt(x, y))
				texturedRegions2.SetGray(x, y, img2.GrayAt(x, y))
			}
		}
	}

	return segmentedImage{
			edges:           edges1,
			smoothRegions:   smoothRegions1,
			texturedRegions: texturedRegions1,
		}, segmentedImage{
			edges:           edges2,
			smoothRegions:   smoothRegions2,
			texturedRegions: texturedRegions2,
		}
}

func ContentWeightedSsim(img1 *image.Gray, img2 *image.Gray) float64 {
	g := gift.New(gift.Sobel())

	sobel1 := image.NewGray(img1.Bounds())
	g.Draw(sobel1, img1)
	sobel2 := image.NewGray(img1.Bounds())
	g.Draw(sobel2, img2)

	segmented1, segmented2 := segmentImage(img1, sobel1, img2, sobel2)

	return 0.5*Ssim(segmented1.edges, segmented2.edges) +
		0.25*Ssim(segmented1.smoothRegions, segmented2.smoothRegions) +
		0.25*Ssim(segmented1.texturedRegions, segmented2.texturedRegions)
}
<commit_msg>Print max and min ssim.<commit_after>package ssim

import (
	"image"
	"log"
	"math"

	"github.com/disintegration/gift"
)

const (
	k1 = 0.01
	k2 = 0.03
	l  = 255
	c1 = (k1 * l) * (k1 * l)
	c2 = (k2 * l) * (k2 * l)
)

var kernel = [][]float64{
	{1.0576e-06, 7.8144e-06, 3.7022e-05, 1.1246e-04, 2.1905e-04, 2.7356e-04, 2.1905e-04, 1.1246e-04, 3.7022e-05, 7.8144e-06, 1.0576e-06},
	{7.8144e-06, 5.7741e-05, 2.7356e-04, 8.3101e-04, 1.6186e-03, 2.0214e-03, 1.6186e-03, 8.3101e-04, 2.7356e-04, 5.7741e-05, 7.8144e-06},
	{3.7022e-05, 2.7356e-04, 1.2961e-03, 3.9371e-03, 7.6684e-03, 9.5766e-03, 7.6684e-03, 3.9371e-03, 1.2961e-03, 2.7356e-04, 3.7022e-05},
	{1.1246e-04, 8.3101e-04, 3.9371e-03, 1.1960e-02, 2.3294e-02, 2.9091e-02, 2.3294e-02, 1.1960e-02, 3.9371e-03, 8.3101e-04, 1.1246e-04},
	{2.1905e-04, 1.6186e-03, 7.6684e-03, 2.3294e-02, 4.5371e-02, 5.6662e-02, 4.5371e-02, 2.3294e-02, 7.6684e-03, 1.6186e-03, 2.1905e-04},
	{2.7356e-04, 2.0214e-03, 9.5766e-03, 2.9091e-02, 5.6662e-02, 7.0762e-02, 5.6662e-02, 2.9091e-02, 9.5766e-03, 2.0214e-03, 2.7356e-04},
	{2.1905e-04, 1.6186e-03, 7.6684e-03, 2.3294e-02, 4.5371e-02, 5.6662e-02, 4.5371e-02, 2.3294e-02, 7.6684e-03, 1.6186e-03, 2.1905e-04},
	{1.1246e-04, 8.3101e-04, 3.9371e-03, 1.1960e-02, 2.3294e-02, 2.9091e-02, 2.3294e-02, 1.1960e-02, 3.9371e-03, 8.3101e-04, 1.1246e-04},
	{3.7022e-05, 2.7356e-04, 1.2961e-03, 3.9371e-03, 7.6684e-03, 9.5766e-03, 7.6684e-03, 3.9371e-03, 1.2961e-03, 2.7356e-04, 3.7022e-05},
	{7.8144e-06, 5.7741e-05, 2.7356e-04, 8.3101e-04, 1.6186e-03, 2.0214e-03, 1.6186e-03, 8.3101e-04, 2.7356e-04, 5.7741e-05, 7.8144e-06},
	{1.0576e-06, 7.8144e-06, 3.7022e-05, 1.1246e-04, 2.1905e-04, 2.7356e-04, 2.1905e-04, 1.1246e-04, 3.7022e-05, 7.8144e-06, 1.0576e-06},
}

func SsimWithAlpha(img1 *image.Gray, img2 *image.Gray, alpha *image.Alpha) float64 {
	boundsMin := img1.Bounds().Min
	boundsMax := img1.Bounds().Max

	const windowSize = 11

	var sum float64
	var totalWindows uint
	var numWindows uint
	var numTransparentWindows uint
	for y := boundsMin.Y; y < boundsMax.Y-windowSize; y++ {
		for x := boundsMin.X; x < boundsMax.X-windowSize; x++ {
			totalWindows += 1
			rect := image.Rect(x, y, x+windowSize, y+windowSize)
			alphaWindow := alpha.SubImage(rect).(*image.Alpha)
			if isFullyTransparent(alphaWindow) {
				numTransparentWindows += 1
				continue
			}
			img1Window := img1.SubImage(rect).(*image.Gray)
			img2Window := img2.SubImage(rect).(*image.Gray)
			sum += ssimWindow(img1Window, img2Window)
			numWindows++
		}
	}

	log.Printf("Number of windows: %d Transparent: %d Total: %d", numWindows, numTransparentWindows, totalWindows)

	return sum / float64(numWindows)
}

func isFullyTransparent(img *image.Alpha) bool {
	boundsMin := img.Bounds().Min
	boundsMax := img.Bounds().Max

	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			if img.AlphaAt(x, y).A > 0 {
				return false
			}
		}
	}
	return true
}

func Ssim(img1 *image.Gray, img2 *image.Gray) float64 {
	boundsMin := img1.Bounds().Min
	boundsMax := img1.Bounds().Max

	const windowSize = 11

	var sum, max, min float64 = 0, 0, math.MaxFloat64
	var numWindows uint
	for y := boundsMin.Y; y < boundsMax.Y-windowSize; y++ {
		for x := boundsMin.X; x < boundsMax.X-windowSize; x++ {
			rect := image.Rect(x, y, x+windowSize, y+windowSize)
			img1Window := img1.SubImage(rect).(*image.Gray)
			img2Window := img2.SubImage(rect).(*image.Gray)
			windowSsim := ssimWindow(img1Window, img2Window)
			if windowSsim > max {
				max = windowSsim
			}
			if windowSsim < min {
				min = windowSsim
			}
			sum += windowSsim
			numWindows++
		}
	}

	log.Printf("SSIM: %f MIN: %f MAX: %f", sum/float64(numWindows), min, max)

	return sum / float64(numWindows)
}

func ssimWindow(img1 *image.Gray, img2 *image.Gray) float64 {
	mean1 := mean(img1)
	mean2 := mean(img2)

	variance1 := stdev(mean1, img1)
	variance2 := stdev(mean2, img2)

	covar := covariance(mean1, img1, mean2, img2)

	a := (2*mean1*mean2 + c1) * (2*covar + c2)
	b := (mean1*mean1 + mean2*mean2 + c1) * (variance1*variance1 + variance2*variance2 + c2)

	return a / b
}

func mean(img *image.Gray) float64 {
	boundsMin := img.Bounds().Min
	boundsMax := img.Bounds().Max

	var sum float64
	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			sum += kernel[y-boundsMin.Y][x-boundsMin.X] * float64(img.GrayAt(x, y).Y)
		}
	}

	return sum
}

func stdev(mean float64, img *image.Gray) float64 {
	boundsMin := img.Bounds().Min
	boundsMax := img.Bounds().Max

	var sum float64
	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			val := float64(img.GrayAt(x, y).Y) - mean
			sum += kernel[y-boundsMin.Y][x-boundsMin.X] * (val * val)
		}
	}

	return math.Pow(sum, 0.5)
}

func covariance(mean1 float64, img1 *image.Gray, mean2 float64, img2 *image.Gray) float64 {
	boundsMin := img1.Bounds().Min
	boundsMax := img2.Bounds().Max

	var sum float64
	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			val1 := float64(img1.GrayAt(x, y).Y) - mean1
			val2 := float64(img2.GrayAt(x, y).Y) - mean2
			sum += kernel[y-boundsMin.Y][x-boundsMin.X] * val1 * val2
		}
	}

	return sum
}

type segmentedImage struct {
	edges           *image.Gray
	smoothRegions   *image.Gray
	texturedRegions *image.Gray
}

func segmentImage(img1 *image.Gray, sobel1 *image.Gray, img2 *image.Gray, sobel2 *image.Gray) (segmentedImage, segmentedImage) {
	boundsMin := sobel1.Bounds().Min
	boundsMax := sobel1.Bounds().Max

	var gmax uint8
	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			value := sobel1.GrayAt(x, y).Y
			if value > gmax {
				gmax = value
			}
		}
	}

	th1 := 0.12 * float64(gmax)
	th2 := 0.06 * float64(gmax)

	edges1 := image.NewGray(sobel1.Bounds())
	edges2 := image.NewGray(sobel1.Bounds())
	smoothRegions1 := image.NewGray(sobel1.Bounds())
	smoothRegions2 := image.NewGray(sobel1.Bounds())
	texturedRegions1 := image.NewGray(sobel1.Bounds())
	texturedRegions2 := image.NewGray(sobel1.Bounds())

	for y := boundsMin.Y; y < boundsMax.Y; y++ {
		for x := boundsMin.X; x < boundsMax.X; x++ {
			if float64(sobel1.GrayAt(x, y).Y) > th1 || float64(sobel2.GrayAt(x, y).Y) > th1 {
				edges1.SetGray(x, y, img1.GrayAt(x, y))
				edges2.SetGray(x, y, img2.GrayAt(x, y))
			} else if float64(sobel1.GrayAt(x, y).Y) < th2 || float64(sobel2.GrayAt(x, y).Y) <= th1 {
				smoothRegions1.SetGray(x, y, img1.GrayAt(x, y))
				smoothRegions2.SetGray(x, y, img2.GrayAt(x, y))
			} else {
				texturedRegions1.SetGray(x, y, img1.GrayAt(x, y))
				texturedRegions2.SetGray(x, y, img2.GrayAt(x, y))
			}
		}
	}

	return segmentedImage{
			edges:           edges1,
			smoothRegions:   smoothRegions1,
			texturedRegions: texturedRegions1,
		}, segmentedImage{
			edges:           edges2,
			smoothRegions:   smoothRegions2,
			texturedRegions: texturedRegions2,
		}
}

func ContentWeightedSsim(img1 *image.Gray, img2 *image.Gray) float64 {
	g := gift.New(gift.Sobel())

	sobel1 := image.NewGray(img1.Bounds())
	g.Draw(sobel1, img1)
	sobel2 := image.NewGray(img1.Bounds())
	g.Draw(sobel2, img2)

	segmented1, segmented2 := segmentImage(img1, sobel1, img2, sobel2)

	return 0.5*Ssim(segmented1.edges, segmented2.edges) +
		0.25*Ssim(segmented1.smoothRegions, segmented2.smoothRegions) +
		0.25*Ssim(segmented1.texturedRegions, segmented2.texturedRegions)
}
<|endoftext|>


<commit_before>package nyb

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/url"
	"strings"
	"time"

	"github.com/hako/durafmt"
	"github.com/ugjka/dumbirc"
	"github.com/ugjka/go-tz"
)

var nickChangeInterval = time.Second * 5

func (bot *Settings) addCallbacks() {
	irc := bot.IrcConn
	//On any message send a signal to ping timer to be ready
	irc.AddCallback(dumbirc.ANYMESSAGE, func(msg *dumbirc.Message) {
		pingpong(bot.pp)
	})

	irc.AddCallback(dumbirc.WELCOME, func(msg *dumbirc.Message) {
		irc.Join(bot.IrcChans)
		//Prevent early start
		bot.Do(func() {
			close(bot.start)
		})
	})

	irc.AddCallback(dumbirc.PING, func(msg *dumbirc.Message) {
		log.Println("PING recieved, sending PONG")
		irc.Pong()
	})

	irc.AddCallback(dumbirc.PONG, func(msg *dumbirc.Message) {
		log.Println("Got PONG...")
	})

	irc.AddCallback(dumbirc.NICKTAKEN, func(msg *dumbirc.Message) {
		log.Println("Nick taken, changing...")
		time.Sleep(nickChangeInterval)
		irc.Nick = changeNick(irc.Nick)
		log.Printf("New nick: %s", irc.Nick)
		irc.NewNick(irc.Nick)
	})
}

func (bot *Settings) addTriggers() {
	irc := bot.IrcConn
	//Trigger for !help
	stHelp := "%s: Query location: '%s <location>', Next zone: '%s !next', Last zone: '%s !last', Remaining: '%s !remaining', Source code: https://github.com/ugjka/newyearsbot"
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				msg.Trailing == fmt.Sprintf("%s !help", bot.IrcTrigger)
		},
		Response: func(msg *dumbirc.Message) {
			irc.Reply(msg, fmt.Sprintf(stHelp, msg.Name, bot.IrcTrigger, bot.IrcTrigger, bot.IrcTrigger, bot.IrcTrigger))
		},
	})
	//Trigger for !next
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				msg.Trailing == fmt.Sprintf("%s !next", bot.IrcTrigger)
		},
		Response: func(msg *dumbirc.Message) {
			log.Println("Querying !next...")
			dur := time.Minute * time.Duration(bot.next.Offset*60)
			if timeNow().UTC().Add(dur).After(target) {
				irc.Reply(msg, fmt.Sprintf("No more next, %d is here AoE", target.Year()))
				return
			}
			humandur := durafmt.Parse(target.Sub(timeNow().UTC().Add(dur)))
			irc.Reply(msg, fmt.Sprintf("Next New Year in %s in %s",
				removeMilliseconds(humandur), bot.next))
		},
	})
	//Trigger for !last
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				msg.Trailing == fmt.Sprintf("%s !last", bot.IrcTrigger)
		},
		Response: func(msg *dumbirc.Message) {
			log.Println("Querying !last...")
			dur := time.Minute * time.Duration(bot.last.Offset*60)
			humandur := durafmt.Parse(timeNow().UTC().Add(dur).Sub(target))
			if bot.last.Offset == -12 {
				humandur = durafmt.Parse(timeNow().UTC().Add(dur).Sub(target.AddDate(-1, 0, 0)))
			}
			irc.Reply(msg, fmt.Sprintf("Last New Year %s ago in %s",
				removeMilliseconds(humandur), bot.last))
		},
	})
	//Trigger for !remaining
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				msg.Trailing == fmt.Sprintf("%s !remaining", bot.IrcTrigger)
		},
		Response: func(msg *dumbirc.Message) {
			ss := "s"
			if bot.remaining == 1 {
				ss = ""
			}
			irc.Reply(msg, fmt.Sprintf("%s: %d timezone%s remaining", msg.Name, bot.remaining, ss))
		},
	})
	//Trigger for location queries
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				!strings.Contains(msg.Trailing, "!next") &&
				!strings.Contains(msg.Trailing, "!last") &&
				!strings.Contains(msg.Trailing, "!help") &&
				!strings.Contains(msg.Trailing, "!remaining") &&
				strings.HasPrefix(msg.Trailing, fmt.Sprintf("%s ", bot.IrcTrigger))
		},
		Response: func(msg *dumbirc.Message) {
			tz, err := bot.getNewYear(msg.Trailing[len(bot.IrcTrigger)+1:])
			if err == errNoZone || err == errNoPlace {
				log.Println("Query error:", err)
				irc.Reply(msg, fmt.Sprintf("%s: %s", msg.Name, err))
				return
			}
			if err != nil {
				log.Println("Query error:", err)
				irc.Reply(msg, "Some error occurred!")
				return
			}
			irc.Reply(msg, fmt.Sprintf("%s: %s", msg.Name, tz))
		},
	})
}

var (
	errNoZone  = errors.New("couldn't get the timezone for that location")
	errNoPlace = errors.New("Couldn't find that place")
)

func (bot *Settings) getNominatimReqURL(location *string) string {
	maps := url.Values{}
	maps.Add("q", *location)
	maps.Add("format", "json")
	maps.Add("accept-language", "en")
	maps.Add("limit", "1")
	maps.Add("email", bot.Email)
	return bot.Nominatim + NominatimEndpoint + maps.Encode()
}

var stNewYearWillHappen = "New Year in %s will happen in %s"
var stNewYearHappenned = "New Year in %s happened %s ago"

func (bot *Settings) getNewYear(location string) (string, error) {
	log.Println("Querying location:", location)
	data, err := NominatimGetter(bot.getNominatimReqURL(&location))
	if err != nil {
		log.Println(err)
		return "", err
	}
	var res NominatimResults
	if err = json.Unmarshal(data, &res); err != nil {
		log.Println(err)
		return "", err
	}
	if len(res) == 0 {
		return "", errNoPlace
	}
	p := gotz.Point{
		Lat: res[0].Lat,
		Lon: res[0].Lon,
	}
	zone, err := gotz.GetZone(p)
	if err != nil {
		return "", errNoZone
	}
	offset := time.Second * time.Duration(getOffset(target, zone))
	adress := res[0].DisplayName

	if timeNow().UTC().Add(offset).Before(target) {
		humandur := durafmt.Parse(target.Sub(timeNow().UTC().Add(offset)))
		return fmt.Sprintf(stNewYearWillHappen, adress, removeMilliseconds(humandur)), nil
	}
	humandur := durafmt.Parse(timeNow().UTC().Add(offset).Sub(target))
	return fmt.Sprintf(stNewYearHappenned, adress, removeMilliseconds(humandur)), nil
}
<commit_msg>adress caller<commit_after>package nyb

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/url"
	"strings"
	"time"

	"github.com/hako/durafmt"
	"github.com/ugjka/dumbirc"
	"github.com/ugjka/go-tz"
)

var nickChangeInterval = time.Second * 5

func (bot *Settings) addCallbacks() {
	irc := bot.IrcConn
	//On any message send a signal to ping timer to be ready
	irc.AddCallback(dumbirc.ANYMESSAGE, func(msg *dumbirc.Message) {
		pingpong(bot.pp)
	})

	irc.AddCallback(dumbirc.WELCOME, func(msg *dumbirc.Message) {
		irc.Join(bot.IrcChans)
		//Prevent early start
		bot.Do(func() {
			close(bot.start)
		})
	})

	irc.AddCallback(dumbirc.PING, func(msg *dumbirc.Message) {
		log.Println("PING recieved, sending PONG")
		irc.Pong()
	})

	irc.AddCallback(dumbirc.PONG, func(msg *dumbirc.Message) {
		log.Println("Got PONG...")
	})

	irc.AddCallback(dumbirc.NICKTAKEN, func(msg *dumbirc.Message) {
		log.Println("Nick taken, changing...")
		time.Sleep(nickChangeInterval)
		irc.Nick = changeNick(irc.Nick)
		log.Printf("New nick: %s", irc.Nick)
		irc.NewNick(irc.Nick)
	})
}

func (bot *Settings) addTriggers() {
	irc := bot.IrcConn
	//Trigger for !help
	stHelp := "%s: Query location: '%s <location>', Next zone: '%s !next', Last zone: '%s !last', Remaining: '%s !remaining', Source code: https://github.com/ugjka/newyearsbot"
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				msg.Trailing == fmt.Sprintf("%s !help", bot.IrcTrigger)
		},
		Response: func(msg *dumbirc.Message) {
			irc.Reply(msg, fmt.Sprintf(stHelp, msg.Name, bot.IrcTrigger, bot.IrcTrigger, bot.IrcTrigger, bot.IrcTrigger))
		},
	})
	//Trigger for !next
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				msg.Trailing == fmt.Sprintf("%s !next", bot.IrcTrigger)
		},
		Response: func(msg *dumbirc.Message) {
			log.Println("Querying !next...")
			dur := time.Minute * time.Duration(bot.next.Offset*60)
			if timeNow().UTC().Add(dur).After(target) {
				irc.Reply(msg, fmt.Sprintf("No more next, %d is here AoE", target.Year()))
				return
			}
			humandur := durafmt.Parse(target.Sub(timeNow().UTC().Add(dur)))
			irc.Reply(msg, fmt.Sprintf("Next New Year in %s in %s",
				removeMilliseconds(humandur), bot.next))
		},
	})
	//Trigger for !last
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				msg.Trailing == fmt.Sprintf("%s !last", bot.IrcTrigger)
		},
		Response: func(msg *dumbirc.Message) {
			log.Println("Querying !last...")
			dur := time.Minute * time.Duration(bot.last.Offset*60)
			humandur := durafmt.Parse(timeNow().UTC().Add(dur).Sub(target))
			if bot.last.Offset == -12 {
				humandur = durafmt.Parse(timeNow().UTC().Add(dur).Sub(target.AddDate(-1, 0, 0)))
			}
			irc.Reply(msg, fmt.Sprintf("Last New Year %s ago in %s",
				removeMilliseconds(humandur), bot.last))
		},
	})
	//Trigger for !remaining
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				msg.Trailing == fmt.Sprintf("%s !remaining", bot.IrcTrigger)
		},
		Response: func(msg *dumbirc.Message) {
			ss := "s"
			if bot.remaining == 1 {
				ss = ""
			}
			irc.Reply(msg, fmt.Sprintf("%s: %d timezone%s remaining", msg.Name, bot.remaining, ss))
		},
	})
	//Trigger for location queries
	irc.AddTrigger(dumbirc.Trigger{
		Condition: func(msg *dumbirc.Message) bool {
			return msg.Command == dumbirc.PRIVMSG &&
				!strings.Contains(msg.Trailing, "!next") &&
				!strings.Contains(msg.Trailing, "!last") &&
				!strings.Contains(msg.Trailing, "!help") &&
				!strings.Contains(msg.Trailing, "!remaining") &&
				strings.HasPrefix(msg.Trailing, fmt.Sprintf("%s ", bot.IrcTrigger))
		},
		Response: func(msg *dumbirc.Message) {
			tz, err := bot.getNewYear(msg.Trailing[len(bot.IrcTrigger)+1:])
			if err == errNoZone || err == errNoPlace {
				log.Println("Query error:", err)
				irc.Reply(msg, fmt.Sprintf("%s: %s", msg.Name, err))
				return
			}
			if err != nil {
				log.Println("Query error:", err)
				irc.Reply(msg, fmt.Sprintf("%s: Some error occurred!", msg.Name))
				return
			}
			irc.Reply(msg, fmt.Sprintf("%s: %s", msg.Name, tz))
		},
	})
}

var (
	errNoZone  = errors.New("couldn't get the timezone for that location")
	errNoPlace = errors.New("Couldn't find that place")
)

func (bot *Settings) getNominatimReqURL(location *string) string {
	maps := url.Values{}
	maps.Add("q", *location)
	maps.Add("format", "json")
	maps.Add("accept-language", "en")
	maps.Add("limit", "1")
	maps.Add("email", bot.Email)
	return bot.Nominatim + NominatimEndpoint + maps.Encode()
}

var stNewYearWillHappen = "New Year in %s will happen in %s"
var stNewYearHappenned = "New Year in %s happened %s ago"

func (bot *Settings) getNewYear(location string) (string, error) {
	log.Println("Querying location:", location)
	data, err := NominatimGetter(bot.getNominatimReqURL(&location))
	if err != nil {
		log.Println(err)
		return "", err
	}
	var res NominatimResults
	if err = json.Unmarshal(data, &res); err != nil {
		log.Println(err)
		return "", err
	}
	if len(res) == 0 {
		return "", errNoPlace
	}
	p := gotz.Point{
		Lat: res[0].Lat,
		Lon: res[0].Lon,
	}
	zone, err := gotz.GetZone(p)
	if err != nil {
		return "", errNoZone
	}
	offset := time.Second * time.Duration(getOffset(target, zone))
	adress := res[0].DisplayName

	if timeNow().UTC().Add(offset).Before(target) {
		humandur := durafmt.Parse(target.Sub(timeNow().UTC().Add(offset)))
		return fmt.Sprintf(stNewYearWillHappen, adress, removeMilliseconds(humandur)), nil
	}
	humandur := durafmt.Parse(timeNow().UTC().Add(offset).Sub(target))
	return fmt.Sprintf(stNewYearHappenned, adress, removeMilliseconds(humandur)), nil
}
<|endoftext|>


<commit_before>package modelhelper

import (
  "koding/db/models"
  "koding/db/mongodb"
  "labix.org/v2/mgo"
)

var (
  POST_COLL = "jNewStatusUpdates"
)

func GetStatusUpdateById(id string) (*models.StatusUpdate, error) {
  statusUpdate := new(models.StatusUpdate)
  if err := mongodb.One(POST_COLL, id, statusUpdate); err != nil {
    return nil, err
  }

  return statusUpdate, nil
}

func UpdateStatusUpdate(s *models.StatusUpdate) error {
  query := func(c *mgo.Collection) error {
    return c.UpdateId(s.Id, s)
  }

  return mongodb.Run(POST_COLL, query)
}
<commit_msg>Moderation: DeleteStatusUpdateById function is added to status update helper<commit_after>package modelhelper

import (
  "koding/db/models"
  "koding/db/mongodb"
  "labix.org/v2/mgo"
)

var (
  POST_COLL = "jNewStatusUpdates"
)

func GetStatusUpdateById(id string) (*models.StatusUpdate, error) {
  statusUpdate := new(models.StatusUpdate)
  if err := mongodb.One(POST_COLL, id, statusUpdate); err != nil {
    return nil, err
  }

  return statusUpdate, nil
}

func UpdateStatusUpdate(s *models.StatusUpdate) error {
  query := func(c *mgo.Collection) error {
    return c.UpdateId(s.Id, s)
  }

  return mongodb.Run(POST_COLL, query)
}

func DeleteStatusUpdateById(id string) error {
  selector := Selector{"_id": GetObjectId(id)}
  query := func(c *mgo.Collection) error {
    return c.Remove(selector)
  }

  return mongodb.Run(POST_COLL, query)
}
<|endoftext|>


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

package main

import (
	"encoding/json"
	"strings"

	"github.com/fatih/color"
	"github.com/minio/cli"
	"github.com/minio/mc/pkg/console"
	"github.com/minio/minio-xl/pkg/probe"
)

// Set access permissions.
var accessCmd = cli.Command{
	Name:   "access",
	Usage:  "Set or get access permissions.",
	Action: mainAccess,
	CustomHelpTemplate: `Name:
   mc {{.Name}} - {{.Usage}}

USAGE:
   mc {{.Name}} set PERMISSION TARGET [TARGET ...]
   mc {{.Name}} get TARGET [TARGET ...]

   PERMISSION = private | readonly | public | authorized {{if .Description}}

DESCRIPTION:
   {{.Description}}{{end}}

EXAMPLES:
   1. Set bucket to "private" on Amazon S3 cloud storage.
      $ mc {{.Name}} set private https://s3.amazonaws.com/burningman2011

   2. Set bucket to "public" on Amazon S3 cloud storage.
      $ mc {{.Name}} set public https://s3.amazonaws.com/shared

   3. Set bucket to "authenticated" on Amazon S3 cloud storage to provide read access to IAM Authenticated Users group.
      $ mc {{.Name}} set authorized https://s3.amazonaws.com/shared-authenticated

   4. Get bucket permissions.
      $ mc {{.Name}} get https://s3.amazonaws.com/shared

   5. Get bucket permissions.
      $ mc {{.Name}} get https://storage.googleapis.com/miniocloud
`,
}

// accessMessage is container for access command on bucket success and failure messages
type accessMessage struct {
	Operation string      `json:"operation"`
	Status    string      `json:"status"`
	Bucket    string      `json:"bucket"`
	Perms     accessPerms `json:"permission"`
}

// String colorized access message
func (s accessMessage) String() string {
	if s.Operation == "set" {
		return console.Colorize("Access", "Set access permission ‘"+string(s.Perms)+"’ updated successfully for ‘"+s.Bucket+"’")
	}
	if s.Operation == "get" {
		return console.Colorize("Access", "Access permission for ‘"+s.Bucket+"’"+" is ‘"+string(s.Perms)+"’")
	}
	// nothing to print
	return ""
}

// JSON jsonified access message
func (s accessMessage) JSON() string {
	accessJSONBytes, err := json.Marshal(s)
	fatalIf(probe.NewError(err), "Unable to marshal into JSON.")

	return string(accessJSONBytes)
}

func checkAccessSyntax(ctx *cli.Context) {
	if !ctx.Args().Present() {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
	}
	if len(ctx.Args()) < 2 {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
	}
	switch ctx.Args().First() {
	case "set":
		if len(ctx.Args().Tail()) < 2 {
			cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
		}
		perms := accessPerms(ctx.Args().Tail().Get(0))
		if !perms.isValidAccessPERM() {
			fatalIf(errDummy().Trace(),
				"Unrecognized permission ‘"+perms.String()+"’. Allowed values are [private, public, readonly].")
		}
		for _, arg := range ctx.Args().Tail().Tail() {
			if strings.TrimSpace(arg) == "" {
				fatalIf(errInvalidArgument().Trace(), "Unable to validate empty argument.")
			}
		}
	case "get":
		if len(ctx.Args().Tail()) < 1 {
			cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
		}
	}
}

func doSetAccess(targetURL string, targetPERMS accessPerms) *probe.Error {
	clnt, err := url2Client(targetURL)
	if err != nil {
		return err.Trace(targetURL)
	}
	if err = clnt.SetBucketAccess(targetPERMS.String()); err != nil {
		return err.Trace(targetURL, targetPERMS.String())
	}
	return nil
}

func doGetAccess(targetURL string) (perms accessPerms, err *probe.Error) {
	clnt, err := url2Client(targetURL)
	if err != nil {
		return "", err.Trace(targetURL)
	}
	acl, err := clnt.GetBucketAccess()
	if err != nil {
		return "", err.Trace(targetURL)
	}
	return aclToPerms(acl), nil
}

func mainAccess(ctx *cli.Context) {
	checkAccessSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("Access", color.New(color.FgGreen, color.Bold))
	config := mustGetMcConfig()

	switch ctx.Args().Get(0) {
	case "set":
		perms := accessPerms(ctx.Args().Tail().Get(0))
		for _, arg := range ctx.Args().Tail().Tail() {
			targetURL := getAliasURL(arg, config.Aliases)

			fatalIf(doSetAccess(targetURL, perms).Trace(targetURL, string(perms)), "Unable to set access permission ‘"+string(perms)+"’ for ‘"+targetURL+"’.")

			printMsg(accessMessage{
				Operation: "set",
				Status:    "success",
				Bucket:    targetURL,
				Perms:     perms,
			})
		}
	case "get":
		for _, arg := range ctx.Args().Tail() {
			targetURL := getAliasURL(arg, config.Aliases)
			perms, err := doGetAccess(targetURL)
			fatalIf(err.Trace(targetURL), "Unable to get access permission for ‘"+targetURL+"’.")

			printMsg(accessMessage{
				Operation: "get",
				Status:    "success",
				Bucket:    targetURL,
				Perms:     perms,
			})
		}
	}
}
<commit_msg>access command review<commit_after>/*
 * Minio Client, (C) 2015 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"encoding/json"
	"strings"

	"github.com/fatih/color"
	"github.com/minio/cli"
	"github.com/minio/mc/pkg/console"
	"github.com/minio/minio-xl/pkg/probe"
)

// Set access permissions.
var accessCmd = cli.Command{
	Name:   "access",
	Usage:  "Set or get access permissions.",
	Action: mainAccess,
	CustomHelpTemplate: `Name:
   mc {{.Name}} - {{.Usage}}

USAGE:
   mc {{.Name}} set PERMISSION TARGET [TARGET ...]
   mc {{.Name}} get TARGET [TARGET ...]

PERMISSION:
   Allowed permissions are: [private, readonly, public, authorized].

EXAMPLES:
   1. Set bucket to "private" on Amazon S3 cloud storage.
      $ mc {{.Name}} set private https://s3.amazonaws.com/burningman2011

   2. Set bucket to "public" on Amazon S3 cloud storage.
      $ mc {{.Name}} set public https://s3.amazonaws.com/shared

   3. Set bucket to "authenticated" on Amazon S3 cloud storage to provide read access to IAM Authenticated Users group.
      $ mc {{.Name}} set authorized https://s3.amazonaws.com/shared-authenticated

   4. Get bucket permissions.
      $ mc {{.Name}} get https://s3.amazonaws.com/shared

   5. Get bucket permissions.
      $ mc {{.Name}} get https://storage.googleapis.com/miniocloud
`,
}

// accessMessage is container for access command on bucket success and failure messages
type accessMessage struct {
	Operation string      `json:"operation"`
	Status    string      `json:"status"`
	Bucket    string      `json:"bucket"`
	Perms     accessPerms `json:"permission"`
}

// String colorized access message
func (s accessMessage) String() string {
	if s.Operation == "set" {
		return console.Colorize("Access", "Set access permission ‘"+string(s.Perms)+"’ updated successfully for ‘"+s.Bucket+"’")
	}
	if s.Operation == "get" {
		return console.Colorize("Access", "Access permission for ‘"+s.Bucket+"’"+" is ‘"+string(s.Perms)+"’")
	}
	// nothing to print
	return ""
}

// JSON jsonified access message
func (s accessMessage) JSON() string {
	accessJSONBytes, err := json.Marshal(s)
	fatalIf(probe.NewError(err), "Unable to marshal into JSON.")

	return string(accessJSONBytes)
}

func checkAccessSyntax(ctx *cli.Context) {
	if !ctx.Args().Present() {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
	}
	if len(ctx.Args()) < 2 {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
	}
	switch ctx.Args().First() {
	case "set":
		if len(ctx.Args().Tail()) < 2 {
			cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
		}
		perms := accessPerms(ctx.Args().Tail().Get(0))
		if !perms.isValidAccessPERM() {
			fatalIf(errDummy().Trace(),
				"Unrecognized permission ‘"+perms.String()+"’. Allowed values are [private, public, readonly].")
		}
		for _, arg := range ctx.Args().Tail().Tail() {
			if strings.TrimSpace(arg) == "" {
				fatalIf(errInvalidArgument().Trace(), "Unable to validate empty argument.")
			}
		}
	case "get":
		if len(ctx.Args().Tail()) < 1 {
			cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code
		}
	}
}

func doSetAccess(targetURL string, targetPERMS accessPerms) *probe.Error {
	clnt, err := url2Client(targetURL)
	if err != nil {
		return err.Trace(targetURL)
	}
	if err = clnt.SetBucketAccess(targetPERMS.String()); err != nil {
		return err.Trace(targetURL, targetPERMS.String())
	}
	return nil
}

func doGetAccess(targetURL string) (perms accessPerms, err *probe.Error) {
	clnt, err := url2Client(targetURL)
	if err != nil {
		return "", err.Trace(targetURL)
	}
	acl, err := clnt.GetBucketAccess()
	if err != nil {
		return "", err.Trace(targetURL)
	}
	return aclToPerms(acl), nil
}

func mainAccess(ctx *cli.Context) {
	checkAccessSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("Access", color.New(color.FgGreen, color.Bold))
	config := mustGetMcConfig()

	switch ctx.Args().First() {
	case "set":
		perms := accessPerms(ctx.Args().Tail().First())
		for _, arg := range ctx.Args().Tail().Tail() {
			targetURL := getAliasURL(arg, config.Aliases)

			fatalIf(doSetAccess(targetURL, perms).Trace(targetURL, string(perms)), "Unable to set access permission ‘"+string(perms)+"’ for ‘"+targetURL+"’.")

			printMsg(accessMessage{
				Operation: "set",
				Status:    "success",
				Bucket:    targetURL,
				Perms:     perms,
			})
		}
	case "get":
		for _, arg := range ctx.Args().Tail() {
			targetURL := getAliasURL(arg, config.Aliases)
			perms, err := doGetAccess(targetURL)
			fatalIf(err.Trace(targetURL), "Unable to get access permission for ‘"+targetURL+"’.")

			printMsg(accessMessage{
				Operation: "get",
				Status:    "success",
				Bucket:    targetURL,
				Perms:     perms,
			})
		}
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2015 Gravitational, Inc.

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

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

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

package web

import (
	"io"
	"io/ioutil"
	"net/http"
	"sync"
	"time"

	"github.com/gravitational/teleport/lib/events"
	"github.com/gravitational/teleport/lib/reversetunnel"
	"github.com/gravitational/teleport/lib/session"

	log "github.com/Sirupsen/logrus"
	"github.com/gravitational/trace"
	"golang.org/x/net/websocket"
)

func newSessionStreamHandler(sessionID string, ctx *sessionContext, site reversetunnel.RemoteSite, pollPeriod time.Duration) (*sessionStreamHandler, error) {
	return &sessionStreamHandler{
		pollPeriod: pollPeriod,
		sessionID:  sessionID,
		ctx:        ctx,
		site:       site,
		closeC:     make(chan bool),
	}, nil
}

// sessionStreamHandler streams events related to some particular session
// as a stream of JSON encoded event packets
type sessionStreamHandler struct {
	closeOnce  sync.Once
	pollPeriod time.Duration
	ctx        *sessionContext
	site       reversetunnel.RemoteSite
	sessionID  string
	closeC     chan bool
	ws         *websocket.Conn
}

func (w *sessionStreamHandler) Close() error {
	w.ws.Close()
	w.closeOnce.Do(func() {
		close(w.closeC)
	})
	return nil
}

func (w *sessionStreamHandler) stream(ws *websocket.Conn) error {
	w.ws = ws
	clt, err := w.site.GetClient()
	if err != nil {
		return trace.Wrap(err)
	}
	// spin up a goroutine to detect closed socket by reading
	// from it
	go func() {
		defer w.Close()
		io.Copy(ioutil.Discard, ws)
	}()

	var lastCheckpoint time.Time
	var lastEvent *sessionStreamEvent
	ticker := time.NewTicker(w.pollPeriod)
	defer ticker.Stop()
	defer w.Close()
	for {
		now := time.Now()
		f := events.Filter{
			SessionID: w.sessionID,
			Order:     events.Desc,
			Limit:     20,
			Start:     now,
			End:       lastCheckpoint,
		}
		events, err := clt.GetEvents(f)
		if err != nil {
			return trace.Wrap(err)
		}

		servers, err := clt.GetServers()
		if err != nil {
			return trace.Wrap(err)
		}

		sess, err := clt.GetSession(w.sessionID)
		if err != nil {
			return trace.Wrap(err)
		}

		event := &sessionStreamEvent{
			Session: *sess,
			Nodes:   servers,
			Events:  events,
		}

		newData := w.diffEvents(lastEvent, event)
		lastCheckpoint = now
		lastEvent = event
		if newData {
			if err := websocket.JSON.Send(ws, event); err != nil {
				return trace.Wrap(err)
			}
		}

		log.Infof("about to sleep %v", w.pollPeriod)
		select {
		case <-ticker.C:
		case <-w.closeC:
			log.Infof("stream is closed")
			return nil
		}
	}
}

const defaultPollPeriod = time.Second

func (w *sessionStreamHandler) Handler() http.Handler {
	// TODO(klizhentas)
	// we instantiate a server explicitly here instead of using
	// websocket.HandlerFunc to set empty origin checker
	// make sure we check origin when in prod mode
	return &websocket.Server{
		Handler: w.logResult(w.stream),
	}
}

func (w *sessionStreamHandler) logResult(fn func(*websocket.Conn) error) websocket.Handler {
	return func(ws *websocket.Conn) {
		err := fn(ws)
		if err != nil {
			log.WithFields(log.Fields{"sid": w.sessionID}).Infof("handler returned: %#v", err)
		}
	}
}

func (w *sessionStreamHandler) diffEvents(last *sessionStreamEvent, new *sessionStreamEvent) bool {
	// this is first call, ship whatever we have on this session
	if last == nil {
		return true
	}
	// we've got new events
	if len(new.Events) != 0 {
		log.Infof("got new events")
		return true
	}
	// new servers have arrived or disappeared
	if len(last.Nodes) != len(new.Nodes) {
		log.Infof("nodes have changes")
		return true
	}
	// parties have joined or left the scene
	if setsDifferent(partySet(last), partySet(new)) {
		log.Infof("parties have changes")
		return true
	}
	return false
}

func partySet(e *sessionStreamEvent) map[session.Party]bool {
	parties := make(map[session.Party]bool, len(e.Session.Parties))
	for _, party := range e.Session.Parties {
		parties[party] = true
	}
	return parties
}

func setsDifferent(a, b map[session.Party]bool) bool {
	for key := range a {
		if !b[key] {
			return true
		}
	}
	for key := range b {
		if !a[key] {
			return true
		}
	}
	return false
}
<commit_msg>fix events<commit_after>/*
Copyright 2015 Gravitational, Inc.

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

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

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

package web

import (
	"io"
	"io/ioutil"
	"net/http"
	"sync"
	"time"

	"github.com/gravitational/teleport"
	"github.com/gravitational/teleport/lib/events"
	"github.com/gravitational/teleport/lib/reversetunnel"
	"github.com/gravitational/teleport/lib/session"

	log "github.com/Sirupsen/logrus"
	"github.com/gravitational/trace"
	"golang.org/x/net/websocket"
)

func newSessionStreamHandler(sessionID string, ctx *sessionContext, site reversetunnel.RemoteSite, pollPeriod time.Duration) (*sessionStreamHandler, error) {
	return &sessionStreamHandler{
		pollPeriod: pollPeriod,
		sessionID:  sessionID,
		ctx:        ctx,
		site:       site,
		closeC:     make(chan bool),
	}, nil
}

// sessionStreamHandler streams events related to some particular session
// as a stream of JSON encoded event packets
type sessionStreamHandler struct {
	closeOnce  sync.Once
	pollPeriod time.Duration
	ctx        *sessionContext
	site       reversetunnel.RemoteSite
	sessionID  string
	closeC     chan bool
	ws         *websocket.Conn
}

func (w *sessionStreamHandler) Close() error {
	w.ws.Close()
	w.closeOnce.Do(func() {
		close(w.closeC)
	})
	return nil
}

func (w *sessionStreamHandler) stream(ws *websocket.Conn) error {
	w.ws = ws
	clt, err := w.site.GetClient()
	if err != nil {
		return trace.Wrap(err)
	}
	// spin up a goroutine to detect closed socket by reading
	// from it
	go func() {
		defer w.Close()
		io.Copy(ioutil.Discard, ws)
	}()

	var lastCheckpoint time.Time
	var lastEvent *sessionStreamEvent
	ticker := time.NewTicker(w.pollPeriod)
	defer ticker.Stop()
	defer w.Close()
	for {
		now := time.Now()
		f := events.Filter{
			SessionID: w.sessionID,
			Order:     events.Desc,
			Limit:     20,
			Start:     now,
			End:       lastCheckpoint,
		}
		events, err := clt.GetEvents(f)
		if err != nil {
			if !teleport.IsNotFound(err) {
				return trace.Wrap(err)
			}
		}

		servers, err := clt.GetServers()
		if err != nil {
			if !teleport.IsNotFound(err) {
				return trace.Wrap(err)
			}
		}

		sess, err := clt.GetSession(w.sessionID)
		if err != nil {
			if !teleport.IsNotFound(err) {
				return trace.Wrap(err)
			}
		}

		if sess != nil {
			event := &sessionStreamEvent{
				Session: *sess,
				Nodes:   servers,
				Events:  events,
			}

			newData := w.diffEvents(lastEvent, event)
			lastCheckpoint = now
			lastEvent = event
			if newData {
				log.Infof("about to send %#v", event)
				if err := websocket.JSON.Send(ws, event); err != nil {
					return trace.Wrap(err)
				}
			}
		}

		log.Infof("about to sleep %v", w.pollPeriod)
		select {
		case <-ticker.C:
		case <-w.closeC:
			log.Infof("stream is closed")
			return nil
		}
	}
}

const defaultPollPeriod = time.Second

func (w *sessionStreamHandler) Handler() http.Handler {
	// TODO(klizhentas)
	// we instantiate a server explicitly here instead of using
	// websocket.HandlerFunc to set empty origin checker
	// make sure we check origin when in prod mode
	return &websocket.Server{
		Handler: w.logResult(w.stream),
	}
}

func (w *sessionStreamHandler) logResult(fn func(*websocket.Conn) error) websocket.Handler {
	return func(ws *websocket.Conn) {
		err := fn(ws)
		if err != nil {
			log.WithFields(log.Fields{"sid": w.sessionID}).Infof("handler returned: %#v", err)
		}
	}
}

func (w *sessionStreamHandler) diffEvents(last *sessionStreamEvent, new *sessionStreamEvent) bool {
	// this is first call, ship whatever we have on this session
	if last == nil {
		return true
	}
	// we've got new events
	if len(new.Events) != 0 {
		log.Infof("got new events")
		return true
	}
	// new servers have arrived or disappeared
	if len(last.Nodes) != len(new.Nodes) {
		log.Infof("nodes have changes")
		return true
	}
	// parties have joined or left the scene
	if setsDifferent(partySet(last), partySet(new)) {
		log.Infof("parties have changes")
		return true
	}
	return false
}

func partySet(e *sessionStreamEvent) map[session.Party]bool {
	parties := make(map[session.Party]bool, len(e.Session.Parties))
	for _, party := range e.Session.Parties {
		parties[party] = true
	}
	return parties
}

func setsDifferent(a, b map[session.Party]bool) bool {
	for key := range a {
		if !b[key] {
			return true
		}
	}
	for key := range b {
		if !a[key] {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"math/rand"
	"testing"
	"time"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

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

func TestAccAWSS3Bucket(t *testing.T) {

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
				),
			},
			resource.TestStep{
				Config: testAccAWSS3BucketWebsiteConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketExists("aws_s3_bucket.website"),
				),
			},
		},
	})
}

func testAccCheckAWSS3BucketDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).s3conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_s3_bucket" {
			continue
		}
		_, err := conn.DeleteBucket(&s3.DeleteBucketInput{
			Bucket: aws.String(rs.Primary.ID),
		})
		if err != nil {
			return err
		}
	}
	return nil
}

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

		if rs.Primary.ID == "" {
			return fmt.Errorf("No S3 Bucket ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).s3conn
		_, err := conn.HeadBucket(&s3.HeadBucketInput{
			Bucket: aws.String(rs.Primary.ID),
		})

		if err != nil {
			return fmt.Errorf("S3Bucket error: %v", err)
		}
		return nil
	}
}

// These need a bit of randoness as the name can only be used once globally
// within AWS
var testAccAWSS3BucketConfig = fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
	bucket = "tf-test-bucket-%d"
	acl = "public-read"
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int())

var testAccAWSS3BucketWebsiteConfig = fmt.Sprintf(`
resource "aws_s3_bucket" "website" {
	bucket = "tf-test-bucket-website-%d"
	acl = "public-read"

	website {
		index_document = "index.html"
	}
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int())
<commit_msg>providers/aws: Check that S3 website sets docs<commit_after>package aws

import (
	"fmt"
	"math/rand"
	"testing"
	"time"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

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

func TestAccAWSS3Bucket(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
				),
			},
		},
	})
}

func TestAccAWSS3BucketWebsite(t *testing.T) {
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSS3BucketDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSS3BucketWebsiteConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSS3BucketExists("aws_s3_bucket.website"),
					testAccCheckAWSS3BucketWebsite(
						"aws_s3_bucket.website", "index.html", "error.html"),
				),
			},
		},
	})
}

func testAccCheckAWSS3BucketDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).s3conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_s3_bucket" {
			continue
		}
		_, err := conn.DeleteBucket(&s3.DeleteBucketInput{
			Bucket: aws.String(rs.Primary.ID),
		})
		if err != nil {
			return err
		}
	}
	return nil
}

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

		if rs.Primary.ID == "" {
			return fmt.Errorf("No S3 Bucket ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).s3conn
		_, err := conn.HeadBucket(&s3.HeadBucketInput{
			Bucket: aws.String(rs.Primary.ID),
		})

		if err != nil {
			return fmt.Errorf("S3Bucket error: %v", err)
		}
		return nil
	}
}

func testAccCheckAWSS3BucketWebsite(n string, indexDoc string, errorDoc string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, _ := s.RootModule().Resources[n]
		conn := testAccProvider.Meta().(*AWSClient).s3conn

		out, err := conn.GetBucketWebsite(&s3.GetBucketWebsiteInput{
			Bucket: aws.String(rs.Primary.ID),
		})

		if err != nil {
			return fmt.Errorf("S3BucketWebsite error: %v", err)
		}

		if *out.IndexDocument.Suffix != indexDoc {
			return fmt.Errorf("bad: %s", out.IndexDocument)
		}

		if *out.ErrorDocument.Key != errorDoc {
			return fmt.Errorf("bad: %s", out.ErrorDocument)
		}

		return nil
	}
}

// These need a bit of randoness as the name can only be used once globally
// within AWS
var testAccAWSS3BucketConfig = fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
	bucket = "tf-test-bucket-%d"
	acl = "public-read"
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int())

var testAccAWSS3BucketWebsiteConfig = fmt.Sprintf(`
resource "aws_s3_bucket" "website" {
	bucket = "tf-test-bucket-website-%d"
	acl = "public-read"

	website {
		index_document = "index.html"
		error_document = "error.html"
	}
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int())
<|endoftext|>