<commit_before>package api

import (
	"errors"

	"github.com/leancloud/lean-cli/api/regions"
	"github.com/levigross/grequests"
)

// GetAppListResult is GetAppList function's result type
type GetAppListResult struct {
	AppID     string `json:"app_id"`
	AppKey    string `json:"app_key"`
	AppName   string `json:"app_name"`
	MasterKey string `json:"master_key"`
	AppDomain string `json:"app_domain"`
}

// GetAppList returns the current user's all LeanCloud application
// this will also update the app router cache
func GetAppList(region regions.Region) ([]*GetAppListResult, error) {
	client := NewClient(region)

	resp, err := client.get("/1/clients/self/apps", nil)
	if err != nil {
		return nil, err
	}

	var result []*GetAppListResult
	err = resp.JSON(&result)
	if err != nil {
		return nil, err
	}

	for _, app := range result {
		routerCache[app.AppID] = region
	}
	if err = saveRouterCache(); err != nil {
		return nil, err
	}

	return result, nil
}

func deploy(appID string, group string, prod int, params map[string]interface{}) (*grequests.Response, error) {
	region, err := GetAppRegion(appID)
	if err != nil {
		return nil, err
	}
	client := NewClient(region)

	opts, err := client.options()
	if err != nil {
		return nil, err
	}
	opts.Headers["X-LC-Id"] = appID

	var url string
	switch prod {
	case 0:
		url = "/1.1/engine/groups/" + group + "/stagingImage"
	case 1:
		url = "/1.1/engine/groups/" + group + "/productionImage"
	default:
		return nil, errors.New("invalid prod value " + string(prod))
	}

	return client.post(url, params, opts)
}

// DeployImage will deploy the engine group with specify image tag
func DeployImage(appID string, group string, prod int, imageTag string) (string, error) {
	params := map[string]interface{}{
		"imageTag": imageTag,
		"async":    true,
	}
	resp, err := deploy(appID, group, prod, params)
	if err != nil {
		return "", err
	}
	result := new(struct {
		EventToken string `json:"eventToken"`
	})
	err = resp.JSON(result)
	return result.EventToken, err
}

// DeployAppFromGit will deploy applications with user's git repo
// returns the event token for polling deploy log
func DeployAppFromGit(appID string, group string, prod int, revision string, noDepsCache bool) (string, error) {
	params := map[string]interface{}{
		"noDependenciesCache": noDepsCache,
		"async":               true,
		"gitTag":              revision,
	}
	resp, err := deploy(appID, group, prod, params)
	if err != nil {
		return "", err
	}
	result := new(struct {
		EventToken string `json:"eventToken"`
	})
	err = resp.JSON(result)
	return result.EventToken, err
}

// DeployAppFromFile will deploy applications with specific file
// returns the event token for polling deploy log
func DeployAppFromFile(appID string, group string, prod int, fileURL string, message string, noDepsCache bool) (string, error) {
	params := map[string]interface{}{
		"zipUrl":              fileURL,
		"comment":             message,
		"noDependenciesCache": noDepsCache,
		"async":               true,
	}
	resp, err := deploy(appID, group, prod, params)
	if err != nil {
		return "", err
	}

	result := new(struct {
		EventToken string `json:"eventToken"`
	})
	err = resp.JSON(result)
	return result.EventToken, err
}

// GetAppInfoResult is GetAppInfo function's result type
type GetAppInfoResult struct {
	AppDomain string `json:"app_domain"`
	AppID     string `json:"app_id"`
	AppKey    string `json:"app_key"`
	AppName   string `json:"app_name"`
	HookKey   string `json:"hook_key"`
	MasterKey string `json:"master_key"`
}

// GetAppInfo returns the application's detail info
func GetAppInfo(appID string) (*GetAppInfoResult, error) {
	region, err := GetAppRegion(appID)
	if err != nil {
		return nil, err
	}
	client := NewClient(region)

	resp, err := client.get("/1.1/clients/self/apps/"+appID, nil)
	if err != nil {
		return nil, err
	}
	result := new(GetAppInfoResult)
	err = resp.JSON(result)
	return result, err
}

// GetGroupsResult is GetGroups's result struct
type GetGroupsResult struct {
	GroupName  string `json:"groupName"`
	Repository string `json:"repository"`
	Instances  []struct {
		Name  string `json:"name"`
		Quota int    `json:"quota"`
	} `json:"instances"`
	StagingImage struct {
		Runtime  string `json:"runtime"`
		ImageTag string `json:"imageTag"`
	} `json:"stagingImage"`
	Environments map[string]string `json:"environments"`
}

// GetGroups returns the application's engine groups
func GetGroups(appID string) ([]*GetGroupsResult, error) {
	region, err := GetAppRegion(appID)
	if err != nil {
		return nil, err
	}
	client := NewClient(region)

	opts, err := client.options()
	if err != nil {
		return nil, err
	}
	opts.Headers["X-LC-Id"] = appID

	resp, err := client.get("/1.1/engine/groups", opts)
	if err != nil {
		return nil, err
	}

	var result []*GetGroupsResult
	err = resp.JSON(&result)
	if err != nil {
		return nil, err
	}

	// filter the staging group, since it's not used anymore
	var filtered []*GetGroupsResult
	for _, group := range result {
		if group.GroupName == "staging" {
			continue
		}
		filtered = append(filtered, group)
	}

	return filtered, nil
}

// GetGroup will fetch all groups from API and return the current group info
func GetGroup(appID string, groupName string) (*GetGroupsResult, error) {
	groups, err := GetGroups(appID)
	if err != nil {
		return nil, err
	}
	for _, group := range groups {
		if group.GroupName == groupName {
			return group, nil
		}
	}
	return nil, errors.New("找不到分组：" + groupName)
}

type GetEngineInfoResult struct {
	AppID         string            `json:"appId"`
	Mode          string            `json:"mode"`
	InstanceLimit int               `json:"instanceLimit"`
	Version       string            `json:"version"`
	Environments  map[string]string `json:"environments"`
}

func GetEngineInfo(appID string) (*GetEngineInfoResult, error) {
	region, err := GetAppRegion(appID)
	if err != nil {
		return nil, err
	}
	client := NewClient(region)

	opts, err := client.options()
	if err != nil {
		return nil, err
	}
	opts.Headers["X-LC-Id"] = appID

	response, err := client.get("/1.1/functions/_ops/engine", opts)
	if err != nil {
		return nil, err
	}
	var result = new(GetEngineInfoResult)
	err = response.JSON(result)
	return result, err
}

func PutEnvironments(appID string, group string, envs map[string]string) error {
	region, err := GetAppRegion(appID)
	if err != nil {
		return err
	}
	client := NewClient(region)

	opts, err := client.options()
	if err != nil {
		return err
	}
	opts.Headers["X-LC-Id"] = appID

	params := make(map[string]interface{})
	environments := make(map[string]interface{})
	for k, v := range envs {
		environments[k] = v
	}
	params["environments"] = environments

	url := "/1.1/engine/groups/" + group
	response, err := client.patch(url, params, opts)
	if err != nil {
		return err
	}
	if response.StatusCode != 200 {
		return errors.New("更新运引擎环境变量失败，响应码：" + string(response.StatusCode))
	}
	return nil
}
<commit_msg>:alien: change engien api endpoint<commit_after>package api

import (
	"errors"

	"github.com/leancloud/lean-cli/api/regions"
	"github.com/levigross/grequests"
)

// GetAppListResult is GetAppList function's result type
type GetAppListResult struct {
	AppID     string `json:"app_id"`
	AppKey    string `json:"app_key"`
	AppName   string `json:"app_name"`
	MasterKey string `json:"master_key"`
	AppDomain string `json:"app_domain"`
}

// GetAppList returns the current user's all LeanCloud application
// this will also update the app router cache
func GetAppList(region regions.Region) ([]*GetAppListResult, error) {
	client := NewClient(region)

	resp, err := client.get("/1/clients/self/apps", nil)
	if err != nil {
		return nil, err
	}

	var result []*GetAppListResult
	err = resp.JSON(&result)
	if err != nil {
		return nil, err
	}

	for _, app := range result {
		routerCache[app.AppID] = region
	}
	if err = saveRouterCache(); err != nil {
		return nil, err
	}

	return result, nil
}

func deploy(appID string, group string, prod int, params map[string]interface{}) (*grequests.Response, error) {
	region, err := GetAppRegion(appID)
	if err != nil {
		return nil, err
	}
	client := NewClient(region)

	opts, err := client.options()
	if err != nil {
		return nil, err
	}
	opts.Headers["X-LC-Id"] = appID

	var url string
	switch prod {
	case 0:
		url = "/1.1/engine/groups/" + group + "/stagingImage"
	case 1:
		url = "/1.1/engine/groups/" + group + "/productionImage"
	default:
		return nil, errors.New("invalid prod value " + string(prod))
	}

	return client.post(url, params, opts)
}

// DeployImage will deploy the engine group with specify image tag
func DeployImage(appID string, group string, prod int, imageTag string) (string, error) {
	params := map[string]interface{}{
		"imageTag": imageTag,
		"async":    true,
	}
	resp, err := deploy(appID, group, prod, params)
	if err != nil {
		return "", err
	}
	result := new(struct {
		EventToken string `json:"eventToken"`
	})
	err = resp.JSON(result)
	return result.EventToken, err
}

// DeployAppFromGit will deploy applications with user's git repo
// returns the event token for polling deploy log
func DeployAppFromGit(appID string, group string, prod int, revision string, noDepsCache bool) (string, error) {
	params := map[string]interface{}{
		"noDependenciesCache": noDepsCache,
		"async":               true,
		"gitTag":              revision,
	}
	resp, err := deploy(appID, group, prod, params)
	if err != nil {
		return "", err
	}
	result := new(struct {
		EventToken string `json:"eventToken"`
	})
	err = resp.JSON(result)
	return result.EventToken, err
}

// DeployAppFromFile will deploy applications with specific file
// returns the event token for polling deploy log
func DeployAppFromFile(appID string, group string, prod int, fileURL string, message string, noDepsCache bool) (string, error) {
	params := map[string]interface{}{
		"zipUrl":              fileURL,
		"comment":             message,
		"noDependenciesCache": noDepsCache,
		"async":               true,
	}
	resp, err := deploy(appID, group, prod, params)
	if err != nil {
		return "", err
	}

	result := new(struct {
		EventToken string `json:"eventToken"`
	})
	err = resp.JSON(result)
	return result.EventToken, err
}

// GetAppInfoResult is GetAppInfo function's result type
type GetAppInfoResult struct {
	AppDomain string `json:"app_domain"`
	AppID     string `json:"app_id"`
	AppKey    string `json:"app_key"`
	AppName   string `json:"app_name"`
	HookKey   string `json:"hook_key"`
	MasterKey string `json:"master_key"`
}

// GetAppInfo returns the application's detail info
func GetAppInfo(appID string) (*GetAppInfoResult, error) {
	region, err := GetAppRegion(appID)
	if err != nil {
		return nil, err
	}
	client := NewClient(region)

	resp, err := client.get("/1.1/clients/self/apps/"+appID, nil)
	if err != nil {
		return nil, err
	}
	result := new(GetAppInfoResult)
	err = resp.JSON(result)
	return result, err
}

// GetGroupsResult is GetGroups's result struct
type GetGroupsResult struct {
	GroupName  string `json:"groupName"`
	Repository string `json:"repository"`
	Instances  []struct {
		Name  string `json:"name"`
		Quota int    `json:"quota"`
	} `json:"instances"`
	StagingImage struct {
		Runtime  string `json:"runtime"`
		ImageTag string `json:"imageTag"`
	} `json:"stagingImage"`
	Environments map[string]string `json:"environments"`
}

// GetGroups returns the application's engine groups
func GetGroups(appID string) ([]*GetGroupsResult, error) {
	region, err := GetAppRegion(appID)
	if err != nil {
		return nil, err
	}
	client := NewClient(region)

	opts, err := client.options()
	if err != nil {
		return nil, err
	}
	opts.Headers["X-LC-Id"] = appID

	resp, err := client.get("/1.1/engine/groups", opts)
	if err != nil {
		return nil, err
	}

	var result []*GetGroupsResult
	err = resp.JSON(&result)
	if err != nil {
		return nil, err
	}

	// filter the staging group, since it's not used anymore
	var filtered []*GetGroupsResult
	for _, group := range result {
		if group.GroupName == "staging" {
			continue
		}
		filtered = append(filtered, group)
	}

	return filtered, nil
}

// GetGroup will fetch all groups from API and return the current group info
func GetGroup(appID string, groupName string) (*GetGroupsResult, error) {
	groups, err := GetGroups(appID)
	if err != nil {
		return nil, err
	}
	for _, group := range groups {
		if group.GroupName == groupName {
			return group, nil
		}
	}
	return nil, errors.New("找不到分组：" + groupName)
}

type GetEngineInfoResult struct {
	AppID         string            `json:"appId"`
	Mode          string            `json:"mode"`
	InstanceLimit int               `json:"instanceLimit"`
	Version       string            `json:"version"`
	Environments  map[string]string `json:"environments"`
}

func GetEngineInfo(appID string) (*GetEngineInfoResult, error) {
	region, err := GetAppRegion(appID)
	if err != nil {
		return nil, err
	}
	client := NewClient(region)

	opts, err := client.options()
	if err != nil {
		return nil, err
	}
	opts.Headers["X-LC-Id"] = appID

	response, err := client.get("/1.1/engine", opts)
	if err != nil {
		return nil, err
	}
	var result = new(GetEngineInfoResult)
	err = response.JSON(result)
	return result, err
}

func PutEnvironments(appID string, group string, envs map[string]string) error {
	region, err := GetAppRegion(appID)
	if err != nil {
		return err
	}
	client := NewClient(region)

	opts, err := client.options()
	if err != nil {
		return err
	}
	opts.Headers["X-LC-Id"] = appID

	params := make(map[string]interface{})
	environments := make(map[string]interface{})
	for k, v := range envs {
		environments[k] = v
	}
	params["environments"] = environments

	url := "/1.1/engine/groups/" + group
	response, err := client.patch(url, params, opts)
	if err != nil {
		return err
	}
	if response.StatusCode != 200 {
		return errors.New("更新运引擎环境变量失败，响应码：" + string(response.StatusCode))
	}
	return nil
}
<|endoftext|>


<commit_before>package broker

import (
	"github.com/travisjeffery/jocko"
	"github.com/travisjeffery/jocko/protocol"
	"github.com/travisjeffery/jocko/server"
)

type replicationManager struct {
	jocko.Broker
	replicators map[*jocko.Partition]*replicator
}

func newReplicationManager() *replicationManager {
	return &replicationManager{
		replicators: make(map[*jocko.Partition]*replicator),
	}
}

func (rm *replicationManager) BecomeFollower(topic string, pid int32, command *protocol.PartitionState) error {
	p, err := rm.Partition(topic, pid)
	if err != nil {
		return err
	}
	// stop replicator to current leader
	if r, ok := rm.replicators[p]; ok {
		if err := r.close(); err != nil {
			return err
		}
	}
	delete(rm.replicators, p)
	p.Leader = command.Leader
	hw := p.HighWatermark()
	if err := p.TruncateTo(hw); err != nil {
		return err
	}
	r := newReplicator(p, rm.ID(),
		ReplicatorProxy(server.NewProxy(p.Conn)))
	r.replicate()
	rm.replicators[p] = r
	return nil
}

func (rm *replicationManager) BecomeLeader(topic string, pid int32, command *protocol.PartitionState) error {
	p, err := rm.Partition(topic, pid)
	if err != nil {
		return err
	}
	if r, ok := rm.replicators[p]; ok {
		if err := r.close(); err != nil {
			return err
		}
	}
	p.Leader = rm.ID()
	p.ISR = command.ISR
	p.LeaderAndISRVersionInZK = command.ZKVersion
	return nil
}
<commit_msg>change partition conn when leader changes<commit_after>package broker

import (
	"github.com/travisjeffery/jocko"
	"github.com/travisjeffery/jocko/protocol"
	"github.com/travisjeffery/jocko/server"
)

type replicationManager struct {
	jocko.Broker
	replicators map[*jocko.Partition]*replicator
}

func newReplicationManager() *replicationManager {
	return &replicationManager{
		replicators: make(map[*jocko.Partition]*replicator),
	}
}

func (rm *replicationManager) BecomeFollower(topic string, pid int32, command *protocol.PartitionState) error {
	p, err := rm.Partition(topic, pid)
	if err != nil {
		return err
	}
	// stop replicator to current leader
	if r, ok := rm.replicators[p]; ok {
		if err := r.close(); err != nil {
			return err
		}
	}
	delete(rm.replicators, p)
	hw := p.HighWatermark()
	if err := p.TruncateTo(hw); err != nil {
		return err
	}
	p.Leader = command.Leader
	p.Conn = rm.ClusterMember(p.LeaderID())
	r := newReplicator(p, rm.ID(),
		ReplicatorProxy(server.NewProxy(p.Conn)))
	r.replicate()
	rm.replicators[p] = r
	return nil
}

func (rm *replicationManager) BecomeLeader(topic string, pid int32, command *protocol.PartitionState) error {
	p, err := rm.Partition(topic, pid)
	if err != nil {
		return err
	}
	if r, ok := rm.replicators[p]; ok {
		if err := r.close(); err != nil {
			return err
		}
	}
	p.Leader = rm.ID()
	p.Conn = rm.ClusterMember(p.LeaderID())
	p.ISR = command.ISR
	p.LeaderAndISRVersionInZK = command.ZKVersion
	return nil
}
<|endoftext|>


<commit_before>/*
Package web is a microframework inspired by Sinatra.

The underlying philosophy behind this package is that net/http is a very good
HTTP library which is only missing a few features. If you disagree with this
statement (e.g., you think that the interfaces it exposes are not especially
good, or if you're looking for a comprehensive "batteries included" feature
list), you're likely not going to have a good time using this library. In that
spirit, we have attempted wherever possible to be compatible with net/http. You
should be able to insert any net/http compliant handler into this library, or
use this library with any other net/http compliant mux.

This package attempts to solve three problems that net/http does not. First, it
allows you to specify URL patterns with Sinatra-like named wildcards and
regexps. Second, it allows you to write reconfigurable middleware stacks. And
finally, it allows you to attach additional context to requests, in a manner
that can be manipulated by both compliant middleware and handlers.

A usage example:

	m := web.New()

Use your favorite HTTP verbs:

	var legacyFooHttpHandler http.Handler // From elsewhere
	m.Get("/foo", legacyFooHttpHandler)
	m.Post("/bar", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello world!"))
	})

Bind parameters using either Sinatra-like patterns or regular expressions:

	m.Get("/hello/:name", func(c web.C, w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"])
	})
	pattern := regexp.MustCompile(`^/ip/(?P<ip>(?:\d{1,3}\.){3}\d{1,3})$`)
	m.Get(pattern, func(c web.C, w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Info for IP address %s:", c.URLParams["ip"])
	})

Middleware are functions that wrap http.Handlers, just like you'd use with raw
net/http. Middleware functions can optionally take a context parameter, which
will be threaded throughout the middleware stack and to the final handler, even
if not all of these things do not support contexts. Middleware are encouraged to
use the Env parameter to pass data to other middleware and to the final handler:

	m.Use(func(h http.Handler) http.Handler {
		handler := func(w http.ResponseWriter, r *http.Request) {
			log.Println("Before request")
			h.ServeHTTP(w, r)
			log.Println("After request")
		}
		return http.HandlerFunc(handler)
	})
	m.Use(func(c *web.C, h http.Handler) http.Handler {
		handler := func(w http.ResponseWriter, r *http.Request) {
			cookie, err := r.Cookie("user")
			if err == nil {
				// Consider using the middleware EnvInit instead
				// of repeating the below check
				if c.Env == nil {
					c.Env = make(map[string]interface{})
				}
				c.Env["user"] = cookie.Value
			}
			h.ServeHTTP(w, r)
		}
		return http.HandlerFunc(handler)
	})

	m.Get("/baz", func(c web.C, w http.ResponseWriter, r *http.Request) {
		if user, ok := c.Env["user"].(string); ok {
			w.Write([]byte("Hello " + user))
		} else {
			w.Write([]byte("Hello Stranger!"))
		}
	})
*/
package web

import (
	"net/http"
)

/*
C is a per-request context object which is threaded through all compliant middleware
layers and to the final request handler.

As an implementation detail, references to these structs are reused between
requests to reduce allocation churn, but the maps they contain are created fresh
on every request. If you are closing over a context (especially relevant for
middleware), you should not close over either the URLParams or Env objects,
instead accessing them through the context whenever they are required.
*/
type C struct {
	// The parameters parsed by the mux from the URL itself. In most cases,
	// will contain a map from programmer-specified identifiers to the
	// strings that matched those identifiers, but if a unnamed regex
	// capture is used, it will be assigned to the special identifiers "$1",
	// "$2", etc.
	URLParams map[string]string
	// A free-form environment, similar to Rack or PEP 333's environments.
	// Middleware layers are encouraged to pass data to downstream layers
	// and other handlers using this map, and are even more strongly
	// encouraged to document and maybe namespace they keys they use.
	Env map[string]interface{}
}

// Handler is a superset of net/http's http.Handler, which also includes a
// mechanism for serving requests with a context. If your handler does not
// support the use of contexts, we encourage you to use http.Handler instead.
type Handler interface {
	http.Handler
	ServeHTTPC(C, http.ResponseWriter, *http.Request)
}

// HandlerFunc is like net/http's http.HandlerFunc, but supports a context
// object. Implements both http.Handler and web.Handler free of charge.
type HandlerFunc func(C, http.ResponseWriter, *http.Request)

func (h HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h(C{}, w, r)
}

// ServeHTTPC wraps ServeHTTP with a context parameter.
func (h HandlerFunc) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request) {
	h(c, w, r)
}
<commit_msg>Minor documentation touch-ups<commit_after>/*
Package web implements a fast and flexible middleware stack and mux.

The underlying philosophy behind this package is that net/http is a very good
HTTP library which is only missing a few features. If you disagree with this
statement (e.g., you think that the interfaces it exposes are not especially
good, or if you're looking for a comprehensive "batteries included" feature
list), you're likely not going to have a good time using this library. In that
spirit, we have attempted wherever possible to be compatible with net/http. You
should be able to insert any net/http compliant handler into this library, or
use this library with any other net/http compliant mux.

This package attempts to solve three problems that net/http does not. First, it
allows you to specify URL patterns with Sinatra-like named wildcards and
regexps. Second, it allows you to write reconfigurable middleware stacks. And
finally, it allows you to attach additional context to requests, in a manner
that can be manipulated by both compliant middleware and handlers.

A usage example:

	m := web.New()

Use your favorite HTTP verbs:

	var legacyFooHttpHandler http.Handler // From elsewhere
	m.Get("/foo", legacyFooHttpHandler)
	m.Post("/bar", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello world!"))
	})

Bind parameters using either Sinatra-like patterns or regular expressions:

	m.Get("/hello/:name", func(c web.C, w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"])
	})
	pattern := regexp.MustCompile(`^/ip/(?P<ip>(?:\d{1,3}\.){3}\d{1,3})$`)
	m.Get(pattern, func(c web.C, w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Info for IP address %s:", c.URLParams["ip"])
	})

Middleware are functions that wrap http.Handlers, just like you'd use with raw
net/http. Middleware functions can optionally take a context parameter, which
will be threaded throughout the middleware stack and to the final handler, even
if not all of these things support contexts. Middleware are encouraged to use
the Env parameter to pass data to other middleware and to the final handler:

	m.Use(func(h http.Handler) http.Handler {
		handler := func(w http.ResponseWriter, r *http.Request) {
			log.Println("Before request")
			h.ServeHTTP(w, r)
			log.Println("After request")
		}
		return http.HandlerFunc(handler)
	})
	m.Use(func(c *web.C, h http.Handler) http.Handler {
		handler := func(w http.ResponseWriter, r *http.Request) {
			cookie, err := r.Cookie("user")
			if err == nil {
				// Consider using the middleware EnvInit instead
				// of repeating the below check
				if c.Env == nil {
					c.Env = make(map[string]interface{})
				}
				c.Env["user"] = cookie.Value
			}
			h.ServeHTTP(w, r)
		}
		return http.HandlerFunc(handler)
	})

	m.Get("/baz", func(c web.C, w http.ResponseWriter, r *http.Request) {
		if user, ok := c.Env["user"].(string); ok {
			w.Write([]byte("Hello " + user))
		} else {
			w.Write([]byte("Hello Stranger!"))
		}
	})
*/
package web

import (
	"net/http"
)

/*
C is a per-request context object which is threaded through all compliant middleware
layers and to the final request handler.

As an implementation detail, references to these structs are reused between
requests to reduce allocation churn, but the maps they contain are created fresh
on every request. If you are closing over a context (especially relevant for
middleware), you should not close over either the URLParams or Env objects,
instead accessing them through the context whenever they are required.
*/
type C struct {
	// The parameters parsed by the mux from the URL itself. In most cases,
	// will contain a map from programmer-specified identifiers to the
	// strings that matched those identifiers, but if a unnamed regex
	// capture is used, it will be assigned to the special identifiers "$1",
	// "$2", etc.
	URLParams map[string]string
	// A free-form environment, similar to Rack or PEP 333's environments.
	// Middleware layers are encouraged to pass data to downstream layers
	// and other handlers using this map, and are even more strongly
	// encouraged to document and maybe namespace they keys they use.
	Env map[string]interface{}
}

// Handler is a superset of net/http's http.Handler, which also includes a
// mechanism for serving requests with a context. If your handler does not
// support the use of contexts, we encourage you to use http.Handler instead.
type Handler interface {
	http.Handler
	ServeHTTPC(C, http.ResponseWriter, *http.Request)
}

// HandlerFunc is like net/http's http.HandlerFunc, but supports a context
// object. Implements both http.Handler and web.Handler free of charge.
type HandlerFunc func(C, http.ResponseWriter, *http.Request)

func (h HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h(C{}, w, r)
}

// ServeHTTPC wraps ServeHTTP with a context parameter.
func (h HandlerFunc) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request) {
	h(c, w, r)
}
<|endoftext|>


<commit_before>package smoke

import (
	"fmt"
	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
	"io"
	"net"
	"net/http"
	"strings"
	"sync"
)

var _ = Describe("Loggregator:", func() {
	var testConfig = GetConfig()
	var useExistingApp = (testConfig.LoggingApp != "")
	var appName string

	Describe("cf logs", func() {
		BeforeEach(func() {
			appName = testConfig.LoggingApp
			if !useExistingApp {
				appName = generator.RandomName()
				Expect(cf.Cf("push", appName, "-p", SIMPLE_RUBY_APP_BITS_PATH).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
		})

		AfterEach(func() {
			if !useExistingApp {
				Expect(cf.Cf("delete", appName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
		})

		It("can see app messages in the logs", func() {
			Eventually(func() *Session {
				appLogsSession := cf.Cf("logs", "--recent", appName)
				Expect(appLogsSession.Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
				return appLogsSession
			}, 5).Should(Say(`\[App/0\]`))
		})
	})

	Describe("Syslog drains", func() {
		var drainListener *syslogDrainListener
		var serviceName string
		var appUrl string

		BeforeEach(func() {
			syslogDrainAddress := fmt.Sprintf("%s:%d", testConfig.SyslogIpAddress, testConfig.SyslogDrainPort)

			drainListener = &syslogDrainListener{port: testConfig.SyslogDrainPort}
			drainListener.StartListener()
			go drainListener.AcceptConnections()

			// verify listener is reachable via configured public IP
			var conn net.Conn

			var err error
			conn, err = net.Dial("tcp", syslogDrainAddress)
			Expect(err).ToNot(HaveOccurred())

			defer conn.Close()

			randomMessage := "random-message-" + generator.RandomName()
			_, err = conn.Write([]byte(randomMessage))
			Expect(err).ToNot(HaveOccurred())

			Eventually(func() bool {
				return drainListener.DidReceive(randomMessage)
			}).Should(BeTrue())

			appName = generator.RandomName()
			appUrl = appName + "." + testConfig.AppsDomain
			Expect(cf.Cf("push", appName, "-p", SIMPLE_RUBY_APP_BITS_PATH).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))

			syslogDrainUrl := "syslog://" + syslogDrainAddress
			serviceName = "service-" + generator.RandomName()

			Expect(cf.Cf("cups", serviceName, "-l", syslogDrainUrl).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("bind-service", appName, serviceName).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("restage", appName).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
		})

		AfterEach(func() {
			Expect(cf.Cf("delete", appName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("delete-service", serviceName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))

			drainListener.Stop()
		})

		It("forwards app messages to registered syslog drains", func() {
			randomMessage := "random-message-" + generator.RandomName()
			http.Get("http://" + appUrl + "/log/" + randomMessage)

			Eventually(func() bool {
				return drainListener.DidReceive(randomMessage)
			}).Should(BeTrue())
		})
	})
})

type syslogDrainListener struct {
	sync.Mutex
	port             int
	listener         net.Listener
	receivedMessages string
}

func (s *syslogDrainListener) StartListener() {
	listenAddress := fmt.Sprintf(":%d", s.port)
	var err error
	s.listener, err = net.Listen("tcp", listenAddress)
	Expect(err).ToNot(HaveOccurred())
}

func (s *syslogDrainListener) AcceptConnections() {
	defer GinkgoRecover()

	for {
		conn, err := s.listener.Accept()
		if err != nil {
			return
		}
		go s.handleConnection(conn)
	}
}

func (s *syslogDrainListener) Stop() {
	s.listener.Close()
}

func (s *syslogDrainListener) DidReceive(message string) bool {
	s.Lock()
	defer s.Unlock()

	return strings.Contains(s.receivedMessages, message)
}

func (s *syslogDrainListener) handleConnection(conn net.Conn) {
	defer GinkgoRecover()
	buffer := make([]byte, 65536)
	for {
		n, err := conn.Read(buffer)

		if err == io.EOF {
			return
		}
		Expect(err).ToNot(HaveOccurred())

		s.Lock()
		s.receivedMessages += string(buffer[0:n])
		s.Unlock()
	}
}
<commit_msg>increase restage timeout to 5 minutes<commit_after>package smoke

import (
	"fmt"
	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
	"io"
	"net"
	"net/http"
	"strings"
	"sync"
)

var _ = Describe("Loggregator:", func() {
	var testConfig = GetConfig()
	var useExistingApp = (testConfig.LoggingApp != "")
	var appName string

	Describe("cf logs", func() {
		BeforeEach(func() {
			appName = testConfig.LoggingApp
			if !useExistingApp {
				appName = generator.RandomName()
				Expect(cf.Cf("push", appName, "-p", SIMPLE_RUBY_APP_BITS_PATH).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
		})

		AfterEach(func() {
			if !useExistingApp {
				Expect(cf.Cf("delete", appName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
		})

		It("can see app messages in the logs", func() {
			Eventually(func() *Session {
				appLogsSession := cf.Cf("logs", "--recent", appName)
				Expect(appLogsSession.Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
				return appLogsSession
			}, 5).Should(Say(`\[App/0\]`))
		})
	})

	Describe("Syslog drains", func() {
		var drainListener *syslogDrainListener
		var serviceName string
		var appUrl string

		BeforeEach(func() {
			syslogDrainAddress := fmt.Sprintf("%s:%d", testConfig.SyslogIpAddress, testConfig.SyslogDrainPort)

			drainListener = &syslogDrainListener{port: testConfig.SyslogDrainPort}
			drainListener.StartListener()
			go drainListener.AcceptConnections()

			// verify listener is reachable via configured public IP
			var conn net.Conn

			var err error
			conn, err = net.Dial("tcp", syslogDrainAddress)
			Expect(err).ToNot(HaveOccurred())

			defer conn.Close()

			randomMessage := "random-message-" + generator.RandomName()
			_, err = conn.Write([]byte(randomMessage))
			Expect(err).ToNot(HaveOccurred())

			Eventually(func() bool {
				return drainListener.DidReceive(randomMessage)
			}).Should(BeTrue())

			appName = generator.RandomName()
			appUrl = appName + "." + testConfig.AppsDomain
			Expect(cf.Cf("push", appName, "-p", SIMPLE_RUBY_APP_BITS_PATH).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))

			syslogDrainUrl := "syslog://" + syslogDrainAddress
			serviceName = "service-" + generator.RandomName()

			Expect(cf.Cf("cups", serviceName, "-l", syslogDrainUrl).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("bind-service", appName, serviceName).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("restage", appName).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))
		})

		AfterEach(func() {
			Expect(cf.Cf("delete", appName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("delete-service", serviceName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))

			drainListener.Stop()
		})

		It("forwards app messages to registered syslog drains", func() {
			randomMessage := "random-message-" + generator.RandomName()
			http.Get("http://" + appUrl + "/log/" + randomMessage)

			Eventually(func() bool {
				return drainListener.DidReceive(randomMessage)
			}).Should(BeTrue())
		})
	})
})

type syslogDrainListener struct {
	sync.Mutex
	port             int
	listener         net.Listener
	receivedMessages string
}

func (s *syslogDrainListener) StartListener() {
	listenAddress := fmt.Sprintf(":%d", s.port)
	var err error
	s.listener, err = net.Listen("tcp", listenAddress)
	Expect(err).ToNot(HaveOccurred())
}

func (s *syslogDrainListener) AcceptConnections() {
	defer GinkgoRecover()

	for {
		conn, err := s.listener.Accept()
		if err != nil {
			return
		}
		go s.handleConnection(conn)
	}
}

func (s *syslogDrainListener) Stop() {
	s.listener.Close()
}

func (s *syslogDrainListener) DidReceive(message string) bool {
	s.Lock()
	defer s.Unlock()

	return strings.Contains(s.receivedMessages, message)
}

func (s *syslogDrainListener) handleConnection(conn net.Conn) {
	defer GinkgoRecover()
	buffer := make([]byte, 65536)
	for {
		n, err := conn.Read(buffer)

		if err == io.EOF {
			return
		}
		Expect(err).ToNot(HaveOccurred())

		s.Lock()
		s.receivedMessages += string(buffer[0:n])
		s.Unlock()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/md5"
	"crypto/sha1"
	"fmt"
	"github.com/gorilla/schema"
	"io"
	"net/http"
)

type Hasher struct {
	Query  string `schema:"q"`      //query
	Format string `schema:"format"` //format of hash
}

var hasher = new(Hasher)
var decoder = schema.NewDecoder()

func MyHandler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	err = decoder.Decode(hasher, r.Form)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	if hasher.Query == "" || hasher.Format == "" {
		fmt.Fprint(w, InputForm)
		return
	}
	switch hasher.Format {
	case "md5":
		h := md5.New()
		io.WriteString(h, hasher.Query)
		fmt.Fprintf(w, "%x", h.Sum(nil))
		return
	case "sha1":
		h := sha1.New()
		io.WriteString(h, hasher.Query)
		fmt.Fprintf(w, "%x", h.Sum(nil))
		return
	case "sha256":
		fmt.Fprintf(w, "sha256")
		return
	default:
		fmt.Fprintf(w, "Shit, not supported")
		return
	}
}

func InputHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, InputForm)
}

const InputForm = `<html>
<body>
<form method="GET" action="/hash">
<label>
Type the text you want to convert:
<input type="text" name="q" />
</label>
<select name="format">
<option value="md5">MD5</option>
<option value="sha1">SHA1</option>
<option value="sha256">SHA256</option>
</select>
<button type="submit">Go</button>
</form>
</body>
</html>`

func main() {
	http.HandleFunc("/", InputHandler)
	http.HandleFunc("/hash", MyHandler)
	http.ListenAndServe(":8080", nil)
}
<commit_msg>Implements SHA256<commit_after>package main

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"fmt"
	"github.com/gorilla/schema"
	"io"
	"net/http"
)

type Hasher struct {
	Query  string `schema:"q"`      //query
	Format string `schema:"format"` //format of hash
}

var hasher = new(Hasher)
var decoder = schema.NewDecoder()

func MyHandler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	err = decoder.Decode(hasher, r.Form)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	if hasher.Query == "" || hasher.Format == "" {
		fmt.Fprint(w, InputForm)
		return
	}
	switch hasher.Format {
	case "md5":
		h := md5.New()
		io.WriteString(h, hasher.Query)
		fmt.Fprintf(w, "%x", h.Sum(nil))
		return
	case "sha1":
		h := sha1.New()
		io.WriteString(h, hasher.Query)
		fmt.Fprintf(w, "%x", h.Sum(nil))
		return
	case "sha256":
		h := sha256.New()
		io.WriteString(h, hasher.Query)
		fmt.Fprintf(w, "%x", h.Sum(nil))
		return
	default:
		fmt.Fprintf(w, "Shit, not supported")
		return
	}
}

func InputHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, InputForm)
}

const InputForm = `<html>
<body>
<form method="GET" action="/hash">
<label>
Type the text you want to convert:
<input type="text" name="q" />
</label>
<select name="format">
<option value="md5">MD5</option>
<option value="sha1">SHA1</option>
<option value="sha256">SHA256</option>
</select>
<button type="submit">Go</button>
</form>
</body>
</html>`

func main() {
	http.HandleFunc("/", InputHandler)
	http.HandleFunc("/hash", MyHandler)
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/md5"
	"fmt"
	"github.com/gorilla/schema"
	"io"
	"net/http"
)

type Hasher struct {
	Query  string `schema:"q"`      //query
	Format string `schema:"format"` //format of hash
}

var hasher = new(Hasher)
var decoder = schema.NewDecoder()

func MyHandler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	err = decoder.Decode(hasher, r.Form)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	if hasher.Query == "" || hasher.Format == "" {
		fmt.Fprint(w, InputForm)
		return
	}
	switch hasher.Format {
	case "md5":
		h := md5.New()
		io.WriteString(h, hasher.Query)
		fmt.Fprintf(w, "%x", h.Sum(nil))
		return
	case "sha1":
		fmt.Fprintf(w, "sha1")
		return
	case "sha256":
		fmt.Fprintf(w, "sha256")
		return
	default:
		fmt.Fprintf(w, "Shit, not supported")
		return
	}
}

func InputHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, InputForm)
}

const InputForm = `<html>
<body>
<form method="GET" action="/hash">
<label>
Type the text you want to convert:
<input type="text" name="q" />
</label>
<select name="format">
<option value="md5">MD5</option>
<option value="sha1">SHA1</option>
<option value="sha256">SHA256</option>
</select>
<button type="submit">Go</button>
</form>
</body>
</html>`

func main() {
	http.HandleFunc("/", InputHandler)
	http.HandleFunc("/hash", MyHandler)
	http.ListenAndServe(":8080", nil)
}
<commit_msg>Implements SHA1<commit_after>package main

import (
	"crypto/md5"
	"crypto/sha1"
	"fmt"
	"github.com/gorilla/schema"
	"io"
	"net/http"
)

type Hasher struct {
	Query  string `schema:"q"`      //query
	Format string `schema:"format"` //format of hash
}

var hasher = new(Hasher)
var decoder = schema.NewDecoder()

func MyHandler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	err = decoder.Decode(hasher, r.Form)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	if hasher.Query == "" || hasher.Format == "" {
		fmt.Fprint(w, InputForm)
		return
	}
	switch hasher.Format {
	case "md5":
		h := md5.New()
		io.WriteString(h, hasher.Query)
		fmt.Fprintf(w, "%x", h.Sum(nil))
		return
	case "sha1":
		h := sha1.New()
		io.WriteString(h, hasher.Query)
		fmt.Fprintf(w, "%x", h.Sum(nil))
		return
	case "sha256":
		fmt.Fprintf(w, "sha256")
		return
	default:
		fmt.Fprintf(w, "Shit, not supported")
		return
	}
}

func InputHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, InputForm)
}

const InputForm = `<html>
<body>
<form method="GET" action="/hash">
<label>
Type the text you want to convert:
<input type="text" name="q" />
</label>
<select name="format">
<option value="md5">MD5</option>
<option value="sha1">SHA1</option>
<option value="sha256">SHA256</option>
</select>
<button type="submit">Go</button>
</form>
</body>
</html>`

func main() {
	http.HandleFunc("/", InputHandler)
	http.HandleFunc("/hash", MyHandler)
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>package main

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

	"github.com/codegangsta/cli"
)

const (
	appName    = "webhook"
	appUsage   = "handle git webhook and auto update repo"
	appVersion = "v0.0.1"
	appAuthor  = "Xuyuan Pang"
	appEmail   = "pangxuyuan@gmail.com"
)

// Repository struct
type Repository struct {
	Name        string `json:"name"`
	URL         string `json:"url"`
	Description string `json:"description"`
	Homepage    string `json:"homepage"`
}

// Commit struct
type Commit struct {
	ID        string `json:"id"`
	Message   string `json:"message"`
	Timestamp string `json:"timestamp"`
	URL       string `json:"url"`
	Author    Author `json:"author"`
}

// Author struct
type Author struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

// PushEvent struct
type PushEvent struct {
	Before            string     `json:"before"`
	After             string     `json:"after"`
	Ref               string     `json:"ref"`
	UserID            int        `json:"user_id"`
	UserName          string     `json:"user_name"`
	ProjectID         int        `json:"project_id"`
	Repository        Repository `json:"repository"`
	Commits           []Commit   `json:"commits"`
	TotalCommitsCount int        `json:"total_commits_count"`
}

func main() {
	app := cli.NewApp()

	app.Name = appName
	app.Usage = appUsage
	app.Version = appVersion
	app.Author = appAuthor
	app.Email = appEmail
	app.HideHelp = true

	app.Action = func(ctx *cli.Context) {

		mux := http.NewServeMux()

		mux.HandleFunc("/push", pushEventHandler)
		mux.HandleFunc("/push/tag", pushTagEventHandler)

		http.ListenAndServe(":12138", mux)
	}

	app.Run(os.Args)
}

func pushEventHandler(w http.ResponseWriter, req *http.Request) {
	data, err := ioutil.ReadAll(req.Body)
	if err != nil {
		fmt.Println(err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	event := &PushEvent{}
	err = json.Unmarshal(data, event)
	if err != nil {
		fmt.Println(err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}
}

func pushTagEventHandler(w http.ResponseWriter, req *http.Request) {
	data, err := ioutil.ReadAll(req.Body)
	if err != nil {
		fmt.Println(err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	event := &PushEvent{}
	err = json.Unmarshal(data, event)
	if err != nil {
		fmt.Println(err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	fmt.Printf("%v\n", event)
}
<commit_msg>Added flag<commit_after>package main

import (
	"encoding/json"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
)

var updateScript = flag.String("update-script", "", "update shell path")

// Repository struct
type Repository struct {
	Name        string `json:"name"`
	URL         string `json:"url"`
	Description string `json:"description"`
	Homepage    string `json:"homepage"`
}

// Commit struct
type Commit struct {
	ID        string `json:"id"`
	Message   string `json:"message"`
	Timestamp string `json:"timestamp"`
	URL       string `json:"url"`
	Author    Author `json:"author"`
}

// Author struct
type Author struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

// PushEvent struct
type PushEvent struct {
	Before            string     `json:"before"`
	After             string     `json:"after"`
	Ref               string     `json:"ref"`
	UserID            int        `json:"user_id"`
	UserName          string     `json:"user_name"`
	ProjectID         int        `json:"project_id"`
	Repository        Repository `json:"repository"`
	Commits           []Commit   `json:"commits"`
	TotalCommitsCount int        `json:"total_commits_count"`
}

func init() {
	flag.Parse()
}

func main() {
	if *updateScript == "" {
		log.Fatal("update shell required")
	}

	stat, err := os.Stat(*updateScript)
	if err != nil {
		log.Fatal(err)
	}
	if stat.Mode()&0100 == 0 {
		log.Fatal("script has no exec perm")
	}

	mux := http.NewServeMux()

	mux.HandleFunc("/push", pushEventHandler)
	mux.HandleFunc("/push/tag", pushTagEventHandler)

	log.Fatal(http.ListenAndServe(":12138", mux))
}

func pushEventHandler(w http.ResponseWriter, req *http.Request) {
	event, err := parseEvent(req.Body)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	if event.Ref != "refs/head/develop" {
		w.WriteHeader(http.StatusNotModified)
		return
	}

	cmd := exec.Command(*updateScript)
	if err = cmd.Run(); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusOK)
}

func pushTagEventHandler(w http.ResponseWriter, req *http.Request) {
	event, err := parseEvent(req.Body)
	if err != nil {
		log.Println(err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	log.Printf("%v\n", event)
}

func parseEvent(r io.Reader) (*Event, error) {
	data, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return nil, err
	}

	event := &PushEvent{}
	err = json.Unmarshal(data, event)
	if err != nil {
		return nil, err
	}
	return event, nil
}
<|endoftext|>


<commit_before>package webpack

import (
	"errors"
	"html/template"
	"log"
	"strings"

	"github.com/go-webpack/webpack/helper"
	"github.com/go-webpack/webpack/reader"
)

// DevHost webpack-dev-server host:port
var DevHost = "localhost:3808"

// FsPath filesystem path to public webpack dir
var FsPath = "./public/webpack"

// WebPath http path to public webpack dir
var WebPath = "webpack"

// Plugin webpack plugin to use, can be stats or manifest
var Plugin = "deprecated-stats"

// IgnoreMissing ignore assets missing on manifest or fail on them
var IgnoreMissing = true

// Verbose error messages to console (even if error is ignored)
var Verbose = true

// Config is an instance of go-webpack configuration to use with multiple manifest files (multiple webpack configs)
type Config struct {
	// DevHost webpack-dev-server host:port
	DevHost string
	// FsPath filesystem path to public webpack dir
	FsPath string
	// WebPath http path to public webpack dir
	WebPath string
	// Plugin webpack plugin to use, can be stats or manifest
	Plugin string
	// IgnoreMissing ignore assets missing on manifest or fail on them
	IgnoreMissing bool
	// Verbose - show more info
	Verbose bool
	// IsDev - true to use webpack-serve or webpack-dev-server, false to use filesystem and manifest.json
	IsDev bool
}

// AssetHelper renders asset tag with url from webpack manifest to the page. This is a default assethelper, exported at package level. You can also get your own AssetHelper with webpack.GetAssetHelper
var AssetHelper func(string) (template.HTML, error)

// Init Set current environment and preload manifest
func Init(dev bool) {
	if Plugin == "deprecated-stats" {
		Plugin = "stats"
		log.Println("go-webpack: default plugin will be changed to manifest instead of stats-plugin")
		log.Println("go-webpack: to continue using stats-plugin, please set webpack.Plugin = 'stats' explicitly")
	}

	AssetHelper = GetAssetHelper(&Config{
		DevHost:       DevHost,
		FsPath:        FsPath,
		WebPath:       WebPath,
		Plugin:        Plugin,
		IgnoreMissing: IgnoreMissing,
		Verbose:       Verbose,
		IsDev:         dev,
	})
}

// BasicConfig returns a config with basic options set to defaults
func BasicConfig(host, path, webPath string) *Config {
	return &Config{
		DevHost:       host,
		FsPath:        path,
		WebPath:       webPath,
		Plugin:        "manifest",
		IgnoreMissing: true,
		Verbose:       true,
		IsDev:         false,
	}
}

func readManifest(conf *Config) (map[string][]string, error) {
	//if conf.Verbose {
	//log.Println("go-webpack: reading manifest. Plugin:", conf.Plugin, "dev:", conf.IsDev, "dev host:", conf.DevHost, "fs path:", conf.FsPath, "web path:", conf.WebPath)
	//}
	return reader.Read(conf.Plugin, conf.DevHost, conf.FsPath, conf.WebPath, conf.IsDev)
}

func ErrorFunction(err error) func(string) (template.HTML, error) {
	log.Println("go-webpack: error:", err)
	return func(string) (template.HTML, error) {
		return template.HTML(""), err
	}
}

// GetAssetHelper returns an asset helper function based on your config, for use with multiple webpack manifests
func GetAssetHelper(conf *Config) func(string) (template.HTML, error) {
	preloadedAssets := map[string][]string{}

	var err error
	if conf.IsDev {
		// Try to preload manifest, so we can show an error if webpack-dev-server is not running
		_, err = readManifest(conf)
		if err != nil {
			log.Println(err)
		}
		//if err != nil {
		//return ErrorFunction(err)
		//}
	} else {
		preloadedAssets, err = readManifest(conf)
		// we won't ever re-check assets in this case.  this should be a hard error.
		if err != nil {
			return ErrorFunction(err)
		}
	}

	return createAssetHelper(conf, preloadedAssets)
}

func createAssetHelper(conf *Config, preloadedAssets map[string][]string) func(string) (template.HTML, error) {
	return func(key string) (template.HTML, error) {
		var err error

		var assets map[string][]string
		if conf.IsDev {
			assets, err = readManifest(conf)
			if err != nil {
				return template.HTML(""), err
			}
		} else {
			assets = preloadedAssets
		}

		parts := strings.Split(key, ".")
		kind := parts[len(parts)-1]
		//log.Println("showing assets:", key, parts, kind)
		v, ok := assets[key]
		if !ok {
			message := "go-webpack: Asset file '" + key + "' not found in manifest"
			if conf.Verbose {
				log.Printf("%s. Manifest contents:", message)
				for k, a := range assets {
					log.Printf("%s: %s", k, a)
				}
			}
			if conf.IgnoreMissing {
				return template.HTML(""), nil
			}
			return template.HTML(""), errors.New(message)
		}

		buf := []string{}
		for _, s := range v {
			if strings.HasSuffix(s, "."+kind) {
				buf = append(buf, helper.AssetTag(kind, s))
			} else {
				log.Println("skip asset", s, ": bad type")
			}
		}
		return template.HTML(strings.Join(buf, "\n")), nil
	}
}
<commit_msg>comment<commit_after>package webpack

import (
	"errors"
	"html/template"
	"log"
	"strings"

	"github.com/go-webpack/webpack/helper"
	"github.com/go-webpack/webpack/reader"
)

// DevHost webpack-dev-server host:port
var DevHost = "localhost:3808"

// FsPath filesystem path to public webpack dir
var FsPath = "./public/webpack"

// WebPath http path to public webpack dir
var WebPath = "webpack"

// Plugin webpack plugin to use, can be stats or manifest
var Plugin = "deprecated-stats"

// IgnoreMissing ignore assets missing on manifest or fail on them
var IgnoreMissing = true

// Verbose error messages to console (even if error is ignored)
var Verbose = true

// Config is an instance of go-webpack configuration to use with multiple manifest files (multiple webpack configs)
type Config struct {
	// DevHost webpack-dev-server host:port
	DevHost string
	// FsPath filesystem path to public webpack dir
	FsPath string
	// WebPath http path to public webpack dir
	WebPath string
	// Plugin webpack plugin to use, can be stats or manifest
	Plugin string
	// IgnoreMissing ignore assets missing on manifest or fail on them
	IgnoreMissing bool
	// Verbose - show more info
	Verbose bool
	// IsDev - true to use webpack-serve or webpack-dev-server, false to use filesystem and manifest.json
	IsDev bool
}

// AssetHelper renders asset tag with url from webpack manifest to the page. This is a default assethelper, exported at package level. You can also get your own AssetHelper with webpack.GetAssetHelper
var AssetHelper func(string) (template.HTML, error)

// Init Set current environment and preload manifest
func Init(dev bool) {
	if Plugin == "deprecated-stats" {
		Plugin = "stats"
		log.Println("go-webpack: default plugin will be changed to manifest instead of stats-plugin")
		log.Println("go-webpack: to continue using stats-plugin, please set webpack.Plugin = 'stats' explicitly")
	}

	AssetHelper = GetAssetHelper(&Config{
		DevHost:       DevHost,
		FsPath:        FsPath,
		WebPath:       WebPath,
		Plugin:        Plugin,
		IgnoreMissing: IgnoreMissing,
		Verbose:       Verbose,
		IsDev:         dev,
	})
}

// BasicConfig returns a config with basic options set to defaults
func BasicConfig(host, path, webPath string) *Config {
	return &Config{
		DevHost:       host,
		FsPath:        path,
		WebPath:       webPath,
		Plugin:        "manifest",
		IgnoreMissing: true,
		Verbose:       true,
		IsDev:         false,
	}
}

func readManifest(conf *Config) (map[string][]string, error) {
	//if conf.Verbose {
	//log.Println("go-webpack: reading manifest. Plugin:", conf.Plugin, "dev:", conf.IsDev, "dev host:", conf.DevHost, "fs path:", conf.FsPath, "web path:", conf.WebPath)
	//}
	return reader.Read(conf.Plugin, conf.DevHost, conf.FsPath, conf.WebPath, conf.IsDev)
}

// ErrorFunction returns a template function that returns a fixed error message
func ErrorFunction(err error) func(string) (template.HTML, error) {
	log.Println("go-webpack: error:", err)
	return func(string) (template.HTML, error) {
		return template.HTML(""), err
	}
}

// GetAssetHelper returns an asset helper function based on your config, for use with multiple webpack manifests
func GetAssetHelper(conf *Config) func(string) (template.HTML, error) {
	preloadedAssets := map[string][]string{}

	var err error
	if conf.IsDev {
		// Try to preload manifest, so we can show an error if webpack-dev-server is not running
		_, err = readManifest(conf)
		if err != nil {
			log.Println(err)
		}
		//if err != nil {
		//return ErrorFunction(err)
		//}
	} else {
		preloadedAssets, err = readManifest(conf)
		// we won't ever re-check assets in this case.  this should be a hard error.
		if err != nil {
			return ErrorFunction(err)
		}
	}

	return createAssetHelper(conf, preloadedAssets)
}

func createAssetHelper(conf *Config, preloadedAssets map[string][]string) func(string) (template.HTML, error) {
	return func(key string) (template.HTML, error) {
		var err error

		var assets map[string][]string
		if conf.IsDev {
			assets, err = readManifest(conf)
			if err != nil {
				return template.HTML(""), err
			}
		} else {
			assets = preloadedAssets
		}

		parts := strings.Split(key, ".")
		kind := parts[len(parts)-1]
		//log.Println("showing assets:", key, parts, kind)
		v, ok := assets[key]
		if !ok {
			message := "go-webpack: Asset file '" + key + "' not found in manifest"
			if conf.Verbose {
				log.Printf("%s. Manifest contents:", message)
				for k, a := range assets {
					log.Printf("%s: %s", k, a)
				}
			}
			if conf.IgnoreMissing {
				return template.HTML(""), nil
			}
			return template.HTML(""), errors.New(message)
		}

		buf := []string{}
		for _, s := range v {
			if strings.HasSuffix(s, "."+kind) {
				buf = append(buf, helper.AssetTag(kind, s))
			} else {
				log.Println("skip asset", s, ": bad type")
			}
		}
		return template.HTML(strings.Join(buf, "\n")), nil
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Nicolas Lamirault <nicolas.lamirault@gmail.com>

// 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 (
	// "flag"
	"fmt"
	// "log"
	"os"

	"github.com/mitchellh/cli"

	"github.com/nlamirault/aneto/version"
)

func main() {
	os.Exit(realMain())
}

func realMain() int {
	cli := &cli.CLI{
		Args:       os.Args[1:],
		Commands:   Commands,
		HelpFunc:   cli.BasicHelpFunc("aneto"),
		HelpWriter: os.Stdout,
		Version:    version.Version,
	}

	exitCode, err := cli.Run()
	if err != nil {
		Ui.Error(fmt.Sprintf("Error executing CLI: %s", err.Error()))
		// fmt.Printf(colorstring.Color(
		// 	"[red] Error executing CLI: " + err.Error() + "\n"))
		return 1
	}

	return exitCode
}
<commit_msg>cleanup<commit_after>// Copyright (C) 2015 Nicolas Lamirault <nicolas.lamirault@gmail.com>

// 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 (
	// "flag"
	"fmt"
	// "log"
	"os"

	"github.com/mitchellh/cli"

	"github.com/nlamirault/aneto/version"
)

func main() {
	os.Exit(realMain())
}

func realMain() int {
	cli := &cli.CLI{
		Args:       os.Args[1:],
		Commands:   Commands,
		HelpFunc:   cli.BasicHelpFunc("aneto"),
		HelpWriter: os.Stdout,
		Version:    version.Version,
	}

	exitCode, err := cli.Run()
	if err != nil {
		Ui.Error(fmt.Sprintf("Error executing CLI: %s", err.Error()))
		return 1
	}

	return exitCode
}
<|endoftext|>


<commit_before>package instructions

import "jvmgo/rtda"

// Branch if int comparison succeeds
type if_icmpeq struct {BranchInstruction}
func (self *if_icmpeq) execute(thread *rtda.Thread) {
    if val1, val2 := popInts(thread); val1 == val2 {
        // todo
    }
}

type if_icmpne struct {BranchInstruction}
func (self *if_icmpne) execute(thread *rtda.Thread) {
    if val1, val2 := popInts(thread); val1 != val2 {
        // todo
    }
}

type if_icmplt struct {BranchInstruction}
func (self *if_icmplt) execute(thread *rtda.Thread) {
    if val1, val2 := popInts(thread); val1 < val2 {
        // todo
    }
}

type if_icmple struct {BranchInstruction}
func (self *if_icmple) execute(thread *rtda.Thread) {
    if val1, val2 := popInts(thread); val1 <= val2 {
        // todo
    }
}

type if_icmpgt struct {BranchInstruction}
func (self *if_icmpgt) execute(thread *rtda.Thread) {
    if val1, val2 := popInts(thread); val1 > val2 {
        // todo
    }
}

type if_icmpge struct {BranchInstruction}
func (self *if_icmpge) execute(thread *rtda.Thread) {
    if val1, val2 := popInts(thread); val1 >= val2 {
        // todo
    }
}

func popInts(thread *rtda.Thread) (val1, val2 int32) {
    stack := thread.CurrentFrame().OperandStack()
    val1 = stack.PopInt()
    val2 = stack.PopInt()
    return
}
<commit_msg>code refactor<commit_after>package instructions

import "jvmgo/rtda"

// Branch if int comparison succeeds
type if_icmpeq struct {BranchInstruction}
func (self *if_icmpeq) execute(thread *rtda.Thread) {
    if val1, val2 := pop2Ints(thread); val1 == val2 {
        // todo
    }
}

type if_icmpne struct {BranchInstruction}
func (self *if_icmpne) execute(thread *rtda.Thread) {
    if val1, val2 := pop2Ints(thread); val1 != val2 {
        // todo
    }
}

type if_icmplt struct {BranchInstruction}
func (self *if_icmplt) execute(thread *rtda.Thread) {
    if val1, val2 := pop2Ints(thread); val1 < val2 {
        // todo
    }
}

type if_icmple struct {BranchInstruction}
func (self *if_icmple) execute(thread *rtda.Thread) {
    if val1, val2 := pop2Ints(thread); val1 <= val2 {
        // todo
    }
}

type if_icmpgt struct {BranchInstruction}
func (self *if_icmpgt) execute(thread *rtda.Thread) {
    if val1, val2 := pop2Ints(thread); val1 > val2 {
        // todo
    }
}

type if_icmpge struct {BranchInstruction}
func (self *if_icmpge) execute(thread *rtda.Thread) {
    if val1, val2 := pop2Ints(thread); val1 >= val2 {
        // todo
    }
}

func pop2Ints(thread *rtda.Thread) (val1, val2 int32) {
    stack := thread.CurrentFrame().OperandStack()
    val1 = stack.PopInt()
    val2 = stack.PopInt()
    return
}
<|endoftext|>


<commit_before>package main

import (
	. "github.com/lxn/walk/declarative"
)

const (
	_PROGRAM_TITLE                     = "Внимательный Поставшик"
	_TAB_TITLE_SERVER_SETTINGS         = "Прокси"
	_TAB_TOOL_TIP_TEXT_SERVER_SETTINGS = "Настройки локального прокси сервера"
	_TAB_TITLE_LINKS                   = "Адреса"
	_TAB_TOOL_TIP_TEXT_LINKS           = "Генерация ссылок для RSS-клиента"
)

func StartInterface() {
	if _, err := (MainWindow{
		Title:  _PROGRAM_TITLE,
		Size:   Size{200, 200},
		Layout: VBox{},
		Children: []Widget{
			TabWidget{
				Pages: []TabPage{
					{
						Title:       _TAB_TITLE_SERVER_SETTINGS,
						ToolTipText: _TAB_TOOL_TIP_TEXT_SERVER_SETTINGS,
						Layout:      VBox{},
						Children: []Widget{
							HSplitter{
								Children: []Widget{},
							},
						},
					},
					{
						Title:       _TAB_TITLE_LINKS,
						ToolTipText: _TAB_TOOL_TIP_TEXT_LINKS,
						Layout:      VBox{},
						Children: []Widget{
							TextEdit{
								ToolTipText: "=)",
							},
						},
					},
				},
			},
		},
	}.Run()); err != nil {
		log.Error.Fatal(err)
	}
}
<commit_msg>games with windows<commit_after>package main

import (
	. "github.com/lxn/walk/declarative"
)

const (
	_PROGRAM_TITLE                     = "Внимательный Поставшик"
	_TAB_TITLE_SERVER_SETTINGS         = "Прокси"
	_TAB_TOOL_TIP_TEXT_SERVER_SETTINGS = "Настройки локального прокси сервера"
	_TAB_TITLE_LINKS                   = "Адреса"
	_TAB_TOOL_TIP_TEXT_LINKS           = "Генерация ссылок для RSS-клиента"
)

func StartInterface() {
	if _, err := (MainWindow{
		Title:  _PROGRAM_TITLE,
		Size:   Size{200, 200},
		Layout: VBox{},
		Children: []Widget{
			TabWidget{
				Pages: []TabPage{
					{
						Title:       _TAB_TITLE_SERVER_SETTINGS,
						ToolTipText: _TAB_TOOL_TIP_TEXT_SERVER_SETTINGS,
						Layout:      VBox{},
						Children: []Widget{
							HSplitter{
								Children: []Widget{},
							},
						},
					},
					{
						Title:       _TAB_TITLE_LINKS,
						ToolTipText: _TAB_TOOL_TIP_TEXT_LINKS,
						Layout:      VBox{},
						Children:    []Widget{},
					},
				},
			},
		},
	}.Run()); err != nil {
		log.Error.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package winston

import (
	"fmt"
	"io/ioutil"
	"log"
	"math"
	"net/http"
	"net/url"
	"os"
	"regexp"
	"strings"
)

func CheckError(err error) {
	if err != nil {
		log.Fatal("[ERROR]", err)
	}
}

type Winston struct {
	Text  string
	SafeText  string
	Grams []string
	Freq  map[string]int
}

func (w1 *Winston) CommonFreqKeys(w2 *Winston) []string {
	common := make([]string, 0)

	for key, _ := range w1.Freq {
		if w2.Freq[key] != 0 {
			common = append(common, key)
		}
	}

	return common
}

func (w *Winston) FreqSum() (sum int) {
	for _, count := range w.Freq {
		sum += count
	}

	return
}

func (w *Winston) FreqSquare() (sum float64) {
	for _, count := range w.Freq {
		sum += math.Pow(float64(count), 2)
	}

	return
}

func (w1 *Winston) FreqProduct(w2 *Winston) (sum int) {
	for _, key := range w1.CommonFreqKeys(w2) {
		sum += w1.Freq[key] * w2.Freq[key]
	}

	return
}

func (w1 *Winston) Pearson(w2 *Winston) float64 {
	sum1 := float64(w1.FreqSum())
	sum2 := float64(w2.FreqSum())
	sumsq1 := w1.FreqSquare()
	sumsq2 := w2.FreqSquare()
	sump := float64(w1.FreqProduct(w2))
	n := float64(len(w1.Freq))

	// fmt.Println(sum1, sum2, sumsq1, sumsq2, sump, n)

	num := sump - ((sum1 * sum2) / n)
	den := math.Sqrt((sumsq1 - (math.Pow(sum1, 2))/n) * (sumsq2 - (math.Pow(sum2, 2))/n))

	// fmt.Println(num, den)

	if den == 0 {
		return 0
	}

	return num / den
}

func (w *Winston) CleanText() {
	asciiregexp, err := regexp.Compile("[^A-Za-z ]+")
	CheckError(err)

	tagregexp, err := regexp.Compile("<[^>]+>")
	CheckError(err)

	spaceregexp, err := regexp.Compile("[ ]+")
	CheckError(err)

	w.SafeText = tagregexp.ReplaceAllString(w.Text, " ")
	w.SafeText = asciiregexp.ReplaceAllString(w.SafeText, " ")
	w.SafeText = spaceregexp.ReplaceAllString(w.SafeText, " ")
	w.SafeText = strings.Trim(w.SafeText, "")
	w.SafeText = strings.ToLower(w.SafeText)
	w.SafeText = strings.TrimSpace(w.SafeText)
}

func (w *Winston) CalcGrams() {
	w.CleanText()

	w.Grams = strings.Split(w.Text, ` `)
	w.Freq = make(map[string]int)

	for _, gram := range w.Grams {
		w.Freq[gram] += 1
	}

	fmt.Println(w.SafeText)
}

func (w *Winston) FetchUrl(theurl string) {
	var client *http.Client

	if proxy := os.Getenv("http_proxy"); proxy != `` {
		proxyUrl, err := url.Parse(proxy)
		CheckError(err)

		client = &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}
	} else {
		client = &http.Client{}
	}

	req, err := http.NewRequest(`GET`, theurl, nil)
	CheckError(err)

	resp, err := client.Do(req)
	CheckError(err)

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	CheckError(err)

	w.Text = string(body)
}
<commit_msg>add loc<commit_after>package winston

import (
	"fmt"
	"io/ioutil"
	"log"
	"math"
	"net/http"
	"net/url"
	"os"
	"regexp"
	"strings"
)

func CheckError(err error) {
	if err != nil {
		log.Fatal("[ERROR]", err)
	}
}

type Winston struct {
	Location string
	Text  string
	SafeText  string
	Grams []string
	Freq  map[string]int
}

func (w1 *Winston) CommonFreqKeys(w2 *Winston) []string {
	common := make([]string, 0)

	for key, _ := range w1.Freq {
		if w2.Freq[key] != 0 {
			common = append(common, key)
		}
	}

	return common
}

func (w *Winston) FreqSum() (sum int) {
	for _, count := range w.Freq {
		sum += count
	}

	return
}

func (w *Winston) FreqSquare() (sum float64) {
	for _, count := range w.Freq {
		sum += math.Pow(float64(count), 2)
	}

	return
}

func (w1 *Winston) FreqProduct(w2 *Winston) (sum int) {
	for _, key := range w1.CommonFreqKeys(w2) {
		sum += w1.Freq[key] * w2.Freq[key]
	}

	return
}

func (w1 *Winston) Pearson(w2 *Winston) float64 {
	sum1 := float64(w1.FreqSum())
	sum2 := float64(w2.FreqSum())
	sumsq1 := w1.FreqSquare()
	sumsq2 := w2.FreqSquare()
	sump := float64(w1.FreqProduct(w2))
	n := float64(len(w1.Freq))

	// fmt.Println(sum1, sum2, sumsq1, sumsq2, sump, n)

	num := sump - ((sum1 * sum2) / n)
	den := math.Sqrt((sumsq1 - (math.Pow(sum1, 2))/n) * (sumsq2 - (math.Pow(sum2, 2))/n))

	// fmt.Println(num, den)

	if den == 0 {
		return 0
	}

	return num / den
}

func (w *Winston) CleanText() {
	asciiregexp, err := regexp.Compile("[^A-Za-z ]+")
	CheckError(err)

	tagregexp, err := regexp.Compile("<[^>]+>")
	CheckError(err)

	spaceregexp, err := regexp.Compile("[ ]+")
	CheckError(err)

	w.SafeText = tagregexp.ReplaceAllString(w.Text, " ")
	w.SafeText = asciiregexp.ReplaceAllString(w.SafeText, " ")
	w.SafeText = spaceregexp.ReplaceAllString(w.SafeText, " ")
	w.SafeText = strings.Trim(w.SafeText, "")
	w.SafeText = strings.ToLower(w.SafeText)
	w.SafeText = strings.TrimSpace(w.SafeText)
}

func (w *Winston) CalcGrams() {
	w.CleanText()

	w.Grams = strings.Split(w.Text, ` `)
	w.Freq = make(map[string]int)

	for _, gram := range w.Grams {
		w.Freq[gram] += 1
	}

	fmt.Println(w.SafeText)
}

func (w *Winston) FetchUrl(theurl string) {
	var client *http.Client

	if proxy := os.Getenv("http_proxy"); proxy != `` {
		proxyUrl, err := url.Parse(proxy)
		CheckError(err)

		client = &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}
	} else {
		client = &http.Client{}
	}

	req, err := http.NewRequest(`GET`, theurl, nil)
	CheckError(err)

	resp, err := client.Do(req)
	CheckError(err)

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	CheckError(err)

	w.Text = string(body)
}
<|endoftext|>


<commit_before>//Copyright 2015 Vibhav Pant. All rights reserved.
//Use of this source code is governed by the MIT
//that can be found in the LICENSE file.

//Package wsevent implements thread-safe event-driven communication similar to socket.IO,
//on the top of Gorilla's WebSocket implementation.
package wsevent

import (
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"net/http"
	"sync"
	"time"

	ws "github.com/gorilla/websocket"
	"log"
)

//Client
type Client struct {
	//Session ID
	id string

	conn     *ws.Conn
	connLock *sync.RWMutex
}

//Server
type Server struct {
	rooms     map[string]([]*Client)
	roomsLock *sync.RWMutex

	//maps client IDs tothe list of rooms the corresponding client has joined
	joinedRooms     map[string][]string
	joinedRoomsLock *sync.RWMutex

	//The extractor function reads the byte array and the message type
	//and returns the event represented by the message.
	Extractor func(string) string
	//Called when the websocket connection closes. The disconnected client's
	//session ID is sent as an argument
	OnDisconnect func(string)

	handlers     map[string]func(*Client, string) string
	handlersLock *sync.RWMutex

	newClient chan *Client
}

func genID(r *http.Request) string {
	hash := fmt.Sprintf("%s%d", r.RemoteAddr, time.Now().UnixNano())
	return fmt.Sprintf("%x", sha1.Sum([]byte(hash)))
}

//Returns the client's unique session ID
func (c *Client) Id() string {
	return c.id
}

func (s *Server) NewClient(upgrader ws.Upgrader, w http.ResponseWriter, r *http.Request) (*Client, error) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		return nil, err
	}

	client := &Client{
		id:       genID(r),
		conn:     conn,
		connLock: new(sync.RWMutex),
	}
	s.newClient <- client

	return client, nil
}

//A thread-safe variant of WriteMessage
func (c *Client) Emit(data string) error {
	c.connLock.Lock()
	defer c.connLock.Unlock()

	return c.conn.WriteMessage(ws.TextMessage, []byte(data))
}

//Return a new server object
func NewServer() *Server {
	s := &Server{
		rooms:     make(map[string]([]*Client)),
		roomsLock: new(sync.RWMutex),

		joinedRooms:     make(map[string][]string),
		joinedRoomsLock: new(sync.RWMutex),

		handlers:     make(map[string](func(*Client, string) string)),
		handlersLock: new(sync.RWMutex),

		newClient: make(chan *Client),
	}

	return s
}

//Add a client c to room r
func (s *Server) AddClient(c *Client, r string) {
	s.roomsLock.Lock()
	defer s.roomsLock.Unlock()
	s.rooms[r] = append(s.rooms[r], c)

	s.joinedRoomsLock.Lock()
	defer s.joinedRoomsLock.Unlock()
	s.joinedRooms[c.id] = append(s.joinedRooms[c.id], r)
}

//Send all clients in room room data with type messageType
func (s *Server) Broadcast(room string, data string) {
	wg := new(sync.WaitGroup)

	for _, client := range s.rooms[room] {
		go func(c *Client) {
			wg.Add(1)
			defer wg.Done()
			c.Emit(data)
		}(client)
	}

	wg.Wait()
}

func (c *Client) cleanup(s *Server) {
	c.conn.Close()
	s.joinedRoomsLock.RLock()
	defer s.joinedRoomsLock.RUnlock()

	for _, room := range s.joinedRooms[c.id] {
		s.roomsLock.Lock()
		delete(s.rooms, room)
		s.roomsLock.Unlock()
	}

	if s.OnDisconnect != nil {
		s.OnDisconnect(c.id)
	}
}

//Returns an array of rooms the client c has been added to
func (s *Server) RoomsJoined(c *Client) []string {
	var rooms []string
	s.joinedRoomsLock.RLock()
	defer s.joinedRoomsLock.RUnlock()

	for _, room := range s.joinedRooms[c.id] {
		rooms = append(rooms, room)
	}

	return rooms
}

//Starts listening for events on added sockets. Needs to be called only once.
func (s *Server) Listener() {
	for {
		c := <-s.newClient
		go func(c *Client) {
			for {
				mtype, data, err := c.conn.ReadMessage()
				if err != nil {
					c.cleanup(s)
					return
				}

				var js struct {
					Id   string
					Data json.RawMessage
				}
				err = json.Unmarshal(data, &js)

				if err != nil || mtype != ws.TextMessage {
					log.Println(err)
					continue
				}

				callName := s.Extractor(string(js.Data))

				s.handlersLock.RLock()
				f, ok := s.handlers[callName]
				s.handlersLock.RUnlock()

				if !ok {
					continue
				}

				rtrn := f(c, string(js.Data))
				reply := struct {
					Id   string `json:"id"`
					Data string `json:"data,string"`
				}{js.Id, rtrn}

				bytes, _ := json.Marshal(reply)
				c.Emit(string(bytes))
			}
		}(c)
	}
}

//Registers a callback for the event string. The callback must take 2 arguments,
//The client from which the message was received and the string message itself.
func (s *Server) On(event string, f func(*Client, string) string) {
	s.handlersLock.Lock()
	s.handlers[event] = f
	s.handlersLock.Unlock()
}
<commit_msg>Add EmitJSON(), Request()<commit_after>//Copyright 2015 Vibhav Pant. All rights reserved.
//Use of this source code is governed by the MIT
//that can be found in the LICENSE file.

//Package wsevent implements thread-safe event-driven communication similar to socket.IO,
//on the top of Gorilla's WebSocket implementation.
package wsevent

import (
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"net/http"
	"sync"
	"time"

	ws "github.com/gorilla/websocket"
	"log"
)

//Client
type Client struct {
	//Session ID
	id string

	conn     *ws.Conn
	connLock *sync.RWMutex
	request  *http.Request
}

//Server
type Server struct {
	rooms     map[string]([]*Client)
	roomsLock *sync.RWMutex

	//maps client IDs tothe list of rooms the corresponding client has joined
	joinedRooms     map[string][]string
	joinedRoomsLock *sync.RWMutex

	//The extractor function reads the byte array and the message type
	//and returns the event represented by the message.
	Extractor func(string) string
	//Called when the websocket connection closes. The disconnected client's
	//session ID is sent as an argument
	OnDisconnect func(string)

	handlers     map[string]func(*Client, string) string
	handlersLock *sync.RWMutex

	newClient chan *Client
}

func genID(r *http.Request) string {
	hash := fmt.Sprintf("%s%d", r.RemoteAddr, time.Now().UnixNano())
	return fmt.Sprintf("%x", sha1.Sum([]byte(hash)))
}

//Returns the client's unique session ID
func (c *Client) Id() string {
	return c.id
}

// Returns the first http request when established connection.
func (c *Client) Request() *http.Request {
	return c.request
}

func (s *Server) NewClient(upgrader ws.Upgrader, w http.ResponseWriter, r *http.Request) (*Client, error) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		return nil, err
	}

	client := &Client{
		id:       genID(r),
		conn:     conn,
		connLock: new(sync.RWMutex),
		request:  r,
	}
	s.newClient <- client

	return client, nil
}

//A thread-safe variant of WriteMessage
func (c *Client) Emit(data string) error {
	c.connLock.Lock()
	defer c.connLock.Unlock()

	js := struct {
		Id   int             `json:"id"`
		Data json.RawMessage `json:"data"`
	}{-1, []byte(data)}
	return c.conn.WriteJSON(js)
}

//A thread-safe variant of EmitJSON
func (c *Client) EmitJSON(v interface{}) error {
	c.connLock.Lock()
	defer c.connLock.Unlock()

	js := struct {
		Id   int         `json:"id"`
		Data interface{} `json:"data"`
	}{-1, v}

	return c.conn.WriteJSON(js)
}

//Return a new server object
func NewServer() *Server {
	s := &Server{
		rooms:     make(map[string]([]*Client)),
		roomsLock: new(sync.RWMutex),

		joinedRooms:     make(map[string][]string),
		joinedRoomsLock: new(sync.RWMutex),

		handlers:     make(map[string](func(*Client, string) string)),
		handlersLock: new(sync.RWMutex),

		newClient: make(chan *Client),
	}

	return s
}

//Add a client c to room r
func (s *Server) AddClient(c *Client, r string) {
	s.roomsLock.Lock()
	defer s.roomsLock.Unlock()
	s.rooms[r] = append(s.rooms[r], c)

	s.joinedRoomsLock.Lock()
	defer s.joinedRoomsLock.Unlock()
	s.joinedRooms[c.id] = append(s.joinedRooms[c.id], r)
}

//Remove client c from room r
func (s *Server) RemoveClient(c *Client, r string) {
	index := -1
	s.roomsLock.Lock()

	for i, client := range s.rooms[r] {
		if c == client {
			index = i
		}
	}
	if index == -1 {
		return
	}

	s.rooms[r][index] = s.rooms[r][len(s.rooms[r])-1]
	s.rooms[r][len(s.rooms[r])-1] = nil
	s.rooms[r] = s.rooms[r][:len(s.rooms[r])-1]
	s.roomsLock.Unlock()

	s.joinedRoomsLock.Lock()
	index = -1
	for i, room := range s.joinedRooms[c.id] {
		if room == r {
			index = i
		}
	}
	if index == -1 {
		return
	}

	length := len(s.joinedRooms[c.id])
	s.joinedRooms[c.id][index] = s.joinedRooms[c.id][length-1]
	s.joinedRooms[c.id][length-1] = ""
	s.joinedRooms[c.id] = s.joinedRooms[c.id][:length-1]
	s.joinedRoomsLock.Unlock()
}

//Send all clients in room room data with type messageType
func (s *Server) Broadcast(room string, data string) {
	wg := new(sync.WaitGroup)

	for _, client := range s.rooms[room] {
		go func(c *Client) {
			wg.Add(1)
			defer wg.Done()
			c.Emit(data)
		}(client)
	}

	wg.Wait()
}

func (c *Client) cleanup(s *Server) {
	c.conn.Close()
	s.joinedRoomsLock.RLock()
	defer s.joinedRoomsLock.RUnlock()

	for _, room := range s.joinedRooms[c.id] {
		s.roomsLock.Lock()
		delete(s.rooms, room)
		s.roomsLock.Unlock()
	}

	if s.OnDisconnect != nil {
		s.OnDisconnect(c.id)
	}
}

//Returns an array of rooms the client c has been added to
func (s *Server) RoomsJoined(c *Client) []string {
	var rooms []string
	s.joinedRoomsLock.RLock()
	defer s.joinedRoomsLock.RUnlock()

	for _, room := range s.joinedRooms[c.id] {
		rooms = append(rooms, room)
	}

	return rooms
}

//Starts listening for events on added sockets. Needs to be called only once.
func (s *Server) Listener() {
	for {
		c := <-s.newClient
		go func(c *Client) {
			for {
				mtype, data, err := c.conn.ReadMessage()
				if err != nil {
					c.cleanup(s)
					return
				}

				var js struct {
					Id   string
					Data json.RawMessage
				}
				err = json.Unmarshal(data, &js)

				if err != nil || mtype != ws.TextMessage {
					log.Println(err)
					continue
				}

				callName := s.Extractor(string(js.Data))

				s.handlersLock.RLock()
				f, ok := s.handlers[callName]
				s.handlersLock.RUnlock()

				if !ok {
					continue
				}

				rtrn := f(c, string(js.Data))
				reply := struct {
					Id   string `json:"id"`
					Data string `json:"data,string"`
				}{js.Id, rtrn}

				bytes, _ := json.Marshal(reply)
				c.Emit(string(bytes))
			}
		}(c)
	}
}

//Registers a callback for the event string. The callback must take 2 arguments,
//The client from which the message was received and the string message itself.
func (s *Server) On(event string, f func(*Client, string) string) {
	s.handlersLock.Lock()
	s.handlers[event] = f
	s.handlersLock.Unlock()
}
<|endoftext|>