<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"koding/db/mongodb/modelhelper"
	"koding/kites/kloud/keys"
	"koding/kites/kloud/koding"
	"log"
	"net/url"
	"os"

	"github.com/fatih/structs"
	"github.com/koding/kite"
	kiteconfig "github.com/koding/kite/config"
	"github.com/koding/kite/protocol"
	"github.com/koding/kloud"
	kloudprotocol "github.com/koding/kloud/protocol"
	"github.com/koding/logging"
	"github.com/koding/multiconfig"
)

// Config defines the configuration that Kloud needs to operate.
type Config struct {
	// ---  KLOUD SPECIFIC ---
	IP          string
	Port        int
	Region      string
	Environment string
	Id          string

	// Connect to Koding mongodb
	MongoURL string

	// --- DEVELOPMENT CONFIG ---
	// Show version and exit if enabled
	Version bool

	// Enable debug log mode
	DebugMode bool

	// Enable production mode, operates on production channel
	ProdMode bool

	// Enable test mode, disabled some authentication checks
	TestMode bool

	// --- KLIENT DEVELOPMENT ---
	// KontrolURL to connect and to de deployed with klient
	KontrolURL string

	// Private key to create kite.key
	PrivateKey string

	// Public key to create kite.key
	PublicKey string

	// Contains the users home directory to be added into a image
	TemplateDir string

	// --- KONTROL CONFIGURATION ---
	Public      bool   // Try to register with a public ip
	Proxy       bool   // Try to register behind a koding proxy
	RegisterURL string // Explicitly register with this given url
}

func main() {
	conf := new(Config)

	// Load the config, it's reads environment variables or from flags
	multiconfig.New().MustLoad(conf)

	if conf.Version {
		fmt.Println(kloud.VERSION)
		os.Exit(0)
	}

	fmt.Printf("Kloud loaded with following configuration variables: %+v\n", conf)

	k := newKite(conf)

	registerURL := k.RegisterURL(!conf.Public)
	if conf.RegisterURL != "" {
		u, err := url.Parse(conf.RegisterURL)
		if err != nil {
			k.Log.Fatal("Couldn't parse register url: %s", err)
		}

		registerURL = u
	}

	fmt.Printf("registering with url %+v\n", registerURL)

	if conf.Proxy {
		k.Log.Info("Proxy mode is enabled")
		// Koding proxies in production only
		proxyQuery := &protocol.KontrolQuery{
			Username:    "koding",
			Environment: "production",
			Name:        "proxy",
		}

		k.Log.Info("Seaching proxy: %#v", proxyQuery)
		go k.RegisterToProxy(registerURL, proxyQuery)
	} else {
		if err := k.RegisterForever(registerURL); err != nil {
			k.Log.Fatal(err.Error())
		}
	}

	k.Run()
}

func newKite(conf *Config) *kite.Kite {
	k := kite.New(kloud.NAME, kloud.VERSION)
	k.Config = kiteconfig.MustGet()
	k.Config.Port = conf.Port

	if conf.Region != "" {
		k.Config.Region = conf.Region
	}

	if conf.Environment != "" {
		k.Config.Environment = conf.Environment
	}

	id := uniqueId()
	if conf.Id != "" {
		id = conf.Id
	}

	modelhelper.Initialize(conf.MongoURL)
	db := modelhelper.Mongo

	kodingProvider := &koding.Provider{
		Log:          newLogger("koding", conf.DebugMode),
		AssigneeName: id,
		Session:      db,
		Test:         conf.TestMode,
		TemplateDir:  conf.TemplateDir,
	}

	if err := kodingProvider.CleanupOldData(); err != nil {
		k.Log.Warning("Cleaning up mongodb err: %s", err.Error())
	}

	klientFolder := "klient/development/latest"
	if conf.ProdMode {
		klientFolder = "klient/production/latest"
	}

	privateKey, publicKey := kontrolKeys(conf)

	deployer := &KodingDeploy{
		Kite:              k,
		Log:               newLogger("kloud-deploy", conf.DebugMode),
		KontrolURL:        kontrolURL(conf.KontrolURL),
		KontrolPrivateKey: privateKey,
		KontrolPublicKey:  publicKey,
		Bucket:            newBucket("koding-kites", klientFolder),
		DB:                db,
	}

	kld := kloud.NewKloud()
	kld.Storage = kodingProvider
	kld.Log = newLogger("kloud", conf.DebugMode)

	kld.AddProvider("koding", kodingProvider)

	injectDeploy := func(r *kite.Request) (interface{}, error) {
		d := kloudprotocol.ProviderDeploy{
			KeyName:    keys.DeployKeyName,
			PublicKey:  keys.DeployPublicKey,
			PrivateKey: keys.DeployPrivateKey,
			Username:   r.Username,
		}

		r.Context.Set("deployData", structs.Map(d))
		return true, nil
	}

	k.Handle("build", kld.NewBuild(deployer)).PreHandleFunc(injectDeploy)
	k.HandleFunc("start", kld.Start)
	k.HandleFunc("stop", kld.Stop)
	k.HandleFunc("restart", kld.Restart)
	k.HandleFunc("info", kld.Info)
	k.HandleFunc("destroy", kld.Destroy)
	k.HandleFunc("event", kld.Event)
	k.HandleFunc("report", kodingProvider.Report)

	return k
}

func uniqueId() string {
	// TODO: add a unique identifier, for letting multiple version of the same
	// worker work on the same hostname.
	hostname, err := os.Hostname()
	if err != nil {
		panic(err) // we should not let it start
	}

	return fmt.Sprintf("%s-%s", kloud.NAME, hostname)
}

func newLogger(name string, debug bool) logging.Logger {
	log := logging.NewLogger(name)
	logHandler := logging.NewWriterHandler(os.Stderr)
	logHandler.Colorize = true
	log.SetHandler(logHandler)

	if debug {
		log.SetLevel(logging.DEBUG)
		logHandler.SetLevel(logging.DEBUG)
	}

	return log
}

func kontrolKeys(conf *Config) (string, string) {
	pubKey, err := ioutil.ReadFile(conf.PublicKey)
	if err != nil {
		log.Fatalln(err)
	}
	publicKey := string(pubKey)

	privKey, err := ioutil.ReadFile(conf.PrivateKey)
	if err != nil {
		log.Fatalln(err)
	}
	privateKey := string(privKey)

	return privateKey, publicKey
}

func kontrolURL(ownURL string) string {
	// read kontrolURL from kite.key if it doesn't exist.
	kontrolURL := kiteconfig.MustGet().KontrolURL

	if ownURL != "" {
		u, err := url.Parse(ownURL)
		if err != nil {
			log.Fatalln(err)
		}

		kontrolURL = u.String()
	}

	return kontrolURL
}
<commit_msg>kloud: panic if there is an error<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"koding/db/mongodb/modelhelper"
	"koding/kites/kloud/keys"
	"koding/kites/kloud/koding"
	"log"
	"net/url"
	"os"

	"github.com/fatih/structs"
	"github.com/koding/kite"
	kiteconfig "github.com/koding/kite/config"
	"github.com/koding/kite/protocol"
	"github.com/koding/kloud"
	kloudprotocol "github.com/koding/kloud/protocol"
	"github.com/koding/logging"
	"github.com/koding/multiconfig"
)

// Config defines the configuration that Kloud needs to operate.
type Config struct {
	// ---  KLOUD SPECIFIC ---
	IP          string
	Port        int
	Region      string
	Environment string
	Id          string

	// Connect to Koding mongodb
	MongoURL string

	// --- DEVELOPMENT CONFIG ---
	// Show version and exit if enabled
	Version bool

	// Enable debug log mode
	DebugMode bool

	// Enable production mode, operates on production channel
	ProdMode bool

	// Enable test mode, disabled some authentication checks
	TestMode bool

	// --- KLIENT DEVELOPMENT ---
	// KontrolURL to connect and to de deployed with klient
	KontrolURL string

	// Private key to create kite.key
	PrivateKey string

	// Public key to create kite.key
	PublicKey string

	// Contains the users home directory to be added into a image
	TemplateDir string

	// --- KONTROL CONFIGURATION ---
	Public      bool   // Try to register with a public ip
	Proxy       bool   // Try to register behind a koding proxy
	RegisterURL string // Explicitly register with this given url
}

func main() {
	conf := new(Config)

	// Load the config, it's reads environment variables or from flags
	multiconfig.New().MustLoad(conf)

	if conf.Version {
		fmt.Println(kloud.VERSION)
		os.Exit(0)
	}

	fmt.Printf("Kloud loaded with following configuration variables: %+v\n", conf)

	k := newKite(conf)

	registerURL := k.RegisterURL(!conf.Public)
	if conf.RegisterURL != "" {
		u, err := url.Parse(conf.RegisterURL)
		if err != nil {
			k.Log.Fatal("Couldn't parse register url: %s", err)
		}

		registerURL = u
	}

	fmt.Printf("registering with url %+v\n", registerURL)

	if conf.Proxy {
		k.Log.Info("Proxy mode is enabled")
		// Koding proxies in production only
		proxyQuery := &protocol.KontrolQuery{
			Username:    "koding",
			Environment: "production",
			Name:        "proxy",
		}

		k.Log.Info("Seaching proxy: %#v", proxyQuery)
		go k.RegisterToProxy(registerURL, proxyQuery)
	} else {
		if err := k.RegisterForever(registerURL); err != nil {
			k.Log.Fatal(err.Error())
		}
	}

	k.Run()
}

func newKite(conf *Config) *kite.Kite {
	k := kite.New(kloud.NAME, kloud.VERSION)
	k.Config = kiteconfig.MustGet()
	k.Config.Port = conf.Port

	if conf.Region != "" {
		k.Config.Region = conf.Region
	}

	if conf.Environment != "" {
		k.Config.Environment = conf.Environment
	}

	id := uniqueId()
	if conf.Id != "" {
		id = conf.Id
	}

	modelhelper.Initialize(conf.MongoURL)
	db := modelhelper.Mongo

	kodingProvider := &koding.Provider{
		Log:          newLogger("koding", conf.DebugMode),
		AssigneeName: id,
		Session:      db,
		Test:         conf.TestMode,
		TemplateDir:  conf.TemplateDir,
	}

	if err := kodingProvider.CleanupOldData(); err != nil {
		k.Log.Warning("Cleaning up mongodb err: %s", err.Error())
	}

	klientFolder := "klient/development/latest"
	if conf.ProdMode {
		klientFolder = "klient/production/latest"
	}

	privateKey, publicKey := kontrolKeys(conf)

	deployer := &KodingDeploy{
		Kite:              k,
		Log:               newLogger("kloud-deploy", conf.DebugMode),
		KontrolURL:        kontrolURL(conf.KontrolURL),
		KontrolPrivateKey: privateKey,
		KontrolPublicKey:  publicKey,
		Bucket:            newBucket("koding-kites", klientFolder),
		DB:                db,
	}

	kld := kloud.NewKloud()
	kld.Storage = kodingProvider
	kld.Log = newLogger("kloud", conf.DebugMode)

	err := kld.AddProvider("koding", kodingProvider)
	if err != nil {
		panic(err)
	}

	injectDeploy := func(r *kite.Request) (interface{}, error) {
		d := kloudprotocol.ProviderDeploy{
			KeyName:    keys.DeployKeyName,
			PublicKey:  keys.DeployPublicKey,
			PrivateKey: keys.DeployPrivateKey,
			Username:   r.Username,
		}

		r.Context.Set("deployData", structs.Map(d))
		return true, nil
	}

	k.Handle("build", kld.NewBuild(deployer)).PreHandleFunc(injectDeploy)
	k.HandleFunc("start", kld.Start)
	k.HandleFunc("stop", kld.Stop)
	k.HandleFunc("restart", kld.Restart)
	k.HandleFunc("info", kld.Info)
	k.HandleFunc("destroy", kld.Destroy)
	k.HandleFunc("event", kld.Event)
	k.HandleFunc("report", kodingProvider.Report)

	return k
}

func uniqueId() string {
	// TODO: add a unique identifier, for letting multiple version of the same
	// worker work on the same hostname.
	hostname, err := os.Hostname()
	if err != nil {
		panic(err) // we should not let it start
	}

	return fmt.Sprintf("%s-%s", kloud.NAME, hostname)
}

func newLogger(name string, debug bool) logging.Logger {
	log := logging.NewLogger(name)
	logHandler := logging.NewWriterHandler(os.Stderr)
	logHandler.Colorize = true
	log.SetHandler(logHandler)

	if debug {
		log.SetLevel(logging.DEBUG)
		logHandler.SetLevel(logging.DEBUG)
	}

	return log
}

func kontrolKeys(conf *Config) (string, string) {
	pubKey, err := ioutil.ReadFile(conf.PublicKey)
	if err != nil {
		log.Fatalln(err)
	}
	publicKey := string(pubKey)

	privKey, err := ioutil.ReadFile(conf.PrivateKey)
	if err != nil {
		log.Fatalln(err)
	}
	privateKey := string(privKey)

	return privateKey, publicKey
}

func kontrolURL(ownURL string) string {
	// read kontrolURL from kite.key if it doesn't exist.
	kontrolURL := kiteconfig.MustGet().KontrolURL

	if ownURL != "" {
		u, err := url.Parse(ownURL)
		if err != nil {
			log.Fatalln(err)
		}

		kontrolURL = u.String()
	}

	return kontrolURL
}
<|endoftext|>


<commit_before>package request

import (
	"math"
	"net/url"
	"strconv"
	"time"

	"github.com/kennygrant/sanitize"
)

const (
	DEFAULT_REPLY_LIMIT = 3
	MAX_REPLY_LIMIT     = 25
	MAX_LIMIT           = 25
)

type Query struct {
	Id             int64     `url:"id,omitempty"`
	Skip           int       `url:"skip"`
	Limit          int       `url:"limit"`
	To             time.Time `url:"to"`
	From           time.Time `url:"from"`
	GroupName      string    `url:"groupName"`
	GroupChannelId int64     `url:"groupChannelId"`
	Type           string    `url:"type"`
	Privacy        string    `url:"privacy"`
	AccountId      int64     `url:"accountId"`
	Name           string    `url:"name"`
	Slug           string    `url:"slug"`
	ShowExempt     bool      `url:"showExempt"`
	ReplyLimit     int       `url:"replyLimit"`
	ReplySkip      int       `url:"replySkip"`
}

func NewQuery() *Query {
	return &Query{}
}

func (q *Query) MapURL(u *url.URL) *Query {
	urlQuery := u.Query()

	q.Skip, _ = strconv.Atoi(urlQuery.Get("skip"))
	q.Limit, _ = strconv.Atoi(urlQuery.Get("limit"))

	q.Name = urlQuery.Get("name")
	if q.Name != "" {
		q.Name = sanitize.Name(q.Name)
	}

	q.Slug = urlQuery.Get("slug")
	if q.Slug != "" {
		q.Slug = sanitize.Name(q.Slug)
	}

	q.GroupName = urlQuery.Get("groupName")
	if q.GroupName != "" {
		q.GroupName = sanitize.Name(q.GroupName)
	}

	q.Type = urlQuery.Get("type")
	if q.Type != "" {
		q.Type = sanitize.Name(q.Type)
	}

	q.Privacy = urlQuery.Get("privacy")
	if q.Privacy != "" {
		q.Privacy = sanitize.Name(q.Privacy)
	}

	q.Id, _ = GetURIInt64(u, "id")
	q.AccountId, _ = GetURIInt64(u, "accountId")
	q.GroupChannelId, _ = GetURIInt64(u, "groupChannelId")

	if to := urlQuery.Get("to"); to != "" {
		q.To, _ = time.Parse(time.RFC3339, to)
	}

	if from := urlQuery.Get("from"); from != "" {
		q.From, _ = time.Parse(time.RFC3339, from)
	}

	if showExempt := urlQuery.Get("showExempt"); showExempt != "" {
		isExempt, _ := strconv.ParseBool(showExempt)
		q.ShowExempt = isExempt
	}

	if replyLimit := urlQuery.Get("replyLimit"); replyLimit != "" {
		replyLimit, _ := strconv.Atoi(replyLimit)
		q.ReplyLimit = replyLimit
	}

	if replySkip := urlQuery.Get("replyLimit"); replySkip != "" {
		replySkip, _ := strconv.Atoi(replySkip)
		q.ReplySkip = replySkip
	}

	return q
}

func (q *Query) Clone() *Query {
	cq := NewQuery()
	*cq = *q

	return cq
}

func (q *Query) SetDefaults() *Query {
	if q.Skip == 0 {
		// no need to do something
	}

	if q.Limit == 0 || q.Limit > MAX_LIMIT {
		q.Limit = MAX_LIMIT
	}

	if q.From.IsZero() {
		q.From = time.Now().UTC()
	}

	if q.GroupName == "" {
		q.GroupName = "koding"
	}

	if q.ReplyLimit == 0 {
		q.ReplyLimit = DEFAULT_REPLY_LIMIT
	} else {
		q.ReplyLimit = int(math.Min(float64(q.ReplyLimit), float64(MAX_REPLY_LIMIT)))
	}

	return q
}
<commit_msg>StaticPage: [Fixes #74246958]<commit_after>package request

import (
	"math"
	"net/url"
	"strconv"
	"time"

	"github.com/kennygrant/sanitize"
)

const (
	DEFAULT_REPLY_LIMIT = 3
	MAX_REPLY_LIMIT     = 25
	MAX_LIMIT           = 25
)

type Query struct {
	Id             int64     `url:"id,omitempty"`
	Skip           int       `url:"skip"`
	Limit          int       `url:"limit"`
	To             time.Time `url:"to"`
	From           time.Time `url:"from"`
	GroupName      string    `url:"groupName"`
	GroupChannelId int64     `url:"groupChannelId"`
	Type           string    `url:"type"`
	Privacy        string    `url:"privacy"`
	AccountId      int64     `url:"accountId"`
	Name           string    `url:"name"`
	Slug           string    `url:"slug"`
	ShowExempt     bool      `url:"showExempt"`
	ReplyLimit     int       `url:"replyLimit"`
	ReplySkip      int       `url:"replySkip"`
}

func NewQuery() *Query {
	return &Query{}
}

func (q *Query) MapURL(u *url.URL) *Query {
	urlQuery := u.Query()

	q.Skip, _ = strconv.Atoi(urlQuery.Get("skip"))
	q.Limit, _ = strconv.Atoi(urlQuery.Get("limit"))

	q.Name = urlQuery.Get("name")
	if q.Name != "" {
		q.Name = sanitize.Name(q.Name)
	}

	q.Slug = urlQuery.Get("slug")
	if q.Slug != "" {
		q.Slug = sanitize.Name(q.Slug)
	}

	q.GroupName = urlQuery.Get("groupName")
	if q.GroupName != "" {
		q.GroupName = sanitize.Name(q.GroupName)
	}

	q.Type = urlQuery.Get("type")
	if q.Type != "" {
		q.Type = sanitize.Name(q.Type)
	}

	q.Privacy = urlQuery.Get("privacy")
	if q.Privacy != "" {
		q.Privacy = sanitize.Name(q.Privacy)
	}

	q.Id, _ = GetURIInt64(u, "id")
	q.AccountId, _ = GetURIInt64(u, "accountId")
	q.GroupChannelId, _ = GetURIInt64(u, "groupChannelId")

	if to := urlQuery.Get("to"); to != "" {
		q.To, _ = time.Parse(time.RFC3339, to)
	}

	if from := urlQuery.Get("from"); from != "" {
		q.From, _ = time.Parse(time.RFC3339, from)
	}

	if showExempt := urlQuery.Get("showExempt"); showExempt != "" {
		isExempt, _ := strconv.ParseBool(showExempt)
		q.ShowExempt = isExempt
	}

	if replyLimit := urlQuery.Get("replyLimit"); replyLimit != "" {
		replyLimit, _ := strconv.Atoi(replyLimit)
		q.ReplyLimit = replyLimit
	}

	if replySkip := urlQuery.Get("replySkip"); replySkip != "" {
		replySkip, _ := strconv.Atoi(replySkip)
		q.ReplySkip = replySkip
	}

	return q
}

func (q *Query) Clone() *Query {
	cq := NewQuery()
	*cq = *q

	return cq
}

func (q *Query) SetDefaults() *Query {
	if q.Skip == 0 {
		// no need to do something
	}

	if q.Limit == 0 || q.Limit > MAX_LIMIT {
		q.Limit = MAX_LIMIT
	}

	if q.From.IsZero() {
		q.From = time.Now().UTC()
	}

	if q.GroupName == "" {
		q.GroupName = "koding"
	}

	if q.ReplyLimit == 0 {
		q.ReplyLimit = DEFAULT_REPLY_LIMIT
	} else {
		q.ReplyLimit = int(math.Min(float64(q.ReplyLimit), float64(MAX_REPLY_LIMIT)))
	}

	return q
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp. 2016 All Rights Reserved.

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 integration

import (
	"strconv"
	"strings"
	"time"

	"github.com/hyperledger/fabric/gossip/api"
	"github.com/hyperledger/fabric/gossip/common"
	"github.com/hyperledger/fabric/gossip/gossip"
	"github.com/hyperledger/fabric/peer/gossip/mcs"
	"github.com/hyperledger/fabric/peer/gossip/sa"
	"github.com/spf13/viper"
	"google.golang.org/grpc"
)

// This file is used to bootstrap a gossip instance for integration/demo purposes ONLY

func newConfig(selfEndpoint string, bootPeers ...string) *gossip.Config {
	port, err := strconv.ParseInt(strings.Split(selfEndpoint, ":")[1], 10, 64)
	if err != nil {
		panic(err)
	}

	return &gossip.Config{
		BindPort:                   int(port),
		BootstrapPeers:             bootPeers,
		ID:                         selfEndpoint,
		MaxBlockCountToStore:       100,
		MaxPropagationBurstLatency: time.Duration(10) * time.Millisecond,
		MaxPropagationBurstSize:    10,
		PropagateIterations:        1,
		PropagatePeerNum:           3,
		PullInterval:               time.Duration(4) * time.Second,
		PullPeerNum:                3,
		SelfEndpoint:               selfEndpoint,
		PublishCertPeriod:          10 * time.Second,
		RequestStateInfoInterval:   4 * time.Second,
		PublishStateInfoInterval:   4 * time.Second,
	}
}

// NewGossipComponent creates a gossip component that attaches itself to the given gRPC server
func NewGossipComponent(identity []byte, endpoint string, s *grpc.Server, dialOpts []grpc.DialOption, bootPeers ...string) gossip.Gossip {
	conf := newConfig(endpoint, bootPeers...)
	cryptSvc := mcs.NewMessageCryptoService()
	secAdv := sa.NewSecurityAdvisor()
	if viper.GetBool("peer.gossip.ignoresecurity") {
		sec := &secImpl{[]byte(endpoint)}
		cryptSvc = sec
		secAdv = sec
		identity = []byte(endpoint)
	}
	return gossip.NewGossipService(conf, s, secAdv, cryptSvc, identity, dialOpts...)
}

type secImpl struct {
	identity []byte
}

func (*secImpl) OrgByPeerIdentity(api.PeerIdentityType) api.OrgIdentityType {
	return api.OrgIdentityType("DEFAULT")
}

func (s *secImpl) GetPKIidOfCert(peerIdentity api.PeerIdentityType) common.PKIidType {
	return common.PKIidType(peerIdentity)
}

func (s *secImpl) VerifyBlock(chainID common.ChainID, signedBlock api.SignedBlock) error {
	return nil
}

func (s *secImpl) Sign(msg []byte) ([]byte, error) {
	return msg, nil
}

func (s *secImpl) Verify(peerIdentity api.PeerIdentityType, signature, message []byte) error {
	return nil
}

func (s *secImpl) VerifyByChannel(chainID common.ChainID, peerIdentity api.PeerIdentityType, signature, message []byte) error {
	return nil
}

func (s *secImpl) ValidateIdentity(peerIdentity api.PeerIdentityType) error {
	return nil
}
<commit_msg>Add option to override gossip endpoint<commit_after>/*
Copyright IBM Corp. 2016 All Rights Reserved.

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 integration

import (
	"strconv"
	"strings"
	"time"

	"github.com/hyperledger/fabric/gossip/api"
	"github.com/hyperledger/fabric/gossip/common"
	"github.com/hyperledger/fabric/gossip/gossip"
	"github.com/hyperledger/fabric/peer/gossip/mcs"
	"github.com/hyperledger/fabric/peer/gossip/sa"
	"github.com/spf13/viper"
	"google.golang.org/grpc"
)

// This file is used to bootstrap a gossip instance for integration/demo purposes ONLY

func newConfig(selfEndpoint string, bootPeers ...string) *gossip.Config {
	port, err := strconv.ParseInt(strings.Split(selfEndpoint, ":")[1], 10, 64)
	if err != nil {
		panic(err)
	}

	return &gossip.Config{
		BindPort:                   int(port),
		BootstrapPeers:             bootPeers,
		ID:                         selfEndpoint,
		MaxBlockCountToStore:       100,
		MaxPropagationBurstLatency: time.Duration(10) * time.Millisecond,
		MaxPropagationBurstSize:    10,
		PropagateIterations:        1,
		PropagatePeerNum:           3,
		PullInterval:               time.Duration(4) * time.Second,
		PullPeerNum:                3,
		SelfEndpoint:               selfEndpoint,
		PublishCertPeriod:          10 * time.Second,
		RequestStateInfoInterval:   4 * time.Second,
		PublishStateInfoInterval:   4 * time.Second,
	}
}

// NewGossipComponent creates a gossip component that attaches itself to the given gRPC server
func NewGossipComponent(identity []byte, endpoint string, s *grpc.Server, dialOpts []grpc.DialOption, bootPeers ...string) gossip.Gossip {
	if overrideEndpoint := viper.GetString("peer.gossip.endpoint"); overrideEndpoint != "" {
		endpoint = overrideEndpoint
	}

	conf := newConfig(endpoint, bootPeers...)
	cryptSvc := mcs.NewMessageCryptoService()
	secAdv := sa.NewSecurityAdvisor()

	if viper.GetBool("peer.gossip.ignoresecurity") {
		sec := &secImpl{[]byte(endpoint)}
		cryptSvc = sec
		secAdv = sec
		identity = []byte(endpoint)
	}

	return gossip.NewGossipService(conf, s, secAdv, cryptSvc, identity, dialOpts...)
}

type secImpl struct {
	identity []byte
}

func (*secImpl) OrgByPeerIdentity(api.PeerIdentityType) api.OrgIdentityType {
	return api.OrgIdentityType("DEFAULT")
}

func (s *secImpl) GetPKIidOfCert(peerIdentity api.PeerIdentityType) common.PKIidType {
	return common.PKIidType(peerIdentity)
}

func (s *secImpl) VerifyBlock(chainID common.ChainID, signedBlock api.SignedBlock) error {
	return nil
}

func (s *secImpl) Sign(msg []byte) ([]byte, error) {
	return msg, nil
}

func (s *secImpl) Verify(peerIdentity api.PeerIdentityType, signature, message []byte) error {
	return nil
}

func (s *secImpl) VerifyByChannel(chainID common.ChainID, peerIdentity api.PeerIdentityType, signature, message []byte) error {
	return nil
}

func (s *secImpl) ValidateIdentity(peerIdentity api.PeerIdentityType) error {
	return nil
}
<|endoftext|>


<commit_before>package handlers

import (
	"net/http"

	"github.com/danielkrainas/gobag/context"
	"github.com/gorilla/mux"

	"github.com/danielkrainas/shex/api/v1"
	"github.com/danielkrainas/shex/registry/actions"
)

const ServerVersionHeader = "Shex-Registry-Version"
const ApiVersionHeader = "Shex-Api-Version"
const ApiVersion = "1"

type Api struct {
	router *mux.Router
}

func NewApi(actionPack actions.Pack) (*Api, error) {
	api := &Api{
		router: v1.RouterWithPrefix(""),
	}

	api.register(v1.RouteNameBase, Base)

	return api, nil
}

func (api *Api) register(routeName string, dispatch http.HandlerFunc) {
	api.router.GetRoute(routeName).Handler(api.dispatcher(dispatch))
}

func (api *Api) dispatcher(dispatch http.HandlerFunc) http.Handler {
	return http.Handler(dispatch)
}

func (api *Api) ServerHTTP(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	w.Header().Add(ServerVersionHeader, acontext.GetVersion(r.Context()))
	w.Header().Add(ApiVersionHeader, ApiVersion)
	api.router.ServeHTTP(w, r)
}

/* API endpoint
app.post('/profiles/:user/:profileId', function (req, res) {
	console.log('profile posted:');
	console.log(JSON.stringify(req.body, null, 4));
	res.send('1');// return current version number of profile
});

app.head('/profiles/:user/:profileId', function (req, res) {
	//If-Modified-Since: version
});

app.get('/profiles/:user/:profileId', function (req, res) {
	var name = req.params.user + '/' + req.params.profileId;
	console.log('profile request:', name);
	res.json({
		rev: 1,
		name: name,
		mods: {},
	});
});

app.get('/mods/:user/:mod/v', function (req, res) {
	res.json(['0.1.8', '1.0.0']);
});

app.get('/mods/:user/:mod/v/:version/meta', function (req, res) {
	if (req.params.version === 'latest') {
		req.params.version = '1.0.0';
	}

	console.info('params ', req.params);
	var result = {
		name: req.params.user + '/' + req.params.mod,
		version: req.params.version
	};

	console.info('meta ', result);
	res.json(result);
});

app.get('/mods/:user/v/:mod/:version', function (req, res) {
	if (req.params.version === 'latest') {
		req.params.version = '1.0.0';
	}

	console.info('params ', req.params);

	res.sendFile(path.join(__dirname, '/candyland2.smod'), function (err) {
		if (err) {
			console.error(err);
			return;
		}
	});
});*/
<commit_msg>fix api interface matching for http handler<commit_after>package handlers

import (
	"net/http"

	"github.com/danielkrainas/gobag/context"
	"github.com/gorilla/mux"

	"github.com/danielkrainas/shex/api/v1"
	"github.com/danielkrainas/shex/registry/actions"
)

const ServerVersionHeader = "Shex-Registry-Version"
const ApiVersionHeader = "Shex-Api-Version"
const ApiVersion = "1"

type Api struct {
	router *mux.Router
}

func NewApi(actionPack actions.Pack) (*Api, error) {
	api := &Api{
		router: v1.RouterWithPrefix(""),
	}

	api.register(v1.RouteNameBase, Base)

	return api, nil
}

func (api *Api) register(routeName string, dispatch http.HandlerFunc) {
	api.router.GetRoute(routeName).Handler(api.dispatcher(dispatch))
}

func (api *Api) dispatcher(dispatch http.HandlerFunc) http.Handler {
	return http.Handler(dispatch)
}

func (api *Api) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	w.Header().Add(ServerVersionHeader, acontext.GetVersion(r.Context()))
	w.Header().Add(ApiVersionHeader, ApiVersion)
	api.router.ServeHTTP(w, r)
}

/* API endpoint
app.post('/profiles/:user/:profileId', function (req, res) {
	console.log('profile posted:');
	console.log(JSON.stringify(req.body, null, 4));
	res.send('1');// return current version number of profile
});

app.head('/profiles/:user/:profileId', function (req, res) {
	//If-Modified-Since: version
});

app.get('/profiles/:user/:profileId', function (req, res) {
	var name = req.params.user + '/' + req.params.profileId;
	console.log('profile request:', name);
	res.json({
		rev: 1,
		name: name,
		mods: {},
	});
});

app.get('/mods/:user/:mod/v', function (req, res) {
	res.json(['0.1.8', '1.0.0']);
});

app.get('/mods/:user/:mod/v/:version/meta', function (req, res) {
	if (req.params.version === 'latest') {
		req.params.version = '1.0.0';
	}

	console.info('params ', req.params);
	var result = {
		name: req.params.user + '/' + req.params.mod,
		version: req.params.version
	};

	console.info('meta ', result);
	res.json(result);
});

app.get('/mods/:user/v/:mod/:version', function (req, res) {
	if (req.params.version === 'latest') {
		req.params.version = '1.0.0';
	}

	console.info('params ', req.params);

	res.sendFile(path.join(__dirname, '/candyland2.smod'), function (err) {
		if (err) {
			console.error(err);
			return;
		}
	});
});*/
<|endoftext|>


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

// Package index implement CSI and tabix BGZF indexing.
package index

import (
	"io"

	"code.google.com/p/biogo.bam/bgzf"
)

// Reader wraps a bgzf.Reader to provide a mechanism to read a selection of
// BGZF chunks.
type ChunkReader struct {
	r *bgzf.Reader

	chunks []bgzf.Chunk
}

// NewChunkReader returns a ChunkReader to read from r, limiting the reads to
// the provided chunks.
//
// Note: Currently the limiting is loose; a single read that extends beyond the
// end of a chunk will not be truncated. In practice this should not be an issue
// since reads should correspond to the reads that were performed during indexing.
// This behaviour may change in future.
func NewChunkReader(r *bgzf.Reader, chunks []bgzf.Chunk) (*ChunkReader, error) {
	if len(chunks) != 0 {
		err := r.Seek(chunks[0].Begin)
		if err != nil {
			return nil, err
		}
	}
	return &ChunkReader{r: r, chunks: chunks}, nil
}

// Read satisfies the io.Reader interface.
func (r *ChunkReader) Read(p []byte) (int, error) {
	if len(r.chunks) == 0 && vOffset(r.r.LastChunk().End) >= vOffset(r.chunks[0].End) {
		return 0, io.EOF
	}

	// TODO(kortschak): Make the chunk limits hard. Currently a read that
	// extends beyond the end of a chunk is not truncated. It probably
	// should be. This may require invasive changes to bgzf.Reader.
	n, err := r.r.Read(p)
	if err != nil {
		return n, err
	}
	if len(r.chunks) != 0 && vOffset(r.r.LastChunk().End) >= vOffset(r.chunks[0].End) {
		err = r.r.Seek(r.chunks[0].Begin)
		r.chunks = r.chunks[1:]
	}
	return n, err
}
<commit_msg>Make chunk limits tight<commit_after>// Copyright ©2015 The bíogo.bam Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package index implement CSI and tabix BGZF indexing.
package index

import (
	"io"

	"code.google.com/p/biogo.bam/bgzf"
)

// Reader wraps a bgzf.Reader to provide a mechanism to read a selection of
// BGZF chunks.
type ChunkReader struct {
	r *bgzf.Reader

	chunks []bgzf.Chunk
}

// NewChunkReader returns a ChunkReader to read from r, limiting the reads to
// the provided chunks. The provided bgzf.Reader will be put into Blocked mode.
func NewChunkReader(r *bgzf.Reader, chunks []bgzf.Chunk) (*ChunkReader, error) {
	if len(chunks) != 0 {
		r.Blocked(true)
		err := r.Seek(chunks[0].Begin)
		if err != nil {
			return nil, err
		}
	}
	return &ChunkReader{r: r, chunks: chunks}, nil
}

// Read satisfies the io.Reader interface.
func (r *ChunkReader) Read(p []byte) (int, error) {
	if len(r.chunks) == 0 && vOffset(r.r.LastChunk().End) >= vOffset(r.chunks[0].End) {
		return 0, io.EOF
	}

	// Ensure the byte slice does not extend beyond the end of
	// the current chunk. We do not need to consider reading
	// beyond the end of the block because the bgzf.Reader is in
	// blocked mode and so will stop there anyway.
	if r.r.LastChunk().End.File == r.chunks[0].End.File {
		p = p[:r.chunks[0].End.Block-r.r.LastChunk().End.Block]
	}

	n, err := r.r.Read(p)
	if err != nil {
		if n != 0 && err == io.EOF {
			err = nil
		}
		return n, err
	}
	if len(r.chunks) != 0 && vOffset(r.r.LastChunk().End) >= vOffset(r.chunks[0].End) {
		err = r.r.Seek(r.chunks[0].Begin)
		r.chunks = r.chunks[1:]
	}
	return n, err
}
<|endoftext|>


<commit_before>package bham

import (
	"fmt"
	"strings"
	"text/template/parse"
)

func newTree(source, name string) *parse.Tree {
	return &parse.Tree{
		Name:      name,
		ParseName: source,
		Root: &parse.ListNode{
			NodeType: parse.NodeList,
		},
	}
}
func newTextNode(text string) parse.Node {
	return &parse.TextNode{
		NodeType: parse.NodeText,
		Text:     []byte(text),
	}
}

func (pt *protoTree) newMaybeTextNode(text string) []parse.Node {
	if strings.Contains(text, LeftDelim) && strings.Contains(text, RightDelim) {
		output := make([]parse.Node, 0)
		workingText := text
		for containsDelimeters(workingText) {
			index := strings.Index(workingText, LeftDelim)
			output = append(output, newTextNode(workingText[:index]))
			workingText = workingText[index:]

			index = strings.Index(workingText, RightDelim)
			pipeText := workingText[:index+len(RightDelim)]
			workingText = workingText[index+len(RightDelim):]

			action, e := pt.safeAction(pipeText)
			if e != nil {
				output = append(output, newTextNode(pipeText+" "))
			} else {
				output = append(output, action)
			}
		}

		if workingText != "" {
			return append(output, newTextNode(workingText+" "))
		}
		return output
	} else {
		return []parse.Node{
			newTextNode(text + " "),
		}
	}
}

func newValueNode(val string) parse.Node {
	switch val {
	case "true":
		return &parse.BoolNode{
			NodeType: parse.NodeBool,
			True:     true,
		}
	case "false":
		return &parse.BoolNode{
			NodeType: parse.NodeBool,
			True:     false,
		}
	case "nil":
		return &parse.NilNode{}
	}
	panic("Can only call value node for true, false, nil")
}

func newFieldNode(field string) parse.Node {

	return &parse.ActionNode{
		NodeType: parse.NodeAction,
		Pipe: &parse.PipeNode{
			NodeType: parse.NodePipe,
			Cmds: []*parse.CommandNode{
				&parse.CommandNode{
					NodeType: parse.NodeCommand,
					Args: []parse.Node{
						newBareFieldNode(field),
					},
				},
			},
		},
	}
}
func newBareFieldNode(field string) *parse.FieldNode {
	if field[0] == '.' {
		field = field[1:]
	}

	return &parse.FieldNode{
		NodeType: parse.NodeField,
		Ident:    strings.Split(field, "."),
	}
}

func newBareVariableNode(field string) *parse.VariableNode {
	return &parse.VariableNode{
		NodeType: parse.NodeVariable,
		Ident:    strings.Split(field, "."),
	}
}

func newFunctionNode(command string) parse.Node {
	return &parse.ActionNode{
		NodeType: parse.NodeAction,
		Pipe: &parse.PipeNode{
			NodeType: parse.NodePipe,
			Cmds: []*parse.CommandNode{
				&parse.CommandNode{
					NodeType: parse.NodeCommand,
					Args:     newBareFunctionNode(command),
				},
			},
		},
	}
}
func newBareFunctionNode(command string) []parse.Node {
	args := strings.Split(command, " ")
	nodeArgs := []parse.Node{}
	for _, arg := range args {
		switch arg[:1] {
		case ".":
			nodeArgs = append(nodeArgs,
				&parse.FieldNode{
					NodeType: parse.NodeField,
					Ident:    strings.Split(arg[1:], "."),
				},
			)
		case "$":
			nodeArgs = append(nodeArgs,
				&parse.VariableNode{
					NodeType: parse.NodeVariable,
					Ident:    strings.Split(arg, "."),
				},
			)
		default:
			nodeArgs = append(nodeArgs,
				&parse.IdentifierNode{
					NodeType: parse.NodeIdentifier,
					Ident:    arg,
				},
			)
		}
	}

	return nodeArgs
}

func (pt *protoTree) newStandaloneTag(content string) ([]parse.Node, error) {
	td, c, err := pt.parseTag(content)
	if err != nil {
		return []parse.Node{}, err
	}
	return td.Nodes(pt, c)
}

const (
	stateNull = iota
	stateTag
	stateId
	stateClass
	stateAttr
	stateValue
	stateBridge
	stateSpace
	stateDone
)

func (pt *protoTree) parseTag(content string) (tagDescription, string, error) {
	chars := []rune{}
	td := newTagDescription(pt)
	var current, state int
	for _, char := range content {
		chars = append(chars, char)
	}
	var value string
	limit := len(chars)
	{
		switch chars[current] {
		case '.':
			current++
			state = stateClass
			goto preamble_consume
		case '#':
			current++
			state = stateId
			goto preamble_consume
		case '%':
			current++
			state = stateTag
			goto preamble_consume
		}
	preamble_choose:
		if current == limit {
			value = ""
			goto ending
		} else {
			switch chars[current] {
			case '.':
				current++
				state = stateClass
			case '#':
				current++
				state = stateId
			case '(':
				current++
				state = stateAttr
				goto attr_consume
			case '=', '-', ' ':
				goto extra_consume
			}
		}
	preamble_consume:
		for current < limit {
			switch chars[current] {
			case '.', '#':
				td.Add(value, state)
				value = ""
				goto preamble_choose
			case '(':
				current++
				td.Add(value, state)
				value = ""
				goto attr_consume
			case '-', '=', ' ':
				td.Add(value, state)
				value = ""
				goto extra_consume
			default:
				value = value + string(chars[current])
			}
			current++
		}
		td.Add(value, state)
		value = ""
		goto ending
	attr_consume:
		for current < limit {
			switch chars[current] {
			case ' ':
				td.attributes = append(td.attributes, value)
				value = ""
			case '=':
				value = value + "="
				current++
				goto value_consume
			case ')':
				if value != "" {
					td.attributes = append(td.attributes, value)
				}
				current++
				value = ""
				goto extra_consume
			default:
				value = value + string(chars[current])
			}
			current++
		}
		return td, "", fmt.Errorf("Unterminated attributes for %s", content)
	value_consume:
		if current < limit && chars[current] == '"' {
			value = value + "\""
			current++
			quoteIndex := strings.Index(string(chars[current:]), "\"")
			delimIndex := strings.Index(string(chars[current:]), LeftDelim)
			if delimIndex > 0 && quoteIndex > delimIndex {
				leftLen := len([]rune(LeftDelim))
				fmt.Println("here", string(chars[current:]))
				for string(chars[current:current+leftLen]) != LeftDelim {
					value = value + string(chars[current])
					current += 1
				}
				value = value + LeftDelim
				current += len(LeftDelim)
				rightLen := len([]rune(RightDelim))
				searching := true
				for current < limit-rightLen && searching {
					if string(chars[current:current+rightLen]) == RightDelim {
						searching = false
						value = value + RightDelim
						current += rightLen
						td.executableOpen = true
					} else {
						value = value + string(chars[current])
						current++
					}
				}
			}
			for current < limit {
				if chars[current] == '"' {
					td.attributes = append(td.attributes, value+"\"")
					value = ""
					current++
					goto attr_consume
				} else {
					value = value + string(chars[current])
				}
				current++
			}
			return td, "", fmt.Errorf("HTML attribute values must have closing quotation marks for %s", content)
		}
		return td, "", fmt.Errorf("HTML attribute values must have quotation marks for %s", content)
	extra_consume:
		for current < limit {
			value = value + string(chars[current])
			current++
		}
	ending:
		return td, value, nil
	}
}
func newTagDescription(pt *protoTree) tagDescription {
	return tagDescription{
		tag:  "div",
		tree: pt,
	}
}

type tagDescription struct {
	tag            string
	tree           *protoTree
	executableOpen bool
	classes        []string
	idParts        []string
	attributes     []string
}

func (td *tagDescription) Add(content string, state int) {
	if content == "" {
		return
	}
	switch state {
	case stateClass:
		td.classes = append(td.classes, content)
	case stateId:
		td.idParts = append(td.idParts, content)
	case stateTag:
		td.tag = content
	}
}
func (td tagDescription) Opening() string {
	output := fmt.Sprintf("<%s", td.tag)
	if len(td.attributes) > 0 {
		for _, attr := range td.attributes {
			if len(td.classes) > 0 && strings.HasPrefix(attr, "class") {
				output = output +
					" class=\"" +
					strings.Join(td.classes, " ") +
					" " + attr[7:]
				td.classes = []string{}
			} else {
				if len(td.idParts) > 0 && strings.HasPrefix(attr, "id=") {
					output = output + " id=\"" + strings.Join(td.idParts, "_") + "_" + attr[4:]
					td.idParts = []string{}
				} else {
					output = output + " " + attr
				}
			}
		}
	}
	if len(td.classes) > 0 {
		output = output + " class=\"" + strings.Join(td.classes, " ") + "\""
	}
	if len(td.idParts) > 0 {
		output = output + " id=\"" + strings.Join(td.idParts, IdJoin) + "\""
	}
	return output + ">"
}

func (td tagDescription) Close() string {
	return fmt.Sprintf("</%s>", td.tag)
}

func (td tagDescription) Nodes(pt *protoTree, content string) ([]parse.Node, error) {
	if content != "" {
		if content[0] == '=' {
			content = strings.TrimSpace(content[1:])
			node, err := td.tree.parseTemplateCode(content)
			return append(append(pt.newMaybeTextNode(td.Opening()),
				&parse.ActionNode{
					NodeType: parse.NodeAction,
					Pipe:     node,
				}),
				pt.newMaybeTextNode(td.Close())...,
			), err
		} else {
			output := pt.newMaybeTextNode(td.Opening())
			output = append(output, pt.newMaybeTextNode(content)...)
			return append(output, pt.newMaybeTextNode(td.Close())...), nil
		}
	} else {
		return []parse.Node{
			newTextNode(td.Opening()),
			newTextNode(td.Close()),
		}, nil
	}
}
<commit_msg>Remove debug statement, fix bug<commit_after>package bham

import (
	"fmt"
	"strings"
	"text/template/parse"
)

func newTree(source, name string) *parse.Tree {
	return &parse.Tree{
		Name:      name,
		ParseName: source,
		Root: &parse.ListNode{
			NodeType: parse.NodeList,
		},
	}
}
func newTextNode(text string) parse.Node {
	return &parse.TextNode{
		NodeType: parse.NodeText,
		Text:     []byte(text),
	}
}

func (pt *protoTree) newMaybeTextNode(text string) []parse.Node {
	if strings.Contains(text, LeftDelim) && strings.Contains(text, RightDelim) {
		output := make([]parse.Node, 0)
		workingText := text
		for containsDelimeters(workingText) {
			index := strings.Index(workingText, LeftDelim)
			output = append(output, newTextNode(workingText[:index]))
			workingText = workingText[index:]

			index = strings.Index(workingText, RightDelim)
			pipeText := workingText[:index+len(RightDelim)]
			workingText = workingText[index+len(RightDelim):]

			action, e := pt.safeAction(pipeText)
			if e != nil {
				output = append(output, newTextNode(pipeText+" "))
			} else {
				output = append(output, action)
			}
		}

		if workingText != "" {
			return append(output, newTextNode(workingText+" "))
		}
		return output
	} else {
		return []parse.Node{
			newTextNode(text + " "),
		}
	}
}

func newValueNode(val string) parse.Node {
	switch val {
	case "true":
		return &parse.BoolNode{
			NodeType: parse.NodeBool,
			True:     true,
		}
	case "false":
		return &parse.BoolNode{
			NodeType: parse.NodeBool,
			True:     false,
		}
	case "nil":
		return &parse.NilNode{}
	}
	panic("Can only call value node for true, false, nil")
}

func newFieldNode(field string) parse.Node {

	return &parse.ActionNode{
		NodeType: parse.NodeAction,
		Pipe: &parse.PipeNode{
			NodeType: parse.NodePipe,
			Cmds: []*parse.CommandNode{
				&parse.CommandNode{
					NodeType: parse.NodeCommand,
					Args: []parse.Node{
						newBareFieldNode(field),
					},
				},
			},
		},
	}
}
func newBareFieldNode(field string) *parse.FieldNode {
	if field[0] == '.' {
		field = field[1:]
	}

	return &parse.FieldNode{
		NodeType: parse.NodeField,
		Ident:    strings.Split(field, "."),
	}
}

func newBareVariableNode(field string) *parse.VariableNode {
	return &parse.VariableNode{
		NodeType: parse.NodeVariable,
		Ident:    strings.Split(field, "."),
	}
}

func newFunctionNode(command string) parse.Node {
	return &parse.ActionNode{
		NodeType: parse.NodeAction,
		Pipe: &parse.PipeNode{
			NodeType: parse.NodePipe,
			Cmds: []*parse.CommandNode{
				&parse.CommandNode{
					NodeType: parse.NodeCommand,
					Args:     newBareFunctionNode(command),
				},
			},
		},
	}
}
func newBareFunctionNode(command string) []parse.Node {
	args := strings.Split(command, " ")
	nodeArgs := []parse.Node{}
	for _, arg := range args {
		switch arg[:1] {
		case ".":
			nodeArgs = append(nodeArgs,
				&parse.FieldNode{
					NodeType: parse.NodeField,
					Ident:    strings.Split(arg[1:], "."),
				},
			)
		case "$":
			nodeArgs = append(nodeArgs,
				&parse.VariableNode{
					NodeType: parse.NodeVariable,
					Ident:    strings.Split(arg, "."),
				},
			)
		default:
			nodeArgs = append(nodeArgs,
				&parse.IdentifierNode{
					NodeType: parse.NodeIdentifier,
					Ident:    arg,
				},
			)
		}
	}

	return nodeArgs
}

func (pt *protoTree) newStandaloneTag(content string) ([]parse.Node, error) {
	td, c, err := pt.parseTag(content)
	if err != nil {
		return []parse.Node{}, err
	}
	return td.Nodes(pt, c)
}

const (
	stateNull = iota
	stateTag
	stateId
	stateClass
	stateAttr
	stateValue
	stateBridge
	stateSpace
	stateDone
)

func (pt *protoTree) parseTag(content string) (tagDescription, string, error) {
	chars := []rune{}
	td := newTagDescription(pt)
	var current, state int
	for _, char := range content {
		chars = append(chars, char)
	}
	var value string
	limit := len(chars)
	{
		switch chars[current] {
		case '.':
			current++
			state = stateClass
			goto preamble_consume
		case '#':
			current++
			state = stateId
			goto preamble_consume
		case '%':
			current++
			state = stateTag
			goto preamble_consume
		}
	preamble_choose:
		if current == limit {
			value = ""
			goto ending
		} else {
			switch chars[current] {
			case '.':
				current++
				state = stateClass
			case '#':
				current++
				state = stateId
			case '(':
				current++
				state = stateAttr
				goto attr_consume
			case '=', '-', ' ':
				goto extra_consume
			}
		}
	preamble_consume:
		for current < limit {
			switch chars[current] {
			case '.', '#':
				td.Add(value, state)
				value = ""
				goto preamble_choose
			case '(':
				current++
				td.Add(value, state)
				value = ""
				goto attr_consume
			case '-', '=', ' ':
				td.Add(value, state)
				value = ""
				goto extra_consume
			default:
				value = value + string(chars[current])
			}
			current++
		}
		td.Add(value, state)
		value = ""
		goto ending
	attr_consume:
		for current < limit {
			switch chars[current] {
			case ' ':
				td.attributes = append(td.attributes, value)
				value = ""
			case '=':
				value = value + "="
				current++
				goto value_consume
			case ')':
				if value != "" {
					td.attributes = append(td.attributes, value)
				}
				current++
				value = ""
				goto extra_consume
			default:
				value = value + string(chars[current])
			}
			current++
		}
		return td, "", fmt.Errorf("Unterminated attributes for %s", content)
	value_consume:
		if current < limit && chars[current] == '"' {
			value = value + "\""
			current++
			quoteIndex := strings.Index(string(chars[current:]), "\"")
			delimIndex := strings.Index(string(chars[current:]), LeftDelim)
			if delimIndex > 0 && quoteIndex > delimIndex {
				value = value + string(chars[current:current+delimIndex])
				value = value + LeftDelim
				current += len(LeftDelim)
				rightLen := len([]rune(RightDelim))
				searching := true
				for current < limit-rightLen && searching {
					if string(chars[current:current+rightLen]) == RightDelim {
						searching = false
						value = value + RightDelim
						current += rightLen
						td.executableOpen = true
					} else {
						value = value + string(chars[current])
						current++
					}
				}
			}
			for current < limit {
				if chars[current] == '"' {
					td.attributes = append(td.attributes, value+"\"")
					value = ""
					current++
					goto attr_consume
				} else {
					value = value + string(chars[current])
				}
				current++
			}
			return td, "", fmt.Errorf("HTML attribute values must have closing quotation marks for %s", content)
		}
		return td, "", fmt.Errorf("HTML attribute values must have quotation marks for %s", content)
	extra_consume:
		for current < limit {
			value = value + string(chars[current])
			current++
		}
	ending:
		return td, value, nil
	}
}
func newTagDescription(pt *protoTree) tagDescription {
	return tagDescription{
		tag:  "div",
		tree: pt,
	}
}

type tagDescription struct {
	tag            string
	tree           *protoTree
	executableOpen bool
	classes        []string
	idParts        []string
	attributes     []string
}

func (td *tagDescription) Add(content string, state int) {
	if content == "" {
		return
	}
	switch state {
	case stateClass:
		td.classes = append(td.classes, content)
	case stateId:
		td.idParts = append(td.idParts, content)
	case stateTag:
		td.tag = content
	}
}
func (td tagDescription) Opening() string {
	output := fmt.Sprintf("<%s", td.tag)
	if len(td.attributes) > 0 {
		for _, attr := range td.attributes {
			if len(td.classes) > 0 && strings.HasPrefix(attr, "class") {
				output = output +
					" class=\"" +
					strings.Join(td.classes, " ") +
					" " + attr[7:]
				td.classes = []string{}
			} else {
				if len(td.idParts) > 0 && strings.HasPrefix(attr, "id=") {
					output = output + " id=\"" + strings.Join(td.idParts, "_") + "_" + attr[4:]
					td.idParts = []string{}
				} else {
					output = output + " " + attr
				}
			}
		}
	}
	if len(td.classes) > 0 {
		output = output + " class=\"" + strings.Join(td.classes, " ") + "\""
	}
	if len(td.idParts) > 0 {
		output = output + " id=\"" + strings.Join(td.idParts, IdJoin) + "\""
	}
	return output + ">"
}

func (td tagDescription) Close() string {
	return fmt.Sprintf("</%s>", td.tag)
}

func (td tagDescription) Nodes(pt *protoTree, content string) ([]parse.Node, error) {
	if content != "" {
		if content[0] == '=' {
			content = strings.TrimSpace(content[1:])
			node, err := td.tree.parseTemplateCode(content)
			return append(append(pt.newMaybeTextNode(td.Opening()),
				&parse.ActionNode{
					NodeType: parse.NodeAction,
					Pipe:     node,
				}),
				pt.newMaybeTextNode(td.Close())...,
			), err
		} else {
			output := pt.newMaybeTextNode(td.Opening())
			output = append(output, pt.newMaybeTextNode(content)...)
			return append(output, pt.newMaybeTextNode(td.Close())...), nil
		}
	} else {
		return []parse.Node{
			newTextNode(td.Opening()),
			newTextNode(td.Close()),
		}, nil
	}
}
<|endoftext|>


<commit_before>package db

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/url"
	"sort"
	"strconv"
	"strings"

	"github.com/bosssauce/ponzu/content"
	"github.com/bosssauce/ponzu/management/editor"
	"github.com/bosssauce/ponzu/management/manager"

	"github.com/boltdb/bolt"
	"github.com/gorilla/schema"
)

// SetContent inserts or updates values in the database.
// The `target` argument is a string made up of namespace:id (string:int)
func SetContent(target string, data url.Values) (int, error) {
	t := strings.Split(target, ":")
	ns, id := t[0], t[1]

	// check if content id == -1 (indicating new post).
	// if so, run an insert which will assign the next auto incremented int.
	// this is done because boltdb begins its bucket auto increment value at 0,
	// which is the zero-value of an int in the Item struct field for ID.
	// this is a problem when the original first post (with auto ID = 0) gets
	// overwritten by any new post, originally having no ID, defauting to 0.
	if id == "-1" {
		return insert(ns, data)
	}

	return update(ns, id, data)
}

func update(ns, id string, data url.Values) (int, error) {
	var specifier string // i.e. _pending, _sorted, etc.
	if strings.Contains(ns, "_") {
		spec := strings.Split(ns, "_")
		ns = spec[0]
		specifier = "_" + spec[1]
	}

	cid, err := strconv.Atoi(id)
	if err != nil {
		return 0, err
	}

	err = store.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte(ns + specifier))
		if err != nil {
			return err
		}

		j, err := postToJSON(ns, data)
		if err != nil {
			return err
		}

		err = b.Put([]byte(fmt.Sprintf("%d", cid)), j)
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return 0, nil
	}

	if specifier == "" {
		go SortContent(ns)
	}

	return cid, nil
}

func insert(ns string, data url.Values) (int, error) {
	var effectedID int
	var specifier string // i.e. _pending, _sorted, etc.
	if strings.Contains(ns, "_") {
		spec := strings.Split(ns, "_")
		ns = spec[0]
		specifier = "_" + spec[1]
	}

	err := store.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte(ns + specifier))
		if err != nil {
			return err
		}

		// get the next available ID and convert to string
		// also set effectedID to int of ID
		id, err := b.NextSequence()
		if err != nil {
			return err
		}
		cid := strconv.FormatUint(id, 10)
		effectedID, err = strconv.Atoi(cid)
		if err != nil {
			return err
		}
		data.Set("id", cid)

		j, err := postToJSON(ns, data)
		if err != nil {
			return err
		}

		err = b.Put([]byte(cid), j)
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return 0, err
	}

	if specifier == "" {
		go SortContent(ns)
	}

	return effectedID, nil
}

// DeleteContent removes an item from the database. Deleting a non-existent item
// will return a nil error.
func DeleteContent(target string) error {
	t := strings.Split(target, ":")
	ns, id := t[0], t[1]

	err := store.Update(func(tx *bolt.Tx) error {
		tx.Bucket([]byte(ns)).Delete([]byte(id))
		return nil
	})

	if err != nil {
		return err
	}

	// exception to typical "run in goroutine" pattern:
	// we want to have an updated admin view as soon as this is deleted, so
	// in some cases, the delete and redirect is faster than the sort,
	// thus still showing a deleted post in the admin view.
	SortContent(ns)

	return nil
}

// Content retrives one item from the database. Non-existent values will return an empty []byte
// The `target` argument is a string made up of namespace:id (string:int)
func Content(target string) ([]byte, error) {
	t := strings.Split(target, ":")
	ns, id := t[0], t[1]

	val := &bytes.Buffer{}
	err := store.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(ns))
		_, err := val.Write(b.Get([]byte(id)))
		if err != nil {
			log.Println(err)
			return err
		}

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

	return val.Bytes(), nil
}

// ContentAll retrives all items from the database within the provided namespace
func ContentAll(namespace string) [][]byte {
	var posts [][]byte
	store.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(namespace))

		if b == nil {
			return nil
		}

		numKeys := b.Stats().KeyN
		posts = make([][]byte, 0, numKeys)

		b.ForEach(func(k, v []byte) error {
			posts = append(posts, v)

			return nil
		})

		return nil
	})

	return posts
}

// SortContent sorts all content of the type supplied as the namespace by time,
// in descending order, from most recent to least recent
// Should be called from a goroutine after SetContent is successful
func SortContent(namespace string) {
	all := ContentAll(namespace)

	var posts sortablePosts
	// decode each (json) into type to then sort
	for i := range all {
		j := all[i]
		post := content.Types[namespace]()

		err := json.Unmarshal(j, &post)
		if err != nil {
			log.Println("Error decoding json while sorting", namespace, ":", err)
			return
		}

		posts = append(posts, post.(editor.Sortable))
	}

	// sort posts
	sort.Sort(posts)

	// store in <namespace>_sorted bucket, first delete existing
	err := store.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte(namespace + "_sorted"))
		if err != nil {
			return err
		}

		// encode to json and store as 'i:post.Time()':post
		for i := range posts {
			j, err := json.Marshal(posts[i])
			if err != nil {
				return err
			}

			cid := fmt.Sprintf("%d:%d", i, posts[i].Time())
			err = b.Put([]byte(cid), j)
			if err != nil {
				return err
			}
		}

		return nil
	})
	if err != nil {
		log.Println("Error while updating db with sorted", namespace, err)
	}

}

type sortablePosts []editor.Sortable

func (s sortablePosts) Len() int {
	return len(s)
}

func (s sortablePosts) Less(i, j int) bool {
	return s[i].Time() > s[j].Time()
}

func (s sortablePosts) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func postToJSON(ns string, data url.Values) ([]byte, error) {
	// find the content type and decode values into it
	ns = strings.TrimSuffix(ns, "_external")
	t, ok := content.Types[ns]
	if !ok {
		return nil, fmt.Errorf(content.ErrTypeNotRegistered, ns)
	}
	post := t()

	dec := schema.NewDecoder()
	dec.SetAliasTag("json")     // allows simpler struct tagging when creating a content type
	dec.IgnoreUnknownKeys(true) // will skip over form values submitted, but not in struct
	err := dec.Decode(post, data)
	if err != nil {
		return nil, err
	}

	slug, err := manager.Slug(post.(editor.Editable))
	if err != nil {
		return nil, err
	}
	post.(editor.Editable).SetSlug(slug)

	// marshall content struct to json for db storage
	j, err := json.Marshal(post)
	if err != nil {
		return nil, err
	}

	return j, nil
}
<commit_msg>need to delete _sorted bucket before re-sorting on delete<commit_after>package db

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/url"
	"sort"
	"strconv"
	"strings"

	"github.com/bosssauce/ponzu/content"
	"github.com/bosssauce/ponzu/management/editor"
	"github.com/bosssauce/ponzu/management/manager"

	"github.com/boltdb/bolt"
	"github.com/gorilla/schema"
)

// SetContent inserts or updates values in the database.
// The `target` argument is a string made up of namespace:id (string:int)
func SetContent(target string, data url.Values) (int, error) {
	t := strings.Split(target, ":")
	ns, id := t[0], t[1]

	// check if content id == -1 (indicating new post).
	// if so, run an insert which will assign the next auto incremented int.
	// this is done because boltdb begins its bucket auto increment value at 0,
	// which is the zero-value of an int in the Item struct field for ID.
	// this is a problem when the original first post (with auto ID = 0) gets
	// overwritten by any new post, originally having no ID, defauting to 0.
	if id == "-1" {
		return insert(ns, data)
	}

	return update(ns, id, data)
}

func update(ns, id string, data url.Values) (int, error) {
	var specifier string // i.e. _pending, _sorted, etc.
	if strings.Contains(ns, "_") {
		spec := strings.Split(ns, "_")
		ns = spec[0]
		specifier = "_" + spec[1]
	}

	cid, err := strconv.Atoi(id)
	if err != nil {
		return 0, err
	}

	err = store.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte(ns + specifier))
		if err != nil {
			return err
		}

		j, err := postToJSON(ns, data)
		if err != nil {
			return err
		}

		err = b.Put([]byte(fmt.Sprintf("%d", cid)), j)
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return 0, nil
	}

	if specifier == "" {
		go SortContent(ns)
	}

	return cid, nil
}

func insert(ns string, data url.Values) (int, error) {
	var effectedID int
	var specifier string // i.e. _pending, _sorted, etc.
	if strings.Contains(ns, "_") {
		spec := strings.Split(ns, "_")
		ns = spec[0]
		specifier = "_" + spec[1]
	}

	err := store.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte(ns + specifier))
		if err != nil {
			return err
		}

		// get the next available ID and convert to string
		// also set effectedID to int of ID
		id, err := b.NextSequence()
		if err != nil {
			return err
		}
		cid := strconv.FormatUint(id, 10)
		effectedID, err = strconv.Atoi(cid)
		if err != nil {
			return err
		}
		data.Set("id", cid)

		j, err := postToJSON(ns, data)
		if err != nil {
			return err
		}

		err = b.Put([]byte(cid), j)
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return 0, err
	}

	if specifier == "" {
		go SortContent(ns)
	}

	return effectedID, nil
}

// DeleteContent removes an item from the database. Deleting a non-existent item
// will return a nil error.
func DeleteContent(target string) error {
	t := strings.Split(target, ":")
	ns, id := t[0], t[1]

	err := store.Update(func(tx *bolt.Tx) error {
		tx.Bucket([]byte(ns)).Delete([]byte(id))
		return nil
	})

	if err != nil {
		return err
	}

	// exception to typical "run in goroutine" pattern:
	// we want to have an updated admin view as soon as this is deleted, so
	// in some cases, the delete and redirect is faster than the sort,
	// thus still showing a deleted post in the admin view.
	SortContent(ns)

	return nil
}

// Content retrives one item from the database. Non-existent values will return an empty []byte
// The `target` argument is a string made up of namespace:id (string:int)
func Content(target string) ([]byte, error) {
	t := strings.Split(target, ":")
	ns, id := t[0], t[1]

	val := &bytes.Buffer{}
	err := store.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(ns))
		_, err := val.Write(b.Get([]byte(id)))
		if err != nil {
			log.Println(err)
			return err
		}

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

	return val.Bytes(), nil
}

// ContentAll retrives all items from the database within the provided namespace
func ContentAll(namespace string) [][]byte {
	var posts [][]byte
	store.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(namespace))

		if b == nil {
			return nil
		}

		numKeys := b.Stats().KeyN
		posts = make([][]byte, 0, numKeys)

		b.ForEach(func(k, v []byte) error {
			posts = append(posts, v)

			return nil
		})

		return nil
	})

	return posts
}

// SortContent sorts all content of the type supplied as the namespace by time,
// in descending order, from most recent to least recent
// Should be called from a goroutine after SetContent is successful
func SortContent(namespace string) {
	all := ContentAll(namespace)

	var posts sortablePosts
	// decode each (json) into type to then sort
	for i := range all {
		j := all[i]
		post := content.Types[namespace]()

		err := json.Unmarshal(j, &post)
		if err != nil {
			log.Println("Error decoding json while sorting", namespace, ":", err)
			return
		}

		posts = append(posts, post.(editor.Sortable))
	}

	// sort posts
	sort.Sort(posts)

	// store in <namespace>_sorted bucket, first delete existing
	err := store.Update(func(tx *bolt.Tx) error {
		bname := []byte(namespace + "_sorted")
		err := tx.DeleteBucket(bname)
		if err != nil {
			return err
		}

		b, err := tx.CreateBucketIfNotExists(bname)
		if err != nil {
			return err
		}

		// encode to json and store as 'i:post.Time()':post
		for i := range posts {
			j, err := json.Marshal(posts[i])
			if err != nil {
				return err
			}

			cid := fmt.Sprintf("%d:%d", i, posts[i].Time())
			err = b.Put([]byte(cid), j)
			if err != nil {
				return err
			}
		}

		return nil
	})
	if err != nil {
		log.Println("Error while updating db with sorted", namespace, err)
	}

}

type sortablePosts []editor.Sortable

func (s sortablePosts) Len() int {
	return len(s)
}

func (s sortablePosts) Less(i, j int) bool {
	return s[i].Time() > s[j].Time()
}

func (s sortablePosts) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func postToJSON(ns string, data url.Values) ([]byte, error) {
	// find the content type and decode values into it
	ns = strings.TrimSuffix(ns, "_external")
	t, ok := content.Types[ns]
	if !ok {
		return nil, fmt.Errorf(content.ErrTypeNotRegistered, ns)
	}
	post := t()

	dec := schema.NewDecoder()
	dec.SetAliasTag("json")     // allows simpler struct tagging when creating a content type
	dec.IgnoreUnknownKeys(true) // will skip over form values submitted, but not in struct
	err := dec.Decode(post, data)
	if err != nil {
		return nil, err
	}

	slug, err := manager.Slug(post.(editor.Editable))
	if err != nil {
		return nil, err
	}
	post.(editor.Editable).SetSlug(slug)

	// marshall content struct to json for db storage
	j, err := json.Marshal(post)
	if err != nil {
		return nil, err
	}

	return j, nil
}
<|endoftext|>


<commit_before>package algoholic

import "testing"

// A simple test which sorts a reversed set of integers and ensures they are correctly sorted
// afterward.
func correctlySortsReversedInts(t *testing.T, max int, doSort func([]int) []int) {
	ns := make([]int, max)

	for i := 0; i < max; i++ {
		ns[i] = max - i
	}

	sorted := doSort(ns)

	for i := 0; i < max; i++ {
		if sorted[i] != i+1 {
			t.Fatalf("Unsorted at index %d: got %d, expected %d.", i, sorted[i], i+1)
		}
	}
}
<commit_msg>Add useful helper function.<commit_after>package algoholic

import "testing"

// A simple test which sorts a reversed set of integers and ensures they are correctly sorted
// afterward.
func correctlySortsReversedInts(t *testing.T, max int, doSort func([]int) []int) {
	ns := make([]int, max)

	for i := 0; i < max; i++ {
		ns[i] = max - i
	}

	sorted := doSort(ns)

	for i := 0; i < max; i++ {
		if sorted[i] != i+1 {
			t.Fatalf("Unsorted at index %d: got %d, expected %d.", i, sorted[i], i+1)
		}
	}
}

func slicesAreEqual(ns1, ns2 []int) bool {
	if ns1 == nil || ns2 == nil || len(ns1) != len(ns2) {
		return false
	}

	for i, n := range ns1 {
		if ns2[i] != n {
			return false
		}
	}

	return true
}
<|endoftext|>


<commit_before>// Copyright 2016 tsuru-client authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"os"

	"github.com/tsuru/tsuru/cmd"
)

const (
	version = "1.0.1-rc1"
	header  = "Supported-Tsuru"
)

func buildManager(name string) *cmd.Manager {
	lookup := func(context *cmd.Context) error {
		return runPlugin(context)
	}
	m := cmd.BuildBaseManager(name, version, header, lookup)
	m.Register(&appRun{})
	m.Register(&appInfo{})
	m.Register(&appCreate{})
	m.Register(&appRemove{})
	m.Register(&appUpdate{})
	m.Register(&unitAdd{})
	m.Register(&unitRemove{})
	m.Register(&appList{})
	m.Register(&appLog{})
	m.Register(&appGrant{})
	m.Register(&appRevoke{})
	m.Register(&appRestart{})
	m.Register(&appStart{})
	m.Register(&appStop{})
	m.RegisterRemoved("app-pool-change", "You should use `tsuru app-update` instead.")
	m.RegisterRemoved("app-plan-change", "You should use `tsuru app-update` instead.")
	m.Register(&cnameAdd{})
	m.Register(&cnameRemove{})
	m.Register(&envGet{})
	m.Register(&envSet{})
	m.Register(&envUnset{})
	m.Register(&keyAdd{})
	m.Register(&keyRemove{})
	m.Register(&keyList{})
	m.Register(serviceList{})
	m.Register(&serviceInstanceAdd{})
	m.RegisterRemoved("service-add", "You should use `tsuru service-instance-add` instead.")
	m.Register(&serviceInstanceUpdate{})
	m.RegisterRemoved("service-update", "You should use `tsuru service-instance-update` instead.")
	m.Register(&serviceInstanceRemove{})
	m.RegisterRemoved("service-remove", "You should use `tsuru service-instance-remove` instead.")
	m.Register(serviceInfo{})
	m.Register(serviceInstanceInfo{})
	m.RegisterRemoved("service-status", "You should use `tsuru service-instance-status` instead.")
	m.Register(serviceInstanceStatus{})
	m.Register(&serviceInstanceGrant{})
	m.Register(&serviceInstanceRevoke{})
	m.Register(&serviceInstanceBind{})
	m.RegisterRemoved("service-bind", "You should use `tsuru service-instance-bind` instead.")
	m.Register(&serviceInstanceUnbind{})
	m.RegisterRemoved("service-unbind", "You should use `tsuru service-instance-unbind` instead.")
	m.Register(platformList{})
	m.Register(&pluginInstall{})
	m.Register(&pluginRemove{})
	m.Register(&pluginList{})
	m.Register(&appSwap{})
	m.Register(&appDeploy{})
	m.Register(&planList{})
	m.RegisterRemoved("app-team-owner-set", "You should use `tsuru service-info` instead.")
	m.Register(&userCreate{})
	m.Register(&resetPassword{})
	m.Register(&userRemove{})
	m.Register(&listUsers{})
	m.Register(&teamCreate{})
	m.Register(&teamRemove{})
	m.Register(&teamList{})
	m.RegisterRemoved("service-doc", "You should use `tsuru service-info` instead.")
	m.RegisterRemoved("team-user-add", "You should use `tsuru role-assign` instead.")
	m.RegisterRemoved("team-user-remove", "You should use `tsuru role-dissociate` instead.")
	m.RegisterRemoved("team-user-list", "You should use `tsuru user-list` instead.")
	m.Register(&changePassword{})
	m.Register(&showAPIToken{})
	m.Register(&regenerateAPIToken{})
	m.Register(&appDeployList{})
	m.Register(&appDeployRollback{})
	m.Register(&cmd.ShellToContainerCmd{})
	m.Register(&poolList{})
	m.Register(&permissionList{})
	m.Register(&roleAdd{})
	m.Register(&roleRemove{})
	m.Register(&roleList{})
	m.Register(&roleInfo{})
	m.Register(&rolePermissionAdd{})
	m.Register(&rolePermissionRemove{})
	m.Register(&roleAssign{})
	m.Register(&roleDissociate{})
	m.Register(&roleDefaultAdd{})
	m.Register(&roleDefaultList{})
	m.Register(&roleDefaultRemove{})
	return m
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	manager.Run(os.Args[1:])
}
<commit_msg>bump to 1.0.1-rc2<commit_after>// Copyright 2016 tsuru-client authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"os"

	"github.com/tsuru/tsuru/cmd"
)

const (
	version = "1.0.1-rc2"
	header  = "Supported-Tsuru"
)

func buildManager(name string) *cmd.Manager {
	lookup := func(context *cmd.Context) error {
		return runPlugin(context)
	}
	m := cmd.BuildBaseManager(name, version, header, lookup)
	m.Register(&appRun{})
	m.Register(&appInfo{})
	m.Register(&appCreate{})
	m.Register(&appRemove{})
	m.Register(&appUpdate{})
	m.Register(&unitAdd{})
	m.Register(&unitRemove{})
	m.Register(&appList{})
	m.Register(&appLog{})
	m.Register(&appGrant{})
	m.Register(&appRevoke{})
	m.Register(&appRestart{})
	m.Register(&appStart{})
	m.Register(&appStop{})
	m.RegisterRemoved("app-pool-change", "You should use `tsuru app-update` instead.")
	m.RegisterRemoved("app-plan-change", "You should use `tsuru app-update` instead.")
	m.Register(&cnameAdd{})
	m.Register(&cnameRemove{})
	m.Register(&envGet{})
	m.Register(&envSet{})
	m.Register(&envUnset{})
	m.Register(&keyAdd{})
	m.Register(&keyRemove{})
	m.Register(&keyList{})
	m.Register(serviceList{})
	m.Register(&serviceInstanceAdd{})
	m.RegisterRemoved("service-add", "You should use `tsuru service-instance-add` instead.")
	m.Register(&serviceInstanceUpdate{})
	m.RegisterRemoved("service-update", "You should use `tsuru service-instance-update` instead.")
	m.Register(&serviceInstanceRemove{})
	m.RegisterRemoved("service-remove", "You should use `tsuru service-instance-remove` instead.")
	m.Register(serviceInfo{})
	m.Register(serviceInstanceInfo{})
	m.RegisterRemoved("service-status", "You should use `tsuru service-instance-status` instead.")
	m.Register(serviceInstanceStatus{})
	m.Register(&serviceInstanceGrant{})
	m.Register(&serviceInstanceRevoke{})
	m.Register(&serviceInstanceBind{})
	m.RegisterRemoved("service-bind", "You should use `tsuru service-instance-bind` instead.")
	m.Register(&serviceInstanceUnbind{})
	m.RegisterRemoved("service-unbind", "You should use `tsuru service-instance-unbind` instead.")
	m.Register(platformList{})
	m.Register(&pluginInstall{})
	m.Register(&pluginRemove{})
	m.Register(&pluginList{})
	m.Register(&appSwap{})
	m.Register(&appDeploy{})
	m.Register(&planList{})
	m.RegisterRemoved("app-team-owner-set", "You should use `tsuru service-info` instead.")
	m.Register(&userCreate{})
	m.Register(&resetPassword{})
	m.Register(&userRemove{})
	m.Register(&listUsers{})
	m.Register(&teamCreate{})
	m.Register(&teamRemove{})
	m.Register(&teamList{})
	m.RegisterRemoved("service-doc", "You should use `tsuru service-info` instead.")
	m.RegisterRemoved("team-user-add", "You should use `tsuru role-assign` instead.")
	m.RegisterRemoved("team-user-remove", "You should use `tsuru role-dissociate` instead.")
	m.RegisterRemoved("team-user-list", "You should use `tsuru user-list` instead.")
	m.Register(&changePassword{})
	m.Register(&showAPIToken{})
	m.Register(&regenerateAPIToken{})
	m.Register(&appDeployList{})
	m.Register(&appDeployRollback{})
	m.Register(&cmd.ShellToContainerCmd{})
	m.Register(&poolList{})
	m.Register(&permissionList{})
	m.Register(&roleAdd{})
	m.Register(&roleRemove{})
	m.Register(&roleList{})
	m.Register(&roleInfo{})
	m.Register(&rolePermissionAdd{})
	m.Register(&rolePermissionRemove{})
	m.Register(&roleAssign{})
	m.Register(&roleDissociate{})
	m.Register(&roleDefaultAdd{})
	m.Register(&roleDefaultList{})
	m.Register(&roleDefaultRemove{})
	return m
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	manager.Run(os.Args[1:])
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"net/http"
	"strings"

	"github.com/tsuru/tsuru/cmd"
)

type poolList struct{}

type PoolsByTeam struct {
	Team  string
	Pools []string
}

type Pool struct {
	Name string
}

type ListPoolResponse struct {
	PoolsByTeam  []PoolsByTeam `json:"pools_by_team"`
	PublicPools  []Pool        `json:"public_pools"`
	DefaultPools []Pool        `json:"default_pool"`
}

func (poolList) Run(context *cmd.Context, client *cmd.Client) error {
	url, err := cmd.GetURL("/pools")
	if err != nil {
		return err
	}
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return err
	}
	resp, err := client.Do(request)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	var pools ListPoolResponse
	err = json.NewDecoder(resp.Body).Decode(&pools)
	if err != nil {
		return err
	}
	t := cmd.Table{Headers: cmd.Row([]string{"Team", "Pools"})}
	for _, pool := range pools.PoolsByTeam {
		t.AddRow(cmd.Row([]string{pool.Team, strings.Join(pool.Pools, ", ")}))
	}
	t.Sort()
	context.Stdout.Write(t.Bytes())
	tp := cmd.Table{Headers: cmd.Row([]string{"Public Pools"})}
	for _, pool := range pools.PublicPools {
		tp.AddRow(cmd.Row([]string{pool.Name}))
	}
	tp.Sort()
	context.Stdout.Write([]byte("\n"))
	context.Stdout.Write(tp.Bytes())
	if len(pools.DefaultPools) > 0 {
		td := cmd.Table{Headers: cmd.Row([]string{"Default Pool"})}
		td.AddRow(cmd.Row([]string{pools.DefaultPools[0].Name}))
		context.Stdout.Write([]byte("\n"))
		context.Stdout.Write(td.Bytes())
	}
	return nil
}

func (poolList) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "pool-list",
		Usage:   "pool-list",
		Desc:    "List all pools available for deploy.",
		MinArgs: 0,
	}
}
<commit_msg>tsuru/pool: add license header.<commit_after>// Copyright 2016 tsuru-client authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.package main

import (
	"encoding/json"
	"net/http"
	"strings"

	"github.com/tsuru/tsuru/cmd"
)

type poolList struct{}

type PoolsByTeam struct {
	Team  string
	Pools []string
}

type Pool struct {
	Name string
}

type ListPoolResponse struct {
	PoolsByTeam  []PoolsByTeam `json:"pools_by_team"`
	PublicPools  []Pool        `json:"public_pools"`
	DefaultPools []Pool        `json:"default_pool"`
}

func (poolList) Run(context *cmd.Context, client *cmd.Client) error {
	url, err := cmd.GetURL("/pools")
	if err != nil {
		return err
	}
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return err
	}
	resp, err := client.Do(request)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	var pools ListPoolResponse
	err = json.NewDecoder(resp.Body).Decode(&pools)
	if err != nil {
		return err
	}
	t := cmd.Table{Headers: cmd.Row([]string{"Team", "Pools"})}
	for _, pool := range pools.PoolsByTeam {
		t.AddRow(cmd.Row([]string{pool.Team, strings.Join(pool.Pools, ", ")}))
	}
	t.Sort()
	context.Stdout.Write(t.Bytes())
	tp := cmd.Table{Headers: cmd.Row([]string{"Public Pools"})}
	for _, pool := range pools.PublicPools {
		tp.AddRow(cmd.Row([]string{pool.Name}))
	}
	tp.Sort()
	context.Stdout.Write([]byte("\n"))
	context.Stdout.Write(tp.Bytes())
	if len(pools.DefaultPools) > 0 {
		td := cmd.Table{Headers: cmd.Row([]string{"Default Pool"})}
		td.AddRow(cmd.Row([]string{pools.DefaultPools[0].Name}))
		context.Stdout.Write([]byte("\n"))
		context.Stdout.Write(td.Bytes())
	}
	return nil
}

func (poolList) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "pool-list",
		Usage:   "pool-list",
		Desc:    "List all pools available for deploy.",
		MinArgs: 0,
	}
}
<|endoftext|>


<commit_before>package sweetiebot

import (
  "strings"
  "strconv"
  "os/exec"
  "os"
)

type EchoCommand struct {
}

func (c *EchoCommand) Name() string {
  return "Echo";
}
func (c *EchoCommand) Process(args []string) string {
  if len(args) == 0 {
    return "```You have to tell me to say something, silly!```"
  }
  return "```" + strings.Join(args, " ") + "```";
}
func (c *EchoCommand) Usage() string {
  return FormatUsage(c, "[#channel] [string]", "Makes Sweetie Bot say the given sentence in #channel, or in the current channel if no argument is provided.")
}
func (c *EchoCommand) UsageShort() string { return "Makes Sweetie Bot say something in the given channel." }
func (c *EchoCommand) Roles() []string { return []string{"Princesses", "Royal Guard", "Night Guard"} }

func SetCommandEnable(args []string, enable bool, success string) string {
  if len(args) == 0 {
    return "No module specified.\n\n" + GetActiveModules()
  }
  name := strings.ToLower(args[0])
  for _, v := range sb.modules {
    if strings.ToLower(v.Name()) == name {
      v.Enable(enable)
      if v.IsEnabled() != enable {
        return "Could not enable/disable " + args[0] + " module. Is this a restricted module?"
      }
      return args[0] + success + "\n\n" + GetActiveModules()
    }
  }
  return "The " + args[0] + " module does not exist.\n\n" + GetActiveModules()
}

type DisableCommand struct {
}

func (c *DisableCommand) Name() string {
  return "Disable";
}
func (c *DisableCommand) Process(args []string) string {
  return "```" + SetCommandEnable(args, false, " was disabled.") + "```"
}
func (c *DisableCommand) Usage() string {
  return FormatUsage(c, "[module]", "Disables the given module, if possible. If the module is already disabled, does nothing.")
}
func (c *DisableCommand) UsageShort() string { return "Disables the given module, if possible." }
func (c *DisableCommand) Roles() []string { return []string{"Princesses", "Royal Guard"} }

type EnableCommand struct {
}

func (c *EnableCommand) Name() string {
  return "Enable";
}
func (c *EnableCommand) Process(args []string) string {
  return "```" + SetCommandEnable(args, true, " was enabled.") + "```"
}
func (c *EnableCommand) Usage() string {
  return FormatUsage(c, "[module]", "Disables the given module. If the module is already enabled, does nothing.")
}
func (c *EnableCommand) UsageShort() string { return "Enables the given module." }
func (c *EnableCommand) Roles() []string { return []string{"Princesses", "Royal Guard"} }

type UpdateCommand struct {
}

func (c *UpdateCommand) Name() string {
  return "Update";
}
func (c *UpdateCommand) Process(args []string) string {
  err := exec.Command("./update.sh", strconv.Itoa(os.Getpid())).Start()
  if err != nil {
    sb.log.Log("Command.Start() error: ", err.Error())
    return "```Could not start update script!```"
  }
  return "```Shutting down for update...```"
}
func (c *UpdateCommand) Usage() string {
  return FormatUsage(c, "", "Tells sweetiebot to shut down, calls an update script, rebuilds the code, and then restarts.")
}
func (c *UpdateCommand) UsageShort() string { return "Updates sweetiebot." }
func (c *UpdateCommand) Roles() []string { return []string{"Princesses"} }<commit_msg>actually shut down<commit_after>package sweetiebot

import (
  "strings"
  "strconv"
  "os/exec"
  "os"
)

type EchoCommand struct {
}

func (c *EchoCommand) Name() string {
  return "Echo";
}
func (c *EchoCommand) Process(args []string) string {
  if len(args) == 0 {
    return "```You have to tell me to say something, silly!```"
  }
  return "```" + strings.Join(args, " ") + "```";
}
func (c *EchoCommand) Usage() string {
  return FormatUsage(c, "[#channel] [string]", "Makes Sweetie Bot say the given sentence in #channel, or in the current channel if no argument is provided.")
}
func (c *EchoCommand) UsageShort() string { return "Makes Sweetie Bot say something in the given channel." }
func (c *EchoCommand) Roles() []string { return []string{"Princesses", "Royal Guard", "Night Guard"} }

func SetCommandEnable(args []string, enable bool, success string) string {
  if len(args) == 0 {
    return "No module specified.\n\n" + GetActiveModules()
  }
  name := strings.ToLower(args[0])
  for _, v := range sb.modules {
    if strings.ToLower(v.Name()) == name {
      v.Enable(enable)
      if v.IsEnabled() != enable {
        return "Could not enable/disable " + args[0] + " module. Is this a restricted module?"
      }
      return args[0] + success + "\n\n" + GetActiveModules()
    }
  }
  return "The " + args[0] + " module does not exist.\n\n" + GetActiveModules()
}

type DisableCommand struct {
}

func (c *DisableCommand) Name() string {
  return "Disable";
}
func (c *DisableCommand) Process(args []string) string {
  return "```" + SetCommandEnable(args, false, " was disabled.") + "```"
}
func (c *DisableCommand) Usage() string {
  return FormatUsage(c, "[module]", "Disables the given module, if possible. If the module is already disabled, does nothing.")
}
func (c *DisableCommand) UsageShort() string { return "Disables the given module, if possible." }
func (c *DisableCommand) Roles() []string { return []string{"Princesses", "Royal Guard"} }

type EnableCommand struct {
}

func (c *EnableCommand) Name() string {
  return "Enable";
}
func (c *EnableCommand) Process(args []string) string {
  return "```" + SetCommandEnable(args, true, " was enabled.") + "```"
}
func (c *EnableCommand) Usage() string {
  return FormatUsage(c, "[module]", "Disables the given module. If the module is already enabled, does nothing.")
}
func (c *EnableCommand) UsageShort() string { return "Enables the given module." }
func (c *EnableCommand) Roles() []string { return []string{"Princesses", "Royal Guard"} }

type UpdateCommand struct {
}

func (c *UpdateCommand) Name() string {
  return "Update";
}
func (c *UpdateCommand) Process(args []string) string {
  sb.log.Log("Update command called, current PID: ", os.Getpid())
  err := exec.Command("./update.sh", strconv.Itoa(os.Getpid())).Start()
  if err != nil {
    sb.log.Log("Command.Start() error: ", err.Error())
    return "```Could not start update script!```"
  }
  sb.quit = true
  return "```Shutting down for update...```"
}
func (c *UpdateCommand) Usage() string {
  return FormatUsage(c, "", "Tells sweetiebot to shut down, calls an update script, rebuilds the code, and then restarts.")
}
func (c *UpdateCommand) UsageShort() string { return "Updates sweetiebot." }
func (c *UpdateCommand) Roles() []string { return []string{"Princesses"} }<|endoftext|>


<commit_before>package twitch

import (
	"bufio"
	"fmt"
	"net"
	"net/textproto"
	"regexp"
	"strings"
	"gopkg.in/redis.v5"
	"github.com/op/go-logging"
)

type Bot struct {
	Messages chan Message
	ircAddress string
	ircUser string
	ircToken string
	rClient redis.Client
	logger logging.Logger
	channels map[Channel]bool
}

var (
	mainConn   *net.Conn
	userReg        = regexp.MustCompile(`:\w+!\w+@\w+\.tmi\.twitch\.tv`)
	channelReg  = regexp.MustCompile(`#\w+\s:`)
	actionReg    = regexp.MustCompile(`^\x{0001}ACTION\s`)
	actionReg2  = regexp.MustCompile(`([\x{0001}]+)`)
)

func NewBot(ircAddress string, ircUser string, ircToken string, rClient redis.Client, logger logging.Logger) Bot {
	channels := make(map[Channel]bool)
	channels[NewChannel(ircUser)] = true

	return Bot{
		Messages: make(chan Message),
		ircAddress: ircAddress,
		ircUser: strings.ToLower(ircUser),
		ircToken: ircToken,
		rClient: rClient,
		logger: logger,
		channels: channels,
	}
}

func (bot *Bot) Say(channel Channel, text string, adminCommand bool) {
	if !bot.channels[channel] && !adminCommand {
		return
	}
	fmt.Fprintf(*mainConn, "PRIVMSG %s :%s\r\n", channel.Name, text)
}

func (bot *Bot) CreateConnection() error {
	conn, err := net.Dial("tcp", bot.ircAddress)
	mainConn = &conn
	if err != nil {
		bot.logger.Error(err.Error())
		return err
	}
	fmt.Fprintf(*mainConn, "PASS %s\r\n", bot.ircToken)
	fmt.Fprintf(*mainConn, "NICK %s\r\n", bot.ircUser)
	fmt.Fprint(*mainConn, "CAP REQ :twitch.tv/tags\r\n")
	fmt.Fprint(*mainConn, "CAP REQ :twitch.tv/commands\r\n")
	fmt.Fprintf(*mainConn, "JOIN %s\r\n", "#" + bot.ircUser)

	go bot.joinDefault()

	reader := bufio.NewReader(conn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			bot.logger.Error(err.Error())
			return err
		}
		messages := strings.Split(line, "\r\n")
		if len(messages) == 0 {
			continue
		}
		for _, msg := range messages {
			if strings.Contains(msg, ".tmi.twitch.tv PRIVMSG ") {
				bot.Messages <- parseMessage(msg)
			}
		}
	}
	defer bot.CreateConnection()
	return nil
}

func (bot *Bot) joinDefault() {
	val,_ := bot.rClient.HGetAll("channels").Result()
	for channelStr, activeNum := range val {
		channel := NewChannel(channelStr)
		active := false
		if activeNum == "1" {
			active = true
		}
		bot.channels[channel] = active
		go bot.join(channel)
	}
}

func (bot *Bot) join(channel Channel) {
	fmt.Fprintf(*mainConn, "JOIN %s\r\n", channel.Name)
}<commit_msg>added ping<commit_after>package twitch

import (
	"bufio"
	"fmt"
	"net"
	"net/textproto"
	"regexp"
	"strings"
	"gopkg.in/redis.v5"
	"github.com/op/go-logging"
)

type Bot struct {
	Messages chan Message
	ircAddress string
	ircUser string
	ircToken string
	rClient redis.Client
	logger logging.Logger
	channels map[Channel]bool
}

var (
	mainConn   *net.Conn
	userReg        = regexp.MustCompile(`:\w+!\w+@\w+\.tmi\.twitch\.tv`)
	channelReg  = regexp.MustCompile(`#\w+\s:`)
	actionReg    = regexp.MustCompile(`^\x{0001}ACTION\s`)
	actionReg2  = regexp.MustCompile(`([\x{0001}]+)`)
)

func NewBot(ircAddress string, ircUser string, ircToken string, rClient redis.Client, logger logging.Logger) Bot {
	channels := make(map[Channel]bool)
	channels[NewChannel(ircUser)] = true

	return Bot{
		Messages: make(chan Message),
		ircAddress: ircAddress,
		ircUser: strings.ToLower(ircUser),
		ircToken: ircToken,
		rClient: rClient,
		logger: logger,
		channels: channels,
	}
}

func (bot *Bot) Say(channel Channel, text string, adminCommand bool) {
	if !bot.channels[channel] && !adminCommand {
		return
	}
	fmt.Fprintf(*mainConn, "PRIVMSG %s :%s\r\n", channel.Name, text)
}

func (bot *Bot) CreateConnection() error {
	conn, err := net.Dial("tcp", bot.ircAddress)
	mainConn = &conn
	if err != nil {
		bot.logger.Error(err.Error())
		return err
	}
	fmt.Fprintf(*mainConn, "PASS %s\r\n", bot.ircToken)
	fmt.Fprintf(*mainConn, "NICK %s\r\n", bot.ircUser)
	fmt.Fprint(*mainConn, "CAP REQ :twitch.tv/tags\r\n")
	fmt.Fprint(*mainConn, "CAP REQ :twitch.tv/commands\r\n")
	fmt.Fprintf(*mainConn, "JOIN %s\r\n", "#" + bot.ircUser)

	go bot.joinDefault()

	reader := bufio.NewReader(*mainConn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			bot.logger.Error(err.Error())
			return err
		}
		messages := strings.Split(line, "\r\n")
		if len(messages) == 0 {
			continue
		}
		for _, msg := range messages {
			if strings.HasPrefix(line, "PING") {
				fmt.Fprintf(*mainConn, strings.Replace(line, "PING", "PONG", 1))
			}
			if strings.Contains(msg, ".tmi.twitch.tv PRIVMSG ") {
				bot.Messages <- parseMessage(msg)
			}

		}
	}
	defer bot.CreateConnection()
	return nil
}

func (bot *Bot) joinDefault() {
	val,_ := bot.rClient.HGetAll("channels").Result()
	for channelStr, activeNum := range val {
		channel := NewChannel(channelStr)
		active := false
		if activeNum == "1" {
			active = true
		}
		bot.channels[channel] = active
		go bot.join(channel)
	}
}

func (bot *Bot) join(channel Channel) {
	fmt.Fprintf(*mainConn, "JOIN %s\r\n", channel.Name)
}<|endoftext|>