<commit_before>package middleware

import (
	"github.com/gin-gonic/gin"
	"strings"
	"time"

	u "github.com/techjanitor/pram-get/utils"
)

// requesttype holds the data we want to capture
type RequestType struct {
	Ib        string
	Ip        string
	User      uint
	Path      string
	ItemKey   string
	ItemValue string
	Status    int
	Latency   time.Duration
	Cached    bool
}

// Analytics will log requests in the database
func Analytics() gin.HandlerFunc {
	return func(c *gin.Context) {
		req := c.Request
		// Start timer
		start := time.Now()
		// get request path
		path := req.URL.Path

		// Process request
		c.Next()

		// get userdata from session middleware
		userdata := c.MustGet("userdata").(u.User)

		// get cached state from cache middleware
		cached := c.MustGet("cached").(bool)

		// Trim leading / from path and split
		params := strings.Split(strings.Trim(path, "/"), "/")

		// Make key from path
		key := itemKey{}
		key.generateKey(params...)

		// get the ib
		ib := c.Param("ib")

		// Stop timer
		end := time.Now()
		// get request latency
		latency := end.Sub(start)

		// set our data
		request := RequestType{
			Ib:        ib,
			Ip:        c.ClientIP(),
			User:      userdata.Id,
			Path:      path,
			Status:    c.Writer.Status(),
			Latency:   latency,
			ItemKey:   key.Key,
			ItemValue: key.Value,
			Cached:    cached,
		}

		// Get Database handle
		db, err := u.GetDb()
		if err != nil {
			c.Error(err)
			c.Abort()
			return
		}

		// prepare query for analytics table
		ps1, err := db.Prepare("INSERT INTO analytics (ib_id, user_id, request_ip, request_path, request_status, request_latency, request_itemkey, request_itemvalue, request_cached, request_time) VALUES (?,?,?,?,?,?,?,?,?,NOW())")
		if err != nil {
			c.Error(err)
			c.Abort()
			return
		}

		// input data
		_, err = ps1.Exec(request.Ib, request.User, request.Ip, request.Path, request.Status, request.Latency, request.ItemKey, request.ItemValue, request.Cached)
		if err != nil {
			c.Error(err)
			c.Abort()
			return
		}

	}
}

type itemKey struct {
	Key   string
	Value string
}

// Will take the params from the request and turn them into a key
func (r *itemKey) generateKey(params ...string) {

	switch {
	case len(params) <= 2:
		r.Key = params[0]
		r.Value = "1"
	case len(params) >= 3:
		r.Key = params[0]
		r.Value = params[2]
	}

	return

}
<commit_msg>add skip key to analytics<commit_after>package middleware

import (
	"github.com/gin-gonic/gin"
	"strings"
	"time"

	u "github.com/techjanitor/pram-get/utils"
)

// requesttype holds the data we want to capture
type RequestType struct {
	Ib        string
	Ip        string
	User      uint
	Path      string
	ItemKey   string
	ItemValue string
	Status    int
	Latency   time.Duration
	Cached    bool
}

// Analytics will log requests in the database
func Analytics() gin.HandlerFunc {
	return func(c *gin.Context) {
		req := c.Request
		// Start timer
		start := time.Now()
		// get request path
		path := req.URL.Path

		// Process request
		c.Next()

		// Stop timer
		end := time.Now()
		// get request latency
		latency := end.Sub(start)

		// get userdata from session middleware
		userdata := c.MustGet("userdata").(u.User)

		// get cached state from cache middleware
		cached := c.MustGet("cached").(bool)

		// get the ib
		ib := c.Param("ib")

		// Trim leading / from path and split
		params := strings.Split(strings.Trim(path, "/"), "/")

		// Make key from path
		key := itemKey{}
		key.generateKey(params...)

		if !skipKey(params[0]) {

			// set our data
			request := RequestType{
				Ib:        ib,
				Ip:        c.ClientIP(),
				User:      userdata.Id,
				Path:      path,
				Status:    c.Writer.Status(),
				Latency:   latency,
				ItemKey:   key.Key,
				ItemValue: key.Value,
				Cached:    cached,
			}

			// Get Database handle
			db, err := u.GetDb()
			if err != nil {
				c.Error(err)
				c.Abort()
				return
			}

			// prepare query for analytics table
			ps1, err := db.Prepare("INSERT INTO analytics (ib_id, user_id, request_ip, request_path, request_status, request_latency, request_itemkey, request_itemvalue, request_cached, request_time) VALUES (?,?,?,?,?,?,?,?,?,NOW())")
			if err != nil {
				c.Error(err)
				c.Abort()
				return
			}

			// input data
			_, err = ps1.Exec(request.Ib, request.User, request.Ip, request.Path, request.Status, request.Latency, request.ItemKey, request.ItemValue, request.Cached)
			if err != nil {
				c.Error(err)
				c.Abort()
				return
			}

		}

	}
}

type itemKey struct {
	Key   string
	Value string
}

// Will take the params from the request and turn them into a key
func (r *itemKey) generateKey(params ...string) {

	switch {
	case len(params) <= 2:
		r.Key = params[0]
		r.Value = "1"
	case len(params) >= 3:
		r.Key = params[0]
		r.Value = params[2]
	}

	return

}

// Check if key should be expired
func skipKey(key string) bool {

	keyList := map[string]bool{
		"taginfo": true,
		"tags":    true,
	}

	if keyList[strings.ToLower(key)] {
		return true
	}

	return false

}
<|endoftext|>


<commit_before>// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package runtime

import "context"

// ClientOperation represents the context for a swagger operation to be submitted to the transport
type ClientOperation struct {
	ID                 string
	Method             string
	PathPattern        string
	ProducesMediaTypes []string
	ConsumesMediaTypes []string
	Schemes            []string
	AuthInfo           ClientAuthInfoWriter
	Params             ClientRequestWriter
	Reader             ClientResponseReader
	Context            context.Context
}

// A ClientTransport implementor knows how to submit Request objects to some destination
type ClientTransport interface {
	//Submit(string, RequestWriter, ResponseReader, AuthInfoWriter) (interface{}, error)
	Submit(*ClientOperation) (interface{}, error)
}
<commit_msg>use golang.org/x/net/context instead of context<commit_after>// Copyright 2015 go-swagger maintainers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package runtime

import "golang.org/x/net/context"

// ClientOperation represents the context for a swagger operation to be submitted to the transport
type ClientOperation struct {
	ID                 string
	Method             string
	PathPattern        string
	ProducesMediaTypes []string
	ConsumesMediaTypes []string
	Schemes            []string
	AuthInfo           ClientAuthInfoWriter
	Params             ClientRequestWriter
	Reader             ClientResponseReader
	Context            context.Context
}

// A ClientTransport implementor knows how to submit Request objects to some destination
type ClientTransport interface {
	//Submit(string, RequestWriter, ResponseReader, AuthInfoWriter) (interface{}, error)
	Submit(*ClientOperation) (interface{}, error)
}
<|endoftext|>


<commit_before>package cluster

import (
	"sync"

	log "github.com/Sirupsen/logrus"
)

// Watchdog listens to cluster events and handles container rescheduling
type Watchdog struct {
	sync.Mutex
	cluster Cluster
}

// Handle handles cluster callbacks
func (w *Watchdog) Handle(e *Event) error {
	// Skip non-swarm events.
	if e.From != "swarm" {
		return nil
	}

	switch e.Status {
	case "engine_reconnect":
		go w.removeDuplicateContainers(e.Engine)
	case "engine_disconnect":
		go w.rescheduleContainers(e.Engine)
	}
	return nil
}

// removeDuplicateContainers removes duplicate containers when a node comes back
func (w *Watchdog) removeDuplicateContainers(e *Engine) {
	log.Debugf("removing duplicate containers from Node %s", e.ID)

	e.RefreshContainers(false)

	w.Lock()
	defer w.Unlock()

	for _, container := range e.Containers() {
		// skip non-swarm containers
		if container.Config.SwarmID() == "" {
			continue
		}

		for _, containerInCluster := range w.cluster.Containers() {
			if containerInCluster.Config.SwarmID() == container.Config.SwarmID() && containerInCluster.Engine.ID != container.Engine.ID {
				log.Debugf("container %s was rescheduled on node %s, removing it", container.Id, containerInCluster.Engine.ID)
				// container already exists in the cluster, destroy it
				e.RemoveContainer(container, true, true)
			}
		}
	}
}

// rescheduleContainers reschedules containers as soon as a node fails
func (w *Watchdog) rescheduleContainers(e *Engine) {
	w.Lock()
	defer w.Unlock()

	log.Debugf("Node %s failed - rescheduling containers", e.ID)
	for _, c := range e.Containers() {

		// Skip containers which don't have an "on-node-failure" reschedule policy.
		if !c.Config.HasReschedulePolicy("on-node-failure") {
			log.Debugf("Skipping rescheduling of %s based on rescheduling policies", c.Id)
			continue
		}

		// Remove the container from the dead engine. If we don't, then both
		// the old and new one will show up in docker ps.
		// We have to do this before calling `CreateContainer`, otherwise it
		// will abort because the name is already taken.
		c.Engine.removeContainer(c)

		newContainer, err := w.cluster.CreateContainer(c.Config, c.Info.Name, nil)

		if err != nil {
			log.Errorf("Failed to reschedule container %s: %v", c.Id, err)
			// add the container back, so we can retry later
			c.Engine.AddContainer(c)
		} else {
			log.Infof("Rescheduled container %s from %s to %s as %s", c.Id, c.Engine.Name, newContainer.Engine.Name, newContainer.Id)
			if c.Info.State.Running {
				log.Infof("Container %s was running, starting container %s", c.Id, newContainer.Id)
				if err := w.cluster.StartContainer(newContainer, nil); err != nil {
					log.Errorf("Failed to start rescheduled container %s: %v", newContainer.Id, err)
				}
			}
		}
	}

}

// NewWatchdog creates a new watchdog
func NewWatchdog(cluster Cluster) *Watchdog {
	log.Debugf("Watchdog enabled")
	w := &Watchdog{
		cluster: cluster,
	}
	cluster.RegisterEventHandler(w)
	return w
}
<commit_msg>log err when remove container fails in rescheduling<commit_after>package cluster

import (
	"sync"

	log "github.com/Sirupsen/logrus"
)

// Watchdog listens to cluster events and handles container rescheduling
type Watchdog struct {
	sync.Mutex
	cluster Cluster
}

// Handle handles cluster callbacks
func (w *Watchdog) Handle(e *Event) error {
	// Skip non-swarm events.
	if e.From != "swarm" {
		return nil
	}

	switch e.Status {
	case "engine_reconnect":
		go w.removeDuplicateContainers(e.Engine)
	case "engine_disconnect":
		go w.rescheduleContainers(e.Engine)
	}
	return nil
}

// removeDuplicateContainers removes duplicate containers when a node comes back
func (w *Watchdog) removeDuplicateContainers(e *Engine) {
	log.Debugf("removing duplicate containers from Node %s", e.ID)

	e.RefreshContainers(false)

	w.Lock()
	defer w.Unlock()

	for _, container := range e.Containers() {
		// skip non-swarm containers
		if container.Config.SwarmID() == "" {
			continue
		}

		for _, containerInCluster := range w.cluster.Containers() {
			if containerInCluster.Config.SwarmID() == container.Config.SwarmID() && containerInCluster.Engine.ID != container.Engine.ID {
				log.Debugf("container %s was rescheduled on node %s, removing it", container.Id, containerInCluster.Engine.Name)
				// container already exists in the cluster, destroy it
				if err := e.RemoveContainer(container, true, true); err != nil {
					log.Errorf("Failed to remove duplicate container %s on node %s: %v", container.Id, containerInCluster.Engine.Name, err)
				}
			}
		}
	}
}

// rescheduleContainers reschedules containers as soon as a node fails
func (w *Watchdog) rescheduleContainers(e *Engine) {
	w.Lock()
	defer w.Unlock()

	log.Debugf("Node %s failed - rescheduling containers", e.ID)
	for _, c := range e.Containers() {

		// Skip containers which don't have an "on-node-failure" reschedule policy.
		if !c.Config.HasReschedulePolicy("on-node-failure") {
			log.Debugf("Skipping rescheduling of %s based on rescheduling policies", c.Id)
			continue
		}

		// Remove the container from the dead engine. If we don't, then both
		// the old and new one will show up in docker ps.
		// We have to do this before calling `CreateContainer`, otherwise it
		// will abort because the name is already taken.
		c.Engine.removeContainer(c)

		newContainer, err := w.cluster.CreateContainer(c.Config, c.Info.Name, nil)

		if err != nil {
			log.Errorf("Failed to reschedule container %s: %v", c.Id, err)
			// add the container back, so we can retry later
			c.Engine.AddContainer(c)
		} else {
			log.Infof("Rescheduled container %s from %s to %s as %s", c.Id, c.Engine.Name, newContainer.Engine.Name, newContainer.Id)
			if c.Info.State.Running {
				log.Infof("Container %s was running, starting container %s", c.Id, newContainer.Id)
				if err := w.cluster.StartContainer(newContainer, nil); err != nil {
					log.Errorf("Failed to start rescheduled container %s: %v", newContainer.Id, err)
				}
			}
		}
	}

}

// NewWatchdog creates a new watchdog
func NewWatchdog(cluster Cluster) *Watchdog {
	log.Debugf("Watchdog enabled")
	w := &Watchdog{
		cluster: cluster,
	}
	cluster.RegisterEventHandler(w)
	return w
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"talisman/checksumcalculator"
	"talisman/gitrepo"
	"talisman/utility"
)

type ChecksumCmd struct {
	fileNamePatterns []string
}

func NewChecksumCmd(fileNamePatterns []string) *ChecksumCmd {
	return &ChecksumCmd{fileNamePatterns: fileNamePatterns}
}

func (s *ChecksumCmd) Run() int {
	exitStatus := 1
	wd, _ := os.Getwd()
	repo := gitrepo.RepoLocatedAt(wd)
	gitTrackedFilesAsAdditions := repo.TrackedFilesAsAdditions()
	gitTrackedFilesAsAdditions = append(gitTrackedFilesAsAdditions, repo.StagedAdditions()...)
	cc := checksumcalculator.NewChecksumCalculator(utility.DefaultSHA256Hasher{}, gitTrackedFilesAsAdditions)
	rcSuggestion := cc.SuggestTalismanRC(s.fileNamePatterns)
	if rcSuggestion != "" {
		fmt.Print(rcSuggestion)
		exitStatus = 0
	}
	return exitStatus
}
<commit_msg>Address code review comments<commit_after>package main

import (
	"fmt"
	"os"
	"talisman/checksumcalculator"
	"talisman/gitrepo"
	"talisman/utility"
)

type ChecksumCmd struct {
	fileNamePatterns []string
}

func NewChecksumCmd(fileNamePatterns []string) *ChecksumCmd {
	return &ChecksumCmd{fileNamePatterns: fileNamePatterns}
}

func (s *ChecksumCmd) Run() int {
	wd, _ := os.Getwd()
	repo := gitrepo.RepoLocatedAt(wd)
	gitTrackedFilesAsAdditions := repo.TrackedFilesAsAdditions()
	gitTrackedFilesAsAdditions = append(gitTrackedFilesAsAdditions, repo.StagedAdditions()...)
	cc := checksumcalculator.NewChecksumCalculator(utility.DefaultSHA256Hasher{}, gitTrackedFilesAsAdditions)
	rcSuggestion := cc.SuggestTalismanRC(s.fileNamePatterns)
	if rcSuggestion != "" {
		fmt.Print(rcSuggestion)
		return 0
	}
	return 1
}
<|endoftext|>


<commit_before>/* Copyright 2016 The Bazel Authors. All rights reserved.

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

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

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

package main

import (
	"io/ioutil"
	"os"
	"os/exec"

	bf "github.com/bazelbuild/buildtools/build"
	"github.com/bazelbuild/bazel-gazelle/config"
)

func diffFile(c *config.Config, file *bf.File) error {
	f, err := ioutil.TempFile("", c.DefaultBuildFileName())
	if err != nil {
		return err
	}
	defer os.Remove(f.Name())
	defer f.Close()
	if _, err := f.Write(bf.Format(file)); err != nil {
		return err
	}
	if err := f.Sync(); err != nil {
		return err
	}

	cmd := exec.Command("diff", "-u", "--new-file", file.Path, f.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if _, ok := err.(*exec.ExitError); ok {
		// diff returns non-zero when files are different. This is not an error.
		return nil
	}
	return err
}
<commit_msg>Improve performance of gazelle --mode=diff (#40)<commit_after>/* Copyright 2016 The Bazel Authors. All rights reserved.

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

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

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

package main

import (
	"bytes"
	"io/ioutil"
	"os"
	"os/exec"

	"github.com/bazelbuild/bazel-gazelle/config"
	bf "github.com/bazelbuild/buildtools/build"
)

func diffFile(c *config.Config, file *bf.File) error {
	oldContents, err := ioutil.ReadFile(file.Path)
	if err != nil {
		oldContents = nil
	}
	newContents := bf.Format(file)
	if bytes.Equal(oldContents, newContents) {
		return nil
	}
	f, err := ioutil.TempFile("", c.DefaultBuildFileName())
	if err != nil {
		return err
	}
	f.Close()
	defer os.Remove(f.Name())
	if err := ioutil.WriteFile(f.Name(), newContents, 0666); err != nil {
		return err
	}
	cmd := exec.Command("diff", "-u", "--new-file", file.Path, f.Name())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if _, ok := err.(*exec.ExitError); ok {
		// diff returns non-zero when files are different. This is not an error.
		return nil
	}
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/influxdata/platform"
	"github.com/influxdata/platform/http"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var writeCmd = &cobra.Command{
	Use:   "write [line protocol or @/path/to/points.txt",
	Short: "Write points to influxdb",
	Long: `Write a single line of line protocol to influx db,
		or add an entire file specified with an @ prefix`,
	Args: cobra.ExactArgs(1),
	Run:  fluxWriteF,
}

var writeFlags struct {
	OrgID    string
	Org      string
	BucketID string
	Bucket   string
}

func init() {
	writeCmd.PersistentFlags().StringVar(&writeFlags.OrgID, "org-id", "", "id of the organization that owns the bucket")
	viper.BindEnv("ORG_ID")
	if h := viper.GetString("ORG_ID"); h != "" {
		writeFlags.OrgID = h
	}

	writeCmd.PersistentFlags().StringVarP(&writeFlags.Org, "org", "o", "", "name of the organization that owns the bucket")
	viper.BindEnv("ORG")
	if h := viper.GetString("ORG"); h != "" {
		writeFlags.Org = h
	}

	writeCmd.PersistentFlags().StringVar(&writeFlags.BucketID, "bucket-id", "", "ID of destination bucket")
	viper.BindEnv("BUCKET_ID")
	if h := viper.GetString("BUCKET_ID"); h != "" {
		writeFlags.BucketID = h
	}

	writeCmd.PersistentFlags().StringVarP(&writeFlags.Org, "bucket", "b", "", "name of destination bucket")
	viper.BindEnv("BUCKET_NAME")
	if h := viper.GetString("BUCKET_NAM"); h != "" {
		writeFlags.Bucket = h
	}
}

func fluxWriteF(cmd *cobra.Command, args []string) {
	ctx := context.TODO()

	if writeFlags.Org != "" && writeFlags.OrgID != "" {
		fmt.Println("must specify exactly one of org or org-id")
		cmd.Usage()
		os.Exit(1)
	}

	if writeFlags.Bucket != "" && writeFlags.BucketID != "" {
		fmt.Println("must specify exactly one of org or org-id")
		cmd.Usage()
		os.Exit(1)
	}

	bs := &http.BucketService{
		Addr:  flags.host,
		Token: flags.token,
	}

	filter := platform.BucketFilter{}
	if writeFlags.Bucket != "" {
		filter.Name = &writeFlags.Bucket
	}
	if writeFlags.BucketID != "" {
		filter.ID = &platform.ID{}
		err := filter.ID.DecodeFromString(writeFlags.BucketID)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	}

	if writeFlags.OrgID != "" {
		filter.OrganizationID = &platform.ID{}
		err := filter.OrganizationID.DecodeFromString(bucketFindFlags.orgID)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	}
	if writeFlags.Org != "" {
		filter.Organization = &writeFlags.Org
	}

	buckets, _, err := bs.FindBuckets(ctx, filter)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	bucketID, orgID := buckets[0].ID, buckets[0].OrganizationID

	var r io.Reader
	if args[0] == "-" {
		r = os.Stdin
	} else if len(args[0]) > 0 && args[0][0] == '@' {
		f, err := os.Open(args[0][1:])
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		defer f.Close()
		r = f
	} else {
		r = strings.NewReader(args[0])
	}

	s := &http.WriteService{
		Addr:  flags.host,
		Token: flags.token,
	}

	if err = s.Write(ctx, orgID, bucketID, r); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
<commit_msg>fix(cmd/influx): update write to new platform ID<commit_after>package main

import (
	"context"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/influxdata/platform"
	"github.com/influxdata/platform/http"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var writeCmd = &cobra.Command{
	Use:   "write [line protocol or @/path/to/points.txt",
	Short: "Write points to influxdb",
	Long: `Write a single line of line protocol to influx db,
		or add an entire file specified with an @ prefix`,
	Args: cobra.ExactArgs(1),
	Run:  fluxWriteF,
}

var writeFlags struct {
	OrgID    string
	Org      string
	BucketID string
	Bucket   string
}

func init() {
	writeCmd.PersistentFlags().StringVar(&writeFlags.OrgID, "org-id", "", "id of the organization that owns the bucket")
	viper.BindEnv("ORG_ID")
	if h := viper.GetString("ORG_ID"); h != "" {
		writeFlags.OrgID = h
	}

	writeCmd.PersistentFlags().StringVarP(&writeFlags.Org, "org", "o", "", "name of the organization that owns the bucket")
	viper.BindEnv("ORG")
	if h := viper.GetString("ORG"); h != "" {
		writeFlags.Org = h
	}

	writeCmd.PersistentFlags().StringVar(&writeFlags.BucketID, "bucket-id", "", "ID of destination bucket")
	viper.BindEnv("BUCKET_ID")
	if h := viper.GetString("BUCKET_ID"); h != "" {
		writeFlags.BucketID = h
	}

	writeCmd.PersistentFlags().StringVarP(&writeFlags.Org, "bucket", "b", "", "name of destination bucket")
	viper.BindEnv("BUCKET_NAME")
	if h := viper.GetString("BUCKET_NAM"); h != "" {
		writeFlags.Bucket = h
	}
}

func fluxWriteF(cmd *cobra.Command, args []string) {
	ctx := context.TODO()

	if writeFlags.Org != "" && writeFlags.OrgID != "" {
		fmt.Println("must specify exactly one of org or org-id")
		cmd.Usage()
		os.Exit(1)
	}

	if writeFlags.Bucket != "" && writeFlags.BucketID != "" {
		fmt.Println("must specify exactly one of org or org-id")
		cmd.Usage()
		os.Exit(1)
	}

	bs := &http.BucketService{
		Addr:  flags.host,
		Token: flags.token,
	}

	var err error
	filter := platform.BucketFilter{}

	if writeFlags.BucketID != "" {
		filter.ID, err = platform.IDFromString(writeFlags.BucketID)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	}
	if writeFlags.Bucket != "" {
		filter.Name = &writeFlags.Bucket
	}

	if writeFlags.OrgID != "" {
		filter.OrganizationID, err = platform.IDFromString(writeFlags.OrgID)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	}
	if writeFlags.Org != "" {
		filter.Organization = &writeFlags.Org
	}

	buckets, _, err := bs.FindBuckets(ctx, filter)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	bucketID, orgID := buckets[0].ID, buckets[0].OrganizationID

	var r io.Reader
	if args[0] == "-" {
		r = os.Stdin
	} else if len(args[0]) > 0 && args[0][0] == '@' {
		f, err := os.Open(args[0][1:])
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		defer f.Close()
		r = f
	} else {
		r = strings.NewReader(args[0])
	}

	s := &http.WriteService{
		Addr:  flags.host,
		Token: flags.token,
	}

	if err = s.Write(ctx, orgID, bucketID, r); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package commands

import (
	"log"
	"strings"
	"time"

	"github.com/benfb/vin/api"
	"github.com/benfb/vin/util"
	"github.com/urfave/cli"
)

// ResultsCmd is the command run by `vin results`
func ResultsCmd(date, team, without string) error {
	go util.Spinner()

	if !util.ContainsString(api.Teams, strings.Title(team)) && team != "all" {
		return cli.NewExitError("Error! \""+team+"\" is not a valid team.", 1)
	}
	timeFmtStr := "1/_2/06"
	if date == "today" {
		date = time.Now().Format(timeFmtStr)
	}
	parsedTime, timeErr := time.Parse(timeFmtStr, date)
	if timeErr != nil {
		return cli.NewExitError("Error! \""+date+"\" is not a valid date.", 1)
	}
	list := api.FetchGames(parsedTime)
	for _, g := range list {
		if !g.FindTeam(strings.Title(without)) && (g.FindTeam(strings.Title(team)) || team == "all") {
			w := without
			a := g.FindTeam(strings.Title(without))
			b := !g.FindTeam(strings.Title(without)) && (g.FindTeam(strings.Title(team)) || team == "all")
			log.Println("w: " + w)
			log.Printf("a: %t\n", a)
			log.Printf("b: %t\n", b)
			g.PrintBoxScoreTable()
			g.PrintProbablePitchers()
		}
	}

	return nil
}
<commit_msg>remove results debugging<commit_after>package commands

import (
	"strings"
	"time"

	"github.com/benfb/vin/api"
	"github.com/benfb/vin/util"
	"github.com/urfave/cli"
)

// ResultsCmd is the command run by `vin results`
func ResultsCmd(date, team, without string) error {
	go util.Spinner()

	if !util.ContainsString(api.Teams, strings.Title(team)) && team != "all" {
		return cli.NewExitError("Error! \""+team+"\" is not a valid team.", 1)
	}
	timeFmtStr := "1/_2/06"
	if date == "today" {
		date = time.Now().Format(timeFmtStr)
	}
	parsedTime, timeErr := time.Parse(timeFmtStr, date)
	if timeErr != nil {
		return cli.NewExitError("Error! \""+date+"\" is not a valid date.", 1)
	}
	list := api.FetchGames(parsedTime)
	for _, g := range list {
		if !g.FindTeam(strings.Title(without)) && (g.FindTeam(strings.Title(team)) || team == "all") {
			g.PrintBoxScoreTable()
			g.PrintProbablePitchers()
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package migrate_test

import (
	"fmt"
	"github.com/JackC/pgx"
	"github.com/JackC/pgx/migrate"
	. "gopkg.in/check.v1"
	"testing"
)

type MigrateSuite struct {
	conn *pgx.Connection
}

func Test(t *testing.T) { TestingT(t) }

var _ = Suite(&MigrateSuite{})

var versionTable string = "schema_version"

func (s *MigrateSuite) SetUpTest(c *C) {
	var err error
	s.conn, err = pgx.Connect(*defaultConnectionParameters)
	c.Assert(err, IsNil)

	s.cleanupSampleMigrator(c)
}

func (s *MigrateSuite) SelectValue(c *C, sql string, arguments ...interface{}) interface{} {
	value, err := s.conn.SelectValue(sql, arguments...)
	c.Assert(err, IsNil)
	return value
}

func (s *MigrateSuite) Execute(c *C, sql string, arguments ...interface{}) string {
	commandTag, err := s.conn.Execute(sql, arguments...)
	c.Assert(err, IsNil)
	return commandTag
}

func (s *MigrateSuite) tableExists(c *C, tableName string) bool {
	return s.SelectValue(c,
		"select exists(select 1 from information_schema.tables where table_catalog=$1 and table_name=$2)",
		defaultConnectionParameters.Database,
		tableName).(bool)
}

func (s *MigrateSuite) createEmptyMigrator(c *C) *migrate.Migrator {
	var err error
	m, err := migrate.NewMigrator(s.conn, versionTable)
	c.Assert(err, IsNil)
	return m
}

func (s *MigrateSuite) createSampleMigrator(c *C) *migrate.Migrator {
	m := s.createEmptyMigrator(c)
	m.AppendMigration("Create t1", "create table t1(id serial);", "drop table t1;")
	m.AppendMigration("Create t2", "create table t2(id serial);", "drop table t2;")
	m.AppendMigration("Create t3", "create table t3(id serial);", "drop table t3;")
	return m
}

func (s *MigrateSuite) cleanupSampleMigrator(c *C) {
	tables := []string{versionTable, "t1", "t2", "t3"}
	for _, table := range tables {
		s.Execute(c, "drop table if exists "+table)
	}
}

func (s *MigrateSuite) TestNewMigrator(c *C) {
	var m *migrate.Migrator
	var err error

	// Initial run
	m, err = migrate.NewMigrator(s.conn, versionTable)
	c.Assert(err, IsNil)

	// Creates version table
	schemaVersionExists := s.tableExists(c, versionTable)
	c.Assert(schemaVersionExists, Equals, true)

	// Succeeds when version table is already created
	m, err = migrate.NewMigrator(s.conn, versionTable)
	c.Assert(err, IsNil)

	initialVersion, err := m.GetCurrentVersion()
	c.Assert(err, IsNil)
	c.Assert(initialVersion, Equals, int32(0))
}

func (s *MigrateSuite) TestAppendMigration(c *C) {
	m := s.createEmptyMigrator(c)

	name := "Create t"
	upSQL := "create t..."
	downSQL := "drop t..."
	m.AppendMigration(name, upSQL, downSQL)

	c.Assert(len(m.Migrations), Equals, 1)
	c.Assert(m.Migrations[0].Name, Equals, name)
	c.Assert(m.Migrations[0].UpSQL, Equals, upSQL)
	c.Assert(m.Migrations[0].DownSQL, Equals, downSQL)
}

func (s *MigrateSuite) TestLoadMigrationsMissingDirectory(c *C) {
	m := s.createEmptyMigrator(c)
	err := m.LoadMigrations("testdata/missing")
	c.Assert(err, ErrorMatches, "No migrations found at testdata/missing")
}

func (s *MigrateSuite) TestLoadMigrationsEmptyDirectory(c *C) {
	m := s.createEmptyMigrator(c)
	err := m.LoadMigrations("testdata/empty")
	c.Assert(err, ErrorMatches, "No migrations found at testdata/empty")
}

func (s *MigrateSuite) TestLoadMigrations(c *C) {
	m := s.createEmptyMigrator(c)
	err := m.LoadMigrations("testdata/sample")
	c.Assert(err, IsNil)
	c.Assert(m.Migrations, HasLen, 3)

	c.Check(m.Migrations[0].Name, Equals, "001_create_t1.sql")
	c.Check(m.Migrations[0].UpSQL, Equals, `create table t1(
  id serial primary key
);`)
	c.Check(m.Migrations[0].DownSQL, Equals, "drop table t1;")

	c.Check(m.Migrations[1].Name, Equals, "002_create_t2.sql")
	c.Check(m.Migrations[1].UpSQL, Equals, `create table t2(
  id serial primary key
);`)
	c.Check(m.Migrations[1].DownSQL, Equals, "drop table t2;")

	c.Check(m.Migrations[2].Name, Equals, "003_irreversible.sql")
	c.Check(m.Migrations[2].UpSQL, Equals, "drop table t2;")
	c.Check(m.Migrations[2].DownSQL, Equals, "")
}

func (s *MigrateSuite) TestMigrate(c *C) {
	m := s.createSampleMigrator(c)

	err := m.Migrate()
	c.Assert(err, IsNil)
	currentVersion := s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(3))
}

func (s *MigrateSuite) TestMigrateToLifeCycle(c *C) {
	m := s.createSampleMigrator(c)

	var onStartCallUpCount int
	var onStartCallDownCount int
	m.OnStart = func(_ *migrate.Migration, direction string) {
		switch direction {
		case "up":
			onStartCallUpCount++
		case "down":
			onStartCallDownCount++
		default:
			c.Fatalf("Unexpected direction: %s", direction)
		}
	}

	// Migrate from 0 up to 1
	err := m.MigrateTo(1)
	c.Assert(err, IsNil)
	currentVersion := s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(1))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, false)
	c.Assert(s.tableExists(c, "t3"), Equals, false)
	c.Assert(onStartCallUpCount, Equals, 1)
	c.Assert(onStartCallDownCount, Equals, 0)

	// Migrate from 1 up to 3
	err = m.MigrateTo(3)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(3))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, true)
	c.Assert(s.tableExists(c, "t3"), Equals, true)
	c.Assert(onStartCallUpCount, Equals, 3)
	c.Assert(onStartCallDownCount, Equals, 0)

	// Migrate from 3 to 3 is no-op
	err = m.MigrateTo(3)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(3))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, true)
	c.Assert(s.tableExists(c, "t3"), Equals, true)
	c.Assert(onStartCallUpCount, Equals, 3)
	c.Assert(onStartCallDownCount, Equals, 0)

	// Migrate from 3 down to 1
	err = m.MigrateTo(1)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(1))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, false)
	c.Assert(s.tableExists(c, "t3"), Equals, false)
	c.Assert(onStartCallUpCount, Equals, 3)
	c.Assert(onStartCallDownCount, Equals, 2)

	// Migrate from 1 down to 0
	err = m.MigrateTo(0)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(0))
	c.Assert(s.tableExists(c, "t1"), Equals, false)
	c.Assert(s.tableExists(c, "t2"), Equals, false)
	c.Assert(s.tableExists(c, "t3"), Equals, false)
	c.Assert(onStartCallUpCount, Equals, 3)
	c.Assert(onStartCallDownCount, Equals, 3)

	// Migrate back up to 3
	err = m.MigrateTo(3)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(3))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, true)
	c.Assert(s.tableExists(c, "t3"), Equals, true)
	c.Assert(onStartCallUpCount, Equals, 6)
	c.Assert(onStartCallDownCount, Equals, 3)
}

func (s *MigrateSuite) TestMigrateToBoundaries(c *C) {
	m := s.createSampleMigrator(c)

	// Migrate to -1 is error
	err := m.MigrateTo(-1)
	c.Assert(err, ErrorMatches, "schema_version version -1 is outside the valid versions of 0 to 3")

	// Migrate past end is error
	err = m.MigrateTo(int32(len(m.Migrations)) + 1)
	c.Assert(err, ErrorMatches, "schema_version version 4 is outside the valid versions of 0 to 3")
}

func (s *MigrateSuite) TestMigrateToIrreversible(c *C) {
	m := s.createEmptyMigrator(c)
	m.AppendMigration("Foo", "drop table if exists t3", "")

	err := m.MigrateTo(1)
	c.Assert(err, IsNil)

	err = m.MigrateTo(0)
	c.Assert(err, ErrorMatches, "Irreversible migration: 1 - Foo")
}

func Example_OnStartMigrationProgressLogging() {
	conn, err := pgx.Connect(*defaultConnectionParameters)
	if err != nil {
		fmt.Printf("Unable to establish connection: %v", err)
		return
	}

	// Clear any previous runs
	if _, err = conn.Execute("drop table if exists schema_version"); err != nil {
		fmt.Printf("Unable to drop schema_version table: %v", err)
		return
	}

	var m *migrate.Migrator
	m, err = migrate.NewMigrator(conn, "schema_version")
	if err != nil {
		fmt.Printf("Unable to create migrator: %v", err)
		return
	}

	m.OnStart = func(migration *migrate.Migration, direction string) {
		fmt.Printf("Migrating %s: %s", direction, migration.Name)
	}

	m.AppendMigration("create a table", "create temporary table foo(id serial primary key)", "")

	if err = m.Migrate(); err != nil {
		fmt.Printf("Unexpected failure migrating: %v", err)
		return
	}
	// Output:
	// Migrating up: create a table
}
<commit_msg>Test should import correct migrate package<commit_after>package migrate_test

import (
	"fmt"
	"github.com/JackC/pgx"
	"github.com/JackC/tern/migrate"
	. "gopkg.in/check.v1"
	"testing"
)

type MigrateSuite struct {
	conn *pgx.Connection
}

func Test(t *testing.T) { TestingT(t) }

var _ = Suite(&MigrateSuite{})

var versionTable string = "schema_version"

func (s *MigrateSuite) SetUpTest(c *C) {
	var err error
	s.conn, err = pgx.Connect(*defaultConnectionParameters)
	c.Assert(err, IsNil)

	s.cleanupSampleMigrator(c)
}

func (s *MigrateSuite) SelectValue(c *C, sql string, arguments ...interface{}) interface{} {
	value, err := s.conn.SelectValue(sql, arguments...)
	c.Assert(err, IsNil)
	return value
}

func (s *MigrateSuite) Execute(c *C, sql string, arguments ...interface{}) string {
	commandTag, err := s.conn.Execute(sql, arguments...)
	c.Assert(err, IsNil)
	return commandTag
}

func (s *MigrateSuite) tableExists(c *C, tableName string) bool {
	return s.SelectValue(c,
		"select exists(select 1 from information_schema.tables where table_catalog=$1 and table_name=$2)",
		defaultConnectionParameters.Database,
		tableName).(bool)
}

func (s *MigrateSuite) createEmptyMigrator(c *C) *migrate.Migrator {
	var err error
	m, err := migrate.NewMigrator(s.conn, versionTable)
	c.Assert(err, IsNil)
	return m
}

func (s *MigrateSuite) createSampleMigrator(c *C) *migrate.Migrator {
	m := s.createEmptyMigrator(c)
	m.AppendMigration("Create t1", "create table t1(id serial);", "drop table t1;")
	m.AppendMigration("Create t2", "create table t2(id serial);", "drop table t2;")
	m.AppendMigration("Create t3", "create table t3(id serial);", "drop table t3;")
	return m
}

func (s *MigrateSuite) cleanupSampleMigrator(c *C) {
	tables := []string{versionTable, "t1", "t2", "t3"}
	for _, table := range tables {
		s.Execute(c, "drop table if exists "+table)
	}
}

func (s *MigrateSuite) TestNewMigrator(c *C) {
	var m *migrate.Migrator
	var err error

	// Initial run
	m, err = migrate.NewMigrator(s.conn, versionTable)
	c.Assert(err, IsNil)

	// Creates version table
	schemaVersionExists := s.tableExists(c, versionTable)
	c.Assert(schemaVersionExists, Equals, true)

	// Succeeds when version table is already created
	m, err = migrate.NewMigrator(s.conn, versionTable)
	c.Assert(err, IsNil)

	initialVersion, err := m.GetCurrentVersion()
	c.Assert(err, IsNil)
	c.Assert(initialVersion, Equals, int32(0))
}

func (s *MigrateSuite) TestAppendMigration(c *C) {
	m := s.createEmptyMigrator(c)

	name := "Create t"
	upSQL := "create t..."
	downSQL := "drop t..."
	m.AppendMigration(name, upSQL, downSQL)

	c.Assert(len(m.Migrations), Equals, 1)
	c.Assert(m.Migrations[0].Name, Equals, name)
	c.Assert(m.Migrations[0].UpSQL, Equals, upSQL)
	c.Assert(m.Migrations[0].DownSQL, Equals, downSQL)
}

func (s *MigrateSuite) TestLoadMigrationsMissingDirectory(c *C) {
	m := s.createEmptyMigrator(c)
	err := m.LoadMigrations("testdata/missing")
	c.Assert(err, ErrorMatches, "No migrations found at testdata/missing")
}

func (s *MigrateSuite) TestLoadMigrationsEmptyDirectory(c *C) {
	m := s.createEmptyMigrator(c)
	err := m.LoadMigrations("testdata/empty")
	c.Assert(err, ErrorMatches, "No migrations found at testdata/empty")
}

func (s *MigrateSuite) TestLoadMigrations(c *C) {
	m := s.createEmptyMigrator(c)
	err := m.LoadMigrations("testdata/sample")
	c.Assert(err, IsNil)
	c.Assert(m.Migrations, HasLen, 3)

	c.Check(m.Migrations[0].Name, Equals, "001_create_t1.sql")
	c.Check(m.Migrations[0].UpSQL, Equals, `create table t1(
  id serial primary key
);`)
	c.Check(m.Migrations[0].DownSQL, Equals, "drop table t1;")

	c.Check(m.Migrations[1].Name, Equals, "002_create_t2.sql")
	c.Check(m.Migrations[1].UpSQL, Equals, `create table t2(
  id serial primary key
);`)
	c.Check(m.Migrations[1].DownSQL, Equals, "drop table t2;")

	c.Check(m.Migrations[2].Name, Equals, "003_irreversible.sql")
	c.Check(m.Migrations[2].UpSQL, Equals, "drop table t2;")
	c.Check(m.Migrations[2].DownSQL, Equals, "")
}

func (s *MigrateSuite) TestMigrate(c *C) {
	m := s.createSampleMigrator(c)

	err := m.Migrate()
	c.Assert(err, IsNil)
	currentVersion := s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(3))
}

func (s *MigrateSuite) TestMigrateToLifeCycle(c *C) {
	m := s.createSampleMigrator(c)

	var onStartCallUpCount int
	var onStartCallDownCount int
	m.OnStart = func(_ *migrate.Migration, direction string) {
		switch direction {
		case "up":
			onStartCallUpCount++
		case "down":
			onStartCallDownCount++
		default:
			c.Fatalf("Unexpected direction: %s", direction)
		}
	}

	// Migrate from 0 up to 1
	err := m.MigrateTo(1)
	c.Assert(err, IsNil)
	currentVersion := s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(1))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, false)
	c.Assert(s.tableExists(c, "t3"), Equals, false)
	c.Assert(onStartCallUpCount, Equals, 1)
	c.Assert(onStartCallDownCount, Equals, 0)

	// Migrate from 1 up to 3
	err = m.MigrateTo(3)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(3))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, true)
	c.Assert(s.tableExists(c, "t3"), Equals, true)
	c.Assert(onStartCallUpCount, Equals, 3)
	c.Assert(onStartCallDownCount, Equals, 0)

	// Migrate from 3 to 3 is no-op
	err = m.MigrateTo(3)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(3))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, true)
	c.Assert(s.tableExists(c, "t3"), Equals, true)
	c.Assert(onStartCallUpCount, Equals, 3)
	c.Assert(onStartCallDownCount, Equals, 0)

	// Migrate from 3 down to 1
	err = m.MigrateTo(1)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(1))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, false)
	c.Assert(s.tableExists(c, "t3"), Equals, false)
	c.Assert(onStartCallUpCount, Equals, 3)
	c.Assert(onStartCallDownCount, Equals, 2)

	// Migrate from 1 down to 0
	err = m.MigrateTo(0)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(0))
	c.Assert(s.tableExists(c, "t1"), Equals, false)
	c.Assert(s.tableExists(c, "t2"), Equals, false)
	c.Assert(s.tableExists(c, "t3"), Equals, false)
	c.Assert(onStartCallUpCount, Equals, 3)
	c.Assert(onStartCallDownCount, Equals, 3)

	// Migrate back up to 3
	err = m.MigrateTo(3)
	c.Assert(err, IsNil)
	currentVersion = s.SelectValue(c, "select version from schema_version")
	c.Assert(currentVersion, Equals, int32(3))
	c.Assert(s.tableExists(c, "t1"), Equals, true)
	c.Assert(s.tableExists(c, "t2"), Equals, true)
	c.Assert(s.tableExists(c, "t3"), Equals, true)
	c.Assert(onStartCallUpCount, Equals, 6)
	c.Assert(onStartCallDownCount, Equals, 3)
}

func (s *MigrateSuite) TestMigrateToBoundaries(c *C) {
	m := s.createSampleMigrator(c)

	// Migrate to -1 is error
	err := m.MigrateTo(-1)
	c.Assert(err, ErrorMatches, "schema_version version -1 is outside the valid versions of 0 to 3")

	// Migrate past end is error
	err = m.MigrateTo(int32(len(m.Migrations)) + 1)
	c.Assert(err, ErrorMatches, "schema_version version 4 is outside the valid versions of 0 to 3")
}

func (s *MigrateSuite) TestMigrateToIrreversible(c *C) {
	m := s.createEmptyMigrator(c)
	m.AppendMigration("Foo", "drop table if exists t3", "")

	err := m.MigrateTo(1)
	c.Assert(err, IsNil)

	err = m.MigrateTo(0)
	c.Assert(err, ErrorMatches, "Irreversible migration: 1 - Foo")
}

func Example_OnStartMigrationProgressLogging() {
	conn, err := pgx.Connect(*defaultConnectionParameters)
	if err != nil {
		fmt.Printf("Unable to establish connection: %v", err)
		return
	}

	// Clear any previous runs
	if _, err = conn.Execute("drop table if exists schema_version"); err != nil {
		fmt.Printf("Unable to drop schema_version table: %v", err)
		return
	}

	var m *migrate.Migrator
	m, err = migrate.NewMigrator(conn, "schema_version")
	if err != nil {
		fmt.Printf("Unable to create migrator: %v", err)
		return
	}

	m.OnStart = func(migration *migrate.Migration, direction string) {
		fmt.Printf("Migrating %s: %s", direction, migration.Name)
	}

	m.AppendMigration("create a table", "create temporary table foo(id serial primary key)", "")

	if err = m.Migrate(); err != nil {
		fmt.Printf("Unexpected failure migrating: %v", err)
		return
	}
	// Output:
	// Migrating up: create a table
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
	"errors"
	"fmt"
	"reflect"

	"github.com/google/cel-go/common/types/ref"
)

// Err type which extends the built-in go error and implements ref.Val.
type Err struct {
	error
}

var (
	// ErrType singleton.
	ErrType = NewTypeValue("error")

	// errDivideByZero is an error indicating a division by zero of an integer value.
	errDivideByZero = errors.New("division by zero")
	// errModulusByZero is an error indicating a modulus by zero of an integer value.
	errModulusByZero = errors.New("modulus by zero")
	// errIntOverflow is an error representing integer overflow.
	errIntOverflow = errors.New("integer overflow")
	// errUintOverflow is an error representing unsigned integer overflow.
	errUintOverflow = errors.New("unsigned integer overflow")
	// errDurationOverflow is an error representing duration overflow.
	errDurationOverflow = errors.New("duration overflow")
	// errTimestampOverflow is an error representing timestamp overflow.
	errTimestampOverflow    = errors.New("timestamp overflow")
	celErrTimestampOverflow = &Err{error: errTimestampOverflow}

	// celErrNoSuchOverload indicates that the call arguments did not match a supported method signature.
	celErrNoSuchOverload = NewErr("no such overload")
)

// NewErr creates a new Err described by the format string and args.
// TODO: Audit the use of this function and standardize the error messages and codes.
func NewErr(format string, args ...interface{}) ref.Val {
	return &Err{fmt.Errorf(format, args...)}
}

// NoSuchOverloadErr returns a new types.Err instance with a no such overload message.
func NoSuchOverloadErr() ref.Val {
	return celErrNoSuchOverload
}

// UnsupportedRefValConversionErr returns a types.NewErr instance with a no such conversion
// message that indicates that the native value could not be converted to a CEL ref.Val.
func UnsupportedRefValConversionErr(val interface{}) ref.Val {
	return NewErr("unsupported conversion to ref.Val: (%T)%v", val, val)
}

// MaybeNoSuchOverloadErr returns the error or unknown if the input ref.Val is one of these types,
// else a new no such overload error.
func MaybeNoSuchOverloadErr(val ref.Val) ref.Val {
	return ValOrErr(val, "no such overload")
}

// ValOrErr either returns the existing error or create a new one.
// TODO: Audit the use of this function and standardize the error messages and codes.
func ValOrErr(val ref.Val, format string, args ...interface{}) ref.Val {
	if val == nil {
		return NewErr(format, args...)
	}
	if IsUnknownOrError(val) {
		return val
	}
	return NewErr(format, args...)
}

// wrapErr wraps an existing Go error value into a CEL Err value.
func wrapErr(err error) ref.Val {
	return &Err{error: err}
}

// ConvertToNative implements ref.Val.ConvertToNative.
func (e *Err) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
	return nil, e.error
}

// ConvertToType implements ref.Val.ConvertToType.
func (e *Err) ConvertToType(typeVal ref.Type) ref.Val {
	// Errors are not convertible to other representations.
	return e
}

// Equal implements ref.Val.Equal.
func (e *Err) Equal(other ref.Val) ref.Val {
	// An error cannot be equal to any other value, so it returns itself.
	return e
}

// String implements fmt.Stringer.
func (e *Err) String() string {
	return e.error.Error()
}

// Type implements ref.Val.Type.
func (e *Err) Type() ref.Type {
	return ErrType
}

// Value implements ref.Val.Value.
func (e *Err) Value() interface{} {
	return e.error
}

// IsError returns whether the input element ref.Type or ref.Val is equal to
// the ErrType singleton.
func IsError(val ref.Val) bool {
	switch val.(type) {
	case *Err:
		return true
	default:
		return false
	}
}
<commit_msg>Minor simplification of ValOrErr (#522)<commit_after>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
	"errors"
	"fmt"
	"reflect"

	"github.com/google/cel-go/common/types/ref"
)

// Err type which extends the built-in go error and implements ref.Val.
type Err struct {
	error
}

var (
	// ErrType singleton.
	ErrType = NewTypeValue("error")

	// errDivideByZero is an error indicating a division by zero of an integer value.
	errDivideByZero = errors.New("division by zero")
	// errModulusByZero is an error indicating a modulus by zero of an integer value.
	errModulusByZero = errors.New("modulus by zero")
	// errIntOverflow is an error representing integer overflow.
	errIntOverflow = errors.New("integer overflow")
	// errUintOverflow is an error representing unsigned integer overflow.
	errUintOverflow = errors.New("unsigned integer overflow")
	// errDurationOverflow is an error representing duration overflow.
	errDurationOverflow = errors.New("duration overflow")
	// errTimestampOverflow is an error representing timestamp overflow.
	errTimestampOverflow    = errors.New("timestamp overflow")
	celErrTimestampOverflow = &Err{error: errTimestampOverflow}

	// celErrNoSuchOverload indicates that the call arguments did not match a supported method signature.
	celErrNoSuchOverload = NewErr("no such overload")
)

// NewErr creates a new Err described by the format string and args.
// TODO: Audit the use of this function and standardize the error messages and codes.
func NewErr(format string, args ...interface{}) ref.Val {
	return &Err{fmt.Errorf(format, args...)}
}

// NoSuchOverloadErr returns a new types.Err instance with a no such overload message.
func NoSuchOverloadErr() ref.Val {
	return celErrNoSuchOverload
}

// UnsupportedRefValConversionErr returns a types.NewErr instance with a no such conversion
// message that indicates that the native value could not be converted to a CEL ref.Val.
func UnsupportedRefValConversionErr(val interface{}) ref.Val {
	return NewErr("unsupported conversion to ref.Val: (%T)%v", val, val)
}

// MaybeNoSuchOverloadErr returns the error or unknown if the input ref.Val is one of these types,
// else a new no such overload error.
func MaybeNoSuchOverloadErr(val ref.Val) ref.Val {
	return ValOrErr(val, "no such overload")
}

// ValOrErr either returns the existing error or creates a new one.
// TODO: Audit the use of this function and standardize the error messages and codes.
func ValOrErr(val ref.Val, format string, args ...interface{}) ref.Val {
	if val == nil || !IsUnknownOrError(val) {
		return NewErr(format, args...)
	}
	return val
}

// wrapErr wraps an existing Go error value into a CEL Err value.
func wrapErr(err error) ref.Val {
	return &Err{error: err}
}

// ConvertToNative implements ref.Val.ConvertToNative.
func (e *Err) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
	return nil, e.error
}

// ConvertToType implements ref.Val.ConvertToType.
func (e *Err) ConvertToType(typeVal ref.Type) ref.Val {
	// Errors are not convertible to other representations.
	return e
}

// Equal implements ref.Val.Equal.
func (e *Err) Equal(other ref.Val) ref.Val {
	// An error cannot be equal to any other value, so it returns itself.
	return e
}

// String implements fmt.Stringer.
func (e *Err) String() string {
	return e.error.Error()
}

// Type implements ref.Val.Type.
func (e *Err) Type() ref.Type {
	return ErrType
}

// Value implements ref.Val.Value.
func (e *Err) Value() interface{} {
	return e.error
}

// IsError returns whether the input element ref.Type or ref.Val is equal to
// the ErrType singleton.
func IsError(val ref.Val) bool {
	switch val.(type) {
	case *Err:
		return true
	default:
		return false
	}
}
<|endoftext|>


<commit_before>package action

import (
	"appengine"
	"appengine/datastore"
	"time"
)

const (
	UpdateNotification ActionType = iota //Client was notified it should update.
	DownloadStart      ActionType = iota //Client startde downloading.
	DownloadFinish     ActionType = iota //Client finished download.
)

type ActionType int

func (at ActionType) String() string {
	switch at {
	case UpdateNotification:
		return "Update notification"
	case DownloadStart:
		return "Download started"
	case DownloadFinish:
		return "Download is finished"
	}
	return "Unknown action"
}

//Action (better name would be Action, but it would be hard to change it now)
//is a type used for recording whe time when clients
//did an action specified by the ActionType.
type Action struct {
	Type         ActionType     //Type of action
	Client       string         //Name of the client
	Time         time.Time      //Time of the action
	Presentation *datastore.Key //What object is the action related to.
	Key          string         `datastore:"-"`
}

//Model is an nterface specifying models - structs which Datastore keys can be obtained.
type Model interface {
	GetKey(appengine.Context) (*datastore.Key, error)
}

func (a Action) GetKey() (k *datastore.Key, err error) {
	k, err = datastore.DecodeKey(a.Key)
	return
}

//Newreturns a pointer to an action with its fields set according
//to arguments.
func New(k *datastore.Key, at ActionType, client string) (a *Action) {
	a = new(Action)
	a.Presentation = k
	a.Type = at
	a.Client = client
	a.Time = time.Now()
	return a
}

//Make creates a new Action using New and then saves
//it to Datastore.
func Make(m Model, at ActionType, client string, c appengine.Context) (a *Action, err error) {
	k, err := m.GetKey(c)
	if err != nil {
		return
	}
	a = New(k, at, client)
	err = a.Save(c)
	return
}

//Save saves an Action to Datastore.
//If its Key field is set, it will use it, replacing
//existing records. If not, it will use datastore.NewIncompleteKey()
//to create a new key and set the field.
func (a *Action) Save(c appengine.Context) (err error) {
	if a.Key == "" {
		var key *datastore.Key
		key, err = datastore.Put(c, datastore.NewIncompleteKey(c, "Action", a.Presentation), a)
		a.Key = key.Encode()
		return
	} else {
		var key *datastore.Key
		key, err = datastore.DecodeKey(a.Key)
		if err != nil {
			return
		}
		_, err = datastore.Put(c, key, a)
	}
	return
}

//Works like Make but logs errors instead of returning them.
func LogAction(m Model, client string, at ActionType, c appengine.Context) {
	if client == "" {
		c.Infof("%v called without client name.", at)
		return
	}

	_, err := Make(m, at, client, c)
	if err != nil {
		c.Infof("Can't log Action to Datastore: %v", err)
	}
}

//GetFor returns a slice containing all the Actions for
//a given Model.
func GetFor(m Model, c appengine.Context) (as []Action, err error) {
	key, err := m.GetKey(c)
	if err != nil {
		return
	}
	as = make([]Action, 12)
	keys, err := datastore.NewQuery("Action").Ancestor(key).GetAll(c, &as)
	if err != nil {
		return
	}
	for i := range keys {
		as[i].Key = keys[i].Encode()
	}
	return
}

//GetDownloadCount returns how many times given Model was downloaded.
func GetDownloadCount(m Model, c appengine.Context) (count int, err error) {
	key, err := m.GetKey(c)
	if err != nil {
		return
	}
	count, err = datastore.NewQuery("Action").Ancestor(key).Filter("Type =", DownloadFinish).Count(c)
	return
}

//WasDownloadedBy returns whether given client downloaded file associated
//with given Model.
func WasDownloadedBy(m Model, client string, c appengine.Context) (bool, error) {
	key, err := m.GetKey(c)
	if err != nil {
		return false, err
	}
	i := datastore.NewQuery("Action").Ancestor(key).Filter("Client =", client).Filter("Type =", DownloadFinish).KeysOnly().Run(c)
	_, err = i.Next(nil)
	if err == datastore.Done {
		return false, nil
	}
	return true, err
}

//DeleteFor deletes all Actions for a specified Model.
func DeleteFor(m Model, c appengine.Context) (err error) {
	var keys []*datastore.Key
	key, err := m.GetKey(c)
	if err != nil {
		return
	}
	keys, err = datastore.NewQuery("Action").Ancestor(key).KeysOnly().GetAll(c, nil)
	if err != nil {
		return
	}
	err = datastore.DeleteMulti(c, keys)
	if err != nil {
		return
	}
	return
}
<commit_msg>Generalized GetDownloadsFor to GetCountFor<commit_after>package action

import (
	"appengine"
	"appengine/datastore"
	"time"
)

const (
	UpdateNotification ActionType = iota //Client was notified it should update.
	DownloadStart      ActionType = iota //Client startde downloading.
	DownloadFinish     ActionType = iota //Client finished download.
)

type ActionType int

func (at ActionType) String() string {
	switch at {
	case UpdateNotification:
		return "Update notification"
	case DownloadStart:
		return "Download started"
	case DownloadFinish:
		return "Download is finished"
	}
	return "Unknown action"
}

//Action (better name would be Action, but it would be hard to change it now)
//is a type used for recording whe time when clients
//did an action specified by the ActionType.
type Action struct {
	Type         ActionType     //Type of action
	Client       string         //Name of the client
	Time         time.Time      //Time of the action
	Presentation *datastore.Key //What object is the action related to.
	Key          string         `datastore:"-"`
}

//Model is an nterface specifying models - structs which Datastore keys can be obtained.
type Model interface {
	GetKey(appengine.Context) (*datastore.Key, error)
}

func (a Action) GetKey() (k *datastore.Key, err error) {
	k, err = datastore.DecodeKey(a.Key)
	return
}

//Newreturns a pointer to an action with its fields set according
//to arguments.
func New(k *datastore.Key, at ActionType, client string) (a *Action) {
	a = new(Action)
	a.Presentation = k
	a.Type = at
	a.Client = client
	a.Time = time.Now()
	return a
}

//Make creates a new Action using New and then saves
//it to Datastore.
func Make(m Model, at ActionType, client string, c appengine.Context) (a *Action, err error) {
	k, err := m.GetKey(c)
	if err != nil {
		return
	}
	a = New(k, at, client)
	err = a.Save(c)
	return
}

//Save saves an Action to Datastore.
//If its Key field is set, it will use it, replacing
//existing records. If not, it will use datastore.NewIncompleteKey()
//to create a new key and set the field.
func (a *Action) Save(c appengine.Context) (err error) {
	if a.Key == "" {
		var key *datastore.Key
		key, err = datastore.Put(c, datastore.NewIncompleteKey(c, "Action", a.Presentation), a)
		a.Key = key.Encode()
		return
	} else {
		var key *datastore.Key
		key, err = datastore.DecodeKey(a.Key)
		if err != nil {
			return
		}
		_, err = datastore.Put(c, key, a)
	}
	return
}

//Works like Make but logs errors instead of returning them.
func LogAction(m Model, client string, at ActionType, c appengine.Context) {
	if client == "" {
		c.Infof("%v called without client name.", at)
		return
	}

	_, err := Make(m, at, client, c)
	if err != nil {
		c.Infof("Can't log Action to Datastore: %v", err)
	}
}

//GetFor returns a slice containing all the Actions for
//a given Model.
func GetFor(m Model, c appengine.Context) (as []Action, err error) {
	key, err := m.GetKey(c)
	if err != nil {
		return
	}
	as = make([]Action, 12)
	keys, err := datastore.NewQuery("Action").Ancestor(key).GetAll(c, &as)
	if err != nil {
		return
	}
	for i := range keys {
		as[i].Key = keys[i].Encode()
	}
	return
}

//GetDownloadCount returns how many times given ActionType was performed on a Model.
func GetCountFor(at ActionType, m Model, c appengine.Context) (count int, err error) {
	key, err := m.GetKey(c)
	if err != nil {
		return
	}
	count, err = datastore.NewQuery("Action").Ancestor(key).Filter("Type =", at).Count(c)
	return
}

//WasDownloadedBy returns whether given client downloaded file associated
//with given Model.
func WasDownloadedBy(m Model, client string, c appengine.Context) (bool, error) {
	key, err := m.GetKey(c)
	if err != nil {
		return false, err
	}
	i := datastore.NewQuery("Action").Ancestor(key).Filter("Client =", client).Filter("Type =", DownloadFinish).KeysOnly().Run(c)
	_, err = i.Next(nil)
	if err == datastore.Done {
		return false, nil
	}
	return true, err
}

//DeleteFor deletes all Actions for a specified Model.
func DeleteFor(m Model, c appengine.Context) (err error) {
	var keys []*datastore.Key
	key, err := m.GetKey(c)
	if err != nil {
		return
	}
	keys, err = datastore.NewQuery("Action").Ancestor(key).KeysOnly().GetAll(c, nil)
	if err != nil {
		return
	}
	err = datastore.DeleteMulti(c, keys)
	if err != nil {
		return
	}
	return
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	"log"
	"net/url"
	"strings"
	"time"

	"github.com/UniversityRadioYork/2016-site/structs"
	"github.com/UniversityRadioYork/myradio-go"
)

// ScheduleItem contains information about one item in a URY schedule.
type ScheduleItem struct {
	// Name is the display name of the schedule item.
	Name string

	// Desc is the description of the schedule item.
	Desc string

	// Start is the start time of the schedule item.
	Start time.Time

	// Finish is the finish time of the schedule item.
	Finish time.Time

	// Block is the block name of the schedule item.
	Block string

	// PageURL is the root-relative URL to this schedule item's page,
	// or "" if there is no URL.
	PageURL string
}

// IsSustainer checks whether this schedule item is the URY sustainer.
func (s *ScheduleItem) IsSustainer() bool {
	return s.Block == "sustainer"
}

// NewSustainerItem creates a new sustainer schedule item lasting from start to finish.
// It takes a sustainer config, c, to work out the sustainer name.
func NewSustainerItem(c structs.SustainerConfig, start, finish time.Time) *ScheduleItem {
	return &ScheduleItem{
		Name:    c.Name,
		Desc:    c.Desc,
		Start:   start,
		Finish:  finish,
		Block:   "sustainer",
		PageURL: "",
	}
}

// NewTimeslotItem converts a myradio.Timeslot into a TimeslotItem.
// It accepts a separate finish time to account for any truncating that occurs when resolving overlaps.
func NewTimeslotItem(t *myradio.Timeslot, finish time.Time, u func(*myradio.Timeslot) (*url.URL, error)) (*ScheduleItem, error) {
	if t == nil {
		return nil, errors.New("NewTimeslotItem: given nil timeslot")
	}

	url, err := u(t)
	if err != nil {
		return nil, err
	}
	return &ScheduleItem{
		Name:    t.Title,
		Desc:    t.Description,
		Start:   t.StartTime,
		Finish:  finish,
		Block:   getBlock(t.Title, t.StartTime),
		PageURL: url.Path,
	}, nil
}

func getBlock(name string, StartTime time.Time) string {
	name = strings.ToLower(name)

	type blockMatch struct {
		nameFragment string
		block        string
	}
	var blockMatches = []blockMatch{
		{"ury: early morning", "primetime"},
		{"ury breakfast", "primetime"},
		{"ury lunch", "primetime"},
		{"ury brunch", "primetime"},
		{"URY Brunch", "primetime"},
		{"URY Afternoon Tea:", "primetime"},
		{"URY:PM", "primetime"},
		{"Alumni Takeover:", "primetime"},

		{"ury news", "news"},
		{"ury sports", "news"},
		{"ury football", "news"},
		{"york sport report", "news"},
		{"university radio talk", "news"},
		{"candidate interview night", "news"},
		{"election results night", "news"},
		{"yusu election", "news"},
		{"The Second Half With Josh Kerr", "news"},
		{"URY SPORT", "news"},
		{"URY News & Sport:", "news"},

		{"ury speech", "speech"},
		{"yorworld", "speech"},
		{"in the stalls", "speech"},
		{"screen", "speech"},
		{"stage", "speech"},
		{"game breaking", "speech"},
		{"radio drama", "speech"},
		{"Book Corner", "speech"},
		{"Saturated Facts", "speech"},
		{"URWatch", "speech"},
		{"Society Challenge", "speech"},
		{"Speech Showcase", "speech"},
		{"URY Speech:", "speech"},

		{"URY Music:", "music"},

		{"roses live 20", "event"},
		{"roses 20", "event"},
    	{"freshers 20", "event"},
		{"woodstock", "event"},
		{"movember", "event"},
		{"panto", "event"},
		{"101:", "event"},
		{"Vanbrugh Chair Debate", "event"},
		{"URY Does RAG Courtyard Takeover", "event"},
		{"URY Presents", "event"},
		{"URYOnTour", "event"},
		{"URY On Tour", "event"},

		{"YSTV", "collab"},
		{"Nouse", "collab"},
		{"York Politics Digest", "collab"},
	}
	for _, bm := range blockMatches {
		if strings.Contains(name, strings.ToLower(bm.nameFragment)) {
			return bm.block
		}
	}
	// certain times of the day correspond to a specific show type.
	if (StartTime.Hour() == 11) || (StartTime.Hour() == 19) { // missed flagship
		return "primetime"
	}
	return "regular"
}

// scheduleBuilder is an internal type holding information about a schedule slice under construction.
type scheduleBuilder struct {
	// config is the sustainer config to use when creating sustainer slots.
	config structs.SustainerConfig
	// slice is the schedule slice being constructed.
	items []*ScheduleItem
	// nitems is the number of items currently inside the schedule.
	nitems int
	// tbuilder is the function used to create schedule items from timeslots.
	tbuilder func(*myradio.Timeslot, time.Time) (*ScheduleItem, error)
	// err stores any error caused while building the schedule.
	err error
}

// newScheduleBuilder creates an empty schedule builder for nslots shows, given config c and builder tbuilder.
func newScheduleBuilder(c structs.SustainerConfig, tbuilder func(*myradio.Timeslot, time.Time) (*ScheduleItem, error), nslots int) *scheduleBuilder {
	return &scheduleBuilder{
		config: c,
		// nslots slots, (nslots - 1) sustainers in between, and 2 sustainers at the ends.
		items:    make([]*ScheduleItem, ((2 * nslots) + 1)),
		nitems:   0,
		tbuilder: tbuilder,
		err:      nil,
	}
}

// add adds an item to the scheduleBuilder s.
func (s *scheduleBuilder) add(i *ScheduleItem) {
	s.items[s.nitems] = i
	s.nitems++
}

// fill adds a sustainer timeslot between start and finish into the scheduleBuilder s if one needs to be there.
func (s *scheduleBuilder) fill(start, finish time.Time) {
	if start.Before(finish) {
		s.add(NewSustainerItem(s.config, start, finish))
	}
}

// addTimeslot converts a timeslot t to a schedule item, then adds it to the scheduleBuilder s.
// It takes an overlap-adjusted finish, and does not add an item if this adjustment causes t to disappear.
func (s *scheduleBuilder) addTimeslot(t *myradio.Timeslot, finish time.Time) {
	if s.err != nil || !t.StartTime.Before(finish) {
		return
	}

	var ts *ScheduleItem
	if ts, s.err = s.tbuilder(t, finish); s.err != nil {
		return
	}

	s.add(ts)
}

// schedule gets the schedule from a scheduleBuilder, or an err if schedule building failed.
func (s *scheduleBuilder) schedule() ([]*ScheduleItem, error) {
	if s.err != nil {
		return nil, s.err
	}
	return s.items[:s.nitems], nil
}

// truncateOverlap clips finish to nextStart if the two overlap and nextShow exists.
// If so, we log an overlap warning, whose content depends on show and nextShow.
// If nextShow is nil, we've overlapped with the end of the schedule, which doesn't need truncating.
func truncateOverlap(finish, nextStart time.Time, show, nextShow *myradio.Timeslot) time.Time {
	if nextShow == nil || !finish.After(nextStart) {
		return finish
	}

	// If the show starts after the next ends then there is no overlap
	if show.StartTime.After(nextStart.Add(nextShow.Duration)) {
		return finish
	}

	log.Println("Truncating" + show.Title)

	log.Printf(
		"Timeslot '%s', ID %d, finishing at %v overlaps with timeslot '%s', ID %d, starting at %v'",
		show.Title,
		show.TimeslotID,
		finish,
		nextShow.Title,
		nextShow.TimeslotID,
		nextStart,
	)

	return nextStart
}

// MakeScheduleSlice converts a slice of Timeslots to a slice of ScheduleItems.
// It does so by filling in any gaps between the start time and the first show, the final show and the finish time, and any two shows.
// Any overlaps are resolved by truncating the timeslot finish time, and dropping it if this makes the timeslot disappear.
// It expects a constructor function for lifting Timeslots (and overlap-adjusted finish times) to TimeslotItems.
// It will return an error if any two shows overlap.
// It presumes the timeslot slice is already sorted in chronological order.
func MakeScheduleSlice(c structs.SustainerConfig, start, finish time.Time, slots []myradio.Timeslot, tbuilder func(*myradio.Timeslot, time.Time) (*ScheduleItem, error)) ([]*ScheduleItem, error) {
	nslots := len(slots)
	if nslots == 0 {
		return []*ScheduleItem{NewSustainerItem(c, start, finish)}, nil
	}

	s := newScheduleBuilder(c, tbuilder, nslots)
	s.fill(start, slots[0].StartTime)

	// Now, if possible, start filling between.
	var show, nextShow *myradio.Timeslot
	for i := range slots {
		show = &slots[i]
		rawShowFinish := show.StartTime.Add(show.Duration)

		var nextStart time.Time
		// Is the next start another show, or the end of the schedule?
		if i < nslots-1 {
			nextShow = &slots[i+1]
			nextStart = nextShow.StartTime
		} else {
			nextShow = nil
			nextStart = finish
		}

		showFinish := truncateOverlap(rawShowFinish, nextStart, show, nextShow)
		s.addTimeslot(show, showFinish)
		s.fill(showFinish, nextStart)
	}

	return s.schedule()
}
<commit_msg>Fixed whitespace<commit_after>package models

import (
	"errors"
	"log"
	"net/url"
	"strings"
	"time"

	"github.com/UniversityRadioYork/2016-site/structs"
	"github.com/UniversityRadioYork/myradio-go"
)

// ScheduleItem contains information about one item in a URY schedule.
type ScheduleItem struct {
	// Name is the display name of the schedule item.
	Name string

	// Desc is the description of the schedule item.
	Desc string

	// Start is the start time of the schedule item.
	Start time.Time

	// Finish is the finish time of the schedule item.
	Finish time.Time

	// Block is the block name of the schedule item.
	Block string

	// PageURL is the root-relative URL to this schedule item's page,
	// or "" if there is no URL.
	PageURL string
}

// IsSustainer checks whether this schedule item is the URY sustainer.
func (s *ScheduleItem) IsSustainer() bool {
	return s.Block == "sustainer"
}

// NewSustainerItem creates a new sustainer schedule item lasting from start to finish.
// It takes a sustainer config, c, to work out the sustainer name.
func NewSustainerItem(c structs.SustainerConfig, start, finish time.Time) *ScheduleItem {
	return &ScheduleItem{
		Name:    c.Name,
		Desc:    c.Desc,
		Start:   start,
		Finish:  finish,
		Block:   "sustainer",
		PageURL: "",
	}
}

// NewTimeslotItem converts a myradio.Timeslot into a TimeslotItem.
// It accepts a separate finish time to account for any truncating that occurs when resolving overlaps.
func NewTimeslotItem(t *myradio.Timeslot, finish time.Time, u func(*myradio.Timeslot) (*url.URL, error)) (*ScheduleItem, error) {
	if t == nil {
		return nil, errors.New("NewTimeslotItem: given nil timeslot")
	}

	url, err := u(t)
	if err != nil {
		return nil, err
	}
	return &ScheduleItem{
		Name:    t.Title,
		Desc:    t.Description,
		Start:   t.StartTime,
		Finish:  finish,
		Block:   getBlock(t.Title, t.StartTime),
		PageURL: url.Path,
	}, nil
}

func getBlock(name string, StartTime time.Time) string {
	name = strings.ToLower(name)

	type blockMatch struct {
		nameFragment string
		block        string
	}
	var blockMatches = []blockMatch{
		{"ury: early morning", "primetime"},
		{"ury breakfast", "primetime"},
		{"ury lunch", "primetime"},
		{"ury brunch", "primetime"},
		{"URY Brunch", "primetime"},
		{"URY Afternoon Tea:", "primetime"},
		{"URY:PM", "primetime"},
		{"Alumni Takeover:", "primetime"},

		{"ury news", "news"},
		{"ury sports", "news"},
		{"ury football", "news"},
		{"york sport report", "news"},
		{"university radio talk", "news"},
		{"candidate interview night", "news"},
		{"election results night", "news"},
		{"yusu election", "news"},
		{"The Second Half With Josh Kerr", "news"},
		{"URY SPORT", "news"},
		{"URY News & Sport:", "news"},

		{"ury speech", "speech"},
		{"yorworld", "speech"},
		{"in the stalls", "speech"},
		{"screen", "speech"},
		{"stage", "speech"},
		{"game breaking", "speech"},
		{"radio drama", "speech"},
		{"Book Corner", "speech"},
		{"Saturated Facts", "speech"},
		{"URWatch", "speech"},
		{"Society Challenge", "speech"},
		{"Speech Showcase", "speech"},
		{"URY Speech:", "speech"},

		{"URY Music:", "music"},

		{"roses live 20", "event"},
		{"roses 20", "event"},
    {"freshers 20", "event"},
		{"woodstock", "event"},
		{"movember", "event"},
		{"panto", "event"},
		{"101:", "event"},
		{"Vanbrugh Chair Debate", "event"},
		{"URY Does RAG Courtyard Takeover", "event"},
		{"URY Presents", "event"},
		{"URYOnTour", "event"},
		{"URY On Tour", "event"},

		{"YSTV", "collab"},
		{"Nouse", "collab"},
		{"York Politics Digest", "collab"},
	}
	for _, bm := range blockMatches {
		if strings.Contains(name, strings.ToLower(bm.nameFragment)) {
			return bm.block
		}
	}
	// certain times of the day correspond to a specific show type.
	if (StartTime.Hour() == 11) || (StartTime.Hour() == 19) { // missed flagship
		return "primetime"
	}
	return "regular"
}

// scheduleBuilder is an internal type holding information about a schedule slice under construction.
type scheduleBuilder struct {
	// config is the sustainer config to use when creating sustainer slots.
	config structs.SustainerConfig
	// slice is the schedule slice being constructed.
	items []*ScheduleItem
	// nitems is the number of items currently inside the schedule.
	nitems int
	// tbuilder is the function used to create schedule items from timeslots.
	tbuilder func(*myradio.Timeslot, time.Time) (*ScheduleItem, error)
	// err stores any error caused while building the schedule.
	err error
}

// newScheduleBuilder creates an empty schedule builder for nslots shows, given config c and builder tbuilder.
func newScheduleBuilder(c structs.SustainerConfig, tbuilder func(*myradio.Timeslot, time.Time) (*ScheduleItem, error), nslots int) *scheduleBuilder {
	return &scheduleBuilder{
		config: c,
		// nslots slots, (nslots - 1) sustainers in between, and 2 sustainers at the ends.
		items:    make([]*ScheduleItem, ((2 * nslots) + 1)),
		nitems:   0,
		tbuilder: tbuilder,
		err:      nil,
	}
}

// add adds an item to the scheduleBuilder s.
func (s *scheduleBuilder) add(i *ScheduleItem) {
	s.items[s.nitems] = i
	s.nitems++
}

// fill adds a sustainer timeslot between start and finish into the scheduleBuilder s if one needs to be there.
func (s *scheduleBuilder) fill(start, finish time.Time) {
	if start.Before(finish) {
		s.add(NewSustainerItem(s.config, start, finish))
	}
}

// addTimeslot converts a timeslot t to a schedule item, then adds it to the scheduleBuilder s.
// It takes an overlap-adjusted finish, and does not add an item if this adjustment causes t to disappear.
func (s *scheduleBuilder) addTimeslot(t *myradio.Timeslot, finish time.Time) {
	if s.err != nil || !t.StartTime.Before(finish) {
		return
	}

	var ts *ScheduleItem
	if ts, s.err = s.tbuilder(t, finish); s.err != nil {
		return
	}

	s.add(ts)
}

// schedule gets the schedule from a scheduleBuilder, or an err if schedule building failed.
func (s *scheduleBuilder) schedule() ([]*ScheduleItem, error) {
	if s.err != nil {
		return nil, s.err
	}
	return s.items[:s.nitems], nil
}

// truncateOverlap clips finish to nextStart if the two overlap and nextShow exists.
// If so, we log an overlap warning, whose content depends on show and nextShow.
// If nextShow is nil, we've overlapped with the end of the schedule, which doesn't need truncating.
func truncateOverlap(finish, nextStart time.Time, show, nextShow *myradio.Timeslot) time.Time {
	if nextShow == nil || !finish.After(nextStart) {
		return finish
	}

	// If the show starts after the next ends then there is no overlap
	if show.StartTime.After(nextStart.Add(nextShow.Duration)) {
		return finish
	}

	log.Println("Truncating" + show.Title)

	log.Printf(
		"Timeslot '%s', ID %d, finishing at %v overlaps with timeslot '%s', ID %d, starting at %v'",
		show.Title,
		show.TimeslotID,
		finish,
		nextShow.Title,
		nextShow.TimeslotID,
		nextStart,
	)

	return nextStart
}

// MakeScheduleSlice converts a slice of Timeslots to a slice of ScheduleItems.
// It does so by filling in any gaps between the start time and the first show, the final show and the finish time, and any two shows.
// Any overlaps are resolved by truncating the timeslot finish time, and dropping it if this makes the timeslot disappear.
// It expects a constructor function for lifting Timeslots (and overlap-adjusted finish times) to TimeslotItems.
// It will return an error if any two shows overlap.
// It presumes the timeslot slice is already sorted in chronological order.
func MakeScheduleSlice(c structs.SustainerConfig, start, finish time.Time, slots []myradio.Timeslot, tbuilder func(*myradio.Timeslot, time.Time) (*ScheduleItem, error)) ([]*ScheduleItem, error) {
	nslots := len(slots)
	if nslots == 0 {
		return []*ScheduleItem{NewSustainerItem(c, start, finish)}, nil
	}

	s := newScheduleBuilder(c, tbuilder, nslots)
	s.fill(start, slots[0].StartTime)

	// Now, if possible, start filling between.
	var show, nextShow *myradio.Timeslot
	for i := range slots {
		show = &slots[i]
		rawShowFinish := show.StartTime.Add(show.Duration)

		var nextStart time.Time
		// Is the next start another show, or the end of the schedule?
		if i < nslots-1 {
			nextShow = &slots[i+1]
			nextStart = nextShow.StartTime
		} else {
			nextShow = nil
			nextStart = finish
		}

		showFinish := truncateOverlap(rawShowFinish, nextStart, show, nextShow)
		s.addTimeslot(show, showFinish)
		s.fill(showFinish, nextStart)
	}

	return s.schedule()
}
<|endoftext|>


<commit_before>package concurrency

import (
	"fmt"
	"sync"
	"time"

	"github.com/heqzha/goutils/container"
)

type WorkQueue struct {
	q         chan WorkRequest
	maxLength int
}

func (w *WorkQueue) push(work WorkRequest) error {
	if len(w.q) >= w.maxLength {
		return fmt.Errorf("WorkQueue is full, cannot add more works.")
	}
	w.q <- work
	return nil
}

func (w *WorkQueue) isFull() bool {
	return len(w.q) >= w.maxLength
}

func (w *WorkQueue) isEmpty() bool {
	return len(w.q) == 0
}

type WorkRequest struct {
	f      func(interface{}) interface{}
	params interface{}
	delay  time.Duration
	output chan interface{}
}

type Worker struct {
	ID   int
	Work chan WorkRequest
	Quit chan bool
}

func newWorker(id int) Worker {
	worker := Worker{
		ID:   id,
		Work: make(chan WorkRequest),
		Quit: make(chan bool),
	}
	return worker
}

func (w *Worker) Start() {
	go func() {
		for {
			select {
			case work := <-w.Work:
				//Work
				if work.output != nil {
					work.output <- work.f(work.params)
				} else {
					work.f(work.params)
				}
				time.Sleep(work.delay)
			case <-w.Quit:
				return
			}
		}
	}()
}

func (w *Worker) Stop() {
	go func() {
		w.Quit <- true
	}()
}

type WorkersPool struct {
	container.Queue
	workQ *WorkQueue
	Quit  chan bool
	mutex *sync.Mutex
}

func newWorkQueue(max int) *WorkQueue {
	return &WorkQueue{
		q:         make(chan WorkRequest, max),
		maxLength: max,
	}
}

func (wp *WorkersPool) Start(nWorkers int, maxBuffer int) {
	wp.Clear()
	wp.Quit = make(chan bool)
	wp.workQ = newWorkQueue(maxBuffer)
	wp.mutex = &sync.Mutex{}

	for i := 0; i < nWorkers; i++ {
		worker := newWorker(i)
		worker.Start()
		wp.Push(&worker)
	}

	go func() {
		for {
			select {
			case work := <-wp.workQ.q:
				go func() {
					wp.mutex.Lock()
					worker := wp.Pop().(*Worker)
					worker.Work <- work
					wp.Push(worker)
					wp.mutex.Unlock()
				}()
			case <-wp.Quit:
				return
			}
		}
	}()
}

func (wp *WorkersPool) Collect(f func(interface{}) interface{}, params interface{}, delay time.Duration) error {
	if wp.workQ == nil {
		return fmt.Errorf("WorkQueue is nil.")
	}
	work := WorkRequest{
		f:      f,
		params: params,
		delay:  delay,
		output: nil,
	}
	return wp.workQ.push(work)
}

func (wp *WorkersPool) CollectWithOutput(f func(interface{}) interface{}, params interface{}, delay time.Duration, output chan interface{}) error {
	if wp.workQ == nil {
		return fmt.Errorf("WorkQueue is nil.")
	}
	work := WorkRequest{
		f:      f,
		params: params,
		delay:  delay,
		output: output,
	}
	return wp.workQ.push(work)
}

func (wp *WorkersPool) Stop() {
	for wp.Len() > 0 {
		w := wp.Pop().(*Worker)
		w.Stop()
	}
	wp.Quit <- true
}

func (wp *WorkersPool) IsFull() bool {
	return wp.workQ.isFull()
}

func (wp *WorkersPool) IsEmpty() bool {
	return wp.workQ.isEmpty()
}
<commit_msg>Fixed loss tasks bug<commit_after>package concurrency

import (
	"fmt"
	"sync"
	"time"

	"github.com/heqzha/goutils/container"
)

type WorkQueue struct {
	q         chan WorkRequest
	maxLength int
}

func newWorkQueue(max int) *WorkQueue {
	return &WorkQueue{
		q:         make(chan WorkRequest, max),
		maxLength: max,
	}
}

func (w *WorkQueue) push(work WorkRequest) error {
	if len(w.q) >= w.maxLength {
		return fmt.Errorf("WorkQueue is full, cannot add more works.")
	}
	w.q <- work
	return nil
}

func (w *WorkQueue) isFull() bool {
	return len(w.q) >= w.maxLength
}

func (w *WorkQueue) isEmpty() bool {
	return len(w.q) == 0
}

type WorkRequest struct {
	f      func(interface{}) interface{}
	params interface{}
	delay  time.Duration
	output chan interface{}
}

type Worker struct {
	ID   int
	Work *WorkQueue
	Quit chan bool
}

func newWorker(id int, max int) Worker {
	worker := Worker{
		ID:   id,
		Work: newWorkQueue(max),
		Quit: make(chan bool),
	}
	return worker
}

func (w *Worker) Start() {
	go func() {
		for {
			select {
			case work := <-w.Work.q:
				//Work
				if work.output != nil {
					work.output <- work.f(work.params)
				} else {
					work.f(work.params)
				}
				time.Sleep(work.delay)
			case <-w.Quit:
				return
			}
		}
	}()
}

func (w *Worker) Stop() {
	go func() {
		w.Quit <- true
	}()
}

type WorkersPool struct {
	container.Queue
	workQ *WorkQueue
	Quit  chan bool
	mutex *sync.Mutex
}

func (wp *WorkersPool) Start(nWorkers int, maxBuffer int) {
	wp.Clear()
	wp.Quit = make(chan bool)
	wp.workQ = newWorkQueue(maxBuffer)
	wp.mutex = &sync.Mutex{}

	for i := 0; i < nWorkers; i++ {
		worker := newWorker(i, maxBuffer)
		worker.Start()
		wp.Push(&worker)
	}

	go func() {
		for {
			select {
			case work := <-wp.workQ.q:
				go func() {
					wp.mutex.Lock()
					worker := wp.Pop().(*Worker)
					worker.Work.q <- work
					wp.Push(worker)
					wp.mutex.Unlock()
				}()
			case <-wp.Quit:
				return
			}
		}
	}()
}

func (wp *WorkersPool) Collect(f func(interface{}) interface{}, params interface{}, delay time.Duration) error {
	if wp.workQ == nil {
		return fmt.Errorf("WorkQueue is nil.")
	}
	work := WorkRequest{
		f:      f,
		params: params,
		delay:  delay,
		output: nil,
	}
	return wp.workQ.push(work)
}

func (wp *WorkersPool) CollectWithOutput(f func(interface{}) interface{}, params interface{}, delay time.Duration, output chan interface{}) error {
	if wp.workQ == nil {
		return fmt.Errorf("WorkQueue is nil.")
	}
	work := WorkRequest{
		f:      f,
		params: params,
		delay:  delay,
		output: output,
	}
	return wp.workQ.push(work)
}

func (wp *WorkersPool) Stop() {
	for wp.Len() > 0 {
		w := wp.Pop().(*Worker)
		w.Stop()
	}
	wp.Quit <- true
}

func (wp *WorkersPool) IsFull() bool {
	return wp.workQ.isFull()
}

func (wp *WorkersPool) IsEmpty() bool {
	return wp.workQ.isEmpty()
}
<|endoftext|>


<commit_before>package matchers

import (
	"fmt"
	"strings"

	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/onsi/gomega"
)

type SliceMatcher struct {
	expected      [][]string
	failedAtIndex int
}

func ContainSubstrings(substrings ...[]string) gomega.OmegaMatcher {
	return &SliceMatcher{expected: substrings}
}

//func (matcher *SliceMatcher) Match(actual interface{}) (success bool, err error) {
//	actualStrings, ok := actual.([]string)
//	if !ok {
//		return false, nil
//	}
//
//	matcher.failedAtIndex = 0
//	for _, actualValue := range actualStrings {
//		allStringsFound := true
//		for _, expectedValue := range matcher.expected[matcher.failedAtIndex] {
//			allStringsFound = allStringsFound && strings.Contains(terminal.Decolorize(actualValue), expectedValue)
//		}
//
//		if allStringsFound {
//			matcher.failedAtIndex++
//			if matcher.failedAtIndex == len(matcher.expected) {
//				matcher.failedAtIndex--
//				return true, nil
//			}
//		}
//	}
//
//	return false, nil
//}

func (matcher *SliceMatcher) Match(actual interface{}) (success bool, err error) {
	actualStrings, ok := actual.([]string)
	if !ok {
		return false, nil
	}

	allStringsMatched := make([]bool, len(matcher.expected))

	for index, expectedArray := range matcher.expected {
		for _, actualValue := range actualStrings {

			allStringsFound := true

			for _, expectedValue := range expectedArray {
				allStringsFound = allStringsFound && strings.Contains(terminal.Decolorize(actualValue), expectedValue)
			}

			if allStringsFound {
				allStringsMatched[index] = true
				break
			}
		}
	}

	for index, value := range allStringsMatched {
		if !value {
			matcher.failedAtIndex = index
			return false, nil
		}
	}

	return true, nil
}

func (matcher *SliceMatcher) FailureMessage(actual interface{}) string {
	actualStrings, ok := actual.([]string)
	if !ok {
		return fmt.Sprintf("Expected actual to be a slice of strings, but it's actually a %T", actual)
	}

	return fmt.Sprintf("expected to find \"%s\" in actual:\n'%s'\n", matcher.expected[matcher.failedAtIndex], strings.Join(actualStrings, "\n"))
}

func (matcher *SliceMatcher) NegatedFailureMessage(actual interface{}) string {
	actualStrings, ok := actual.([]string)
	if !ok {
		return fmt.Sprintf("Expected actual to be a slice of strings, but it's actually a %T", actual)
	}
	return fmt.Sprintf("expected to not find \"%s\" in actual:\n'%s'\n", matcher.expected[matcher.failedAtIndex], strings.Join(actualStrings, "\n"))
}
<commit_msg>remove commented code<commit_after>package matchers

import (
	"fmt"
	"strings"

	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/onsi/gomega"
)

type SliceMatcher struct {
	expected      [][]string
	failedAtIndex int
}

func ContainSubstrings(substrings ...[]string) gomega.OmegaMatcher {
	return &SliceMatcher{expected: substrings}
}

func (matcher *SliceMatcher) Match(actual interface{}) (success bool, err error) {
	actualStrings, ok := actual.([]string)
	if !ok {
		return false, nil
	}

	allStringsMatched := make([]bool, len(matcher.expected))

	for index, expectedArray := range matcher.expected {
		for _, actualValue := range actualStrings {

			allStringsFound := true

			for _, expectedValue := range expectedArray {
				allStringsFound = allStringsFound && strings.Contains(terminal.Decolorize(actualValue), expectedValue)
			}

			if allStringsFound {
				allStringsMatched[index] = true
				break
			}
		}
	}

	for index, value := range allStringsMatched {
		if !value {
			matcher.failedAtIndex = index
			return false, nil
		}
	}

	return true, nil
}

func (matcher *SliceMatcher) FailureMessage(actual interface{}) string {
	actualStrings, ok := actual.([]string)
	if !ok {
		return fmt.Sprintf("Expected actual to be a slice of strings, but it's actually a %T", actual)
	}

	return fmt.Sprintf("expected to find \"%s\" in actual:\n'%s'\n", matcher.expected[matcher.failedAtIndex], strings.Join(actualStrings, "\n"))
}

func (matcher *SliceMatcher) NegatedFailureMessage(actual interface{}) string {
	actualStrings, ok := actual.([]string)
	if !ok {
		return fmt.Sprintf("Expected actual to be a slice of strings, but it's actually a %T", actual)
	}
	return fmt.Sprintf("expected to not find \"%s\" in actual:\n'%s'\n", matcher.expected[matcher.failedAtIndex], strings.Join(actualStrings, "\n"))
}
<|endoftext|>


<commit_before>package socket

import (
	"context"
	"errors"
	"fmt"
	"net/http"

	"github.com/go-ggz/ggz/helper"
	"github.com/go-ggz/ggz/router/middleware/auth0"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/googollee/go-socket.io"
	"github.com/sirupsen/logrus"
)

// Server for socket server
var Server *socketio.Server
var err error
var key = "user"

type A struct {
	A int    `json:"abc"`
	B string `json:"def"`
}

// NewEngine for socket server
func NewEngine() error {
	Server, err = socketio.NewServer(nil)
	if err != nil {
		logrus.Debugf("create socker server error: %s", err.Error())
		return err
	}

	Server.SetAllowRequest(func(r *http.Request) error {
		token := r.URL.Query().Get("token")

		if token == "" {
			return errors.New("Required authorization token not found")
		}

		parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
			return auth0.ParseRSAPublicKeyFromPEM()
		})

		if err != nil {
			return fmt.Errorf("Error parsing token: %v", err)
		}

		if jwt.SigningMethodHS256.Alg() != parsedToken.Header["alg"] {
			message := fmt.Sprintf("Expected %s signing method but token specified %s",
				jwt.SigningMethodHS256.Alg(),
				parsedToken.Header["alg"])
			return fmt.Errorf("Error validating token algorithm: %s", message)
		}

		if !parsedToken.Valid {
			return errors.New("Token is invalid")
		}

		// If we get here, everything worked and we can set the
		// user property in context.
		newRequest := r.WithContext(context.WithValue(r.Context(), key, parsedToken))
		// Update the current request with the new context information.
		*r = *newRequest

		return nil
	})

	Server.On("connection", func(so socketio.Socket) {
		user := helper.GetUserDataFromToken(so.Request().Context())
		room := user["email"].(string)
		logrus.Debugf("room is %s", room)
		so.Join(room)

		so.On("chat message", func(msg string) {
			logrus.Debugln("emit:", so.Emit("chat message", msg))
			so.BroadcastTo(room, "chat message", A{
				A: 1,
				B: "100",
			})
		})

		so.On("chat message with ack", func(msg string) string {
			return msg
		})

		so.On("disconnection", func() {
			logrus.Debugln("client disconnection")
		})
	})

	Server.On("error", func(so socketio.Socket, err error) {
		logrus.Debugf("socker server error: %s", err.Error())
	})

	return nil
}

// Handler initializes the prometheus middleware.
func Handler() gin.HandlerFunc {
	return func(c *gin.Context) {
		origin := c.GetHeader("Origin")
		c.Header("Access-Control-Allow-Credentials", "true")
		c.Header("Access-Control-Allow-Origin", origin)
		Server.ServeHTTP(c.Writer, c.Request)
	}
}
<commit_msg>fix golint.<commit_after>package socket

import (
	"context"
	"errors"
	"fmt"
	"net/http"

	"github.com/go-ggz/ggz/helper"
	"github.com/go-ggz/ggz/router/middleware/auth0"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/googollee/go-socket.io"
	"github.com/sirupsen/logrus"
)

// Server for socket server
var Server *socketio.Server
var err error
var key = "user"

// Test for testing websocket
type Test struct {
	A int    `json:"abc"`
	B string `json:"def"`
}

// NewEngine for socket server
func NewEngine() error {
	Server, err = socketio.NewServer(nil)
	if err != nil {
		logrus.Debugf("create socker server error: %s", err.Error())
		return err
	}

	Server.SetAllowRequest(func(r *http.Request) error {
		token := r.URL.Query().Get("token")

		if token == "" {
			return errors.New("Required authorization token not found")
		}

		parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
			return auth0.ParseRSAPublicKeyFromPEM()
		})

		if err != nil {
			return fmt.Errorf("Error parsing token: %v", err)
		}

		if jwt.SigningMethodHS256.Alg() != parsedToken.Header["alg"] {
			message := fmt.Sprintf("Expected %s signing method but token specified %s",
				jwt.SigningMethodHS256.Alg(),
				parsedToken.Header["alg"])
			return fmt.Errorf("Error validating token algorithm: %s", message)
		}

		if !parsedToken.Valid {
			return errors.New("Token is invalid")
		}

		// If we get here, everything worked and we can set the
		// user property in context.
		newRequest := r.WithContext(context.WithValue(r.Context(), key, parsedToken))
		// Update the current request with the new context information.
		*r = *newRequest

		return nil
	})

	Server.On("connection", func(so socketio.Socket) {
		user := helper.GetUserDataFromToken(so.Request().Context())
		room := user["email"].(string)
		logrus.Debugf("room is %s", room)
		so.Join(room)

		so.On("chat message", func(msg string) {
			logrus.Debugln("emit:", so.Emit("chat message", msg))
			so.BroadcastTo(room, "chat message", Test{
				A: 1,
				B: "100",
			})
		})

		so.On("chat message with ack", func(msg string) string {
			return msg
		})

		so.On("disconnection", func() {
			logrus.Debugln("client disconnection")
		})
	})

	Server.On("error", func(so socketio.Socket, err error) {
		logrus.Debugf("socker server error: %s", err.Error())
	})

	return nil
}

// Handler initializes the prometheus middleware.
func Handler() gin.HandlerFunc {
	return func(c *gin.Context) {
		origin := c.GetHeader("Origin")
		c.Header("Access-Control-Allow-Credentials", "true")
		c.Header("Access-Control-Allow-Origin", origin)
		Server.ServeHTTP(c.Writer, c.Request)
	}
}
<|endoftext|>