<commit_before>package lua

type lValueArraySorter struct {
	L      *LState
	Fn     *LFunction
	Values []LValue
}

func (lv lValueArraySorter) Len() int {
	return len(lv.Values)
}

func (lv lValueArraySorter) Swap(i, j int) {
	lv.Values[i], lv.Values[j] = lv.Values[j], lv.Values[i]
}

func (lv lValueArraySorter) Less(i, j int) bool {
	if lv.Fn != nil {
		lv.L.Push(lv.Fn)
		lv.L.Push(lv.Values[i])
		lv.L.Push(lv.Values[j])
		lv.L.Call(2, 1)
		return LVAsBool(lv.L.reg.Pop())
	}
	return lessThan(lv.L, lv.Values[i], lv.Values[j])
}

func newLTable(acap int, hcap int) *LTable {
	if acap < 0 {
		acap = 0
	}
	if hcap < 0 {
		hcap = 0
	}
	tb := &LTable{
		array:     make([]LValue, 0, acap),
		dict:      make(map[LValue]LValue, hcap),
		keys:      nil,
		k2i:       nil,
		Metatable: LNil,
	}
	return tb
}

func (tb *LTable) Len() int {
	var prev LValue = LNil
	for i := len(tb.array) - 1; i >= 0; i-- {
		v := tb.array[i]
		if prev == LNil && v != LNil {
			return i + 1
		}
		prev = v
	}
	return 0
}

func (tb *LTable) Append(value LValue) {
	tb.array = append(tb.array, value)
}

func (tb *LTable) Insert(i int, value LValue) {
	if i > len(tb.array) {
		tb.RawSetInt(i, value)
		return
	}
	if i <= 0 {
		tb.RawSet(LNumber(i), value)
		return
	}
	i -= 1
	tb.array = append(tb.array, LNil)
	copy(tb.array[i+1:], tb.array[i:])
	tb.array[i] = value
}

func (tb *LTable) MaxN() int {
	for i := len(tb.array) - 1; i >= 0; i-- {
		if tb.array[i] != LNil {
			return i
		}
	}
	return 0
}

func (tb *LTable) Remove(pos int) {
	i := pos - 1
	larray := len(tb.array)
	switch {
	case i >= larray:
		return
	case i == larray-1 || i < 0:
		tb.array = tb.array[:larray-1]
	default:
		copy(tb.array[i:], tb.array[i+1:])
		tb.array[larray-1] = nil
		tb.array = tb.array[:larray-1]
	}
}

func (tb *LTable) RawSet(key LValue, value LValue) {
	switch v := key.(type) {
	case LNumber:
		if isArrayKey(v) {
			index := int(v) - 1
			alen := len(tb.array)
			switch {
			case index == alen:
				tb.array = append(tb.array, value)
			case index > alen:
				for i := 0; i < (index - alen); i++ {
					tb.array = append(tb.array, LNil)
				}
				tb.array = append(tb.array, value)
			case index < alen:
				tb.array[index] = value
			}
			return
		}
	}
	tb.dict[key] = value
}

func (tb *LTable) RawSetInt(key int, value LValue) {
	if key < 1 || key >= MaxArrayIndex {
		tb.dict[LNumber(key)] = value
		return
	}
	index := key - 1
	alen := len(tb.array)
	switch {
	case index == alen:
		tb.array = append(tb.array, value)
	case index > alen:
		for i := 0; i < (index - alen); i++ {
			tb.array = append(tb.array, LNil)
		}
		tb.array = append(tb.array, value)
	case index < alen:
		tb.array[index] = value
	}
}

func (tb *LTable) RawSetH(key LValue, value LValue) {
	tb.dict[key] = value
}

func (tb *LTable) RawGet(key LValue) LValue {
	switch v := key.(type) {
	case LNumber:
		if isArrayKey(v) {
			index := int(v) - 1
			if index >= len(tb.array) {
				return LNil
			}
			return tb.array[index]
		}
	}
	if v, ok := tb.dict[key]; ok {
		return v
	}
	return LNil
}

func (tb *LTable) RawGetInt(key int) LValue {
	index := int(key) - 1
	if index >= len(tb.array) || index < 0 {
		return LNil
	}
	return tb.array[index]
}

func (tb *LTable) RawGetH(key LValue) LValue {
	if v, ok := tb.dict[key]; ok {
		return v
	}
	return LNil
}

func (tb *LTable) ForEach(cb func(LValue, LValue)) {
	for i, v := range tb.array {
		if v != LNil {
			cb(LNumber(i+1), v)
		}
	}
	for k, v := range tb.dict {
		if v != LNil {
			cb(k, v)
		}
	}
}

func (tb *LTable) Next(key LValue) (LValue, LValue) {
	// TODO: inefficient way
	if key == LNil {
		tb.keys = nil
		tb.k2i = nil
		key = LNumber(0)
	}

	if tb.keys == nil {
		tb.keys = make([]LValue, len(tb.dict))
		tb.k2i = make(map[LValue]int)
		i := 0
		for k, _ := range tb.dict {
			tb.keys[i] = k
			tb.k2i[k] = i
			i++
		}
	}

	if kv, ok := key.(LNumber); ok && isInteger(kv) && int(kv) >= 0 {
		index := int(kv)
		for ; index < len(tb.array); index++ {
			if v := tb.array[index]; v != LNil {
				return LNumber(index + 1), v
			}
		}
		if index == len(tb.array) {
			if len(tb.dict) == 0 {
				tb.keys = nil
				tb.k2i = nil
				return LNil, LNil
			}
			key = tb.keys[0]
			if v := tb.dict[key]; v != LNil {
				return key, v
			}
		}
	}
	for i := tb.k2i[key] + 1; i < len(tb.dict); i++ {
		key = tb.keys[i]
		if v := tb.dict[key]; v != LNil {
			return key, v
		}
	}
	tb.keys = nil
	tb.k2i = nil
	return LNil, LNil
}
<commit_msg>fixed MaxN bug<commit_after>package lua

type lValueArraySorter struct {
	L      *LState
	Fn     *LFunction
	Values []LValue
}

func (lv lValueArraySorter) Len() int {
	return len(lv.Values)
}

func (lv lValueArraySorter) Swap(i, j int) {
	lv.Values[i], lv.Values[j] = lv.Values[j], lv.Values[i]
}

func (lv lValueArraySorter) Less(i, j int) bool {
	if lv.Fn != nil {
		lv.L.Push(lv.Fn)
		lv.L.Push(lv.Values[i])
		lv.L.Push(lv.Values[j])
		lv.L.Call(2, 1)
		return LVAsBool(lv.L.reg.Pop())
	}
	return lessThan(lv.L, lv.Values[i], lv.Values[j])
}

func newLTable(acap int, hcap int) *LTable {
	if acap < 0 {
		acap = 0
	}
	if hcap < 0 {
		hcap = 0
	}
	tb := &LTable{
		array:     make([]LValue, 0, acap),
		dict:      make(map[LValue]LValue, hcap),
		keys:      nil,
		k2i:       nil,
		Metatable: LNil,
	}
	return tb
}

func (tb *LTable) Len() int {
	var prev LValue = LNil
	for i := len(tb.array) - 1; i >= 0; i-- {
		v := tb.array[i]
		if prev == LNil && v != LNil {
			return i + 1
		}
		prev = v
	}
	return 0
}

func (tb *LTable) Append(value LValue) {
	tb.array = append(tb.array, value)
}

func (tb *LTable) Insert(i int, value LValue) {
	if i > len(tb.array) {
		tb.RawSetInt(i, value)
		return
	}
	if i <= 0 {
		tb.RawSet(LNumber(i), value)
		return
	}
	i -= 1
	tb.array = append(tb.array, LNil)
	copy(tb.array[i+1:], tb.array[i:])
	tb.array[i] = value
}

func (tb *LTable) MaxN() int {
	for i := len(tb.array) - 1; i >= 0; i-- {
		if tb.array[i] != LNil {
			return i+1
		}
	}
	return 0
}

func (tb *LTable) Remove(pos int) {
	i := pos - 1
	larray := len(tb.array)
	switch {
	case i >= larray:
		return
	case i == larray-1 || i < 0:
		tb.array = tb.array[:larray-1]
	default:
		copy(tb.array[i:], tb.array[i+1:])
		tb.array[larray-1] = nil
		tb.array = tb.array[:larray-1]
	}
}

func (tb *LTable) RawSet(key LValue, value LValue) {
	switch v := key.(type) {
	case LNumber:
		if isArrayKey(v) {
			index := int(v) - 1
			alen := len(tb.array)
			switch {
			case index == alen:
				tb.array = append(tb.array, value)
			case index > alen:
				for i := 0; i < (index - alen); i++ {
					tb.array = append(tb.array, LNil)
				}
				tb.array = append(tb.array, value)
			case index < alen:
				tb.array[index] = value
			}
			return
		}
	}
	tb.dict[key] = value
}

func (tb *LTable) RawSetInt(key int, value LValue) {
	if key < 1 || key >= MaxArrayIndex {
		tb.dict[LNumber(key)] = value
		return
	}
	index := key - 1
	alen := len(tb.array)
	switch {
	case index == alen:
		tb.array = append(tb.array, value)
	case index > alen:
		for i := 0; i < (index - alen); i++ {
			tb.array = append(tb.array, LNil)
		}
		tb.array = append(tb.array, value)
	case index < alen:
		tb.array[index] = value
	}
}

func (tb *LTable) RawSetH(key LValue, value LValue) {
	tb.dict[key] = value
}

func (tb *LTable) RawGet(key LValue) LValue {
	switch v := key.(type) {
	case LNumber:
		if isArrayKey(v) {
			index := int(v) - 1
			if index >= len(tb.array) {
				return LNil
			}
			return tb.array[index]
		}
	}
	if v, ok := tb.dict[key]; ok {
		return v
	}
	return LNil
}

func (tb *LTable) RawGetInt(key int) LValue {
	index := int(key) - 1
	if index >= len(tb.array) || index < 0 {
		return LNil
	}
	return tb.array[index]
}

func (tb *LTable) RawGetH(key LValue) LValue {
	if v, ok := tb.dict[key]; ok {
		return v
	}
	return LNil
}

func (tb *LTable) ForEach(cb func(LValue, LValue)) {
	for i, v := range tb.array {
		if v != LNil {
			cb(LNumber(i+1), v)
		}
	}
	for k, v := range tb.dict {
		if v != LNil {
			cb(k, v)
		}
	}
}

func (tb *LTable) Next(key LValue) (LValue, LValue) {
	// TODO: inefficient way
	if key == LNil {
		tb.keys = nil
		tb.k2i = nil
		key = LNumber(0)
	}

	if tb.keys == nil {
		tb.keys = make([]LValue, len(tb.dict))
		tb.k2i = make(map[LValue]int)
		i := 0
		for k, _ := range tb.dict {
			tb.keys[i] = k
			tb.k2i[k] = i
			i++
		}
	}

	if kv, ok := key.(LNumber); ok && isInteger(kv) && int(kv) >= 0 {
		index := int(kv)
		for ; index < len(tb.array); index++ {
			if v := tb.array[index]; v != LNil {
				return LNumber(index + 1), v
			}
		}
		if index == len(tb.array) {
			if len(tb.dict) == 0 {
				tb.keys = nil
				tb.k2i = nil
				return LNil, LNil
			}
			key = tb.keys[0]
			if v := tb.dict[key]; v != LNil {
				return key, v
			}
		}
	}
	for i := tb.k2i[key] + 1; i < len(tb.dict); i++ {
		key = tb.keys[i]
		if v := tb.dict[key]; v != LNil {
			return key, v
		}
	}
	tb.keys = nil
	tb.k2i = nil
	return LNil, LNil
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/servicequotas"
	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceAwsServiceQuotasServiceQuota() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsServiceQuotasServiceQuotaCreate,
		Read:   resourceAwsServiceQuotasServiceQuotaRead,
		Update: resourceAwsServiceQuotasServiceQuotaUpdate,
		Delete: schema.Noop,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"adjustable": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"default_value": {
				Type:     schema.TypeFloat,
				Computed: true,
			},
			"quota_code": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"quota_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"request_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"request_status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"service_code": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"service_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"value": {
				Type:     schema.TypeFloat,
				Required: true,
			},
		},
	}
}

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

	quotaCode := d.Get("quota_code").(string)
	serviceCode := d.Get("service_code").(string)
	value := d.Get("value").(float64)

	d.SetId(fmt.Sprintf("%s/%s", serviceCode, quotaCode))

	input := &servicequotas.GetServiceQuotaInput{
		QuotaCode:   aws.String(quotaCode),
		ServiceCode: aws.String(serviceCode),
	}

	output, err := conn.GetServiceQuota(input)

	if err != nil {
		return fmt.Errorf("error getting Service Quotas Service Quota (%s): %s", d.Id(), err)
	}

	if output == nil {
		return fmt.Errorf("error getting Service Quotas Service Quota (%s): empty result", d.Id())
	}

	if value > aws.Float64Value(output.Quota.Value) {
		input := &servicequotas.RequestServiceQuotaIncreaseInput{
			DesiredValue: aws.Float64(value),
			QuotaCode:    aws.String(quotaCode),
			ServiceCode:  aws.String(serviceCode),
		}

		output, err := conn.RequestServiceQuotaIncrease(input)

		if err != nil {
			return fmt.Errorf("error requesting Service Quota (%s) increase: %s", d.Id(), err)
		}

		if output == nil || output.RequestedQuota == nil {
			return fmt.Errorf("error requesting Service Quota (%s) increase: empty result", d.Id())
		}

		d.Set("request_id", output.RequestedQuota.Id)
	}

	return resourceAwsServiceQuotasServiceQuotaRead(d, meta)
}

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

	serviceCode, quotaCode, err := resourceAwsServiceQuotasServiceQuotaParseID(d.Id())

	if err != nil {
		return err
	}

	input := &servicequotas.GetServiceQuotaInput{
		QuotaCode:   aws.String(quotaCode),
		ServiceCode: aws.String(serviceCode),
	}

	output, err := conn.GetServiceQuota(input)

	if err != nil {
		return fmt.Errorf("error getting Service Quotas Service Quota (%s): %s", d.Id(), err)
	}

	if output == nil {
		return fmt.Errorf("error getting Service Quotas Service Quota (%s): empty result", d.Id())
	}

	defaultInput := &servicequotas.GetAWSDefaultServiceQuotaInput{
		QuotaCode:   aws.String(quotaCode),
		ServiceCode: aws.String(serviceCode),
	}

	defaultOutput, err := conn.GetAWSDefaultServiceQuota(defaultInput)

	if err != nil {
		return fmt.Errorf("error getting Service Quotas Default Service Quota (%s): %s", d.Id(), err)
	}

	if defaultOutput == nil {
		return fmt.Errorf("error getting Service Quotas Default Service Quota (%s): empty result", d.Id())
	}

	d.Set("adjustable", output.Quota.Adjustable)
	d.Set("arn", output.Quota.QuotaArn)
	d.Set("default_value", defaultOutput.Quota.Value)
	d.Set("quota_code", output.Quota.QuotaCode)
	d.Set("quota_name", output.Quota.QuotaName)
	d.Set("service_code", output.Quota.ServiceCode)
	d.Set("service_name", output.Quota.ServiceName)
	d.Set("value", output.Quota.Value)

	requestID := d.Get("request_id").(string)

	if requestID != "" {
		input := &servicequotas.GetRequestedServiceQuotaChangeInput{
			RequestId: aws.String(requestID),
		}

		output, err := conn.GetRequestedServiceQuotaChange(input)

		if isAWSErr(err, servicequotas.ErrCodeNoSuchResourceException, "") {
			d.Set("request_id", "")
			d.Set("request_status", "")
			return nil
		}

		if err != nil {
			return fmt.Errorf("error getting Service Quotas Requested Service Quota Change (%s): %s", requestID, err)
		}

		if output == nil || output.RequestedQuota == nil {
			return fmt.Errorf("error getting Service Quotas Requested Service Quota Change (%s): empty result", requestID)
		}

		requestStatus := aws.StringValue(output.RequestedQuota.Status)
		d.Set("request_status", requestStatus)

		switch requestStatus {
		case servicequotas.RequestStatusApproved, servicequotas.RequestStatusCaseClosed, servicequotas.RequestStatusDenied:
			d.Set("request_id", "")
		case servicequotas.RequestStatusCaseOpened, servicequotas.RequestStatusPending:
			d.Set("value", output.RequestedQuota.DesiredValue)
		}
	}

	return nil
}

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

	value := d.Get("value").(float64)
	serviceCode, quotaCode, err := resourceAwsServiceQuotasServiceQuotaParseID(d.Id())

	if err != nil {
		return err
	}

	input := &servicequotas.RequestServiceQuotaIncreaseInput{
		DesiredValue: aws.Float64(value),
		QuotaCode:    aws.String(quotaCode),
		ServiceCode:  aws.String(serviceCode),
	}

	output, err := conn.RequestServiceQuotaIncrease(input)

	if err != nil {
		return fmt.Errorf("error requesting Service Quota (%s) increase: %s", d.Id(), err)
	}

	if output == nil || output.RequestedQuota == nil {
		return fmt.Errorf("error requesting Service Quota (%s) increase: empty result", d.Id())
	}

	d.Set("request_id", output.RequestedQuota.Id)

	return resourceAwsServiceQuotasServiceQuotaRead(d, meta)
}

func resourceAwsServiceQuotasServiceQuotaParseID(id string) (string, string, error) {
	parts := strings.SplitN(id, "/", 2)

	if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
		return "", "", fmt.Errorf("unexpected format of ID (%s), expected SERVICE-CODE/QUOTA-CODE", id)
	}

	return parts[0], parts[1], nil
}
<commit_msg>resource/aws_servicequotas_service_quota: Remove resource from Terraform state on NoSuchResourceException error (#10735)<commit_after>package aws

import (
	"fmt"
	"log"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/servicequotas"
	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceAwsServiceQuotasServiceQuota() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsServiceQuotasServiceQuotaCreate,
		Read:   resourceAwsServiceQuotasServiceQuotaRead,
		Update: resourceAwsServiceQuotasServiceQuotaUpdate,
		Delete: schema.Noop,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"adjustable": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"default_value": {
				Type:     schema.TypeFloat,
				Computed: true,
			},
			"quota_code": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"quota_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"request_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"request_status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"service_code": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"service_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"value": {
				Type:     schema.TypeFloat,
				Required: true,
			},
		},
	}
}

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

	quotaCode := d.Get("quota_code").(string)
	serviceCode := d.Get("service_code").(string)
	value := d.Get("value").(float64)

	d.SetId(fmt.Sprintf("%s/%s", serviceCode, quotaCode))

	input := &servicequotas.GetServiceQuotaInput{
		QuotaCode:   aws.String(quotaCode),
		ServiceCode: aws.String(serviceCode),
	}

	output, err := conn.GetServiceQuota(input)

	if err != nil {
		return fmt.Errorf("error getting Service Quotas Service Quota (%s): %s", d.Id(), err)
	}

	if output == nil {
		return fmt.Errorf("error getting Service Quotas Service Quota (%s): empty result", d.Id())
	}

	if value > aws.Float64Value(output.Quota.Value) {
		input := &servicequotas.RequestServiceQuotaIncreaseInput{
			DesiredValue: aws.Float64(value),
			QuotaCode:    aws.String(quotaCode),
			ServiceCode:  aws.String(serviceCode),
		}

		output, err := conn.RequestServiceQuotaIncrease(input)

		if err != nil {
			return fmt.Errorf("error requesting Service Quota (%s) increase: %s", d.Id(), err)
		}

		if output == nil || output.RequestedQuota == nil {
			return fmt.Errorf("error requesting Service Quota (%s) increase: empty result", d.Id())
		}

		d.Set("request_id", output.RequestedQuota.Id)
	}

	return resourceAwsServiceQuotasServiceQuotaRead(d, meta)
}

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

	serviceCode, quotaCode, err := resourceAwsServiceQuotasServiceQuotaParseID(d.Id())

	if err != nil {
		return err
	}

	input := &servicequotas.GetServiceQuotaInput{
		QuotaCode:   aws.String(quotaCode),
		ServiceCode: aws.String(serviceCode),
	}

	output, err := conn.GetServiceQuota(input)

	if isAWSErr(err, servicequotas.ErrCodeNoSuchResourceException, "") {
		log.Printf("[WARN] Service Quotas Service Quota (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("error getting Service Quotas Service Quota (%s): %s", d.Id(), err)
	}

	if output == nil {
		return fmt.Errorf("error getting Service Quotas Service Quota (%s): empty result", d.Id())
	}

	defaultInput := &servicequotas.GetAWSDefaultServiceQuotaInput{
		QuotaCode:   aws.String(quotaCode),
		ServiceCode: aws.String(serviceCode),
	}

	defaultOutput, err := conn.GetAWSDefaultServiceQuota(defaultInput)

	if err != nil {
		return fmt.Errorf("error getting Service Quotas Default Service Quota (%s): %s", d.Id(), err)
	}

	if defaultOutput == nil {
		return fmt.Errorf("error getting Service Quotas Default Service Quota (%s): empty result", d.Id())
	}

	d.Set("adjustable", output.Quota.Adjustable)
	d.Set("arn", output.Quota.QuotaArn)
	d.Set("default_value", defaultOutput.Quota.Value)
	d.Set("quota_code", output.Quota.QuotaCode)
	d.Set("quota_name", output.Quota.QuotaName)
	d.Set("service_code", output.Quota.ServiceCode)
	d.Set("service_name", output.Quota.ServiceName)
	d.Set("value", output.Quota.Value)

	requestID := d.Get("request_id").(string)

	if requestID != "" {
		input := &servicequotas.GetRequestedServiceQuotaChangeInput{
			RequestId: aws.String(requestID),
		}

		output, err := conn.GetRequestedServiceQuotaChange(input)

		if isAWSErr(err, servicequotas.ErrCodeNoSuchResourceException, "") {
			d.Set("request_id", "")
			d.Set("request_status", "")
			return nil
		}

		if err != nil {
			return fmt.Errorf("error getting Service Quotas Requested Service Quota Change (%s): %s", requestID, err)
		}

		if output == nil || output.RequestedQuota == nil {
			return fmt.Errorf("error getting Service Quotas Requested Service Quota Change (%s): empty result", requestID)
		}

		requestStatus := aws.StringValue(output.RequestedQuota.Status)
		d.Set("request_status", requestStatus)

		switch requestStatus {
		case servicequotas.RequestStatusApproved, servicequotas.RequestStatusCaseClosed, servicequotas.RequestStatusDenied:
			d.Set("request_id", "")
		case servicequotas.RequestStatusCaseOpened, servicequotas.RequestStatusPending:
			d.Set("value", output.RequestedQuota.DesiredValue)
		}
	}

	return nil
}

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

	value := d.Get("value").(float64)
	serviceCode, quotaCode, err := resourceAwsServiceQuotasServiceQuotaParseID(d.Id())

	if err != nil {
		return err
	}

	input := &servicequotas.RequestServiceQuotaIncreaseInput{
		DesiredValue: aws.Float64(value),
		QuotaCode:    aws.String(quotaCode),
		ServiceCode:  aws.String(serviceCode),
	}

	output, err := conn.RequestServiceQuotaIncrease(input)

	if err != nil {
		return fmt.Errorf("error requesting Service Quota (%s) increase: %s", d.Id(), err)
	}

	if output == nil || output.RequestedQuota == nil {
		return fmt.Errorf("error requesting Service Quota (%s) increase: empty result", d.Id())
	}

	d.Set("request_id", output.RequestedQuota.Id)

	return resourceAwsServiceQuotasServiceQuotaRead(d, meta)
}

func resourceAwsServiceQuotasServiceQuotaParseID(id string) (string, string, error) {
	parts := strings.SplitN(id, "/", 2)

	if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
		return "", "", fmt.Errorf("unexpected format of ID (%s), expected SERVICE-CODE/QUOTA-CODE", id)
	}

	return parts[0], parts[1], nil
}
<|endoftext|>


<commit_before>// Copyright 2013 Travis Keep. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or
// at http://opensource.org/licenses/BSD-3-Clause.

// Package tasks handles tasks that can be started and stopped
package tasks

import (
  "github.com/keep94/gofunctional3/functional"
  "github.com/keep94/tasks/recurring"
  "sync"
  "time"
)

// Task represents any task
type Task interface {

  // Do performs the task. execution is the specific execution of this task.
  Do(execution *Execution) error
}

// TaskFunc wraps a simple function to implement Task.
type TaskFunc func(execution *Execution) error

func (f TaskFunc) Do(execution *Execution) error {
  return f(execution)
}

// Clock represents the system clock.
type Clock interface {

  // Now returns the current time
  Now() time.Time

  // After waits for given duration to elapse and then sends current time on the  // returned channel.
  After(d time.Duration) <-chan time.Time
}

// Execution represents a particular execution of some task.
type Execution struct {
  Clock
  ended chan struct{}
  err error
  lock sync.Mutex
}

// Run executes a task in the current goroutine and exits when the task
// finishes.
func Run(task Task) error {
  return runForTesting(task, systemClock{})
}

func runForTesting(task Task, clock Clock) (err error) {
  execution := &Execution{Clock: clock, ended: make(chan struct{})}
  execution.setError(task.Do(execution))
  execution.End()
  return execution.Error()
}

// Start starts a task in a separate goroutine and returns immediately.
// Start returns that particular execution of the task.
func Start(task Task) *Execution {
  execution := &Execution{Clock: systemClock{}, ended: make(chan struct{})}
  go func() {
    execution.setError(task.Do(execution))
    execution.End()
  }()
  return execution
}

// Error returns error from this execution. If called before this execution
// has ended, it returns nil.
func (e *Execution) Error() error {
  e.lock.Lock()
  defer e.lock.Unlock()
  return e.err
}

// End ends this execution.
func (e *Execution) End() {
  close(e.ended)
}

// Ended returns a channel that gets closed when this execution ends whether
// naturaly or because End was called on this execution.
func (e *Execution) Ended() <-chan struct{} {
  return e.ended
}

// IsEnded returns true if this execution has ended.
func (e *Execution) IsEnded() bool {
  select {
    case <-e.ended:
      return true
    default:
      return false
  }
  return false
}

// Sleep sleeps for the specified duration ends or until this execution ends,
// whichever comes first. Sleep returns true if this execution ended while
// sleeping or false otherwise. If execution ends while sleeping, Sleep may
// return before Duration d elapses.
func (e *Execution) Sleep(d time.Duration) bool {
  select {
    case <-e.ended:
      return true
    case <-e.After(d):
      return false
  }
  return false
}

func (e *Execution) setError(err error) {
  if err == nil {
    return
  }
  e.lock.Lock()
  defer e.lock.Unlock()
  e.err = err
}

// RecurringTask returns a task that does t at each time that r specifies.
// The returned task ends when there are no more times from r or if some
// error happens while executing one of the tasks.
func RecurringTask(t Task, r recurring.R) Task {
  return &recurringTask{t, r}
}

// ParallelTasks returns a task that performs all the passed in tasks in
// parallel.
func ParallelTasks(tasks ...Task) Task {
  return parallelTasks(tasks)
}

// SerialTasks returns a task that performs all the passed in tasks in
// series, one after the other.
func SerialTasks(tasks ...Task) Task {
  return serialTasks(tasks)
}

type recurringTask struct {
  t Task
  r recurring.R
}

func (rt *recurringTask) Do(e *Execution) (err error) {
  s := rt.r.ForTime(e.Now())
  defer s.Close()
  var t time.Time
  for err = s.Next(&t); err == nil; err = s.Next(&t) {
    dur := t.Sub(e.Now())
    if dur <= 0 {
      continue
    }
    if e.Sleep(dur) {
      return
    }
    if err = rt.t.Do(e); err != nil {
      return
    }
  }
  if err == functional.Done {
    err = nil
  }
  return
}

type parallelTasks []Task

func (p parallelTasks) Do(e *Execution) (err error) {
  var wg sync.WaitGroup
  wg.Add(len(p))
  for _, task := range p {
    go func(t Task) {
      e.setError(t.Do(e))
      wg.Done()
    }(task)
  }
  wg.Wait()
  return
}

type serialTasks []Task

func (s serialTasks) Do(e *Execution) (err error) {
  for _, task := range s {
    e.setError(task.Do(e))
  }
  e.End()
  return
}

type systemClock struct {
}

func (s systemClock) Now() time.Time {
  return time.Now()
}

func (s systemClock) After(d time.Duration) <-chan time.Time {
  return time.After(d)
}
<commit_msg>Fixed concurrency bug in Execution.End() where it was possible to close the ended channel twice.<commit_after>// Copyright 2013 Travis Keep. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or
// at http://opensource.org/licenses/BSD-3-Clause.

// Package tasks handles tasks that can be started and stopped
package tasks

import (
  "github.com/keep94/gofunctional3/functional"
  "github.com/keep94/tasks/recurring"
  "sync"
  "time"
)

// Task represents any task
type Task interface {

  // Do performs the task. execution is the specific execution of this task.
  Do(execution *Execution) error
}

// TaskFunc wraps a simple function to implement Task.
type TaskFunc func(execution *Execution) error

func (f TaskFunc) Do(execution *Execution) error {
  return f(execution)
}

// Clock represents the system clock.
type Clock interface {

  // Now returns the current time
  Now() time.Time

  // After waits for given duration to elapse and then sends current time on the  // returned channel.
  After(d time.Duration) <-chan time.Time
}

// Execution represents a particular execution of some task.
type Execution struct {
  Clock
  ended chan struct{}
  bEnded bool
  err error
  lock sync.Mutex
}

// Run executes a task in the current goroutine and exits when the task
// finishes.
func Run(task Task) error {
  return runForTesting(task, systemClock{})
}

func runForTesting(task Task, clock Clock) (err error) {
  execution := &Execution{Clock: clock, ended: make(chan struct{})}
  execution.setError(task.Do(execution))
  execution.End()
  return execution.Error()
}

// Start starts a task in a separate goroutine and returns immediately.
// Start returns that particular execution of the task.
func Start(task Task) *Execution {
  execution := &Execution{Clock: systemClock{}, ended: make(chan struct{})}
  go func() {
    execution.setError(task.Do(execution))
    execution.End()
  }()
  return execution
}

// Error returns error from this execution. If called before this execution
// has ended, it returns nil.
func (e *Execution) Error() error {
  e.lock.Lock()
  defer e.lock.Unlock()
  return e.err
}

// End ends this execution.
func (e *Execution) End() {
  if e.markEnded() {
    close(e.ended)
  }
}

// Ended returns a channel that gets closed when this execution ends whether
// naturaly or because End was called on this execution.
func (e *Execution) Ended() <-chan struct{} {
  return e.ended
}

// IsEnded returns true if this execution has ended.
func (e *Execution) IsEnded() bool {
  e.lock.Lock()
  defer e.lock.Unlock()
  return e.bEnded
}

// Sleep sleeps for the specified duration ends or until this execution ends,
// whichever comes first. Sleep returns true if this execution ended while
// sleeping or false otherwise. If execution ends while sleeping, Sleep may
// return before Duration d elapses.
func (e *Execution) Sleep(d time.Duration) bool {
  select {
    case <-e.ended:
      return true
    case <-e.After(d):
      return false
  }
  return false
}

func (e *Execution) setError(err error) {
  if err == nil {
    return
  }
  e.lock.Lock()
  defer e.lock.Unlock()
  e.err = err
}

func (e *Execution) markEnded() bool {
  e.lock.Lock()
  defer e.lock.Unlock()
  result := !e.bEnded
  e.bEnded = true
  return result
}

// RecurringTask returns a task that does t at each time that r specifies.
// The returned task ends when there are no more times from r or if some
// error happens while executing one of the tasks.
func RecurringTask(t Task, r recurring.R) Task {
  return &recurringTask{t, r}
}

// ParallelTasks returns a task that performs all the passed in tasks in
// parallel.
func ParallelTasks(tasks ...Task) Task {
  return parallelTasks(tasks)
}

// SerialTasks returns a task that performs all the passed in tasks in
// series, one after the other.
func SerialTasks(tasks ...Task) Task {
  return serialTasks(tasks)
}

type recurringTask struct {
  t Task
  r recurring.R
}

func (rt *recurringTask) Do(e *Execution) (err error) {
  s := rt.r.ForTime(e.Now())
  defer s.Close()
  var t time.Time
  for err = s.Next(&t); err == nil; err = s.Next(&t) {
    dur := t.Sub(e.Now())
    if dur <= 0 {
      continue
    }
    if e.Sleep(dur) {
      return
    }
    if err = rt.t.Do(e); err != nil {
      return
    }
  }
  if err == functional.Done {
    err = nil
  }
  return
}

type parallelTasks []Task

func (p parallelTasks) Do(e *Execution) (err error) {
  var wg sync.WaitGroup
  wg.Add(len(p))
  for _, task := range p {
    go func(t Task) {
      e.setError(t.Do(e))
      wg.Done()
    }(task)
  }
  wg.Wait()
  return
}

type serialTasks []Task

func (s serialTasks) Do(e *Execution) (err error) {
  for _, task := range s {
    e.setError(task.Do(e))
  }
  e.End()
  return
}

type systemClock struct {
}

func (s systemClock) Now() time.Time {
  return time.Now()
}

func (s systemClock) After(d time.Duration) <-chan time.Time {
  return time.After(d)
}
<|endoftext|>


<commit_before>package vimeo

import (
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strings"
)

var _token string
var _url = "https://api.vimeo.com"

// Available APIs
var (
	Me = new(MeClient)
)

// Set access token
func SetToken(token string) {
	_token = token
}

// Set VIMEO_TOKEN to token in environment
func SetTokenFromEnv() error {
	_token = os.Getenv("VIMEO_TOKEN")
	if _token == "" {
		return errors.New("VIMEO_TOKEN is not set.")
	}
	return nil
}

// Query for Vimeo APIs (supported GET, POST, PUT, DELET)
func query(method, path string, values url.Values, v interface{}) error {
	var body io.Reader
	if method == "POST" || method == "PUT" {
		body = strings.NewReader(values.Encode())
	}

	req, err := http.NewRequest(method, _url+path, body)
	if err != nil {
		return err
	}

	switch method {
	case "GET", "DELETE":
		if values != nil {
			req.URL.RawQuery = values.Encode()
		}
	case "PUT", "POST":
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	}
	req.Header.Add("Authorization", "Bearer "+_token)

	cli := http.Client{}
	resp, err := cli.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	//TODO: check response code
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	return json.Unmarshal(b, v)
}
<commit_msg>Support patch method<commit_after>package vimeo

import (
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"strings"
)

var _token string
var _url = "https://api.vimeo.com"

// Available APIs
var (
	Me = new(MeClient)
)

// Set access token
func SetToken(token string) {
	_token = token
}

// Set VIMEO_TOKEN to token in environment
func SetTokenFromEnv() error {
	_token = os.Getenv("VIMEO_TOKEN")
	if _token == "" {
		return errors.New("VIMEO_TOKEN is not set.")
	}
	return nil
}

// Query for Vimeo APIs (supported GET, POST, PATCH, DELET)
// return ResponseCode, error
func query(method, path string, values url.Values, v interface{}) error {
	var body io.Reader
	if method == "POST" || method == "PATCH" || method == "PUT" {
		body = strings.NewReader(values.Encode())
	}

	req, err := http.NewRequest(method, _url+path, body)
	if err != nil {
		return err
	}

	switch method {
	case "GET", "DELETE":
		if values != nil {
			req.URL.RawQuery = values.Encode()
		}
	case "PATCH", "POST", "PUT":
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	}
	req.Header.Add("Authorization", "Bearer "+_token)

	cli := http.Client{}
	resp, err := cli.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	//TODO: check response code
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	return json.Unmarshal(b, v)
}
<|endoftext|>


<commit_before>package watcher

import (
	"expvar"

	"github.com/golang/glog"
	"gopkg.in/fsnotify.v1"
)

var (
	event_count = expvar.NewMap("log_watcher_event_count")
)

type LogWatcher struct {
	*fsnotify.Watcher
	events chan Event
	quit   chan struct{}
}

func NewLogWatcher() (w *LogWatcher, err error) {
	f, err := fsnotify.NewWatcher()
	if err != nil {
		return
	}
	w = &LogWatcher{f, make(chan Event), make(chan struct{})}
	go w.run()
	return
}

func (w *LogWatcher) Events() <-chan Event { return w.events }

func (w *LogWatcher) run() {
	for {
		select {
		case e, more := <-w.Watcher.Events:
			event_count.Add(e.Name, 1)
			glog.Infof("Writing %v", e)
			event := Event{Pathname: e.Name}
			switch {
			case e.Op&fsnotify.Create == fsnotify.Create:
				event.Type = Create
			case e.Op&fsnotify.Write == fsnotify.Write:
				event.Type = Update
			case e.Op&fsnotify.Remove == fsnotify.Remove:
				event.Type = Delete
			default:
				glog.Infof("Unexpected event type detected: %q", e)
			}
			w.events <- event
			if !more {
				goto end
			}
		case err := <-w.Errors:
			glog.Errorf("fsnotify error: %s\n", err)
		case <-w.quit:
			goto end
		}
	}
end:
	close(w.events)
}

func (w *LogWatcher) Close() err error {
	close(w.quit)
	return w.Watcher.Close()
}
<commit_msg>Fix typo.<commit_after>package watcher

import (
	"expvar"

	"github.com/golang/glog"
	"gopkg.in/fsnotify.v1"
)

var (
	event_count = expvar.NewMap("log_watcher_event_count")
)

type LogWatcher struct {
	*fsnotify.Watcher
	events chan Event
	quit   chan struct{}
}

func NewLogWatcher() (w *LogWatcher, err error) {
	f, err := fsnotify.NewWatcher()
	if err != nil {
		return
	}
	w = &LogWatcher{f, make(chan Event), make(chan struct{})}
	go w.run()
	return
}

func (w *LogWatcher) Events() <-chan Event { return w.events }

func (w *LogWatcher) run() {
	for {
		select {
		case e, more := <-w.Watcher.Events:
			event_count.Add(e.Name, 1)
			glog.Infof("Writing %v", e)
			event := Event{Pathname: e.Name}
			switch {
			case e.Op&fsnotify.Create == fsnotify.Create:
				event.Type = Create
			case e.Op&fsnotify.Write == fsnotify.Write:
				event.Type = Update
			case e.Op&fsnotify.Remove == fsnotify.Remove:
				event.Type = Delete
			default:
				glog.Infof("Unexpected event type detected: %q", e)
			}
			w.events <- event
			if !more {
				goto end
			}
		case err := <-w.Errors:
			glog.Errorf("fsnotify error: %s\n", err)
		case <-w.quit:
			goto end
		}
	}
end:
	close(w.events)
}

func (w *LogWatcher) Close() error {
	close(w.quit)
	return w.Watcher.Close()
}
<|endoftext|>


<commit_before>package waa

import (
	"unsafe"

	"github.com/go-ole/go-ole"
)

type IAccessible struct {
	ole.IDispatch
}

type IAccessibleVtbl struct {
	ole.IDispatchBtbl
	Get_accParent           uintptr
	Get_accChildCount       uintptr
	Get_accChild            uintptr
	Get_accName             uintptr
	Get_accValue            uintptr
	Get_accDescription      uintptr
	Get_accRole             uintptr
	Get_accState            uintptr
	Get_accHelp             uintptr
	Get_accHelpTopic        uintptr
	Get_accKeyboardShortcut uintptr
	Get_accFocus            uintptr
	Get_accSelection        uintptr
	Get_accDefaultAction    uintptr
	AccSelect               uintptr
	AccLocation             uintptr
	AccNavigate             uintptr
	AccHitTest              uintptr
	AccDoDefaultAction      uintptr
	Put_accName             uintptr
	Put_accValue            uintptr
}

func (v *IAccessible) VTable() *IAccessibleVtbl {
	return (*IAccessibleVtbl)(unsafe.Pointer(v.RawVTable))
}

func (v *IAccessible) Get_accParent() error {
	return nil
}

func (v *IAccessible) Get_accChildCount() error {
	return nil
}

func (v *IAccessible) Get_accChild() error {
	return nil
}

func (v *IAccessible) Get_accName() error {
	return nil
}

func (v *IAccessible) Get_accValue() error {
	return nil
}

func (v *IAccessible) Get_accDescription() error {
	return nil
}

func (v *IAccessible) Get_accRole() error {
	return nil
}

func (v *IAccessible) Get_accState() error {
	return nil
}

func (v *IAccessible) Get_accHelp() error {
	return nil
}

func (v *IAccessible) Get_accHelpTopic() error {
	return nil
}

func (v *IAccessible) Get_accKeyboardShortcut() error {
	return nil
}

func (v *IAccessible) Get_accFocus() error {
	return nil
}

func (v *IAccessible) Get_accSelection() error {
	return nil
}

func (v *IAccessible) Get_accDefaultAction() error {
	return nil
}

func (v *IAccessible) AccSelect() error {
	return nil
}

func (v *IAccessible) AccLocation() error {
	return nil
}

func (v *IAccessible) AccNavigate() error {
	return nil
}

func (v *IAccessible) AccHitTest() error {
	return nil
}

func (v *IAccessible) AccDoDefaultAction() error {
	return nil
}

func (v *IAccessible) Put_accName() error {
	return nil
}

func (v *IAccessible) Put_accValue() error {
	return nil
}
<commit_msg>Fix typo<commit_after>package waa

import (
	"unsafe"

	"github.com/go-ole/go-ole"
)

type IAccessible struct {
	ole.IDispatch
}

type IAccessibleVtbl struct {
	ole.IDispatchVtbl
	Get_accParent           uintptr
	Get_accChildCount       uintptr
	Get_accChild            uintptr
	Get_accName             uintptr
	Get_accValue            uintptr
	Get_accDescription      uintptr
	Get_accRole             uintptr
	Get_accState            uintptr
	Get_accHelp             uintptr
	Get_accHelpTopic        uintptr
	Get_accKeyboardShortcut uintptr
	Get_accFocus            uintptr
	Get_accSelection        uintptr
	Get_accDefaultAction    uintptr
	AccSelect               uintptr
	AccLocation             uintptr
	AccNavigate             uintptr
	AccHitTest              uintptr
	AccDoDefaultAction      uintptr
	Put_accName             uintptr
	Put_accValue            uintptr
}

func (v *IAccessible) VTable() *IAccessibleVtbl {
	return (*IAccessibleVtbl)(unsafe.Pointer(v.RawVTable))
}

func (v *IAccessible) Get_accParent() error {
	return nil
}

func (v *IAccessible) Get_accChildCount() error {
	return nil
}

func (v *IAccessible) Get_accChild() error {
	return nil
}

func (v *IAccessible) Get_accName() error {
	return nil
}

func (v *IAccessible) Get_accValue() error {
	return nil
}

func (v *IAccessible) Get_accDescription() error {
	return nil
}

func (v *IAccessible) Get_accRole() error {
	return nil
}

func (v *IAccessible) Get_accState() error {
	return nil
}

func (v *IAccessible) Get_accHelp() error {
	return nil
}

func (v *IAccessible) Get_accHelpTopic() error {
	return nil
}

func (v *IAccessible) Get_accKeyboardShortcut() error {
	return nil
}

func (v *IAccessible) Get_accFocus() error {
	return nil
}

func (v *IAccessible) Get_accSelection() error {
	return nil
}

func (v *IAccessible) Get_accDefaultAction() error {
	return nil
}

func (v *IAccessible) AccSelect() error {
	return nil
}

func (v *IAccessible) AccLocation() error {
	return nil
}

func (v *IAccessible) AccNavigate() error {
	return nil
}

func (v *IAccessible) AccHitTest() error {
	return nil
}

func (v *IAccessible) AccDoDefaultAction() error {
	return nil
}

func (v *IAccessible) Put_accName() error {
	return nil
}

func (v *IAccessible) Put_accValue() error {
	return nil
}
<|endoftext|>


<commit_before><commit_msg>[cv][poller] decouple task scheduling from running a Gerrit query.<commit_after><|endoftext|>


<commit_before>/* This example shows a scrolling menu similar to that found in the ncurses
 * examples from TLDP */

package main

import gc "code.google.com/p/goncurses"

const (
	HEIGHT = 10
	WIDTH  = 40
)

func main() {
	stdscr, _ := gc.Init()
	defer gc.End()

	gc.StartColor()
	gc.Raw(true)
	gc.Echo(false)
	gc.Cursor(0)
	stdscr.Keypad(true)
	gc.InitPair(1, gc.C_RED, gc.C_BLACK)
	gc.InitPair(2, gc.C_CYAN, gc.C_BLACK)

	// build the menu items
	menu_items := []string{
		"Choice 1",
		"Choice 2",
		"Choice 3",
		"Choice 4",
		"Choice 5",
		"Choice 6",
		"Choice 7",
		"Choice 8",
		"Choice 9",
		"Choice 10",
		"Exit"}
	items := make([]*gc.MenuItem, len(menu_items))
	for i, val := range menu_items {
		items[i], _ = gc.NewItem(val, "")
		defer items[i].Free()
	}

	// create the menu
	menu, _ := gc.NewMenu(items)
	defer menu.Free()

	menuwin, _ := gc.NewWindow(HEIGHT, WIDTH, 4, 14)
	menuwin.Keypad(true)

	menu.SetWindow(&menuwin)
	dwin := menuwin.Derived(6, 38, 3, 1)
	menu.SubWindow(&dwin)
	menu.Format(5, 1)
	menu.Mark(" * ")

	// Print centered menu title
	title := "My Menu"
	menuwin.Box(0, 0)
	menuwin.ColorOn(1)
	menuwin.Print(1, (WIDTH/2)-(len(title)/2), title)
	menuwin.ColorOff(1)
	menuwin.MoveAddChar(2, 0, gc.ACS_LTEE)
	menuwin.HLine(2, 1, gc.ACS_HLINE, WIDTH-2)
	menuwin.MoveAddChar(2, WIDTH-1, gc.ACS_RTEE)

	y, _ := stdscr.Maxyx()
	stdscr.ColorOn(2)
	stdscr.Print(y-3, 1,
		"Use up/down arrows or page up/down to navigate. 'q' to exit")
	stdscr.ColorOff(2)
	stdscr.Refresh()

	menu.Post()
	defer menu.UnPost()
	menuwin.Refresh()

	for {
		gc.Update()
		if ch := menuwin.GetChar(); ch == 'q' {
			return
		} else {
			menu.Driver(gc.DriverActions[ch])
		}
	}
}
<commit_msg>Update scroll menu example for MovePrint<commit_after>/* This example shows a scrolling menu similar to that found in the ncurses
 * examples from TLDP */

package main

import gc "code.google.com/p/goncurses"

const (
	HEIGHT = 10
	WIDTH  = 40
)

func main() {
	stdscr, _ := gc.Init()
	defer gc.End()

	gc.StartColor()
	gc.Raw(true)
	gc.Echo(false)
	gc.Cursor(0)
	stdscr.Keypad(true)
	gc.InitPair(1, gc.C_RED, gc.C_BLACK)
	gc.InitPair(2, gc.C_CYAN, gc.C_BLACK)

	// build the menu items
	menu_items := []string{
		"Choice 1",
		"Choice 2",
		"Choice 3",
		"Choice 4",
		"Choice 5",
		"Choice 6",
		"Choice 7",
		"Choice 8",
		"Choice 9",
		"Choice 10",
		"Exit"}
	items := make([]*gc.MenuItem, len(menu_items))
	for i, val := range menu_items {
		items[i], _ = gc.NewItem(val, "")
		defer items[i].Free()
	}

	// create the menu
	menu, _ := gc.NewMenu(items)
	defer menu.Free()

	menuwin, _ := gc.NewWindow(HEIGHT, WIDTH, 4, 14)
	menuwin.Keypad(true)

	menu.SetWindow(&menuwin)
	dwin := menuwin.Derived(6, 38, 3, 1)
	menu.SubWindow(&dwin)
	menu.Format(5, 1)
	menu.Mark(" * ")

	// Print centered menu title
	title := "My Menu"
	menuwin.Box(0, 0)
	menuwin.ColorOn(1)
	menuwin.MovePrint(1, (WIDTH/2)-(len(title)/2), title)
	menuwin.ColorOff(1)
	menuwin.MoveAddChar(2, 0, gc.ACS_LTEE)
	menuwin.HLine(2, 1, gc.ACS_HLINE, WIDTH-2)
	menuwin.MoveAddChar(2, WIDTH-1, gc.ACS_RTEE)

	y, _ := stdscr.Maxyx()
	stdscr.ColorOn(2)
	stdscr.MovePrint(y-3, 1,
		"Use up/down arrows or page up/down to navigate. 'q' to exit")
	stdscr.ColorOff(2)
	stdscr.Refresh()

	menu.Post()
	defer menu.UnPost()
	menuwin.Refresh()

	for {
		gc.Update()
		if ch := menuwin.GetChar(); ch == 'q' {
			return
		} else {
			menu.Driver(gc.DriverActions[ch])
		}
	}
}
<|endoftext|>


<commit_before>package flickr

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const (
	API_ENDPOINT = "https://api.flickr.com/services/rest"
)

// Generate a random string of 8 chars, needed for OAuth signature
func generateNonce() string {
	rand.Seed(time.Now().UTC().UnixNano())
	// For convenience, use a set of chars we don't need to url-escape
	var letters = []rune("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ")
	b := make([]rune, 8)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)
}

type FlickrClient struct {
	ApiKey           string
	ApiSecret        string
	HTTPClient       *http.Client
	EndpointUrl      string
	HTTPVerb         string
	Args             url.Values
	OAuthToken       string
	OAuthTokenSecret string
}

func NewFlickrClient(apiKey string, apiSecret string) *FlickrClient {
	return &FlickrClient{
		ApiKey:     apiKey,
		ApiSecret:  apiSecret,
		HTTPClient: &http.Client{},
		HTTPVerb:   "GET",
		Args:       url.Values{},
	}
}

// Sign the next request performed by the FlickrClient
func (c *FlickrClient) Sign(tokenSecret string) {
	// the "oauth_signature" param must not be included in the signing process
	c.Args.Del("oauth_signature")
	c.Args.Set("oauth_signature", c.getSignature(tokenSecret))
}

func (c *FlickrClient) GetUrl() string {
	return fmt.Sprintf("%s?%s", c.EndpointUrl, c.Args.Encode())
}

func (c *FlickrClient) ClearArgs() {
	c.Args = url.Values{}
}

// Set a default set of args needed for signing a request
func (c *FlickrClient) SetDefaultArgs() {
	c.Args = url.Values{}
	c.Args.Add("oauth_version", "1.0")
	c.Args.Add("oauth_signature_method", "HMAC-SHA1")
	c.Args.Add("oauth_nonce", generateNonce())
	c.Args.Add("oauth_timestamp", fmt.Sprintf("%d", time.Now().Unix()))
}

func (c *FlickrClient) getSigningBaseString() string {
	request_url := url.QueryEscape(c.EndpointUrl)
	query := url.QueryEscape(c.Args.Encode())

	return fmt.Sprintf("%s&%s&%s", c.HTTPVerb, request_url, query)
}

func (c *FlickrClient) getSignature(token_secret string) string {
	key := fmt.Sprintf("%s&%s", url.QueryEscape(c.ApiSecret), url.QueryEscape(token_secret))
	base_string := c.getSigningBaseString()

	mac := hmac.New(sha1.New, []byte(key))
	mac.Write([]byte(base_string))

	ret := base64.StdEncoding.EncodeToString(mac.Sum(nil))

	return ret
}

type FlickrResponse struct {
	XMLName xml.Name `xml:"rsp"`
	Status  string   `xml:"stat,attr"`
	Error   struct {
		XMLName xml.Name `xml:"err"`
		Code    int      `xml:"code,attr"`
		Message string   `xml:"msg,attr"`
	}
}

func (r *FlickrResponse) HasErrors() bool {
	return r.Status == "fail"
}

func (r *FlickrResponse) ErrorCode() int {
	return r.Error.Code
}

func (r *FlickrResponse) ErrorMsg() string {
	return r.Error.Message
}

type RequestToken struct {
	OauthCallbackConfirmed bool
	OauthToken             string
	OauthTokenSecret       string
}

func NewRequestToken(response string) (*RequestToken, error) {
	// TODO parse flickr errors inside the body
	val, err := url.ParseQuery(strings.TrimSpace(response))
	if err != nil {
		return nil, err
	}

	confirmed, _ := strconv.ParseBool(val.Get("oauth_callback_confirmed"))

	return &RequestToken{
		confirmed,
		val.Get("oauth_token"),
		val.Get("oauth_token_secret"),
	}, nil
}

type OAuthToken struct {
	OAuthToken       string
	OAuthTokenSecret string
	UserNsid         string
	Username         string
	Fullname         string
}

func NewOAuthToken(response string) (*OAuthToken, error) {
	// TODO parse flickr errors inside the body
	val, err := url.ParseQuery(strings.TrimSpace(response))
	if err != nil {
		return nil, err
	}

	return &OAuthToken{
		OAuthToken:       val.Get("oauth_token"),
		OAuthTokenSecret: val.Get("oauth_token_secret"),
		Fullname:         val.Get("fullname"),
		UserNsid:         val.Get("user_nsid"),
		Username:         val.Get("username"),
	}, nil
}

func GetRequestToken(client *FlickrClient) (*RequestToken, error) {
	client.EndpointUrl = "https://www.flickr.com/services/oauth/request_token"
	client.SetDefaultArgs()
	client.Args.Set("oauth_consumer_key", client.ApiKey)
	client.Args.Set("oauth_callback", "oob")

	// we don't have token secret at this stage, pass an empty string
	client.Sign("")

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	return NewRequestToken(string(body))
}

func GetAuthorizeUrl(client *FlickrClient, reqToken *RequestToken) (string, error) {
	client.EndpointUrl = "https://www.flickr.com/services/oauth/authorize"
	client.Args = url.Values{}
	client.Args.Set("oauth_token", reqToken.OauthToken)
	client.Args.Set("perms", "delete")

	return client.GetUrl(), nil
}

func GetAccessToken(client *FlickrClient, reqToken *RequestToken, oauthVerifier string) (*OAuthToken, error) {
	client.EndpointUrl = "https://www.flickr.com/services/oauth/access_token"
	client.SetDefaultArgs()
	client.Args.Set("oauth_verifier", oauthVerifier)
	client.Args.Set("oauth_consumer_key", client.ApiKey)
	client.Args.Set("oauth_token", reqToken.OauthToken)
	// use the request token for signing
	client.Sign(reqToken.OauthTokenSecret)

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	return NewOAuthToken(string(body))
}
<commit_msg>more docs<commit_after>package flickr

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

const (
	API_ENDPOINT      = "https://api.flickr.com/services/rest"
	AUTHORIZE_URL     = "https://www.flickr.com/services/oauth/authorize"
	REQUEST_TOKEN_URL = "https://www.flickr.com/services/oauth/request_token"
	ACCESS_TOKEN_URL  = "https://www.flickr.com/services/oauth/access_token"
)

// Generate a random string of 8 chars, needed for OAuth signature
func generateNonce() string {
	rand.Seed(time.Now().UTC().UnixNano())
	// For convenience, use a set of chars we don't need to url-escape
	var letters = []rune("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ")
	b := make([]rune, 8)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)
}

// An utility type to wrap all resources and data needed to complete requests
// to the Flickr API
type FlickrClient struct {
	// Flickr application api key
	ApiKey string
	// Flickr application api secret
	ApiSecret string
	// A generic HTTP client to perform GET and POST requests
	HTTPClient *http.Client
	// The base url for API endpoints
	EndpointUrl string
	// A string containing POST or GET, needed for OAuth signing
	HTTPVerb string
	// A set of url params to query the API
	Args url.Values
	// User access token
	OAuthToken string
	// User secret token
	OAuthTokenSecret string
}

// Create a Flickr client, apiKey and apiSecret are mandatory
func NewFlickrClient(apiKey string, apiSecret string) *FlickrClient {
	return &FlickrClient{
		ApiKey:     apiKey,
		ApiSecret:  apiSecret,
		HTTPClient: &http.Client{},
		HTTPVerb:   "GET",
		Args:       url.Values{},
	}
}

// Sign the next request performed by the FlickrClient
func (c *FlickrClient) Sign(tokenSecret string) {
	// the "oauth_signature" param must not be included in the signing process
	c.Args.Del("oauth_signature")
	c.Args.Set("oauth_signature", c.getSignature(tokenSecret))
}

// Evaluate the complete URL to make requests (base url + params)
func (c *FlickrClient) GetUrl() string {
	return fmt.Sprintf("%s?%s", c.EndpointUrl, c.Args.Encode())
}

// Remove all query params
func (c *FlickrClient) ClearArgs() {
	c.Args = url.Values{}
}

// Set a default set of args needed for signing a request
func (c *FlickrClient) SetDefaultArgs() {
	c.Args = url.Values{}
	c.Args.Add("oauth_version", "1.0")
	c.Args.Add("oauth_signature_method", "HMAC-SHA1")
	c.Args.Add("oauth_nonce", generateNonce())
	c.Args.Add("oauth_timestamp", fmt.Sprintf("%d", time.Now().Unix()))
}

// Get the base string to compose the signature
func (c *FlickrClient) getSigningBaseString() string {
	request_url := url.QueryEscape(c.EndpointUrl)
	query := url.QueryEscape(c.Args.Encode())

	return fmt.Sprintf("%s&%s&%s", c.HTTPVerb, request_url, query)
}

// Compute the signature of a signed request
func (c *FlickrClient) getSignature(token_secret string) string {
	key := fmt.Sprintf("%s&%s", url.QueryEscape(c.ApiSecret), url.QueryEscape(token_secret))
	base_string := c.getSigningBaseString()

	mac := hmac.New(sha1.New, []byte(key))
	mac.Write([]byte(base_string))

	ret := base64.StdEncoding.EncodeToString(mac.Sum(nil))

	return ret
}

// Base type representing responses from Flickr API
type FlickrResponse struct {
	XMLName xml.Name `xml:"rsp"`
	// Status might contain "err" or "ok" strings
	Status string `xml:"stat,attr"`
	// Flickr API error detail
	Error struct {
		XMLName xml.Name `xml:"err"`
		Code    int      `xml:"code,attr"`
		Message string   `xml:"msg,attr"`
	}
}

// Return whether a response contains errors
func (r *FlickrResponse) HasErrors() bool {
	return r.Status == "fail"
}

// Return the error code (0 if no errors)
func (r *FlickrResponse) ErrorCode() int {
	return r.Error.Code
}

// Return error message string (empty string if no errors)
func (r *FlickrResponse) ErrorMsg() string {
	return r.Error.Message
}

// Type representing a request token during the exchange process
type RequestToken struct {
	OauthCallbackConfirmed bool
	OauthToken             string
	OauthTokenSecret       string
}

func NewRequestToken(response string) (*RequestToken, error) {
	// TODO parse flickr errors inside the body
	val, err := url.ParseQuery(strings.TrimSpace(response))
	if err != nil {
		return nil, err
	}

	confirmed, _ := strconv.ParseBool(val.Get("oauth_callback_confirmed"))

	return &RequestToken{
		confirmed,
		val.Get("oauth_token"),
		val.Get("oauth_token_secret"),
	}, nil
}

type OAuthToken struct {
	OAuthToken       string
	OAuthTokenSecret string
	UserNsid         string
	Username         string
	Fullname         string
}

func NewOAuthToken(response string) (*OAuthToken, error) {
	// TODO parse flickr errors inside the body
	val, err := url.ParseQuery(strings.TrimSpace(response))
	if err != nil {
		return nil, err
	}

	return &OAuthToken{
		OAuthToken:       val.Get("oauth_token"),
		OAuthTokenSecret: val.Get("oauth_token_secret"),
		Fullname:         val.Get("fullname"),
		UserNsid:         val.Get("user_nsid"),
		Username:         val.Get("username"),
	}, nil
}

func GetRequestToken(client *FlickrClient) (*RequestToken, error) {
	client.EndpointUrl = REQUEST_TOKEN_URL
	client.SetDefaultArgs()
	client.Args.Set("oauth_consumer_key", client.ApiKey)
	client.Args.Set("oauth_callback", "oob")

	// we don't have token secret at this stage, pass an empty string
	client.Sign("")

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	return NewRequestToken(string(body))
}

func GetAuthorizeUrl(client *FlickrClient, reqToken *RequestToken) (string, error) {
	client.EndpointUrl = AUTHORIZE_URL
	client.Args = url.Values{}
	client.Args.Set("oauth_token", reqToken.OauthToken)
	client.Args.Set("perms", "delete")

	return client.GetUrl(), nil
}

func GetAccessToken(client *FlickrClient, reqToken *RequestToken, oauthVerifier string) (*OAuthToken, error) {
	client.EndpointUrl = ACCESS_TOKEN_URL
	client.SetDefaultArgs()
	client.Args.Set("oauth_verifier", oauthVerifier)
	client.Args.Set("oauth_consumer_key", client.ApiKey)
	client.Args.Set("oauth_token", reqToken.OauthToken)
	// use the request token for signing
	client.Sign(reqToken.OauthTokenSecret)

	res, err := client.HTTPClient.Get(client.GetUrl())
	if err != nil {
		return nil, err
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	return NewOAuthToken(string(body))
}
<|endoftext|>


<commit_before>package auth

import "net/http"

type NoopReader struct{}

func (NoopReader) GetTeam(r *http.Request) (string, int, bool, bool) { return "", 0, false, false }
<commit_msg>Revert "Add in NoopReader to prevent body being read"<commit_after><|endoftext|>


<commit_before>package questagbot

import (
	"bytes"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"strconv"

	"golang.org/x/net/context"

	martini "github.com/codegangsta/martini"
	binding "github.com/codegangsta/martini-contrib/binding"
	godotenv "github.com/joho/godotenv"
	appengine "google.golang.org/appengine"
	log "google.golang.org/appengine/log"
	urlfetch "google.golang.org/appengine/urlfetch"

	// hexapic "github.com/blan4/hexapic/core"
)

// Update struct from telegram Webhook API
type Update struct {
	ID      int         `json:"update_id"`
	Message MessageMeta `json:"message"`
}

// MessageMeta struct from telegram Webhook API
type MessageMeta struct {
	ID   int    `json:"message_id"`
	Date int    `json:"date"`
	Text string `json:"text"`
	From User   `json:"from"`
	Chat User   `json:"chat"`
}

// User struct from telegram Webhook API
type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Username  string `json:"username"`
}

func appEngine(c martini.Context, r *http.Request) {
	c.Map(appengine.NewContext(r))
}

func init() {
	godotenv.Load("secrets.env")
	apiURL := fmt.Sprintf("https://api.telegram.org/bot%v/", os.Getenv("TELEGRAM_KEY"))

	m := martini.Classic()
	m.Use(appEngine)
	m.Use(martini.Logger())
	m.Get("/", func() string {
		return "Hello world"
	})
	m.Post("/bothook", binding.Bind(Update{}), func(c context.Context, update Update) string {
		log.Infof(c, "%v", update)
		sendMessage(c, apiURL, update, "Hello")
		return strconv.Itoa(update.ID)
	})
	http.Handle("/", m)
}

func sendMessage(c context.Context, apiURL string, data Update, text string) {
	httpClient := urlfetch.Client(c)
	query := url.Values{}
	query.Set("text", "Hello")
	query.Add("chat_id", strconv.Itoa(data.Message.Chat.ID))
	url := apiURL + "sendMessage"
	log.Infof(c, "%v", url)
	r, err := http.NewRequest("POST", url, bytes.NewBufferString(query.Encode()))
	if err != nil {
		log.Criticalf(c, "%v", err)
	}
	r.Header.Add("Content-Length", strconv.Itoa(len(query.Encode())))
	resp, err := httpClient.Do(r)
	defer resp.Body.Close()
	if err != nil {
		log.Criticalf(c, "%v", err)
	}
	log.Infof(c, "%v", resp)
}
<commit_msg>send photo on each message<commit_after>package questagbot

import (
	"bytes"
	"fmt"
	"image"
	"image/jpeg"
	"io"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"strconv"

	"golang.org/x/net/context"

	hexapic "github.com/blan4/hexapic/core"
	martini "github.com/codegangsta/martini"
	binding "github.com/codegangsta/martini-contrib/binding"
	godotenv "github.com/joho/godotenv"
	appengine "google.golang.org/appengine"
	log "google.golang.org/appengine/log"
	urlfetch "google.golang.org/appengine/urlfetch"
)

// Update struct from telegram Webhook API
type Update struct {
	ID      int         `json:"update_id"`
	Message MessageMeta `json:"message"`
}

// MessageMeta struct from telegram Webhook API
type MessageMeta struct {
	ID   int    `json:"message_id"`
	Date int    `json:"date"`
	Text string `json:"text"`
	From User   `json:"from"`
	Chat User   `json:"chat"`
}

// User struct from telegram Webhook API
type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Username  string `json:"username"`
}

// GetID return id as string
func (user User) GetID() string {
	return strconv.Itoa(user.ID)
}

// ReplyKeyboardMarkup is a object represents a custom keyboard
type ReplyKeyboardMarkup struct {
	Keyboard        [][]string `json:"keyboard"`
	ResizeKeyboard  bool       `json:"resize_keyboard"`
	OneTimeKeyboard bool       `json:"one_time_keyboard"`
	Selective       bool       `json:"selective"`
}

// TextMessage is a object for sendMessage API method
type TextMessage struct {
	ChatID                int         `json:"chat_id"`
	Text                  string      `json:"text"`
	DisableWebPagePreview bool        `json:"disable_web_page_preview"`
	ReplyToMessageID      int         `json:"reply_to_message_id"`
	ReplyMarkup           interface{} `json:"reply_markup"`
}

// PhotoMessage is a object for sendPhoto API method
type PhotoMessage struct {
	ChatID           int         `json:"chat_id"`
	Photo            string      `json:"photo"`
	Caption          string      `json:"caption"`
	ReplyToMessageID int         `json:"reply_to_message_id"`
	ReplyMarkup      interface{} `json:"reply_markup"`
}

func appEngine(c martini.Context, r *http.Request) {
	c.Map(appengine.NewContext(r))
}

func init() {
	godotenv.Load("secrets.env")
	apiURL := fmt.Sprintf("https://api.telegram.org/bot%v/", os.Getenv("TELEGRAM_KEY"))

	m := martini.Classic()
	m.Use(appEngine)
	m.Use(martini.Logger())
	m.Get("/", func() string {
		return "Hello world"
	})
	m.Post("/bothook", binding.Bind(Update{}), func(c context.Context, update Update) string {
		log.Infof(c, "%v", update)
		//sendMessage(c, apiURL, update, "Hello")
		if err := sendChatAction(c, apiURL, update, "upload_photo"); err != nil {
			log.Criticalf(c, "Can't sendChatAction %v", err)
		}
		if err := sendPhoto(c, os.Getenv("INSTAGRAM_CLIENT_ID"), apiURL, update, "cat"); err != nil {
			log.Criticalf(c, "Can't sendPhoto %v", err)
		}
		return strconv.Itoa(update.ID)
	})
	http.Handle("/", m)
}

func sendMessage(c context.Context, apiURL string, data Update, text string) {
	httpClient := urlfetch.Client(c)
	query := url.Values{}
	query.Set("text", "Hello")
	query.Add("chat_id", strconv.Itoa(data.Message.Chat.ID))
	url := apiURL + "sendMessage"
	log.Infof(c, "%v", url)
	r, err := http.NewRequest("POST", url, bytes.NewBufferString(query.Encode()))
	if err != nil {
		log.Criticalf(c, "%v", err)
	}
	r.Header.Add("Content-Length", strconv.Itoa(len(query.Encode())))
	resp, err := httpClient.Do(r)
	defer resp.Body.Close()
	if err != nil {
		log.Criticalf(c, "%v", err)
	}
	log.Infof(c, "%v", resp)
}

func sendChatAction(c context.Context, apiURL string, data Update, action string) (err error) {
	httpClient := urlfetch.Client(c)
	query := url.Values{}
	query.Set("action", action)
	query.Add("chat_id", strconv.Itoa(data.Message.Chat.ID))
	url := apiURL + "sendChatAction"
	r, err := http.NewRequest("POST", url, bytes.NewBufferString(query.Encode()))
	if err != nil {
		return
	}
	r.Header.Add("Content-Length", strconv.Itoa(len(query.Encode())))
	resp, err := httpClient.Do(r)
	defer resp.Body.Close()
	log.Infof(c, "sendChatAction: %v %v", url, query.Encode())
	return
}

func sendPhoto(c context.Context, clientdID string, apiURL string, data Update, text string) (err error) {
	httpClient := urlfetch.Client(c)
	hexapicAPI := hexapic.NewSearchApi(clientdID, httpClient)
	hexapicAPI.Count = 4
	var (
		imageQuality = jpeg.Options{Quality: jpeg.DefaultQuality}
		b            bytes.Buffer
		fw           io.Writer
		imgs         []image.Image
	)
	w := multipart.NewWriter(&b)
	if fw, err = w.CreateFormField("chat_id"); err != nil {
		return
	}
	if _, err = fw.Write([]byte(data.Message.Chat.GetID())); err != nil {
		return
	}
	if fw, err = w.CreateFormField("caption"); err != nil {
		return
	}
	if _, err = fw.Write([]byte(text)); err != nil {
		return
	}
	if fw, err = w.CreateFormFile("photo", "image.jpg"); err != nil {
		return
	}
	imgs = hexapicAPI.SearchByTag("cat")
	img := hexapic.GenerateCollage(imgs, 2, 2)
	if err = jpeg.Encode(fw, img, &imageQuality); err != nil {
		return
	}
	w.Close()

	req, err := http.NewRequest("POST", apiURL+"sendPhoto", &b)
	if err != nil {
		return
	}
	req.Header.Set("Content-Type", w.FormDataContentType())
	req.Header.Add("Content-Length", strconv.Itoa(b.Len()))
	res, err := httpClient.Do(req)
	defer res.Body.Close()
	if err != nil {
		return
	}
	if res.StatusCode != http.StatusOK {
		err = fmt.Errorf("bad status: %s", res.Status)
	}
	return
}
<|endoftext|>


<commit_before>// Copyright 2016 The Cockroach 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 acceptance

import "testing"

func TestDockerFinagle(t *testing.T) {
	t.Skip("TODO(dt): #5951, #5928, and needs #5484")
	testDockerSuccess(t, "finagle", []string{"/bin/sh", "-c", finagle})
}

const finagle = `
set -e
openssl pkcs12 -export -in $PGSSLCERT -inkey $PGSSLKEY -out /client.p12 -name "Whatever" -password pass:
echo "CREATE DATABASE finagle_postgres_test" | psql
PGHOSTPORT=$PGHOST:$PGPORT USE_PG_SSL=1 RUN_PG_INTEGRATION_TESTS=1 PGUSER="root" PG_PKCS12=/client.p12 java -jar /finagle-postgres-tests.jar com.twitter.finagle.postgres.integration.IntegrationSpec
`
<commit_msg>Revert "acceptance: disable TestDockerFinagle"<commit_after>// Copyright 2016 The Cockroach 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 acceptance

import "testing"

func TestDockerFinagle(t *testing.T) {
	testDockerSuccess(t, "finagle", []string{"/bin/sh", "-c", finagle})
}

const finagle = `
set -e
openssl pkcs12 -export -in $PGSSLCERT -inkey $PGSSLKEY -out /client.p12 -name "Whatever" -password pass:
echo "CREATE DATABASE finagle_postgres_test" | psql
PGHOSTPORT=$PGHOST:$PGPORT USE_PG_SSL=1 RUN_PG_INTEGRATION_TESTS=1 PGUSER="root" PG_PKCS12=/client.p12 java -jar /finagle-postgres-tests.jar com.twitter.finagle.postgres.integration.IntegrationSpec
`
<|endoftext|>


<commit_before>package modules

import (
//"encoding/json"
)

type User struct {
	UserID    string `bson:"_id"`
	LoginName string
	Password  string
	UserName  string
}
<commit_msg>update<commit_after>package modules

import (
//"encoding/json"
)

type User struct {
	UserID    string `bson:"_id"`
	LoginName string
	Password  string
	UserName  string
	DepID     string
	RoleIDs   []string
}
<|endoftext|>


<commit_before>package main

import (
	badfmt "fmt"
	otherrand "math/rand"
    "path/to/different/rand"
	_ "os"
)

func main() {
	fmt.Println("Hello, playground")
}
<commit_msg>Format example.go and add package comment<commit_after>// Package main is an example package
package main

import (
	badfmt "fmt"
	otherrand "math/rand"
	_ "os"
	"path/to/different/rand"
)

func main() {
	fmt.Println("Hello, playground")
}
<|endoftext|>


<commit_before>//  Copyright (c) 2014 Couchbase, 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 (
	"io/ioutil"
	"os"
	"testing"
)

func TestOpenPIndex(t *testing.T) {
	pindex, err := OpenPIndex("fake", "not-a-bleve-file")
	if pindex != nil || err == nil {
		t.Errorf("expected OpenPIndex to fail on a bad file")
	}
}

func TestNewPIndex(t *testing.T) {
	emptyDir, _ := ioutil.TempDir("./tmp", "test")
	defer os.RemoveAll(emptyDir)

	pindex, err := NewPIndex("fake", PIndexPath(emptyDir, "fake"),
		[]byte{})
	if pindex == nil || err != nil {
		t.Errorf("expected NewPIndex to work")
	}
	close(pindex.Stream())

	pindex, err = NewPIndex("fake", PIndexPath(emptyDir, "fake"),
		[]byte("{}"))
	if pindex != nil || err == nil {
		t.Errorf("expected NewPIndex to fail with empty json map")
	}
}
<commit_msg>test NewPIndex with bad index mapping<commit_after>//  Copyright (c) 2014 Couchbase, 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 (
	"io/ioutil"
	"os"
	"testing"
)

func TestOpenPIndex(t *testing.T) {
	pindex, err := OpenPIndex("fake", "not-a-bleve-file")
	if pindex != nil || err == nil {
		t.Errorf("expected OpenPIndex to fail on a bad file")
	}
}

func TestNewPIndex(t *testing.T) {
	emptyDir, _ := ioutil.TempDir("./tmp", "test")
	defer os.RemoveAll(emptyDir)

	pindex, err := NewPIndex("fake", PIndexPath(emptyDir, "fake"),
		[]byte{})
	if pindex == nil || err != nil {
		t.Errorf("expected NewPIndex to work")
	}
	close(pindex.Stream())

	pindex, err = NewPIndex("fake", PIndexPath(emptyDir, "fake"),
		[]byte("{}"))
	if pindex != nil || err == nil {
		t.Errorf("expected NewPIndex to fail with empty json map")
	}

	pindex, err = NewPIndex("fake", PIndexPath(emptyDir, "fake"),
		[]byte("} hey this isn't json :-("))
	if pindex != nil || err == nil {
		t.Errorf("expected NewPIndex to fail with bad json")
	}
}
<|endoftext|>


<commit_before>package s3api

import (
	"fmt"
	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/s3api/s3_constants"
	"io/ioutil"
	"net/http"

	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/pb/iam_pb"
	xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
	"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
)

type Action string

type Iam interface {
	Check(f http.HandlerFunc, actions ...Action) http.HandlerFunc
}

type IdentityAccessManagement struct {
	identities []*Identity
	domain     string
}

type Identity struct {
	Name        string
	Credentials []*Credential
	Actions     []Action
}

type Credential struct {
	AccessKey string
	SecretKey string
}

func NewIdentityAccessManagement(option *S3ApiServerOption) *IdentityAccessManagement {
	iam := &IdentityAccessManagement{
		domain: option.DomainName,
	}
	if option.Config != "" {
		if err := iam.loadS3ApiConfigurationFromFile(option.Config); err != nil {
			glog.Fatalf("fail to load config file %s: %v", option.Config, err)
		}
	} else {
		if err := iam.loadS3ApiConfigurationFromFiler(option); err != nil {
			glog.Warningf("fail to load config: %v", err)
		}
	}
	return iam
}

func (iam *IdentityAccessManagement) loadS3ApiConfigurationFromFiler(option *S3ApiServerOption) error {
	content, err := filer.ReadContent(option.Filer, filer.IamConfigDirecotry, filer.IamIdentityFile)
	if err != nil {
		return fmt.Errorf("read S3 config: %v", err)
	}
	return iam.loadS3ApiConfigurationFromBytes(content)
}

func (iam *IdentityAccessManagement) loadS3ApiConfigurationFromFile(fileName string) error {
	content, readErr := ioutil.ReadFile(fileName)
	if readErr != nil {
		glog.Warningf("fail to read %s : %v", fileName, readErr)
		return fmt.Errorf("fail to read %s : %v", fileName, readErr)
	}
	return iam.loadS3ApiConfigurationFromBytes(content)
}

func (iam *IdentityAccessManagement) loadS3ApiConfigurationFromBytes(content []byte) error {
	s3ApiConfiguration := &iam_pb.S3ApiConfiguration{}
	if err := filer.ParseS3ConfigurationFromBytes(content, s3ApiConfiguration); err != nil {
		glog.Warningf("unmarshal error: %v", err)
		return fmt.Errorf("unmarshal error: %v", err)
	}
	if err := iam.loadS3ApiConfiguration(s3ApiConfiguration); err != nil {
		return err
	}
	return nil
}

func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3ApiConfiguration) error {
	var identities []*Identity
	for _, ident := range config.Identities {
		t := &Identity{
			Name:        ident.Name,
			Credentials: nil,
			Actions:     nil,
		}
		for _, action := range ident.Actions {
			t.Actions = append(t.Actions, Action(action))
		}
		for _, cred := range ident.Credentials {
			t.Credentials = append(t.Credentials, &Credential{
				AccessKey: cred.AccessKey,
				SecretKey: cred.SecretKey,
			})
		}
		identities = append(identities, t)
	}

	// atomically switch
	iam.identities = identities
	return nil
}

func (iam *IdentityAccessManagement) isEnabled() bool {

	return len(iam.identities) > 0
}

func (iam *IdentityAccessManagement) lookupByAccessKey(accessKey string) (identity *Identity, cred *Credential, found bool) {

	for _, ident := range iam.identities {
		for _, cred := range ident.Credentials {
			if cred.AccessKey == accessKey {
				return ident, cred, true
			}
		}
	}
	return nil, nil, false
}

func (iam *IdentityAccessManagement) lookupAnonymous() (identity *Identity, found bool) {

	for _, ident := range iam.identities {
		if ident.Name == "anonymous" {
			return ident, true
		}
	}
	return nil, false
}

func (iam *IdentityAccessManagement) Auth(f http.HandlerFunc, action Action) http.HandlerFunc {

	if !iam.isEnabled() {
		return f
	}

	return func(w http.ResponseWriter, r *http.Request) {
		identity, errCode := iam.authRequest(r, action)
		if errCode == s3err.ErrNone {
			if identity != nil && identity.Name != "" {
				r.Header.Set(xhttp.AmzIdentityId, identity.Name)
				if identity.isAdmin() {
					r.Header.Set(xhttp.AmzIsAdmin, "true")
				}
			}
			f(w, r)
			return
		}
		writeErrorResponse(w, errCode, r.URL)
	}
}

// check whether the request has valid access keys
func (iam *IdentityAccessManagement) authRequest(r *http.Request, action Action) (*Identity, s3err.ErrorCode) {
	var identity *Identity
	var s3Err s3err.ErrorCode
	var found bool
	switch getRequestAuthType(r) {
	case authTypeStreamingSigned:
		return identity, s3err.ErrNone
	case authTypeUnknown:
		glog.V(3).Infof("unknown auth type")
		return identity, s3err.ErrAccessDenied
	case authTypePresignedV2, authTypeSignedV2:
		glog.V(3).Infof("v2 auth type")
		identity, s3Err = iam.isReqAuthenticatedV2(r)
	case authTypeSigned, authTypePresigned:
		glog.V(3).Infof("v4 auth type")
		identity, s3Err = iam.reqSignatureV4Verify(r)
	case authTypePostPolicy:
		glog.V(3).Infof("post policy auth type")
		return identity, s3err.ErrNone
	case authTypeJWT:
		glog.V(3).Infof("jwt auth type")
		return identity, s3err.ErrNotImplemented
	case authTypeAnonymous:
		identity, found = iam.lookupAnonymous()
		if !found {
			return identity, s3err.ErrAccessDenied
		}
	default:
		return identity, s3err.ErrNotImplemented
	}

	if s3Err != s3err.ErrNone {
		return identity, s3Err
	}

	glog.V(3).Infof("user name: %v actions: %v", identity.Name, identity.Actions)

	bucket, _ := getBucketAndObject(r)

	if !identity.canDo(action, bucket) {
		return identity, s3err.ErrAccessDenied
	}

	return identity, s3err.ErrNone

}

func (iam *IdentityAccessManagement) authUser(r *http.Request) (*Identity, s3err.ErrorCode) {
	var identity *Identity
	var s3Err s3err.ErrorCode
	var found bool
	switch getRequestAuthType(r) {
	case authTypeStreamingSigned:
		return identity, s3err.ErrNone
	case authTypeUnknown:
		glog.V(3).Infof("unknown auth type")
		return identity, s3err.ErrAccessDenied
	case authTypePresignedV2, authTypeSignedV2:
		glog.V(3).Infof("v2 auth type")
		identity, s3Err = iam.isReqAuthenticatedV2(r)
	case authTypeSigned, authTypePresigned:
		glog.V(3).Infof("v4 auth type")
		identity, s3Err = iam.reqSignatureV4Verify(r)
	case authTypePostPolicy:
		glog.V(3).Infof("post policy auth type")
		return identity, s3err.ErrNone
	case authTypeJWT:
		glog.V(3).Infof("jwt auth type")
		return identity, s3err.ErrNotImplemented
	case authTypeAnonymous:
		identity, found = iam.lookupAnonymous()
		if !found {
			return identity, s3err.ErrAccessDenied
		}
	default:
		return identity, s3err.ErrNotImplemented
	}

	glog.V(3).Infof("auth error: %v", s3Err)
	if s3Err != s3err.ErrNone {
		return identity, s3Err
	}
	return identity, s3err.ErrNone
}

func (identity *Identity) canDo(action Action, bucket string) bool {
	if identity.isAdmin() {
		return true
	}
	for _, a := range identity.Actions {
		if a == action {
			return true
		}
	}
	if bucket == "" {
		return false
	}
	limitedByBucket := string(action) + ":" + bucket
	adminLimitedByBucket := s3_constants.ACTION_ADMIN + ":" + bucket
	for _, a := range identity.Actions {
		if string(a) == limitedByBucket {
			return true
		}
		if string(a) == adminLimitedByBucket {
			return true
		}
	}
	return false
}

func (identity *Identity) isAdmin() bool {
	for _, a := range identity.Actions {
		if a == "Admin" {
			return true
		}
	}
	return false
}
<commit_msg>auth use bucket wild cards<commit_after>package s3api

import (
	"fmt"
	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/pb/iam_pb"
	xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
	"github.com/chrislusf/seaweedfs/weed/s3api/s3_constants"
	"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
	"io/ioutil"
	"net/http"
	"strings"
)

type Action string

type Iam interface {
	Check(f http.HandlerFunc, actions ...Action) http.HandlerFunc
}

type IdentityAccessManagement struct {
	identities []*Identity
	domain     string
}

type Identity struct {
	Name        string
	Credentials []*Credential
	Actions     []Action
}

type Credential struct {
	AccessKey string
	SecretKey string
}

func NewIdentityAccessManagement(option *S3ApiServerOption) *IdentityAccessManagement {
	iam := &IdentityAccessManagement{
		domain: option.DomainName,
	}
	if option.Config != "" {
		if err := iam.loadS3ApiConfigurationFromFile(option.Config); err != nil {
			glog.Fatalf("fail to load config file %s: %v", option.Config, err)
		}
	} else {
		if err := iam.loadS3ApiConfigurationFromFiler(option); err != nil {
			glog.Warningf("fail to load config: %v", err)
		}
	}
	return iam
}

func (iam *IdentityAccessManagement) loadS3ApiConfigurationFromFiler(option *S3ApiServerOption) error {
	content, err := filer.ReadContent(option.Filer, filer.IamConfigDirecotry, filer.IamIdentityFile)
	if err != nil {
		return fmt.Errorf("read S3 config: %v", err)
	}
	return iam.loadS3ApiConfigurationFromBytes(content)
}

func (iam *IdentityAccessManagement) loadS3ApiConfigurationFromFile(fileName string) error {
	content, readErr := ioutil.ReadFile(fileName)
	if readErr != nil {
		glog.Warningf("fail to read %s : %v", fileName, readErr)
		return fmt.Errorf("fail to read %s : %v", fileName, readErr)
	}
	return iam.loadS3ApiConfigurationFromBytes(content)
}

func (iam *IdentityAccessManagement) loadS3ApiConfigurationFromBytes(content []byte) error {
	s3ApiConfiguration := &iam_pb.S3ApiConfiguration{}
	if err := filer.ParseS3ConfigurationFromBytes(content, s3ApiConfiguration); err != nil {
		glog.Warningf("unmarshal error: %v", err)
		return fmt.Errorf("unmarshal error: %v", err)
	}
	if err := iam.loadS3ApiConfiguration(s3ApiConfiguration); err != nil {
		return err
	}
	return nil
}

func (iam *IdentityAccessManagement) loadS3ApiConfiguration(config *iam_pb.S3ApiConfiguration) error {
	var identities []*Identity
	for _, ident := range config.Identities {
		t := &Identity{
			Name:        ident.Name,
			Credentials: nil,
			Actions:     nil,
		}
		for _, action := range ident.Actions {
			t.Actions = append(t.Actions, Action(action))
		}
		for _, cred := range ident.Credentials {
			t.Credentials = append(t.Credentials, &Credential{
				AccessKey: cred.AccessKey,
				SecretKey: cred.SecretKey,
			})
		}
		identities = append(identities, t)
	}

	// atomically switch
	iam.identities = identities
	return nil
}

func (iam *IdentityAccessManagement) isEnabled() bool {

	return len(iam.identities) > 0
}

func (iam *IdentityAccessManagement) lookupByAccessKey(accessKey string) (identity *Identity, cred *Credential, found bool) {

	for _, ident := range iam.identities {
		for _, cred := range ident.Credentials {
			if cred.AccessKey == accessKey {
				return ident, cred, true
			}
		}
	}
	return nil, nil, false
}

func (iam *IdentityAccessManagement) lookupAnonymous() (identity *Identity, found bool) {

	for _, ident := range iam.identities {
		if ident.Name == "anonymous" {
			return ident, true
		}
	}
	return nil, false
}

func (iam *IdentityAccessManagement) Auth(f http.HandlerFunc, action Action) http.HandlerFunc {

	if !iam.isEnabled() {
		return f
	}

	return func(w http.ResponseWriter, r *http.Request) {
		identity, errCode := iam.authRequest(r, action)
		if errCode == s3err.ErrNone {
			if identity != nil && identity.Name != "" {
				r.Header.Set(xhttp.AmzIdentityId, identity.Name)
				if identity.isAdmin() {
					r.Header.Set(xhttp.AmzIsAdmin, "true")
				}
			}
			f(w, r)
			return
		}
		writeErrorResponse(w, errCode, r.URL)
	}
}

// check whether the request has valid access keys
func (iam *IdentityAccessManagement) authRequest(r *http.Request, action Action) (*Identity, s3err.ErrorCode) {
	var identity *Identity
	var s3Err s3err.ErrorCode
	var found bool
	switch getRequestAuthType(r) {
	case authTypeStreamingSigned:
		return identity, s3err.ErrNone
	case authTypeUnknown:
		glog.V(3).Infof("unknown auth type")
		return identity, s3err.ErrAccessDenied
	case authTypePresignedV2, authTypeSignedV2:
		glog.V(3).Infof("v2 auth type")
		identity, s3Err = iam.isReqAuthenticatedV2(r)
	case authTypeSigned, authTypePresigned:
		glog.V(3).Infof("v4 auth type")
		identity, s3Err = iam.reqSignatureV4Verify(r)
	case authTypePostPolicy:
		glog.V(3).Infof("post policy auth type")
		return identity, s3err.ErrNone
	case authTypeJWT:
		glog.V(3).Infof("jwt auth type")
		return identity, s3err.ErrNotImplemented
	case authTypeAnonymous:
		identity, found = iam.lookupAnonymous()
		if !found {
			return identity, s3err.ErrAccessDenied
		}
	default:
		return identity, s3err.ErrNotImplemented
	}

	if s3Err != s3err.ErrNone {
		return identity, s3Err
	}

	glog.V(3).Infof("user name: %v actions: %v", identity.Name, identity.Actions)

	bucket, _ := getBucketAndObject(r)

	if !identity.canDo(action, bucket) {
		return identity, s3err.ErrAccessDenied
	}

	return identity, s3err.ErrNone

}

func (iam *IdentityAccessManagement) authUser(r *http.Request) (*Identity, s3err.ErrorCode) {
	var identity *Identity
	var s3Err s3err.ErrorCode
	var found bool
	switch getRequestAuthType(r) {
	case authTypeStreamingSigned:
		return identity, s3err.ErrNone
	case authTypeUnknown:
		glog.V(3).Infof("unknown auth type")
		return identity, s3err.ErrAccessDenied
	case authTypePresignedV2, authTypeSignedV2:
		glog.V(3).Infof("v2 auth type")
		identity, s3Err = iam.isReqAuthenticatedV2(r)
	case authTypeSigned, authTypePresigned:
		glog.V(3).Infof("v4 auth type")
		identity, s3Err = iam.reqSignatureV4Verify(r)
	case authTypePostPolicy:
		glog.V(3).Infof("post policy auth type")
		return identity, s3err.ErrNone
	case authTypeJWT:
		glog.V(3).Infof("jwt auth type")
		return identity, s3err.ErrNotImplemented
	case authTypeAnonymous:
		identity, found = iam.lookupAnonymous()
		if !found {
			return identity, s3err.ErrAccessDenied
		}
	default:
		return identity, s3err.ErrNotImplemented
	}

	glog.V(3).Infof("auth error: %v", s3Err)
	if s3Err != s3err.ErrNone {
		return identity, s3Err
	}
	return identity, s3err.ErrNone
}

func (identity *Identity) canDo(action Action, bucket string) bool {
	if identity.isAdmin() {
		return true
	}
	for _, a := range identity.Actions {
		if a == action {
			return true
		}
	}
	if bucket == "" {
		return false
	}
	limitedByBucket := string(action) + ":" + bucket
	adminLimitedByBucket := s3_constants.ACTION_ADMIN + ":" + bucket
	for _, a := range identity.Actions {
		act := string(a)
		if strings.HasSuffix(act, "*") {
			if strings.HasPrefix(limitedByBucket, act[:len(act)-1]) {
				return true
			}
			if strings.HasPrefix(adminLimitedByBucket, act[:len(act)-1]) {
				return true
			}
		} else {
			if act == limitedByBucket {
				return true
			}
			if act == adminLimitedByBucket {
				return true
			}
		}
	}
	return false
}

func (identity *Identity) isAdmin() bool {
	for _, a := range identity.Actions {
		if a == "Admin" {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/ligato/cn-infra/core"
	"github.com/ligato/cn-infra/flavors/local"
	prom "github.com/ligato/cn-infra/rpc/prometheus"
	"github.com/ligato/cn-infra/rpc/rest"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"math/rand"
	"time"
)

// *************************************************************************
// This example demonstrates the usage of prometheus plugin that allows
// to expose metrics.
//
// Default metrics are exposed at path /metrics on port specified for http plugin
// to access these metrics following command can be used:
//       curl localhost:9191/metrics
//
// There is also created custom metrics registry exposed accessible:
//       curl localhost:9191/custom
// ************************************************************************/

func main() {
	// Init close channel used to stop the example.
	exampleFinished := make(chan struct{}, 1)

	// Start Agent with ExamplePlugin, REST, prometheus plugin & FlavorLocal (reused cn-infra plugins).
	agent := local.NewAgent(local.WithPlugins(func(flavor *local.FlavorLocal) []*core.NamedPlugin {
		httpPlugin := &rest.Plugin{}

		rest.DeclareHTTPPortFlag("http")
		httpPlugDeps := *flavor.InfraDeps("http", local.WithConf())
		httpPlugin.Deps.Log = httpPlugDeps.Log
		httpPlugin.Deps.PluginConfig = httpPlugDeps.PluginConfig
		httpPlugin.Deps.PluginName = httpPlugDeps.PluginName

		prometheusPlugin := &prom.Plugin{}
		prometheusPlugin.Deps.PluginInfraDeps = *flavor.InfraDeps("prometheus")
		prometheusPlugin.Deps.HTTP = httpPlugin

		examplePlug := &ExamplePlugin{}
		examplePlug.Deps.PluginInfraDeps = *flavor.InfraDeps("prometheus-example")
		examplePlug.Deps.Prometheus = prometheusPlugin

		return []*core.NamedPlugin{
			{httpPlugin.PluginName, httpPlugin},
			{prometheusPlugin.PluginName, prometheusPlugin},
			{examplePlug.PluginName, examplePlug}}
	}))
	core.EventLoopWithInterrupt(agent, exampleFinished)
}

type Deps struct {
	local.PluginInfraDeps
	Prometheus prom.API
}

// ExamplePlugin demonstrates the usage of datasync API.
type ExamplePlugin struct {
	Deps

	temporaryCounter prometheus.Gauge
	counterVal       int

	gaugeVec *prometheus.GaugeVec
}

// Identifier of the custom registry
const customRegistry = "/custom"

const orderLabel = "order"

// Init creates metric registries and adds gauges
func (plugin *ExamplePlugin) Init() error {

	// add new metric to default registry (accessible at the path /metrics)
	//
	// the current value is returned by provided callback
	// created gauge is identified by tuple(namespace, subsystem, name) only the name field is mandatory
	// additional properties can be defined using labels - key-value pairs. They do not change over time for the given gauge.
	err := plugin.Prometheus.RegisterGaugeFunc(prom.DefaultRegistry, "ns", "sub", "gaugeOne",
		"this metrics represents randomly generated numbers", prometheus.Labels{"Property1": "ABC", "Property2": "DEF"}, func() float64 {
			return rand.Float64()
		})
	if err != nil {
		return err
	}

	// create new registry that will be exposed at /custom path
	err = plugin.Prometheus.NewRegistry(customRegistry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError})
	if err != nil {
		return err
	}

	// create gauge using prometheus API
	plugin.temporaryCounter = prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "Countdown",
		Help: "This gauge is decremented by 1 each second, once it reaches 0 the gauge is removed.",
	})
	plugin.counterVal = 60
	plugin.temporaryCounter.Set(float64(plugin.counterVal))

	// register created gauge to the custom registry
	err = plugin.Prometheus.Register(customRegistry, plugin.temporaryCounter)
	if err != nil {
		return err
	}

	// create gauge vector and register it
	plugin.gaugeVec = prometheus.NewGaugeVec(prometheus.GaugeOpts{
		Name:        "Vector",
		Help:        "This gauge groups multiple similar metrics.",
		ConstLabels: prometheus.Labels{"type": "vector", "answer": "42"},
	}, []string{orderLabel})
	err = plugin.Prometheus.Register(customRegistry, plugin.gaugeVec)

	return err

}

// AfterInit starts go routines that modifies metrics
func (plugin *ExamplePlugin) AfterInit() error {

	go plugin.decrementCounter()

	go plugin.addNewGaugesToVector()

	return nil
}

// Close cleanup resources allocated by plugin
func (plugin *ExamplePlugin) Close() error {
	return nil
}

func (plugin *ExamplePlugin) addNewGaugesToVector() {
	for i := 1; i < 10; i++ {
		// add gauge with given labels to the vector
		g, err := plugin.gaugeVec.GetMetricWith(prometheus.Labels{orderLabel: fmt.Sprint(i)})
		if err != nil {
			plugin.Log.Error(err)
		} else {
			g.Set(1)
		}
		time.Sleep(2 * time.Second)
	}

}

func (plugin *ExamplePlugin) decrementCounter() {
	for {
		select {
		case <-time.After(time.Second):
			if plugin.counterVal == 0 {
				// once the countdown reaches zero remove gauge from registry+
				plugin.Prometheus.Unregister(customRegistry, plugin.temporaryCounter)
				return
			}
			plugin.counterVal--
			plugin.temporaryCounter.Set(float64(plugin.counterVal))

		}
	}
}
<commit_msg>Add comment<commit_after>package main

import (
	"fmt"
	"github.com/ligato/cn-infra/core"
	"github.com/ligato/cn-infra/flavors/local"
	prom "github.com/ligato/cn-infra/rpc/prometheus"
	"github.com/ligato/cn-infra/rpc/rest"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"math/rand"
	"time"
)

// *************************************************************************
// This example demonstrates the usage of prometheus plugin that allows
// to expose metrics.
//
// Default metrics are exposed at path /metrics on port specified for http plugin
// to access these metrics following command can be used:
//       curl localhost:9191/metrics
//
// There is also created custom metrics registry exposed accessible:
//       curl localhost:9191/custom
// ************************************************************************/

func main() {
	// Init close channel used to stop the example.
	exampleFinished := make(chan struct{}, 1)

	// Start Agent with ExamplePlugin, REST, prometheus plugin & FlavorLocal (reused cn-infra plugins).
	agent := local.NewAgent(local.WithPlugins(func(flavor *local.FlavorLocal) []*core.NamedPlugin {
		httpPlugin := &rest.Plugin{}

		rest.DeclareHTTPPortFlag("http")
		httpPlugDeps := *flavor.InfraDeps("http", local.WithConf())
		httpPlugin.Deps.Log = httpPlugDeps.Log
		httpPlugin.Deps.PluginConfig = httpPlugDeps.PluginConfig
		httpPlugin.Deps.PluginName = httpPlugDeps.PluginName

		prometheusPlugin := &prom.Plugin{}
		prometheusPlugin.Deps.PluginInfraDeps = *flavor.InfraDeps("prometheus")
		prometheusPlugin.Deps.HTTP = httpPlugin

		examplePlug := &ExamplePlugin{}
		examplePlug.Deps.PluginInfraDeps = *flavor.InfraDeps("prometheus-example")
		examplePlug.Deps.Prometheus = prometheusPlugin

		return []*core.NamedPlugin{
			{httpPlugin.PluginName, httpPlugin},
			{prometheusPlugin.PluginName, prometheusPlugin},
			{examplePlug.PluginName, examplePlug}}
	}))
	core.EventLoopWithInterrupt(agent, exampleFinished)
}

// Deps group dependencies of the ExamplePlugin
type Deps struct {
	local.PluginInfraDeps
	Prometheus prom.API
}

// ExamplePlugin demonstrates the usage of datasync API.
type ExamplePlugin struct {
	Deps

	temporaryCounter prometheus.Gauge
	counterVal       int

	gaugeVec *prometheus.GaugeVec
}

// Identifier of the custom registry
const customRegistry = "/custom"

const orderLabel = "order"

// Init creates metric registries and adds gauges
func (plugin *ExamplePlugin) Init() error {

	// add new metric to default registry (accessible at the path /metrics)
	//
	// the current value is returned by provided callback
	// created gauge is identified by tuple(namespace, subsystem, name) only the name field is mandatory
	// additional properties can be defined using labels - key-value pairs. They do not change over time for the given gauge.
	err := plugin.Prometheus.RegisterGaugeFunc(prom.DefaultRegistry, "ns", "sub", "gaugeOne",
		"this metrics represents randomly generated numbers", prometheus.Labels{"Property1": "ABC", "Property2": "DEF"}, func() float64 {
			return rand.Float64()
		})
	if err != nil {
		return err
	}

	// create new registry that will be exposed at /custom path
	err = plugin.Prometheus.NewRegistry(customRegistry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError})
	if err != nil {
		return err
	}

	// create gauge using prometheus API
	plugin.temporaryCounter = prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "Countdown",
		Help: "This gauge is decremented by 1 each second, once it reaches 0 the gauge is removed.",
	})
	plugin.counterVal = 60
	plugin.temporaryCounter.Set(float64(plugin.counterVal))

	// register created gauge to the custom registry
	err = plugin.Prometheus.Register(customRegistry, plugin.temporaryCounter)
	if err != nil {
		return err
	}

	// create gauge vector and register it
	plugin.gaugeVec = prometheus.NewGaugeVec(prometheus.GaugeOpts{
		Name:        "Vector",
		Help:        "This gauge groups multiple similar metrics.",
		ConstLabels: prometheus.Labels{"type": "vector", "answer": "42"},
	}, []string{orderLabel})
	err = plugin.Prometheus.Register(customRegistry, plugin.gaugeVec)

	return err

}

// AfterInit starts go routines that modifies metrics
func (plugin *ExamplePlugin) AfterInit() error {

	go plugin.decrementCounter()

	go plugin.addNewGaugesToVector()

	return nil
}

// Close cleanup resources allocated by plugin
func (plugin *ExamplePlugin) Close() error {
	return nil
}

func (plugin *ExamplePlugin) addNewGaugesToVector() {
	for i := 1; i < 10; i++ {
		// add gauge with given labels to the vector
		g, err := plugin.gaugeVec.GetMetricWith(prometheus.Labels{orderLabel: fmt.Sprint(i)})
		if err != nil {
			plugin.Log.Error(err)
		} else {
			g.Set(1)
		}
		time.Sleep(2 * time.Second)
	}

}

func (plugin *ExamplePlugin) decrementCounter() {
	for {
		select {
		case <-time.After(time.Second):
			if plugin.counterVal == 0 {
				// once the countdown reaches zero remove gauge from registry+
				plugin.Prometheus.Unregister(customRegistry, plugin.temporaryCounter)
				return
			}
			plugin.counterVal--
			plugin.temporaryCounter.Set(float64(plugin.counterVal))

		}
	}
}
<|endoftext|>