<commit_before>package RethinkDBStorage

import (
	"github.com/ahmet/osin-rethinkdb/Godeps/_workspace/src/github.com/RangelReale/osin"
	"github.com/ahmet/osin-rethinkdb/Godeps/_workspace/src/github.com/mitchellh/mapstructure"
	r "github.com/ahmet/osin-rethinkdb/Godeps/_workspace/src/gopkg.in/dancannon/gorethink.v1"
)

const (
	clientsTable      = "oauth_clients"
	authorizeTable    = "oauth_authorize_data"
	accessTable       = "oauth_access_data"
	accessTokenField  = "AccessToken"
	refreshTokenField = "RefreshToken"
)

// RethinkDBStorage implements storage for osin
type RethinkDBStorage struct {
	dbName  string
	session *r.Session
}

// New initializes and returns a new RethinkDBStorage
func New(session *r.Session, dbName string) *RethinkDBStorage {
	storage := &RethinkDBStorage{dbName, session}
	return storage
}

// CreateClient inserts a new client
func (s *RethinkDBStorage) CreateClient(c osin.Client) error {
	_, err := r.Table(clientsTable).Insert(c).RunWrite(s.session)
	return err
}

// GetClient returns client with given ID
func (s *RethinkDBStorage) GetClient(clientID string) (*osin.DefaultClient, error) {
	result, err := r.Table(clientsTable).Filter(r.Row.Field("Id").Eq(clientID)).Run(s.session)
	if err != nil {
		return nil, err
	}
	defer result.Close()

	var clientMap map[string]interface{}
	err = result.One(&clientMap)
	if err != nil {
		return nil, err
	}

	var clientStruct osin.DefaultClient
	err = mapstructure.Decode(clientMap, &clientStruct)
	if err != nil {
		return nil, err
	}

	return &clientStruct, nil
}

// UpdateClient updates given client
func (s *RethinkDBStorage) UpdateClient(c osin.Client) error {
	result, err := r.Table(clientsTable).Filter(r.Row.Field("Id").Eq(c.GetId())).Run(s.session)
	if err != nil {
		return err
	}
	defer result.Close()

	var clientMap map[string]interface{}
	err = result.One(&clientMap)
	if err != nil {
		return err
	}

	_, err = r.Table(clientsTable).Get(clientMap["id"]).Update(c).RunWrite(s.session)
	return err
}

// DeleteClient deletes given client
func (s *RethinkDBStorage) DeleteClient(c osin.Client) error {
	result, err := r.Table(clientsTable).Filter(r.Row.Field("Id").Eq(c.GetId())).Run(s.session)
	if err != nil {
		return err
	}
	defer result.Close()

	var clientMap map[string]interface{}
	err = result.One(&clientMap)
	if err != nil {
		return err
	}

	_, err = r.Table(clientsTable).Get(clientMap["id"]).Delete().RunWrite(s.session)
	return err
}

// SaveAuthorize creates a new authorization
func (s *RethinkDBStorage) SaveAuthorize(data *osin.AuthorizeData) error {
	_, err := r.Table(authorizeTable).Insert(data).RunWrite(s.session)
	return err
}

// LoadAuthorize gets authorization data with given code
func (s *RethinkDBStorage) LoadAuthorize(code string) (*osin.AuthorizeData, error) {
	result, err := r.Table(authorizeTable).Filter(r.Row.Field("Code").Eq(code)).Run(s.session)
	if err != nil {
		return nil, err
	}
	defer result.Close()

	var dataMap map[string]interface{}
	err = result.One(&dataMap)
	if err != nil {
		return nil, err
	}

	var client *osin.DefaultClient
	clientID := dataMap["Client"].(map[string]interface{})["Id"].(string)
	client, err = s.GetClient(clientID)
	if err != nil {
		return nil, err
	}
	dataMap["Client"] = client

	var dataStruct osin.AuthorizeData
	err = mapstructure.Decode(dataMap, &dataStruct)
	if err != nil {
		return nil, err
	}

	return &dataStruct, nil
}

// RemoveAuthorize deletes given authorization
func (s *RethinkDBStorage) RemoveAuthorize(code string) error {
	result, err := r.Table(authorizeTable).Filter(r.Row.Field("Code").Eq(code)).Run(s.session)
	if err != nil {
		return err
	}
	defer result.Close()

	var dataMap map[string]interface{}
	err = result.One(&dataMap)
	if err != nil {
		return err
	}

	_, err = r.Table(authorizeTable).Get(dataMap["id"]).Delete().RunWrite(s.session)
	return err
}

// SaveAccess creates a new access data
func (s *RethinkDBStorage) SaveAccess(data *osin.AccessData) error {
	_, err := r.Table(accessTable).Insert(data).RunWrite(s.session)
	return err
}

// LoadAccess gets access data with given access token
func (s *RethinkDBStorage) LoadAccess(accessToken string) (*osin.AccessData, error) {
	return s.getAccessData(accessTokenField, accessToken)
}

// RemoveAccess deletes AccessData with given access token
func (s *RethinkDBStorage) RemoveAccess(accessToken string) error {
	return s.removeAccessData(accessTokenField, accessToken)
}

// LoadRefresh gets access data with given refresh token
func (s *RethinkDBStorage) LoadRefresh(refreshToken string) (*osin.AccessData, error) {
	return s.getAccessData(refreshTokenField, refreshToken)
}

// RemoveRefresh deletes AccessData with given refresh token
func (s *RethinkDBStorage) RemoveRefresh(refreshToken string) error {
	return s.removeAccessData(refreshTokenField, refreshToken)
}

// getAccessData is a common function to get AccessData by field
func (s *RethinkDBStorage) getAccessData(fieldName, token string) (*osin.AccessData, error) {
	result, err := r.Table(accessTable).Filter(r.Row.Field(fieldName).Eq(token)).Run(s.session)
	if err != nil {
		return nil, err
	}
	defer result.Close()

	var dataMap map[string]interface{}
	err = result.One(&dataMap)
	if err != nil {
		return nil, err
	}

	var client *osin.DefaultClient
	clientID := dataMap["Client"].(map[string]interface{})["Id"].(string)
	client, err = s.GetClient(clientID)
	if err != nil {
		return nil, err
	}
	dataMap["Client"] = client

	var authorizeDataClient *osin.DefaultClient
	clientID = dataMap["AuthorizeData"].(map[string]interface{})["Client"].(map[string]interface{})["Id"].(string)
	authorizeDataClient, err = s.GetClient(clientID)
	if err != nil {
		return nil, err
	}
	dataMap["AuthorizeData"].(map[string]interface{})["Client"] = authorizeDataClient

	var dataStruct osin.AccessData
	err = mapstructure.Decode(dataMap, &dataStruct)
	if err != nil {
		return nil, err
	}

	return &dataStruct, nil
}

// removeAccessData is a common function to remove AccessData by field
func (s *RethinkDBStorage) removeAccessData(fieldName, token string) error {
	result, err := r.Table(accessTable).Filter(r.Row.Field(fieldName).Eq(token)).Run(s.session)
	if err != nil {
		return err
	}
	defer result.Close()

	var dataMap map[string]interface{}
	err = result.One(&dataMap)
	if err != nil {
		return err
	}

	_, err = r.Table(accessTable).Get(dataMap["id"]).Delete().RunWrite(s.session)
	return err
}
<commit_msg>Remove obsolete variable.<commit_after>package RethinkDBStorage

import (
	"github.com/ahmet/osin-rethinkdb/Godeps/_workspace/src/github.com/RangelReale/osin"
	"github.com/ahmet/osin-rethinkdb/Godeps/_workspace/src/github.com/mitchellh/mapstructure"
	r "github.com/ahmet/osin-rethinkdb/Godeps/_workspace/src/gopkg.in/dancannon/gorethink.v1"
)

const (
	clientsTable      = "oauth_clients"
	authorizeTable    = "oauth_authorize_data"
	accessTable       = "oauth_access_data"
	accessTokenField  = "AccessToken"
	refreshTokenField = "RefreshToken"
)

// RethinkDBStorage implements storage for osin
type RethinkDBStorage struct {
	session *r.Session
}

// New initializes and returns a new RethinkDBStorage
func New(session *r.Session) *RethinkDBStorage {
	storage := &RethinkDBStorage{session}
	return storage
}

// CreateClient inserts a new client
func (s *RethinkDBStorage) CreateClient(c osin.Client) error {
	_, err := r.Table(clientsTable).Insert(c).RunWrite(s.session)
	return err
}

// GetClient returns client with given ID
func (s *RethinkDBStorage) GetClient(clientID string) (*osin.DefaultClient, error) {
	result, err := r.Table(clientsTable).Filter(r.Row.Field("Id").Eq(clientID)).Run(s.session)
	if err != nil {
		return nil, err
	}
	defer result.Close()

	var clientMap map[string]interface{}
	err = result.One(&clientMap)
	if err != nil {
		return nil, err
	}

	var clientStruct osin.DefaultClient
	err = mapstructure.Decode(clientMap, &clientStruct)
	if err != nil {
		return nil, err
	}

	return &clientStruct, nil
}

// UpdateClient updates given client
func (s *RethinkDBStorage) UpdateClient(c osin.Client) error {
	result, err := r.Table(clientsTable).Filter(r.Row.Field("Id").Eq(c.GetId())).Run(s.session)
	if err != nil {
		return err
	}
	defer result.Close()

	var clientMap map[string]interface{}
	err = result.One(&clientMap)
	if err != nil {
		return err
	}

	_, err = r.Table(clientsTable).Get(clientMap["id"]).Update(c).RunWrite(s.session)
	return err
}

// DeleteClient deletes given client
func (s *RethinkDBStorage) DeleteClient(c osin.Client) error {
	result, err := r.Table(clientsTable).Filter(r.Row.Field("Id").Eq(c.GetId())).Run(s.session)
	if err != nil {
		return err
	}
	defer result.Close()

	var clientMap map[string]interface{}
	err = result.One(&clientMap)
	if err != nil {
		return err
	}

	_, err = r.Table(clientsTable).Get(clientMap["id"]).Delete().RunWrite(s.session)
	return err
}

// SaveAuthorize creates a new authorization
func (s *RethinkDBStorage) SaveAuthorize(data *osin.AuthorizeData) error {
	_, err := r.Table(authorizeTable).Insert(data).RunWrite(s.session)
	return err
}

// LoadAuthorize gets authorization data with given code
func (s *RethinkDBStorage) LoadAuthorize(code string) (*osin.AuthorizeData, error) {
	result, err := r.Table(authorizeTable).Filter(r.Row.Field("Code").Eq(code)).Run(s.session)
	if err != nil {
		return nil, err
	}
	defer result.Close()

	var dataMap map[string]interface{}
	err = result.One(&dataMap)
	if err != nil {
		return nil, err
	}

	var client *osin.DefaultClient
	clientID := dataMap["Client"].(map[string]interface{})["Id"].(string)
	client, err = s.GetClient(clientID)
	if err != nil {
		return nil, err
	}
	dataMap["Client"] = client

	var dataStruct osin.AuthorizeData
	err = mapstructure.Decode(dataMap, &dataStruct)
	if err != nil {
		return nil, err
	}

	return &dataStruct, nil
}

// RemoveAuthorize deletes given authorization
func (s *RethinkDBStorage) RemoveAuthorize(code string) error {
	result, err := r.Table(authorizeTable).Filter(r.Row.Field("Code").Eq(code)).Run(s.session)
	if err != nil {
		return err
	}
	defer result.Close()

	var dataMap map[string]interface{}
	err = result.One(&dataMap)
	if err != nil {
		return err
	}

	_, err = r.Table(authorizeTable).Get(dataMap["id"]).Delete().RunWrite(s.session)
	return err
}

// SaveAccess creates a new access data
func (s *RethinkDBStorage) SaveAccess(data *osin.AccessData) error {
	_, err := r.Table(accessTable).Insert(data).RunWrite(s.session)
	return err
}

// LoadAccess gets access data with given access token
func (s *RethinkDBStorage) LoadAccess(accessToken string) (*osin.AccessData, error) {
	return s.getAccessData(accessTokenField, accessToken)
}

// RemoveAccess deletes AccessData with given access token
func (s *RethinkDBStorage) RemoveAccess(accessToken string) error {
	return s.removeAccessData(accessTokenField, accessToken)
}

// LoadRefresh gets access data with given refresh token
func (s *RethinkDBStorage) LoadRefresh(refreshToken string) (*osin.AccessData, error) {
	return s.getAccessData(refreshTokenField, refreshToken)
}

// RemoveRefresh deletes AccessData with given refresh token
func (s *RethinkDBStorage) RemoveRefresh(refreshToken string) error {
	return s.removeAccessData(refreshTokenField, refreshToken)
}

// getAccessData is a common function to get AccessData by field
func (s *RethinkDBStorage) getAccessData(fieldName, token string) (*osin.AccessData, error) {
	result, err := r.Table(accessTable).Filter(r.Row.Field(fieldName).Eq(token)).Run(s.session)
	if err != nil {
		return nil, err
	}
	defer result.Close()

	var dataMap map[string]interface{}
	err = result.One(&dataMap)
	if err != nil {
		return nil, err
	}

	var client *osin.DefaultClient
	clientID := dataMap["Client"].(map[string]interface{})["Id"].(string)
	client, err = s.GetClient(clientID)
	if err != nil {
		return nil, err
	}
	dataMap["Client"] = client

	var authorizeDataClient *osin.DefaultClient
	clientID = dataMap["AuthorizeData"].(map[string]interface{})["Client"].(map[string]interface{})["Id"].(string)
	authorizeDataClient, err = s.GetClient(clientID)
	if err != nil {
		return nil, err
	}
	dataMap["AuthorizeData"].(map[string]interface{})["Client"] = authorizeDataClient

	var dataStruct osin.AccessData
	err = mapstructure.Decode(dataMap, &dataStruct)
	if err != nil {
		return nil, err
	}

	return &dataStruct, nil
}

// removeAccessData is a common function to remove AccessData by field
func (s *RethinkDBStorage) removeAccessData(fieldName, token string) error {
	result, err := r.Table(accessTable).Filter(r.Row.Field(fieldName).Eq(token)).Run(s.session)
	if err != nil {
		return err
	}
	defer result.Close()

	var dataMap map[string]interface{}
	err = result.One(&dataMap)
	if err != nil {
		return err
	}

	_, err = r.Table(accessTable).Get(dataMap["id"]).Delete().RunWrite(s.session)
	return err
}
<|endoftext|>


<commit_before>// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

package main

import (
	"fmt"

	"github.com/go-vgo/robotgo"
	// "go-vgo/robotgo"
)

func addEvent() {
	fmt.Println("--- Please press ctrl + shift + q ---")
	ok := robotgo.AddEvents("q", "ctrl", "shift")
	if ok {
		fmt.Println("add events...")
	}

	fmt.Println("--- Please press w---")
	ok = robotgo.AddEvents("w")
	if ok {
		fmt.Println("add events")
	}

	s := robotgo.Start()
	defer robotgo.End()

	for ev := range s {
		fmt.Println(ev)
	}
}

func add() {
	fmt.Println("--- Please press v---")
	eve := robotgo.AddEvent("v")

	if eve {
		fmt.Println("--- You press v---", "v")
	}

	fmt.Println("--- Please press k---")
	keve := robotgo.AddEvent("k")
	if keve {
		fmt.Println("--- You press k---", "k")
	}

	fmt.Println("--- Please press f1---")
	feve := robotgo.AddEvent("f1")
	if feve {
		fmt.Println("You press...", "f1")
	}
}

func event() {
	////////////////////////////////////////////////////////////////////////////////
	// Global event listener
	////////////////////////////////////////////////////////////////////////////////

	add()

	fmt.Println("--- Please press left mouse button---")
	mleft := robotgo.AddEvent("mleft")
	if mleft {
		fmt.Println("--- You press left mouse button---", "mleft")
	}

	mright := robotgo.AddEvent("mright")
	if mright {
		fmt.Println("--- You press right mouse button---", "mright")
	}

	// stop AddEvent
	// robotgo.StopEvent()
}

func main() {
	fmt.Println("test begin...")

	addEvent()

	event()
}
<commit_msg>update example, add godoc<commit_after>// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

package main

import (
	"fmt"

	"github.com/go-vgo/robotgo"
	// "go-vgo/robotgo"
)

func addEvent() {
	fmt.Println("--- Please press ctrl + shift + q ---")
	ok := robotgo.AddEvents("q", "ctrl", "shift")
	if ok {
		fmt.Println("add events...")
	}

	fmt.Println("--- Please press w---")
	ok = robotgo.AddEvents("w")
	if ok {
		fmt.Println("add events")
	}

	// start hook
	s := robotgo.Start()
	// end hook
	defer robotgo.End()

	for ev := range s {
		fmt.Println(ev)
	}
}

func add() {
	fmt.Println("--- Please press v---")
	eve := robotgo.AddEvent("v")

	if eve {
		fmt.Println("--- You press v---", "v")
	}

	fmt.Println("--- Please press k---")
	keve := robotgo.AddEvent("k")
	if keve {
		fmt.Println("--- You press k---", "k")
	}

	fmt.Println("--- Please press f1---")
	feve := robotgo.AddEvent("f1")
	if feve {
		fmt.Println("You press...", "f1")
	}
}

func event() {
	////////////////////////////////////////////////////////////////////////////////
	// Global event listener
	////////////////////////////////////////////////////////////////////////////////

	add()

	fmt.Println("--- Please press left mouse button---")
	mleft := robotgo.AddEvent("mleft")
	if mleft {
		fmt.Println("--- You press left mouse button---", "mleft")
	}

	mright := robotgo.AddEvent("mright")
	if mright {
		fmt.Println("--- You press right mouse button---", "mright")
	}

	// stop AddEvent
	// robotgo.StopEvent()
}

func main() {
	fmt.Println("test begin...")

	addEvent()

	event()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"koding/db/models"
	mm "koding/db/mongodb"
	helper "koding/db/mongodb/modelhelper"
	"koding/tools/config"
	"koding/tools/logger"
	"time"

	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

var log = logger.New("post truncator")

type strToInf map[string]interface{}

var (
	MAX_ITERATION_COUNT = 50
	conf                *config.Config
	SLEEPING_TIME       = 10 * time.Millisecond
	oneMonthAgo         = time.Now().Add(-time.Hour * 24 * 30).UTC()
	flagProfile         = flag.String("c", "vagrant", "Configuration profile from file")
	flagSkip            = flag.Int("s", 0, "Configuration profile from file")
	flagLimit           = flag.Int("l", 1000, "Configuration profile from file")
	mongodb             *mm.MongoDB
	deletedItems        = 0
)

func main() {
	log.SetLevel(logger.DEBUG)
	flag.Parse()
	if *flagProfile == "" {
		log.Fatal("Please specify profile via -c. Aborting.")
	}

	conf = config.MustConfig(*flagProfile)
	helper.Initialize(conf.Mongo)
	log.Info("Sync worker started")
	mongodb = helper.Mongo
	for _, coll := range ToBeDTruncatedNames {
		collName := coll
		err := mongodb.Run(collName, createQuery(collName))
		if err != nil {
			log.Fatal("Connecting to Mongo: %v", err)
		}
	}

}

func createQuery(collectionName string) func(coll *mgo.Collection) error {
	return func(coll *mgo.Collection) error {

		query := coll.Find(helper.Selector{})
		totalCount, err := query.Count()
		if err != nil {
			log.Error("While getting count, exiting: %v", err)
			return err
		}

		if totalCount == 0 {
			fmt.Println("Collection is empty ", collectionName)
			log.Info("deleted item count %v", deletedItems)
			return nil
		}

		skip := *flagSkip
		// this is a starting point
		index := skip
		// this is the item count to be processed
		limit := *flagLimit
		// this will be the ending point
		count := index + limit

		var result map[string]interface{}

		iteration := 0
		for {
			// if we reach to the end of the all collection, exit
			if index >= totalCount {
				log.Info("All items are processed, exiting")
				break
			}

			// this is the max re-iterating count
			if iteration == MAX_ITERATION_COUNT {
				break
			}

			// if we processed all items then exit
			if index == count {
				break
			}

			iter := query.Skip(index).Limit(count - index).Iter()
			for iter.Next(&result) {
				time.Sleep(SLEEPING_TIME)

				deleteDoc(result, collectionName)

				index++
				log.Info("Index: %v", index)
			}

			if err := iter.Close(); err != nil {
				log.Error("Iteration failed: %v", err)
			}

			if iter.Timeout() {
				continue
			}

			log.Info("iter existed, starting over from %v  -- %v  item(s) are processsed on this iter", index+1, index-skip)
			iteration++
		}

		if iteration == MAX_ITERATION_COUNT {
			log.Info("Max iteration count %v reached, exiting", iteration)
		}
		log.Info("%v entries on this process", index-skip)
		log.Info("deleted item count %v", deletedItems)

		return nil
	}
}

func deleteDoc(result map[string]interface{}, collectionName string) {

	id, ok := result["_id"]
	if !ok {
		log.Error("result doesnt have _id %v", result)
		return
	}
	var collectionId bson.ObjectId

	collectionId = (id.(bson.ObjectId))

	if !collectionId.Valid() {
		log.Info("result id is not valid %v", collectionId)
		return
	}

	if collectionId.Time().UTC().UnixNano() > oneMonthAgo.UnixNano() {
		log.Info("not deleting docuemnt %v", collectionId.Time())
		return
	}

	deleteRel(collectionId)

	log.Info("removing collectionId: %v from collectionName: %v ", collectionId.Hex(), collectionName)

	if err := mongodb.Run(collectionName, func(coll *mgo.Collection) error {
		return coll.RemoveId(collectionId)
	}); err != nil {
		log.Error("couldnt remove collectionId: %v from collectionName: %v  ", collectionId.Hex(), collectionName)
	}
	deletedItems++
}

func deleteRel(id bson.ObjectId) {
	var rels []models.Relationship
	if err := mongodb.Run("relationships", func(coll *mgo.Collection) error {
		selector := helper.Selector{"$or": []helper.Selector{
			helper.Selector{"sourceId": id},
			helper.Selector{"targetId": id},
		}}
		return coll.Find(selector).All(&rels)
	}); err != nil {
		log.Error("couldnt fetch collectionId: %v from relationships  ", id.Hex())
		return
	}

	deleteDocumentsFromRelationships(rels)
}

func deleteDocumentsFromRelationships(rels []models.Relationship) {
	if len(rels) == 0 {
		log.Info("document has no relationship")
		return
	}

	for _, rel := range rels {
		if err := mongodb.Run("relationships", func(coll *mgo.Collection) error {
			return coll.RemoveId(rel.Id)
		}); err != nil {
			log.Error("couldnt remove collectionId: %v from relationships  ", rel.Id.Hex())
		}
		deletedItems++
	}
}

var ToBeDTruncatedNames = []string{
	"cActivities",
	"cFolloweeBuckets",
	"cLikeeBuckets",
	"cLikerBuckets",
	"cNewMemberBuckets",
	"cReplieeBuckets",
	"jEmailConfirmations",
	"jEmailNotifications",
	"jInvitationRequests",
	"jInvitations",
	"jLogs",
	"jMailNotifications",
	"jMails",
	"jOldUsers",
	"jPasswordRecoveries",
	"jVerificationTokens",
}
<commit_msg>Truncator: switch using Iter helper<commit_after>package main

import (
	"flag"
	"koding/db/models"
	"koding/db/mongodb"

	helper "koding/db/mongodb/modelhelper"
	"koding/helpers"
	"koding/tools/config"
	"koding/tools/logger"
	"time"

	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

var log = logger.New("post truncator")

type strToInf map[string]interface{}

var (
	conf          *config.Config
	flagProfile   = flag.String("c", "vagrant", "Configuration profile from file")
	flagDirection = flag.String("direction", "targetName", "direction name ")
	flagSkip      = flag.Int("s", 0, "Configuration profile from file")
	flagLimit     = flag.Int("l", 1000, "Configuration profile from file")
	mongo         *mongodb.MongoDB
	deletedItems  = 0
	oneMonthAgo   = time.Now().Add(-time.Minute * 60 * 24 * 30).UTC()
)

func initialize() {
	flag.Parse()
	log.SetLevel(logger.INFO)
	if *flagProfile == "" {
		log.Fatal("Please specify profile via -c. Aborting.")
	}

	conf = config.MustConfig(*flagProfile)
	helper.Initialize(conf.Mongo)
	mongo = helper.Mongo
}

func main() {

	// init the package
	initialize()
	log.Info("Truncater worker started")

	var resultDataType map[string]interface{}

	iterOptions := helpers.NewIterOptions()
	iterOptions.Filter = helper.Selector{}
	iterOptions.DataType = &resultDataType
	iterOptions.Limit = *flagLimit
	iterOptions.Skip = *flagSkip
	iterOptions.Log = log

	log.SetLevel(logger.DEBUG)

	for _, coll := range ToBeDTruncatedNames {
		iterOptions.CollectionName = coll
		iterOptions.F = truncateItems(coll)
		err := helpers.Iter(mongo, iterOptions)
		if err != nil {
			log.Fatal("Error while iter: %v", err)
		}
	}

	log.Info("Truncator worker finished")

}

func truncateItems(collectionName string) func(doc interface{}) {
	return func(doc interface{}) {
		result := *(doc.(*map[string]interface{}))

		id, ok := result["_id"]
		if !ok {
			log.Error("result doesnt have _id %v", result)
			return
		}
		var collectionId bson.ObjectId

		collectionId = (id.(bson.ObjectId))

		if !collectionId.Valid() {
			log.Info("result id is not valid %v", collectionId)
			return
		}

		if collectionId.Time().UTC().UnixNano() > oneMonthAgo.UnixNano() {
			log.Info("not deleting docuemnt %v", collectionId.Time())
			return
		}

		deleteRel(collectionId)

		log.Info("removing collectionId: %v from collectionName: %v ", collectionId.Hex(), collectionName)

		if err := mongo.Run(collectionName, func(coll *mgo.Collection) error {
			return coll.RemoveId(collectionId)
		}); err != nil {
			log.Error("couldnt remove collectionId: %v from collectionName: %v  ", collectionId.Hex(), collectionName)
		}
		deletedItems++
	}
}

func deleteRel(id bson.ObjectId) {
	var rels []models.Relationship
	if err := mongo.Run("relationships", func(coll *mgo.Collection) error {
		selector := helper.Selector{"$or": []helper.Selector{
			helper.Selector{"sourceId": id},
			helper.Selector{"targetId": id},
		}}
		return coll.Find(selector).All(&rels)
	}); err != nil {
		log.Error("couldnt fetch collectionId: %v from relationships  ", id.Hex())
		return
	}

	deleteDocumentsFromRelationships(rels)
}

func deleteDocumentsFromRelationships(rels []models.Relationship) {
	if len(rels) == 0 {
		log.Info("document has no relationship")
		return
	}

	for _, rel := range rels {
		if err := mongo.Run("relationships", func(coll *mgo.Collection) error {
			return coll.RemoveId(rel.Id)
		}); err != nil {
			log.Error("couldnt remove collectionId: %v from relationships  ", rel.Id.Hex())
		}
		deletedItems++
	}
}

var ToBeDTruncatedNames = []string{
	"cActivities",
	"cFolloweeBuckets",
	"cLikeeBuckets",
	"cLikerBuckets",
	"cNewMemberBuckets",
	"cReplieeBuckets",
	"jEmailConfirmations",
	"jEmailNotifications",
	"jInvitationRequests",
	"jInvitations",
	"jLogs",
	"jMailNotifications",
	"jMails",
	"jOldUsers",
	"jPasswordRecoveries",
	"jVerificationTokens",
}
<|endoftext|>


<commit_before>package inflector_test

import (
	"testing"

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

var SingularToPlural = map[string]string{
	"search":      "searches",
	"switch":      "switches",
	"fix":         "fixes",
	"box":         "boxes",
	"process":     "processes",
	"address":     "addresses",
	"case":        "cases",
	"stack":       "stacks",
	"wish":        "wishes",
	"fish":        "fish",
	"jeans":       "jeans",
	"funky jeans": "funky jeans",
	"my money":    "my money",
	"category":    "categories",
	"query":       "queries",
	"ability":     "abilities",
	"agency":      "agencies",
	"movie":       "movies",
	"archive":     "archives",
	"index":       "indices",
	"wife":        "wives",
	"safe":        "saves",
	"half":        "halves",
	"move":        "moves",
	"salesperson": "salespeople",
	"person":      "people",
	"spokesman":   "spokesmen",
	"man":         "men",
	"woman":       "women",
	"basis":       "bases",
	"diagnosis":   "diagnoses",
	"diagnosis_a": "diagnosis_as",
	"datum":       "data",
	"medium":      "media",
	"stadium":     "stadia",
	"analysis":    "analyses",
	"my_analysis": "my_analyses",
	"node_child":  "node_children",
	"child":       "children",
	"experience":  "experiences",
	"day":         "days",
	"comment":     "comments",
	"foobar":      "foobars",
	"newsletter":  "newsletters",
	"old_news":    "old_news",
	"news":        "news",
	"series":      "series",
	"miniseries":  "miniseries",
	"species":     "species",
	"quiz":        "quizzes",
	"perspective": "perspectives",
	"ox":          "oxen",
	"photo":       "photos",
	"buffalo":     "buffaloes",
	"tomato":      "tomatoes",
	"dwarf":       "dwarves",
	"elf":         "elves",
	"information": "information",
	"equipment":   "equipment",
	"bus":         "buses",
	"status":      "statuses",
	"status_code": "status_codes",
	"mouse":       "mice",
	"louse":       "lice",
	"house":       "houses",
	"octopus":     "octopi",
	"virus":       "viri",
	"alias":       "aliases",
	"portfolio":   "portfolios",
	"vertex":      "vertices",
	"matrix":      "matrices",
	"matrix_fu":   "matrix_fus",
	"axis":        "axes",
	"taxi":        "taxis",
	"testis":      "testes",
	"crisis":      "crises",
	"rice":        "rice",
	"shoe":        "shoes",
	"horse":       "horses",
	"prize":       "prizes",
	"edge":        "edges",
	"database":    "databases",
}

var CamelToUnderscore = map[string]string{
	"Product":               "product",
	"SpecialGuest":          "special_guest",
	"ApplicationController": "application_controller",
	"Area51Controller":      "area51_controller",
}

var CamelToDashes = map[string]string{
	"Product":               "product",
	"SpecialGuest":          "special-guest",
	"ApplicationController": "application-controller",
	"Area51Controller":      "area51-controller",
}

var ToTables = map[string]string{
	"Product":      "products",
	"AdminUser":    "admin_users",
	"user-account": "user_accounts",
	"specialOrder": "special_orders",
}
var ToForeignKey = map[string]string{
	"Product":      "product_id",
	"AdminUser":    "admin_user_id",
	"user-account": "user_account_id",
	"specialOrder": "special_order_id",
}

func TestPluralize(t *testing.T) {
	inflector.ClearCache()
	inflector.ShouldCache = false
	for singular, plural := range SingularToPlural {
		assert.Equal(t, plural, inflector.Pluralize(singular))
	}
}

func TestCachedPluralize(t *testing.T) {
	inflector.ClearCache()
	inflector.ShouldCache = true
	for singular, plural := range SingularToPlural {
		assert.Equal(t, plural, inflector.Pluralize(singular))
	}
}

func TestSingularize(t *testing.T) {
	inflector.ClearCache()
	inflector.ShouldCache = false
	for singular, plural := range SingularToPlural {
		assert.Equal(t, singular, inflector.Singularize(plural))
	}
}

func TestCachedSingularize(t *testing.T) {
	inflector.ClearCache()
	inflector.ShouldCache = true
	for singular, plural := range SingularToPlural {
		assert.Equal(t, singular, inflector.Singularize(plural))
	}
}

func TestCamelize(t *testing.T) {
	for camel, underscore := range CamelToUnderscore {
		assert.Equal(t, camel, inflector.Camelize(underscore))
	}
}

func TestUnderscorize(t *testing.T) {
	for camel, underscore := range CamelToUnderscore {
		assert.Equal(t, underscore, inflector.Underscorize(camel))
	}
}

func TestDasherize(t *testing.T) {
	for camel, dash := range CamelToDashes {
		assert.Equal(t, dash, inflector.Dasherize(camel))
	}
}

func TestTableize(t *testing.T) {
	for term, table := range ToTables {
		assert.Equal(t, table, inflector.Tableize(term))
	}
}
func TestForeignKey(t *testing.T) {
	for term, key := range ToForeignKey {
		assert.Equal(t, key, inflector.ForeignKey(term))
	}
}
<commit_msg>added missing empty line :P<commit_after>package inflector_test

import (
	"testing"

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

var SingularToPlural = map[string]string{
	"search":      "searches",
	"switch":      "switches",
	"fix":         "fixes",
	"box":         "boxes",
	"process":     "processes",
	"address":     "addresses",
	"case":        "cases",
	"stack":       "stacks",
	"wish":        "wishes",
	"fish":        "fish",
	"jeans":       "jeans",
	"funky jeans": "funky jeans",
	"my money":    "my money",
	"category":    "categories",
	"query":       "queries",
	"ability":     "abilities",
	"agency":      "agencies",
	"movie":       "movies",
	"archive":     "archives",
	"index":       "indices",
	"wife":        "wives",
	"safe":        "saves",
	"half":        "halves",
	"move":        "moves",
	"salesperson": "salespeople",
	"person":      "people",
	"spokesman":   "spokesmen",
	"man":         "men",
	"woman":       "women",
	"basis":       "bases",
	"diagnosis":   "diagnoses",
	"diagnosis_a": "diagnosis_as",
	"datum":       "data",
	"medium":      "media",
	"stadium":     "stadia",
	"analysis":    "analyses",
	"my_analysis": "my_analyses",
	"node_child":  "node_children",
	"child":       "children",
	"experience":  "experiences",
	"day":         "days",
	"comment":     "comments",
	"foobar":      "foobars",
	"newsletter":  "newsletters",
	"old_news":    "old_news",
	"news":        "news",
	"series":      "series",
	"miniseries":  "miniseries",
	"species":     "species",
	"quiz":        "quizzes",
	"perspective": "perspectives",
	"ox":          "oxen",
	"photo":       "photos",
	"buffalo":     "buffaloes",
	"tomato":      "tomatoes",
	"dwarf":       "dwarves",
	"elf":         "elves",
	"information": "information",
	"equipment":   "equipment",
	"bus":         "buses",
	"status":      "statuses",
	"status_code": "status_codes",
	"mouse":       "mice",
	"louse":       "lice",
	"house":       "houses",
	"octopus":     "octopi",
	"virus":       "viri",
	"alias":       "aliases",
	"portfolio":   "portfolios",
	"vertex":      "vertices",
	"matrix":      "matrices",
	"matrix_fu":   "matrix_fus",
	"axis":        "axes",
	"taxi":        "taxis",
	"testis":      "testes",
	"crisis":      "crises",
	"rice":        "rice",
	"shoe":        "shoes",
	"horse":       "horses",
	"prize":       "prizes",
	"edge":        "edges",
	"database":    "databases",
}

var CamelToUnderscore = map[string]string{
	"Product":               "product",
	"SpecialGuest":          "special_guest",
	"ApplicationController": "application_controller",
	"Area51Controller":      "area51_controller",
}

var CamelToDashes = map[string]string{
	"Product":               "product",
	"SpecialGuest":          "special-guest",
	"ApplicationController": "application-controller",
	"Area51Controller":      "area51-controller",
}

var ToTables = map[string]string{
	"Product":      "products",
	"AdminUser":    "admin_users",
	"user-account": "user_accounts",
	"specialOrder": "special_orders",
}
var ToForeignKey = map[string]string{
	"Product":      "product_id",
	"AdminUser":    "admin_user_id",
	"user-account": "user_account_id",
	"specialOrder": "special_order_id",
}

func TestPluralize(t *testing.T) {
	inflector.ClearCache()
	inflector.ShouldCache = false
	for singular, plural := range SingularToPlural {
		assert.Equal(t, plural, inflector.Pluralize(singular))
	}
}

func TestCachedPluralize(t *testing.T) {
	inflector.ClearCache()
	inflector.ShouldCache = true
	for singular, plural := range SingularToPlural {
		assert.Equal(t, plural, inflector.Pluralize(singular))
	}
}

func TestSingularize(t *testing.T) {
	inflector.ClearCache()
	inflector.ShouldCache = false
	for singular, plural := range SingularToPlural {
		assert.Equal(t, singular, inflector.Singularize(plural))
	}
}

func TestCachedSingularize(t *testing.T) {
	inflector.ClearCache()
	inflector.ShouldCache = true
	for singular, plural := range SingularToPlural {
		assert.Equal(t, singular, inflector.Singularize(plural))
	}
}

func TestCamelize(t *testing.T) {
	for camel, underscore := range CamelToUnderscore {
		assert.Equal(t, camel, inflector.Camelize(underscore))
	}
}

func TestUnderscorize(t *testing.T) {
	for camel, underscore := range CamelToUnderscore {
		assert.Equal(t, underscore, inflector.Underscorize(camel))
	}
}

func TestDasherize(t *testing.T) {
	for camel, dash := range CamelToDashes {
		assert.Equal(t, dash, inflector.Dasherize(camel))
	}
}

func TestTableize(t *testing.T) {
	for term, table := range ToTables {
		assert.Equal(t, table, inflector.Tableize(term))
	}
}

func TestForeignKey(t *testing.T) {
	for term, key := range ToForeignKey {
		assert.Equal(t, key, inflector.ForeignKey(term))
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Hajime Hoshi
//
// 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 graphics

import (
	"errors"
	"fmt"
	"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
)

func glMatrix(m *[4][4]float64) []float32 {
	return []float32{
		float32(m[0][0]), float32(m[1][0]), float32(m[2][0]), float32(m[3][0]),
		float32(m[0][1]), float32(m[1][1]), float32(m[2][1]), float32(m[3][1]),
		float32(m[0][2]), float32(m[1][2]), float32(m[2][2]), float32(m[3][2]),
		float32(m[0][3]), float32(m[1][3]), float32(m[2][3]), float32(m[3][3]),
	}
}

type Matrix interface {
	Element(i, j int) float64
}

var vertices = make([]int16, 16*quadsMaxNum)

var shadersInitialized = false

func drawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4][4]float64, quads TextureQuads, geo Matrix, color Matrix) error {
	// NOTE: WebGL doesn't seem to have Check gl.MAX_ELEMENTS_VERTICES or gl.MAX_ELEMENTS_INDICES so far.
	// Let's use them to compare to len(quads) in the future.

	if !shadersInitialized {
		if err := initialize(c); err != nil {
			return err
		}
		shadersInitialized = true
	}

	l := quads.Len()
	if l == 0 {
		return nil
	}
	if quadsMaxNum < l {
		return errors.New(fmt.Sprintf("len(quads) must be equal to or less than %d", quadsMaxNum))
	}

	p := programContext{
		program:          programTexture,
		context:          c,
		projectionMatrix: glMatrix(projectionMatrix),
		texture:          texture,
		geoM:             geo,
		colorM:           color,
	}
	p.begin()
	defer p.end()

	for i := 0; i < l; i++ {
		x0, y0, x1, y1 := quads.Vertex(i)
		u0, v0, u1, v1 := quads.Texture(i)
		vertices[16*i] = int16(x0)
		vertices[16*i+1] = int16(y0)
		vertices[16*i+2] = int16(u0)
		vertices[16*i+3] = int16(v0)
		vertices[16*i+4] = int16(x1)
		vertices[16*i+5] = int16(y0)
		vertices[16*i+6] = int16(u1)
		vertices[16*i+7] = int16(v0)
		vertices[16*i+8] = int16(x0)
		vertices[16*i+9] = int16(y1)
		vertices[16*i+10] = int16(u0)
		vertices[16*i+11] = int16(v1)
		vertices[16*i+12] = int16(x1)
		vertices[16*i+13] = int16(y1)
		vertices[16*i+14] = int16(u1)
		vertices[16*i+15] = int16(v1)
	}
	if len(vertices) == 0 {
		return nil
	}
	c.BufferSubData(c.ArrayBuffer, vertices[:16*quads.Len()])
	c.DrawElements(c.Triangles, 6*quads.Len())
	return nil
}
<commit_msg>graphics: Remove unneeded 'if'<commit_after>// Copyright 2014 Hajime Hoshi
//
// 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 graphics

import (
	"errors"
	"fmt"
	"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
)

func glMatrix(m *[4][4]float64) []float32 {
	return []float32{
		float32(m[0][0]), float32(m[1][0]), float32(m[2][0]), float32(m[3][0]),
		float32(m[0][1]), float32(m[1][1]), float32(m[2][1]), float32(m[3][1]),
		float32(m[0][2]), float32(m[1][2]), float32(m[2][2]), float32(m[3][2]),
		float32(m[0][3]), float32(m[1][3]), float32(m[2][3]), float32(m[3][3]),
	}
}

type Matrix interface {
	Element(i, j int) float64
}

var vertices = make([]int16, 16*quadsMaxNum)

var shadersInitialized = false

func drawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4][4]float64, quads TextureQuads, geo Matrix, color Matrix) error {
	// NOTE: WebGL doesn't seem to have Check gl.MAX_ELEMENTS_VERTICES or gl.MAX_ELEMENTS_INDICES so far.
	// Let's use them to compare to len(quads) in the future.

	if !shadersInitialized {
		if err := initialize(c); err != nil {
			return err
		}
		shadersInitialized = true
	}

	l := quads.Len()
	if l == 0 {
		return nil
	}
	if quadsMaxNum < l {
		return errors.New(fmt.Sprintf("len(quads) must be equal to or less than %d", quadsMaxNum))
	}

	p := programContext{
		program:          programTexture,
		context:          c,
		projectionMatrix: glMatrix(projectionMatrix),
		texture:          texture,
		geoM:             geo,
		colorM:           color,
	}
	p.begin()
	defer p.end()

	for i := 0; i < l; i++ {
		x0, y0, x1, y1 := quads.Vertex(i)
		u0, v0, u1, v1 := quads.Texture(i)
		vertices[16*i] = int16(x0)
		vertices[16*i+1] = int16(y0)
		vertices[16*i+2] = int16(u0)
		vertices[16*i+3] = int16(v0)
		vertices[16*i+4] = int16(x1)
		vertices[16*i+5] = int16(y0)
		vertices[16*i+6] = int16(u1)
		vertices[16*i+7] = int16(v0)
		vertices[16*i+8] = int16(x0)
		vertices[16*i+9] = int16(y1)
		vertices[16*i+10] = int16(u0)
		vertices[16*i+11] = int16(v1)
		vertices[16*i+12] = int16(x1)
		vertices[16*i+13] = int16(y1)
		vertices[16*i+14] = int16(u1)
		vertices[16*i+15] = int16(v1)
	}
	c.BufferSubData(c.ArrayBuffer, vertices[:16*quads.Len()])
	c.DrawElements(c.Triangles, 6*quads.Len())
	return nil
}
<|endoftext|>


<commit_before>package kite

import (
	"fmt"
	"net/http"
	"testing"
	"time"
)

// Test 2 way communication between kites.
func TestKite(t *testing.T) {
	mathKite := New("mathworker", "0.0.1")
	mathKite.HandleFunc("square", Square)
	mathKite.HandleFunc("squareCB", SquareCB)
	mathKite.Config.DisableAuthentication = true
	go http.ListenAndServe("127.0.0.1:3636", mathKite)

	exp2Kite := New("exp2", "0.0.1")
	go http.ListenAndServe("127.0.0.1:3637", exp2Kite)

	// Wait until they start serving
	time.Sleep(time.Second)

	fooChan := make(chan string)
	handleFoo := func(r *Request) (interface{}, error) {
		s := r.Args.One().MustString()
		fmt.Printf("Message received: %s\n", s)
		fooChan <- s
		return nil, nil
	}

	exp2Kite.HandleFunc("foo", handleFoo)

	// exp2 connects to mathworker
	remote := exp2Kite.NewRemoteKiteString("ws://127.0.0.1:3636")
	err := remote.Dial()
	if err != nil {
		t.Errorf(err.Error())
		return
	}

	result, err := remote.Tell("square", 2)
	if err != nil {
		t.Errorf(err.Error())
		return
	}

	number := result.MustFloat64()

	fmt.Printf("rpc result: %f\n", number)

	if number != 4 {
		t.Errorf("Invalid result: %f", number)
	}

	select {
	case s := <-fooChan:
		if s != "bar" {
			t.Errorf("Invalid message: %s", s)
			return
		}
	case <-time.After(100 * time.Millisecond):
		t.Errorf("Did not get the message")
		return
	}

	resultChan := make(chan float64, 1)
	resultCallback := func(r *Request) {
		fmt.Printf("Request: %#v\n", r)
		n := r.Args.One().MustFloat64()
		resultChan <- n
	}

	result, err = remote.Tell("squareCB", 3, Callback(resultCallback))
	if err != nil {
		t.Errorf(err.Error())
	}

	select {
	case n := <-resultChan:
		if n != 9.0 {
			t.Errorf("Unexpected result: %f", n)
			return
		}
	case <-time.After(100 * time.Millisecond):
		t.Errorf("Did not get the message")
		return
	}
}

// Returns the result. Also tests reverse call.
func Square(r *Request) (interface{}, error) {
	a := r.Args[0].MustFloat64()
	result := a * a

	fmt.Printf("Kite call, sending result '%f' back\n", result)

	// Reverse method call
	r.RemoteKite.Go("foo", "bar")

	return result, nil
}

// Calls the callback with the result. For testing requests with Callback.
func SquareCB(r *Request) (interface{}, error) {
	args := r.Args.MustSliceOfLength(2)
	a := args[0].MustFloat64()
	cb := args[1].MustFunction()

	result := a * a

	fmt.Printf("Kite call, sending result '%f' back\n", result)

	// Send the result.
	err := cb(result)
	if err != nil {
		return nil, err
	}

	return nil, nil
}
<commit_msg>refactor kite test<commit_after>package kite

import (
	"fmt"
	"net/http"
	"testing"
	"time"
)

// Test 2 way communication between kites.
func TestKite(t *testing.T) {
	mathKite := New("mathworker", "0.0.1")
	mathKite.HandleFunc("square", Square)
	mathKite.HandleFunc("squareCB", SquareCB)
	mathKite.Config.DisableAuthentication = true
	go http.ListenAndServe("127.0.0.1:3636", mathKite)

	exp2Kite := New("exp2", "0.0.1")
	go http.ListenAndServe("127.0.0.1:3637", exp2Kite)

	// Wait until they start serving
	time.Sleep(time.Second)

	fooChan := make(chan string)
	handleFoo := func(r *Request) (interface{}, error) {
		s := r.Args.One().MustString()
		fmt.Printf("Message received: %s\n", s)
		fooChan <- s
		return nil, nil
	}

	exp2Kite.HandleFunc("foo", handleFoo)

	// exp2 connects to mathworker
	remote := exp2Kite.NewRemoteKiteString("ws://127.0.0.1:3636")
	err := remote.Dial()
	if err != nil {
		t.Fatal(err)
	}

	result, err := remote.Tell("square", 2)
	if err != nil {
		t.Fatal(err)
	}

	number := result.MustFloat64()

	fmt.Printf("rpc result: %f\n", number)

	if number != 4 {
		t.Fatalf("Invalid result: %f", number)
	}

	select {
	case s := <-fooChan:
		if s != "bar" {
			t.Fatalf("Invalid message: %s", s)
		}
	case <-time.After(100 * time.Millisecond):
		t.Fatal("Did not get the message")
	}

	resultChan := make(chan float64, 1)
	resultCallback := func(r *Request) {
		fmt.Printf("Request: %#v\n", r)
		n := r.Args.One().MustFloat64()
		resultChan <- n
	}

	result, err = remote.Tell("squareCB", 3, Callback(resultCallback))
	if err != nil {
		t.Fatal(err)
	}

	select {
	case n := <-resultChan:
		if n != 9.0 {
			t.Fatalf("Unexpected result: %f", n)
		}
	case <-time.After(100 * time.Millisecond):
		t.Fatal("Did not get the message")
	}
}

// Returns the result. Also tests reverse call.
func Square(r *Request) (interface{}, error) {
	a := r.Args[0].MustFloat64()
	result := a * a

	fmt.Printf("Kite call, sending result '%f' back\n", result)

	// Reverse method call
	r.RemoteKite.Go("foo", "bar")

	return result, nil
}

// Calls the callback with the result. For testing requests with Callback.
func SquareCB(r *Request) (interface{}, error) {
	args := r.Args.MustSliceOfLength(2)
	a := args[0].MustFloat64()
	cb := args[1].MustFunction()

	result := a * a

	fmt.Printf("Kite call, sending result '%f' back\n", result)

	// Send the result.
	err := cb(result)
	if err != nil {
		return nil, err
	}

	return nil, nil
}
<|endoftext|>


<commit_before>/*

   Copyright 2013 Niklas Voss

   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 golem

import (
	"errors"
	"github.com/garyburd/go-websocket/websocket"
	"log"
	"net/http"
	"reflect"
)

// Router handles multiplexing of incoming messenges by typenames/events.
// Initially a router uses heartbeats and the default protocol.
type Router struct {
	// Map of callbacks for event types.
	callbacks map[string]func(*Connection, interface{})
	// Protocol extensions
	extensions map[reflect.Type]reflect.Value
	// Function being called if connection is closed.
	closeFunc func(*Connection)
	// Function verifying handshake.
	handshakeFunc func(http.ResponseWriter, *http.Request) bool
	// Active protocol
	protocol Protocol
	// Flag to enable or disable heartbeats
	useHeartbeats bool
	//
	connExtensionConstructor reflect.Value
}

// NewRouter intialises a new instance and returns the pointer.
func NewRouter() *Router {
	// Tries to run hub, if already running nothing will happen.
	hub.run()
	// Returns pointer to instance.
	return &Router{
		callbacks:                make(map[string]func(*Connection, interface{})),
		extensions:               make(map[reflect.Type]reflect.Value),
		closeFunc:                func(*Connection) {},                                          // Empty placeholder close function.
		handshakeFunc:            func(http.ResponseWriter, *http.Request) bool { return true }, // Handshake always allowed.
		protocol:                 initialProtocol,
		useHeartbeats:            true,
		connExtensionConstructor: defaultConnectionExtension,
	}
}

// Handler creates a handler function for this router, that can be used with the
// http-package to handle WebSocket-Connections.
func (router *Router) Handler() func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		// Check if method used was GET.
		if r.Method != "GET" {
			http.Error(w, "Method not allowed", 405)
			return
		}
		// Disallow cross-origin connections.
		if r.Header.Get("Origin") != "http://"+r.Host {
			http.Error(w, "Origin not allowed", 403)
			return
		}
		// Check if handshake callback verifies upgrade.
		if !router.handshakeFunc(w, r) {
			http.Error(w, "Authorization failed", 403)
			return
		}
		// Upgrade websocket connection.
		socket, err := websocket.Upgrade(w, r.Header, nil, 1024, 1024)
		// Check if handshake was successful
		if _, ok := err.(websocket.HandshakeError); ok {
			http.Error(w, "Not a websocket handshake", 400)
			return
		} else if err != nil {
			log.Println(err)
			return
		}

		// Create the connection.
		conn := newConnection(socket, router)
		//
		if router.connExtensionConstructor.IsValid() {
			conn.extend(router.connExtensionConstructor.Call([]reflect.Value{reflect.ValueOf(conn)})[0].Interface())
		}
		// And start reading and writing routines.
		conn.run()
	}
}

// The On-function adds callbacks by name of the event, that should be handled.
// For type T the callback would be of type:
//     func (*golem.Connection, *T)
// Type T can be any type. By default golem tries to unmarshal json into the
// specified type. If a custom protocol is used, it will be used instead to process the data.
// If type T is registered to use a protocol extension, it will be used instead.
// If type T is interface{} the interstage data of the active protocol will be directly forwarded!
// (Note: the golem wiki has a whole page about this function)
func (router *Router) On(name string, callback interface{}) {

	callbackValue := reflect.ValueOf(callback)
	callbackType := reflect.TypeOf(callback)
	if router.connExtensionConstructor.IsValid() {
		extType := router.connExtensionConstructor.Type().Out(0)
		if callbackType.In(0) == extType {
			// EXTENSION TYPE

			// NO DATA
			if callbackType.NumIn() == 1 {
				router.callbacks[name] = func(conn *Connection, data interface{}) {
					args := []reflect.Value{reflect.ValueOf(conn.extension)}
					callbackValue.Call(args)
				}
				return
			}

			// INTERFACE
			if callbackType.In(1).Kind() == reflect.Interface {
				router.callbacks[name] = func(conn *Connection, data interface{}) {
					args := []reflect.Value{reflect.ValueOf(conn.extension), reflect.ValueOf(data)}
					callbackValue.Call(args)
				}
				return
			}

			// PROTOCOL EXTENSION
			if parser, ok := router.extensions[callbackType.In(1)]; ok {
				router.callbacks[name] = func(conn *Connection, data interface{}) {
					if result := parser.Call([]reflect.Value{reflect.ValueOf(data)}); result[1].Bool() {
						args := []reflect.Value{reflect.ValueOf(conn.extension), result[0]}
						callbackValue.Call(args)
					}
				}
				return
			}

			// PROTOCOL
			callbackDataElem := callbackType.In(1).Elem()
			router.callbacks[name] = func(conn *Connection, data interface{}) {
				result := reflect.New(callbackDataElem)

				err := router.protocol.Unmarshal(data, result.Interface())
				if err == nil {
					args := []reflect.Value{reflect.ValueOf(conn.extension), result}
					callbackValue.Call(args)
				} else {
					// TODO: Proper debug output!
				}
			}
			return
		}
	} else {
		// DEFAULT TYPE

		// NO DATA
		if reflect.TypeOf(callback).NumIn() == 1 {
			router.callbacks[name] = func(conn *Connection, data interface{}) {
				callback.(func(*Connection))(conn)
			}
			return
		}

		// INTERFACE
		if cb, ok := callback.(func(*Connection, interface{})); ok {
			router.callbacks[name] = cb
			return
		}

		// PROTOCOL EXTENSION
		if parser, ok := router.extensions[callbackType.In(1)]; ok {
			router.callbacks[name] = func(conn *Connection, data interface{}) {
				if result := parser.Call([]reflect.Value{reflect.ValueOf(data)}); result[1].Bool() {
					args := []reflect.Value{reflect.ValueOf(conn), result[0]}
					callbackValue.Call(args)
				}
			}
			return
		}

		// PROTOCOL
		callbackDataElem := callbackType.In(1).Elem()
		router.callbacks[name] = func(conn *Connection, data interface{}) {
			result := reflect.New(callbackDataElem)

			err := router.protocol.Unmarshal(data, result.Interface())
			if err == nil {
				args := []reflect.Value{reflect.ValueOf(conn), result}
				callbackValue.Call(args)
			} else {
				// TODO: Proper debug output!
			}
		}
		return
	}
}

// Unpacks incoming data and forwards it to callback.
func (router *Router) processMessage(conn *Connection, in []byte) {
	if name, data, err := router.protocol.Unpack(in); err == nil {
		if callback, ok := router.callbacks[name]; ok {
			callback(conn, data)
		}
	} // TODO: else error logging?

	defer recover()
}

// OnClose sets the callback for connection closes.
func (router *Router) OnClose(callback func(*Connection)) {
	router.closeFunc = callback
}

// OnHandshake sets the callback for handshake verfication.
// If the handshake function returns false the request will not be upgraded.
func (router *Router) OnHandshake(callback func(http.ResponseWriter, *http.Request) bool) {
	router.handshakeFunc = callback
}

// The AddProtocolExtension-function allows adding of custom parsers for custom types. For any Type T
// the parser function would look like this:
//      func (interface{}) (T, bool)
// The interface's type is depending on the interstage product of the active protocol, by default
// for the JSON-based protocol it is []byte and therefore the function could be simplified to:
//      func ([]byte) (T, bool)
// Or in general if P is the interstage product:
//      func (*P) (T, bool)
// The boolean return value is necessary to verify if parsing was successful.
// All On-handling function accepting T as input data will now automatically use the custom
// extension. For an example see the example_data.go file in the example repository.
func (router *Router) AddProtocolExtension(extensionFunc interface{}) error {
	extensionValue := reflect.ValueOf(extensionFunc)
	extensionType := extensionValue.Type()

	if extensionType.NumIn() != 1 {
		return errors.New("Cannot add function(" + extensionType.String() + ") as parser: To many arguments!")
	}
	if extensionType.NumOut() != 2 {
		return errors.New("Cannot add function(" + extensionType.String() + ") as parser: Wrong number of return values!")
	}
	if extensionType.Out(1).Kind() != reflect.Bool {
		return errors.New("Cannot add function(" + extensionType.String() + ") as parser: Second return value is not Bool!")
	}

	router.extensions[extensionType.Out(0)] = extensionValue

	return nil
}

// SetConnectionExtension sets the extension for this router. A connection extension is an extended connection structure, that afterwards can be
// used by On-handlers as well (use-cases: add persistent storage to connection, additional methods et cetera).
// The SetConnectionExtension function takes the constructor of the custom format to be able to use and create it on
// connection to the router.
// For type E the constructor needs to fulfil the following requirements:
//     func NewE(conn *Connection) *E
// Afterwards On-handler can us this extended type:
//     router.On(func (extendedConn E, data Datatype) { ... })
// For an example have a look at the example repository and have a look at the 'example_connection_extension.go'.
func (router *Router) SetConnectionExtension(constructor interface{}) {
	router.connExtensionConstructor = reflect.ValueOf(constructor)
}

// SetProtocol sets the protocol of the router to the supplied implementation of the Protocol interface.
func (router *Router) SetProtocol(protocol Protocol) {
	router.protocol = protocol
}

//

// SetHeartbeat activates or deactivates the heartbeat depending on the flag parameter. By default heartbeats are activated.
func (router *Router) SetHeartbeat(flag bool) {
	router.useHeartbeats = flag
}
<commit_msg>OnClose function extended to accept callbacks with extended connections.<commit_after>/*

   Copyright 2013 Niklas Voss

   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 golem

import (
	"errors"
	"github.com/garyburd/go-websocket/websocket"
	"log"
	"net/http"
	"reflect"
)

// Router handles multiplexing of incoming messenges by typenames/events.
// Initially a router uses heartbeats and the default protocol.
type Router struct {
	// Map of callbacks for event types.
	callbacks map[string]func(*Connection, interface{})
	// Protocol extensions
	extensions map[reflect.Type]reflect.Value
	// Function being called if connection is closed.
	closeFunc func(*Connection)
	// Function verifying handshake.
	handshakeFunc func(http.ResponseWriter, *http.Request) bool
	// Active protocol
	protocol Protocol
	// Flag to enable or disable heartbeats
	useHeartbeats bool
	//
	connExtensionConstructor reflect.Value
}

// NewRouter intialises a new instance and returns the pointer.
func NewRouter() *Router {
	// Tries to run hub, if already running nothing will happen.
	hub.run()
	// Returns pointer to instance.
	return &Router{
		callbacks:                make(map[string]func(*Connection, interface{})),
		extensions:               make(map[reflect.Type]reflect.Value),
		closeFunc:                func(*Connection) {},                                          // Empty placeholder close function.
		handshakeFunc:            func(http.ResponseWriter, *http.Request) bool { return true }, // Handshake always allowed.
		protocol:                 initialProtocol,
		useHeartbeats:            true,
		connExtensionConstructor: defaultConnectionExtension,
	}
}

// Handler creates a handler function for this router, that can be used with the
// http-package to handle WebSocket-Connections.
func (router *Router) Handler() func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		// Check if method used was GET.
		if r.Method != "GET" {
			http.Error(w, "Method not allowed", 405)
			return
		}
		// Disallow cross-origin connections.
		if r.Header.Get("Origin") != "http://"+r.Host {
			http.Error(w, "Origin not allowed", 403)
			return
		}
		// Check if handshake callback verifies upgrade.
		if !router.handshakeFunc(w, r) {
			http.Error(w, "Authorization failed", 403)
			return
		}
		// Upgrade websocket connection.
		socket, err := websocket.Upgrade(w, r.Header, nil, 1024, 1024)
		// Check if handshake was successful
		if _, ok := err.(websocket.HandshakeError); ok {
			http.Error(w, "Not a websocket handshake", 400)
			return
		} else if err != nil {
			log.Println(err)
			return
		}

		// Create the connection.
		conn := newConnection(socket, router)
		//
		if router.connExtensionConstructor.IsValid() {
			conn.extend(router.connExtensionConstructor.Call([]reflect.Value{reflect.ValueOf(conn)})[0].Interface())
		}
		// And start reading and writing routines.
		conn.run()
	}
}

// The On-function adds callbacks by name of the event, that should be handled.
// For type T the callback would be of type:
//     func (*golem.Connection, *T)
// Type T can be any type. By default golem tries to unmarshal json into the
// specified type. If a custom protocol is used, it will be used instead to process the data.
// If type T is registered to use a protocol extension, it will be used instead.
// If type T is interface{} the interstage data of the active protocol will be directly forwarded!
// (Note: the golem wiki has a whole page about this function)
func (router *Router) On(name string, callback interface{}) {

	callbackValue := reflect.ValueOf(callback)
	callbackType := reflect.TypeOf(callback)
	if router.connExtensionConstructor.IsValid() {
		extType := router.connExtensionConstructor.Type().Out(0)
		if callbackType.In(0) == extType {
			// EXTENSION TYPE

			// NO DATA
			if callbackType.NumIn() == 1 {
				router.callbacks[name] = func(conn *Connection, data interface{}) {
					args := []reflect.Value{reflect.ValueOf(conn.extension)}
					callbackValue.Call(args)
				}
				return
			}

			// INTERFACE
			if callbackType.In(1).Kind() == reflect.Interface {
				router.callbacks[name] = func(conn *Connection, data interface{}) {
					args := []reflect.Value{reflect.ValueOf(conn.extension), reflect.ValueOf(data)}
					callbackValue.Call(args)
				}
				return
			}

			// PROTOCOL EXTENSION
			if parser, ok := router.extensions[callbackType.In(1)]; ok {
				router.callbacks[name] = func(conn *Connection, data interface{}) {
					if result := parser.Call([]reflect.Value{reflect.ValueOf(data)}); result[1].Bool() {
						args := []reflect.Value{reflect.ValueOf(conn.extension), result[0]}
						callbackValue.Call(args)
					}
				}
				return
			}

			// PROTOCOL
			callbackDataElem := callbackType.In(1).Elem()
			router.callbacks[name] = func(conn *Connection, data interface{}) {
				result := reflect.New(callbackDataElem)

				err := router.protocol.Unmarshal(data, result.Interface())
				if err == nil {
					args := []reflect.Value{reflect.ValueOf(conn.extension), result}
					callbackValue.Call(args)
				} else {
					// TODO: Proper debug output!
				}
			}
			return
		}
	} else {
		// DEFAULT TYPE

		// NO DATA
		if reflect.TypeOf(callback).NumIn() == 1 {
			router.callbacks[name] = func(conn *Connection, data interface{}) {
				callback.(func(*Connection))(conn)
			}
			return
		}

		// INTERFACE
		if cb, ok := callback.(func(*Connection, interface{})); ok {
			router.callbacks[name] = cb
			return
		}

		// PROTOCOL EXTENSION
		if parser, ok := router.extensions[callbackType.In(1)]; ok {
			router.callbacks[name] = func(conn *Connection, data interface{}) {
				if result := parser.Call([]reflect.Value{reflect.ValueOf(data)}); result[1].Bool() {
					args := []reflect.Value{reflect.ValueOf(conn), result[0]}
					callbackValue.Call(args)
				}
			}
			return
		}

		// PROTOCOL
		callbackDataElem := callbackType.In(1).Elem()
		router.callbacks[name] = func(conn *Connection, data interface{}) {
			result := reflect.New(callbackDataElem)

			err := router.protocol.Unmarshal(data, result.Interface())
			if err == nil {
				args := []reflect.Value{reflect.ValueOf(conn), result}
				callbackValue.Call(args)
			} else {
				// TODO: Proper debug output!
			}
		}
		return
	}
}

// Unpacks incoming data and forwards it to callback.
func (router *Router) processMessage(conn *Connection, in []byte) {
	if name, data, err := router.protocol.Unpack(in); err == nil {
		if callback, ok := router.callbacks[name]; ok {
			callback(conn, data)
		}
	} // TODO: else error logging?

	defer recover()
}

// OnClose sets the callback, that is called when the connection is closed.
// It accept function of the type func(*Connection) by default or functions
// taking extended connection types if previously registered.
func (router *Router) OnClose(callback interface{}) error { //func(*Connection)) {
	if cb, ok := callback.(func(*Connection)); ok {
		router.closeFunc = cb
	} else {
		if router.connExtensionConstructor.IsValid() {
			callbackValue := reflect.ValueOf(callback)
			extType := router.connExtensionConstructor.Type().Out(0)
			if reflect.TypeOf(callback).In(0) == extType {
				router.closeFunc = func(conn *Connection) {
					callbackValue.Call([]reflect.Value{reflect.ValueOf(conn.extension)})
				}
			} else {
				return errors.New("OnClose cannot accept a callback of the type " + reflect.TypeOf(callback).String() + ".")
			}
		} else {
			return errors.New("OnClose can only accept functions of the type func(*Connection), if no extension is registered.")
		}
	}
	return nil
}

// OnHandshake sets the callback for handshake verfication.
// If the handshake function returns false the request will not be upgraded.
func (router *Router) OnHandshake(callback func(http.ResponseWriter, *http.Request) bool) {
	router.handshakeFunc = callback
}

// The AddProtocolExtension-function allows adding of custom parsers for custom types. For any Type T
// the parser function would look like this:
//      func (interface{}) (T, bool)
// The interface's type is depending on the interstage product of the active protocol, by default
// for the JSON-based protocol it is []byte and therefore the function could be simplified to:
//      func ([]byte) (T, bool)
// Or in general if P is the interstage product:
//      func (*P) (T, bool)
// The boolean return value is necessary to verify if parsing was successful.
// All On-handling function accepting T as input data will now automatically use the custom
// extension. For an example see the example_data.go file in the example repository.
func (router *Router) AddProtocolExtension(extensionFunc interface{}) error {
	extensionValue := reflect.ValueOf(extensionFunc)
	extensionType := extensionValue.Type()

	if extensionType.NumIn() != 1 {
		return errors.New("Cannot add function(" + extensionType.String() + ") as parser: To many arguments!")
	}
	if extensionType.NumOut() != 2 {
		return errors.New("Cannot add function(" + extensionType.String() + ") as parser: Wrong number of return values!")
	}
	if extensionType.Out(1).Kind() != reflect.Bool {
		return errors.New("Cannot add function(" + extensionType.String() + ") as parser: Second return value is not Bool!")
	}

	router.extensions[extensionType.Out(0)] = extensionValue

	return nil
}

// SetConnectionExtension sets the extension for this router. A connection extension is an extended connection structure, that afterwards can be
// used by On-handlers as well (use-cases: add persistent storage to connection, additional methods et cetera).
// The SetConnectionExtension function takes the constructor of the custom format to be able to use and create it on
// connection to the router.
// For type E the constructor needs to fulfil the following requirements:
//     func NewE(conn *Connection) *E
// Afterwards On-handler can us this extended type:
//     router.On(func (extendedConn E, data Datatype) { ... })
// For an example have a look at the example repository and have a look at the 'example_connection_extension.go'.
func (router *Router) SetConnectionExtension(constructor interface{}) {
	router.connExtensionConstructor = reflect.ValueOf(constructor)
}

// SetProtocol sets the protocol of the router to the supplied implementation of the Protocol interface.
func (router *Router) SetProtocol(protocol Protocol) {
	router.protocol = protocol
}

//

// SetHeartbeat activates or deactivates the heartbeat depending on the flag parameter. By default heartbeats are activated.
func (router *Router) SetHeartbeat(flag bool) {
	router.useHeartbeats = flag
}
<|endoftext|>


<commit_before>package plexgoslack

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

const base_url string = "http://api.themoviedb.org/3"

type TMDb struct {
	api_key string
}

func New(api_key string) *TMDb {
	return &TMDb{api_key: api_key}
}

type Result struct {
	VoteCount        int     `json:"vote_count"`
	Id               int     `json:"id"`
	Video            bool    `json:"video"`
	VoteAverage      float32 `json:"vote_average"`
	Title            string  `json:"title"`
	Popularity       float32 `json:"popularity"`
	PosterPath       string  `json:"poster_path"`
	OriginalLanguage string  `json:"original_language"`
	OriginalTitle    string  `json:"original_title"`
	GenreIds         []int   `json:"genre_ids"`
	BackdropPath     string  `json:"backdrop_path"`
	Adult            bool    `json:"adult"`
	Overview         string  `json:"overview"`
	ReleaseDate      string  `json:"release_date"`
}

type SearchResult struct {
	Page         int      `json:"page"`
	TotalResults int      `json:"total_results"`
	TotalPages   int      `json:"total_pages"`
	Results      []Result `json:"results"`
}

type MovieInfo struct {
	Title    string
	Year     string
	Tumbnail string
	Synopsis string
}

func (tmdb *TMDb) GetInfo(title string, year string) (MovieInfo, error) {
	var resp MovieInfo
	result, err := tmdb.SearchMovie(title, year)
	if err != nil {
		return resp, err
	}
	if result.TotalResults == 0 {
		return resp, errors.New("Couldn't find " + title + " (" + year + ") at TMDb")
	}
	return MovieInfo{Title: title, Year: year, Tumbnail: "https://image.tmdb.org/t/p/w92" + result.Results[0].PosterPath, Synopsis: result.Results[0].Overview}, nil
}

func (tmdb *TMDb) SearchMovie(title string, year string) (SearchResult, error) {
	var resp SearchResult
	res, err := http.Get(base_url + "/search/movie?api_key=" + tmdb.api_key + "&query=" + url.QueryEscape(title) + "&year=" + year)
	if err != nil {
		return resp, err
	}
	if res.StatusCode != 200 {
		return resp, errors.New(fmt.Sprintf("HTTP Resposnse %s", res.StatusCode))
	}
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return SearchResult{}, err
	}
	if err := json.Unmarshal(body, &resp); err != nil {
		return SearchResult{}, err
	}
	return resp, nil
}
<commit_msg>moved<commit_after><|endoftext|>


<commit_before>package kontena

import (
	"fmt"
	"strings"

	"github.com/jakubknejzlik/kontena-git-cli/model"
	"github.com/jakubknejzlik/kontena-git-cli/utils"
)

// ServiceCreate ...
func (c *Client) ServiceCreate(name string, service model.KontenaService) error {
	cmd := []string{`kontena service create`}
	if *service.Instances > 0 {
		cmd = append(cmd, `--instances `+string(*service.Instances))
	}
	if service.Command != "" {
		cmd = append(cmd, `--cmd `+service.Command)
	}
	for _, value := range service.Environment {
		cmd = append(cmd, `-e "`+value+`"`)
	}
	for _, value := range service.Links {
		cmd = append(cmd, `-l "`+value+`"`)
	}
	for _, value := range service.Volumes {
		cmd = append(cmd, `-v "`+value+`"`)
	}
	for _, value := range service.Ports {
		cmd = append(cmd, `-p "`+value+`"`)
	}
	if service.Deploy.Strategy != "" {
		cmd = append(cmd, `--deploy `+service.Deploy.Strategy)
	}
	cmd = append(cmd, name)
	cmd = append(cmd, service.Image)

	utils.Log("creating service", name)
	return utils.RunInteractive(strings.Join(cmd, " "))
}

// ServiceDeploy ...
func (c *Client) ServiceDeploy(service string) error {
	utils.Log("deploying service", service)
	return utils.RunInteractive(fmt.Sprintf("kontena service deploy %s", service))
}

// ServiceInStackDeploy ...
func (c *Client) ServiceInStackDeploy(stack, service string) error {
	return c.ServiceDeploy(stack + "/" + service)
}

// ServiceExec ...
func (c *Client) ServiceExec(service, command string) ([]byte, error) {
	return utils.Run(fmt.Sprintf("kontena service exec %s %s", service, command))
}

// ServiceInStackExec ...
func (c *Client) ServiceInStackExec(stack, service, command string) ([]byte, error) {
	return c.ServiceExec(stack+"/"+service, command)
}

// ServiceRemove ...
func (c *Client) ServiceRemove(service string) error {
	utils.Log("removing service", service)
	return utils.RunInteractive(fmt.Sprintf("kontena service rm --force %s", service))
}
<commit_msg>Fix service instances nil dereference<commit_after>package kontena

import (
	"fmt"
	"strings"

	"github.com/jakubknejzlik/kontena-git-cli/model"
	"github.com/jakubknejzlik/kontena-git-cli/utils"
)

// ServiceCreate ...
func (c *Client) ServiceCreate(name string, service model.KontenaService) error {
	cmd := []string{`kontena service create`}
	if service.Instances != nil && *service.Instances > 0 {
		cmd = append(cmd, `--instances `+string(*service.Instances))
	}
	if service.Command != "" {
		cmd = append(cmd, `--cmd `+service.Command)
	}
	for _, value := range service.Environment {
		cmd = append(cmd, `-e "`+value+`"`)
	}
	for _, value := range service.Links {
		cmd = append(cmd, `-l "`+value+`"`)
	}
	for _, value := range service.Volumes {
		cmd = append(cmd, `-v "`+value+`"`)
	}
	for _, value := range service.Ports {
		cmd = append(cmd, `-p "`+value+`"`)
	}
	if service.Deploy.Strategy != "" {
		cmd = append(cmd, `--deploy `+service.Deploy.Strategy)
	}
	cmd = append(cmd, name)
	cmd = append(cmd, service.Image)

	utils.Log("creating service", name)
	return utils.RunInteractive(strings.Join(cmd, " "))
}

// ServiceDeploy ...
func (c *Client) ServiceDeploy(service string) error {
	utils.Log("deploying service", service)
	return utils.RunInteractive(fmt.Sprintf("kontena service deploy %s", service))
}

// ServiceInStackDeploy ...
func (c *Client) ServiceInStackDeploy(stack, service string) error {
	return c.ServiceDeploy(stack + "/" + service)
}

// ServiceExec ...
func (c *Client) ServiceExec(service, command string) ([]byte, error) {
	return utils.Run(fmt.Sprintf("kontena service exec %s %s", service, command))
}

// ServiceInStackExec ...
func (c *Client) ServiceInStackExec(stack, service, command string) ([]byte, error) {
	return c.ServiceExec(stack+"/"+service, command)
}

// ServiceRemove ...
func (c *Client) ServiceRemove(service string) error {
	utils.Log("removing service", service)
	return utils.RunInteractive(fmt.Sprintf("kontena service rm --force %s", service))
}
<|endoftext|>


<commit_before>package app

import (
	. "github.com/tendermint/go-common"
	"github.com/tendermint/go-merkle"
	"github.com/tendermint/go-wire"
	tmsp "github.com/tendermint/tmsp/types"
)

type MerkleEyesApp struct {
	tree merkle.Tree
}

func NewMerkleEyesApp() *MerkleEyesApp {
	tree := merkle.NewIAVLTree(
		0,
		nil,
	)
	return &MerkleEyesApp{tree: tree}
}

func (app *MerkleEyesApp) Info() string {
	return Fmt("size:%v", app.tree.Size())
}

func (app *MerkleEyesApp) SetOption(key string, value string) (log string) {
	return "No options are supported yet"
}

func (app *MerkleEyesApp) AppendTx(tx []byte) (code tmsp.CodeType, result []byte, log string) {
	if len(tx) == 0 {
		return tmsp.CodeType_EncodingError, nil, "Tx length cannot be zero"
	}
	typeByte := tx[0]
	tx = tx[1:]
	switch typeByte {
	case 0x01: // Set
		key, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		tx = tx[n:]
		value, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting value: %v", err.Error())
		}
		tx = tx[n:]
		if len(tx) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		app.tree.Set(key, value)
	case 0x02: // Remove
		key, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		tx = tx[n:]
		if len(tx) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		app.tree.Remove(key)
	default:
		return tmsp.CodeType_UnknownRequest, nil, Fmt("Unexpected type byte %X", typeByte)
	}
	return tmsp.CodeType_OK, nil, ""
}

func (app *MerkleEyesApp) CheckTx(tx []byte) (code tmsp.CodeType, result []byte, log string) {
	if len(tx) == 0 {
		return tmsp.CodeType_EncodingError, nil, "Tx length cannot be zero"
	}
	typeByte := tx[0]
	tx = tx[1:]
	switch typeByte {
	case 0x01: // Set
		_, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		tx = tx[n:]
		_, n, err = wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting value: %v", err.Error())
		}
		tx = tx[n:]
		if len(tx) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		//app.tree.Set(key, value)
	case 0x02: // Remove
		_, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		tx = tx[n:]
		if len(tx) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		//app.tree.Remove(key)
	default:
		return tmsp.CodeType_UnknownRequest, nil, Fmt("Unexpected type byte %X", typeByte)
	}
	return tmsp.CodeType_OK, nil, ""
}

func (app *MerkleEyesApp) GetHash() (hash []byte, log string) {
	if app.tree.Size() == 0 {
		return nil, "Empty hash for empty tree"
	}
	hash = app.tree.Hash()
	return hash, ""
}

func (app *MerkleEyesApp) Query(query []byte) (code tmsp.CodeType, result []byte, log string) {
	if len(query) == 0 {
		return tmsp.CodeType_OK, nil, "Query length cannot be zero"
	}
	typeByte := query[0]
	query = query[1:]
	switch typeByte {
	case 0x01: // Get
		key, n, err := wire.GetByteSlice(query)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		query = query[n:]
		if len(query) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		_, value, _ := app.tree.Get(key)
		res := make([]byte, wire.ByteSliceSize(value))
		buf := res
		n, err = wire.PutByteSlice(buf, value)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error putting value: %v", err.Error())
		}
		buf = buf[n:]
		return tmsp.CodeType_OK, res, ""
	default:
		return tmsp.CodeType_UnknownRequest, nil, Fmt("Unexpected type byte %X", typeByte)
	}
}
<commit_msg>Print SET for demo<commit_after>package app

import (
	"fmt"
	. "github.com/tendermint/go-common"
	"github.com/tendermint/go-merkle"
	"github.com/tendermint/go-wire"
	tmsp "github.com/tendermint/tmsp/types"
)

type MerkleEyesApp struct {
	tree merkle.Tree
}

func NewMerkleEyesApp() *MerkleEyesApp {
	tree := merkle.NewIAVLTree(
		0,
		nil,
	)
	return &MerkleEyesApp{tree: tree}
}

func (app *MerkleEyesApp) Info() string {
	return Fmt("size:%v", app.tree.Size())
}

func (app *MerkleEyesApp) SetOption(key string, value string) (log string) {
	return "No options are supported yet"
}

func (app *MerkleEyesApp) AppendTx(tx []byte) (code tmsp.CodeType, result []byte, log string) {
	if len(tx) == 0 {
		return tmsp.CodeType_EncodingError, nil, "Tx length cannot be zero"
	}
	typeByte := tx[0]
	tx = tx[1:]
	switch typeByte {
	case 0x01: // Set
		key, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		tx = tx[n:]
		value, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting value: %v", err.Error())
		}
		tx = tx[n:]
		if len(tx) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		app.tree.Set(key, value)
		fmt.Println("SET", Fmt("%X", key), Fmt("%X", value))
	case 0x02: // Remove
		key, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		tx = tx[n:]
		if len(tx) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		app.tree.Remove(key)
	default:
		return tmsp.CodeType_UnknownRequest, nil, Fmt("Unexpected type byte %X", typeByte)
	}
	return tmsp.CodeType_OK, nil, ""
}

func (app *MerkleEyesApp) CheckTx(tx []byte) (code tmsp.CodeType, result []byte, log string) {
	if len(tx) == 0 {
		return tmsp.CodeType_EncodingError, nil, "Tx length cannot be zero"
	}
	typeByte := tx[0]
	tx = tx[1:]
	switch typeByte {
	case 0x01: // Set
		_, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		tx = tx[n:]
		_, n, err = wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting value: %v", err.Error())
		}
		tx = tx[n:]
		if len(tx) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		//app.tree.Set(key, value)
	case 0x02: // Remove
		_, n, err := wire.GetByteSlice(tx)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		tx = tx[n:]
		if len(tx) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		//app.tree.Remove(key)
	default:
		return tmsp.CodeType_UnknownRequest, nil, Fmt("Unexpected type byte %X", typeByte)
	}
	return tmsp.CodeType_OK, nil, ""
}

func (app *MerkleEyesApp) GetHash() (hash []byte, log string) {
	if app.tree.Size() == 0 {
		return nil, "Empty hash for empty tree"
	}
	hash = app.tree.Hash()
	return hash, ""
}

func (app *MerkleEyesApp) Query(query []byte) (code tmsp.CodeType, result []byte, log string) {
	if len(query) == 0 {
		return tmsp.CodeType_OK, nil, "Query length cannot be zero"
	}
	typeByte := query[0]
	query = query[1:]
	switch typeByte {
	case 0x01: // Get
		key, n, err := wire.GetByteSlice(query)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error getting key: %v", err.Error())
		}
		query = query[n:]
		if len(query) != 0 {
			return tmsp.CodeType_EncodingError, nil, Fmt("Got bytes left over")
		}
		_, value, _ := app.tree.Get(key)
		res := make([]byte, wire.ByteSliceSize(value))
		buf := res
		n, err = wire.PutByteSlice(buf, value)
		if err != nil {
			return tmsp.CodeType_EncodingError, nil, Fmt("Error putting value: %v", err.Error())
		}
		buf = buf[n:]
		return tmsp.CodeType_OK, res, ""
	default:
		return tmsp.CodeType_UnknownRequest, nil, Fmt("Unexpected type byte %X", typeByte)
	}
}
<|endoftext|>


<commit_before>package pt

type Material struct {
	Color       Color
	Texture     Texture
	Emittance   float64
	Attenuation Attenuation
	Index       float64 // refractive index
	Gloss       float64 // reflection cone angle in radians
	Tint        float64 // specular tinting
	Transparent bool
}

func DiffuseMaterial(color Color) Material {
	return Material{color, nil, 0, NoAttenuation, 1, 0, 0, false}
}

func SpecularMaterial(color Color, index float64) Material {
	return Material{color, nil, 0, NoAttenuation, index, 0, 0, false}
}

func GlossyMaterial(color Color, index, gloss float64) Material {
	return Material{color, nil, 0, NoAttenuation, index, gloss, 0, false}
}

func TransparentMaterial(color Color, index, gloss, tint float64) Material {
	return Material{color, nil, 0, NoAttenuation, index, gloss, tint, true}
}

func LightMaterial(color Color, emittance float64, attenuation Attenuation) Material {
	return Material{color, nil, emittance, attenuation, 1, 0, 0, false}
}
<commit_msg>ClearMaterial<commit_after>package pt

type Material struct {
	Color       Color
	Texture     Texture
	Emittance   float64
	Attenuation Attenuation
	Index       float64 // refractive index
	Gloss       float64 // reflection cone angle in radians
	Tint        float64 // specular tinting
	Transparent bool
}

func DiffuseMaterial(color Color) Material {
	return Material{color, nil, 0, NoAttenuation, 1, 0, 0, false}
}

func SpecularMaterial(color Color, index float64) Material {
	return Material{color, nil, 0, NoAttenuation, index, 0, 0, false}
}

func GlossyMaterial(color Color, index, gloss float64) Material {
	return Material{color, nil, 0, NoAttenuation, index, gloss, 0, false}
}

func ClearMaterial(index, gloss float64) Material {
	return Material{Color{}, nil, 0, NoAttenuation, index, gloss, 0, true}
}

func TransparentMaterial(color Color, index, gloss, tint float64) Material {
	return Material{color, nil, 0, NoAttenuation, index, gloss, tint, true}
}

func LightMaterial(color Color, emittance float64, attenuation Attenuation) Material {
	return Material{color, nil, emittance, attenuation, 1, 0, 0, false}
}
<|endoftext|>


<commit_before>package errs

import (
	"errors"
	"fmt"
)

var (
	ErrMissingObjectID      = errors.New("objectID is missing or empty")
	ErrMissingKeyID         = errors.New("key ID is not set in Key.Value")
	ErrNoMoreHostToTry      = errors.New("all hosts have been contacted unsuccessfully, it can either be a network error or wrong appID/key credentials were used")
	ErrIndexAlreadyExists   = errors.New("destination index already exists, please delete it first as the CopyIndex cannot hold the responsibility of modifying the destination index")
	ErrSameAppID            = errors.New("indices cannot target the same application ID, please use Client.CopyIndex for same-app index copy instead")
	ErrObjectNotFound       = errors.New("object not found in with search responses' hits list")
	ErrEmptySecuredAPIKey   = errors.New("secured API key cannot be empty")
	ErrInvalidSecuredAPIKey = errors.New("invalid secured API key, please check that the given key is a secured one")
	ErrValidUntilNotFound   = errors.New("no validUntil parameter found, please make sure the secured API key has one")
)

func ErrJSONDecode(data []byte, t string) error {
	return fmt.Errorf("cannot decode value %s to type %s", string(data), t)
}
<commit_msg>refactor(errors): improve error message for `errs.ErrValidUntilNotFound`<commit_after>package errs

import (
	"errors"
	"fmt"
)

var (
	ErrMissingObjectID      = errors.New("objectID is missing or empty")
	ErrMissingKeyID         = errors.New("key ID is not set in Key.Value")
	ErrNoMoreHostToTry      = errors.New("all hosts have been contacted unsuccessfully, it can either be a network error or wrong appID/key credentials were used")
	ErrIndexAlreadyExists   = errors.New("destination index already exists, please delete it first as the CopyIndex cannot hold the responsibility of modifying the destination index")
	ErrSameAppID            = errors.New("indices cannot target the same application ID, please use Client.CopyIndex for same-app index copy instead")
	ErrObjectNotFound       = errors.New("object not found in with search responses' hits list")
	ErrEmptySecuredAPIKey   = errors.New("secured API key cannot be empty")
	ErrInvalidSecuredAPIKey = errors.New("invalid secured API key, please check that the given key is a secured one")
	ErrValidUntilNotFound   = errors.New("no valid `validUntil` parameter found, please make sure the secured API key has been generated correctly")
)

func ErrJSONDecode(data []byte, t string) error {
	return fmt.Errorf("cannot decode value %s to type %s", string(data), t)
}
<|endoftext|>


<commit_before>package main

import (
	"femebe"
	"fmt"
	"io"
	"net"
	"os"
	"strings"
)

// Automatically chooses between unix sockets and tcp sockets for
// listening
func autoListen(place string) (net.Listener, error) {
	if strings.Contains(place, "/") {
		return net.Listen("unix", place)
	}

	return net.Listen("tcp", place)
}

// Automatically chooses between unix sockets and tcp sockets for
// dialing.
func autoDial(place string) (net.Conn, error) {
	if strings.Contains(place, "/") {
		return net.Dial("unix", place)
	}

	return net.Dial("tcp", place)
}

type handlerFunc func(
	client femebe.MessageStream,
	server femebe.MessageStream,
	errch chan error)

type proxyBehavior struct {
	toFrontend handlerFunc
	toServer   handlerFunc
}

func (pbh *proxyBehavior) start(
	client femebe.MessageStream,
	server femebe.MessageStream) (errch chan error) {

	errch = make(chan error)

	go pbh.toFrontend(client, server, errch)
	go pbh.toServer(client, server, errch)
	return errch
}

var simpleProxy = proxyBehavior{
	toFrontend: func(client femebe.MessageStream,
		server femebe.MessageStream, errch chan error) {
		for {
			msg, err := server.Next()
			if err != nil {
				errch <- err
				return
			}

			err = client.Send(msg)
			if err != nil {
				errch <- err
				return
			}
		}
	},
	toServer: func(client femebe.MessageStream,
		server femebe.MessageStream, errch chan error) {
		for {
			msg, err := client.Next()
			if err != nil {
				errch <- err
				return
			}

			err = server.Send(msg)
			if err != nil {
				errch <- err
				return
			}
		}
	},
}

// Generic connection handler
//
// This redelegates to more specific proxy handlers that contain the
// main proxy loop logic.
func handleConnection(proxy proxyBehavior,
	clientConn net.Conn, serverAddr string) {
	var err error

	// Log disconnections
	defer func() {
		if err != nil && err != io.EOF {
			fmt.Printf("Session exits with error: %v\n", err)
		} else {
			fmt.Printf("Session exits cleanly\n")
		}
	}()

	defer clientConn.Close()

	c := femebe.NewMessageStream("Client", clientConn, clientConn)

	serverConn, err := autoDial(serverAddr)
	if err != nil {
		fmt.Printf("Could not connect to server: %v\n", err)
	}

	b := femebe.NewMessageStream("Server", serverConn, serverConn)

	done := proxy.start(c, b)
	err = <-done
}

// Startup and main client acceptance loop
func main() {
	if len(os.Args) != 3 {
		fmt.Printf("Usage: simpleproxy LISTENADDR SERVERADDR\n")
		os.Exit(1)
	}

	ln, err := autoListen(os.Args[1])
	if err != nil {
		fmt.Printf("Could not listen on address: %v\n", err)
		os.Exit(1)
	}

	for {
		conn, err := ln.Accept()

		if err != nil {
			fmt.Printf("Error: %v\n", err)
			continue
		}

		go handleConnection(simpleProxy, conn, os.Args[2])
	}

	fmt.Println("simpleproxy quits successfully")
	return
}
<commit_msg>Remove proxyBehavior, in favor of "session" construct<commit_after>package main

import (
	"femebe"
	"fmt"
	"io"
	"net"
	"os"
	"strings"
)

// Automatically chooses between unix sockets and tcp sockets for
// listening
func autoListen(place string) (net.Listener, error) {
	if strings.Contains(place, "/") {
		return net.Listen("unix", place)
	}

	return net.Listen("tcp", place)
}

// Automatically chooses between unix sockets and tcp sockets for
// dialing.
func autoDial(place string) (net.Conn, error) {
	if strings.Contains(place, "/") {
		return net.Dial("unix", place)
	}

	return net.Dial("tcp", place)
}

type session struct {
	ingress func()
	egress  func()
}

func (s *session) start() {
	go s.ingress()
	go s.egress()
}

func NewSimpleProxySession(
	errch chan error,
	client femebe.MessageStream,
	server femebe.MessageStream) *session {

	ingress := func() {
		for {
			msg, err := client.Next()
			if err != nil {
				errch <- err
				return
			}

			err = server.Send(msg)
			if err != nil {
				errch <- err
				return
			}
		}
	}

	egress := func() {
		for {
			msg, err := server.Next()
			if err != nil {
				errch <- err
				return
			}

			err = client.Send(msg)
			if err != nil {
				errch <- err
				return
			}
		}
	}

	return &session{ingress: ingress, egress: egress}
}

// Generic connection handler
//
// This redelegates to more specific proxy handlers that contain the
// main proxy loop logic.
func handleConnection(clientConn net.Conn, serverAddr string) {
	var err error

	// Log disconnections
	defer func() {
		if err != nil && err != io.EOF {
			fmt.Printf("Session exits with error: %v\n", err)
		} else {
			fmt.Printf("Session exits cleanly\n")
		}
	}()

	defer clientConn.Close()

	c := femebe.NewMessageStream("Client", clientConn, clientConn)

	serverConn, err := autoDial(serverAddr)
	if err != nil {
		fmt.Printf("Could not connect to server: %v\n", err)
	}

	s := femebe.NewMessageStream("Server", serverConn, serverConn)

	done := make(chan error)
	NewSimpleProxySession(done, c, s).start()
	err = <-done
}

// Startup and main client acceptance loop
func main() {
	if len(os.Args) != 3 {
		fmt.Printf("Usage: simpleproxy LISTENADDR SERVERADDR\n")
		os.Exit(1)
	}

	ln, err := autoListen(os.Args[1])
	if err != nil {
		fmt.Printf("Could not listen on address: %v\n", err)
		os.Exit(1)
	}

	for {
		conn, err := ln.Accept()

		if err != nil {
			fmt.Printf("Error: %v\n", err)
			continue
		}

		go handleConnection(conn, os.Args[2])
	}

	fmt.Println("simpleproxy quits successfully")
	return
}
<|endoftext|>