<commit_before>/*
Copyright 2017 The Kubernetes 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 fake

import (
	"fmt"

	appsv1 "k8s.io/api/apps/v1"
	v1 "k8s.io/api/core/v1"
	storagev1 "k8s.io/api/storage/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	appslisters "k8s.io/client-go/listers/apps/v1"
	corelisters "k8s.io/client-go/listers/core/v1"
	storagelisters "k8s.io/client-go/listers/storage/v1"
	"k8s.io/kubernetes/pkg/scheduler/framework"
)

var _ corelisters.ServiceLister = &ServiceLister{}

// ServiceLister implements ServiceLister on []v1.Service for test purposes.
type ServiceLister []*v1.Service

// Services returns nil.
func (f ServiceLister) Services(namespace string) corelisters.ServiceNamespaceLister {
	var services []*v1.Service
	for i := range f {
		if f[i].Namespace == namespace {
			services = append(services, f[i])
		}
	}
	return &serviceNamespaceLister{
		services:  services,
		namespace: namespace,
	}
}

// List returns v1.ServiceList, the list of all services.
func (f ServiceLister) List(labels.Selector) ([]*v1.Service, error) {
	return f, nil
}

// serviceNamespaceLister is implementation of ServiceNamespaceLister returned by Services() above.
type serviceNamespaceLister struct {
	services  []*v1.Service
	namespace string
}

func (f *serviceNamespaceLister) Get(name string) (*v1.Service, error) {
	return nil, fmt.Errorf("not implemented")
}

func (f *serviceNamespaceLister) List(selector labels.Selector) ([]*v1.Service, error) {
	return f.services, nil
}

var _ corelisters.ReplicationControllerLister = &ControllerLister{}

// ControllerLister implements ControllerLister on []v1.ReplicationController for test purposes.
type ControllerLister []*v1.ReplicationController

// List returns []v1.ReplicationController, the list of all ReplicationControllers.
func (f ControllerLister) List(labels.Selector) ([]*v1.ReplicationController, error) {
	return f, nil
}

// GetPodControllers gets the ReplicationControllers that have the selector that match the labels on the given pod
func (f ControllerLister) GetPodControllers(pod *v1.Pod) (controllers []*v1.ReplicationController, err error) {
	var selector labels.Selector

	for i := range f {
		controller := f[i]
		if controller.Namespace != pod.Namespace {
			continue
		}
		selector = labels.Set(controller.Spec.Selector).AsSelectorPreValidated()
		if selector.Matches(labels.Set(pod.Labels)) {
			controllers = append(controllers, controller)
		}
	}
	if len(controllers) == 0 {
		err = fmt.Errorf("could not find Replication Controller for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
	}

	return
}

// ReplicationControllers returns nil
func (f ControllerLister) ReplicationControllers(namespace string) corelisters.ReplicationControllerNamespaceLister {
	return nil
}

var _ appslisters.ReplicaSetLister = &ReplicaSetLister{}

// ReplicaSetLister implements ControllerLister on []extensions.ReplicaSet for test purposes.
type ReplicaSetLister []*appsv1.ReplicaSet

// List returns replica sets.
func (f ReplicaSetLister) List(labels.Selector) ([]*appsv1.ReplicaSet, error) {
	return f, nil
}

// GetPodReplicaSets gets the ReplicaSets that have the selector that match the labels on the given pod
func (f ReplicaSetLister) GetPodReplicaSets(pod *v1.Pod) (rss []*appsv1.ReplicaSet, err error) {
	var selector labels.Selector

	for _, rs := range f {
		if rs.Namespace != pod.Namespace {
			continue
		}
		selector, err = metav1.LabelSelectorAsSelector(rs.Spec.Selector)
		if err != nil {
			// This object has an invalid selector, it does not match the pod
			continue
		}

		if selector.Matches(labels.Set(pod.Labels)) {
			rss = append(rss, rs)
		}
	}
	if len(rss) == 0 {
		err = fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
	}

	return
}

// ReplicaSets returns nil
func (f ReplicaSetLister) ReplicaSets(namespace string) appslisters.ReplicaSetNamespaceLister {
	return nil
}

var _ appslisters.StatefulSetLister = &StatefulSetLister{}

// StatefulSetLister implements ControllerLister on []appsv1.StatefulSet for testing purposes.
type StatefulSetLister []*appsv1.StatefulSet

// List returns stateful sets.
func (f StatefulSetLister) List(labels.Selector) ([]*appsv1.StatefulSet, error) {
	return f, nil
}

// GetPodStatefulSets gets the StatefulSets that have the selector that match the labels on the given pod.
func (f StatefulSetLister) GetPodStatefulSets(pod *v1.Pod) (sss []*appsv1.StatefulSet, err error) {
	var selector labels.Selector

	for _, ss := range f {
		if ss.Namespace != pod.Namespace {
			continue
		}
		selector, err = metav1.LabelSelectorAsSelector(ss.Spec.Selector)
		if err != nil {
			// This object has an invalid selector, it does not match the pod
			continue
		}
		if selector.Matches(labels.Set(pod.Labels)) {
			sss = append(sss, ss)
		}
	}
	if len(sss) == 0 {
		err = fmt.Errorf("could not find StatefulSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
	}
	return
}

// StatefulSets returns nil
func (f StatefulSetLister) StatefulSets(namespace string) appslisters.StatefulSetNamespaceLister {
	return nil
}

// persistentVolumeClaimNamespaceLister is implementation of PersistentVolumeClaimNamespaceLister returned by List() above.
type persistentVolumeClaimNamespaceLister struct {
	pvcs      []*v1.PersistentVolumeClaim
	namespace string
}

func (f *persistentVolumeClaimNamespaceLister) Get(name string) (*v1.PersistentVolumeClaim, error) {
	for _, pvc := range f.pvcs {
		if pvc.Name == name && pvc.Namespace == f.namespace {
			return pvc, nil
		}
	}
	return nil, fmt.Errorf("persistentvolumeclaim %q not found", name)
}

func (f persistentVolumeClaimNamespaceLister) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) {
	return nil, fmt.Errorf("not implemented")
}

// PersistentVolumeClaimLister declares a []v1.PersistentVolumeClaim type for testing.
type PersistentVolumeClaimLister []v1.PersistentVolumeClaim

var _ corelisters.PersistentVolumeClaimLister = PersistentVolumeClaimLister{}

// List gets PVC matching the namespace and PVC ID.
func (pvcs PersistentVolumeClaimLister) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) {
	return nil, fmt.Errorf("not implemented")
}

// PersistentVolumeClaims returns a fake PersistentVolumeClaimLister object.
func (pvcs PersistentVolumeClaimLister) PersistentVolumeClaims(namespace string) corelisters.PersistentVolumeClaimNamespaceLister {
	ps := make([]*v1.PersistentVolumeClaim, len(pvcs))
	for i := range pvcs {
		ps[i] = &pvcs[i]
	}
	return &persistentVolumeClaimNamespaceLister{
		pvcs:      ps,
		namespace: namespace,
	}
}

// NodeInfoLister declares a framework.NodeInfo type for testing.
type NodeInfoLister []*framework.NodeInfo

// Get returns a fake node object in the fake nodes.
func (nodes NodeInfoLister) Get(nodeName string) (*framework.NodeInfo, error) {
	for _, node := range nodes {
		if node != nil && node.Node().Name == nodeName {
			return node, nil
		}
	}
	return nil, fmt.Errorf("unable to find node: %s", nodeName)
}

// List lists all nodes.
func (nodes NodeInfoLister) List() ([]*framework.NodeInfo, error) {
	return nodes, nil
}

// HavePodsWithAffinityList is supposed to list nodes with at least one pod with affinity. For the fake lister
// we just return everything.
func (nodes NodeInfoLister) HavePodsWithAffinityList() ([]*framework.NodeInfo, error) {
	return nodes, nil
}

// HavePodsWithRequiredAntiAffinityList is supposed to list nodes with at least one pod with
// required anti-affinity. For the fake lister we just return everything.
func (nodes NodeInfoLister) HavePodsWithRequiredAntiAffinityList() ([]*framework.NodeInfo, error) {
	return nodes, nil
}

// NewNodeInfoLister create a new fake NodeInfoLister from a slice of v1.Nodes.
func NewNodeInfoLister(nodes []*v1.Node) framework.NodeInfoLister {
	nodeInfoList := make([]*framework.NodeInfo, len(nodes))
	for _, node := range nodes {
		nodeInfo := framework.NewNodeInfo()
		nodeInfo.SetNode(node)
		nodeInfoList = append(nodeInfoList, nodeInfo)
	}

	return NodeInfoLister(nodeInfoList)
}

var _ storagelisters.CSINodeLister = CSINodeLister{}

// CSINodeLister declares a storagev1.CSINode type for testing.
type CSINodeLister storagev1.CSINode

// Get returns a fake CSINode object.
func (n CSINodeLister) Get(name string) (*storagev1.CSINode, error) {
	csiNode := storagev1.CSINode(n)
	return &csiNode, nil
}

// List lists all CSINodes in the indexer.
func (n CSINodeLister) List(selector labels.Selector) (ret []*storagev1.CSINode, err error) {
	return nil, fmt.Errorf("not implemented")
}

// PersistentVolumeLister declares a []v1.PersistentVolume type for testing.
type PersistentVolumeLister []v1.PersistentVolume

var _ corelisters.PersistentVolumeLister = PersistentVolumeLister{}

// Get returns a fake PV object in the fake PVs by PV ID.
func (pvs PersistentVolumeLister) Get(pvID string) (*v1.PersistentVolume, error) {
	for _, pv := range pvs {
		if pv.Name == pvID {
			return &pv, nil
		}
	}
	return nil, fmt.Errorf("unable to find persistent volume: %s", pvID)
}

// List lists all PersistentVolumes in the indexer.
func (pvs PersistentVolumeLister) List(selector labels.Selector) ([]*v1.PersistentVolume, error) {
	return nil, fmt.Errorf("not implemented")
}

// StorageClassLister declares a []storagev1.StorageClass type for testing.
type StorageClassLister []storagev1.StorageClass

var _ storagelisters.StorageClassLister = StorageClassLister{}

// Get returns a fake storage class object in the fake storage classes by name.
func (classes StorageClassLister) Get(name string) (*storagev1.StorageClass, error) {
	for _, sc := range classes {
		if sc.Name == name {
			return &sc, nil
		}
	}
	return nil, &errors.StatusError{
		ErrStatus: metav1.Status{
			Reason:  metav1.StatusReasonNotFound,
			Message: fmt.Sprintf("unable to find storage class: %s", name),
		},
	}
}

// List lists all StorageClass in the indexer.
func (classes StorageClassLister) List(selector labels.Selector) ([]*storagev1.StorageClass, error) {
	return nil, fmt.Errorf("not implemented")
}
<commit_msg>cleanup: delete unused func NewNodeInfoLister<commit_after>/*
Copyright 2017 The Kubernetes 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 fake

import (
	"fmt"

	appsv1 "k8s.io/api/apps/v1"
	v1 "k8s.io/api/core/v1"
	storagev1 "k8s.io/api/storage/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	appslisters "k8s.io/client-go/listers/apps/v1"
	corelisters "k8s.io/client-go/listers/core/v1"
	storagelisters "k8s.io/client-go/listers/storage/v1"
	"k8s.io/kubernetes/pkg/scheduler/framework"
)

var _ corelisters.ServiceLister = &ServiceLister{}

// ServiceLister implements ServiceLister on []v1.Service for test purposes.
type ServiceLister []*v1.Service

// Services returns nil.
func (f ServiceLister) Services(namespace string) corelisters.ServiceNamespaceLister {
	var services []*v1.Service
	for i := range f {
		if f[i].Namespace == namespace {
			services = append(services, f[i])
		}
	}
	return &serviceNamespaceLister{
		services:  services,
		namespace: namespace,
	}
}

// List returns v1.ServiceList, the list of all services.
func (f ServiceLister) List(labels.Selector) ([]*v1.Service, error) {
	return f, nil
}

// serviceNamespaceLister is implementation of ServiceNamespaceLister returned by Services() above.
type serviceNamespaceLister struct {
	services  []*v1.Service
	namespace string
}

func (f *serviceNamespaceLister) Get(name string) (*v1.Service, error) {
	return nil, fmt.Errorf("not implemented")
}

func (f *serviceNamespaceLister) List(selector labels.Selector) ([]*v1.Service, error) {
	return f.services, nil
}

var _ corelisters.ReplicationControllerLister = &ControllerLister{}

// ControllerLister implements ControllerLister on []v1.ReplicationController for test purposes.
type ControllerLister []*v1.ReplicationController

// List returns []v1.ReplicationController, the list of all ReplicationControllers.
func (f ControllerLister) List(labels.Selector) ([]*v1.ReplicationController, error) {
	return f, nil
}

// GetPodControllers gets the ReplicationControllers that have the selector that match the labels on the given pod
func (f ControllerLister) GetPodControllers(pod *v1.Pod) (controllers []*v1.ReplicationController, err error) {
	var selector labels.Selector

	for i := range f {
		controller := f[i]
		if controller.Namespace != pod.Namespace {
			continue
		}
		selector = labels.Set(controller.Spec.Selector).AsSelectorPreValidated()
		if selector.Matches(labels.Set(pod.Labels)) {
			controllers = append(controllers, controller)
		}
	}
	if len(controllers) == 0 {
		err = fmt.Errorf("could not find Replication Controller for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
	}

	return
}

// ReplicationControllers returns nil
func (f ControllerLister) ReplicationControllers(namespace string) corelisters.ReplicationControllerNamespaceLister {
	return nil
}

var _ appslisters.ReplicaSetLister = &ReplicaSetLister{}

// ReplicaSetLister implements ControllerLister on []extensions.ReplicaSet for test purposes.
type ReplicaSetLister []*appsv1.ReplicaSet

// List returns replica sets.
func (f ReplicaSetLister) List(labels.Selector) ([]*appsv1.ReplicaSet, error) {
	return f, nil
}

// GetPodReplicaSets gets the ReplicaSets that have the selector that match the labels on the given pod
func (f ReplicaSetLister) GetPodReplicaSets(pod *v1.Pod) (rss []*appsv1.ReplicaSet, err error) {
	var selector labels.Selector

	for _, rs := range f {
		if rs.Namespace != pod.Namespace {
			continue
		}
		selector, err = metav1.LabelSelectorAsSelector(rs.Spec.Selector)
		if err != nil {
			// This object has an invalid selector, it does not match the pod
			continue
		}

		if selector.Matches(labels.Set(pod.Labels)) {
			rss = append(rss, rs)
		}
	}
	if len(rss) == 0 {
		err = fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
	}

	return
}

// ReplicaSets returns nil
func (f ReplicaSetLister) ReplicaSets(namespace string) appslisters.ReplicaSetNamespaceLister {
	return nil
}

var _ appslisters.StatefulSetLister = &StatefulSetLister{}

// StatefulSetLister implements ControllerLister on []appsv1.StatefulSet for testing purposes.
type StatefulSetLister []*appsv1.StatefulSet

// List returns stateful sets.
func (f StatefulSetLister) List(labels.Selector) ([]*appsv1.StatefulSet, error) {
	return f, nil
}

// GetPodStatefulSets gets the StatefulSets that have the selector that match the labels on the given pod.
func (f StatefulSetLister) GetPodStatefulSets(pod *v1.Pod) (sss []*appsv1.StatefulSet, err error) {
	var selector labels.Selector

	for _, ss := range f {
		if ss.Namespace != pod.Namespace {
			continue
		}
		selector, err = metav1.LabelSelectorAsSelector(ss.Spec.Selector)
		if err != nil {
			// This object has an invalid selector, it does not match the pod
			continue
		}
		if selector.Matches(labels.Set(pod.Labels)) {
			sss = append(sss, ss)
		}
	}
	if len(sss) == 0 {
		err = fmt.Errorf("could not find StatefulSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
	}
	return
}

// StatefulSets returns nil
func (f StatefulSetLister) StatefulSets(namespace string) appslisters.StatefulSetNamespaceLister {
	return nil
}

// persistentVolumeClaimNamespaceLister is implementation of PersistentVolumeClaimNamespaceLister returned by List() above.
type persistentVolumeClaimNamespaceLister struct {
	pvcs      []*v1.PersistentVolumeClaim
	namespace string
}

func (f *persistentVolumeClaimNamespaceLister) Get(name string) (*v1.PersistentVolumeClaim, error) {
	for _, pvc := range f.pvcs {
		if pvc.Name == name && pvc.Namespace == f.namespace {
			return pvc, nil
		}
	}
	return nil, fmt.Errorf("persistentvolumeclaim %q not found", name)
}

func (f persistentVolumeClaimNamespaceLister) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) {
	return nil, fmt.Errorf("not implemented")
}

// PersistentVolumeClaimLister declares a []v1.PersistentVolumeClaim type for testing.
type PersistentVolumeClaimLister []v1.PersistentVolumeClaim

var _ corelisters.PersistentVolumeClaimLister = PersistentVolumeClaimLister{}

// List gets PVC matching the namespace and PVC ID.
func (pvcs PersistentVolumeClaimLister) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) {
	return nil, fmt.Errorf("not implemented")
}

// PersistentVolumeClaims returns a fake PersistentVolumeClaimLister object.
func (pvcs PersistentVolumeClaimLister) PersistentVolumeClaims(namespace string) corelisters.PersistentVolumeClaimNamespaceLister {
	ps := make([]*v1.PersistentVolumeClaim, len(pvcs))
	for i := range pvcs {
		ps[i] = &pvcs[i]
	}
	return &persistentVolumeClaimNamespaceLister{
		pvcs:      ps,
		namespace: namespace,
	}
}

// NodeInfoLister declares a framework.NodeInfo type for testing.
type NodeInfoLister []*framework.NodeInfo

// Get returns a fake node object in the fake nodes.
func (nodes NodeInfoLister) Get(nodeName string) (*framework.NodeInfo, error) {
	for _, node := range nodes {
		if node != nil && node.Node().Name == nodeName {
			return node, nil
		}
	}
	return nil, fmt.Errorf("unable to find node: %s", nodeName)
}

// List lists all nodes.
func (nodes NodeInfoLister) List() ([]*framework.NodeInfo, error) {
	return nodes, nil
}

// HavePodsWithAffinityList is supposed to list nodes with at least one pod with affinity. For the fake lister
// we just return everything.
func (nodes NodeInfoLister) HavePodsWithAffinityList() ([]*framework.NodeInfo, error) {
	return nodes, nil
}

// HavePodsWithRequiredAntiAffinityList is supposed to list nodes with at least one pod with
// required anti-affinity. For the fake lister we just return everything.
func (nodes NodeInfoLister) HavePodsWithRequiredAntiAffinityList() ([]*framework.NodeInfo, error) {
	return nodes, nil
}

var _ storagelisters.CSINodeLister = CSINodeLister{}

// CSINodeLister declares a storagev1.CSINode type for testing.
type CSINodeLister storagev1.CSINode

// Get returns a fake CSINode object.
func (n CSINodeLister) Get(name string) (*storagev1.CSINode, error) {
	csiNode := storagev1.CSINode(n)
	return &csiNode, nil
}

// List lists all CSINodes in the indexer.
func (n CSINodeLister) List(selector labels.Selector) (ret []*storagev1.CSINode, err error) {
	return nil, fmt.Errorf("not implemented")
}

// PersistentVolumeLister declares a []v1.PersistentVolume type for testing.
type PersistentVolumeLister []v1.PersistentVolume

var _ corelisters.PersistentVolumeLister = PersistentVolumeLister{}

// Get returns a fake PV object in the fake PVs by PV ID.
func (pvs PersistentVolumeLister) Get(pvID string) (*v1.PersistentVolume, error) {
	for _, pv := range pvs {
		if pv.Name == pvID {
			return &pv, nil
		}
	}
	return nil, fmt.Errorf("unable to find persistent volume: %s", pvID)
}

// List lists all PersistentVolumes in the indexer.
func (pvs PersistentVolumeLister) List(selector labels.Selector) ([]*v1.PersistentVolume, error) {
	return nil, fmt.Errorf("not implemented")
}

// StorageClassLister declares a []storagev1.StorageClass type for testing.
type StorageClassLister []storagev1.StorageClass

var _ storagelisters.StorageClassLister = StorageClassLister{}

// Get returns a fake storage class object in the fake storage classes by name.
func (classes StorageClassLister) Get(name string) (*storagev1.StorageClass, error) {
	for _, sc := range classes {
		if sc.Name == name {
			return &sc, nil
		}
	}
	return nil, &errors.StatusError{
		ErrStatus: metav1.Status{
			Reason:  metav1.StatusReasonNotFound,
			Message: fmt.Sprintf("unable to find storage class: %s", name),
		},
	}
}

// List lists all StorageClass in the indexer.
func (classes StorageClassLister) List(selector labels.Selector) ([]*storagev1.StorageClass, error) {
	return nil, fmt.Errorf("not implemented")
}
<|endoftext|>


<commit_before>// Copyright 2018 The gVisor 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 tcp

type segmentHeap []*segment

// Len returns the length of h.
func (h segmentHeap) Len() int {
	return len(h)
}

// Less determines whether the i-th element of h is less than the j-th element.
func (h segmentHeap) Less(i, j int) bool {
	return h[i].sequenceNumber.LessThan(h[j].sequenceNumber)
}

// Swap swaps the i-th and j-th elements of h.
func (h segmentHeap) Swap(i, j int) {
	h[i], h[j] = h[j], h[i]
}

// Push adds x as the last element of h.
func (h *segmentHeap) Push(x interface{}) {
	*h = append(*h, x.(*segment))
}

// Pop removes the last element of h and returns it.
func (h *segmentHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	old[n-1] = nil
	*h = old[:n-1]
	return x
}
<commit_msg>Implement heap.Interface on pointer receiver<commit_after>// Copyright 2018 The gVisor 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 tcp

import "container/heap"

type segmentHeap []*segment

var _ heap.Interface = (*segmentHeap)(nil)

// Len returns the length of h.
func (h *segmentHeap) Len() int {
	return len(*h)
}

// Less determines whether the i-th element of h is less than the j-th element.
func (h *segmentHeap) Less(i, j int) bool {
	return (*h)[i].sequenceNumber.LessThan((*h)[j].sequenceNumber)
}

// Swap swaps the i-th and j-th elements of h.
func (h *segmentHeap) Swap(i, j int) {
	(*h)[i], (*h)[j] = (*h)[j], (*h)[i]
}

// Push adds x as the last element of h.
func (h *segmentHeap) Push(x interface{}) {
	*h = append(*h, x.(*segment))
}

// Pop removes the last element of h and returns it.
func (h *segmentHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	old[n-1] = nil
	*h = old[:n-1]
	return x
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/globocom/gandalf/db"
	"github.com/globocom/gandalf/repository"
	"github.com/globocom/gandalf/user"
	"labix.org/v2/mgo/bson"
	"os"
	"regexp"
	"strings"
)

// TODO: receive argument with user name

func hasWritePermission(u *user.User, r *repository.Repository) (allowed bool) {
	for _, userName := range r.Users {
		if u.Name == userName {
			return true
		}
	}
	return false
}

func hasReadPermission(u *user.User, r *repository.Repository) (allowed bool) {
	if r.IsPublic {
		return true
	}
	for _, userName := range r.Users {
		if u.Name == userName {
			return true
		}
	}
	return false
}

// Returns the command being executed by ssh.
// When a user runs `$ git push` from his/her machine, the server
// receives a ssh command, identified by this user (by the ssh key).
// The command and it's parameters are available through the SSH_ORIGINAL_COMMAND
// environment variable. In the git push example, it would have the following value:
// SSH_ORIGINAL_COMMAND=git-receive-pack 'foo.git'
// This function is responsible for retrieving the `git-receive-pack` part of SSH_ORIGINAL_COMMAND
func action() string {
	return strings.Split(os.Getenv("SSH_ORIGINAL_COMMAND"), " ")[0]
}

// Get the repository name requested in SSH_ORIGINAL_COMMAND and gets
// the related document on the database and returns it.
// this function does two distinct things (maybe it should'n), it
// parses the SSH_ORIGINAL_COMMAND and returns a "validation" error if it doesn't
// matches the expected format and gets the repository from the database based on the info
// obtained by the SSH_ORIGINAL_COMMAND parse.
func requestedRepository() (repository.Repository, error) {
	r, err := regexp.Compile(`[\w-]+ '([\w-]+)\.git'`)
	if err != nil {
		panic(err)
	}
	m := r.FindStringSubmatch(os.Getenv("SSH_ORIGINAL_COMMAND"))
	if len(m) < 2 {
		return repository.Repository{}, errors.New("Cannot deduce repository name from command. You are probably trying to do something you shouldn't")
	}
	repoName := m[1]
	var repo repository.Repository
	if err = db.Session.Repository().Find(bson.M{"_id": repoName}).One(&repo); err != nil {
		return repository.Repository{}, err
	}
	return repo, nil
}

func validateCmd() error {
	r, err := regexp.Compile(`git-([\w-]+) '([\w-]+)\.git'`)
	if err != nil {
		panic(err)
	}
	if m := r.FindStringSubmatch(os.Getenv("SSH_ORIGINAL_COMMAND")); len(m) < 3 {
		return errors.New("You've tried to execute some weird command, I'm deliberately denying you to execute that, get over it.")
	}
	return nil
}

func main() {
	// (flaviamissi): should we call a validate function before anything? (I think so)
	a := action()
	var u user.User
	err := db.Session.User().Find(bson.M{"_id": os.Args[1]}).One(&u)
	if err != nil {
		fmt.Println("Error obtaining user. Gandalf database is probably in an inconsistent state.")
	}
	// user is trying to write into repository
	// see man git-receive-pack
	if a == "git-receive-pack" {
	}
}
<commit_msg>bin: finishing main function (refactor coming)<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/globocom/gandalf/db"
	"github.com/globocom/gandalf/repository"
	"github.com/globocom/gandalf/user"
	"labix.org/v2/mgo/bson"
	"os"
	"os/exec"
	"regexp"
	"strings"
)

// TODO: receive argument with user name

func hasWritePermission(u *user.User, r *repository.Repository) (allowed bool) {
	for _, userName := range r.Users {
		if u.Name == userName {
			return true
		}
	}
	return false
}

func hasReadPermission(u *user.User, r *repository.Repository) (allowed bool) {
	if r.IsPublic {
		return true
	}
	for _, userName := range r.Users {
		if u.Name == userName {
			return true
		}
	}
	return false
}

// Returns the command being executed by ssh.
// When a user runs `$ git push` from his/her machine, the server
// receives a ssh command, identified by this user (by the ssh key).
// The command and it's parameters are available through the SSH_ORIGINAL_COMMAND
// environment variable. In the git push example, it would have the following value:
// SSH_ORIGINAL_COMMAND=git-receive-pack 'foo.git'
// This function is responsible for retrieving the `git-receive-pack` part of SSH_ORIGINAL_COMMAND
func action() string {
	return strings.Split(os.Getenv("SSH_ORIGINAL_COMMAND"), " ")[0]
}

// Get the repository name requested in SSH_ORIGINAL_COMMAND and gets
// the related document on the database and returns it.
// this function does two distinct things (maybe it should'n), it
// parses the SSH_ORIGINAL_COMMAND and returns a "validation" error if it doesn't
// matches the expected format and gets the repository from the database based on the info
// obtained by the SSH_ORIGINAL_COMMAND parse.
func requestedRepository() (repository.Repository, error) {
	r, err := regexp.Compile(`[\w-]+ '([\w-]+)\.git'`)
	if err != nil {
		panic(err)
	}
	m := r.FindStringSubmatch(os.Getenv("SSH_ORIGINAL_COMMAND"))
	if len(m) < 2 {
		return repository.Repository{}, errors.New("Cannot deduce repository name from command. You are probably trying to do something you shouldn't")
	}
	repoName := m[1]
	var repo repository.Repository
	if err = db.Session.Repository().Find(bson.M{"_id": repoName}).One(&repo); err != nil {
		return repository.Repository{}, err
	}
	return repo, nil
}

func validateCmd() error {
	r, err := regexp.Compile(`git-([\w-]+) '([\w-]+)\.git'`)
	if err != nil {
		panic(err)
	}
	if m := r.FindStringSubmatch(os.Getenv("SSH_ORIGINAL_COMMAND")); len(m) < 3 {
		return errors.New("You've tried to execute some weird command, I'm deliberately denying you to execute that, get over it.")
	}
	return nil
}

func main() {
	err := validateCmd()
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	a := action()
	var u user.User
	if err := db.Session.User().Find(bson.M{"_id": os.Args[1]}).One(&u); err != nil {
		fmt.Println("Error obtaining user. Gandalf database is probably in an inconsistent state.")
		return
	}
	repo, err := requestedRepository()
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	cmdStr := strings.Split(os.Getenv("SSH_ORIGINAL_COMMAND"), " ")
	// user is trying to write into repository
	// see man git-receive-pack
	if a == "git-receive-pack" {
		if hasWritePermission(&u, &repo) {
			cmd := exec.Command(cmdStr[0], cmdStr[1:]...)
			err = cmd.Run()
			if err != nil {
				fmt.Println("Got error while executing command:")
				fmt.Println(err.Error())
			}
			return
		}
		fmt.Println("Permission denied.")
		fmt.Println("You don't have access to write in this repository.")
	}
	if a == "git-upload-pack" {
		if hasReadPermission(&u, &repo) {
			cmd := exec.Command(cmdStr[0], cmdStr[1:]...)
			err = cmd.Run()
			if err != nil {
				fmt.Println("Got error while executing command:")
				fmt.Println(err.Error())
			}
			return
		}
		fmt.Println("Permission denied.")
		fmt.Println("You don't have access to read this repository.")
	}
}

//func execute...(fn func, repo, user)
//when receiving a git-receive-pack fn will be hasWritePermission
//when not, hasReadPermission
//the function will also retrieve the user and repository from the database
<|endoftext|>


<commit_before>package zwave

import "fmt"
import cc "github.com/bjyoungblood/gozw/zwave/commandclass"

type Manager struct {
	session *SessionLayer

	ApiVersion     string
	ApiLibraryType string

	HomeId uint32
	NodeId byte

	Version                 byte
	ApiType                 string
	TimerFunctionsSupported bool
	IsPrimaryController     bool
	ApplicationVersion      byte
	ApplicationRevision     byte
	SupportedFunctions      []byte

	nodeList []uint8
	Nodes    map[uint8]*Node
}

func NewManager(session *SessionLayer) *Manager {
	manager := &Manager{
		session: session,
		Nodes:   map[uint8]*Node{},
	}

	manager.init()

	return manager
}

func (m *Manager) init() {
	version := m.GetVersion()
	m.ApiVersion = version.ApiVersion
	m.ApiLibraryType = version.GetLibraryTypeString()

	ids := m.GetHomeId()
	m.HomeId = ids.HomeId
	m.NodeId = ids.NodeId

	appInfo := m.GetAppInfo()
	m.Version = appInfo.Version
	m.ApiType = appInfo.GetApiType()
	m.TimerFunctionsSupported = appInfo.TimerFunctionsSupported()
	m.IsPrimaryController = appInfo.IsPrimaryController()
	m.nodeList = appInfo.GetNodeIds()

	serialApi := m.GetSerialApiCapabilities()
	m.ApplicationVersion = serialApi.ApplicationVersion
	m.ApplicationRevision = serialApi.ApplicationRevision
	m.SupportedFunctions = serialApi.GetSupportedFunctions()

	m.setSerialApiReady(true)
}

func (m *Manager) Close() {
	m.setSerialApiReady(false)
}

func (m *Manager) SetApplicationNodeInformation() {
	m.session.ExecuteCommandNoWait(FnApplicationNodeInformation, []byte{
		ApplicationNodeInfoListening | ApplicationFreqListeningMode250ms | ApplicationNodeInfoOptionalFunctionality,
		GenericTypeGenericController,
		SpecificTypePortableSceneController,
		0x01,
		cc.CommandClassBasic,
	})
}

func (m *Manager) FactoryReset() {
	m.session.ExecuteCommand(FnSetDefault, []byte{0x01})
}

func (m *Manager) AddNode() {
	m.session.ExecuteCommandNoWait(FnAddNodeToNetwork, []byte{
		AddNodeAny | AddNodeOptionNetworkWide | AddNodeOptionNormalPower,
		0x01,
	})

	for {
		frame := m.session.WaitForFrame()
		callback := ParseFunctionPayload(frame.Payload).(*AddRemoveNodeCallback)

		switch {
		case callback.Status == AddNodeStatusLearnReady:
			// timeout after waiting for this for 10 seconds
			// then perform ADD_NODE_STOP
			fmt.Print("Add node ready... ")
		case callback.Status == AddNodeStatusNodeFound:
			// recommended timeout interval for receiving this is 60 seconds
			// can either timeout or manually stop inclusion process
			fmt.Print("found node... ")
		case callback.Status == AddNodeStatusAddingSlave:
			// recommended timeout interval after NodeFound is 60 seconds
			// if timeout, must call ADD_NODE_STOP with callback and wait for ADD_NODE_STATUS_DONE
			fmt.Print("slave... ")
		case callback.Status == AddNodeStatusProtocolDone:
			// must call ADD_NODE_STOP and wait for AddNodeStatusDone
			// must timeout after period depending on network size and composition (see 4.4.1.3.3)
			// when timing out, must call ADD_NODE_STOP with callback
			fmt.Println("protocol done")
			m.session.ExecuteCommandNoWait(FnAddNodeToNetwork, []byte{
				AddNodeStop,
				0x02,
			})
		case callback.Status == AddNodeStatusDone:
			// Must call ADD_NODE_STOP with null callback (Serial API: is this 0x0 or omit the field?)
			fmt.Println("done")
			m.session.ExecuteCommandNoWait(FnAddNodeToNetwork, []byte{
				AddNodeStop,
				0x0,
			})

			return
		default:
			fmt.Println("unknown frame", callback)
		}

	}
}

func (m *Manager) RemoveNode() {
	m.session.ExecuteCommandNoWait(FnRemoveNodeFromNetwork, []byte{
		RemoveNodeAny | RemoveNodeOptionNetworkWide | RemoveNodeOptionNormalPower,
		0x01,
	})

	for {
		frame := m.session.WaitForFrame()
		callback := ParseFunctionPayload(frame.Payload).(*AddRemoveNodeCallback)

		switch {
		case callback.Status == RemoveNodeStatusLearnReady:
			fmt.Print("Remove node ready... ")
		case callback.Status == RemoveNodeStatusNodeFound:
			fmt.Print("found node... ")
		case callback.Status == RemoveNodeStatusRemovingSlave:
			fmt.Print("slave... ")
		case callback.Status == RemoveNodeStatusProtocolDone:
			fmt.Println("protocol done")
			m.session.ExecuteCommandNoWait(FnRemoveNodeFromNetwork, []byte{
				RemoveNodeStop,
				0x02,
			})
		case callback.Status == RemoveNodeStatusDone:
			fmt.Println("done")
			m.session.ExecuteCommandNoWait(FnRemoveNodeFromNetwork, []byte{
				RemoveNodeStop,
				0x0,
			})

			return
		default:
			fmt.Println("unknown frame", callback)
		}

	}
}

func (m *Manager) GetHomeId() *MemoryGetIdResponse {
	resp := m.session.ExecuteCommand(FnMemoryGetId, []byte{})
	return ParseFunctionPayload(resp.Payload).(*MemoryGetIdResponse)
}

func (m *Manager) GetAppInfo() *NodeListResponse {
	resp := m.session.ExecuteCommand(FnGetInitAppData, []byte{})
	return ParseFunctionPayload(resp.Payload).(*NodeListResponse)
}

func (m *Manager) GetSerialApiCapabilities() *SerialApiCapabilitiesResponse {
	resp := m.session.ExecuteCommand(FnSerialApiCapabilities, []byte{})
	return ParseFunctionPayload(resp.Payload).(*SerialApiCapabilitiesResponse)
}

func (m *Manager) GetVersion() *VersionResponse {
	resp := m.session.ExecuteCommand(FnGetVersion, []byte{})
	return ParseFunctionPayload(resp.Payload).(*VersionResponse)
}

func (m *Manager) SendData(nodeId uint8, data []byte) {
	payload := []byte{
		nodeId,
		uint8(len(data)),
	}

	payload = append(payload, data...)
	payload = append(payload, TransmitOptionAck|TransmitOptionAutoRoute)
	payload = append(payload, 0x01)

	resp := m.session.ExecuteCommand(FnSendData, payload)
	fmt.Println("senddata reply", resp.Payload)
}

func (m *Manager) setSerialApiReady(ready bool) {
	var rdy byte
	if ready {
		rdy = 1
	} else {
		rdy = 0
	}

	m.session.ExecuteCommandNoWait(FnSerialAPIReady, []byte{rdy})
}

func (m *Manager) getNodeProtocolInfo(nodeId uint8) *NodeProtocolInfoResponse {
	resp := m.session.ExecuteCommand(FnGetNodeProtocolInfo, []byte{nodeId})
	return ParseFunctionPayload(resp.Payload).(*NodeProtocolInfoResponse)
}

func (m *Manager) loadNodes() {

}
<commit_msg>load node information on startup<commit_after>package zwave

import "fmt"
import cc "github.com/bjyoungblood/gozw/zwave/commandclass"

type Manager struct {
	session *SessionLayer

	ApiVersion     string
	ApiLibraryType string

	HomeId uint32
	NodeId byte

	Version                 byte
	ApiType                 string
	TimerFunctionsSupported bool
	IsPrimaryController     bool
	ApplicationVersion      byte
	ApplicationRevision     byte
	SupportedFunctions      []byte

	nodeList []uint8
	Nodes    map[uint8]*Node
}

func NewManager(session *SessionLayer) *Manager {
	manager := &Manager{
		session: session,
		Nodes:   map[uint8]*Node{},
	}

	manager.init()

	return manager
}

func (m *Manager) init() {
	version := m.GetVersion()
	m.ApiVersion = version.ApiVersion
	m.ApiLibraryType = version.GetLibraryTypeString()

	ids := m.GetHomeId()
	m.HomeId = ids.HomeId
	m.NodeId = ids.NodeId

	appInfo := m.GetAppInfo()
	m.Version = appInfo.Version
	m.ApiType = appInfo.GetApiType()
	m.TimerFunctionsSupported = appInfo.TimerFunctionsSupported()
	m.IsPrimaryController = appInfo.IsPrimaryController()
	m.nodeList = appInfo.GetNodeIds()

	serialApi := m.GetSerialApiCapabilities()
	m.ApplicationVersion = serialApi.ApplicationVersion
	m.ApplicationRevision = serialApi.ApplicationRevision
	m.SupportedFunctions = serialApi.GetSupportedFunctions()

	m.loadNodes()

	m.setSerialApiReady(true)
}

func (m *Manager) Close() {
	m.setSerialApiReady(false)
}

func (m *Manager) SetApplicationNodeInformation() {
	m.session.ExecuteCommandNoWait(FnApplicationNodeInformation, []byte{
		ApplicationNodeInfoListening | ApplicationFreqListeningMode250ms | ApplicationNodeInfoOptionalFunctionality,
		GenericTypeGenericController,
		SpecificTypePortableSceneController,
		0x01,
		cc.CommandClassBasic,
	})
}

func (m *Manager) FactoryReset() {
	m.session.ExecuteCommand(FnSetDefault, []byte{0x01})
}

func (m *Manager) AddNode() {
	m.session.ExecuteCommandNoWait(FnAddNodeToNetwork, []byte{
		AddNodeAny | AddNodeOptionNetworkWide | AddNodeOptionNormalPower,
		0x01,
	})

	for {
		frame := m.session.WaitForFrame()
		callback := ParseFunctionPayload(frame.Payload).(*AddRemoveNodeCallback)

		switch {
		case callback.Status == AddNodeStatusLearnReady:
			// timeout after waiting for this for 10 seconds
			// then perform ADD_NODE_STOP
			fmt.Print("Add node ready... ")
		case callback.Status == AddNodeStatusNodeFound:
			// recommended timeout interval for receiving this is 60 seconds
			// can either timeout or manually stop inclusion process
			fmt.Print("found node... ")
		case callback.Status == AddNodeStatusAddingSlave:
			// recommended timeout interval after NodeFound is 60 seconds
			// if timeout, must call ADD_NODE_STOP with callback and wait for ADD_NODE_STATUS_DONE
			fmt.Print("slave... ")
		case callback.Status == AddNodeStatusProtocolDone:
			// must call ADD_NODE_STOP and wait for AddNodeStatusDone
			// must timeout after period depending on network size and composition (see 4.4.1.3.3)
			// when timing out, must call ADD_NODE_STOP with callback
			fmt.Println("protocol done")
			m.session.ExecuteCommandNoWait(FnAddNodeToNetwork, []byte{
				AddNodeStop,
				0x02,
			})
		case callback.Status == AddNodeStatusDone:
			// Must call ADD_NODE_STOP with null callback (Serial API: is this 0x0 or omit the field?)
			fmt.Println("done")
			m.session.ExecuteCommandNoWait(FnAddNodeToNetwork, []byte{
				AddNodeStop,
				0x0,
			})

			return
		default:
			fmt.Println("unknown frame", callback)
		}

	}
}

func (m *Manager) RemoveNode() {
	m.session.ExecuteCommandNoWait(FnRemoveNodeFromNetwork, []byte{
		RemoveNodeAny | RemoveNodeOptionNetworkWide | RemoveNodeOptionNormalPower,
		0x01,
	})

	for {
		frame := m.session.WaitForFrame()
		callback := ParseFunctionPayload(frame.Payload).(*AddRemoveNodeCallback)

		switch {
		case callback.Status == RemoveNodeStatusLearnReady:
			fmt.Print("Remove node ready... ")
		case callback.Status == RemoveNodeStatusNodeFound:
			fmt.Print("found node... ")
		case callback.Status == RemoveNodeStatusRemovingSlave:
			fmt.Print("slave... ")
		case callback.Status == RemoveNodeStatusProtocolDone:
			fmt.Println("protocol done")
			m.session.ExecuteCommandNoWait(FnRemoveNodeFromNetwork, []byte{
				RemoveNodeStop,
				0x02,
			})
		case callback.Status == RemoveNodeStatusDone:
			fmt.Println("done")
			m.session.ExecuteCommandNoWait(FnRemoveNodeFromNetwork, []byte{
				RemoveNodeStop,
				0x0,
			})

			return
		default:
			fmt.Println("unknown frame", callback)
		}

	}
}

func (m *Manager) GetHomeId() *MemoryGetIdResponse {
	resp := m.session.ExecuteCommand(FnMemoryGetId, []byte{})
	return ParseFunctionPayload(resp.Payload).(*MemoryGetIdResponse)
}

func (m *Manager) GetAppInfo() *NodeListResponse {
	resp := m.session.ExecuteCommand(FnGetInitAppData, []byte{})
	return ParseFunctionPayload(resp.Payload).(*NodeListResponse)
}

func (m *Manager) GetSerialApiCapabilities() *SerialApiCapabilitiesResponse {
	resp := m.session.ExecuteCommand(FnSerialApiCapabilities, []byte{})
	return ParseFunctionPayload(resp.Payload).(*SerialApiCapabilitiesResponse)
}

func (m *Manager) GetVersion() *VersionResponse {
	resp := m.session.ExecuteCommand(FnGetVersion, []byte{})
	return ParseFunctionPayload(resp.Payload).(*VersionResponse)
}

func (m *Manager) SendData(nodeId uint8, data []byte) {
	payload := []byte{
		nodeId,
		uint8(len(data)),
	}

	payload = append(payload, data...)
	payload = append(payload, TransmitOptionAck|TransmitOptionAutoRoute)
	payload = append(payload, 0x01)

	resp := m.session.ExecuteCommand(FnSendData, payload)
	fmt.Println("senddata reply", resp.Payload)
}

func (m *Manager) setSerialApiReady(ready bool) {
	var rdy byte
	if ready {
		rdy = 1
	} else {
		rdy = 0
	}

	m.session.ExecuteCommandNoWait(FnSerialAPIReady, []byte{rdy})
}

func (m *Manager) getNodeProtocolInfo(nodeId uint8) *NodeProtocolInfoResponse {
	resp := m.session.ExecuteCommand(FnGetNodeProtocolInfo, []byte{nodeId})
	return ParseFunctionPayload(resp.Payload).(*NodeProtocolInfoResponse)
}

func (m *Manager) loadNodes() {
	for _, nodeId := range m.nodeList {
		nodeInfo := m.getNodeProtocolInfo(nodeId)
		node := NewNode(m, nodeId)

		node.setFromNodeProtocolInfo(nodeInfo)

		m.Nodes[nodeId] = node
	}
}
<|endoftext|>


<commit_before>package conf

import (
	"encoding/json"
	"log"
	"os"

	"github.com/jessevdk/go-flags"
	"github.com/op/go-logging"
)

type CLIParams struct {
	DefaultMessageTTL    int64
	DefaultDeliveryDelay int64
}

type PQueueConfigData struct {
	DefaultMessageTTL     int64 `long:"default-msg-ttl" description:"Default message TTL for a new queue in milliseconds" default:"3600000" env:"FMPQ_MSG_TTL"`
	DefaultDeliveryDelay  int64 `long:"default-delivery-delay" description:"Default message delivery delay for a new queue in milliseconds" default:"0" env:"FMPQ_DELIVERY_DELAY"`
	DefaultLockTimeout    int64 `long:"default-lock-timeout" description:"Default message lock/visibility timeout for a new queue in milliseconds" default:"60000"`
	DefaultPopCountLimit  int64 `long:"default-pop-count-limit" description:"Default limit for a message receive attempts for a new queue" default:"99"`
	DefaultMaxQueueSize   int64 `long:"default-max-queue-size" description:"Default max number of messages per queue" default:"100000000"`
	DefaultPopWaitTimeout int64 `long:"default-wait-timeout" description:"Default wait timeout to receive a message from the queue for a new queue in milliseconds." default:"0"`

	MaxPopWaitTimeout int64 `long:"max-wait-timeout" description:"Limit receive wait timeout. Milliseconds." default:"20000"`
	MaxPopBatchSize   int64 `long:"max-receive-batch" description:"Limit the number of received messages at once." default:"10"`
	MaxLockTimeout    int64 `long:"max-lock-timeout" description:"Max lock/visibility timeout in milliseconds" default:"43200000"`
	MaxDeliveryDelay  int64 `long:"max-delivery-delay" description:"Maximum delivery delay in milliseconds." default:"900000"`
	MaxMessageTTL     int64 `long:"max-message-ttl" description:"Maximum message TTL for the queue. In milliseconds" default:"345600000"`
	MaxMessageSize    int64 `long:"max-message-size" description:"Maximum message size in bytes." default:"262144"`

	TimeoutCheckBatchSize int64 `long:"tune-process-batch" description:"Internal batching for expired and timedout messages. Large numbers may lead to not desired service timeouts" default:"1000"`
}

// Config is a generic service config type.
type Config struct {
	TextLogLevel        string `long:"log-level" description:"Log level" default:"info" choice:"debug" choice:"info" choice:"warning"`
	Profiler            string `long:"profiler-address" description:"Enables Go profiler on the defined interface:port" default:""`
	LogLevel            logging.Level
	FMPQServerInterface string `long:"fmpq-address" description:"FireMPQ native protocol." default:":8222"`
	SQSServerInterface  string `long:"sqs-address" description:"SQS protocol interface for FireMPQ" default:""`
	SNSServerInterface  string `long:"sns-address" description:"NOT IMPLENTED: SNS protocol interface for FireMPQ" default:""`
	DbFlushInterval     int64  `long:"flush-interval" description:"Disk synchronization interval in milliseconds" default:"100"`
	DatabasePath        string `long:"data-dir" description:"FireMPQ database location" default:"fmpq-data"`
	UpdateInterval      int64  `long:"update-interval" description:"Timeout and expiration check period in milliseconds" default:"100"`

	BinaryLogPath       string
	BinaryLogBufferSize int
	BinaryLogPageSize   uint64
	BinaryLogFrameSize  uint64

	PQueueConfig PQueueConfigData

	PrintConfig bool `long:"print-cfg" description:"Print current config values"`
}

var CFG *Config
var CFG_PQ *PQueueConfigData

func ParseConfigParameters() *Config {
	cfg := Config{}

	_, err := flags.Parse(&cfg)
	if err != nil {
		log.Printf("Could not parse CLI parameters: %v", err)
		os.Exit(255)
	}

	if cfg.TextLogLevel == "warning" {
		cfg.LogLevel = 3
	}

	if cfg.TextLogLevel == "info" {
		cfg.LogLevel = 4
	}

	if cfg.TextLogLevel == "debug" {
		cfg.LogLevel = 5
	}

	if cfg.PrintConfig {
		txt, err := json.MarshalIndent(cfg, " ", "  ")
		if err != nil {
			log.Fatalf("Could not serialize config to print it: %v ", err)
		}
		log.Print(string(txt))
	}

	CFG = &cfg
	CFG_PQ = &(cfg.PQueueConfig)
	return &cfg
}
<commit_msg>Better config description<commit_after>package conf

import (
	"encoding/json"
	"log"
	"os"

	"github.com/jessevdk/go-flags"
	"github.com/op/go-logging"
)

type CLIParams struct {
	DefaultMessageTTL    int64
	DefaultDeliveryDelay int64
}

type PQueueConfigData struct {
	DefaultMessageTTL     int64 `long:"default-msg-ttl" description:"Default message TTL for a new queue in milliseconds" default:"3600000"`
	DefaultDeliveryDelay  int64 `long:"default-delivery-delay" description:"Default message delivery delay for a new queue in milliseconds" default:"0"`
	DefaultLockTimeout    int64 `long:"default-lock-timeout" description:"Default message lock/visibility timeout for a new queue in milliseconds" default:"60000"`
	DefaultPopCountLimit  int64 `long:"default-pop-count-limit" description:"Default receive attempts limit per message for a new queue" default:"99"`
	DefaultMaxQueueSize   int64 `long:"default-max-queue-size" description:"Default max number of messages per queue" default:"100000000"`
	DefaultPopWaitTimeout int64 `long:"default-wait-timeout" description:"Default wait timeout to receive a message for a new queue in milliseconds." default:"0"`

	MaxPopWaitTimeout int64 `long:"max-wait-timeout" description:"Limit receive wait timeout. Milliseconds." default:"20000"`
	MaxPopBatchSize   int64 `long:"max-receive-batch" description:"Limit the number of received messages at once." default:"10"`
	MaxLockTimeout    int64 `long:"max-lock-timeout" description:"Max lock/visibility timeout in milliseconds" default:"43200000"`
	MaxDeliveryDelay  int64 `long:"max-delivery-delay" description:"Maximum delivery delay in milliseconds." default:"900000"`
	MaxMessageTTL     int64 `long:"max-message-ttl" description:"Maximum message TTL for the queue. In milliseconds" default:"345600000"`
	MaxMessageSize    int64 `long:"max-message-size" description:"Maximum message size in bytes." default:"262144"`

	TimeoutCheckBatchSize int64 `long:"tune-process-batch" description:"Batch size to process expired messages and message locks. Large number may lead to not desired service timeouts" default:"1000"`
}

// Config is a generic service config type.
type Config struct {
	FMPQServerInterface string `long:"fmpq-address" description:"FireMPQ native protocol." default:":8222"`
	SQSServerInterface  string `long:"sqs-address" description:"SQS protocol interface for FireMPQ" default:""`
	SNSServerInterface  string `long:"sns-address" description:"NOT IMPLEMENTED: SNS protocol interface for FireMPQ" default:""`
	DbFlushInterval     int64  `long:"flush-interval" description:"Disk synchronization interval in milliseconds" default:"100"`
	DatabasePath        string `long:"data-dir" description:"FireMPQ database location" default:"fmpq-data"`
	UpdateInterval      int64  `long:"update-interval" description:"Timeout and expiration check period in milliseconds" default:"100"`

	BinaryLogPath       string
	BinaryLogBufferSize int
	BinaryLogPageSize   uint64
	BinaryLogFrameSize  uint64

	PQueueConfig PQueueConfigData

	TextLogLevel string `long:"log-level" description:"Log level" default:"info" choice:"debug" choice:"info" choice:"warning"`
	PrintConfig  bool   `long:"print-cfg" description:"Print current config values"`
	Profiler     string `long:"profiler-address" description:"Enables Go profiler on the defined interface:port" default:""`
	LogLevel     logging.Level
}

var CFG *Config
var CFG_PQ *PQueueConfigData

func ParseConfigParameters() *Config {
	cfg := Config{}

	_, err := flags.Parse(&cfg)
	if err != nil {
		os.Exit(255)
	}

	if cfg.TextLogLevel == "warning" {
		cfg.LogLevel = 3
	}

	if cfg.TextLogLevel == "info" {
		cfg.LogLevel = 4
	}

	if cfg.TextLogLevel == "debug" {
		cfg.LogLevel = 5
	}

	if cfg.PrintConfig {
		txt, err := json.MarshalIndent(cfg, " ", "  ")
		if err != nil {
			log.Fatalf("Could not serialize config to print it: %v ", err)
		}
		log.Print(string(txt))
	}

	CFG = &cfg
	CFG_PQ = &(cfg.PQueueConfig)
	return &cfg
}
<|endoftext|>


<commit_before>package api

import (
	"fmt"
	"koding/db/mongodb/modelhelper"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/common/response"

	"github.com/nlopes/slack"

	"golang.org/x/oauth2"
	"gopkg.in/mgo.v2"
)

const slackAway = "away"

type Slack struct {
	OAuthConf *oauth2.Config
}

type SlackRequest struct {
	Token string
}

type SlackMessageRequest struct {
	SlackRequest
	Channel string
	Text    string
	Params  slack.PostMessageParameters
}

// Send & Callback handlers are used for slack oauth
// If we can get the token successfully, then we store user's token in mongo in Callback handler
func (s *Slack) Send(w http.ResponseWriter, req *http.Request) {
	url := s.OAuthConf.AuthCodeURL("state", oauth2.AccessTypeOffline)
	http.Redirect(w, req, url, http.StatusTemporaryRedirect)
}

func (s *Slack) Callback(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	code := u.Query().Get("code")

	token, err := s.OAuthConf.Exchange(oauth2.NoContext, code)
	if err != nil {
		fmt.Printf("oauthConf.Exchange() failed with '%s'\n", err)
		return response.NewBadRequest(err)
	}

	user, err := modelhelper.GetUser(c.Client.Account.Nick)
	if err != nil && err != mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err == mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err := updateUserSlackToken(user, token.AccessToken); err != nil {
		return response.NewBadRequest(err)
	}

	fmt.Printf("TOKEN IS: %+v", token)
	return response.NewOK(nil)
}

//
// ListUsers & ListChannels & PostMessage handlers are used by client of koding
//

func (s *Slack) ListUsers(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context.Client.Account)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getUsers(token))
}

func (s *Slack) ListChannels(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context.Client.Account)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getChannels(token))
}

func (s *Slack) PostMessage(u *url.URL, h http.Header, req *SlackMessageRequest, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context.Client.Account)
	if err != nil {
		return response.NewBadRequest(err)
	}
	req.Token = token
	return response.HandleResultAndError(postMessage(req))
}
<commit_msg>socialapi: update function related with juser token<commit_after>package api

import (
	"fmt"
	"koding/db/mongodb/modelhelper"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/common/response"

	"github.com/nlopes/slack"

	"golang.org/x/oauth2"
	"gopkg.in/mgo.v2"
)

const slackAway = "away"

type Slack struct {
	OAuthConf *oauth2.Config
}

type SlackRequest struct {
	Token string
}

type SlackMessageRequest struct {
	SlackRequest
	Channel string
	Text    string
	Params  slack.PostMessageParameters
}

// Send & Callback handlers are used for slack oauth
// If we can get the token successfully, then we store user's token in mongo in Callback handler
func (s *Slack) Send(w http.ResponseWriter, req *http.Request) {
	url := s.OAuthConf.AuthCodeURL("state", oauth2.AccessTypeOffline)
	http.Redirect(w, req, url, http.StatusTemporaryRedirect)
}

func (s *Slack) Callback(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	code := u.Query().Get("code")

	token, err := s.OAuthConf.Exchange(oauth2.NoContext, code)
	if err != nil {
		fmt.Printf("oauthConf.Exchange() failed with '%s'\n", err)
		return response.NewBadRequest(err)
	}

	user, err := modelhelper.GetUser(c.Client.Account.Nick)
	if err != nil && err != mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err == mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err := updateUserSlackToken(user, c.GroupName, token.AccessToken); err != nil {
		return response.NewBadRequest(err)
	}

	fmt.Printf("TOKEN IS: %+v", token)
	return response.NewOK(nil)
}

//
// ListUsers & ListChannels & PostMessage handlers are used by client of koding
//

func (s *Slack) ListUsers(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getUsers(token))
}

func (s *Slack) ListChannels(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getChannels(token))
}

func (s *Slack) PostMessage(u *url.URL, h http.Header, req *SlackMessageRequest, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}
	req.Token = token
	return response.HandleResultAndError(postMessage(req))
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Vitess 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 tabletmanager

import (
	"golang.org/x/net/context"
	"vitess.io/vitess/go/sqltypes"
	"vitess.io/vitess/go/vt/log"

	querypb "vitess.io/vitess/go/vt/proto/query"
)

// ExecuteFetchAsDba will execute the given query, possibly disabling binlogs and reload schema.
func (tm *TabletManager) ExecuteFetchAsDba(ctx context.Context, query []byte, dbName string, maxrows int, disableBinlogs bool, reloadSchema bool) (*querypb.QueryResult, error) {
	// get a connection
	conn, err := tm.MysqlDaemon.GetDbaConnection(ctx)
	if err != nil {
		return nil, err
	}
	defer conn.Close()

	// disable binlogs if necessary
	if disableBinlogs {
		_, err := conn.ExecuteFetch("SET sql_log_bin = OFF", 0, false)
		if err != nil {
			return nil, err
		}
	}

	if dbName != "" {
		// This execute might fail if db does not exist.
		// Error is ignored because given query might create this database.
		conn.ExecuteFetch("USE "+dbName, 1, false)
	}

	// run the query
	result, err := conn.ExecuteFetch(string(query), maxrows, true /*wantFields*/)

	// re-enable binlogs if necessary
	if disableBinlogs && !conn.IsClosed() {
		_, err := conn.ExecuteFetch("SET sql_log_bin = ON", 0, false)
		if err != nil {
			// if we can't reset the sql_log_bin flag,
			// let's just close the connection.
			conn.Close()
		}
	}

	if err == nil && reloadSchema {
		reloadErr := tm.QueryServiceControl.ReloadSchema(ctx)
		if reloadErr != nil {
			log.Errorf("failed to reload the schema %v", reloadErr)
		}
	}
	return sqltypes.ResultToProto3(result), err
}

// ExecuteFetchAsAllPrivs will execute the given query, possibly reloading schema.
func (tm *TabletManager) ExecuteFetchAsAllPrivs(ctx context.Context, query []byte, dbName string, maxrows int, reloadSchema bool) (*querypb.QueryResult, error) {
	// get a connection
	conn, err := tm.MysqlDaemon.GetAllPrivsConnection(ctx)
	if err != nil {
		return nil, err
	}
	defer conn.Close()

	if dbName != "" {
		// This execute might fail if db does not exist.
		// Error is ignored because given query might create this database.
		conn.ExecuteFetch("USE "+dbName, 1, false)
	}

	// run the query
	result, err := conn.ExecuteFetch(string(query), maxrows, true /*wantFields*/)

	if err == nil && reloadSchema {
		reloadErr := tm.QueryServiceControl.ReloadSchema(ctx)
		if reloadErr != nil {
			log.Errorf("failed to reload the schema %v", reloadErr)
		}
	}
	return sqltypes.ResultToProto3(result), err
}

// ExecuteFetchAsApp will execute the given query.
func (tm *TabletManager) ExecuteFetchAsApp(ctx context.Context, query []byte, maxrows int) (*querypb.QueryResult, error) {
	// get a connection
	conn, err := tm.MysqlDaemon.GetAppConnection(ctx)
	if err != nil {
		return nil, err
	}
	defer conn.Recycle()
	result, err := conn.ExecuteFetch(string(query), maxrows, true /*wantFields*/)
	return sqltypes.ResultToProto3(result), err
}
<commit_msg>Address #6545 by escaping dbname<commit_after>/*
Copyright 2019 The Vitess 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 tabletmanager

import (
	"fmt"

	"golang.org/x/net/context"
	"vitess.io/vitess/go/sqlescape"
	"vitess.io/vitess/go/sqltypes"
	"vitess.io/vitess/go/vt/log"

	querypb "vitess.io/vitess/go/vt/proto/query"
)

// ExecuteFetchAsDba will execute the given query, possibly disabling binlogs and reload schema.
func (tm *TabletManager) ExecuteFetchAsDba(ctx context.Context, query []byte, dbName string, maxrows int, disableBinlogs bool, reloadSchema bool) (*querypb.QueryResult, error) {
	// get a connection
	conn, err := tm.MysqlDaemon.GetDbaConnection(ctx)
	if err != nil {
		return nil, err
	}
	defer conn.Close()

	// disable binlogs if necessary
	if disableBinlogs {
		_, err := conn.ExecuteFetch("SET sql_log_bin = OFF", 0, false)
		if err != nil {
			return nil, err
		}
	}

	if dbName != "" {
		// This execute might fail if db does not exist.
		// Error is ignored because given query might create this database.
		conn.ExecuteFetch(fmt.Sprintf("USE %s", sqlescape.EscapeID(dbName)), 1, false)
	}

	// run the query
	result, err := conn.ExecuteFetch(string(query), maxrows, true /*wantFields*/)

	// re-enable binlogs if necessary
	if disableBinlogs && !conn.IsClosed() {
		_, err := conn.ExecuteFetch("SET sql_log_bin = ON", 0, false)
		if err != nil {
			// if we can't reset the sql_log_bin flag,
			// let's just close the connection.
			conn.Close()
		}
	}

	if err == nil && reloadSchema {
		reloadErr := tm.QueryServiceControl.ReloadSchema(ctx)
		if reloadErr != nil {
			log.Errorf("failed to reload the schema %v", reloadErr)
		}
	}
	return sqltypes.ResultToProto3(result), err
}

// ExecuteFetchAsAllPrivs will execute the given query, possibly reloading schema.
func (tm *TabletManager) ExecuteFetchAsAllPrivs(ctx context.Context, query []byte, dbName string, maxrows int, reloadSchema bool) (*querypb.QueryResult, error) {
	// get a connection
	conn, err := tm.MysqlDaemon.GetAllPrivsConnection(ctx)
	if err != nil {
		return nil, err
	}
	defer conn.Close()

	if dbName != "" {
		// This execute might fail if db does not exist.
		// Error is ignored because given query might create this database.
		conn.ExecuteFetch(fmt.Sprintf("USE %s", sqlescape.EscapeID(dbName)), 1, false)
	}

	// run the query
	result, err := conn.ExecuteFetch(string(query), maxrows, true /*wantFields*/)

	if err == nil && reloadSchema {
		reloadErr := tm.QueryServiceControl.ReloadSchema(ctx)
		if reloadErr != nil {
			log.Errorf("failed to reload the schema %v", reloadErr)
		}
	}
	return sqltypes.ResultToProto3(result), err
}

// ExecuteFetchAsApp will execute the given query.
func (tm *TabletManager) ExecuteFetchAsApp(ctx context.Context, query []byte, maxrows int) (*querypb.QueryResult, error) {
	// get a connection
	conn, err := tm.MysqlDaemon.GetAppConnection(ctx)
	if err != nil {
		return nil, err
	}
	defer conn.Recycle()
	result, err := conn.ExecuteFetch(string(query), maxrows, true /*wantFields*/)
	return sqltypes.ResultToProto3(result), err
}
<|endoftext|>


<commit_before>package main

import (
	"strings"
	"github.com/bwmarrin/discordgo"
	"fmt"
)

type Command struct {
	Help        string   // Text used as instructions to the users
	SimpleReply bool     // true if only a simple text is to be send back
	ReplyText   string   // the text to be send back when is simple reply, "" otherwise (?)
	Aliases     []string // different triggers for this command
}

var commands map[string]Command

func init() {
	commands = make(map[string]Command)

	registerCommand("!help", "Αυτό το μήνυμα με οδηγίες", false, "", []string{"!βοήθεια", "!βοηθεια"})
	registerCommand("!ping", "Απαντά με πόνγκ!", true, "Pong!", nil)
	registerCommand("καλημέρα", "Το ευγενικό bot λέει και αυτό καλημέρα", true, "Καλημέρα %s :sunrise:", []string{"καλημερα", "καλημέρες", "καλημερες"})
	registerCommand("καλησπέρα", "Το ευγενικό bot λέει και αυτό καλησπέρα", true, "Καλησπέρα %s :city_sunset:", []string{"καλησπερα", "καλησπέρες", "καλησπερες"})
	registerCommand("!flip", "Όταν είσαι οργισμένος..", true, "(╯°□°）╯︵ ┻━┻", nil)
}

// Used apparently to register a command.
// When isSimpleReply is true, then the replyText is just being passed to the dispatcher
// Otherwise custom logic determines the result -if any-
func registerCommand(operator string, help string, isSimpleReply bool, replyText string, aliases []string) {
	_, ok := commands[operator]

	if !ok {
		a := make([]string, len(aliases))
		a = aliases
		commands[operator] = Command{help, isSimpleReply, replyText, a}
	}
}

func ParseCommand(m *discordgo.MessageCreate) (string) {
	message := strings.ToLower(m.Content)

	for key, value := range commands {
		if (strings.Contains(message, key) || checkAliases(message, &value) ) && value.SimpleReply {
			return simpleReply(m, value)
		} else if (strings.Contains(message, key) || checkAliases(message, &value)) && !value.SimpleReply {
			return complexReply(m, value, key)
		}
	}
	return ""
}

// Checks if the supplied command is an alias for
// a registered command
func checkAliases(message string, cmnd *Command) bool {
	if cmnd.Aliases == nil {
		return false
	}
	for _, alias := range cmnd.Aliases {
		if strings.Contains(message, alias) {
			return true
		}
	}
	return false
}

func simpleReply(m *discordgo.MessageCreate, c Command) (string) {
	addUser := strings.Contains(c.ReplyText, "%s")
	if addUser {
		return fmt.Sprintf(c.ReplyText, m.Author.Username)
	}
	return c.ReplyText
}

func complexReply(m *discordgo.MessageCreate, c Command, operator string) (string) {
	switch operator {
	case "!help":
		return assembleHelpText()
	default:
		return ""
	}
}

func assembleHelpText() string {
	var help string
	help = "Ragetuitter Bot έκδοση: " + Version + "\n\n"
	for key, value := range commands {
		help = help + fmt.Sprintln("`"+key+"`:", value.Help)
	}

	help = help + fmt.Sprintln("Μπορώ να κάνω γενικά λίγα πράγματα προς το παρόν :sob:")
	return help
}
<commit_msg>add link to the oss repository to the help text<commit_after>package main

import (
	"strings"
	"github.com/bwmarrin/discordgo"
	"fmt"
)

type Command struct {
	Help        string   // Text used as instructions to the users
	SimpleReply bool     // true if only a simple text is to be send back
	ReplyText   string   // the text to be send back when is simple reply, "" otherwise (?)
	Aliases     []string // different triggers for this command
}

var commands map[string]Command

func init() {
	commands = make(map[string]Command)

	registerCommand("!help", "Αυτό το μήνυμα με οδηγίες", false, "", []string{"!βοήθεια", "!βοηθεια"})
	registerCommand("!ping", "Απαντά με πόνγκ!", true, "Pong!", nil)
	registerCommand("καλημέρα", "Το ευγενικό bot λέει και αυτό καλημέρα", true, "Καλημέρα %s :sunrise:", []string{"καλημερα", "καλημέρες", "καλημερες"})
	registerCommand("καλησπέρα", "Το ευγενικό bot λέει και αυτό καλησπέρα", true, "Καλησπέρα %s :city_sunset:", []string{"καλησπερα", "καλησπέρες", "καλησπερες"})
	registerCommand("!flip", "Όταν είσαι οργισμένος..", true, "(╯°□°）╯︵ ┻━┻", nil)
}

// Used apparently to register a command.
// When isSimpleReply is true, then the replyText is just being passed to the dispatcher
// Otherwise custom logic determines the result -if any-
func registerCommand(operator string, help string, isSimpleReply bool, replyText string, aliases []string) {
	_, ok := commands[operator]

	if !ok {
		a := make([]string, len(aliases))
		a = aliases
		commands[operator] = Command{help, isSimpleReply, replyText, a}
	}
}

func ParseCommand(m *discordgo.MessageCreate) (string) {
	message := strings.ToLower(m.Content)

	for key, value := range commands {
		if (strings.Contains(message, key) || checkAliases(message, &value) ) && value.SimpleReply {
			return simpleReply(m, value)
		} else if (strings.Contains(message, key) || checkAliases(message, &value)) && !value.SimpleReply {
			return complexReply(m, value, key)
		}
	}
	return ""
}

// Checks if the supplied command is an alias for
// a registered command
func checkAliases(message string, cmnd *Command) bool {
	if cmnd.Aliases == nil {
		return false
	}
	for _, alias := range cmnd.Aliases {
		if strings.Contains(message, alias) {
			return true
		}
	}
	return false
}

func simpleReply(m *discordgo.MessageCreate, c Command) (string) {
	addUser := strings.Contains(c.ReplyText, "%s")
	if addUser {
		return fmt.Sprintf(c.ReplyText, m.Author.Username)
	}
	return c.ReplyText
}

func complexReply(m *discordgo.MessageCreate, c Command, operator string) (string) {
	switch operator {
	case "!help":
		return assembleHelpText()
	default:
		return ""
	}
}

func assembleHelpText() string {
	var help string
	help = "Ragetuitter Bot έκδοση: " + Version + "\n\n"
	for key, value := range commands {
		help = help + fmt.Sprintln("`"+key+"`:", value.Help)
	}

	help = help + fmt.Sprintln("Μπορώ να κάνω γενικά λίγα πράγματα προς το παρόν :sob:\n\nΜπορείτε να δείτε πώς δουλεύω στο: https://github.com/cmargonis/ragebot")
	return help
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/hashicorp/serf/cli"
	"github.com/hashicorp/serf/cli/agent"
	"github.com/hashicorp/serf/commands"
	"os"
	"os/signal"
)

// Commands is the mapping of all the available Serf commands.
var Commands map[string]cli.CommandFactory

func init() {
	Commands = map[string]cli.CommandFactory{
		"agent": func() (cli.Command, error) {
			return &agent.Command{
				ShutdownCh: makeShutdownCh(),
			}, nil
		},

		"members": func() (cli.Command, error) {
			return &commands.MembersCommand{}, nil
		},

		"version": func() (cli.Command, error) {
			return &cli.VersionCommand{
				Revision:          GitCommit,
				Version:           Version,
				VersionPrerelease: VersionPrerelease,
			}, nil
		},
	}
}

// makeShutdownCh returns a channel that can be used for shutdown
// notifications for commands. This channel will send a message for every
// interrupt received.
func makeShutdownCh() <-chan struct{} {
	resultCh := make(chan struct{})

	signalCh := make(chan os.Signal, 4)
	signal.Notify(signalCh, os.Interrupt)
	go func() {
		for {
			<-signalCh
			resultCh <- struct{}{}
		}
	}()

	return resultCh
}
<commit_msg>main: actually fix commands<commit_after>package main

import (
	"github.com/hashicorp/serf/cli"
	"github.com/hashicorp/serf/cli/agent"
	"github.com/hashicorp/serf/command"
	"os"
	"os/signal"
)

// Commands is the mapping of all the available Serf commands.
var Commands map[string]cli.CommandFactory

func init() {
	Commands = map[string]cli.CommandFactory{
		"agent": func() (cli.Command, error) {
			return &agent.Command{
				ShutdownCh: makeShutdownCh(),
			}, nil
		},

		"members": func() (cli.Command, error) {
			return &command.MembersCommand{}, nil
		},

		"version": func() (cli.Command, error) {
			return &cli.VersionCommand{
				Revision:          GitCommit,
				Version:           Version,
				VersionPrerelease: VersionPrerelease,
			}, nil
		},
	}
}

// makeShutdownCh returns a channel that can be used for shutdown
// notifications for commands. This channel will send a message for every
// interrupt received.
func makeShutdownCh() <-chan struct{} {
	resultCh := make(chan struct{})

	signalCh := make(chan os.Signal, 4)
	signal.Notify(signalCh, os.Interrupt)
	go func() {
		for {
			<-signalCh
			resultCh <- struct{}{}
		}
	}()

	return resultCh
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/go-telegram-bot-api/telegram-bot-api"
	"strings"
)

func StartCommand(update tgbotapi.Update) {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Simple bot for Overwatch by @kraso\n\n"+
		"How to use:\n"+
		"1. Use /save to save your game profile.\n"+
		"2. Use /me to see your stats.\n"+
		"3. ???\n"+
		"4. PROFIT!\n\n"+
		"Features:\n"+
		"— Player profile (/me command)\n"+
		"— Small summary for heroes\n"+
		"— Reports after every game session\n")
	msg.ParseMode = "HTML"
	bot.Send(msg)

	log.Info("/start command executed successful")
}

func DonateCommand(update tgbotapi.Update) {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, "If you find this bot helpful, "+
		"you can make small donation to help me pay server bills!")
	msg.ParseMode = "HTML"
	bot.Send(msg)

	log.Info("donate command executed successful")
}

type Hero struct {
	Name                string
	TimePlayedInSeconds int
}

type Heroes []Hero

func (hero Heroes) Len() int {
	return len(hero)
}

func (hero Heroes) Less(i, j int) bool {
	return hero[i].TimePlayedInSeconds < hero[j].TimePlayedInSeconds
}

func (hero Heroes) Swap(i, j int) {
	hero[i], hero[j] = hero[j], hero[i]
}

func SaveCommand(update tgbotapi.Update) {
	info := strings.Split(update.Message.Text, " ")
	var text string

	if len(info) == 3 {
		if info[1] != "psn" && info[1] != "xbl" {
			info[2] = strings.Replace(info[2], "#", "-", -1)
		}

		profile, err := GetOverwatchProfile(info[1], info[2])
		if err != nil {
			log.Warn(err)
			text = "Player not found!"
		} else {
			_, err := InsertUser(User{
				Id:      fmt.Sprint(dbPKPrefix, update.Message.From.ID),
				Profile: profile,
				Region:  info[1],
				Nick:    info[2],
			})
			if err != nil {
				log.Warn(err)
				return
			}

			log.Info("/save command executed successful")
			text = "Saved!"
		}
	} else {
		text = "Example: /save eu|us|kr|psn|xbl BattleTag#1337|ConsoleLogin"
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func MeCommand(update tgbotapi.Update) {
	user, err := GetUser(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	place, err := GetRatingPlace(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	log.Info("/me command executed successful")

	var text string
	info := strings.Split(update.Message.Text, "_")

	if len(info) == 1 {
		text = MakeSummary(user, place, "CompetitiveStats")
	} else if len(info) == 2 && info[1] == "quick" {
		text = MakeSummary(user, place, "QuickPlayStats")
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func HeroCommand(update tgbotapi.Update) {
	user, err := GetUser(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	log.Info("/h_ command executed successful")

	var text string
	info := strings.Split(update.Message.Text, "_")
	hero := info[1]

	if len(info) == 2 {
		text = MakeHeroSummary(hero, "CompetitiveStats", user)
	} else if len(info) == 3 && info[2] == "quick" {
		text = MakeHeroSummary(hero, "QuickPlayStats", user)
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func RatingTopCommand(update tgbotapi.Update, platform string) {
	var chatId int64
	if update.Message.Chat.Type == "private" {
		chatId = 0
	} else {
		chatId = update.Message.Chat.ID
	}

	top, err := GetRatingTop(platform, 20, chatId)
	if err != nil {
		log.Warn(err)
		return
	}

	text := "Rating Top:\n"
	for i := range top {
		nick := top[i].Nick
		if top[i].Region != "psn" && top[i].Region != "xbl" {
			nick = strings.Replace(nick, "-", "#", -1)
		}
		text += fmt.Sprintf("%d. %s (%d)\n", i+1, nick, top[i].Profile.Rating)
	}
	if len(top) == 0 {
		text += "It's empty..."
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func SetChatCommand(update tgbotapi.Update) {
	res, err := UpdateUser(User{
		Id:   fmt.Sprint("tg:", update.Message.From.ID),
		Chat: update.Message.Chat.ID,
	})
	if err != nil {
		log.Warn(err)
		return
	}

	var text string
	if res.Unchanged != 0 {
		text = "Error: This chat already set as primary!"
	}
	if res.Replaced != 0 || res.Updated != 0 {
		text = "Done: Set as primary chat!"
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}
<commit_msg>Small fixes<commit_after>package main

import (
	"fmt"
	"github.com/go-telegram-bot-api/telegram-bot-api"
	"strings"
)

func StartCommand(update tgbotapi.Update) {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Simple bot for Overwatch by @kraso\n\n"+
		"How to use:\n"+
		"1. Use /save to save your game profile.\n"+
		"2. Use /me to see your stats.\n"+
		"3. ???\n"+
		"4. PROFIT!\n\n"+
		"Features:\n"+
		"— Player profile (/me command)\n"+
		"— Small summary for heroes\n"+
		"— Reports after every game session\n")
	msg.ParseMode = "HTML"
	bot.Send(msg)

	log.Info("/start command executed successful")
}

func DonateCommand(update tgbotapi.Update) {
	msg := tgbotapi.NewMessage(update.Message.Chat.ID, "If you find this bot helpful, "+
		"you can make small donation to help me pay server bills!")
	msg.ParseMode = "HTML"
	bot.Send(msg)

	log.Info("donate command executed successful")
}

type Hero struct {
	Name                string
	TimePlayedInSeconds int
}

type Heroes []Hero

func (hero Heroes) Len() int {
	return len(hero)
}

func (hero Heroes) Less(i, j int) bool {
	return hero[i].TimePlayedInSeconds < hero[j].TimePlayedInSeconds
}

func (hero Heroes) Swap(i, j int) {
	hero[i], hero[j] = hero[j], hero[i]
}

func SaveCommand(update tgbotapi.Update) {
	info := strings.Split(update.Message.Text, " ")
	var text string

	if len(info) == 3 {
		if info[1] != "psn" && info[1] != "xbl" {
			info[2] = strings.Replace(info[2], "#", "-", -1)
		}

		profile, err := GetOverwatchProfile(info[1], info[2])
		if err != nil {
			log.Warn(err)
			text = "Player not found!"
		} else {
			_, err := InsertUser(User{
				Id:      fmt.Sprint(dbPKPrefix, update.Message.From.ID),
				Profile: profile,
				Region:  info[1],
				Nick:    info[2],
			})
			if err != nil {
				log.Warn(err)
				return
			}

			log.Info("/save command executed successful")
			text = "Saved!"
		}
	} else {
		text = "Example: /save eu|us|kr|psn|xbl BattleTag#1337|ConsoleLogin"
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func MeCommand(update tgbotapi.Update) {
	user, err := GetUser(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	place, err := GetRatingPlace(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	log.Info("/me command executed successful")

	var text string
	info := strings.Split(update.Message.Text, "_")

	if len(info) == 1 {
		text = MakeSummary(user, place, "CompetitiveStats")
	} else if len(info) == 2 && info[1] == "quick" {
		text = MakeSummary(user, place, "QuickPlayStats")
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func HeroCommand(update tgbotapi.Update) {
	user, err := GetUser(fmt.Sprint(dbPKPrefix, update.Message.From.ID))
	if err != nil {
		log.Warn(err)
		return
	}

	log.Info("/h_ command executed successful")

	var text string
	info := strings.Split(update.Message.Text, "_")
	hero := info[1]

	if len(info) == 2 {
		text = MakeHeroSummary(hero, "CompetitiveStats", user)
	} else if len(info) == 3 && info[2] == "quick" {
		text = MakeHeroSummary(hero, "QuickPlayStats", user)
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func RatingTopCommand(update tgbotapi.Update, platform string) {
	var chatId int64
	if update.Message.Chat.Type == "private" {
		chatId = 0
	} else {
		chatId = update.Message.Chat.ID
	}

	top, err := GetRatingTop(platform, 20, chatId)
	if err != nil {
		log.Warn(err)
		return
	}

	text := "Rating Top:\n"
	for i, elem := range top {
		nick := elem.Patreon + elem.Nick
		if elem.Region != "psn" && elem.Region != "xbl" {
			nick = strings.Replace(nick, "-", "#", -1)
		}
		text += fmt.Sprintf("%d. %s (%d)\n", i+1, nick, elem.Profile.Rating)
	}
	if len(top) == 0 {
		text += "It's empty..."
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}

func SetChatCommand(update tgbotapi.Update) {
	// Skip if it's private
	if update.Message.Chat.Type == "private" {
		return
	}

	res, err := UpdateUser(User{
		Id:   fmt.Sprint("tg:", update.Message.From.ID),
		Chat: update.Message.Chat.ID,
	})
	if err != nil {
		log.Warn(err)
		return
	}

	var text string
	if res.Unchanged != 0 {
		text = "Error: This chat already set as primary!"
	}
	if res.Replaced != 0 || res.Updated != 0 {
		text = "Done: Set as primary chat!"
	}

	msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
	msg.ParseMode = "HTML"
	bot.Send(msg)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/codegangsta/cli"
	"github.com/mackerelio/gomkr/utils"
	mkr "github.com/mackerelio/mackerel-client-go"
)

var Commands = []cli.Command{
	commandStatus,
	commandHosts,
	commandCreate,
	commandUpdate,
	commandThrow,
	commandFetch,
	commandRetire,
}

var commandStatus = cli.Command{
	Name:  "status",
	Usage: "Show host status",
	Description: `
`,
	Action: doStatus,
	Flags: []cli.Flag{
		cli.BoolFlag{Name: "verbose, v", Usage: "Verbose output mode"},
	},
}

var commandHosts = cli.Command{
	Name:  "hosts",
	Usage: "List hosts",
	Description: `
`,
	Action: doHosts,
	Flags: []cli.Flag{
		cli.StringFlag{Name: "name, n", Value: "", Usage: "Show hosts only matched with <name>"},
		cli.StringFlag{Name: "service, s", Value: "", Usage: "Show hosts only belongs to <service>"},
		cli.StringSliceFlag{
			Name:  "role, r",
			Value: &cli.StringSlice{},
			Usage: "Show hosts only belongs to <role>. Multiple choice allow. Required --service",
		},
		cli.StringSliceFlag{
			Name:  "status, st",
			Value: &cli.StringSlice{},
			Usage: "Show hosts only matched <status>. Multiple choice allow.",
		},
		cli.BoolFlag{Name: "verbose, v", Usage: "Verbose output mode"},
	},
}

var commandCreate = cli.Command{
	Name:  "create",
	Usage: "",
	Description: `
`,
	Action: doCreate,
}

var commandUpdate = cli.Command{
	Name:  "update",
	Usage: "",
	Description: `
`,
	Action: doUpdate,
}

var commandThrow = cli.Command{
	Name:  "throw",
	Usage: "Post metric values",
	Description: `
`,
	Action: doThrow,
	Flags: []cli.Flag{
		cli.StringFlag{Name: "host, H", Value: "", Usage: "Post host metric values to <hostId>."},
		cli.StringFlag{Name: "service, s", Value: "", Usage: "Post service metric values to <service>."},
	},
}

var commandFetch = cli.Command{
	Name:  "fetch",
	Usage: "",
	Description: `
`,
	Action: doFetch,
}

var commandRetire = cli.Command{
	Name:  "retire",
	Usage: "",
	Description: `
`,
	Action: doRetire,
}

func debug(v ...interface{}) {
	if os.Getenv("DEBUG") != "" {
		log.Println(v...)
	}
}

func assert(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func newMackerel() *mkr.Client {
	apiKey := os.Getenv("MACKEREL_APIKEY")
	if apiKey == "" {
		utils.Log("error", `
Not set MACKEREL_APIKEY environment variable. (Try "export MACKEREL_APIKEY='<Your apikey>'")
`)
		os.Exit(1)
	}

	if os.Getenv("DEBUG") != "" {
		mackerel, err := mkr.NewClientForTest(apiKey, "https://mackerel.io/api/v0", true)
		utils.DieIf(err)

		return mackerel
	} else {
		return mkr.NewClient(apiKey)
	}
}

func doStatus(c *cli.Context) {
	argHostId := c.Args().Get(0)
	isVerbose := c.Bool("verbose")

	if argHostId == "" {
		cli.ShowCommandHelp(c, "status")
		os.Exit(1)
	}

	mackerel := newMackerel()
	host, err := mackerel.FindHost(argHostId)
	utils.DieIf(err)

	if isVerbose {
		PrettyPrintJson(host)
	} else {
		format := &HostFormat{
			Id:            host.Id,
			Name:          host.Name,
			Status:        host.Status,
			RoleFullnames: host.GetRoleFullnames(),
			IsRetired:     host.IsRetired,
			CreatedAt:     host.DateStringFromCreatedAt(),
		}

		PrettyPrintJson(format)
	}
}

func doHosts(c *cli.Context) {
	isVerbose := c.Bool("verbose")
	argName := c.String("name")
	argService := c.String("service")
	argRoles := c.StringSlice("role")
	argStatuses := c.StringSlice("status")

	mackerel := newMackerel()
	hosts, err := mackerel.FindHosts(&mkr.FindHostsParam{
		Name:     argName,
		Service:  argService,
		Roles:    argRoles,
		Statuses: argStatuses,
	})
	utils.DieIf(err)

	if isVerbose {
		PrettyPrintJson(hosts)
	} else {
		var hostsFormat []*HostFormat
		for _, host := range hosts {
			format := &HostFormat{
				Id:            host.Id,
				Name:          host.Name,
				Status:        host.Status,
				RoleFullnames: host.GetRoleFullnames(),
				IsRetired:     host.IsRetired,
				CreatedAt:     host.DateStringFromCreatedAt(),
			}
			hostsFormat = append(hostsFormat, format)
		}

		PrettyPrintJson(hostsFormat)
	}
}

func doCreate(c *cli.Context) {
}

func doUpdate(c *cli.Context) {
}

func doThrow(c *cli.Context) {
	argHostId := c.String("host")
	argService := c.String("service")

	var metricValues []*(mkr.MetricValue)

	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		line := scanner.Text()

		// name, value, timestamp
		// ex.) tcp.CLOSING 0 1397031808
		items := strings.Fields(line)
		fmt.Printf("%v+", items)
		if len(items) != 3 {
			continue
		}
		value, err := strconv.ParseFloat(items[1], 64)
		if err != nil {
			utils.Log("warning", fmt.Sprintf("Failed to parse values: %s", err))
			continue
		}
		time, err := strconv.ParseInt(items[2], 10, 64)
		if err != nil {
			utils.Log("warning", fmt.Sprintf("Failed to parse values: %s", err))
			continue
		}

		metricValue := &mkr.MetricValue{
			Name:  items[0],
			Value: value,
			Time:  time,
		}

		metricValues = append(metricValues, metricValue)
	}
	utils.ErrorIf(scanner.Err())

	mackerel := newMackerel()

	if argHostId != "" {
		err := mackerel.PostHostMetricValuesByHostId(argHostId, metricValues)
		utils.DieIf(err)
	} else if argService != "" {
		err := mackerel.PostServiceMetricValues(argService, metricValues)
		utils.DieIf(err)
	} else {
		cli.ShowCommandHelp(c, "throw")
		os.Exit(1)
	}
}

func doFetch(c *cli.Context) {
}

func doRetire(c *cli.Context) {
}
<commit_msg>Impl 'gomkr update'<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/codegangsta/cli"
	"github.com/mackerelio/gomkr/utils"
	mkr "github.com/mackerelio/mackerel-client-go"
)

var Commands = []cli.Command{
	commandStatus,
	commandHosts,
	commandCreate,
	commandUpdate,
	commandThrow,
	commandFetch,
	commandRetire,
}

var commandStatus = cli.Command{
	Name:  "status",
	Usage: "Show host status",
	Description: `
`,
	Action: doStatus,
	Flags: []cli.Flag{
		cli.BoolFlag{Name: "verbose, v", Usage: "Verbose output mode"},
	},
}

var commandHosts = cli.Command{
	Name:  "hosts",
	Usage: "List hosts",
	Description: `
`,
	Action: doHosts,
	Flags: []cli.Flag{
		cli.StringFlag{Name: "name, n", Value: "", Usage: "Show hosts only matched with <name>"},
		cli.StringFlag{Name: "service, s", Value: "", Usage: "Show hosts only belongs to <service>"},
		cli.StringSliceFlag{
			Name:  "role, r",
			Value: &cli.StringSlice{},
			Usage: "Show hosts only belongs to <role>. Multiple choice allow. Required --service",
		},
		cli.StringSliceFlag{
			Name:  "status, st",
			Value: &cli.StringSlice{},
			Usage: "Show hosts only matched <status>. Multiple choice allow.",
		},
		cli.BoolFlag{Name: "verbose, v", Usage: "Verbose output mode"},
	},
}

var commandCreate = cli.Command{
	Name:  "create",
	Usage: "",
	Description: `
`,
	Action: doCreate,
}

var commandUpdate = cli.Command{
	Name:  "update",
	Usage: "Update host information like hostname, status and role",
	Description: `
`,
	Action: doUpdate,
	Flags: []cli.Flag{
		cli.StringFlag{Name: "name, n", Value: "", Usage: "Update <hostId> hostname to <name>."},
		cli.StringFlag{Name: "status, st", Value: "", Usage: "Update <hostId> status to <status>."},
		cli.StringSliceFlag{
			Name:  "fullRolename, R",
			Value: &cli.StringSlice{},
			Usage: "Update <hostId> fullRolename to <fullRolename>.",
		},
	},
}

var commandThrow = cli.Command{
	Name:  "throw",
	Usage: "Post metric values",
	Description: `
`,
	Action: doThrow,
	Flags: []cli.Flag{
		cli.StringFlag{Name: "host, H", Value: "", Usage: "Post host metric values to <hostId>."},
		cli.StringFlag{Name: "service, s", Value: "", Usage: "Post service metric values to <service>."},
	},
}

var commandFetch = cli.Command{
	Name:  "fetch",
	Usage: "",
	Description: `
`,
	Action: doFetch,
}

var commandRetire = cli.Command{
	Name:  "retire",
	Usage: "",
	Description: `
`,
	Action: doRetire,
}

func debug(v ...interface{}) {
	if os.Getenv("DEBUG") != "" {
		log.Println(v...)
	}
}

func assert(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func newMackerel() *mkr.Client {
	apiKey := os.Getenv("MACKEREL_APIKEY")
	if apiKey == "" {
		utils.Log("error", `
Not set MACKEREL_APIKEY environment variable. (Try "export MACKEREL_APIKEY='<Your apikey>'")
`)
		os.Exit(1)
	}

	if os.Getenv("DEBUG") != "" {
		mackerel, err := mkr.NewClientForTest(apiKey, "https://mackerel.io/api/v0", true)
		utils.DieIf(err)

		return mackerel
	} else {
		return mkr.NewClient(apiKey)
	}
}

func doStatus(c *cli.Context) {
	argHostId := c.Args().Get(0)
	isVerbose := c.Bool("verbose")

	if argHostId == "" {
		cli.ShowCommandHelp(c, "status")
		os.Exit(1)
	}

	mackerel := newMackerel()
	host, err := mackerel.FindHost(argHostId)
	utils.DieIf(err)

	if isVerbose {
		PrettyPrintJson(host)
	} else {
		format := &HostFormat{
			Id:            host.Id,
			Name:          host.Name,
			Status:        host.Status,
			RoleFullnames: host.GetRoleFullnames(),
			IsRetired:     host.IsRetired,
			CreatedAt:     host.DateStringFromCreatedAt(),
		}

		PrettyPrintJson(format)
	}
}

func doHosts(c *cli.Context) {
	isVerbose := c.Bool("verbose")
	argName := c.String("name")
	argService := c.String("service")
	argRoles := c.StringSlice("role")
	argStatuses := c.StringSlice("status")

	mackerel := newMackerel()
	hosts, err := mackerel.FindHosts(&mkr.FindHostsParam{
		Name:     argName,
		Service:  argService,
		Roles:    argRoles,
		Statuses: argStatuses,
	})
	utils.DieIf(err)

	if isVerbose {
		PrettyPrintJson(hosts)
	} else {
		var hostsFormat []*HostFormat
		for _, host := range hosts {
			format := &HostFormat{
				Id:            host.Id,
				Name:          host.Name,
				Status:        host.Status,
				RoleFullnames: host.GetRoleFullnames(),
				IsRetired:     host.IsRetired,
				CreatedAt:     host.DateStringFromCreatedAt(),
			}
			hostsFormat = append(hostsFormat, format)
		}

		PrettyPrintJson(hostsFormat)
	}
}

func doCreate(c *cli.Context) {
}

func doUpdate(c *cli.Context) {
	argHostId := c.Args().Get(0)
	name := c.String("name")
	status := c.String("status")
	RoleFullnames := c.StringSlice("roleFullname")

	if argHostId == "" {
		cli.ShowCommandHelp(c, "update")
		os.Exit(1)
	}

	mackerel := newMackerel()

	isUpdated := false

	if status != "" {
		err := mackerel.UpdateHostStatus(argHostId, status)
		utils.DieIf(err)

		isUpdated = true
	}
	if name != "" || len(RoleFullnames) > 0 {
		_, err := mackerel.UpdateHost(argHostId, &mkr.UpdateHostParam{
			Name:          name,
			RoleFullnames: RoleFullnames,
		})
		utils.DieIf(err)

		isUpdated = true
	}

	if !isUpdated {
		cli.ShowCommandHelp(c, "update")
		os.Exit(1)
	}
}

func doThrow(c *cli.Context) {
	argHostId := c.String("host")
	argService := c.String("service")

	var metricValues []*(mkr.MetricValue)

	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		line := scanner.Text()

		// name, value, timestamp
		// ex.) tcp.CLOSING 0 1397031808
		items := strings.Fields(line)
		fmt.Printf("%v+", items)
		if len(items) != 3 {
			continue
		}
		value, err := strconv.ParseFloat(items[1], 64)
		if err != nil {
			utils.Log("warning", fmt.Sprintf("Failed to parse values: %s", err))
			continue
		}
		time, err := strconv.ParseInt(items[2], 10, 64)
		if err != nil {
			utils.Log("warning", fmt.Sprintf("Failed to parse values: %s", err))
			continue
		}

		metricValue := &mkr.MetricValue{
			Name:  items[0],
			Value: value,
			Time:  time,
		}

		metricValues = append(metricValues, metricValue)
	}
	utils.ErrorIf(scanner.Err())

	mackerel := newMackerel()

	if argHostId != "" {
		err := mackerel.PostHostMetricValuesByHostId(argHostId, metricValues)
		utils.DieIf(err)
	} else if argService != "" {
		err := mackerel.PostServiceMetricValues(argService, metricValues)
		utils.DieIf(err)
	} else {
		cli.ShowCommandHelp(c, "throw")
		os.Exit(1)
	}
}

func doFetch(c *cli.Context) {
}

func doRetire(c *cli.Context) {
}
<|endoftext|>