<commit_before>package models

import (
	"encoding/json"
	"github.com/asaskevich/govalidator"
	"golang.org/x/crypto/bcrypt"
	"time"

	"github.com/techjanitor/pram-post/config"
	e "github.com/techjanitor/pram-post/errors"
	"github.com/techjanitor/pram-post/models"
	u "github.com/techjanitor/pram-post/utils"
)

// Register contains information for initial account creation
type RegisterModel struct {
	Name     string
	Email    string
	Password string
}

// Validate will check the provided name length and email
func (r *RegisterModel) Validate() (err error) {

	// Validate name input
	name := u.Validate{Input: r.Name, Max: config.Settings.Limits.NameMaxLength, Min: config.Settings.Limits.NameMinLength}
	if name.IsEmpty() {
		return e.ErrNameEmpty
	} else if name.MinLength() {
		return e.ErrNameShort
	} else if name.MaxLength() {
		return e.ErrNameLong
	}

	// check if name is alphanumeric
	if !govalidator.IsAlphanumeric(r.Name) {
		return e.ErrNameAlphaNum
	}

	// Validate password input
	password := u.Validate{Input: r.Password, Max: config.Settings.Limits.NameMaxLength, Min: config.Settings.Limits.NameMinLength}
	if password.IsEmpty() {
		return e.ErrPasswordEmpty
	} else if password.MinLength() {
		return e.ErrPasswordShort
	} else if password.MaxLength() {
		return e.ErrPasswordLong
	}

	// Validate email
	if !govalidator.IsEmail(r.Email) {
		return e.ErrInvalidEmail
	}

	return

}

// check for duplicate name before registering
func (r *RegisterModel) CheckDuplicate() (err error) {

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

	var check bool

	err = db.QueryRow("select count(*) from users where user_name = ?", r.Name).Scan(&check)
	if err != nil {
		return
	}

	// Error if it does
	if check {
		return e.ErrDuplicateName
	}

	return

}

// register new user
func (r *RegisterModel) Register() (err error) {

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

	// hash password
	password, err := bcrypt.GenerateFromPassword([]byte(r.Password), bcrypt.DefaultCost)
	if err != nil {
		return
	}

	ps1, err := db.Prepare("INSERT into users (usergroup_id, user_name, user_email, user_password, user_confirmed) VALUES (?,?,?,?,?)")
	if err != nil {
		return
	}
	defer ps1.Close()

	_, err = ps1.Exec(1, r.Name, r.Email, password, 1)
	if err != nil {
		return
	}

	return

}
<commit_msg>add registration<commit_after>package models

import (
	"encoding/json"
	"github.com/asaskevich/govalidator"
	"golang.org/x/crypto/bcrypt"
	"time"

	"github.com/techjanitor/pram-post/config"
	e "github.com/techjanitor/pram-post/errors"
	u "github.com/techjanitor/pram-post/utils"
)

// Register contains information for initial account creation
type RegisterModel struct {
	Name     string
	Email    string
	Password string
}

// Validate will check the provided name length and email
func (r *RegisterModel) Validate() (err error) {

	// Validate name input
	name := u.Validate{Input: r.Name, Max: config.Settings.Limits.NameMaxLength, Min: config.Settings.Limits.NameMinLength}
	if name.IsEmpty() {
		return e.ErrNameEmpty
	} else if name.MinLength() {
		return e.ErrNameShort
	} else if name.MaxLength() {
		return e.ErrNameLong
	}

	// check if name is alphanumeric
	if !govalidator.IsAlphanumeric(r.Name) {
		return e.ErrNameAlphaNum
	}

	// Validate password input
	password := u.Validate{Input: r.Password, Max: config.Settings.Limits.NameMaxLength, Min: config.Settings.Limits.NameMinLength}
	if password.IsEmpty() {
		return e.ErrPasswordEmpty
	} else if password.MinLength() {
		return e.ErrPasswordShort
	} else if password.MaxLength() {
		return e.ErrPasswordLong
	}

	// Validate email
	if !govalidator.IsEmail(r.Email) {
		return e.ErrInvalidEmail
	}

	return

}

// check for duplicate name before registering
func (r *RegisterModel) CheckDuplicate() (err error) {

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

	var check bool

	err = db.QueryRow("select count(*) from users where user_name = ?", r.Name).Scan(&check)
	if err != nil {
		return
	}

	// Error if it does
	if check {
		return e.ErrDuplicateName
	}

	return

}

// register new user
func (r *RegisterModel) Register() (err error) {

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

	// hash password
	password, err := bcrypt.GenerateFromPassword([]byte(r.Password), bcrypt.DefaultCost)
	if err != nil {
		return
	}

	ps1, err := db.Prepare("INSERT into users (usergroup_id, user_name, user_email, user_password, user_confirmed) VALUES (?,?,?,?,?)")
	if err != nil {
		return
	}
	defer ps1.Close()

	_, err = ps1.Exec(1, r.Name, r.Email, password, 1)
	if err != nil {
		return
	}

	return

}
<|endoftext|>


<commit_before>package manet

import (
	"fmt"

	ma "github.com/multiformats/go-multiaddr"
)

// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces. If ifaceAddr is nil, we request interface addresses
// from the network stack. (this is so you can provide a cached value if resolving many addrs)
func ResolveUnspecifiedAddress(resolve ma.Multiaddr, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
	// split address into its components
	split := ma.Split(resolve)

	// if first component (ip) is not unspecified, use it as is.
	if !IsIPUnspecified(split[0]) {
		return []ma.Multiaddr{resolve}, nil
	}

	out := make([]ma.Multiaddr, 0, len(ifaceAddrs))
	for _, ia := range ifaceAddrs {
		// must match the first protocol to be resolve.
		if ia.Protocols()[0].Code != resolve.Protocols()[0].Code {
			continue
		}

		split[0] = ia
		joined := ma.Join(split...)
		out = append(out, joined)
	}
	if len(out) < 1 {
		return nil, fmt.Errorf("failed to resolve: %s", resolve)
	}
	return out, nil
}

// ResolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func ResolveUnspecifiedAddresses(unspecAddrs, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
	// todo optimize: only fetch these if we have a "any" addr.
	if len(ifaceAddrs) < 1 {
		var err error
		ifaceAddrs, err = InterfaceAddresses()
		if err != nil {
			return nil, err
		}
	}

	var outputAddrs []ma.Multiaddr
	for _, a := range unspecAddrs {
		// unspecified?
		resolved, err := ResolveUnspecifiedAddress(a, ifaceAddrs)
		if err != nil {
			continue // optimistic. if we can't resolve anything, we'll know at the bottom.
		}
		outputAddrs = append(outputAddrs, resolved...)
	}

	if len(outputAddrs) < 1 {
		return nil, fmt.Errorf("failed to specify addrs: %s", unspecAddrs)
	}
	return outputAddrs, nil
}

// InterfaceAddresses returns a list of addresses associated with local machine
// Note: we do not return link local addresses. IP loopback is ok, because we
// may be connecting to other nodes in the same machine.
func InterfaceAddresses() ([]ma.Multiaddr, error) {
	maddrs, err := InterfaceMultiaddrs()
	if err != nil {
		return nil, err
	}

	var out []ma.Multiaddr
	for _, a := range maddrs {
		if !AddrOverNonLocalIP(a) {
			continue
		}
		out = append(out, a)
	}
	return out, nil
}
<commit_msg>unexport InterfaceAddresses<commit_after>package manet

import (
	"fmt"

	ma "github.com/multiformats/go-multiaddr"
)

// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces. If ifaceAddr is nil, we request interface addresses
// from the network stack. (this is so you can provide a cached value if resolving many addrs)
func ResolveUnspecifiedAddress(resolve ma.Multiaddr, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
	// split address into its components
	split := ma.Split(resolve)

	// if first component (ip) is not unspecified, use it as is.
	if !IsIPUnspecified(split[0]) {
		return []ma.Multiaddr{resolve}, nil
	}

	out := make([]ma.Multiaddr, 0, len(ifaceAddrs))
	for _, ia := range ifaceAddrs {
		// must match the first protocol to be resolve.
		if ia.Protocols()[0].Code != resolve.Protocols()[0].Code {
			continue
		}

		split[0] = ia
		joined := ma.Join(split...)
		out = append(out, joined)
	}
	if len(out) < 1 {
		return nil, fmt.Errorf("failed to resolve: %s", resolve)
	}
	return out, nil
}

// ResolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func ResolveUnspecifiedAddresses(unspecAddrs, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
	// todo optimize: only fetch these if we have a "any" addr.
	if len(ifaceAddrs) < 1 {
		var err error
		ifaceAddrs, err = interfaceAddresses()
		if err != nil {
			return nil, err
		}
	}

	var outputAddrs []ma.Multiaddr
	for _, a := range unspecAddrs {
		// unspecified?
		resolved, err := ResolveUnspecifiedAddress(a, ifaceAddrs)
		if err != nil {
			continue // optimistic. if we can't resolve anything, we'll know at the bottom.
		}
		outputAddrs = append(outputAddrs, resolved...)
	}

	if len(outputAddrs) < 1 {
		return nil, fmt.Errorf("failed to specify addrs: %s", unspecAddrs)
	}
	return outputAddrs, nil
}

// interfaceAddresses returns a list of addresses associated with local machine
// Note: we do not return link local addresses. IP loopback is ok, because we
// may be connecting to other nodes in the same machine.
func interfaceAddresses() ([]ma.Multiaddr, error) {
	maddrs, err := InterfaceMultiaddrs()
	if err != nil {
		return nil, err
	}

	var out []ma.Multiaddr
	for _, a := range maddrs {
		if !AddrOverNonLocalIP(a) {
			continue
		}
		out = append(out, a)
	}
	return out, nil
}
<|endoftext|>


<commit_before>package main

import (
	"bitbucket.org/coreos/core-update/types"
	"bytes"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/xml"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
)

var cmdNewVersion = &Command{
	UsageLine: "new-version -k [key] -a [app-id] -v [version] -t [track] -p [url path] [filename]",
	Short:     "update the version database for a given file",
	Long: `
Takes a file path and some meta data and update the information used in the datastore.
	`,
}

var dryRun = cmdNewVersion.Flag.Bool("d", false, "dry run, print out the xml payload")
var key = cmdNewVersion.Flag.String("k", "", "api key for the admin user")

var appId = cmdNewVersion.Flag.String("a", "", "application id")
var version = cmdNewVersion.Flag.String("v", "", "version ")
var track = cmdNewVersion.Flag.String("t", "", "track")
var path = cmdNewVersion.Flag.String("p", "", "url path")

func init() {
	cmdNewVersion.Run = runNewVersion
}

func calculateHashes(filename string, pkg *types.Package) {
	var (
		writers []io.Writer
		hashes  []hash.Hash
	)

	push := func(h hash.Hash) {
		writers = append(writers, h)
		hashes = append(hashes, h)
	}

	push(sha256.New())
	push(sha1.New())

	in, err := os.Open(filename)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	io.Copy(io.MultiWriter(writers...), in)

	formatHash := func(hash hash.Hash) (out string) {
		return fmt.Sprintf("%x", hash.Sum(nil))
	}

	pkg.Sha256Sum = formatHash(hashes[0])
	pkg.Sha1Sum = formatHash(hashes[1])
}

func runNewVersion(cmd *Command, args []string) {
	if *dryRun == false && *key == "" {
		fmt.Printf("key or dry-run required")
		os.Exit(-1)
	}

	if *appId == "" || *version == "" || *track == "" || *path == "" {
		fmt.Printf("one of the required fields was not present\n")
		os.Exit(-1)
	}

	file := args[0]
	fileBase := filepath.Base(file)
	fi, err := os.Stat(file)
	if err != nil {
		fmt.Printf("%s\n", err.Error())
		os.Exit(-1)
	}

	fileSize := strconv.FormatInt(fi.Size(), 10)

	app := types.App{Id: *appId, Version: *version, Track: *track}
	pkg := types.Package{Name: fileBase, Size: fileSize, Path: *path}
	ver := types.Version{App: &app, Package: &pkg}
	calculateHashes(file, ver.Package)

	raw, err := xml.MarshalIndent(ver, "", " ")
	if err != nil {
		fmt.Printf(err.Error())
		os.Exit(-1)
	}

	body := []byte(xml.Header)
	body = append(body, raw...)

	adminURL, _ := url.Parse(updateURL.String())
	adminURL.Path = "/admin/version"

	req, _ := http.NewRequest("POST", adminURL.String(), bytes.NewBuffer(body))
	req.Header.Set("Content-Type", "text/xml")
	req.SetBasicAuth("admin", *key)

	if *dryRun || *debug {
		req.Write(os.Stdout)
	}

	if *dryRun {
		return
	}

	client := http.Client{}
	resp, err := client.Do(req)

	if err != nil {
		fmt.Printf(err.Error())
		os.Exit(-1)
	}

	body, _ = ioutil.ReadAll(resp.Body)
	os.Stdout.Write(body)
	fmt.Printf("\n")

	if resp.StatusCode != 200 {
		fmt.Printf("Error: bad return code %s\n", resp.Status)
		os.Exit(-1)
	}

	return
}
<commit_msg>fix(new-version): hashes need to be base64 encoded<commit_after>package main

import (
	"bitbucket.org/coreos/core-update/types"
	"bytes"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/base64"
	"encoding/xml"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
)

var cmdNewVersion = &Command{
	UsageLine: "new-version -k [key] -a [app-id] -v [version] -t [track] -p [url path] [filename]",
	Short:     "update the version database for a given file",
	Long: `
Takes a file path and some meta data and update the information used in the datastore.
	`,
}

var dryRun = cmdNewVersion.Flag.Bool("d", false, "dry run, print out the xml payload")
var key = cmdNewVersion.Flag.String("k", "", "api key for the admin user")

var appId = cmdNewVersion.Flag.String("a", "", "application id")
var version = cmdNewVersion.Flag.String("v", "", "version ")
var track = cmdNewVersion.Flag.String("t", "", "track")
var path = cmdNewVersion.Flag.String("p", "", "url path")

func init() {
	cmdNewVersion.Run = runNewVersion
}

func calculateHashes(filename string, pkg *types.Package) {
	var (
		writers []io.Writer
		hashes  []hash.Hash
	)

	push := func(h hash.Hash) {
		writers = append(writers, h)
		hashes = append(hashes, h)
	}

	push(sha256.New())
	push(sha1.New())

	in, err := os.Open(filename)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	io.Copy(io.MultiWriter(writers...), in)

	formatHash := func(hash hash.Hash) string {
		return base64.StdEncoding.EncodeToString(hash.Sum(nil))
	}

	pkg.Sha256Sum = formatHash(hashes[0])
	pkg.Sha1Sum = formatHash(hashes[1])
}

func runNewVersion(cmd *Command, args []string) {
	if *dryRun == false && *key == "" {
		fmt.Printf("key or dry-run required")
		os.Exit(-1)
	}

	if *appId == "" || *version == "" || *track == "" || *path == "" {
		fmt.Printf("one of the required fields was not present\n")
		os.Exit(-1)
	}

	file := args[0]
	fileBase := filepath.Base(file)
	fi, err := os.Stat(file)
	if err != nil {
		fmt.Printf("%s\n", err.Error())
		os.Exit(-1)
	}

	fileSize := strconv.FormatInt(fi.Size(), 10)

	app := types.App{Id: *appId, Version: *version, Track: *track}
	pkg := types.Package{Name: fileBase, Size: fileSize, Path: *path}
	ver := types.Version{App: &app, Package: &pkg}
	calculateHashes(file, ver.Package)

	raw, err := xml.MarshalIndent(ver, "", " ")
	if err != nil {
		fmt.Printf(err.Error())
		os.Exit(-1)
	}

	body := []byte(xml.Header)
	body = append(body, raw...)

	adminURL, _ := url.Parse(updateURL.String())
	adminURL.Path = "/admin/version"

	req, _ := http.NewRequest("POST", adminURL.String(), bytes.NewBuffer(body))
	req.Header.Set("Content-Type", "text/xml")
	req.SetBasicAuth("admin", *key)

	if *dryRun || *debug {
		req.Write(os.Stdout)
	}

	if *dryRun {
		return
	}

	client := http.Client{}
	resp, err := client.Do(req)

	if err != nil {
		fmt.Printf(err.Error())
		os.Exit(-1)
	}

	body, _ = ioutil.ReadAll(resp.Body)
	os.Stdout.Write(body)
	fmt.Printf("\n")

	if resp.StatusCode != 200 {
		fmt.Printf("Error: bad return code %s\n", resp.Status)
		os.Exit(-1)
	}

	return
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package main

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

	"github.com/mvdan/gibot/site/gitlab"
)

const listenAddr = ":9990"

func webhookListen() {
	for _, repo := range repos {
		listenRepo(repo)
	}

	log.Fatal(http.ListenAndServe(listenAddr, nil))
}

func listenRepo(repo *gitlab.Repo) {
	path := fmt.Sprintf("/webhooks/gitlab/%s", repo.Name)
	http.HandleFunc(path, gitlabHandler(repo.Name))
	log.Printf("Receiving webhooks for %s on %s%s", repo.Name, listenAddr, path)
}

func toInt(v interface{}) int {
	i, ok := v.(float64)
	if !ok {
		return 0
	}
	return int(i)
}

func toStr(v interface{}) string {
	s, ok := v.(string)
	if !ok {
		return ""
	}
	return s
}

func toSlice(v interface{}) []interface{} {
	l, ok := v.([]interface{})
	if !ok {
		return []interface{}{}
	}
	return l
}

func toMap(v interface{}) map[string]interface{} {
	m, ok := v.(map[string]interface{})
	if !ok {
		return map[string]interface{}{}
	}
	return m
}

func gitlabHandler(reponame string) func(http.ResponseWriter, *http.Request) {
	repo, e := repos[reponame]
	if !e {
		panic("unknown repo")
	}
	return func(w http.ResponseWriter, r *http.Request) {
		decoder := json.NewDecoder(r.Body)
		m := make(map[string]interface{})
		if err := decoder.Decode(&m); err != nil {
			log.Printf("Error decoding webhook data: %v", err)
			return
		}
		kind := toStr(m["object_kind"])
		switch kind {
		case "push":
			onPush(repo, m)
		case "issue":
			onIssue(repo, m)
		case "merge_request":
			onMergeRequest(repo, m)
		case "tag_push":
		case "note":
		default:
			log.Printf("Webhook event we don't handle: %s", kind)
			return
		}
	}
}

var headBranch = regexp.MustCompile(`^refs/heads/(.*)$`)

func getBranch(ref string) string {
	if s := headBranch.FindStringSubmatch(ref); s != nil {
		return s[1]
	}
	log.Printf("Unknown branch ref format: %s", ref)
	return ""
}

func onPush(r *gitlab.Repo, m map[string]interface{}) {
	userID := toInt(m["user_id"])
	user, err := r.GetUser(userID)
	if err != nil {
		log.Printf("Unknown user: %v", err)
		return
	}
	username := user.Username
	branch := getBranch(toStr(m["ref"]))
	if branch == "" {
		return
	}
	count := toInt(m["total_commits_count"])
	var message string
	if count > 1 {
		before := toStr(m["before"])
		after := toStr(m["after"])
		url := r.CompareURL(before, after)
		message = fmt.Sprintf("%s pushed %d commits to %s - %s", username, count, branch, url)
	} else {
		commits := toSlice(m["commits"])
		if len(commits) == 0 {
			log.Printf("Empty commits")
			return
		}
		commit := toMap(commits[0])
		title := gitlab.ShortTitle(toStr(commit["message"]))
		sha := toStr(commit["id"])
		short := gitlab.ShortCommit(sha)
		url := r.CommitURL(short)
		message = fmt.Sprintf("%s pushed to %s: %s - %s", username, branch, title, url)
	}
	sendNotices(config.Feeds, r.Name, message)
}

func onIssue(r *gitlab.Repo, m map[string]interface{}) {
	user := toMap(m["user"])
	username := toStr(user["username"])
	attrs := toMap(m["object_attributes"])
	iid := toInt(attrs["iid"])
	title := gitlab.ShortTitle(toStr(attrs["title"]))
	url := toStr(attrs["url"])
	action := toStr(attrs["action"])
	var message string
	switch action {
	case "open":
		message = fmt.Sprintf("%s opened #%d: %s - %s", username, iid, title, url)
	case "close":
		message = fmt.Sprintf("%s closed #%d: %s - %s", username, iid, title, url)
	case "reopen":
		message = fmt.Sprintf("%s reopened #%d: %s - %s", username, iid, title, url)
	case "update":
		return
	default:
		log.Printf("Issue action we don't handle: %s", action)
		return
	}
	sendNotices(config.Feeds, r.Name, message)
}

func onMergeRequest(r *gitlab.Repo, m map[string]interface{}) {
	user := toMap(m["user"])
	username := toStr(user["username"])
	attrs := toMap(m["object_attributes"])
	iid := toInt(attrs["iid"])
	title := gitlab.ShortTitle(toStr(attrs["title"]))
	url := toStr(attrs["url"])
	action := toStr(attrs["action"])
	var message string
	switch action {
	case "open":
		message = fmt.Sprintf("%s opened !%d: %s - %s", username, iid, title, url)
	case "merge":
		message = fmt.Sprintf("%s merged !%d: %s - %s", username, iid, title, url)
	case "close":
		message = fmt.Sprintf("%s closed !%d: %s - %s", username, iid, title, url)
	case "reopen":
		message = fmt.Sprintf("%s reopened !%d: %s - %s", username, iid, title, url)
	case "update":
		return
	default:
		log.Printf("Merge Request action we don't handle: %s", action)
		return
	}
	sendNotices(config.Feeds, r.Name, message)
}
<commit_msg>Don't notify on close/reopen of MRs<commit_after>// Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package main

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

	"github.com/mvdan/gibot/site/gitlab"
)

const listenAddr = ":9990"

func webhookListen() {
	for _, repo := range repos {
		listenRepo(repo)
	}

	log.Fatal(http.ListenAndServe(listenAddr, nil))
}

func listenRepo(repo *gitlab.Repo) {
	path := fmt.Sprintf("/webhooks/gitlab/%s", repo.Name)
	http.HandleFunc(path, gitlabHandler(repo.Name))
	log.Printf("Receiving webhooks for %s on %s%s", repo.Name, listenAddr, path)
}

func toInt(v interface{}) int {
	i, ok := v.(float64)
	if !ok {
		return 0
	}
	return int(i)
}

func toStr(v interface{}) string {
	s, ok := v.(string)
	if !ok {
		return ""
	}
	return s
}

func toSlice(v interface{}) []interface{} {
	l, ok := v.([]interface{})
	if !ok {
		return []interface{}{}
	}
	return l
}

func toMap(v interface{}) map[string]interface{} {
	m, ok := v.(map[string]interface{})
	if !ok {
		return map[string]interface{}{}
	}
	return m
}

func gitlabHandler(reponame string) func(http.ResponseWriter, *http.Request) {
	repo, e := repos[reponame]
	if !e {
		panic("unknown repo")
	}
	return func(w http.ResponseWriter, r *http.Request) {
		decoder := json.NewDecoder(r.Body)
		m := make(map[string]interface{})
		if err := decoder.Decode(&m); err != nil {
			log.Printf("Error decoding webhook data: %v", err)
			return
		}
		kind := toStr(m["object_kind"])
		switch kind {
		case "push":
			onPush(repo, m)
		case "issue":
			onIssue(repo, m)
		case "merge_request":
			onMergeRequest(repo, m)
		case "tag_push":
		case "note":
		default:
			log.Printf("Webhook event we don't handle: %s", kind)
			return
		}
	}
}

var headBranch = regexp.MustCompile(`^refs/heads/(.*)$`)

func getBranch(ref string) string {
	if s := headBranch.FindStringSubmatch(ref); s != nil {
		return s[1]
	}
	log.Printf("Unknown branch ref format: %s", ref)
	return ""
}

func onPush(r *gitlab.Repo, m map[string]interface{}) {
	userID := toInt(m["user_id"])
	user, err := r.GetUser(userID)
	if err != nil {
		log.Printf("Unknown user: %v", err)
		return
	}
	username := user.Username
	branch := getBranch(toStr(m["ref"]))
	if branch == "" {
		return
	}
	count := toInt(m["total_commits_count"])
	var message string
	if count > 1 {
		before := toStr(m["before"])
		after := toStr(m["after"])
		url := r.CompareURL(before, after)
		message = fmt.Sprintf("%s pushed %d commits to %s - %s", username, count, branch, url)
	} else {
		commits := toSlice(m["commits"])
		if len(commits) == 0 {
			log.Printf("Empty commits")
			return
		}
		commit := toMap(commits[0])
		title := gitlab.ShortTitle(toStr(commit["message"]))
		sha := toStr(commit["id"])
		short := gitlab.ShortCommit(sha)
		url := r.CommitURL(short)
		message = fmt.Sprintf("%s pushed to %s: %s - %s", username, branch, title, url)
	}
	sendNotices(config.Feeds, r.Name, message)
}

func onIssue(r *gitlab.Repo, m map[string]interface{}) {
	user := toMap(m["user"])
	username := toStr(user["username"])
	attrs := toMap(m["object_attributes"])
	iid := toInt(attrs["iid"])
	title := gitlab.ShortTitle(toStr(attrs["title"]))
	url := toStr(attrs["url"])
	action := toStr(attrs["action"])
	var message string
	switch action {
	case "open":
		message = fmt.Sprintf("%s opened #%d: %s - %s", username, iid, title, url)
	case "close":
		message = fmt.Sprintf("%s closed #%d: %s - %s", username, iid, title, url)
	case "reopen":
		message = fmt.Sprintf("%s reopened #%d: %s - %s", username, iid, title, url)
	case "update":
		return
	default:
		log.Printf("Issue action we don't handle: %s", action)
		return
	}
	sendNotices(config.Feeds, r.Name, message)
}

func onMergeRequest(r *gitlab.Repo, m map[string]interface{}) {
	user := toMap(m["user"])
	username := toStr(user["username"])
	attrs := toMap(m["object_attributes"])
	iid := toInt(attrs["iid"])
	title := gitlab.ShortTitle(toStr(attrs["title"]))
	url := toStr(attrs["url"])
	action := toStr(attrs["action"])
	var message string
	switch action {
	case "open":
		message = fmt.Sprintf("%s opened !%d: %s - %s", username, iid, title, url)
	case "merge":
		message = fmt.Sprintf("%s merged !%d: %s - %s", username, iid, title, url)
	case "close", "reopen", "update":
		return
	default:
		log.Printf("Merge Request action we don't handle: %s", action)
		return
	}
	sendNotices(config.Feeds, r.Name, message)
}
<|endoftext|>


<commit_before>package main

import "net/http"

func init() {
	http.HandleFunc("/push", handlePush)
	http.HandleFunc("/deploy", handleDeploy)
	http.HandleFunc("/release", handleRelease)
}

func handlePush(w http.ResponseWriter, req *http.Request) {
	processes.Add(1)
	defer processes.Done()
	http.Error(w, "", http.StatusNotImplemented)
}

func handleDeploy(w http.ResponseWriter, req *http.Request) {
	processes.Add(1)
	defer processes.Done()
	http.Error(w, "", http.StatusNotImplemented)
}

func handleRelease(w http.ResponseWriter, req *http.Request) {
	processes.Add(1)
	defer processes.Done()
	http.Error(w, "", http.StatusNotImplemented)
}
<commit_msg>Overhaul of routes. Simplifies configuration github side.<commit_after>package main

import (
	"fmt"
	"net/http"
)

func init() {
	http.HandleFunc("/hook", handleHook)
	http.HandleFunc("/", handleRoot)
}

func handleRoot(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(w, "")
	fmt.Fprintln(w, "Welcome to Autobot!
")
	fmt.Fprintln(w, "Autobot is designed to be interfaced with Github's Webhooks API.
")
	fmt.Fprintf(w, "To use, setup your projects Github repository to use the Webhook %s.
\n", hookAddress(req))
	fmt.Fprintln(w, "")
}

func handleHook(w http.ResponseWriter, req *http.Request) {
	processes.Add(1)
	defer processes.Done()
	http.Error(w, "", http.StatusNotImplemented)
}
<|endoftext|>


<commit_before>package ploop

// A test suite, also serving as an example of how to use the package

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"testing"

	"github.com/dustin/go-humanize"
)

var (
	old_pwd  string
	test_dir string
	d        Ploop
	snap     string
)

const baseDelta = "root.hdd"

// abort is used when the tests after the current one
// can't be run as one of their prerequisite(s) failed
func abort(format string, args ...interface{}) {
	s := fmt.Sprintf("ABORT: "+format+"\n", args...)
	f := bufio.NewWriter(os.Stderr)
	f.Write([]byte(s))
	f.Flush()
	cleanup()
	os.Exit(1)
}

// Check for a fatal error, call abort() if it is
func chk(err error) {
	if err != nil {
		abort("%s", err)
	}
}

func prepare(dir string) {
	var err error

	old_pwd, err = os.Getwd()
	chk(err)

	test_dir, err = ioutil.TempDir(old_pwd, dir)
	chk(err)

	err = os.Chdir(test_dir)
	chk(err)

	SetVerboseLevel(255)
}

func TestPrepare(t *testing.T) {
	prepare("tmp-test")
}

func TestUUID(t *testing.T) {
	uuid, e := UUID()
	if e != nil {
		t.Errorf("UUID: %s", e)
	}

	t.Logf("Got uuid %s", uuid)
}

func create() {
	size := "384M"
	var p CreateParam

	s, e := humanize.ParseBytes(size)
	if e != nil {
		abort("humanize.ParseBytes: can't parse %s: %s", size, e)
	}
	p.Size = s / 1024
	p.File = baseDelta

	e = Create(&p)
	if e != nil {
		abort("Create: %s", e)
	}
}

func TestCreate(t *testing.T) {
	create()
}

func open() {
	var e error

	d, e = Open("DiskDescriptor.xml")
	if e != nil {
		abort("Open: %s", e)
	}
}

func TestOpen(t *testing.T) {
	open()
}

func TestMount(t *testing.T) {
	mnt := "mnt"

	e := os.Mkdir(mnt, 0755)
	chk(e)

	p := MountParam{Target: mnt}
	dev, e := d.Mount(&p)
	if e != nil {
		abort("Mount: %s", e)
	}

	t.Logf("Mounted; ploop device %s", dev)
}

func resize(t *testing.T, size string, offline bool) {
	if offline && testing.Short() {
		t.Skip("skipping offline resize test in short mode.")
	}
	s, e := humanize.ParseBytes(size)
	if e != nil {
		t.Fatalf("humanize.ParseBytes: can't parse %s: %s", size, e)
	}
	s = s / 1024

	e = d.Resize(s, offline)
	if e != nil {
		t.Fatalf("Resize to %s (%d bytes) failed: %s", size, s, e)
	}
}

func TestResizeOnlineShrink(t *testing.T) {
	resize(t, "256MB", false)
}

func TestResizeOnlineGrow(t *testing.T) {
	resize(t, "512MB", false)
}

func TestSnapshot(t *testing.T) {
	uuid, e := d.Snapshot()
	if e != nil {
		abort("Snapshot: %s", e)
	}

	t.Logf("Created online snapshot; uuid %s", uuid)
	snap = uuid
}

func copyFile(src, dst string) error {
	return exec.Command("cp", "-a", src, dst).Run()
}

func testReplace(t *testing.T) {
	var p ReplaceParam
	newDelta := baseDelta + ".new"
	e := copyFile(baseDelta, newDelta)
	if e != nil {
		t.Fatalf("copyFile: %s", e)
	}

	p.File = newDelta
	p.CurFile = baseDelta
	p.Flags = KeepName
	e = d.Replace(&p)
	if e != nil {
		t.Fatalf("Replace: %s", e)
	}
}

func TestReplaceOnline(t *testing.T) {
	testReplace(t)
}

func TestSwitchSnapshotOnline(t *testing.T) {
	e := d.SwitchSnapshot(snap)
	// should fail with E_PARAM
	if IsError(e, E_PARAM) {
		t.Logf("SwitchSnapshot: (online) good, expected error")
	} else {
		t.Fatalf("SwitchSnapshot: (should fail): %s", e)
	}
}

func TestDeleteSnapshot(t *testing.T) {
	e := d.DeleteSnapshot(snap)
	if e != nil {
		t.Fatalf("DeleteSnapshot: %s", e)
	} else {
		t.Logf("Deleted snapshot %s", snap)
	}
}

func TestIsMounted1(t *testing.T) {
	m, e := d.IsMounted()
	if e != nil {
		t.Fatalf("IsMounted: %s", e)
	}
	if !m {
		t.Fatalf("IsMounted: unexpectedly returned false")
	}
}

func TestUmount(t *testing.T) {
	e := d.Umount()
	if e != nil {
		t.Fatalf("Umount: %s", e)
	}
}

func TestIsMounted2(t *testing.T) {
	m, e := d.IsMounted()
	if e != nil {
		t.Fatalf("IsMounted: %s", e)
	}
	if m {
		t.Fatalf("IsMounted: unexpectedly returned true")
	}
}

func TestUmountAgain(t *testing.T) {
	e := d.Umount()
	if IsNotMounted(e) {
		t.Logf("Umount: (not mounted) good, expected error")
	} else {
		t.Fatalf("Umount: %s", e)
	}
}

func TestResizeOfflineShrink(t *testing.T) {
	resize(t, "256MB", true)
}

func TestResizeOfflineGrow(t *testing.T) {
	resize(t, "512MB", true)
}

func TestResizeOfflineShrinkAgain(t *testing.T) {
	resize(t, "256MB", true)
}

func TestSnapshotOffline(t *testing.T) {
	uuid, e := d.Snapshot()
	if e != nil {
		t.Fatalf("Snapshot: %s", e)
	} else {
		t.Logf("Created offline snapshot; uuid %s", uuid)
	}

	snap = uuid
}

func TestReplaceOffline(t *testing.T) {
	testReplace(t)
}

func TestSwitchSnapshot(t *testing.T) {
	e := d.SwitchSnapshot(snap)
	if e != nil {
		t.Fatalf("SwitchSnapshot: %s", e)
	} else {
		t.Logf("Switched to snapshot %s", snap)
	}
}

func TestFSInfo(t *testing.T) {
	i, e := FSInfo("DiskDescriptor.xml")

	if e != nil {
		t.Errorf("FSInfo: %v", e)
	} else {
		bTotal := i.Blocks * i.BlockSize
		bAvail := i.BlocksFree * i.BlockSize
		bUsed := bTotal - bAvail

		iTotal := i.Inodes
		iAvail := i.InodesFree
		iUsed := iTotal - iAvail

		t.Logf("\n             Size       Used      Avail Use%%\n%7s %9s %10s %10s %3d%%\n%7s %9d %10d %10d %3d%%",
			"Blocks",
			humanize.Bytes(bTotal),
			humanize.Bytes(bUsed),
			humanize.Bytes(bAvail),
			100*bUsed/bTotal,
			"Inodes",
			iTotal,
			iUsed,
			iAvail,
			100*iUsed/iTotal)
		t.Logf("\nInode ratio: 1 inode per %s of disk space",
			humanize.Bytes(bTotal/iTotal))
	}
}

func TestImageInfo(t *testing.T) {
	i, e := d.ImageInfo()
	if e != nil {
		t.Errorf("ImageInfo: %v", e)
	} else {
		t.Logf("\n              Blocks  Blocksize       Size  Ver\n%20d %10d %10s %4d",
			i.Blocks, i.BlockSize,
			humanize.Bytes(512*i.Blocks),
			i.Version)
	}

}

func cleanup() {
	if d.dd != "" {
		if m, _ := d.IsMounted(); m {
			d.Umount()
		}
		d.Close()
	}
	if old_pwd != "" {
		os.Chdir(old_pwd)
	}
	if test_dir != "" {
		os.RemoveAll(test_dir)
	}
}

// TestCleanup is the last test, removing files created by previous tests
func TestCleanup(t *testing.T) {
	cleanup()
}

func BenchmarkMountUmount(b *testing.B) {
	b.StopTimer()
	prepare("tmp-bench")
	create()
	open()
	mnt := "mnt"
	e := os.Mkdir(mnt, 0755)
	chk(e)
	p := MountParam{Target: mnt, Readonly: true}

	b.StartTimer()
	for n := 0; n < b.N; n++ {
		_, e := d.Mount(&p)
		if e != nil {
			b.Fatalf("Mount: %s", e)
		}
		e = d.Umount()
		if e != nil {
			b.Fatalf("Umount: %s", e)
		}
	}
	b.StopTimer()
	cleanup()
}
<commit_msg>tests: run with minimal output by default<commit_after>package ploop

// A test suite, also serving as an example of how to use the package

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"testing"

	"github.com/dustin/go-humanize"
)

var (
	old_pwd  string
	test_dir string
	d        Ploop
	snap     string
)

const baseDelta = "root.hdd"

// abort is used when the tests after the current one
// can't be run as one of their prerequisite(s) failed
func abort(format string, args ...interface{}) {
	s := fmt.Sprintf("ABORT: "+format+"\n", args...)
	f := bufio.NewWriter(os.Stderr)
	f.Write([]byte(s))
	f.Flush()
	cleanup()
	os.Exit(1)
}

// Check for a fatal error, call abort() if it is
func chk(err error) {
	if err != nil {
		abort("%s", err)
	}
}

func prepare(dir string) {
	var err error

	old_pwd, err = os.Getwd()
	chk(err)

	test_dir, err = ioutil.TempDir(old_pwd, dir)
	chk(err)

	err = os.Chdir(test_dir)
	chk(err)

	SetVerboseLevel(NoStdout)
}

func TestPrepare(t *testing.T) {
	prepare("tmp-test")
}

func TestUUID(t *testing.T) {
	uuid, e := UUID()
	if e != nil {
		t.Errorf("UUID: %s", e)
	}

	t.Logf("Got uuid %s", uuid)
}

func create() {
	size := "384M"
	var p CreateParam

	s, e := humanize.ParseBytes(size)
	if e != nil {
		abort("humanize.ParseBytes: can't parse %s: %s", size, e)
	}
	p.Size = s / 1024
	p.File = baseDelta

	e = Create(&p)
	if e != nil {
		abort("Create: %s", e)
	}
}

func TestCreate(t *testing.T) {
	create()
}

func open() {
	var e error

	d, e = Open("DiskDescriptor.xml")
	if e != nil {
		abort("Open: %s", e)
	}
}

func TestOpen(t *testing.T) {
	open()
}

func TestMount(t *testing.T) {
	mnt := "mnt"

	e := os.Mkdir(mnt, 0755)
	chk(e)

	p := MountParam{Target: mnt}
	dev, e := d.Mount(&p)
	if e != nil {
		abort("Mount: %s", e)
	}

	t.Logf("Mounted; ploop device %s", dev)
}

func resize(t *testing.T, size string, offline bool) {
	if offline && testing.Short() {
		t.Skip("skipping offline resize test in short mode.")
	}
	s, e := humanize.ParseBytes(size)
	if e != nil {
		t.Fatalf("humanize.ParseBytes: can't parse %s: %s", size, e)
	}
	s = s / 1024

	e = d.Resize(s, offline)
	if e != nil {
		t.Fatalf("Resize to %s (%d bytes) failed: %s", size, s, e)
	}
}

func TestResizeOnlineShrink(t *testing.T) {
	resize(t, "256MB", false)
}

func TestResizeOnlineGrow(t *testing.T) {
	resize(t, "512MB", false)
}

func TestSnapshot(t *testing.T) {
	uuid, e := d.Snapshot()
	if e != nil {
		abort("Snapshot: %s", e)
	}

	t.Logf("Created online snapshot; uuid %s", uuid)
	snap = uuid
}

func copyFile(src, dst string) error {
	return exec.Command("cp", "-a", src, dst).Run()
}

func testReplace(t *testing.T) {
	var p ReplaceParam
	newDelta := baseDelta + ".new"
	e := copyFile(baseDelta, newDelta)
	if e != nil {
		t.Fatalf("copyFile: %s", e)
	}

	p.File = newDelta
	p.CurFile = baseDelta
	p.Flags = KeepName
	e = d.Replace(&p)
	if e != nil {
		t.Fatalf("Replace: %s", e)
	}
}

func TestReplaceOnline(t *testing.T) {
	testReplace(t)
}

func TestSwitchSnapshotOnline(t *testing.T) {
	e := d.SwitchSnapshot(snap)
	// should fail with E_PARAM
	if IsError(e, E_PARAM) {
		t.Logf("SwitchSnapshot: (online) good, expected error")
	} else {
		t.Fatalf("SwitchSnapshot: (should fail): %s", e)
	}
}

func TestDeleteSnapshot(t *testing.T) {
	e := d.DeleteSnapshot(snap)
	if e != nil {
		t.Fatalf("DeleteSnapshot: %s", e)
	} else {
		t.Logf("Deleted snapshot %s", snap)
	}
}

func TestIsMounted1(t *testing.T) {
	m, e := d.IsMounted()
	if e != nil {
		t.Fatalf("IsMounted: %s", e)
	}
	if !m {
		t.Fatalf("IsMounted: unexpectedly returned false")
	}
}

func TestUmount(t *testing.T) {
	e := d.Umount()
	if e != nil {
		t.Fatalf("Umount: %s", e)
	}
}

func TestIsMounted2(t *testing.T) {
	m, e := d.IsMounted()
	if e != nil {
		t.Fatalf("IsMounted: %s", e)
	}
	if m {
		t.Fatalf("IsMounted: unexpectedly returned true")
	}
}

func TestUmountAgain(t *testing.T) {
	e := d.Umount()
	if IsNotMounted(e) {
		t.Logf("Umount: (not mounted) good, expected error")
	} else {
		t.Fatalf("Umount: %s", e)
	}
}

func TestResizeOfflineShrink(t *testing.T) {
	resize(t, "256MB", true)
}

func TestResizeOfflineGrow(t *testing.T) {
	resize(t, "512MB", true)
}

func TestResizeOfflineShrinkAgain(t *testing.T) {
	resize(t, "256MB", true)
}

func TestSnapshotOffline(t *testing.T) {
	uuid, e := d.Snapshot()
	if e != nil {
		t.Fatalf("Snapshot: %s", e)
	} else {
		t.Logf("Created offline snapshot; uuid %s", uuid)
	}

	snap = uuid
}

func TestReplaceOffline(t *testing.T) {
	testReplace(t)
}

func TestSwitchSnapshot(t *testing.T) {
	e := d.SwitchSnapshot(snap)
	if e != nil {
		t.Fatalf("SwitchSnapshot: %s", e)
	} else {
		t.Logf("Switched to snapshot %s", snap)
	}
}

func TestFSInfo(t *testing.T) {
	i, e := FSInfo("DiskDescriptor.xml")

	if e != nil {
		t.Errorf("FSInfo: %v", e)
	} else {
		bTotal := i.Blocks * i.BlockSize
		bAvail := i.BlocksFree * i.BlockSize
		bUsed := bTotal - bAvail

		iTotal := i.Inodes
		iAvail := i.InodesFree
		iUsed := iTotal - iAvail

		t.Logf("\n             Size       Used      Avail Use%%\n%7s %9s %10s %10s %3d%%\n%7s %9d %10d %10d %3d%%",
			"Blocks",
			humanize.Bytes(bTotal),
			humanize.Bytes(bUsed),
			humanize.Bytes(bAvail),
			100*bUsed/bTotal,
			"Inodes",
			iTotal,
			iUsed,
			iAvail,
			100*iUsed/iTotal)
		t.Logf("\nInode ratio: 1 inode per %s of disk space",
			humanize.Bytes(bTotal/iTotal))
	}
}

func TestImageInfo(t *testing.T) {
	i, e := d.ImageInfo()
	if e != nil {
		t.Errorf("ImageInfo: %v", e)
	} else {
		t.Logf("\n              Blocks  Blocksize       Size  Ver\n%20d %10d %10s %4d",
			i.Blocks, i.BlockSize,
			humanize.Bytes(512*i.Blocks),
			i.Version)
	}

}

func cleanup() {
	if d.dd != "" {
		if m, _ := d.IsMounted(); m {
			d.Umount()
		}
		d.Close()
	}
	if old_pwd != "" {
		os.Chdir(old_pwd)
	}
	if test_dir != "" {
		os.RemoveAll(test_dir)
	}
}

// TestCleanup is the last test, removing files created by previous tests
func TestCleanup(t *testing.T) {
	cleanup()
}

func BenchmarkMountUmount(b *testing.B) {
	b.StopTimer()
	prepare("tmp-bench")
	SetVerboseLevel(NoStdout)
	create()
	open()
	mnt := "mnt"
	e := os.Mkdir(mnt, 0755)
	chk(e)
	p := MountParam{Target: mnt, Readonly: true}

	b.StartTimer()
	for n := 0; n < b.N; n++ {
		_, e := d.Mount(&p)
		if e != nil {
			b.Fatalf("Mount: %s", e)
		}
		e = d.Umount()
		if e != nil {
			b.Fatalf("Umount: %s", e)
		}
	}
	b.StopTimer()
	cleanup()
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"regexp"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	events "github.com/aws/aws-sdk-go/service/cloudwatchevents"
)

func resourceAwsCloudWatchEventTarget() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsCloudWatchEventTargetCreate,
		Read:   resourceAwsCloudWatchEventTargetRead,
		Update: resourceAwsCloudWatchEventTargetUpdate,
		Delete: resourceAwsCloudWatchEventTargetDelete,

		Schema: map[string]*schema.Schema{
			"rule": &schema.Schema{
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validateCloudWatchEventRuleName,
			},

			"target_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},

			"arn": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},

			"input": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"input_path"},
				// We could be normalizing the JSON here,
				// but for built-in targets input may not be JSON
			},

			"input_path": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"input"},
			},
		},
	}
}

func resourceAwsCloudWatchEventTargetCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	rule := d.Get("rule").(string)

	input, targetId := buildPutTargetInputStruct(d)
	log.Printf("[DEBUG] Creating CloudWatch Event Target: %s", input)
	out, err := conn.PutTargets(input)
	if err != nil {
		return fmt.Errorf("Creating CloudWatch Event Target failed: %s", err)
	}

	if len(out.FailedEntries) > 0 {
		return fmt.Errorf("Creating CloudWatch Event Target failed: %s",
			out.FailedEntries)
	}

	id := rule + "-" + targetId
	d.SetId(id)

	log.Printf("[INFO] CloudWatch Event Target %q created", d.Id())

	return resourceAwsCloudWatchEventTargetRead(d, meta)
}

func resourceAwsCloudWatchEventTargetRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	t, err := findEventTargetById(
		d.Get("target_id").(string),
		d.Get("rule").(string),
		nil, conn)
	if err != nil {
		if regexp.MustCompile(" not found$").MatchString(err.Error()) {
			log.Printf("[WARN] Removing CloudWatch Event Target %q because it's gone.", d.Id())
			d.SetId("")
			return nil
		}
		if awsErr, ok := err.(awserr.Error); ok {
			// This should never happen, but it's useful
			// for recovering from https://github.com/hashicorp/terraform/issues/5389
			if awsErr.Code() == "ValidationException" {
				log.Printf("[WARN] Removing CloudWatch Event Target %q because it never existed.", d.Id())
				d.SetId("")
				return nil
			}
		}
		return err
	}
	log.Printf("[DEBUG] Found Event Target: %s", t)

	d.Set("arn", t.Arn)
	d.Set("target_id", t.Id)
	d.Set("input", t.Input)
	d.Set("input_path", t.InputPath)

	return nil
}

func findEventTargetById(id, rule string, nextToken *string, conn *events.CloudWatchEvents) (
	*events.Target, error) {
	input := events.ListTargetsByRuleInput{
		Rule:      aws.String(rule),
		NextToken: nextToken,
		Limit:     aws.Int64(100), // Set limit to allowed maximum to prevent API throttling
	}
	log.Printf("[DEBUG] Reading CloudWatch Event Target: %s", input)
	out, err := conn.ListTargetsByRule(&input)
	if err != nil {
		return nil, err
	}

	for _, t := range out.Targets {
		if *t.Id == id {
			return t, nil
		}
	}

	if out.NextToken != nil {
		return findEventTargetById(id, rule, nextToken, conn)
	}

	return nil, fmt.Errorf("CloudWatch Event Target %q (%q) not found", id, rule)
}

func resourceAwsCloudWatchEventTargetUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	input, _ := buildPutTargetInputStruct(d)
	log.Printf("[DEBUG] Updating CloudWatch Event Target: %s", input)
	_, err := conn.PutTargets(input)
	if err != nil {
		return fmt.Errorf("Updating CloudWatch Event Target failed: %s", err)
	}

	return resourceAwsCloudWatchEventTargetRead(d, meta)
}

func resourceAwsCloudWatchEventTargetDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	input := events.RemoveTargetsInput{
		Ids:  []*string{aws.String(d.Get("target_id").(string))},
		Rule: aws.String(d.Get("rule").(string)),
	}
	log.Printf("[INFO] Deleting CloudWatch Event Target: %s", input)
	_, err := conn.RemoveTargets(&input)
	if err != nil {
		return fmt.Errorf("Error deleting CloudWatch Event Target: %s", err)
	}
	log.Println("[INFO] CloudWatch Event Target deleted")

	d.SetId("")

	return nil
}

func buildPutTargetInputStruct(d *schema.ResourceData) (*events.PutTargetsInput, string) {
	var targetId string
	if v, ok := d.GetOk("target_id"); ok {
		targetId = v.(string)
	} else {
		targetId = resource.UniqueId()
	}

	e := &events.Target{
		Arn: aws.String(d.Get("arn").(string)),
		Id:  aws.String(targetId),
	}

	if v, ok := d.GetOk("input"); ok {
		e.Input = aws.String(v.(string))
	}
	if v, ok := d.GetOk("input_path"); ok {
		e.InputPath = aws.String(v.(string))
	}

	input := events.PutTargetsInput{
		Rule:    aws.String(d.Get("rule").(string)),
		Targets: []*events.Target{e},
	}

	return &input, targetId
}
<commit_msg>ISSUE-5702: 2nd attempt to impl the target_id be optional<commit_after>package aws

import (
	"fmt"
	"log"
	"regexp"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	events "github.com/aws/aws-sdk-go/service/cloudwatchevents"
)

func resourceAwsCloudWatchEventTarget() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsCloudWatchEventTargetCreate,
		Read:   resourceAwsCloudWatchEventTargetRead,
		Update: resourceAwsCloudWatchEventTargetUpdate,
		Delete: resourceAwsCloudWatchEventTargetDelete,

		Schema: map[string]*schema.Schema{
			"rule": &schema.Schema{
				Type:         schema.TypeString,
				Required:     true,
				ForceNew:     true,
				ValidateFunc: validateCloudWatchEventRuleName,
			},

			"target_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
				ValidateFunc: validateCloudWatchEventTargetId,
			},

			"arn": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},

			"input": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"input_path"},
				// We could be normalizing the JSON here,
				// but for built-in targets input may not be JSON
			},

			"input_path": &schema.Schema{
				Type:          schema.TypeString,
				Optional:      true,
				ConflictsWith: []string{"input"},
			},
		},
	}
}

func resourceAwsCloudWatchEventTargetCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	rule := d.Get("rule").(string)

	var targetId string
	if v, ok := d.GetOk("target_id"); ok {
		targetId = v.(string)
	} else {
		targetId = resource.UniqueId()
		d.Set("target_id", targetId)
	}

	input := buildPutTargetInputStruct(d)
	log.Printf("[DEBUG] Creating CloudWatch Event Target: %s", input)
	out, err := conn.PutTargets(input)
	if err != nil {
		return fmt.Errorf("Creating CloudWatch Event Target failed: %s", err)
	}

	if len(out.FailedEntries) > 0 {
		return fmt.Errorf("Creating CloudWatch Event Target failed: %s",
			out.FailedEntries)
	}

	id := rule + "-" + targetId
	d.SetId(id)

	log.Printf("[INFO] CloudWatch Event Target %q created", d.Id())

	return resourceAwsCloudWatchEventTargetRead(d, meta)
}

func resourceAwsCloudWatchEventTargetRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	t, err := findEventTargetById(
		d.Get("target_id").(string),
		d.Get("rule").(string),
		nil, conn)
	if err != nil {
		if regexp.MustCompile(" not found$").MatchString(err.Error()) {
			log.Printf("[WARN] Removing CloudWatch Event Target %q because it's gone.", d.Id())
			d.SetId("")
			return nil
		}
		if awsErr, ok := err.(awserr.Error); ok {
			// This should never happen, but it's useful
			// for recovering from https://github.com/hashicorp/terraform/issues/5389
			if awsErr.Code() == "ValidationException" {
				log.Printf("[WARN] Removing CloudWatch Event Target %q because it never existed.", d.Id())
				d.SetId("")
				return nil
			}
		}
		return err
	}
	log.Printf("[DEBUG] Found Event Target: %s", t)

	d.Set("arn", t.Arn)
	d.Set("target_id", t.Id)
	d.Set("input", t.Input)
	d.Set("input_path", t.InputPath)

	return nil
}

func findEventTargetById(id, rule string, nextToken *string, conn *events.CloudWatchEvents) (
	*events.Target, error) {
	input := events.ListTargetsByRuleInput{
		Rule:      aws.String(rule),
		NextToken: nextToken,
		Limit:     aws.Int64(100), // Set limit to allowed maximum to prevent API throttling
	}
	log.Printf("[DEBUG] Reading CloudWatch Event Target: %s", input)
	out, err := conn.ListTargetsByRule(&input)
	if err != nil {
		return nil, err
	}

	for _, t := range out.Targets {
		if *t.Id == id {
			return t, nil
		}
	}

	if out.NextToken != nil {
		return findEventTargetById(id, rule, nextToken, conn)
	}

	return nil, fmt.Errorf("CloudWatch Event Target %q (%q) not found", id, rule)
}

func resourceAwsCloudWatchEventTargetUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	input := buildPutTargetInputStruct(d)
	log.Printf("[DEBUG] Updating CloudWatch Event Target: %s", input)
	_, err := conn.PutTargets(input)
	if err != nil {
		return fmt.Errorf("Updating CloudWatch Event Target failed: %s", err)
	}

	return resourceAwsCloudWatchEventTargetRead(d, meta)
}

func resourceAwsCloudWatchEventTargetDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	input := events.RemoveTargetsInput{
		Ids:  []*string{aws.String(d.Get("target_id").(string))},
		Rule: aws.String(d.Get("rule").(string)),
	}
	log.Printf("[INFO] Deleting CloudWatch Event Target: %s", input)
	_, err := conn.RemoveTargets(&input)
	if err != nil {
		return fmt.Errorf("Error deleting CloudWatch Event Target: %s", err)
	}
	log.Println("[INFO] CloudWatch Event Target deleted")

	d.SetId("")

	return nil
}

func buildPutTargetInputStruct(d *schema.ResourceData) *events.PutTargetsInput {
	e := &events.Target{
		Arn: aws.String(d.Get("arn").(string)),
		Id:  aws.String(d.Get("target_id").(string)),
	}

	if v, ok := d.GetOk("input"); ok {
		e.Input = aws.String(v.(string))
	}
	if v, ok := d.GetOk("input_path"); ok {
		e.InputPath = aws.String(v.(string))
	}

	input := events.PutTargetsInput{
		Rule:    aws.String(d.Get("rule").(string)),
		Targets: []*events.Target{e},
	}

	return &input
}
<|endoftext|>


<commit_before>package io

import (
    "github.com/javouhey/seneca/vendor/github.com/stretchr/testify/assert"
    "github.com/javouhey/seneca/util"
    "testing"
)

func TestVideoReader(t *testing.T) {
    vr := new(VideoReader)
    err := vr.reset2(4,
        func() string { return "/tmp" },
        func() string { return "/" },
        func() int64 { return int64(1234567) },
    )
    assert.Error(t, err, "")

    vr.Filename = "/home/putin/crimea.mp4"
    err = vr.reset2(4,
        func() string { return "/tmp" },
        func() string { return "/" },
        func() int64 { return int64(1234567) },
    )
    assert.Equal(t, vr.Gif, "crimea.gif")
    assert.Equal(t, vr.TmpDir, "/tmp/seneca/1234567")
    assert.Equal(t, vr.PngDir, "/tmp/seneca/1234567/p")
    assert.Equal(t, vr.TmpFile, "img-%04d.png")
}

var vfArgsFixtures = []struct {
    NeedScaling bool
    ScaleFilter string
    SpeedSpec   string
    out         string
    vf          bool
}{
    {true, "600:300", "", "600:300", true},
    {false, "", "", "", false},
    {true, "600:300", "1*PTS", "600:300,1*PTS", true},
    {false, "", "1*PTS", "1*PTS", true},
}

func TestVfArgs(t *testing.T) {
    fg := new(FrameGenerator)
    for i, tt := range vfArgsFixtures {
        a := util.NewArguments()
        a.SpeedSpec = tt.SpeedSpec
        a.NeedScaling = tt.NeedScaling
        a.ScaleFilter = tt.ScaleFilter
        b, s := fg.combineVf(a)
        if b != tt.vf || s != tt.out {
            t.Errorf("%d. Error out(%t), want %t // out(%q), want %q", i, b, tt.vf, s, tt.out)
        }
    }
}
<commit_msg>Solving windows issue 1<commit_after>package io

import (
    "github.com/javouhey/seneca/vendor/github.com/stretchr/testify/assert"
    "github.com/javouhey/seneca/util"
    "os"
    "path/filepath"
    "testing"
)

func TestVideoReader(t *testing.T) {
    var pathsep string = string(os.PathSeparator)

    vr := new(VideoReader)
    err := vr.reset2(4,
        func() string { return filepath.Join([]string{pathsep, "tmp"}...) },
        func() string { return string(os.PathSeparator) },
        func() int64 { return int64(1234567) },
    )
    assert.Error(t, err, "")

    src := []string{string(os.PathSeparator), "home", "putin", "crimea.mp4"}
    vr.Filename = filepath.Join(src...)
    err = vr.reset2(4,
        func() string { return filepath.Join([]string{pathsep, "tmp"}...) },
        func() string { return string(os.PathSeparator) },
        func() int64 { return int64(1234567) },
    )
    assert.Equal(t, vr.Gif, "crimea.gif")

    tmpdir := []string{string(os.PathSeparator), "tmp", "seneca", "1234567"}
    assert.Equal(t, vr.TmpDir, filepath.Join(tmpdir...))

    pngdir := []string{string(os.PathSeparator), "tmp", "seneca", "1234567", "p"}
    assert.Equal(t, vr.PngDir, filepath.Join(pngdir...))
    assert.Equal(t, vr.TmpFile, "img-%04d.png")
}

var vfArgsFixtures = []struct {
    NeedScaling bool
    ScaleFilter string
    SpeedSpec   string
    out         string
    vf          bool
}{
    {true, "600:300", "", "600:300", true},
    {false, "", "", "", false},
    {true, "600:300", "1*PTS", "600:300,1*PTS", true},
    {false, "", "1*PTS", "1*PTS", true},
}

func TestVfArgs(t *testing.T) {
    fg := new(FrameGenerator)
    for i, tt := range vfArgsFixtures {
        a := util.NewArguments()
        a.SpeedSpec = tt.SpeedSpec
        a.NeedScaling = tt.NeedScaling
        a.ScaleFilter = tt.ScaleFilter
        b, s := fg.combineVf(a)
        if b != tt.vf || s != tt.out {
            t.Errorf("%d. Error out(%t), want %t // out(%q), want %q", i, b, tt.vf, s, tt.out)
        }
    }
}
<|endoftext|>


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

package docker

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
)

// ErrNetworkAlreadyExists is the error returned by CreateNetwork when the
// network already exists.
var ErrNetworkAlreadyExists = errors.New("network already exists")

// Network represents a network.
//
// See https://goo.gl/6GugX3 for more details.
type Network struct {
	Name       string
	ID         string `json:"Id"`
	Scope      string
	Driver     string
	IPAM       IPAMOptions
	Containers map[string]Endpoint
	Options    map[string]string
	Internal   bool
	EnableIPv6 bool `json:"EnableIPv6"`
}

// Endpoint contains network resources allocated and used for a container in a network
//
// See https://goo.gl/6GugX3 for more details.
type Endpoint struct {
	Name        string
	ID          string `json:"EndpointID"`
	MacAddress  string
	IPv4Address string
	IPv6Address string
}

// ListNetworks returns all networks.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) ListNetworks() ([]Network, error) {
	resp, err := c.do("GET", "/networks", doOptions{})
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var networks []Network
	if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {
		return nil, err
	}
	return networks, nil
}

// NetworkFilterOpts is an aggregation of key=value that Docker
// uses to filter networks
type NetworkFilterOpts map[string]map[string]bool

// FilteredListNetworks returns all networks with the filters applied
//
// See goo.gl/zd2mx4 for more details.
func (c *Client) FilteredListNetworks(opts NetworkFilterOpts) ([]Network, error) {
	params := bytes.NewBuffer(nil)
	if err := json.NewEncoder(params).Encode(&opts); err != nil {
		return nil, err
	}
	path := "/networks?filters=" + params.String()
	resp, err := c.do("GET", path, doOptions{})
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var networks []Network
	if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {
		return nil, err
	}
	return networks, nil
}

// NetworkInfo returns information about a network by its ID.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) NetworkInfo(id string) (*Network, error) {
	path := "/networks/" + id
	resp, err := c.do("GET", path, doOptions{})
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
			return nil, &NoSuchNetwork{ID: id}
		}
		return nil, err
	}
	defer resp.Body.Close()
	var network Network
	if err := json.NewDecoder(resp.Body).Decode(&network); err != nil {
		return nil, err
	}
	return &network, nil
}

// CreateNetworkOptions specify parameters to the CreateNetwork function and
// (for now) is the expected body of the "create network" http request message
//
// See https://goo.gl/6GugX3 for more details.
type CreateNetworkOptions struct {
	Name           string                 `json:"Name"`
	CheckDuplicate bool                   `json:"CheckDuplicate"`
	Driver         string                 `json:"Driver"`
	IPAM           IPAMOptions            `json:"IPAM"`
	Options        map[string]interface{} `json:"Options"`
	Internal       bool                   `json:"Internal"`
	EnableIPv6     bool                   `json:"EnableIPv6"`
}

// IPAMOptions controls IP Address Management when creating a network
//
// See https://goo.gl/T8kRVH for more details.
type IPAMOptions struct {
	Driver string       `json:"Driver"`
	Config []IPAMConfig `json:"Config"`
}

// IPAMConfig represents IPAM configurations
//
// See https://goo.gl/T8kRVH for more details.
type IPAMConfig struct {
	Subnet     string            `json:",omitempty"`
	IPRange    string            `json:",omitempty"`
	Gateway    string            `json:",omitempty"`
	AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`
}

// CreateNetwork creates a new network, returning the network instance,
// or an error in case of failure.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) CreateNetwork(opts CreateNetworkOptions) (*Network, error) {
	resp, err := c.do(
		"POST",
		"/networks/create",
		doOptions{
			data: opts,
		},
	)
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusConflict {
			return nil, ErrNetworkAlreadyExists
		}
		return nil, err
	}
	defer resp.Body.Close()

	type createNetworkResponse struct {
		ID string
	}
	var (
		network Network
		cnr     createNetworkResponse
	)
	if err := json.NewDecoder(resp.Body).Decode(&cnr); err != nil {
		return nil, err
	}

	network.Name = opts.Name
	network.ID = cnr.ID
	network.Driver = opts.Driver

	return &network, nil
}

// RemoveNetwork removes a network or returns an error in case of failure.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) RemoveNetwork(id string) error {
	resp, err := c.do("DELETE", "/networks/"+id, doOptions{})
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
			return &NoSuchNetwork{ID: id}
		}
		return err
	}
	resp.Body.Close()
	return nil
}

// NetworkConnectionOptions specify parameters to the ConnectNetwork and
// DisconnectNetwork function.
//
// See https://goo.gl/RV7BJU for more details.
type NetworkConnectionOptions struct {
	Container string

	// EndpointConfig is only applicable to the ConnectNetwork call
	EndpointConfig *EndpointConfig `json:"EndpointConfig,omitempty"`

	// Force is only applicable to the DisconnectNetwork call
	Force bool
}

// EndpointConfig stores network endpoint details
//
// See https://goo.gl/RV7BJU for more details.
type EndpointConfig struct {
	IPAMConfig          *EndpointIPAMConfig `json:"IPAMConfig,omitempty" yaml:"IPAMConfig,omitempty"`
	Links               []string            `json:"Links,omitempty" yaml:"Links,omitempty"`
	Aliases             []string            `json:"Aliases,omitempty" yaml:"Aliases,omitempty"`
	NetworkID           string              `json:"NetworkID,omitempty" yaml:"NetworkID,omitempty"`
	EndpointID          string              `json:"EndpointID,omitempty" yaml:"EndpointID,omitempty"`
	Gateway             string              `json:"Gateway,omitempty" yaml:"Gateway,omitempty"`
	IPAddress           string              `json:"IPAddress,omitempty" yaml:"IPAddress,omitempty"`
	IPPrefixLen         int                 `json:"IPPrefixLen,omitempty" yaml:"IPPrefixLen,omitempty"`
	IPv6Gateway         string              `json:"IPv6Gateway,omitempty" yaml:"IPv6Gateway,omitempty"`
	GlobalIPv6Address   string              `json:"GlobalIPv6Address,omitempty" yaml:"GlobalIPv6Address,omitempty"`
	GlobalIPv6PrefixLen int                 `json:"GlobalIPv6PrefixLen,omitempty" yaml:"GlobalIPv6PrefixLen,omitempty"`
	MacAddress          string              `json:"MacAddress,omitempty" yaml:"MacAddress,omitempty"`
}

// EndpointIPAMConfig represents IPAM configurations for an
// endpoint
//
// See https://goo.gl/RV7BJU for more details.
type EndpointIPAMConfig struct {
	IPv4Address string `json:",omitempty"`
	IPv6Address string `json:",omitempty"`
}

// ConnectNetwork adds a container to a network or returns an error in case of
// failure.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) ConnectNetwork(id string, opts NetworkConnectionOptions) error {
	resp, err := c.do("POST", "/networks/"+id+"/connect", doOptions{data: opts})
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
			return &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}
		}
		return err
	}
	resp.Body.Close()
	return nil
}

// DisconnectNetwork removes a container from a network or returns an error in
// case of failure.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) DisconnectNetwork(id string, opts NetworkConnectionOptions) error {
	resp, err := c.do("POST", "/networks/"+id+"/disconnect", doOptions{data: opts})
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
			return &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}
		}
		return err
	}
	resp.Body.Close()
	return nil
}

// NoSuchNetwork is the error returned when a given network does not exist.
type NoSuchNetwork struct {
	ID string
}

func (err *NoSuchNetwork) Error() string {
	return fmt.Sprintf("No such network: %s", err.ID)
}

// NoSuchNetworkOrContainer is the error returned when a given network or
// container does not exist.
type NoSuchNetworkOrContainer struct {
	NetworkID   string
	ContainerID string
}

func (err *NoSuchNetworkOrContainer) Error() string {
	return fmt.Sprintf("No such network (%s) or container (%s)", err.NetworkID, err.ContainerID)
}
<commit_msg>Add yaml tags to createnetworkoptions<commit_after>// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
)

// ErrNetworkAlreadyExists is the error returned by CreateNetwork when the
// network already exists.
var ErrNetworkAlreadyExists = errors.New("network already exists")

// Network represents a network.
//
// See https://goo.gl/6GugX3 for more details.
type Network struct {
	Name       string
	ID         string `json:"Id"`
	Scope      string
	Driver     string
	IPAM       IPAMOptions
	Containers map[string]Endpoint
	Options    map[string]string
	Internal   bool
	EnableIPv6 bool `json:"EnableIPv6"`
}

// Endpoint contains network resources allocated and used for a container in a network
//
// See https://goo.gl/6GugX3 for more details.
type Endpoint struct {
	Name        string
	ID          string `json:"EndpointID"`
	MacAddress  string
	IPv4Address string
	IPv6Address string
}

// ListNetworks returns all networks.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) ListNetworks() ([]Network, error) {
	resp, err := c.do("GET", "/networks", doOptions{})
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var networks []Network
	if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {
		return nil, err
	}
	return networks, nil
}

// NetworkFilterOpts is an aggregation of key=value that Docker
// uses to filter networks
type NetworkFilterOpts map[string]map[string]bool

// FilteredListNetworks returns all networks with the filters applied
//
// See goo.gl/zd2mx4 for more details.
func (c *Client) FilteredListNetworks(opts NetworkFilterOpts) ([]Network, error) {
	params := bytes.NewBuffer(nil)
	if err := json.NewEncoder(params).Encode(&opts); err != nil {
		return nil, err
	}
	path := "/networks?filters=" + params.String()
	resp, err := c.do("GET", path, doOptions{})
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var networks []Network
	if err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {
		return nil, err
	}
	return networks, nil
}

// NetworkInfo returns information about a network by its ID.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) NetworkInfo(id string) (*Network, error) {
	path := "/networks/" + id
	resp, err := c.do("GET", path, doOptions{})
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
			return nil, &NoSuchNetwork{ID: id}
		}
		return nil, err
	}
	defer resp.Body.Close()
	var network Network
	if err := json.NewDecoder(resp.Body).Decode(&network); err != nil {
		return nil, err
	}
	return &network, nil
}

// CreateNetworkOptions specify parameters to the CreateNetwork function and
// (for now) is the expected body of the "create network" http request message
//
// See https://goo.gl/6GugX3 for more details.
type CreateNetworkOptions struct {
	Name           string                 `json:"Name" yaml:"Name"`
	CheckDuplicate bool                   `json:"CheckDuplicate" yaml:"CheckDuplicate"`
	Driver         string                 `json:"Driver" yaml:"Driver"`
	IPAM           IPAMOptions            `json:"IPAM" yaml:"IPAM"`
	Options        map[string]interface{} `json:"Options" yaml:"Options"`
	Internal       bool                   `json:"Internal yaml:"Internal""`
	EnableIPv6     bool                   `json:"EnableIPv6" yaml:"EnableIPv6"`
}

// IPAMOptions controls IP Address Management when creating a network
//
// See https://goo.gl/T8kRVH for more details.
type IPAMOptions struct {
	Driver string       `json:"Driver" yaml:"Driver"`
	Config []IPAMConfig `json:"Config" yaml:"Config"`
}

// IPAMConfig represents IPAM configurations
//
// See https://goo.gl/T8kRVH for more details.
type IPAMConfig struct {
	Subnet     string            `json:",omitempty"`
	IPRange    string            `json:",omitempty"`
	Gateway    string            `json:",omitempty"`
	AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`
}

// CreateNetwork creates a new network, returning the network instance,
// or an error in case of failure.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) CreateNetwork(opts CreateNetworkOptions) (*Network, error) {
	resp, err := c.do(
		"POST",
		"/networks/create",
		doOptions{
			data: opts,
		},
	)
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusConflict {
			return nil, ErrNetworkAlreadyExists
		}
		return nil, err
	}
	defer resp.Body.Close()

	type createNetworkResponse struct {
		ID string
	}
	var (
		network Network
		cnr     createNetworkResponse
	)
	if err := json.NewDecoder(resp.Body).Decode(&cnr); err != nil {
		return nil, err
	}

	network.Name = opts.Name
	network.ID = cnr.ID
	network.Driver = opts.Driver

	return &network, nil
}

// RemoveNetwork removes a network or returns an error in case of failure.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) RemoveNetwork(id string) error {
	resp, err := c.do("DELETE", "/networks/"+id, doOptions{})
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
			return &NoSuchNetwork{ID: id}
		}
		return err
	}
	resp.Body.Close()
	return nil
}

// NetworkConnectionOptions specify parameters to the ConnectNetwork and
// DisconnectNetwork function.
//
// See https://goo.gl/RV7BJU for more details.
type NetworkConnectionOptions struct {
	Container string

	// EndpointConfig is only applicable to the ConnectNetwork call
	EndpointConfig *EndpointConfig `json:"EndpointConfig,omitempty"`

	// Force is only applicable to the DisconnectNetwork call
	Force bool
}

// EndpointConfig stores network endpoint details
//
// See https://goo.gl/RV7BJU for more details.
type EndpointConfig struct {
	IPAMConfig          *EndpointIPAMConfig `json:"IPAMConfig,omitempty" yaml:"IPAMConfig,omitempty"`
	Links               []string            `json:"Links,omitempty" yaml:"Links,omitempty"`
	Aliases             []string            `json:"Aliases,omitempty" yaml:"Aliases,omitempty"`
	NetworkID           string              `json:"NetworkID,omitempty" yaml:"NetworkID,omitempty"`
	EndpointID          string              `json:"EndpointID,omitempty" yaml:"EndpointID,omitempty"`
	Gateway             string              `json:"Gateway,omitempty" yaml:"Gateway,omitempty"`
	IPAddress           string              `json:"IPAddress,omitempty" yaml:"IPAddress,omitempty"`
	IPPrefixLen         int                 `json:"IPPrefixLen,omitempty" yaml:"IPPrefixLen,omitempty"`
	IPv6Gateway         string              `json:"IPv6Gateway,omitempty" yaml:"IPv6Gateway,omitempty"`
	GlobalIPv6Address   string              `json:"GlobalIPv6Address,omitempty" yaml:"GlobalIPv6Address,omitempty"`
	GlobalIPv6PrefixLen int                 `json:"GlobalIPv6PrefixLen,omitempty" yaml:"GlobalIPv6PrefixLen,omitempty"`
	MacAddress          string              `json:"MacAddress,omitempty" yaml:"MacAddress,omitempty"`
}

// EndpointIPAMConfig represents IPAM configurations for an
// endpoint
//
// See https://goo.gl/RV7BJU for more details.
type EndpointIPAMConfig struct {
	IPv4Address string `json:",omitempty"`
	IPv6Address string `json:",omitempty"`
}

// ConnectNetwork adds a container to a network or returns an error in case of
// failure.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) ConnectNetwork(id string, opts NetworkConnectionOptions) error {
	resp, err := c.do("POST", "/networks/"+id+"/connect", doOptions{data: opts})
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
			return &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}
		}
		return err
	}
	resp.Body.Close()
	return nil
}

// DisconnectNetwork removes a container from a network or returns an error in
// case of failure.
//
// See https://goo.gl/6GugX3 for more details.
func (c *Client) DisconnectNetwork(id string, opts NetworkConnectionOptions) error {
	resp, err := c.do("POST", "/networks/"+id+"/disconnect", doOptions{data: opts})
	if err != nil {
		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound {
			return &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}
		}
		return err
	}
	resp.Body.Close()
	return nil
}

// NoSuchNetwork is the error returned when a given network does not exist.
type NoSuchNetwork struct {
	ID string
}

func (err *NoSuchNetwork) Error() string {
	return fmt.Sprintf("No such network: %s", err.ID)
}

// NoSuchNetworkOrContainer is the error returned when a given network or
// container does not exist.
type NoSuchNetworkOrContainer struct {
	NetworkID   string
	ContainerID string
}

func (err *NoSuchNetworkOrContainer) Error() string {
	return fmt.Sprintf("No such network (%s) or container (%s)", err.NetworkID, err.ContainerID)
}
<|endoftext|>


<commit_before>package s3

import (
	"encoding/csv"
	"fmt"
	"io"
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
)

func ExampleS3_SelectObjectContent() {
	sess := session.Must(session.NewSession())
	svc := New(sess)

	/*
	   Example myObjectKey CSV content:

	   name,number
	   gopher,0
	   ᵷodɥǝɹ,1
	*/

	// Make the Select Object Content API request using the object uploaded.
	resp, err := svc.SelectObjectContent(&SelectObjectContentInput{
		Bucket:         aws.String("myBucket"),
		Key:            aws.String("myObjectKey"),
		Expression:     aws.String("SELECT name FROM S3Object WHERE cast(number as int) < 1"),
		ExpressionType: aws.String(ExpressionTypeSql),
		InputSerialization: &InputSerialization{
			CSV: &CSVInput{
				FileHeaderInfo: aws.String(FileHeaderInfoUse),
			},
		},
		OutputSerialization: &OutputSerialization{
			CSV: &CSVOutput{},
		},
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed making API request, %v\n", err)
		return
	}
	defer resp.EventStream.Close()

	results, resultWriter := io.Pipe()
	go func() {
		defer resultWriter.Close()
		for event := range resp.EventStream.Events() {
			switch e := event.(type) {
			case *RecordsEvent:
				resultWriter.Write(e.Payload)
			case *StatsEvent:
				fmt.Printf("Processed %d bytes\n", e.Details.BytesProcessed)
			}
		}
	}()

	// Printout the results
	resReader := csv.NewReader(results)
	for {
		record, err := resReader.Read()
		if err == io.EOF {
			break
		}
		fmt.Println(record)
	}

	if err := resp.EventStream.Err(); err != nil {
		fmt.Fprintf(os.Stderr, "reading from event stream failed, %v\n", err)
	}
}
<commit_msg>Dereference *int64 BytesProcessed in S3 select example (#2042)<commit_after>package s3

import (
	"encoding/csv"
	"fmt"
	"io"
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
)

func ExampleS3_SelectObjectContent() {
	sess := session.Must(session.NewSession())
	svc := New(sess)

	/*
	   Example myObjectKey CSV content:

	   name,number
	   gopher,0
	   ᵷodɥǝɹ,1
	*/

	// Make the Select Object Content API request using the object uploaded.
	resp, err := svc.SelectObjectContent(&SelectObjectContentInput{
		Bucket:         aws.String("myBucket"),
		Key:            aws.String("myObjectKey"),
		Expression:     aws.String("SELECT name FROM S3Object WHERE cast(number as int) < 1"),
		ExpressionType: aws.String(ExpressionTypeSql),
		InputSerialization: &InputSerialization{
			CSV: &CSVInput{
				FileHeaderInfo: aws.String(FileHeaderInfoUse),
			},
		},
		OutputSerialization: &OutputSerialization{
			CSV: &CSVOutput{},
		},
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed making API request, %v\n", err)
		return
	}
	defer resp.EventStream.Close()

	results, resultWriter := io.Pipe()
	go func() {
		defer resultWriter.Close()
		for event := range resp.EventStream.Events() {
			switch e := event.(type) {
			case *RecordsEvent:
				resultWriter.Write(e.Payload)
			case *StatsEvent:
				fmt.Printf("Processed %d bytes\n", *e.Details.BytesProcessed)
			}
		}
	}()

	// Printout the results
	resReader := csv.NewReader(results)
	for {
		record, err := resReader.Read()
		if err == io.EOF {
			break
		}
		fmt.Println(record)
	}

	if err := resp.EventStream.Err(); err != nil {
		fmt.Fprintf(os.Stderr, "reading from event stream failed, %v\n", err)
	}
}
<|endoftext|>


<commit_before>package irc

import (
	"log"
	"net/textproto"
	"sync"
)

// Conn is an abstract connection
type Conn interface {
	Close()
	WaitForClose() <-chan struct{}
}

// Connection represents a connection to an irc server
type Connection struct {
	address string
	nick    string

	conn *textproto.Conn
	once sync.Once
	done chan struct{}
}

// Dial connects to the address with the nickname
// and returns a Conn
func Dial(address, nickname string) Conn {
	conn := &Connection{
		address:  address,
		nickname: nickname,
		done:     make(chan struct{}),
	}

	tp, err := textproto.Dial("tcp", address)
	if err != nil {
		log.Fatalln(err)
	}

	conn.conn = tp
	return conn
}

// Close closes the connection
func (c *Connection) Close() {
	c.once.Do(func() {
		c.conn.Close()
		close(c.done)
	})
}

// WaitForClose returns a channel that'll be closed when the connection closes
func (c *Connection) WaitForClose() <-chan struct{} {
	return c.done
}

// Join sends the join command for room
func (c *Connection) Join(room string) {}

// Part sends the part command for room
func (c *Connection) Part(room string) {}

// Kick sends the kick command for user on room with msg
func (c *Connection) Kick(room, user, msg string) {}

// Nick sends the nick command with the new nick
func (c *Connection) Nick(nick string) {}

// Quit sends the quit command with msg
func (c *Connection) Quit(msg string) {}

// Raw sends a raw message, f, formatted with args
func (c *Connection) Raw(f string, args ...interface{}) {}

// Privmsg sends a private message, f, formatted with args to t
func (c *Connection) Privmsg(t, f string, args ...interface{}) {}

// Notice sends a notice message, f, formatted with args to t
func (c *Connection) Notice(t, f string, args ...interface{}) {}
<commit_msg>Added simple implementation to the connection commands<commit_after>package irc

import (
	"fmt"
	"log"
	"net/textproto"
	"sync"
)

// Conn is an abstract connection
type Conn interface {
	Close()
	WaitForClose() <-chan struct{}
}

// Connection represents a connection to an irc server
type Connection struct {
	address string
	nick    string

	conn *textproto.Conn
	once sync.Once
	done chan struct{}
}

// Dial connects to the address with the nickname
// and returns a Conn
func Dial(address, nickname string) Conn {
	conn := &Connection{
		address:  address,
		nickname: nickname,
		done:     make(chan struct{}),
	}

	tp, err := textproto.Dial("tcp", address)
	if err != nil {
		log.Fatalln(err)
	}

	conn.conn = tp
	return conn
}

// Close closes the connection
func (c *Connection) Close() {
	c.once.Do(func() {
		c.conn.Close()
		close(c.done)
	})
}

// WaitForClose returns a channel that'll be closed when the connection closes
func (c *Connection) WaitForClose() <-chan struct{} {
	return c.done
}

// Join sends the join command for room
func (c *Connection) Join(room string) {
	c.Raw("JOIN %s", room)
}

// Part sends the part command for room
func (c *Connection) Part(room string) {
	c.Raw("PART %s", room)
}

// Kick sends the kick command for user on room with msg
func (c *Connection) Kick(room, user, msg string) {
	c.Raw("KICK %s %s :%s", room, user, msg)
}

// Nick sends the nick command with the new nick
func (c *Connection) Nick(nick string) {
	c.Raw("NICK %s", nick)
}

// Quit sends the quit command with msg
func (c *Connection) Quit(msg string) {
	c.Quit("QUIT :%s", msg)
}

// Raw sends a raw message, f, formatted with args
func (c *Connection) Raw(f string, args ...interface{}) {
	c.conn.Cmd(f, args...)
}

// Privmsg sends a private message, f, formatted with args to t
func (c *Connection) Privmsg(t, f string, args ...interface{}) {
	c.Raw("PRIVMSG %s :%s", fmt.Sprintf(f, args...))
}

// Notice sends a notice message, f, formatted with args to t
func (c *Connection) Notice(t, f string, args ...interface{}) {
	c.Raw("NOTICE %s :%s", fmt.Sprintf(f, args...))
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 graph

import (
	"io"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"sync"
	"sync/atomic"
	"time"

	"github.com/gorilla/websocket"

	"github.com/redhat-cip/skydive/logging"
)

type EventListener interface {
	OnConnected()
	OnDisconnected()
}

type AsyncClient struct {
	sync.RWMutex
	Addr      string
	Port      int
	Path      string
	messages  chan string
	quit      chan bool
	wg        sync.WaitGroup
	listeners []EventListener
	connected atomic.Value
	running   atomic.Value
}

func (c *AsyncClient) sendMessage(m string) {
	if !c.IsConnected() {
		return
	}

	c.messages <- m
}

func (c *AsyncClient) SendWSMessage(m WSMessage) {
	c.sendMessage(m.String())
}

func (c *AsyncClient) IsConnected() bool {
	return c.connected.Load() == true
}

func (c *AsyncClient) sendWSMessage(conn *websocket.Conn, msg string) error {
	w, err := conn.NextWriter(websocket.TextMessage)
	if err != nil {
		return err
	}

	_, err = io.WriteString(w, msg)
	if err != nil {
		return err
	}

	return w.Close()
}

func (c *AsyncClient) connect() {
	host := c.Addr + ":" + strconv.FormatInt(int64(c.Port), 10)

	conn, err := net.Dial("tcp", host)
	if err != nil {
		logging.GetLogger().Error("Connection to the WebSocket server failed: %s", err.Error())
		return
	}
	defer conn.Close()

	endpoint := "ws://" + host + c.Path
	u, err := url.Parse(endpoint)
	if err != nil {
		logging.GetLogger().Error("Unable to parse the WebSocket Endpoint %s: %s", endpoint, err.Error())
		return
	}

	wsConn, _, err := websocket.NewClient(conn, u, http.Header{"Origin": {endpoint}}, 1024, 1024)
	if err != nil {
		logging.GetLogger().Error("Unable to create a WebSocket connection %s : %s", endpoint, err.Error())
		return
	}
	defer wsConn.Close()
	wsConn.SetPingHandler(nil)

	logging.GetLogger().Info("Connected to %s", endpoint)

	c.wg.Add(1)
	defer c.wg.Done()

	c.connected.Store(true)

	// notify connected
	for _, l := range c.listeners {
		l.OnConnected()
	}

	go func() {
		for {
			if _, _, err := wsConn.NextReader(); err != nil {
				c.quit <- true
				return
			}
		}
	}()

	for c.connected.Load() == true {
		select {
		case msg := <-c.messages:
			err := c.sendWSMessage(wsConn, msg)
			if err != nil {
				logging.GetLogger().Error("Error while writing to the WebSocket: %s", err.Error())
				break
			}
		case <-c.quit:
			return
		}
	}
}

func (c *AsyncClient) Connect() {
	go func() {
		for c.running.Load() == true {
			c.connect()

			wasConnected := c.connected.Load()
			c.connected.Store(false)

			if wasConnected == true {
				for _, l := range c.listeners {
					l.OnDisconnected()
				}
			}

			time.Sleep(1 * time.Second)
		}
	}()
}

func (c *AsyncClient) AddListener(l EventListener) {
	c.listeners = append(c.listeners, l)
}

func (c *AsyncClient) Disconnect() {
	c.running.Store(false)
	c.quit <- true
	c.wg.Wait()
}

// Create new chat client.
func NewAsyncClient(addr string, port int, path string) *AsyncClient {
	c := &AsyncClient{
		Addr:     addr,
		Port:     port,
		Path:     path,
		messages: make(chan string, 500),
		quit:     make(chan bool),
	}
	c.connected.Store(false)
	c.running.Store(true)
	return c
}
<commit_msg>[topology][graph][client] remove unused sync.RWMutex<commit_after>/*
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 graph

import (
	"io"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"sync"
	"sync/atomic"
	"time"

	"github.com/gorilla/websocket"

	"github.com/redhat-cip/skydive/logging"
)

type EventListener interface {
	OnConnected()
	OnDisconnected()
}

type AsyncClient struct {
	Addr      string
	Port      int
	Path      string
	messages  chan string
	quit      chan bool
	wg        sync.WaitGroup
	listeners []EventListener
	connected atomic.Value
	running   atomic.Value
}

func (c *AsyncClient) sendMessage(m string) {
	if !c.IsConnected() {
		return
	}

	c.messages <- m
}

func (c *AsyncClient) SendWSMessage(m WSMessage) {
	c.sendMessage(m.String())
}

func (c *AsyncClient) IsConnected() bool {
	return c.connected.Load() == true
}

func (c *AsyncClient) sendWSMessage(conn *websocket.Conn, msg string) error {
	w, err := conn.NextWriter(websocket.TextMessage)
	if err != nil {
		return err
	}

	_, err = io.WriteString(w, msg)
	if err != nil {
		return err
	}

	return w.Close()
}

func (c *AsyncClient) connect() {
	host := c.Addr + ":" + strconv.FormatInt(int64(c.Port), 10)

	conn, err := net.Dial("tcp", host)
	if err != nil {
		logging.GetLogger().Error("Connection to the WebSocket server failed: %s", err.Error())
		return
	}
	defer conn.Close()

	endpoint := "ws://" + host + c.Path
	u, err := url.Parse(endpoint)
	if err != nil {
		logging.GetLogger().Error("Unable to parse the WebSocket Endpoint %s: %s", endpoint, err.Error())
		return
	}

	wsConn, _, err := websocket.NewClient(conn, u, http.Header{"Origin": {endpoint}}, 1024, 1024)
	if err != nil {
		logging.GetLogger().Error("Unable to create a WebSocket connection %s : %s", endpoint, err.Error())
		return
	}
	defer wsConn.Close()
	wsConn.SetPingHandler(nil)

	logging.GetLogger().Info("Connected to %s", endpoint)

	c.wg.Add(1)
	defer c.wg.Done()

	c.connected.Store(true)

	// notify connected
	for _, l := range c.listeners {
		l.OnConnected()
	}

	go func() {
		for {
			if _, _, err := wsConn.NextReader(); err != nil {
				c.quit <- true
				return
			}
		}
	}()

	for c.connected.Load() == true {
		select {
		case msg := <-c.messages:
			err := c.sendWSMessage(wsConn, msg)
			if err != nil {
				logging.GetLogger().Error("Error while writing to the WebSocket: %s", err.Error())
				break
			}
		case <-c.quit:
			return
		}
	}
}

func (c *AsyncClient) Connect() {
	go func() {
		for c.running.Load() == true {
			c.connect()

			wasConnected := c.connected.Load()
			c.connected.Store(false)

			if wasConnected == true {
				for _, l := range c.listeners {
					l.OnDisconnected()
				}
			}

			time.Sleep(1 * time.Second)
		}
	}()
}

func (c *AsyncClient) AddListener(l EventListener) {
	c.listeners = append(c.listeners, l)
}

func (c *AsyncClient) Disconnect() {
	c.running.Store(false)
	c.quit <- true
	c.wg.Wait()
}

// Create new chat client.
func NewAsyncClient(addr string, port int, path string) *AsyncClient {
	c := &AsyncClient{
		Addr:     addr,
		Port:     port,
		Path:     path,
		messages: make(chan string, 500),
		quit:     make(chan bool),
	}
	c.connected.Store(false)
	c.running.Store(true)
	return c
}
<|endoftext|>


<commit_before>package api

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

	"github.com/smartystreets/goconvey/web/server/contract"
)

type HTTPServer struct {
	watcher    contract.Watcher
	executor   contract.Executor
	latest     *contract.CompleteOutput
	clientChan chan chan string
}

func (self *HTTPServer) ReceiveUpdate(update *contract.CompleteOutput) {
	self.latest = update
}

func (self *HTTPServer) Watch(response http.ResponseWriter, request *http.Request) {

	// In case a web UI client disconnected (closed the tab),
	// the web UI will request, when it initially loads the page
	// and gets the watched directory, that the status channel
	// buffer be filled so that it can get the latest status updates
	// without missing a single beat.
	/*if request.URL.Query().Get("newclient") != "" {
		select {
		case self.statusUpdate <- true:
		default:
		}
	}*/

	if request.Method == "POST" {
		self.adjustRoot(response, request)
	} else if request.Method == "GET" {
		response.Write([]byte(self.watcher.Root()))
	}
}

func (self *HTTPServer) adjustRoot(response http.ResponseWriter, request *http.Request) {
	newRoot := self.parseQueryString("root", response, request)
	if newRoot == "" {
		return
	}
	err := self.watcher.Adjust(newRoot)
	if err != nil {
		http.Error(response, err.Error(), http.StatusNotFound)
	}
}

func (self *HTTPServer) Ignore(response http.ResponseWriter, request *http.Request) {
	path := self.parseQueryString("path", response, request)
	if path != "" {
		self.watcher.Ignore(path)
	}
}

func (self *HTTPServer) Reinstate(response http.ResponseWriter, request *http.Request) {
	path := self.parseQueryString("path", response, request)
	if path != "" {
		self.watcher.Reinstate(path)
	}
}

func (self *HTTPServer) parseQueryString(key string, response http.ResponseWriter, request *http.Request) string {
	value := request.URL.Query()[key]

	if len(value) == 0 {
		http.Error(response, fmt.Sprintf("No '%s' query string parameter included!", key), http.StatusBadRequest)
		return ""
	}

	path := value[0]
	if path == "" {
		http.Error(response, "You must provide a non-blank path.", http.StatusBadRequest)
	}
	return path
}

func (self *HTTPServer) Status(response http.ResponseWriter, request *http.Request) {
	status := self.executor.Status()
	response.Write([]byte(status))
}

func (self *HTTPServer) LongPollStatus(response http.ResponseWriter, request *http.Request) {
	if self.executor.ClearStatusFlag() {
		response.Write([]byte(self.executor.Status()))
		return
	}

	timeout, err := strconv.Atoi(request.URL.Query().Get("timeout"))
	if err != nil || timeout > 180000 || timeout < 0 {
		timeout = 60000 // default timeout is 60 seconds
	}

	myReqChan := make(chan string)

	select {
	case self.clientChan <- myReqChan: // this case means the executor's status is changing
	case <-time.After(time.Duration(timeout) * time.Millisecond): // this case means the executor hasn't changed status
		return
	}

	out := <-myReqChan

	if out != "" { // TODO: Why is this check necessary? Sometimes it writes empty string...
		response.Write([]byte(out))
	}
}

func (self *HTTPServer) Results(response http.ResponseWriter, request *http.Request) {
	response.Header().Set("Content-Type", "application/json")
	response.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
	response.Header().Set("Pragma", "no-cache")
	response.Header().Set("Expires", "0")
	stuff, _ := json.Marshal(self.latest)
	response.Write(stuff)
}

func (self *HTTPServer) Execute(response http.ResponseWriter, request *http.Request) {
	go self.execute()
}

func (self *HTTPServer) execute() {
	self.latest = self.executor.ExecuteTests(self.watcher.WatchedFolders())
}

func NewHTTPServer(watcher contract.Watcher, executor contract.Executor, status chan chan string) *HTTPServer {
	self := new(HTTPServer)
	self.watcher = watcher
	self.executor = executor
	self.clientChan = status
	return self
}

var _ = fmt.Sprintf("Hi")
<commit_msg>Removed some old, commented server code about new clients<commit_after>package api

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

	"github.com/smartystreets/goconvey/web/server/contract"
)

type HTTPServer struct {
	watcher    contract.Watcher
	executor   contract.Executor
	latest     *contract.CompleteOutput
	clientChan chan chan string
}

func (self *HTTPServer) ReceiveUpdate(update *contract.CompleteOutput) {
	self.latest = update
}

func (self *HTTPServer) Watch(response http.ResponseWriter, request *http.Request) {
	if request.Method == "POST" {
		self.adjustRoot(response, request)
	} else if request.Method == "GET" {
		response.Write([]byte(self.watcher.Root()))
	}
}

func (self *HTTPServer) adjustRoot(response http.ResponseWriter, request *http.Request) {
	newRoot := self.parseQueryString("root", response, request)
	if newRoot == "" {
		return
	}
	err := self.watcher.Adjust(newRoot)
	if err != nil {
		http.Error(response, err.Error(), http.StatusNotFound)
	}
}

func (self *HTTPServer) Ignore(response http.ResponseWriter, request *http.Request) {
	path := self.parseQueryString("path", response, request)
	if path != "" {
		self.watcher.Ignore(path)
	}
}

func (self *HTTPServer) Reinstate(response http.ResponseWriter, request *http.Request) {
	path := self.parseQueryString("path", response, request)
	if path != "" {
		self.watcher.Reinstate(path)
	}
}

func (self *HTTPServer) parseQueryString(key string, response http.ResponseWriter, request *http.Request) string {
	value := request.URL.Query()[key]

	if len(value) == 0 {
		http.Error(response, fmt.Sprintf("No '%s' query string parameter included!", key), http.StatusBadRequest)
		return ""
	}

	path := value[0]
	if path == "" {
		http.Error(response, "You must provide a non-blank path.", http.StatusBadRequest)
	}
	return path
}

func (self *HTTPServer) Status(response http.ResponseWriter, request *http.Request) {
	status := self.executor.Status()
	response.Write([]byte(status))
}

func (self *HTTPServer) LongPollStatus(response http.ResponseWriter, request *http.Request) {
	if self.executor.ClearStatusFlag() {
		response.Write([]byte(self.executor.Status()))
		return
	}

	timeout, err := strconv.Atoi(request.URL.Query().Get("timeout"))
	if err != nil || timeout > 180000 || timeout < 0 {
		timeout = 60000 // default timeout is 60 seconds
	}

	myReqChan := make(chan string)

	select {
	case self.clientChan <- myReqChan: // this case means the executor's status is changing
	case <-time.After(time.Duration(timeout) * time.Millisecond): // this case means the executor hasn't changed status
		return
	}

	out := <-myReqChan

	if out != "" { // TODO: Why is this check necessary? Sometimes it writes empty string...
		response.Write([]byte(out))
	}
}

func (self *HTTPServer) Results(response http.ResponseWriter, request *http.Request) {
	response.Header().Set("Content-Type", "application/json")
	response.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
	response.Header().Set("Pragma", "no-cache")
	response.Header().Set("Expires", "0")
	stuff, _ := json.Marshal(self.latest)
	response.Write(stuff)
}

func (self *HTTPServer) Execute(response http.ResponseWriter, request *http.Request) {
	go self.execute()
}

func (self *HTTPServer) execute() {
	self.latest = self.executor.ExecuteTests(self.watcher.WatchedFolders())
}

func NewHTTPServer(watcher contract.Watcher, executor contract.Executor, status chan chan string) *HTTPServer {
	self := new(HTTPServer)
	self.watcher = watcher
	self.executor = executor
	self.clientChan = status
	return self
}

var _ = fmt.Sprintf("Hi")
<|endoftext|>


<commit_before>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 oglemock_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/oglemock"
	. "github.com/jacobsa/ogletest"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type CallExpectationTest struct {

}

func init() { RegisterTestSuite(&CallExpectationTest{}) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *CallExpectationTest) StoresFileNameAndLineNumber() {
	exp := InternalNewExpectation([]interface{}{}, "taco", 17)

	ExpectThat(exp.FileName, Equals("taco"))
	ExpectThat(exp.LineNumber, Equals(17))
}

func (t *CallExpectationTest) NoArgs() {
}

func (t *CallExpectationTest) MixOfMatchersAndNonMatchers() {
}

func (t *CallExpectationTest) NoTimes() {
}

func (t *CallExpectationTest) TimesN() {
}

func (t *CallExpectationTest) NoActions() {
}

func (t *CallExpectationTest) WillOnce() {
}

func (t *CallExpectationTest) WillRepeatedly() {
}

func (t *CallExpectationTest) TimesCalledTwice() {
}

func (t *CallExpectationTest) TimesCalledAfterWillOnce() {
}

func (t *CallExpectationTest) TimesCalledAfterWillRepeatedly() {
}

func (t *CallExpectationTest) WillOnceCalledAfterWillRepeatedly() {
}

func (t *CallExpectationTest) OneTimeActionRejectsSignature() {
}

func (t *CallExpectationTest) WillRepeatedlyCalledTwice() {
}

func (t *CallExpectationTest) FallbackActionRejectsSignature() {
}
<commit_msg>CallExpectationTest.NoArgs<commit_after>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 oglemock_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/oglemock"
	. "github.com/jacobsa/ogletest"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type CallExpectationTest struct {

}

func init() { RegisterTestSuite(&CallExpectationTest{}) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *CallExpectationTest) StoresFileNameAndLineNumber() {
	exp := InternalNewExpectation([]interface{}{}, "taco", 17)

	ExpectThat(exp.FileName, Equals("taco"))
	ExpectThat(exp.LineNumber, Equals(17))
}

func (t *CallExpectationTest) NoArgs() {
	exp := InternalNewExpectation([]interface{}{}, "", 0)

	ExpectThat(len(exp.ArgMatchers), Equals(0))
}

func (t *CallExpectationTest) MixOfMatchersAndNonMatchers() {
}

func (t *CallExpectationTest) NoTimes() {
}

func (t *CallExpectationTest) TimesN() {
}

func (t *CallExpectationTest) NoActions() {
}

func (t *CallExpectationTest) WillOnce() {
}

func (t *CallExpectationTest) WillRepeatedly() {
}

func (t *CallExpectationTest) TimesCalledTwice() {
}

func (t *CallExpectationTest) TimesCalledAfterWillOnce() {
}

func (t *CallExpectationTest) TimesCalledAfterWillRepeatedly() {
}

func (t *CallExpectationTest) WillOnceCalledAfterWillRepeatedly() {
}

func (t *CallExpectationTest) OneTimeActionRejectsSignature() {
}

func (t *CallExpectationTest) WillRepeatedlyCalledTwice() {
}

func (t *CallExpectationTest) FallbackActionRejectsSignature() {
}
<|endoftext|>