<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"time"

	"./model"
	"github.com/rs/cors"
	"goji.io"
	"goji.io/pat"
	"golang.org/x/net/context"
	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

func main() {
	//trying to connect to mongo
	db, err := mgo.Dial("localhost:27017")
	if err != nil {
		//something happens when dialing
		log.Fatal("Cannot dial mongo", err)
	}
	//clear when we're done
	defer db.Close()
	ensureIndex(db)
	//initiate new multiplexer
	mux := goji.NewMux()
	//register all handler for each end point
	mux.HandleFuncC(pat.Get("/swits/:switId"), getSwit(db))
	mux.HandleFuncC(pat.Get("/swits"), getAllSwits(db))
	mux.HandleFuncC(pat.Post("/swits"), createSwit(db))
	mux.HandleFuncC(pat.Post("/users"), addUser(db))
	mux.HandleFuncC(pat.Get("/users/:uid"), getUser(db))
	//to allow cross origin
	handler := cors.Default().Handler(mux)
	//finally, listen and serve in designated host and port
	http.ListenAndServe("127.0.0.1:3001", handler)
}

func ensureIndex(s *mgo.Session) {
	session := s.Copy()
	defer session.Close()

	c := session.DB("swit_app").C("users")

	index := mgo.Index{
		Key:        []string{"uid"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}
	err := c.EnsureIndex(index)
	if err != nil {
		log.Fatal(err)
	}
}

func addUser(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get the body request
		var user model.User
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&user)
		if err != nil {
			fmt.Println("Incorrect body of request")
			return
		}
		c := session.DB("swit_app").C("users")
		//add new user to database
		err = c.Insert(user)
		if err != nil {
			if mgo.IsDup(err) {
				//check if it's duplicate, if so return something to notify
				ResponseSimpleMessage("User is exist", false, w)
				return
			}
			//failed to Insert
			fmt.Println("Failed to insert a new user")
			log.Fatal(err)
		}

		ResponseSimpleMessage("Successfully added a new user", true, w)
	}
}

func getUser(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get query param
		uid := pat.Param(ctx, "uid")
		//get collection of users
		c := session.DB("swit_app").C("users")
		//prepare the model
		var user model.User
		//fetch the user in db
		err := c.Find(bson.M{"uid": uid}).One(&user)
		if err != nil {
			//failed to Insert
			fmt.Printf("Unable to search user with uid: %s", uid)
			log.Fatal(err)
		}
		//toJson
		respBody, _ := json.Marshal(user)
		ResponseWithJSON(w, respBody, http.StatusOK)
	}
}

func createSwit(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get the body request
		var swit model.Swit
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&swit)
		if err != nil {
			fmt.Println("Incorrect body of request")
			return
		}

		//should be now
		swit.Time = time.Now()
		swit.SwitId = bson.NewObjectIdWithTime(swit.Time)
		//TODO: should get the user id from req too
		swit.UserId = bson.NewObjectId()
		fmt.Println("incoming swit: ", swit)

		c := session.DB("swit_app").C("swits")
		//insert the new swit and catch error
		err = c.Insert(swit)
		if err != nil {
			//failed to Insert
			fmt.Println("Failed to insert a new book")
			log.Fatal(err)
		}
		resBody := SimpleResponse{"Successfully added a new book", true}
		fmt.Println("res body content: ", resBody)
		//toJson
		json, _ := json.Marshal(resBody)
		//write a response back
		ResponseWithJSON(w, json, http.StatusOK)
	}
}

func getAllSwits(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//prepare for the response
		var swits []*model.Swit
		//catch them all and if there is an error
		err := session.DB("swit_app").C("swits").Find(nil).All(&swits)
		if err != nil {
			//let's get panic instead
			panic(err)
		}
		// _ as blank identifier,the function returns multiple values, but we don't care
		switsJSON, _ := json.Marshal(swits)
		//write a response
		ResponseWithJSON(w, switsJSON, http.StatusOK)
	}
}

func getSwit(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get query param out of the http request
		switID := pat.Param(ctx, "switId")
		fmt.Printf("swit id is %s \n", switID)
		//get swits collection
		c := session.DB("swit_app").C("swits")
		var swit model.Swit
		//convert to object id
		oid := bson.ObjectIdHex(switID)
		err := c.Find(bson.M{"switId": oid}).One(&swit)
		if err != nil {
			panic(err)
		}

		fmt.Printf("the swit object is : %s \n", swit)
		//toJson
		respBody, _ := json.Marshal(swit)
		ResponseWithJSON(w, respBody, http.StatusOK)
	}
}

func ResponseSimpleMessage(message string, success bool, w http.ResponseWriter) {
	resBody := SimpleResponse{message, success}
	fmt.Println("res body content: ", resBody)
	//toJson
	json, _ := json.Marshal(resBody)
	//write a response back
	ResponseWithJSON(w, json, http.StatusOK)
}

func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {
	fmt.Println("Response Body : ", string(json))
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.WriteHeader(code)
	w.Write(json)
}

type SimpleResponse struct {
	Message string `json:"message"`
	Success bool   `json:"success"`
}
<commit_msg>Just listen to port 3001<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"time"

	"./model"
	"github.com/rs/cors"
	"goji.io"
	"goji.io/pat"
	"golang.org/x/net/context"
	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

func main() {
	//trying to connect to mongo
	db, err := mgo.Dial("localhost:27017")
	if err != nil {
		//something happens when dialing
		log.Fatal("Cannot dial mongo", err)
	}
	//clear when we're done
	defer db.Close()
	ensureIndex(db)
	//initiate new multiplexer
	mux := goji.NewMux()
	//register all handler for each end point
	mux.HandleFuncC(pat.Get("/swits/:switId"), getSwit(db))
	mux.HandleFuncC(pat.Get("/swits"), getAllSwits(db))
	mux.HandleFuncC(pat.Post("/swits"), createSwit(db))
	mux.HandleFuncC(pat.Post("/users"), addUser(db))
	mux.HandleFuncC(pat.Get("/users/:uid"), getUser(db))
	//to allow cross origin
	handler := cors.Default().Handler(mux)
	//finally, listen and serve in designated host and port
	http.ListenAndServe(":3001", handler)
}

func ensureIndex(s *mgo.Session) {
	session := s.Copy()
	defer session.Close()

	c := session.DB("swit_app").C("users")

	index := mgo.Index{
		Key:        []string{"uid"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}
	err := c.EnsureIndex(index)
	if err != nil {
		log.Fatal(err)
	}
}

func addUser(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get the body request
		var user model.User
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&user)
		if err != nil {
			fmt.Println("Incorrect body of request")
			return
		}
		c := session.DB("swit_app").C("users")
		//add new user to database
		err = c.Insert(user)
		if err != nil {
			if mgo.IsDup(err) {
				//check if it's duplicate, if so return something to notify
				ResponseSimpleMessage("User is exist", false, w)
				return
			}
			//failed to Insert
			fmt.Println("Failed to insert a new user")
			log.Fatal(err)
		}

		ResponseSimpleMessage("Successfully added a new user", true, w)
	}
}

func getUser(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get query param
		uid := pat.Param(ctx, "uid")
		//get collection of users
		c := session.DB("swit_app").C("users")
		//prepare the model
		var user model.User
		//fetch the user in db
		err := c.Find(bson.M{"uid": uid}).One(&user)
		if err != nil {
			//failed to Insert
			fmt.Printf("Unable to search user with uid: %s", uid)
			log.Fatal(err)
		}
		//toJson
		respBody, _ := json.Marshal(user)
		ResponseWithJSON(w, respBody, http.StatusOK)
	}
}

func createSwit(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get the body request
		var swit model.Swit
		decoder := json.NewDecoder(req.Body)
		err := decoder.Decode(&swit)
		if err != nil {
			fmt.Println("Incorrect body of request")
			return
		}

		//should be now
		swit.Time = time.Now()
		swit.SwitId = bson.NewObjectIdWithTime(swit.Time)
		//TODO: should get the user id from req too
		swit.UserId = bson.NewObjectId()
		fmt.Println("incoming swit: ", swit)

		c := session.DB("swit_app").C("swits")
		//insert the new swit and catch error
		err = c.Insert(swit)
		if err != nil {
			//failed to Insert
			fmt.Println("Failed to insert a new book")
			log.Fatal(err)
		}
		resBody := SimpleResponse{"Successfully added a new book", true}
		fmt.Println("res body content: ", resBody)
		//toJson
		json, _ := json.Marshal(resBody)
		//write a response back
		ResponseWithJSON(w, json, http.StatusOK)
	}
}

func getAllSwits(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//prepare for the response
		var swits []*model.Swit
		//catch them all and if there is an error
		err := session.DB("swit_app").C("swits").Find(nil).All(&swits)
		if err != nil {
			//let's get panic instead
			panic(err)
		}
		// _ as blank identifier,the function returns multiple values, but we don't care
		switsJSON, _ := json.Marshal(swits)
		//write a response
		ResponseWithJSON(w, switsJSON, http.StatusOK)
	}
}

func getSwit(s *mgo.Session) goji.HandlerFunc {
	return func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		//create a copy of a session
		session := s.Copy()
		//clear the copied session once it's done
		defer session.Close()
		//get query param out of the http request
		switID := pat.Param(ctx, "switId")
		fmt.Printf("swit id is %s \n", switID)
		//get swits collection
		c := session.DB("swit_app").C("swits")
		var swit model.Swit
		//convert to object id
		oid := bson.ObjectIdHex(switID)
		err := c.Find(bson.M{"switId": oid}).One(&swit)
		if err != nil {
			panic(err)
		}

		fmt.Printf("the swit object is : %s \n", swit)
		//toJson
		respBody, _ := json.Marshal(swit)
		ResponseWithJSON(w, respBody, http.StatusOK)
	}
}

func ResponseSimpleMessage(message string, success bool, w http.ResponseWriter) {
	resBody := SimpleResponse{message, success}
	fmt.Println("res body content: ", resBody)
	//toJson
	json, _ := json.Marshal(resBody)
	//write a response back
	ResponseWithJSON(w, json, http.StatusOK)
}

func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) {
	fmt.Println("Response Body : ", string(json))
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.WriteHeader(code)
	w.Write(json)
}

type SimpleResponse struct {
	Message string `json:"message"`
	Success bool   `json:"success"`
}
<|endoftext|>


<commit_before>/*
Copyright 2017 Google Inc.

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

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

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

package main

import (
	"context"
	"flag"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/0xRLG/ocworkqueue"
	"github.com/golang/glog"
	"go.opencensus.io/exporter/prometheus"
	"go.opencensus.io/stats/view"

	"k8s.io/client-go/discovery"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/workqueue"

	"k8s.io/metacontroller/apis/metacontroller/v1alpha1"
	mcclientset "k8s.io/metacontroller/client/generated/clientset/internalclientset"
	mcinformers "k8s.io/metacontroller/client/generated/informer/externalversions"
	"k8s.io/metacontroller/controller/composite"
	"k8s.io/metacontroller/controller/decorator"
	dynamicclientset "k8s.io/metacontroller/dynamic/clientset"
	dynamicdiscovery "k8s.io/metacontroller/dynamic/discovery"
	dynamicinformer "k8s.io/metacontroller/dynamic/informer"
)

var (
	discoveryInterval = flag.Duration("discovery-interval", 30*time.Second, "How often to refresh discovery cache to pick up newly-installed resources")
	informerRelist    = flag.Duration("cache-flush-interval", 30*time.Minute, "How often to flush local caches and relist objects from the API server")
	debugAddr         = flag.String("debug-addr", ":9999", "The address to bind the debug http endpoints")
	clientConfigPath  = flag.String("client-config-path", "", "Path to kubeconfig file (same format as used by kubectl); if not specified, use in-cluster config")
)

type controller interface {
	Start()
	Stop()
}

func main() {
	flag.Parse()

	glog.Infof("Discovery cache flush interval: %v", *discoveryInterval)
	glog.Infof("API server object cache flush interval: %v", *informerRelist)
	glog.Infof("Debug http server address: %v", *debugAddr)

	var config *rest.Config
	var err error
	if *clientConfigPath != "" {
		glog.Infof("Using current context from kubeconfig file: %v", *clientConfigPath)
		config, err = clientcmd.BuildConfigFromFlags("", *clientConfigPath)
	} else {
		glog.Info("No kubeconfig file specified; trying in-cluster auto-config...")
		config, err = rest.InClusterConfig()
	}
	if err != nil {
		glog.Fatal(err)
	}

	// Periodically refresh discovery to pick up newly-installed resources.
	dc := discovery.NewDiscoveryClientForConfigOrDie(config)
	resources := dynamicdiscovery.NewResourceMap(dc)
	// We don't care about stopping this cleanly since it has no external effects.
	resources.Start(*discoveryInterval)

	// Create informerfactory for metacontroller api objects.
	mcClient, err := mcclientset.NewForConfig(config)
	if err != nil {
		glog.Fatalf("Can't create client for api %s: %v", v1alpha1.SchemeGroupVersion, err)
	}
	mcInformerFactory := mcinformers.NewSharedInformerFactory(mcClient, *informerRelist)

	// Create dynamic clientset (factory for dynamic clients).
	dynClient, err := dynamicclientset.New(config, resources)
	if err != nil {
		glog.Fatal(err)
	}
	// Create dynamic informer factory (for sharing dynamic informers).
	dynInformers := dynamicinformer.NewSharedInformerFactory(dynClient, *informerRelist)

	workqueue.SetProvider(ocworkqueue.MetricsProvider())
	view.Register(ocworkqueue.DefaultViews...)

	// Start metacontrollers (controllers that spawn controllers).
	// Each one requests the informers it needs from the factory.
	controllers := []controller{
		composite.NewMetacontroller(resources, dynClient, dynInformers, mcInformerFactory, mcClient),
		decorator.NewMetacontroller(resources, dynClient, dynInformers, mcInformerFactory),
	}

	// Start all requested informers.
	// We don't care about stopping this cleanly since it has no external effects.
	mcInformerFactory.Start(nil)

	// Start all controllers.
	for _, c := range controllers {
		c.Start()
	}

	exporter, err := prometheus.NewExporter(prometheus.Options{})
	if err != nil {
		glog.Fatalf("can't create prometheus exporter: %v", err)
	}
	view.RegisterExporter(exporter)

	mux := http.NewServeMux()
	mux.Handle("/metrics", exporter)
	srv := &http.Server{
		Addr:    *debugAddr,
		Handler: mux,
	}
	go func() {
		glog.Errorf("Error serving debug endpoint: %v", srv.ListenAndServe())
	}()

	// On SIGTERM, stop all controllers gracefully.
	sigchan := make(chan os.Signal, 2)
	signal.Notify(sigchan, os.Interrupt, syscall.SIGTERM)
	sig := <-sigchan
	glog.Infof("Received %q signal. Shutting down...", sig)

	var wg sync.WaitGroup
	for _, c := range controllers {
		wg.Add(1)
		go func(c controller) {
			defer wg.Done()
			c.Stop()
		}(c)
	}
	wg.Add(1)
	go func() {
		defer wg.Done()
		srv.Shutdown(context.Background())
	}()
	wg.Wait()
}
<commit_msg>Add support for OIDC authentication<commit_after>/*
Copyright 2017 Google Inc.

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

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

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

package main

import (
	"context"
	"flag"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/0xRLG/ocworkqueue"
	"github.com/golang/glog"
	"go.opencensus.io/exporter/prometheus"
	"go.opencensus.io/stats/view"

	"k8s.io/client-go/discovery"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/workqueue"

	"k8s.io/metacontroller/apis/metacontroller/v1alpha1"
	mcclientset "k8s.io/metacontroller/client/generated/clientset/internalclientset"
	mcinformers "k8s.io/metacontroller/client/generated/informer/externalversions"
	"k8s.io/metacontroller/controller/composite"
	"k8s.io/metacontroller/controller/decorator"
	dynamicclientset "k8s.io/metacontroller/dynamic/clientset"
	dynamicdiscovery "k8s.io/metacontroller/dynamic/discovery"
	dynamicinformer "k8s.io/metacontroller/dynamic/informer"

	_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
)

var (
	discoveryInterval = flag.Duration("discovery-interval", 30*time.Second, "How often to refresh discovery cache to pick up newly-installed resources")
	informerRelist    = flag.Duration("cache-flush-interval", 30*time.Minute, "How often to flush local caches and relist objects from the API server")
	debugAddr         = flag.String("debug-addr", ":9999", "The address to bind the debug http endpoints")
	clientConfigPath  = flag.String("client-config-path", "", "Path to kubeconfig file (same format as used by kubectl); if not specified, use in-cluster config")
)

type controller interface {
	Start()
	Stop()
}

func main() {
	flag.Parse()

	glog.Infof("Discovery cache flush interval: %v", *discoveryInterval)
	glog.Infof("API server object cache flush interval: %v", *informerRelist)
	glog.Infof("Debug http server address: %v", *debugAddr)

	var config *rest.Config
	var err error
	if *clientConfigPath != "" {
		glog.Infof("Using current context from kubeconfig file: %v", *clientConfigPath)
		config, err = clientcmd.BuildConfigFromFlags("", *clientConfigPath)
	} else {
		glog.Info("No kubeconfig file specified; trying in-cluster auto-config...")
		config, err = rest.InClusterConfig()
	}
	if err != nil {
		glog.Fatal(err)
	}

	// Periodically refresh discovery to pick up newly-installed resources.
	dc := discovery.NewDiscoveryClientForConfigOrDie(config)
	resources := dynamicdiscovery.NewResourceMap(dc)
	// We don't care about stopping this cleanly since it has no external effects.
	resources.Start(*discoveryInterval)

	// Create informerfactory for metacontroller api objects.
	mcClient, err := mcclientset.NewForConfig(config)
	if err != nil {
		glog.Fatalf("Can't create client for api %s: %v", v1alpha1.SchemeGroupVersion, err)
	}
	mcInformerFactory := mcinformers.NewSharedInformerFactory(mcClient, *informerRelist)

	// Create dynamic clientset (factory for dynamic clients).
	dynClient, err := dynamicclientset.New(config, resources)
	if err != nil {
		glog.Fatal(err)
	}
	// Create dynamic informer factory (for sharing dynamic informers).
	dynInformers := dynamicinformer.NewSharedInformerFactory(dynClient, *informerRelist)

	workqueue.SetProvider(ocworkqueue.MetricsProvider())
	view.Register(ocworkqueue.DefaultViews...)

	// Start metacontrollers (controllers that spawn controllers).
	// Each one requests the informers it needs from the factory.
	controllers := []controller{
		composite.NewMetacontroller(resources, dynClient, dynInformers, mcInformerFactory, mcClient),
		decorator.NewMetacontroller(resources, dynClient, dynInformers, mcInformerFactory),
	}

	// Start all requested informers.
	// We don't care about stopping this cleanly since it has no external effects.
	mcInformerFactory.Start(nil)

	// Start all controllers.
	for _, c := range controllers {
		c.Start()
	}

	exporter, err := prometheus.NewExporter(prometheus.Options{})
	if err != nil {
		glog.Fatalf("can't create prometheus exporter: %v", err)
	}
	view.RegisterExporter(exporter)

	mux := http.NewServeMux()
	mux.Handle("/metrics", exporter)
	srv := &http.Server{
		Addr:    *debugAddr,
		Handler: mux,
	}
	go func() {
		glog.Errorf("Error serving debug endpoint: %v", srv.ListenAndServe())
	}()

	// On SIGTERM, stop all controllers gracefully.
	sigchan := make(chan os.Signal, 2)
	signal.Notify(sigchan, os.Interrupt, syscall.SIGTERM)
	sig := <-sigchan
	glog.Infof("Received %q signal. Shutting down...", sig)

	var wg sync.WaitGroup
	for _, c := range controllers {
		wg.Add(1)
		go func(c controller) {
			defer wg.Done()
			c.Stop()
		}(c)
	}
	wg.Add(1)
	go func() {
		defer wg.Done()
		srv.Shutdown(context.Background())
	}()
	wg.Wait()
}
<|endoftext|>


<commit_before>// testfcp project main.go
package main

import (
	"encoding/hex"
	"fmt"
	"time"
)

func main() {
		foo, err := fcp.NewClient("127.0.0.1:9481", false, "LOL Test")
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		foo.Connect()
		time.Sleep(3 * time.Second)

		upload := foo.NewClientPut()
		upload.SetURI("SSK@")
		upload.SetUploadFrom("disk")
		upload.SetFilename("f:\\curstats.txt")
		verbosity := byte(1 | 64 | 128)
		println(verbosity)
		upload.SetVerbosity(verbosity)
		upload.SetIdentifier("testing123")

		foo.DoInsert(upload)

		time.Sleep(5 * time.Minute)
		err = foo.Disconnect()
		if err != nil {
			fmt.Println(err.Error())
		}
		time.Sleep(3 * time.Second)

}
<commit_msg>fix imports<commit_after>// testfcp project main.go
package main

import (
	"fmt"
	"time"

	"github.com/theseeker/fcp-go"
)

func main() {
	foo, err := fcp.NewClient("127.0.0.1:9481", false, "LOL Test")
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	foo.Connect()
	time.Sleep(3 * time.Second)

	upload := foo.NewClientPut()
	upload.SetURI("SSK@")
	upload.SetUploadFrom("disk")
	upload.SetFilename("f:\\curstats.txt")
	verbosity := byte(1 | 64 | 128)
	println(verbosity)
	upload.SetVerbosity(verbosity)
	upload.SetIdentifier("testing123")

	foo.DoInsert(upload)

	time.Sleep(5 * time.Minute)
	err = foo.Disconnect()
	if err != nil {
		fmt.Println(err.Error())
	}
	time.Sleep(3 * time.Second)

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/fabioxgn/go-bot/commands"
	"github.com/thoj/go-ircevent"
	"log"
	"os"
)

const (
	configFile = "config.json"
)

var (
	irccon *irc.Connection
	config = &Config{}
)

func printAvailableCommands(channel string) {
	irccon.Privmsg(channel, "Available Commands:")
	cmds := ""
	for k, _ := range commands.Commands {
		cmds += k + ", "
	}
	irccon.Privmsg(channel, cmds[:len(cmds)-2])
}

func handleCmd(cmd *Command, channel string) {
	irc_cmd := commands.Commands[cmd.Command]
	if irc_cmd == nil {
		irccon.Privmsg(channel, fmt.Sprintf("Command %v not found.", cmd.Command))
		printAvailableCommands(channel)
	} else {
		log.Printf("cmd %v args %v", cmd.Command, cmd.Args)
		irccon.Privmsg(channel, irc_cmd(cmd.Args))
	}
}

func onPRIVMSG(e *irc.Event) {
	channel := e.Arguments[0]
	args := ""
	if channel == config.Nick {
		channel = e.Nick
		args = e.Message
	} else {
		args = StrAfter(e.Message, config.Cmd)
	}

	cmd, err := Parse(args)
	if err != nil {
		irccon.Privmsg(channel, err.Error())
		return
	}

	handleCmd(cmd, channel)
}

func connect() {
	irccon = irc.IRC(config.User, config.Nick)
	irccon.UseTLS = config.UseTLS
	err := irccon.Connect(config.Server)
	if err != nil {
		log.Fatal(err)
	}
}

func configureEvents() {
	irccon.AddCallback("001", func(e *irc.Event) {
		irccon.Join(config.Channels[0])
	})

	irccon.AddCallback("366", func(e *irc.Event) {
		irccon.Privmsg(config.Channels[0], "Hi there.\n")
	})

	irccon.AddCallback("PRIVMSG", onPRIVMSG)
}

func readConfig() {
	file, err := os.Open(configFile)
	if err != nil {
		panic(err)
	}
	config.Read(file)
	fmt.Printf("%v", config)
}

func main() {
	readConfig()
	connect()
	configureEvents()
	irccon.Loop()
}
<commit_msg>Removed _ from variable name<commit_after>package main

import (
	"fmt"
	"github.com/fabioxgn/go-bot/commands"
	"github.com/thoj/go-ircevent"
	"log"
	"os"
)

const (
	configFile = "config.json"
)

var (
	irccon *irc.Connection
	config = &Config{}
)

func printAvailableCommands(channel string) {
	irccon.Privmsg(channel, "Available Commands:")
	cmds := ""
	for k, _ := range commands.Commands {
		cmds += k + ", "
	}
	irccon.Privmsg(channel, cmds[:len(cmds)-2])
}

func handleCmd(cmd *Command, channel string) {
	cmdFunction := commands.Commands[cmd.Command]
	if cmdFunction == nil {
		irccon.Privmsg(channel, fmt.Sprintf("Command %v not found.", cmd.Command))
		printAvailableCommands(channel)
	} else {
		log.Printf("cmd %v args %v", cmd.Command, cmd.Args)
		irccon.Privmsg(channel, cmdFunction(cmd.Args))
	}
}

func onPRIVMSG(e *irc.Event) {
	channel := e.Arguments[0]
	args := ""
	if channel == config.Nick {
		channel = e.Nick
		args = e.Message
	} else {
		args = StrAfter(e.Message, config.Cmd)
	}

	cmd, err := Parse(args)
	if err != nil {
		irccon.Privmsg(channel, err.Error())
		return
	}

	handleCmd(cmd, channel)
}

func connect() {
	irccon = irc.IRC(config.User, config.Nick)
	irccon.UseTLS = config.UseTLS
	err := irccon.Connect(config.Server)
	if err != nil {
		log.Fatal(err)
	}
}

func configureEvents() {
	irccon.AddCallback("001", func(e *irc.Event) {
		irccon.Join(config.Channels[0])
	})

	irccon.AddCallback("366", func(e *irc.Event) {
		irccon.Privmsg(config.Channels[0], "Hi there.\n")
	})

	irccon.AddCallback("PRIVMSG", onPRIVMSG)
}

func readConfig() {
	file, err := os.Open(configFile)
	if err != nil {
		panic(err)
	}
	config.Read(file)
	fmt.Printf("%v", config)
}

func main() {
	readConfig()
	connect()
	configureEvents()
	irccon.Loop()
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"sync"

	"github.com/mylxsw/coyotes/config"
	"github.com/mylxsw/coyotes/console"
	"github.com/mylxsw/coyotes/log"
	"github.com/mylxsw/coyotes/pidfile"
	"github.com/mylxsw/coyotes/scheduler"
	"github.com/mylxsw/coyotes/signal"

	broker "github.com/mylxsw/coyotes/brokers/redis"
	server "github.com/mylxsw/coyotes/http"
)

var (
	redisAddr              string
	redisPassword          string
	redisDB                int
	redisAddrDepressed     string
	redisPasswordDepressed string
	httpAddr               string
	pidFile                string
	concurrent             int
	taskMode               bool
	colorfulTTY            bool
	defaultChannel         string
	logFilename            string
	debugMode              bool
)

func main() {
	flag.Usage = func() {
		fmt.Println(config.WelcomeMessageStr)
		fmt.Print("Options:\n\n")
		flag.PrintDefaults()
	}

	flag.StringVar(&redisAddr, "redis-host", "127.0.0.1:6379", "redis连接地址，必须指定端口")
	flag.StringVar(&redisPassword, "redis-password", "", "redis连接密码")
	flag.IntVar(&redisDB, "redis-db", 0, "redis默认数据库0-15")
	flag.StringVar(&redisAddrDepressed, "host", "127.0.0.1:6379", "redis连接地址，必须指定端口(depressed,使用redis-host)")
	flag.StringVar(&redisPasswordDepressed, "password", "", "redis连接密码(depressed,使用redis-password)")
	flag.StringVar(&httpAddr, "http-addr", "127.0.0.1:60001", "HTTP监控服务监听地址+端口")
	flag.StringVar(&pidFile, "pidfile", "", "pid文件路径，默认为空，不使用")
	flag.IntVar(&concurrent, "concurrent", 5, "并发执行线程数")
	flag.BoolVar(&taskMode, "task-mode", true, "是否启用任务模式，默认启用，关闭则不会执行消费")
	flag.BoolVar(&colorfulTTY, "colorful-tty", false, "是否启用彩色模式的控制台输出")
	flag.StringVar(&defaultChannel, "channel-default", "default", "默认channel名称，用于消息队列")
	flag.StringVar(&logFilename, "log-file", "", "日志文件存储路径，默认为空，直接输出到标准输出")
	flag.BoolVar(&debugMode, "debug", false, "日志输出级别，默认为false，如果为true，则输出debug日志")

	flag.Parse()

	runtime := config.InitRuntime(
		redisAddr,
		redisPassword,
		redisAddrDepressed,
		redisPasswordDepressed,
		pidFile,
		concurrent,
		redisDB,
		httpAddr,
		taskMode,
		colorfulTTY,
		defaultChannel,
		logFilename,
		debugMode,
	)

	if os.Getuid() == 0 {
		fmt.Println(console.ColorfulText(
			console.TextYellow,
			"\n当前以root(%s)用户执行，使用root权限执行可能会造成严重的安全问题，建议使用非root用户执行\n",
		))
	}

	// 初始化日志输出
	// 指定日志文件时，使用日志文件输出，否则输出到标准输出
	if logFilename != "" {
		logFile, err := os.OpenFile(logFilename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
		if err != nil {
			fmt.Printf("open log file %s failed: %v\n", logFilename, err)
			os.Exit(2)
		}
		defer logFile.Close()

		log.InitLogger(logFile, debugMode)
	} else {
		log.InitLogger(os.Stdout, debugMode)
	}

	// 创建进程pid文件
	if runtime.Config.PidFile != "" {
		pid, err := pidfile.New(runtime.Config.PidFile)
		if err != nil {
			log.Error("failed to create pidfile: %v", err)
			os.Exit(2)
		}
		defer pid.Remove()
	}

	if runtime.Config.ColorfulTTY {
		fmt.Println(console.ColorfulText(console.TextGreen, config.WelcomeMessage()))
	}

	log.Debug("redis addr: %s/%d", runtime.Config.Redis.Addr, runtime.Config.Redis.DB)
	log.Debug("process ID: %d", os.Getpid())

	// 信号处理程序，接收退出信号，平滑退出进程
	ctx, cancel := context.WithCancel(context.Background())
	signal.InitSignalReceiver(ctx, cancel)

	// 初始化所有channel
	scheduler.InitChannels()

	var wg sync.WaitGroup

	// 启动http server
	wg.Add(1)
	go func() {
		defer wg.Done()
		server.StartHTTPServer(ctx)
	}()

	// 启动待执行任务转移任务
	wg.Add(1)
	go func() {
		defer wg.Done()
		broker.TransferPrepareTask(ctx)
	}()

	// 启动延迟任务
	wg.Add(1)
	go func() {
		defer wg.Done()
		broker.StartDelayTaskLifeCycle(ctx)
	}()

	// 启动任务调度器
	scheduler.Schedule(ctx)

	wg.Wait()
	log.Debug("all stoped.")
}
<commit_msg>增加守护进程模式<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"sync"

	"github.com/mylxsw/coyotes/config"
	"github.com/mylxsw/coyotes/console"
	"github.com/mylxsw/coyotes/log"
	"github.com/mylxsw/coyotes/pidfile"
	"github.com/mylxsw/coyotes/scheduler"
	"github.com/mylxsw/coyotes/signal"

	"os/exec"

	broker "github.com/mylxsw/coyotes/brokers/redis"
	server "github.com/mylxsw/coyotes/http"
)

var (
	redisAddr              string
	redisPassword          string
	redisDB                int
	redisAddrDepressed     string
	redisPasswordDepressed string
	httpAddr               string
	pidFile                string
	concurrent             int
	taskMode               bool
	colorfulTTY            bool
	defaultChannel         string
	logFilename            string
	debugMode              bool
	daemonize              bool
)

func main() {

	flag.Usage = func() {
		fmt.Println(config.WelcomeMessageStr)
		fmt.Print("Options:\n\n")
		flag.PrintDefaults()
	}

	flag.StringVar(&redisAddr, "redis-host", "127.0.0.1:6379", "redis连接地址，必须指定端口")
	flag.StringVar(&redisPassword, "redis-password", "", "redis连接密码")
	flag.IntVar(&redisDB, "redis-db", 0, "redis默认数据库0-15")
	flag.StringVar(&redisAddrDepressed, "host", "127.0.0.1:6379", "redis连接地址，必须指定端口(depressed,使用redis-host)")
	flag.StringVar(&redisPasswordDepressed, "password", "", "redis连接密码(depressed,使用redis-password)")
	flag.StringVar(&httpAddr, "http-addr", "127.0.0.1:60001", "HTTP监控服务监听地址+端口")
	flag.StringVar(&pidFile, "pidfile", "", "pid文件路径，默认为空，不使用")
	flag.IntVar(&concurrent, "concurrent", 5, "并发执行线程数")
	flag.BoolVar(&taskMode, "task-mode", true, "是否启用任务模式，默认启用，关闭则不会执行消费")
	flag.BoolVar(&colorfulTTY, "colorful-tty", false, "是否启用彩色模式的控制台输出")
	flag.StringVar(&defaultChannel, "channel-default", "default", "默认channel名称，用于消息队列")
	flag.StringVar(&logFilename, "log-file", "", "日志文件存储路径，默认为空，直接输出到标准输出")
	flag.BoolVar(&debugMode, "debug", false, "日志输出级别，默认为false，如果为true，则输出debug日志")
	flag.BoolVar(&daemonize, "daemonize", false, "守护进程模式，模式为false")

	flag.Parse()

	// 如果是守护进程模式，则创建子进程，退出父进程
	if daemonize && os.Getppid() != 1 {
		binary, err := exec.LookPath(os.Args[0])
		if err != nil {
			fmt.Println("failed to lookup binary:", err)
			os.Exit(2)
		}
		_, err = os.StartProcess(binary, os.Args, &os.ProcAttr{Dir: "", Env: nil, Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}, Sys: nil})
		if err != nil {
			fmt.Println("failed to start process:", err)
			os.Exit(2)
		}

		os.Exit(0)
	}

	runtime := config.InitRuntime(
		redisAddr,
		redisPassword,
		redisAddrDepressed,
		redisPasswordDepressed,
		pidFile,
		concurrent,
		redisDB,
		httpAddr,
		taskMode,
		colorfulTTY,
		defaultChannel,
		logFilename,
		debugMode,
	)

	if os.Getuid() == 0 {
		fmt.Println(console.ColorfulText(
			console.TextYellow,
			"\n当前以root(%s)用户执行，使用root权限执行可能会造成严重的安全问题，建议使用非root用户执行\n",
		))
	}

	// 初始化日志输出
	// 指定日志文件时，使用日志文件输出，否则输出到标准输出
	if logFilename != "" {
		logFile, err := os.OpenFile(logFilename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
		if err != nil {
			fmt.Printf("open log file %s failed: %v\n", logFilename, err)
			os.Exit(2)
		}
		defer logFile.Close()

		log.InitLogger(logFile, debugMode)
	} else {
		log.InitLogger(os.Stdout, debugMode)
	}

	// 创建进程pid文件
	if runtime.Config.PidFile != "" {
		pid, err := pidfile.New(runtime.Config.PidFile)
		if err != nil {
			log.Error("failed to create pidfile: %v", err)
			os.Exit(2)
		}
		defer pid.Remove()
	}

	if runtime.Config.ColorfulTTY {
		fmt.Println(console.ColorfulText(console.TextGreen, config.WelcomeMessage()))
	}

	log.Debug("redis addr: %s/%d", runtime.Config.Redis.Addr, runtime.Config.Redis.DB)
	log.Debug("process ID: %d", os.Getpid())

	// 信号处理程序，接收退出信号，平滑退出进程
	ctx, cancel := context.WithCancel(context.Background())
	signal.InitSignalReceiver(ctx, cancel)

	// 初始化所有channel
	scheduler.InitChannels()

	var wg sync.WaitGroup

	// 启动http server
	wg.Add(1)
	go func() {
		defer wg.Done()
		server.StartHTTPServer(ctx)
	}()

	// 启动待执行任务转移任务
	wg.Add(1)
	go func() {
		defer wg.Done()
		broker.TransferPrepareTask(ctx)
	}()

	// 启动延迟任务
	wg.Add(1)
	go func() {
		defer wg.Done()
		broker.StartDelayTaskLifeCycle(ctx)
	}()

	// 启动任务调度器
	scheduler.Schedule(ctx)

	wg.Wait()
	log.Debug("all stoped.")
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/mreiferson/go-options"
)

func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
	flagSet := flag.NewFlagSet("oauth2_proxy", flag.ExitOnError)

	emailDomains := StringArray{}
	whitelistDomains := StringArray{}
	upstreams := StringArray{}
	skipAuthRegex := StringArray{}
	googleGroups := StringArray{}

	config := flagSet.String("config", "", "path to config file")
	showVersion := flagSet.Bool("version", false, "print version string")

	flagSet.String("http-address", "127.0.0.1:4180", "[http://]<addr>:<port> or unix://<path> to listen on for HTTP clients")
	flagSet.String("https-address", ":443", "<addr>:<port> to listen on for HTTPS clients")
	flagSet.String("tls-cert", "", "path to certificate file")
	flagSet.String("tls-key", "", "path to private key file")
	flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
	flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)")
	flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint or file:// paths for static files. Routing is based on the path")
	flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
	flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
	flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header")
	flagSet.Bool("pass-access-token", false, "pass OAuth access_token to upstream via X-Forwarded-Access-Token header")
	flagSet.Bool("pass-host-header", true, "pass the request Host Header to upstream")
	flagSet.Var(&skipAuthRegex, "skip-auth-regex", "bypass authentication for requests path's that match (may be given multiple times)")
	flagSet.Bool("skip-provider-button", false, "will skip sign-in-page to directly reach the next step: oauth/start")
	flagSet.Bool("skip-auth-preflight", false, "will skip authentication for OPTIONS requests")
	flagSet.Bool("ssl-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS")

	flagSet.Var(&emailDomains, "email-domain", "authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email")
	flagSet.Var(&whitelistDomains, "whitelist-domain", "allowed domains for redirection after authentication. Prefix domain with a . to allow subdomains (eg .example.com)")
	flagSet.String("azure-tenant", "common", "go to a tenant-specific or common (tenant-independent) endpoint.")
	flagSet.String("github-org", "", "restrict logins to members of this organisation")
	flagSet.String("github-team", "", "restrict logins to members of this team")
	flagSet.String("gitlab-group", "", "restrict logins to members of this group (full path) (may be given multiple times)")
	flagSet.Var(&googleGroups, "google-group", "restrict logins to members of this google group (may be given multiple times).")
	flagSet.String("google-admin-email", "", "the google admin to impersonate for api calls")
	flagSet.String("google-service-account-json", "", "the path to the service account json credentials")
	flagSet.String("client-id", "", "the OAuth Client ID: ie: \"123456.apps.googleusercontent.com\"")
	flagSet.String("client-secret", "", "the OAuth Client Secret")
	flagSet.String("authenticated-emails-file", "", "authenticate against emails via file (one per line)")
	flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption or \"htpasswd -B\" for bcrypt encryption")
	flagSet.Bool("display-htpasswd-form", true, "display username / password login form if an htpasswd file is provided")
	flagSet.String("custom-templates-dir", "", "path to custom html templates")
	flagSet.String("footer", "", "custom footer string. Use \"-\" to disable default footer.")
	flagSet.String("proxy-prefix", "/oauth2", "the url root path that this proxy should be nested under (e.g. /<oauth2>/sign_in)")

	flagSet.String("cookie-name", "_oauth2_proxy", "the name of the cookie that the oauth_proxy creates")
	flagSet.String("cookie-secret", "", "the seed string for secure cookies (optionally base64 encoded)")
	flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*")
	flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")
	flagSet.Duration("cookie-refresh", time.Duration(0), "refresh the cookie after this duration; 0 to disable")
	flagSet.Bool("cookie-secure", true, "set secure (HTTPS) cookie flag")
	flagSet.Bool("cookie-httponly", true, "set HttpOnly cookie flag")

	flagSet.Bool("request-logging", true, "Log requests to stdout")
	flagSet.String("request-logging-format", defaultRequestLoggingFormat, "Template for log lines")

	flagSet.String("provider", "google", "OAuth provider")
	flagSet.String("oidc-issuer-url", "", "OpenID Connect issuer URL (ie: https://accounts.google.com)")
	flagSet.String("login-url", "", "Authentication endpoint")
	flagSet.String("redeem-url", "", "Token redemption endpoint")
	flagSet.String("profile-url", "", "Profile access endpoint")
	flagSet.String("resource", "", "The resource that is protected (Azure AD only)")
	flagSet.String("validate-url", "", "Access token validation endpoint")
	flagSet.String("scope", "", "OAuth scope specification")
	flagSet.String("approval-prompt", "force", "OAuth approval_prompt")

	flagSet.String("signature-key", "", "GAP-Signature request signature key (algorithm:secretkey)")

	flagSet.Parse(os.Args[1:])

	if *showVersion {
		fmt.Printf("oauth2_proxy v%s (built with %s)\n", VERSION, runtime.Version())
		return
	}

	opts := NewOptions()

	cfg := make(EnvOptions)
	if *config != "" {
		_, err := toml.DecodeFile(*config, &cfg)
		if err != nil {
			log.Fatalf("ERROR: failed to load config file %s - %s", *config, err)
		}
	}
	cfg.LoadEnvForStruct(opts)
	options.Resolve(opts, flagSet, cfg)

	err := opts.Validate()
	if err != nil {
		log.Printf("%s", err)
		os.Exit(1)
	}
	validator := NewValidator(opts.EmailDomains, opts.AuthenticatedEmailsFile)
	oauthproxy := NewOAuthProxy(opts, validator)

	if len(opts.EmailDomains) != 0 && opts.AuthenticatedEmailsFile == "" {
		if len(opts.EmailDomains) > 1 {
			oauthproxy.SignInMessage = fmt.Sprintf("Authenticate using one of the following domains: %v", strings.Join(opts.EmailDomains, ", "))
		} else if opts.EmailDomains[0] != "*" {
			oauthproxy.SignInMessage = fmt.Sprintf("Authenticate using %v", opts.EmailDomains[0])
		}
	}

	if opts.HtpasswdFile != "" {
		log.Printf("using htpasswd file %s", opts.HtpasswdFile)
		oauthproxy.HtpasswdFile, err = NewHtpasswdFromFile(opts.HtpasswdFile)
		oauthproxy.DisplayHtpasswdForm = opts.DisplayHtpasswdForm
		if err != nil {
			log.Fatalf("FATAL: unable to open %s %s", opts.HtpasswdFile, err)
		}
	}

	s := &Server{
		Handler: LoggingHandler(os.Stdout, oauthproxy, opts.RequestLogging, opts.RequestLoggingFormat),
		Opts:    opts,
	}
	s.ListenAndServe()
}
<commit_msg>fix gitlab groups option<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/mreiferson/go-options"
)

func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
	flagSet := flag.NewFlagSet("oauth2_proxy", flag.ExitOnError)

	emailDomains := StringArray{}
	whitelistDomains := StringArray{}
	upstreams := StringArray{}
	skipAuthRegex := StringArray{}
	googleGroups := StringArray{}
	gitlabGroups := StringArray{}

	config := flagSet.String("config", "", "path to config file")
	showVersion := flagSet.Bool("version", false, "print version string")

	flagSet.String("http-address", "127.0.0.1:4180", "[http://]<addr>:<port> or unix://<path> to listen on for HTTP clients")
	flagSet.String("https-address", ":443", "<addr>:<port> to listen on for HTTPS clients")
	flagSet.String("tls-cert", "", "path to certificate file")
	flagSet.String("tls-key", "", "path to private key file")
	flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
	flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)")
	flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint or file:// paths for static files. Routing is based on the path")
	flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
	flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
	flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header")
	flagSet.Bool("pass-access-token", false, "pass OAuth access_token to upstream via X-Forwarded-Access-Token header")
	flagSet.Bool("pass-host-header", true, "pass the request Host Header to upstream")
	flagSet.Var(&skipAuthRegex, "skip-auth-regex", "bypass authentication for requests path's that match (may be given multiple times)")
	flagSet.Bool("skip-provider-button", false, "will skip sign-in-page to directly reach the next step: oauth/start")
	flagSet.Bool("skip-auth-preflight", false, "will skip authentication for OPTIONS requests")
	flagSet.Bool("ssl-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS")

	flagSet.Var(&emailDomains, "email-domain", "authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email")
	flagSet.Var(&whitelistDomains, "whitelist-domain", "allowed domains for redirection after authentication. Prefix domain with a . to allow subdomains (eg .example.com)")
	flagSet.String("azure-tenant", "common", "go to a tenant-specific or common (tenant-independent) endpoint.")
	flagSet.String("github-org", "", "restrict logins to members of this organisation")
	flagSet.String("github-team", "", "restrict logins to members of this team")
	flagSet.Var(&gitlabGroups, "gitlab-group", "restrict logins to members of this group (full path) (may be given multiple times)")
	flagSet.Var(&googleGroups, "google-group", "restrict logins to members of this google group (may be given multiple times).")
	flagSet.String("google-admin-email", "", "the google admin to impersonate for api calls")
	flagSet.String("google-service-account-json", "", "the path to the service account json credentials")
	flagSet.String("client-id", "", "the OAuth Client ID: ie: \"123456.apps.googleusercontent.com\"")
	flagSet.String("client-secret", "", "the OAuth Client Secret")
	flagSet.String("authenticated-emails-file", "", "authenticate against emails via file (one per line)")
	flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption or \"htpasswd -B\" for bcrypt encryption")
	flagSet.Bool("display-htpasswd-form", true, "display username / password login form if an htpasswd file is provided")
	flagSet.String("custom-templates-dir", "", "path to custom html templates")
	flagSet.String("footer", "", "custom footer string. Use \"-\" to disable default footer.")
	flagSet.String("proxy-prefix", "/oauth2", "the url root path that this proxy should be nested under (e.g. /<oauth2>/sign_in)")

	flagSet.String("cookie-name", "_oauth2_proxy", "the name of the cookie that the oauth_proxy creates")
	flagSet.String("cookie-secret", "", "the seed string for secure cookies (optionally base64 encoded)")
	flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*")
	flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")
	flagSet.Duration("cookie-refresh", time.Duration(0), "refresh the cookie after this duration; 0 to disable")
	flagSet.Bool("cookie-secure", true, "set secure (HTTPS) cookie flag")
	flagSet.Bool("cookie-httponly", true, "set HttpOnly cookie flag")

	flagSet.Bool("request-logging", true, "Log requests to stdout")
	flagSet.String("request-logging-format", defaultRequestLoggingFormat, "Template for log lines")

	flagSet.String("provider", "google", "OAuth provider")
	flagSet.String("oidc-issuer-url", "", "OpenID Connect issuer URL (ie: https://accounts.google.com)")
	flagSet.String("login-url", "", "Authentication endpoint")
	flagSet.String("redeem-url", "", "Token redemption endpoint")
	flagSet.String("profile-url", "", "Profile access endpoint")
	flagSet.String("resource", "", "The resource that is protected (Azure AD only)")
	flagSet.String("validate-url", "", "Access token validation endpoint")
	flagSet.String("scope", "", "OAuth scope specification")
	flagSet.String("approval-prompt", "force", "OAuth approval_prompt")

	flagSet.String("signature-key", "", "GAP-Signature request signature key (algorithm:secretkey)")

	flagSet.Parse(os.Args[1:])

	if *showVersion {
		fmt.Printf("oauth2_proxy v%s (built with %s)\n", VERSION, runtime.Version())
		return
	}

	opts := NewOptions()

	cfg := make(EnvOptions)
	if *config != "" {
		_, err := toml.DecodeFile(*config, &cfg)
		if err != nil {
			log.Fatalf("ERROR: failed to load config file %s - %s", *config, err)
		}
	}
	cfg.LoadEnvForStruct(opts)
	options.Resolve(opts, flagSet, cfg)

	err := opts.Validate()
	if err != nil {
		log.Printf("%s", err)
		os.Exit(1)
	}
	validator := NewValidator(opts.EmailDomains, opts.AuthenticatedEmailsFile)
	oauthproxy := NewOAuthProxy(opts, validator)

	if len(opts.EmailDomains) != 0 && opts.AuthenticatedEmailsFile == "" {
		if len(opts.EmailDomains) > 1 {
			oauthproxy.SignInMessage = fmt.Sprintf("Authenticate using one of the following domains: %v", strings.Join(opts.EmailDomains, ", "))
		} else if opts.EmailDomains[0] != "*" {
			oauthproxy.SignInMessage = fmt.Sprintf("Authenticate using %v", opts.EmailDomains[0])
		}
	}

	if opts.HtpasswdFile != "" {
		log.Printf("using htpasswd file %s", opts.HtpasswdFile)
		oauthproxy.HtpasswdFile, err = NewHtpasswdFromFile(opts.HtpasswdFile)
		oauthproxy.DisplayHtpasswdForm = opts.DisplayHtpasswdForm
		if err != nil {
			log.Fatalf("FATAL: unable to open %s %s", opts.HtpasswdFile, err)
		}
	}

	s := &Server{
		Handler: LoggingHandler(os.Stdout, oauthproxy, opts.RequestLogging, opts.RequestLoggingFormat),
		Opts:    opts,
	}
	s.ListenAndServe()
}
<|endoftext|>


<commit_before>package main

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

func main() {
	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		t := s.Text()
		line := strings.TrimSpace(s.Text())
		if strings.HasPrefix(line, "nnf:") {
			printNotNilFatal(t)
		} else if strings.HasPrefix(line, "lpf(") {
			printLogPrintf(t)
		} else if strings.HasPrefix(line, "fpf(") {
			fPrintf(t)
		} else if strings.HasPrefix(line, "fpl(") {
			fPrintln(t)
		} else if strings.HasPrefix(line, "lpl(") {
			lPrintln(t)
		} else if line == "gomain" {
			goMain()
		} else {
			fmt.Println(t)
		}
	}
}

func printNotNilFatal(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	msg := strings.SplitN(line, ":", 2)[1]

	// print error block
	fmt.Printf("%sif err != nil{\n", pad)
	fmt.Printf("%s%slog.Fatal(%q, err)\n", pad, pad, msg+": ")
	fmt.Printf("%s}\n", pad)
}

func printLogPrintf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fPrintf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lPrintln(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fPrintln(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}
<commit_msg>added "t.t" for "t *testing.T)<commit_after>package main

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

func main() {
	stat, err := os.Stdin.Stat()
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&os.ModeCharDevice != 0 {
		log.Fatal("please pipe in some data")
	}

	s := bufio.NewScanner(os.Stdin)
	for s.Scan() {
		t := s.Text()
		line := strings.TrimSpace(s.Text())
		if strings.HasPrefix(line, "nnf:") {
			printNotNilFatal(t)
		} else if strings.HasPrefix(line, "lpf(") {
			printLogPrintf(t)
		} else if strings.HasPrefix(line, "fpf(") {
			fPrintf(t)
		} else if strings.HasPrefix(line, "fpl(") {
			fPrintln(t)
		} else if strings.HasPrefix(line, "lpl(") {
			lPrintln(t)
		} else if line == "gomain" {
			goMain()
		} else if strings.Contains(t, "(t.t)") {
			fmt.Println(strings.Replace(t, "(t.t)", "(t *testing.T)", 1))
		} else {
			fmt.Println(t)
		}
	}
}

func printNotNilFatal(line string) {
	l := len(line) - len(strings.TrimLeft(line, " "))
	pad := strings.Repeat(" ", l)
	msg := strings.SplitN(line, ":", 2)[1]

	// print error block
	fmt.Printf("%sif err != nil{\n", pad)
	fmt.Printf("%s%slog.Fatal(%q, err)\n", pad, pad, msg+": ")
	fmt.Printf("%s}\n", pad)
}

func printLogPrintf(line string) {
	fmt.Println(strings.Replace(line, "lpf(", "log.Printf(", 1))
}

func fPrintf(line string) {
	fmt.Println(strings.Replace(line, "fpf(", "fmt.Printf(", 1))
}

func lPrintln(line string) {
	fmt.Println(strings.Replace(line, "lpl(", "log.Println(", 1))
}

func fPrintln(line string) {
	fmt.Println(strings.Replace(line, "fpl(", "fmt.Println(", 1))
}

func goMain() {
	fmt.Println(`package main

import (
    "fmt"
)

func main() {
    fmt.Println("gopher")
}
`)
}
<|endoftext|>


<commit_before>package main

import "math"
import "math/rand"
import "math/big"
import crand "crypto/rand"
import "fmt"
import "strings"
import "flag"

var players []*Player
var debug bool
var singleRound bool

func main() {
	seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
	if err != nil {
		panic(err)
	}
	rand.Seed(seed.Int64())

	flag.BoolVar(&debug, "v", false, "Provide more verbose output for debugging purposes")
	flag.BoolVar(&singleRound, "s", false, "Stop after running only a single round of the game")
	flag.Parse()

	players = make([]*Player, flag.NArg())
	var startPlayer = 0

	var deck = new(Deck)

	for i, _ := range players {
		players[i] = new(Player)
	}

	for won, _ := PlayerWon(); !won; won, _ = PlayerWon() {
		deck.Init()
		for i, _ := range players {
			players[i].Init(flag.Arg(i), i, len(players), startPlayer)
			cardDrawn := deck.Draw()
			players[i].Send("draw", cardDrawn)
			players[i].AddToHand(cardDrawn)
			Debug("*** Player", i, "drew", cardDrawn, "***")
			Debug("*** Player", i, "hand:", players[i].HandString(), "***")
		}

		_ = deck.Draw() //throw away a card to prevent perfect information

		var currentPlayer = startPlayer
		for !deck.IsEmpty() && (SurvivingPlayers() > 1) {
			var fullMove, action, cardStr, queryStr string
			var target, n int
			var card, cardDrawn Card

			if players[currentPlayer].lost {
				goto endTurn
			}

			SendAll("player", currentPlayer)
			players[currentPlayer].protected = false //protection expires on your turn

			cardDrawn = deck.Draw()
			players[currentPlayer].Send("draw", cardDrawn)
			players[currentPlayer].AddToHand(cardDrawn)
			if players[currentPlayer].ministered && (players[currentPlayer].HandValue() >= 12) {
				Out(currentPlayer)
				goto endTurn
			}

			Debug("*** Player", currentPlayer, "drew", cardDrawn, "***")
			Debug("*** Player", currentPlayer, "hand:", players[currentPlayer].HandString(), "***")

			fullMove = players[currentPlayer].Recieve()
			Debug("*** Player", currentPlayer, "move:", fullMove, "***")

			n, _ = fmt.Sscan(fullMove, &action, &cardStr, &target, &queryStr)

			if !strings.EqualFold(action, "play") {
				//must be "forfeit" or some invalid action
				Debug("*** ERROR: Player", currentPlayer, "made an illegal play or forfeited ***")
				Out(currentPlayer)
				goto endTurn
			}

			if n < 2 {
				//malformed move
				Debug("*** ERROR: Player", currentPlayer, "passed too few arguments ***")
				Out(currentPlayer)
				goto endTurn
			}

			card = ParseCard(cardStr)
			if ok := players[currentPlayer].RemoveFromHand(card); !ok {
				//trying to play a card you don't have is illegal
				Debug("*** ERROR: Player", currentPlayer, "played a card they dont have:", card, "***")
				Out(currentPlayer)
				goto endTurn
			}
			Debug("*** Player", currentPlayer, "played", card, "***")
			Debug("*** Player", currentPlayer, "hand:", players[currentPlayer].HandString(), "***")

			//check the right arguments have been given
			switch card {
			case Princess, Minister, Priestess:
				if n != 2 {
					Debug("*** ERROR: Player", currentPlayer, "passed the wrong number of arguments for the played card ***")
					Out(currentPlayer)
					goto endTurn
				}
			case General, Wizard, Knight, Clown:
				if n != 3 {
					Debug("*** ERROR: Player", currentPlayer, "passed the wrong number of arguments for the played card ***")
					Out(currentPlayer)
					goto endTurn
				}

			case Soldier:
				if n != 4 {
					Debug("*** ERROR: Player", currentPlayer, "passed the wrong number of arguments for the played card ***")
					Out(currentPlayer)
					goto endTurn
				}
				if (target >= len(players)) && (target < 0) {
					Debug("*** ERROR: Player", currentPlayer, "passed a bad target argument ***")
					Out(currentPlayer)
					goto endTurn
				}
			}

			SendAll("played", currentPlayer, card)

			//check target is okay
			switch card {
			case General, Wizard, Knight, Clown, Soldier:
				if (target >= len(players)) && (target < 0) {
					Debug("*** ERROR: Player", currentPlayer, "passed a bad target argument ***")
					Out(currentPlayer)
					goto endTurn
				}
				if players[target].lost {
					Debug("*** ERROR: Player", currentPlayer, "attempted to target a player who has already lost ***")
					Out(currentPlayer)
					goto endTurn
				}
				if players[target].protected {
					Debug("*** Player", target, "was protected by a priestess")
					goto endTurn
				}
			}

			switch card {
			case Princess:
				Out(currentPlayer)
			case Minister:
				players[currentPlayer].ministered = true
			case General:
				players[currentPlayer].Send("swap", players[target].hand[0])
				players[target].Send("swap", players[currentPlayer].hand[0])
				players[currentPlayer].hand[0], players[target].hand[0] = players[target].hand[0], players[currentPlayer].hand[0]
				Debug("*** Player", currentPlayer, "and Player", target, "swapped hands ***")
				Debug("*** Player", currentPlayer, "hand:", players[currentPlayer].HandString(), "***")
				Debug("*** Player", target, "hand:", players[target].HandString(), "***")
			case Wizard:
				Debug("*** Player", target, "discards hand and draws a new card ***")
				SendAll("discard", target, players[target].hand[0])
				if players[target].hand[0] == Princess {
					Out(target)
					goto endTurn
				}
				if deck.IsEmpty() {
					Debug("*** Player", target, "can't draw as there are no cards left ***")
					Out(target)
					goto endTurn
				}
				players[target].hand[0] = deck.Draw()
				players[target].Send("draw", players[target].hand[0])
				Debug("*** Player", target, "hand:", players[target].HandString(), "***")
			case Priestess:
				players[currentPlayer].protected = true
			case Knight:
				Debug("*** Player", currentPlayer, "and Player", target, "compare hands ***")
				Debug("*** Player", currentPlayer, "hand:", players[currentPlayer].HandString(), "***")
				Debug("*** Player", target, "hand:", players[target].HandString(), "***")
				players[target].Send("reveal", currentPlayer, players[currentPlayer].hand[0])
				players[currentPlayer].Send("reveal", target, players[target].hand[0])
				if players[currentPlayer].HandValue() > players[target].HandValue() {
					Out(target)
				} else if players[currentPlayer].HandValue() < players[target].HandValue() {
					Out(currentPlayer)
				}
			case Clown:
				Debug("*** Player", target, "reveals a", players[target].hand[0], "from their hand to Player", currentPlayer, "***")
				players[currentPlayer].Send("reveal", target, players[target].hand[0])
			case Soldier:
				Debug("*** Player", currentPlayer, "asked Player", target, "if they have a", queryStr, "in their hand ***")
				if players[target].HasInHand(ParseCard(queryStr)) {
					Out(target)
				}
			default:
				Debug("*** ERROR: Player", currentPlayer, "played an illegal card:", cardStr, "***")
				Out(currentPlayer)
			}

		endTurn:
			currentPlayer++
			if currentPlayer >= len(players) {
				currentPlayer = 0
			}
		}
		startPlayer++
		if startPlayer >= len(players) {
			startPlayer = 0
		}

		winningHandValue := 0
		for i, _ := range players {
			if players[i].HandValue() > winningHandValue {
				winningHandValue = players[i].HandValue()
			}
		}
		for i, _ := range players {
			if players[i].HandValue() == winningHandValue {
				players[i].roundsWon++
			}
			players[i].Forfeit()
		}
		fmt.Print("Round ended.\t")
		for i, p := range players {
			fmt.Print("Player ", i, " score: ", p.roundsWon, "\t")
		}
		fmt.Println()

		if singleRound {
			//only running one round so stop now
			return
		}
	}
	_, winner := PlayerWon()
	fmt.Println("Player won:", winner, players[winner].name)
}

func SendAll(args ...interface{}) {
	for _, player := range players {
		if !player.lost {
			player.Send(args...)
		}
	}
}

func SurvivingPlayers() int {
	result := 0
	for _, player := range players {
		if !player.lost {
			result++
		}
	}
	return result
}

func PlayerWon() (bool, int) {
	for i, p := range players {
		if p.roundsWon >= 4 {
			return true, i
		}
	}
	return false, 0
}

func Out(playerNumber int) {
	players[playerNumber].Forfeit()
	SendAll("out", playerNumber, players[playerNumber].HandString())
	Debug("*** Player", playerNumber, "out:", players[playerNumber].HandString(), "***")
}

func Debug(args ...interface{}) {
	if debug {
		fmt.Println(args...)
	}
}
<commit_msg>Implemented correct targetting behaviour<commit_after>package main

import "math"
import "math/rand"
import "math/big"
import crand "crypto/rand"
import "fmt"
import "strings"
import "flag"

var players []*Player
var debug bool
var singleRound bool

func main() {
	seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
	if err != nil {
		panic(err)
	}
	rand.Seed(seed.Int64())

	flag.BoolVar(&debug, "v", false, "Provide more verbose output for debugging purposes")
	flag.BoolVar(&singleRound, "s", false, "Stop after running only a single round of the game")
	flag.Parse()

	players = make([]*Player, flag.NArg())
	var startPlayer = 0

	var deck = new(Deck)

	for i, _ := range players {
		players[i] = new(Player)
	}

	for won, _ := PlayerWon(); !won; won, _ = PlayerWon() {
		deck.Init()
		for i, _ := range players {
			players[i].Init(flag.Arg(i), i, len(players), startPlayer)
			cardDrawn := deck.Draw()
			players[i].Send("draw", cardDrawn)
			players[i].AddToHand(cardDrawn)
			Debug("*** Player", i, "drew", cardDrawn, "***")
			Debug("*** Player", i, "hand:", players[i].HandString(), "***")
		}

		_ = deck.Draw() //throw away a card to prevent perfect information

		var currentPlayer = startPlayer
		for !deck.IsEmpty() && (SurvivingPlayers() > 1) {
			var fullMove, action, cardStr, queryStr string
			var target, n int
			var card, cardDrawn Card

			if players[currentPlayer].lost {
				goto endTurn
			}

			SendAll("player", currentPlayer)
			players[currentPlayer].protected = false //protection expires on your turn

			cardDrawn = deck.Draw()
			players[currentPlayer].Send("draw", cardDrawn)
			players[currentPlayer].AddToHand(cardDrawn)
			if players[currentPlayer].ministered && (players[currentPlayer].HandValue() >= 12) {
				Out(currentPlayer)
				goto endTurn
			}

			Debug("*** Player", currentPlayer, "drew", cardDrawn, "***")
			Debug("*** Player", currentPlayer, "hand:", players[currentPlayer].HandString(), "***")

			fullMove = players[currentPlayer].Recieve()
			Debug("*** Player", currentPlayer, "move:", fullMove, "***")

			n, _ = fmt.Sscan(fullMove, &action, &cardStr, &target, &queryStr)

			if !strings.EqualFold(action, "play") {
				//must be "forfeit" or some invalid action
				Debug("*** ERROR: Player", currentPlayer, "made an illegal play or forfeited ***")
				Out(currentPlayer)
				goto endTurn
			}

			if n < 2 {
				//malformed move
				Debug("*** ERROR: Player", currentPlayer, "passed too few arguments ***")
				Out(currentPlayer)
				goto endTurn
			}

			card = ParseCard(cardStr)
			if ok := players[currentPlayer].RemoveFromHand(card); !ok {
				//trying to play a card you don't have is illegal
				Debug("*** ERROR: Player", currentPlayer, "played a card they dont have:", card, "***")
				Out(currentPlayer)
				goto endTurn
			}
			Debug("*** Player", currentPlayer, "played", card, "***")
			Debug("*** Player", currentPlayer, "hand:", players[currentPlayer].HandString(), "***")

			//check the right arguments have been given
			switch card {
			case Princess, Minister, Priestess:
				if n != 2 {
					Debug("*** ERROR: Player", currentPlayer, "passed the wrong number of arguments for the played card ***")
					Out(currentPlayer)
					goto endTurn
				}
			case General, Wizard, Knight, Clown:
				if n != 3 {
					Debug("*** ERROR: Player", currentPlayer, "passed the wrong number of arguments for the played card ***")
					Out(currentPlayer)
					goto endTurn
				}

			case Soldier:
				if n != 4 {
					Debug("*** ERROR: Player", currentPlayer, "passed the wrong number of arguments for the played card ***")
					Out(currentPlayer)
					goto endTurn
				}
				if (target >= len(players)) && (target < 0) {
					Debug("*** ERROR: Player", currentPlayer, "passed a bad target argument ***")
					Out(currentPlayer)
					goto endTurn
				}
			}

			SendAll("played", currentPlayer, card)

			//check target is okay
			switch card {
			case General, Wizard, Knight, Clown, Soldier:
				if (target >= len(players)) && (target < 0) {
					Debug("*** ERROR: Player", currentPlayer, "passed a bad target argument ***")
					Out(currentPlayer)
					goto endTurn
				}
				if players[target].lost {
					Debug("*** ERROR: Player", currentPlayer, "attempted to target a player who has already lost ***")
					Out(currentPlayer)
					goto endTurn
				}
				if players[target].protected {
					Debug("*** Player", currentPlayer, "tried to target Player", target, "who was protected by a priestess ***")
					Out(currentPlayer)
					goto endTurn
				}
				if target == currentPlayer {
					Debug("*** Player", currentPlayer, "tried to target themself ***")
					var availableTargets = 0
					for _, v := range players {
						if !(v.protected || v.lost) {
							availableTargets++
						}
					}
					if availableTargets <= 1 {
						Debug("*** Player", currentPlayer, "is permitted to target themself as there are no other valid targets left ***")
					} else {
						Out(currentPlayer)
						goto endTurn
					}
				}
			}

			switch card {
			case Princess:
				Out(currentPlayer)
			case Minister:
				players[currentPlayer].ministered = true
			case General:
				players[currentPlayer].Send("swap", players[target].hand[0])
				players[target].Send("swap", players[currentPlayer].hand[0])
				players[currentPlayer].hand[0], players[target].hand[0] = players[target].hand[0], players[currentPlayer].hand[0]
				Debug("*** Player", currentPlayer, "and Player", target, "swapped hands ***")
				Debug("*** Player", currentPlayer, "hand:", players[currentPlayer].HandString(), "***")
				Debug("*** Player", target, "hand:", players[target].HandString(), "***")
			case Wizard:
				Debug("*** Player", target, "discards hand and draws a new card ***")
				SendAll("discard", target, players[target].hand[0])
				if players[target].hand[0] == Princess {
					Out(target)
					goto endTurn
				}
				if deck.IsEmpty() {
					Debug("*** Player", target, "can't draw as there are no cards left ***")
					Out(target)
					goto endTurn
				}
				players[target].hand[0] = deck.Draw()
				players[target].Send("draw", players[target].hand[0])
				Debug("*** Player", target, "hand:", players[target].HandString(), "***")
			case Priestess:
				players[currentPlayer].protected = true
			case Knight:
				Debug("*** Player", currentPlayer, "and Player", target, "compare hands ***")
				Debug("*** Player", currentPlayer, "hand:", players[currentPlayer].HandString(), "***")
				Debug("*** Player", target, "hand:", players[target].HandString(), "***")
				players[target].Send("reveal", currentPlayer, players[currentPlayer].hand[0])
				players[currentPlayer].Send("reveal", target, players[target].hand[0])
				if players[currentPlayer].HandValue() > players[target].HandValue() {
					Out(target)
				} else if players[currentPlayer].HandValue() < players[target].HandValue() {
					Out(currentPlayer)
				}
			case Clown:
				Debug("*** Player", target, "reveals a", players[target].hand[0], "from their hand to Player", currentPlayer, "***")
				players[currentPlayer].Send("reveal", target, players[target].hand[0])
			case Soldier:
				Debug("*** Player", currentPlayer, "asked Player", target, "if they have a", queryStr, "in their hand ***")
				if players[target].HasInHand(ParseCard(queryStr)) {
					Out(target)
				}
			default:
				Debug("*** ERROR: Player", currentPlayer, "played an illegal card:", cardStr, "***")
				Out(currentPlayer)
			}

		endTurn:
			currentPlayer++
			if currentPlayer >= len(players) {
				currentPlayer = 0
			}
		}
		startPlayer++
		if startPlayer >= len(players) {
			startPlayer = 0
		}

		winningHandValue := 0
		for i, _ := range players {
			if players[i].HandValue() > winningHandValue {
				winningHandValue = players[i].HandValue()
			}
		}
		for i, _ := range players {
			if players[i].HandValue() == winningHandValue {
				players[i].roundsWon++
			}
			players[i].Forfeit()
		}
		fmt.Print("Round ended.\t")
		for i, p := range players {
			fmt.Print("Player ", i, " score: ", p.roundsWon, "\t")
		}
		fmt.Println()

		if singleRound {
			//only running one round so stop now
			return
		}
	}
	_, winner := PlayerWon()
	fmt.Println("Player won:", winner, players[winner].name)
}

func SendAll(args ...interface{}) {
	for _, player := range players {
		if !player.lost {
			player.Send(args...)
		}
	}
}

func SurvivingPlayers() int {
	result := 0
	for _, player := range players {
		if !player.lost {
			result++
		}
	}
	return result
}

func PlayerWon() (bool, int) {
	for i, p := range players {
		if p.roundsWon >= 4 {
			return true, i
		}
	}
	return false, 0
}

func Out(playerNumber int) {
	players[playerNumber].Forfeit()
	SendAll("out", playerNumber, players[playerNumber].HandString())
	Debug("*** Player", playerNumber, "out:", players[playerNumber].HandString(), "***")
}

func Debug(args ...interface{}) {
	if debug {
		fmt.Println(args...)
	}
}
<|endoftext|>


<commit_before>package main // import "github.com/tutumcloud/weave-daemon"

import (
	"log"
	"os"
	"os/exec"
	"strings"
	"sync"
	"time"

	"github.com/fsouza/go-dockerclient"
	"github.com/tutumcloud/go-tutum/tutum"
	"github.com/tutumcloud/weave-daemon/nodes"
)

const version = "0.15.2"

func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

func AttachContainer(c *docker.Client, container_id string) error {
	log.Println("[CONTAINER ATTACH]: Inspecting Containers " + container_id)
	inspect, err := c.InspectContainer(container_id)

	if err != nil {
		log.Println("[CONTAINER ATTACH]: Inspecting Containers failed")
		return err
	}

	log.Println("[CONTAINER ATTACH]: Attaching container " + container_id)

	cidr := ""
	env_vars := inspect.Config.Env

	for i := range env_vars {
		if strings.HasPrefix(env_vars[i], "TUTUM_IP_ADDRESS=") {
			cidr = env_vars[i][len("TUTUM_IP_ADDRESS="):]
			break
		}
	}

	if cidr != "" {
		tries := 0
		for {

			log.Printf("%s: adding to weave with IP %s", container_id, cidr)
			cmd := exec.Command("/weave", "--local", "attach", cidr, container_id)

			_, err := cmd.StdoutPipe()
			if err != nil {
				return err
			}

			if err := cmd.Start(); err != nil {
				tries++
				time.Sleep(2 * time.Second)
				log.Println("[CONTAINER ATTACH ERROR]: Start weave cmd failed")
				if tries > 3 {
					return err
				}
			}

			if err := cmd.Wait(); err != nil {
				tries++
				time.Sleep(2 * time.Second)
				log.Println("[CONTAINER ATTACH ERROR]: Wait weave cmd failed")
				if tries > 3 {
					return err
				}
			} else {
				break
			}
		}
	} else {
		log.Printf("%s: cannot find the IP address to add to weave", container_id)
	}
	return nil
}

func ContainerAttachThread(c *docker.Client) error {

	listener := make(chan *docker.APIEvents)
	containerAttached := []string{}

	containers, err := c.ListContainers(docker.ListContainersOptions{All: false, Size: true, Limit: 0, Since: "", Before: ""})
	if err != nil {
		log.Println("[CONTAINER ATTACH THREAD ERROR]: Listing Containers failed")
		return err
	}

	for _, container := range containers {
		log.Println("[CONTAINER ATTACH THREAD]: Found running container with ID: " + container.ID)
		err := AttachContainer(c, container.ID)
		if err != nil {
			log.Println("[CONTAINER ATTACH THREAD ERROR]: Attaching Containers failed")
			return err
		}
		containerAttached = append(containerAttached, container.ID)
	}

	err = c.AddEventListener(listener)
	if err != nil {
		log.Println("[CONTAINER ATTACH THREAD ERROR]: Listening Containers Events failed")
		return err
	}

	defer func() error {

		err = c.RemoveEventListener(listener)
		if err != nil {
			return err
		}
		return nil
	}()

	for {
		timeout := time.Tick(2 * time.Minute)
		select {
		case msg := <-listener:
			if msg.Status == "die" && strings.HasPrefix(msg.From, "weaveworks/weave:") {
				os.Exit(1)
			}
			if msg.Status == "start" && !strings.HasPrefix(msg.From, "weaveworks/weave") {
				err := AttachContainer(c, msg.ID)
				if err != nil {
					log.Println("[CONTAINER ATTACH THREAD ERROR]: " + err.Error())
					break
				}
				containerAttached = append(containerAttached, msg.ID)
			}
		case <-timeout:
			containers, err := c.ListContainers(docker.ListContainersOptions{All: false, Size: true, Limit: 0, Since: "", Before: ""})
			if err != nil {
				log.Println("[CONTAINER ATTACH THREAD ERROR]: Listing Containers failed")
				return err
			}

			for _, container := range containers {
				if stringInSlice(container.ID, containerAttached) {
					break
				} else {
					log.Println("[CONTAINER ATTACH THREAD]: Found running container with ID: " + container.ID)
					err := AttachContainer(c, container.ID)
					if err != nil {
						log.Println("[CONTAINER ATTACH THREAD ERROR]: Attaching Containers failed")
						return err
					}
					containerAttached = append(containerAttached, container.ID)

					err = c.AddEventListener(listener)
					if err != nil {
						log.Println("[CONTAINER ATTACH THREAD ERROR]: Listening Containers Events failed")
						return err
					}

					defer func() error {

						err = c.RemoveEventListener(listener)
						if err != nil {
							return err
						}
						return nil
					}()

				}
				break
			}
			break
		}
	}
}

func discovering(wg *sync.WaitGroup) {
	defer wg.Done()
	c := make(chan tutum.Event)
	e := make(chan error)

	nodes.DiscoverPeers()

	go tutum.TutumEvents(c, e)
Loop:
	for {
		select {
		case event := <-c:
			if event.Type == "node" && (event.State == "Deployed" || event.State == "Terminated") {
				err := nodes.DiscoverPeers()
				if err != nil {
					log.Println(err)
				}
			}
			break
		case err := <-e:
			log.Println("[NODE DISCOVERY ERROR]: " + err.Error())
			time.Sleep(5 * time.Second)
			wg.Add(1)
			go discovering(wg)
			break Loop
		}
	}
}

func containerThread(client *docker.Client, wg *sync.WaitGroup) {
	defer wg.Done()
	for {
		err := ContainerAttachThread(client)
		if err != nil {
			log.Println(err)
			time.Sleep(15 * time.Second)
		}
	}
}

func connectToDocker() (*docker.Client, error) {
	endpoint := "unix:///var/run/docker.sock"

	client, err := docker.NewClient(endpoint)

	if err != nil {

		log.Println(err)
	}
	return client, nil
}

func main() {

	log.Println("Start running daemon")
	wg := &sync.WaitGroup{}
	wg.Add(2)
	//Init Docker client
	client, err := connectToDocker()
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
	log.Println("Starting container discovery goroutine")
	go containerThread(client, wg)

	tries := 0
Loop:
	for {
		tutum.SetUserAgent("weave-daemon/" + version)
		node, err := tutum.GetNode(nodes.Tutum_Node_Api_Uri)
		if err != nil {
			tries++
			log.Println(err)
			time.Sleep(5 * time.Second)
			if tries > 3 {
				time.Sleep(30 * time.Second)
				tries = 0
			}
			continue Loop
		} else {
			nodes.Tutum_Node_Public_Ip = node.Public_ip
			log.Printf("This node IP is %s", nodes.Tutum_Node_Public_Ip)
			if os.Getenv("TUTUM_AUTH") != "" {
				log.Println("Detected Tutum API access - starting peer discovery goroutine")
				go discovering(wg)
				break Loop
			}
		}
	}
	wg.Wait()
}
<commit_msg>Fix script + scheduled container checking<commit_after>package main // import "github.com/tutumcloud/weave-daemon"

import (
	"log"
	"os"
	"os/exec"
	"strings"
	"sync"
	"time"

	"github.com/fsouza/go-dockerclient"
	"github.com/tutumcloud/go-tutum/tutum"
	"github.com/tutumcloud/weave-daemon/nodes"
)

const version = "0.15.2"

func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

func AttachContainer(c *docker.Client, container_id string) error {
	log.Println("[CONTAINER ATTACH]: Inspecting Containers " + container_id)
	inspect, err := c.InspectContainer(container_id)

	if err != nil {
		log.Println("[CONTAINER ATTACH]: Inspecting Containers failed")
		return err
	}

	log.Println("[CONTAINER ATTACH]: Attaching container " + container_id)

	cidr := ""
	env_vars := inspect.Config.Env

	for i := range env_vars {
		if strings.HasPrefix(env_vars[i], "TUTUM_IP_ADDRESS=") {
			cidr = env_vars[i][len("TUTUM_IP_ADDRESS="):]
			break
		}
	}

	if cidr != "" {
		tries := 0
		for {

			log.Printf("%s: adding to weave with IP %s", container_id, cidr)
			cmd := exec.Command("/weave", "--local", "attach", cidr, container_id)

			_, err := cmd.StdoutPipe()
			if err != nil {
				return err
			}

			if err := cmd.Start(); err != nil {
				tries++
				time.Sleep(2 * time.Second)
				log.Println("[CONTAINER ATTACH ERROR]: Start weave cmd failed")
				if tries > 3 {
					return err
				}
			}

			if err := cmd.Wait(); err != nil {
				tries++
				time.Sleep(2 * time.Second)
				log.Println("[CONTAINER ATTACH ERROR]: Wait weave cmd failed")
				if tries > 3 {
					return err
				}
			} else {
				break
			}
		}
	} else {
		log.Printf("%s: cannot find the IP address to add to weave", container_id)
	}
	return nil
}

func ContainerAttachThread(c *docker.Client) error {

	listener := make(chan *docker.APIEvents)
	containerAttached := []string{}

	containers, err := c.ListContainers(docker.ListContainersOptions{All: false, Size: true, Limit: 0, Since: "", Before: ""})
	if err != nil {
		log.Println("[CONTAINER ATTACH THREAD ERROR]: Listing Containers failed")
		return err
	}

	for _, container := range containers {
		log.Println("[CONTAINER ATTACH THREAD]: Found running container with ID: " + container.ID)
		err := AttachContainer(c, container.ID)
		if err != nil {
			log.Println("[CONTAINER ATTACH THREAD ERROR]: Attaching Containers failed")
			return err
		}
		containerAttached = append(containerAttached, container.ID)
	}

	err = c.AddEventListener(listener)
	if err != nil {
		log.Println("[CONTAINER ATTACH THREAD ERROR]: Listening Containers Events failed")
		return err
	}

	defer func() error {

		err = c.RemoveEventListener(listener)
		if err != nil {
			return err
		}
		return nil
	}()

	for {
		timeout := time.Tick(2 * time.Minute)
		select {
		case msg := <-listener:
			if msg.Status == "die" && strings.HasPrefix(msg.From, "weaveworks/weave:") {
				os.Exit(1)
			}
			if msg.Status == "start" {
				if stringInSlice(msg.ID, containerAttached) {
					break
				} else {
					err := AttachContainer(c, msg.ID)
					if err != nil {
						log.Println("[CONTAINER ATTACH THREAD ERROR]: " + err.Error())
						break
					}
					containerAttached = append(containerAttached, msg.ID)
				}
				containerAttached = append(containerAttached, msg.ID)
			}
		case <-timeout:
			containers, err := c.ListContainers(docker.ListContainersOptions{All: false, Size: true, Limit: 0, Since: "", Before: ""})
			if err != nil {
				log.Println("[CONTAINER ATTACH THREAD ERROR]: Listing Containers failed")
				return err
			}

			for _, container := range containers {
				for _, name := range container.Names {
					if strings.HasPrefix(name, "weaveworks/weave:") && !strings.HasPrefix(container.Status, "Up") {
						os.Exit(1)
					}
				}

				if stringInSlice(container.ID, containerAttached) {
					break
				} else {
					log.Println("[CONTAINER ATTACH THREAD]: Found running container with ID: " + container.ID)
					err := AttachContainer(c, container.ID)
					if err != nil {
						log.Println("[CONTAINER ATTACH THREAD ERROR]: Attaching Containers failed")
						return err
					}
					containerAttached = append(containerAttached, container.ID)

					err = c.AddEventListener(listener)
					if err != nil {
						log.Println("[CONTAINER ATTACH THREAD ERROR]: Listening Containers Events failed")
						return err
					}

					defer func() error {

						err = c.RemoveEventListener(listener)
						if err != nil {
							return err
						}
						return nil
					}()

				}
				break
			}
			break
		}
	}
}

func discovering(wg *sync.WaitGroup) {
	defer wg.Done()
	c := make(chan tutum.Event)
	e := make(chan error)

	nodes.DiscoverPeers()

	go tutum.TutumEvents(c, e)
Loop:
	for {
		select {
		case event := <-c:
			if event.Type == "node" && (event.State == "Deployed" || event.State == "Terminated") {
				err := nodes.DiscoverPeers()
				if err != nil {
					log.Println(err)
				}
			}
			break
		case err := <-e:
			log.Println("[NODE DISCOVERY ERROR]: " + err.Error())
			time.Sleep(5 * time.Second)
			wg.Add(1)
			go discovering(wg)
			break Loop
		}
	}
}

func containerThread(client *docker.Client, wg *sync.WaitGroup) {
	defer wg.Done()
	for {
		err := ContainerAttachThread(client)
		if err != nil {
			log.Println(err)
			time.Sleep(15 * time.Second)
		}
	}
}

func connectToDocker() (*docker.Client, error) {
	endpoint := "unix:///var/run/docker.sock"

	client, err := docker.NewClient(endpoint)

	if err != nil {

		log.Println(err)
	}
	return client, nil
}

func main() {

	log.Println("Start running daemon")
	wg := &sync.WaitGroup{}
	wg.Add(2)
	//Init Docker client
	client, err := connectToDocker()
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
	log.Println("Starting container discovery goroutine")
	go containerThread(client, wg)

	tries := 0
Loop:
	for {
		tutum.SetUserAgent("weave-daemon/" + version)
		node, err := tutum.GetNode(nodes.Tutum_Node_Api_Uri)
		if err != nil {
			tries++
			log.Println(err)
			time.Sleep(5 * time.Second)
			if tries > 3 {
				time.Sleep(30 * time.Second)
				tries = 0
			}
			continue Loop
		} else {
			nodes.Tutum_Node_Public_Ip = node.Public_ip
			log.Printf("This node IP is %s", nodes.Tutum_Node_Public_Ip)
			if os.Getenv("TUTUM_AUTH") != "" {
				log.Println("Detected Tutum API access - starting peer discovery goroutine")
				go discovering(wg)
				break Loop
			}
		}
	}
	wg.Wait()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"time"

	"github.com/confluentinc/confluent-kafka-go/kafka"
	log "github.com/sirupsen/logrus"
)

const CONCURRENT_FUNC = 5000

func main() {
	if err := rootCmd.Execute(); err != nil {
		log.Fatal(err)
	}
}

func run() {
	app, err := NewApplication()
	if err != nil {
		log.Fatal(err)
	}

	// create a producer
	producer, err := kafka.NewProducer(&kafka.ConfigMap{"bootstrap.servers": strings.Join(app.Brokers(), ",")})
	if err != nil {
		app.Log.Fatal("Unable to create producer:", err)
	}

	// generic logging for producer
	go func() {
		for e := range producer.Events() {
			switch ev := e.(type) {
			case *kafka.Message:
				m := ev
				if m.TopicPartition.Error != nil {
					app.Log.Fatal("delivery failed", m.TopicPartition.Error)
				} else {
					app.Log.Debugf("Delivered message to topic %s [%d] at offset %v",
						*m.TopicPartition.Topic, m.TopicPartition.Partition, m.TopicPartition.Offset)
				}
				return
			default:
				app.Log.Debugf("Ignored event: %s", ev)
			}
		}
	}()

	// create a proxy to let functions write data back to kafka
	writeProxy, err := NewWriteProxy(app, producer.ProduceChannel())
	if err != nil {
		app.Log.Fatal(err)
	}
	go http.ListenAndServe(app.GetString("write_proxy_listen"), writeProxy)
	app.Log.Infof("Write Proxy Started: %s", app.GetString("write_proxy_listen"))

	consumer, err := kafka.NewConsumer(&kafka.ConfigMap{
		"bootstrap.servers":               strings.Join(app.Brokers(), ","),
		"group.id":                        app.ConsumerGroupID(),
		"session.timeout.ms":              6000,
		"go.application.rebalance.enable": true,
		"default.topic.config":            kafka.ConfigMap{"auto.offset.reset": "earliest"},
		"metadata.max.age.ms":             1000,
		"enable.auto.commit":              false,
	})
	if err != nil {
		app.Log.Fatal("Failed to create consumer", err)
	}

	// TODO: lock this or use goroutine
	lastProcessedMessages := make(map[string]*kafka.Message)
	defer func() {
		for _, msg := range lastProcessedMessages {
			_, err := consumer.CommitMessage(msg)
			if err != nil {
				app.Log.Fatal(err)
			}
		}
		consumer.Close()
	}()

	err = consumer.SubscribeTopics([]string{app.Subscription()}, nil)
	if err != nil {
		app.Log.Fatal("Failed to subscribe topics %v, %s", app.Subscription(), err)
	}
	app.Log.Infof("Consumer Started")

	// close consumers when user press ctrl+c
	run := true
	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt)
	go func() {
		for _ = range c {
			fmt.Println("Exiting...")
			run = false
		}
	}()

	// periodically refresh metadata to know if there's any new topic created
	go refreshMetadata(consumer, app.Log)

	runFunc := make(chan *kafka.Message, CONCURRENT_FUNC)

	// start the consumer loop
	for run {
		ev := consumer.Poll(100)
		if ev == nil {
			continue
		}
		switch e := ev.(type) {
		case kafka.AssignedPartitions:
			app.Log.Info(e)
			consumer.Assign(e.Partitions)
		case kafka.RevokedPartitions:
			app.Log.Info(e)
			consumer.Unassign()
		case *kafka.Message:
			app.Log.Infof("Message Received %s", e.TopicPartition)

			parts := strings.Split(*e.TopicPartition.Topic, "_")
			object := parts[1]

			routePath := GetRouteEvent(object, "UPDATE")
			app.Log.Debugf("Looking up route %s", routePath)

			if _, ok := app.Routes[routePath]; !ok {
				app.Log.Debugf("Route not found")
				lastProcessedMessages[*e.TopicPartition.Topic] = e
				continue
			}

			// block when exceed CONCURRENT_FUNC
			runFunc <- e

			go func() {
				msg := <-runFunc
				parts := strings.Split(*msg.TopicPartition.Topic, "_")
				object := parts[1]

				routePath := GetRouteEvent(object, "UPDATE")

				err := app.Invoke(app.Routes[routePath], []byte(string(msg.Value)))

				if err != nil {
					app.Log.WithField("route", app.Routes[routePath]).Errorf("Invocation Error: %v", err)
					return
				}
				_, err = consumer.CommitMessage(msg)
				if err != nil {
					app.Log.Errorf("Commit Error: %v %v", msg, err)
					return
				}
				lastProcessedMessages[*e.TopicPartition.Topic] = e
			}()
		case kafka.PartitionEOF:
			app.Log.Debugf("Reached %v", e)
		case kafka.Error:
			app.Log.Fatalf("Consumer Error %s", e)
		default:
			app.Log.Debugf("Unknown Message %v", e)
		}
	}
}

type WriteProxy struct {
	produceChan chan *kafka.Message
	app         *Application
}

func NewWriteProxy(app *Application, produceChan chan *kafka.Message) (*WriteProxy, error) {
	proxy := WriteProxy{produceChan, app}
	return &proxy, nil
}

func (p WriteProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		p.app.Log.Error("read body failed", err)
		w.WriteHeader(400)
		return
	}
	var write WriteRequest
	err = json.Unmarshal(body, &write)
	if err != nil {
		p.app.Log.Errorf("decode body failed %v", err)
		w.WriteHeader(400)
		return
	}
	topic := fmt.Sprintf("%s_%s", p.app.GetString("app_name"), write.Topic)
	for key, value := range write.Data {
		p.produceChan <- &kafka.Message{
			TopicPartition: kafka.TopicPartition{Topic: &topic, Partition: kafka.PartitionAny},
			Key:            []byte(key),
			Value:          value,
		}
	}
	fmt.Fprintf(w, "ok")
}

type WriteRequest struct {
	Topic string                     `json:"topic"`
	Data  map[string]json.RawMessage `json:"data"`
}

func refreshMetadata(consumer *kafka.Consumer, logger *log.Entry) {
	for {
		time.Sleep(5 * time.Second)
		metadata, err := consumer.GetMetadata(nil, true, 100)
		if err != nil {
			// somethimes it just timed out, ignore
			logger.Warn("Unable to refresh metadata: ", err)
			continue
		}
		keys := []string{}
		for k := range metadata.Topics {
			keys = append(keys, k)
		}
		// logger.Info("metadata: ", keys)
	}
}
<commit_msg>use autocommit<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"time"

	"github.com/confluentinc/confluent-kafka-go/kafka"
	log "github.com/sirupsen/logrus"
)

const CONCURRENT_FUNC = 5000

func main() {
	if err := rootCmd.Execute(); err != nil {
		log.Fatal(err)
	}
}

func run() {
	app, err := NewApplication()
	if err != nil {
		log.Fatal(err)
	}

	// create a producer
	producer, err := kafka.NewProducer(&kafka.ConfigMap{"bootstrap.servers": strings.Join(app.Brokers(), ",")})
	if err != nil {
		app.Log.Fatal("Unable to create producer:", err)
	}

	// generic logging for producer
	go func() {
		for e := range producer.Events() {
			switch ev := e.(type) {
			case *kafka.Message:
				m := ev
				if m.TopicPartition.Error != nil {
					app.Log.Fatal("delivery failed", m.TopicPartition.Error)
				} else {
					app.Log.Debugf("Delivered message to topic %s [%d] at offset %v",
						*m.TopicPartition.Topic, m.TopicPartition.Partition, m.TopicPartition.Offset)
				}
			default:
				app.Log.Debugf("Ignored event: %s", ev)
			}
		}
	}()

	// create a proxy to let functions write data back to kafka
	writeProxy, err := NewWriteProxy(app, producer.ProduceChannel())
	if err != nil {
		app.Log.Fatal(err)
	}
	go http.ListenAndServe(app.GetString("write_proxy_listen"), writeProxy)
	app.Log.Infof("Write Proxy Started: %s", app.GetString("write_proxy_listen"))

	consumer, err := kafka.NewConsumer(&kafka.ConfigMap{
		"bootstrap.servers":               strings.Join(app.Brokers(), ","),
		"group.id":                        app.ConsumerGroupID(),
		"session.timeout.ms":              6000,
		"go.application.rebalance.enable": true,
		"default.topic.config":            kafka.ConfigMap{"auto.offset.reset": "earliest"},
		"metadata.max.age.ms":             1000,
	})
	if err != nil {
		app.Log.Fatal("Failed to create consumer", err)
	}

	defer consumer.Close()

	err = consumer.SubscribeTopics([]string{app.Subscription()}, nil)
	if err != nil {
		app.Log.Fatal("Failed to subscribe topics %v, %s", app.Subscription(), err)
	}
	app.Log.Infof("Consumer Started")

	// close consumers when user press ctrl+c
	run := true
	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt)
	go func() {
		for _ = range c {
			fmt.Println("Exiting...")
			run = false
		}
	}()

	// periodically refresh metadata to know if there's any new topic created
	go refreshMetadata(consumer, app.Log)

	runFunc := make(chan *kafka.Message, CONCURRENT_FUNC)

	// start the consumer loop
	for run {
		ev := consumer.Poll(100)
		if ev == nil {
			continue
		}
		switch e := ev.(type) {
		case kafka.AssignedPartitions:
			app.Log.Info(e)
			consumer.Assign(e.Partitions)
		case kafka.RevokedPartitions:
			app.Log.Info(e)
			consumer.Unassign()
		case *kafka.Message:
			app.Log.Infof("Message Received %s", e.TopicPartition)

			parts := strings.Split(*e.TopicPartition.Topic, "_")
			object := parts[1]

			routePath := GetRouteEvent(object, "UPDATE")
			app.Log.Debugf("Looking up route %s", routePath)

			if _, ok := app.Routes[routePath]; !ok {
				app.Log.Debugf("Route not found")
				continue
			}

			// block when exceed CONCURRENT_FUNC
			runFunc <- e

			go func() {
				msg := <-runFunc
				parts := strings.Split(*msg.TopicPartition.Topic, "_")
				object := parts[1]

				routePath := GetRouteEvent(object, "UPDATE")

				// TODO: support multiple func per routePath here
				err := app.Invoke(app.Routes[routePath], []byte(string(msg.Value)))

				if err != nil {
					app.Log.WithField("route", app.Routes[routePath]).Errorf("Invocation Error: %v", err)
					return
				}
			}()
		case kafka.PartitionEOF:
			app.Log.Debugf("Reached %v", e)
		case kafka.Error:
			app.Log.Fatalf("Consumer Error %s", e)
		default:
			app.Log.Debugf("Unknown Message %v", e)
		}
	}
}

type WriteProxy struct {
	produceChan chan *kafka.Message
	app         *Application
}

func NewWriteProxy(app *Application, produceChan chan *kafka.Message) (*WriteProxy, error) {
	proxy := WriteProxy{produceChan, app}
	return &proxy, nil
}

func (p WriteProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		p.app.Log.Error("read body failed", err)
		w.WriteHeader(400)
		return
	}
	var write WriteRequest
	err = json.Unmarshal(body, &write)
	if err != nil {
		p.app.Log.Errorf("decode body failed %v", err)
		w.WriteHeader(400)
		return
	}
	topic := fmt.Sprintf("%s_%s", p.app.GetString("app_name"), write.Topic)
	for key, value := range write.Data {
		p.produceChan <- &kafka.Message{
			TopicPartition: kafka.TopicPartition{Topic: &topic, Partition: kafka.PartitionAny},
			Key:            []byte(key),
			Value:          value,
		}
	}
	fmt.Fprintf(w, "ok")
}

type WriteRequest struct {
	Topic string                     `json:"topic"`
	Data  map[string]json.RawMessage `json:"data"`
}

func refreshMetadata(consumer *kafka.Consumer, logger *log.Entry) {
	for {
		time.Sleep(5 * time.Second)
		metadata, err := consumer.GetMetadata(nil, true, 100)
		if err != nil {
			// somethimes it just timed out, ignore
			logger.Warn("Unable to refresh metadata: ", err)
			continue
		}
		keys := []string{}
		for k := range metadata.Topics {
			keys = append(keys, k)
		}
		// logger.Info("metadata: ", keys)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/whereswaldon/ggg/genetic"
	//"math"
	"os"
)

func main() {
	//Process the source image
	args := os.Args
	if len(args) > 1 {
		imageName := os.Args[1]
		err := genetic.SetTarget(imageName)
		if err != nil {
			fmt.Println(err)
		}
		err = genetic.WriteMonochromePNG("red.png", genetic.Target, genetic.RED)
		if err != nil {
			fmt.Println(err)
		}
	}

	/*
		g := &genetic.Gene{250, 250, 10,
			func(a, b, c, x, y int) int {
				return int(math.Sqrt(float64((a-x)*(a-x)+(b-y)*(b-y)))) + c*c
			},
			"%d*x - %d*y + %d"}
		m := genetic.NewMember()
		m.Genes = make([]*genetic.Gene, 1)
		m.Genes[0] = g
		fmt.Println(m)
		genetic.WriteMonochromePNG("out.png", m.GetData(), genetic.RED)
	*/
	//test out new population
	p := genetic.NewPopulation(200, 0.15)
	//fmt.Println(p.GetBestForPrinting(1))
	bestScore := 0
	runs := 100
	for i := 0; i < runs; i++ {
		p.Evolve()
		tempScore := p.Members[0].GetFitness()
		if tempScore > bestScore {
			fmt.Println(p.GetBestForPrinting(1))
			bestScore = tempScore
			genetic.WriteMonochromePNG(fmt.Sprintf("solution-%d.png", i), p.Members[0].GetData(), genetic.RED)
		} else {
			fmt.Printf("%d/%d:\t%d <= %d\n", i, runs, tempScore, bestScore)
		}
	}
}
<commit_msg>Make Fitness function simple.<commit_after>package main

import (
	"fmt"
	"github.com/whereswaldon/ggg/genetic"
	//"math"
	"os"
)

func main() {
	//Process the source image
	args := os.Args
	if len(args) > 1 {
		imageName := os.Args[1]
		err := genetic.SetTarget(imageName)
		if err != nil {
			fmt.Println(err)
		}
		err = genetic.WriteMonochromePNG("red.png", genetic.Target, genetic.RED)
		if err != nil {
			fmt.Println(err)
		}
	}

	g := &genetic.Gene{250, 250, 10,
		func(a, b, c, x, y int) int {
			return (x / a) * (y / b) * c
		},
		"%d*x - %d*y + %d"}
	m := genetic.NewMember()
	m.Genes = make([]*genetic.Gene, 1)
	m.Genes[0] = g
	fmt.Println(m)
	genetic.WriteMonochromePNG("out.png", m.GetData(), genetic.RED)

	/*
		//test out new population
		p := genetic.NewPopulation(200, 0.15)
		//fmt.Println(p.GetBestForPrinting(1))
		bestScore := 0
		runs := 100
		for i := 0; i < runs; i++ {
			p.Evolve()
			tempScore := p.Members[0].GetFitness()
			if tempScore > bestScore {
				fmt.Println(p.GetBestForPrinting(1))
				bestScore = tempScore
				genetic.WriteMonochromePNG(fmt.Sprintf("solution-%d.png", i), p.Members[0].GetData(), genetic.RED)
			} else {
				fmt.Printf("%d/%d:\t%d <= %d\n", i, runs, tempScore, bestScore)
			}
		}
	*/
}
<|endoftext|>