<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	"log"
	"net/http"
	"os"
	"strconv"
)

var (
	db gorm.DB
)

type Tree struct {
	Id         int64    `json:"id"`
	CommonName string   `json:"common_name"`
	LatinName  string   `json:"latin_name"`
	GeomData   []string `json:"geom",sql:"-"`
	Area       float64  `json:"area",sql:"-"`
}

func (t *Tree) GetGeodata() {
	rows, err := db.Table("tree_geoms").Select("ST_AsGeoJSON(ST_CollectionExtract(geom, 3)) as geom2").Where("latin_name = ?", t.LatinName).Rows()
	if err != nil {
		log.Println(err)
	}

	for rows.Next() {
		var geodata string
		rows.Scan(&geodata)
		t.GeomData = append(t.GeomData, geodata)
	}
}

func (t *Tree) GetArea() {
	var a struct {
		Area float64
	}
	db.Table("tree_geoms").Select("SUM(ST_Area(ST_Transform(geom, 900913))) as area").Where("latin_name = ?", t.LatinName).Scan(&a)

	t.Area = a.Area * 0.000189394 * 0.000189394 // Get the miles
	log.Println("Area:", t.Area)
}

type NationalPark struct {
	UnitName string `json:"name"`
	GeomData string `json:"geom"`
}

func renderJson(w http.ResponseWriter, page interface{}) {
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Access-Control-Allow-Origin", "*")

	b, err := json.Marshal(page)
	if err != nil {
		log.Println("error:", err)
		fmt.Fprintf(w, "")
	}

	w.Write(b)
}

func showTreesHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	treeId, _ := strconv.ParseInt(vars["treeId"], 10, 64)

	tree := Tree{Id: int64(treeId)}
	db.First(&tree)
	tree.GetGeodata()
	tree.GetArea()

	renderJson(w, tree)
}

func treesHandler(w http.ResponseWriter, r *http.Request) {
	var trees []Tree

	err := db.Model(Tree{}).Select("id, latin_name, common_name").Scan(&trees)
	if err != nil {
		log.Println(err)
	}

	renderJson(w, trees)
}

func parksHandler(w http.ResponseWriter, r *http.Request) {
	var parks []NationalPark
	db.Model(NationalPark{}).Select("ST_AsGeoJSON(ST_CollectionExtract(geom, 3)) as geom_data, unit_name").Scan(&parks)

	renderJson(w, parks)
}

func init() {
	databaseUrl := os.Getenv("TREELY_DATABASE_URL")
	if databaseUrl == "" {
		databaseUrl = "user=ayerra dbname=treely_development sslmode=disable"
	}

	log.Println("Database:", databaseUrl)

	var err error
	db, err = gorm.Open("postgres", databaseUrl)
	if err != nil {
		log.Println(err)
	}
}

func main() {
	r := mux.NewRouter()
	// r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/trees/{treeId}", showTreesHandler)
	r.HandleFunc("/trees", treesHandler)
	r.HandleFunc("/parks", parksHandler)
	r.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))

	http.Handle("/", r)
	http.ListenAndServe(":3001", nil)
}
<commit_msg>Connect to etcd and do stuff there.<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	sarpa "github.com/abhiyerra/sarpa/client"
	"github.com/coreos/go-etcd/etcd"
	"github.com/gorilla/mux"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	"log"
	"net/http"
	"os"
	"strconv"
	"time"
)

var (
	db gorm.DB
)

type Tree struct {
	Id         int64    `json:"id"`
	CommonName string   `json:"common_name"`
	LatinName  string   `json:"latin_name"`
	GeomData   []string `json:"geom",sql:"-"`
	Area       float64  `json:"area",sql:"-"`
}

func (t *Tree) GetGeodata() {
	rows, err := db.Table("tree_geoms").Select("ST_AsGeoJSON(ST_CollectionExtract(geom, 3)) as geom2").Where("latin_name = ?", t.LatinName).Rows()
	if err != nil {
		log.Println(err)
	}

	for rows.Next() {
		var geodata string
		rows.Scan(&geodata)
		t.GeomData = append(t.GeomData, geodata)
	}
}

func (t *Tree) GetArea() {
	var a struct {
		Area float64
	}
	db.Table("tree_geoms").Select("SUM(ST_Area(ST_Transform(geom, 900913))) as area").Where("latin_name = ?", t.LatinName).Scan(&a)

	t.Area = a.Area * 0.000189394 * 0.000189394 // Get the miles
	log.Println("Area:", t.Area)
}

type NationalPark struct {
	UnitName string `json:"name"`
	GeomData string `json:"geom"`
}

func renderJson(w http.ResponseWriter, page interface{}) {
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Access-Control-Allow-Origin", "*")

	b, err := json.Marshal(page)
	if err != nil {
		log.Println("error:", err)
		fmt.Fprintf(w, "")
	}

	w.Write(b)
}

func showTreesHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	treeId, _ := strconv.ParseInt(vars["treeId"], 10, 64)

	tree := Tree{Id: int64(treeId)}
	db.First(&tree)
	tree.GetGeodata()
	tree.GetArea()

	renderJson(w, tree)
}

func treesHandler(w http.ResponseWriter, r *http.Request) {
	var trees []Tree

	err := db.Model(Tree{}).Select("id, latin_name, common_name").Scan(&trees)
	if err != nil {
		log.Println(err)
	}

	renderJson(w, trees)
}

func parksHandler(w http.ResponseWriter, r *http.Request) {
	var parks []NationalPark
	db.Model(NationalPark{}).Select("ST_AsGeoJSON(ST_CollectionExtract(geom, 3)) as geom_data, unit_name").Scan(&parks)

	renderJson(w, parks)
}

func dbConnect(databaseUrl string) {
	log.Println("Connecting to database:", databaseUrl)
	var err error
	db, err = gorm.Open("postgres", databaseUrl)
	if err != nil {
		log.Println(err)
	}
}

func etcdUpdater(etcdHost string) {
	go func() {
		for {
			etcdClient := etcd.NewClient([]string{etcdHost})

			resp, err := etcdClient.Get("/treely/database_url", false, false)
			if err != nil {
				log.Println("Hey there is no database_url in etcd")
			} else {
				databaseUrl := resp.Node.Value
				log.Println("DatabaseURL:", databaseUrl)
				dbConnect(databaseUrl)
			}

			sarpa.SarpaUpdater(etcdClient, "treely", "123", 120)

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

func init() {
	var etcd = flag.String("etcd", "", "Use etcd for configuration.")
	flag.Parse()

	if *etcd != "" {
		etcdUpdater(*etcd)
	} else {
		databaseUrl := os.Getenv("TREELY_DATABASE_URL")
		if databaseUrl == "" {
			databaseUrl = "user=ayerra dbname=treely_development sslmode=disable"
		}

		dbConnect(databaseUrl)
	}
}

func main() {
	r := mux.NewRouter()
	// r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/trees/{treeId}", showTreesHandler)
	r.HandleFunc("/trees", treesHandler)
	r.HandleFunc("/parks", parksHandler)
	r.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))

	http.Handle("/", r)
	http.ListenAndServe(":3001", nil)
}
<|endoftext|>


<commit_before>// tweetlib - A fully oauth-authenticated Go Twitter library
//
// Copyright 2011 The Tweetlib 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 tweetlib

import (
	"bytes"
	"encoding/json"
	"fmt"
	"mime/multipart"
	"net/http"
)

type TweetsGroup struct {
	*Client
}

// Holds a single tweet. Depending on the API call used, this
// struct may or may not be fully populated.
type Tweet struct {
	Contributors        string `json:"contributors"`
	User                *User  `json:"user"`
	Truncated           bool   `json:"truncated"`
	Text                string `json:"text"`
	InReplyToScreenName string `json:"in_reply_to_screen_name"`
	RetweetCount        int64  `json:"retweet_count"`
	Entities            struct {
		Urls []struct {
			DisplayUrl  string  `json:"display_url"`
			Indices     []int64 `json:"indices"`
			Url         string  `json:"url"`
			ExpandedUrl string  `json:"expanded_url"`
		} `json:"urls"`
		Hashtags []struct {
			Text    string  `json:"text"`
			Indices []int64 `json:"indices"`
		} `json:"hashtags"`
		UserMentions []struct {
			ScreenName string  `json:"screen_name"`
			Name       string  `json:"name"`
			Indices    []int64 `json:"indices"`
			IdStr      string  `json:"id_str"`
			Id         int64   `json:"id"`
		} `json:"user_mentions"`
	} `json:"entities"`
	Geo                  string `json:"geo"`
	InReplyToUserId      int64  `json:"in_reply_to_user_id"`
	IdStr                string `json:"id_str"`
	CreatedAt            string `json:"created_at"`
	Source               string `json:"source"`
	Id                   int64  `json:"id"`
	InReplyToStatusId    string `json:"in_reply_to_status_id"`
	PossiblySensitive    bool   `json:"possibly_sensitive"`
	Retweeted            bool   `json:"retweeted"`
	InReplyToUserIdStr   string `json:"in_reply_to_user_id_str"`
	Coordinates          string `json:"coordinates"`
	Favorited            bool   `json:"favorited"`
	Place                string `json:"place"`
	InReplyToStatusIdStr string `json:"in_reply_to_status_id_str"`
}

// A list of tweets
type TweetList []Tweet

// A media attached to a tweet. In practice, this represents
// an image file.
type TweetMedia struct {
	Filename string // Name for the file (e.g. image.png)
	Data     []byte // Raw file data
}

// Returns the 20 (by default) most recent tweets containing a users's
// @screen_name for the authenticating user.
// THis method can only return up to 800 tweets (via the "count" optional
// parameter.
// See https://dev.twitter.com/docs/api/1.1/get/statuses/mentions_timeline
func (tg *TweetsGroup) Mentions(opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	tweets = &TweetList{}
	err = tg.Call("GET", "statuses/mentions_timeline", opts, tweets)
	return
}

// Returns a collection of the most recent Tweets posted by the user indicated
// by the screen_name.
// See https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
func (tg *TweetsGroup) UserTimeline(screenname string, opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("screen_name", screenname)
	tweets = new(TweetList)
	err = tg.Call("GET", "statuses/user_timeline", opts, tweets)
	return
}

// Returns a collection of the most recent Tweets and retweets posted by
// the authenticating user and the users they follow.
// See https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline
func (tg *TweetsGroup) HomeTimeline(opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	tweets = new(TweetList)
	err = tg.Call("GET", "statuses/home_timeline", opts, tweets)
	return
}

// Returns a collection of the  most recent tweets authored by the
// authenticating user that have been retweeted by others.
// See https://dev.twitter.com/docs/api/1.1/get/statuses/retweets_of_me
func (tg *TweetsGroup) RetweetsOfMe(opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	tweets = new(TweetList)
	err = tg.Call("GET", "statuses/retweets_of_me", opts, tweets)
	return
}

// Update: posts a status update to Twitter
// See https://dev.twitter.com/docs/api/1.1/post/statuses/update
func (tg *TweetsGroup) Update(status string, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("status", status)
	tweet = &Tweet{}
	err = tg.Call("POST", "statuses/update", opts, tweet)
	return tweet, err
}

// Returns up to 100 of the first retweets of a given tweet Id
func (tg *TweetsGroup) Retweets(id int64, opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	tweets = &TweetList{}
	err = tg.Call("GET", fmt.Sprintf("statuses/retweets/%d", id), opts, tweets)
	return
}

// Returns a single Tweet, specified by the id parameter.
// The Tweet's author will also be embedded within the tweet.
func (tg *TweetsGroup) Get(id int64, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("id", id)
	tweet = &Tweet{}
	err = tg.Call("GET", "statuses/show", opts, tweet)
	return
}

// Destroys the status specified by the required ID parameter.
// The authenticating user must be the author of the specified
// status. returns the destroyed tweet if successful
func (tg *TweetsGroup) Destroy(id int64, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("id", id)
	tweet = &Tweet{}
	err = tg.Call("POST", fmt.Sprintf("statuses/destroy/%d", id), opts, tweet)
	return tweet, err
}

// Retweets a tweet. Returns the original tweet with retweet details embedded.
func (tg *TweetsGroup) Retweet(id int64, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("id", id)
	tweet = &Tweet{}
	err = tg.Call("POST", fmt.Sprintf("statuses/retweet/%d", id), opts, tweet)
	return tweet, err
}

// Updates the authenticating user's current status and attaches media for
// upload. In other words, it creates a Tweet with a picture attached.
func (tg *TweetsGroup) UpdateWithMedia(status string, media *TweetMedia, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}

	body := bytes.NewBufferString("")
	mp := multipart.NewWriter(body)
	mp.WriteField("status", status)
	for n, v := range opts.Values {
		mp.WriteField(n, v[0])
	}
	writer, err := mp.CreateFormFile("media[]", media.Filename)
	if err != nil {
		return nil, err
	}
	writer.Write(media.Data)
	header := fmt.Sprintf("multipart/form-data;boundary=%v", mp.Boundary())
	mp.Close()

	endpoint := fmt.Sprintf("%s/statuses/update_with_media.json?%s", apiURL, opts.Values.Encode())
	req, _ := http.NewRequest("POST", endpoint, body)
	req.Header.Set("Content-Type", header)
	res, err := tg.client.Do(req)
	if err != nil {
		return
	}
	if err = checkResponse(res); err != nil {
		return
	}
	if err = json.NewDecoder(res.Body).Decode(tweet); err != nil {
		return
	}
	return

}

// Results of a search for tweets.
type TweetSearchResults struct {
	// Tweets matching the search query
	Results TweetList `json:"statuses"`
	// Search metadata
	Metadata TweetSearchMetadata `json:"search_metadata"`
}

// When searching, Twitter returns this metadata
// along with results
type TweetSearchMetadata struct {
	MaxId       int64   `json:"max_id"`
	SinceId     int64   `json:"since_id"`
	RefreshUrl  string  `json:"refresh_url"`
	NextResults string  `json:"next_results"`
	Count       int     `json:"count"`
	CompletedIn float64 `json:"completed_in"`
	SinceIdStr  string  `json:"since_id_str"`
	Query       string  `json:"query"`
	MaxIdStr    string  `json:"max_id_str"`
}

// Returns a collection of relevant Tweets matching a specified query.
// See https://dev.twitter.com/docs/api/1.1/get/search/tweets
// and also https://dev.twitter.com/docs/using-search
func (tg *TweetsGroup) Tweets(q string, opts *Optionals) (searchResults *TweetSearchResults, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("q", q)
	searchResults = &TweetSearchResults{}
	err = tg.Call("GET", "search/tweets", opts, searchResults)
	return
}
<commit_msg>Ignore Unmarshal type error on update_with_media<commit_after>// tweetlib - A fully oauth-authenticated Go Twitter library
//
// Copyright 2011 The Tweetlib 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 tweetlib

import (
	"bytes"
	"encoding/json"
	"fmt"
	"mime/multipart"
	"net/http"
	"reflect"
)

type TweetsGroup struct {
	*Client
}

// Holds a single tweet. Depending on the API call used, this
// struct may or may not be fully populated.
type Tweet struct {
	Contributors        string `json:"contributors"`
	User                *User  `json:"user"`
	Truncated           bool   `json:"truncated"`
	Text                string `json:"text"`
	InReplyToScreenName string `json:"in_reply_to_screen_name"`
	RetweetCount        int64  `json:"retweet_count"`
	Entities            struct {
		Urls []struct {
			DisplayUrl  string  `json:"display_url"`
			Indices     []int64 `json:"indices"`
			Url         string  `json:"url"`
			ExpandedUrl string  `json:"expanded_url"`
		} `json:"urls"`
		Hashtags []struct {
			Text    string  `json:"text"`
			Indices []int64 `json:"indices"`
		} `json:"hashtags"`
		UserMentions []struct {
			ScreenName string  `json:"screen_name"`
			Name       string  `json:"name"`
			Indices    []int64 `json:"indices"`
			IdStr      string  `json:"id_str"`
			Id         int64   `json:"id"`
		} `json:"user_mentions"`
	} `json:"entities"`
	Geo                  string `json:"geo"`
	InReplyToUserId      int64  `json:"in_reply_to_user_id"`
	IdStr                string `json:"id_str"`
	CreatedAt            string `json:"created_at"`
	Source               string `json:"source"`
	Id                   int64  `json:"id"`
	InReplyToStatusId    string `json:"in_reply_to_status_id"`
	PossiblySensitive    bool   `json:"possibly_sensitive"`
	Retweeted            bool   `json:"retweeted"`
	InReplyToUserIdStr   string `json:"in_reply_to_user_id_str"`
	Coordinates          string `json:"coordinates"`
	Favorited            bool   `json:"favorited"`
	Place                string `json:"place"`
	InReplyToStatusIdStr string `json:"in_reply_to_status_id_str"`
}

// A list of tweets
type TweetList []Tweet

// A media attached to a tweet. In practice, this represents
// an image file.
type TweetMedia struct {
	Filename string // Name for the file (e.g. image.png)
	Data     []byte // Raw file data
}

// Returns the 20 (by default) most recent tweets containing a users's
// @screen_name for the authenticating user.
// THis method can only return up to 800 tweets (via the "count" optional
// parameter.
// See https://dev.twitter.com/docs/api/1.1/get/statuses/mentions_timeline
func (tg *TweetsGroup) Mentions(opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	tweets = &TweetList{}
	err = tg.Call("GET", "statuses/mentions_timeline", opts, tweets)
	return
}

// Returns a collection of the most recent Tweets posted by the user indicated
// by the screen_name.
// See https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
func (tg *TweetsGroup) UserTimeline(screenname string, opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("screen_name", screenname)
	tweets = new(TweetList)
	err = tg.Call("GET", "statuses/user_timeline", opts, tweets)
	return
}

// Returns a collection of the most recent Tweets and retweets posted by
// the authenticating user and the users they follow.
// See https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline
func (tg *TweetsGroup) HomeTimeline(opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	tweets = new(TweetList)
	err = tg.Call("GET", "statuses/home_timeline", opts, tweets)
	return
}

// Returns a collection of the  most recent tweets authored by the
// authenticating user that have been retweeted by others.
// See https://dev.twitter.com/docs/api/1.1/get/statuses/retweets_of_me
func (tg *TweetsGroup) RetweetsOfMe(opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	tweets = new(TweetList)
	err = tg.Call("GET", "statuses/retweets_of_me", opts, tweets)
	return
}

// Update: posts a status update to Twitter
// See https://dev.twitter.com/docs/api/1.1/post/statuses/update
func (tg *TweetsGroup) Update(status string, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("status", status)
	tweet = &Tweet{}
	err = tg.Call("POST", "statuses/update", opts, tweet)
	return tweet, err
}

// Returns up to 100 of the first retweets of a given tweet Id
func (tg *TweetsGroup) Retweets(id int64, opts *Optionals) (tweets *TweetList, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	tweets = &TweetList{}
	err = tg.Call("GET", fmt.Sprintf("statuses/retweets/%d", id), opts, tweets)
	return
}

// Returns a single Tweet, specified by the id parameter.
// The Tweet's author will also be embedded within the tweet.
func (tg *TweetsGroup) Get(id int64, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("id", id)
	tweet = &Tweet{}
	err = tg.Call("GET", "statuses/show", opts, tweet)
	return
}

// Destroys the status specified by the required ID parameter.
// The authenticating user must be the author of the specified
// status. returns the destroyed tweet if successful
func (tg *TweetsGroup) Destroy(id int64, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("id", id)
	tweet = &Tweet{}
	err = tg.Call("POST", fmt.Sprintf("statuses/destroy/%d", id), opts, tweet)
	return tweet, err
}

// Retweets a tweet. Returns the original tweet with retweet details embedded.
func (tg *TweetsGroup) Retweet(id int64, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("id", id)
	tweet = &Tweet{}
	err = tg.Call("POST", fmt.Sprintf("statuses/retweet/%d", id), opts, tweet)
	return tweet, err
}

// Updates the authenticating user's current status and attaches media for
// upload. In other words, it creates a Tweet with a picture attached.
func (tg *TweetsGroup) UpdateWithMedia(status string, media *TweetMedia, opts *Optionals) (tweet *Tweet, err error) {
	if opts == nil {
		opts = NewOptionals()
	}

	body := bytes.NewBufferString("")
	mp := multipart.NewWriter(body)
	mp.WriteField("status", status)
	for n, v := range opts.Values {
		mp.WriteField(n, v[0])
	}
	writer, err := mp.CreateFormFile("media[]", media.Filename)
	if err != nil {
		return nil, err
	}
	writer.Write(media.Data)
	header := fmt.Sprintf("multipart/form-data;boundary=%v", mp.Boundary())
	mp.Close()

	endpoint := fmt.Sprintf("%s/statuses/update_with_media.json?%s", apiURL, opts.Values.Encode())
	req, _ := http.NewRequest("POST", endpoint, body)
	req.Header.Set("Content-Type", header)
	res, err := tg.client.Do(req)
	if err != nil {
		return
	}
	if err = checkResponse(res); err != nil {
		return
	}
	tweet = &Tweet{}
	if err = json.NewDecoder(res.Body).Decode(tweet); err != nil &&
		reflect.TypeOf(err) != reflect.TypeOf(&json.UnmarshalTypeError{}) {
		return
	}
	return tweet, nil

}

// Results of a search for tweets.
type TweetSearchResults struct {
	// Tweets matching the search query
	Results TweetList `json:"statuses"`
	// Search metadata
	Metadata TweetSearchMetadata `json:"search_metadata"`
}

// When searching, Twitter returns this metadata
// along with results
type TweetSearchMetadata struct {
	MaxId       int64   `json:"max_id"`
	SinceId     int64   `json:"since_id"`
	RefreshUrl  string  `json:"refresh_url"`
	NextResults string  `json:"next_results"`
	Count       int     `json:"count"`
	CompletedIn float64 `json:"completed_in"`
	SinceIdStr  string  `json:"since_id_str"`
	Query       string  `json:"query"`
	MaxIdStr    string  `json:"max_id_str"`
}

// Returns a collection of relevant Tweets matching a specified query.
// See https://dev.twitter.com/docs/api/1.1/get/search/tweets
// and also https://dev.twitter.com/docs/using-search
func (tg *TweetsGroup) Tweets(q string, opts *Optionals) (searchResults *TweetSearchResults, err error) {
	if opts == nil {
		opts = NewOptionals()
	}
	opts.Add("q", q)
	searchResults = &TweetSearchResults{}
	err = tg.Call("GET", "search/tweets", opts, searchResults)
	return
}
<|endoftext|>


<commit_before>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom

import (
	"encoding/json"
)

type MultiBalanceResponse struct {
	CurrentHeight   int `json:"currentheight"`
	LastSavedHeight int `json:"lastsavedheight"`
	Balances        []struct {
		Ack   int    `json:"ack"`
		Saved int    `json:"saved"`
		Err   string `json:"err"`
	} `json:"balances"`
}

// GetECBalance returns the balance in factoshi (factoid * 1e8) of a given Entry
// Credit Public Address.
func GetECBalance(addr string) (int64, error) {
	type balanceResponse struct {
		Balance int64 `json:"balance"`
	}

	params := addressRequest{Address: addr}
	req := NewJSON2Request("entry-credit-balance", APICounter(), params)
	resp, err := factomdRequest(req)
	if err != nil {
		return -1, err
	}
	if resp.Error != nil {
		return -1, resp.Error
	}

	balance := new(balanceResponse)
	if err := json.Unmarshal(resp.JSONResult(), balance); err != nil {
		return -1, err
	}

	return balance.Balance, nil
}

// GetFactoidBalance returns the balance in factoshi (factoid * 1e8) of a given
// Factoid Public Address.
func GetFactoidBalance(addr string) (int64, error) {
	type balanceResponse struct {
		Balance int64 `json:"balance"`
	}

	params := addressRequest{Address: addr}
	req := NewJSON2Request("factoid-balance", APICounter(), params)
	resp, err := factomdRequest(req)
	if err != nil {
		return -1, err
	}
	if resp.Error != nil {
		return -1, resp.Error
	}

	balance := new(balanceResponse)
	if err := json.Unmarshal(resp.JSONResult(), balance); err != nil {
		return -1, err
	}

	return balance.Balance, nil
}

// GetBalanceTotals return the total value of Factoids and Entry Credits in the
// wallet according to the the server acknowledgement and the value saved in the
// blockchain.
func GetBalanceTotals() (fs, fa, es, ea int64, err error) {
	type multiBalanceResponse struct {
		FactoidAccountBalances struct {
			Ack   int64 `json:"ack"`
			Saved int64 `json:"saved"`
		} `json:"fctaccountbalances"`
		EntryCreditAccountBalances struct {
			Ack   int64 `json:"ack"`
			Saved int64 `json:"saved"`
		} `json:"ecaccountbalances"`
	}

	req := NewJSON2Request("wallet-balances", APICounter(), nil)
	resp, err := walletRequest(req)
	if err != nil {
		return
	}

	balances := new(multiBalanceResponse)
	err = json.Unmarshal(resp.JSONResult(), balances)
	if err != nil {
		return
	}

	fs = balances.FactoidAccountBalances.Saved
	fa = balances.FactoidAccountBalances.Ack
	es = balances.EntryCreditAccountBalances.Saved
	ea = balances.EntryCreditAccountBalances.Ack

	return
}

// GetMultipleFCTBalances returns balances for multiple Factoid Addresses from
// the factomd API.
func GetMultipleFCTBalances(fas ...string) (*MultiBalanceResponse, error) {
	type multiAddressRequest struct {
		Addresses []string `json:"addresses"`
	}

	params := multiAddressRequest{fas}
	req := NewJSON2Request("multiple-fct-balances", APICounter(), params)
	resp, err := factomdRequest(req)
	if err != nil {
		return nil, err
	}

	balances := new(MultiBalanceResponse)
	err = json.Unmarshal(resp.JSONResult(), balances)
	if err != nil {
		return nil, err
	}

	return balances, nil
}

// GetMultipleECBalances returns balances for multiple Entry Credit Addresses
// from the factomd API.
func GetMultipleECBalances(ecs ...string) (*MultiBalanceResponse, error) {
	type multiAddressRequest struct {
		Addresses []string `json:"addresses"`
	}

	params := multiAddressRequest{ecs}
	req := NewJSON2Request("multiple-ec-balances", APICounter(), params)
	resp, err := factomdRequest(req)
	if err != nil {
		return nil, err
	}

	balances := new(MultiBalanceResponse)
	err = json.Unmarshal(resp.JSONResult(), balances)
	if err != nil {
		return nil, err
	}

	return balances, nil
}
<commit_msg>fix: GetECBalance method documentation (#134)<commit_after>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom

import (
	"encoding/json"
)

type MultiBalanceResponse struct {
	CurrentHeight   int `json:"currentheight"`
	LastSavedHeight int `json:"lastsavedheight"`
	Balances        []struct {
		Ack   int    `json:"ack"`
		Saved int    `json:"saved"`
		Err   string `json:"err"`
	} `json:"balances"`
}

// GetECBalance returns the Entry Credit balance of a given Entry
// Credit Public Address.
func GetECBalance(addr string) (int64, error) {
	type balanceResponse struct {
		Balance int64 `json:"balance"`
	}

	params := addressRequest{Address: addr}
	req := NewJSON2Request("entry-credit-balance", APICounter(), params)
	resp, err := factomdRequest(req)
	if err != nil {
		return -1, err
	}
	if resp.Error != nil {
		return -1, resp.Error
	}

	balance := new(balanceResponse)
	if err := json.Unmarshal(resp.JSONResult(), balance); err != nil {
		return -1, err
	}

	return balance.Balance, nil
}

// GetFactoidBalance returns the balance in factoshi (factoid * 1e8) of a given
// Factoid Public Address.
func GetFactoidBalance(addr string) (int64, error) {
	type balanceResponse struct {
		Balance int64 `json:"balance"`
	}

	params := addressRequest{Address: addr}
	req := NewJSON2Request("factoid-balance", APICounter(), params)
	resp, err := factomdRequest(req)
	if err != nil {
		return -1, err
	}
	if resp.Error != nil {
		return -1, resp.Error
	}

	balance := new(balanceResponse)
	if err := json.Unmarshal(resp.JSONResult(), balance); err != nil {
		return -1, err
	}

	return balance.Balance, nil
}

// GetBalanceTotals return the total value of Factoids and Entry Credits in the
// wallet according to the the server acknowledgement and the value saved in the
// blockchain.
func GetBalanceTotals() (fs, fa, es, ea int64, err error) {
	type multiBalanceResponse struct {
		FactoidAccountBalances struct {
			Ack   int64 `json:"ack"`
			Saved int64 `json:"saved"`
		} `json:"fctaccountbalances"`
		EntryCreditAccountBalances struct {
			Ack   int64 `json:"ack"`
			Saved int64 `json:"saved"`
		} `json:"ecaccountbalances"`
	}

	req := NewJSON2Request("wallet-balances", APICounter(), nil)
	resp, err := walletRequest(req)
	if err != nil {
		return
	}

	balances := new(multiBalanceResponse)
	err = json.Unmarshal(resp.JSONResult(), balances)
	if err != nil {
		return
	}

	fs = balances.FactoidAccountBalances.Saved
	fa = balances.FactoidAccountBalances.Ack
	es = balances.EntryCreditAccountBalances.Saved
	ea = balances.EntryCreditAccountBalances.Ack

	return
}

// GetMultipleFCTBalances returns balances for multiple Factoid Addresses from
// the factomd API.
func GetMultipleFCTBalances(fas ...string) (*MultiBalanceResponse, error) {
	type multiAddressRequest struct {
		Addresses []string `json:"addresses"`
	}

	params := multiAddressRequest{fas}
	req := NewJSON2Request("multiple-fct-balances", APICounter(), params)
	resp, err := factomdRequest(req)
	if err != nil {
		return nil, err
	}

	balances := new(MultiBalanceResponse)
	err = json.Unmarshal(resp.JSONResult(), balances)
	if err != nil {
		return nil, err
	}

	return balances, nil
}

// GetMultipleECBalances returns balances for multiple Entry Credit Addresses
// from the factomd API.
func GetMultipleECBalances(ecs ...string) (*MultiBalanceResponse, error) {
	type multiAddressRequest struct {
		Addresses []string `json:"addresses"`
	}

	params := multiAddressRequest{ecs}
	req := NewJSON2Request("multiple-ec-balances", APICounter(), params)
	resp, err := factomdRequest(req)
	if err != nil {
		return nil, err
	}

	balances := new(MultiBalanceResponse)
	err = json.Unmarshal(resp.JSONResult(), balances)
	if err != nil {
		return nil, err
	}

	return balances, nil
}
<|endoftext|>


<commit_before>package y

import (
	"reflect"

	sq "github.com/lann/squirrel"
)

// Changer updates object values
type Changer struct {
	proxy  *Proxy
	values Values
}

func (c *Changer) modify() sq.Eq {
	modified := sq.Eq{}
	for name, val := range c.values {
		f := c.proxy.Field(name)
		if f.Interface() != val {
			modified[name] = val
			f.Set(reflect.ValueOf(val))
		}
	}
	return modified
}

func (c *Changer) primary() sq.Eq {
	pks := sq.Eq{}
	for _, pk := range c.proxy.schema.xinfo.pk {
		pks[pk] = c.proxy.Field(pk).Interface()
	}
	return pks
}

func (c *Changer) prepare(clauses sq.Eq, where sq.Eq) sq.UpdateBuilder {
	return sq.Update(c.proxy.schema.table).SetMap(clauses).Where(where)
}

// Update saves object changes in db after version validation
func (c *Changer) Update(db DB) (updated bool, err error) {
	// load origin
	err = c.proxy.Load(db)
	if err != nil {
		return
	}
	oldv := c.proxy.Version()
	newv := oldv + 1
	// find changes
	clauses := c.modify()
	if len(clauses) == 0 {
		return
	}
	// set new version
	clauses[_version] = newv
	c.proxy.Field(_version).SetInt(newv)
	// set where condition
	where := c.primary()
	where[_version] = oldv
	// save
	result, err := exec(c.prepare(clauses, where), db)
	if err != nil {
		return
	}
	count, err := result.RowsAffected()
	updated = count == 1
	return
}

func makeChanger(p *Proxy, v Values) *Changer {
	return &Changer{p, v}
}

// Update saves object changes
func Update(db DB, p *Proxy, v Values) (bool, error) {
	return makeChanger(p, v).Update(db)
}
<commit_msg>added incr func for update<commit_after>package y

import (
	"reflect"

	sq "github.com/lann/squirrel"
)

// Changer updates object values
type Changer struct {
	proxy  *Proxy
	values Values
}

// Modifier changes a value for update statement
type Modifier func(v interface{}) interface{}

// IncrInt returns a modifier for int/int8/int16/int32/int64 increment
func IncrInt(to interface{}) Modifier {
	return func(v interface{}) interface{} {
		if x, ok := v.(int); ok {
			return x + to.(int)
		}
		if x, ok := v.(int8); ok {
			return x + to.(int8)
		}
		if x, ok := v.(int16); ok {
			return x + to.(int16)
		}
		if x, ok := v.(int32); ok {
			return x + to.(int32)
		}
		if x, ok := v.(int64); ok {
			return x + to.(int64)
		}
		panic("y/update: unknown int type for increment.")
	}
}

// IncrFloat returns a modifier for float32/float64 increment
func IncrFloat(to interface{}) Modifier {
	return func(v interface{}) interface{} {
		if x, ok := v.(float32); ok {
			return x + to.(float32)
		}
		if x, ok := v.(float64); ok {
			return x + to.(float64)
		}
		panic("y/update: unknown float type for increment.")
	}
}

func (c *Changer) modify() sq.Eq {
	modified := sq.Eq{}
	for name, val := range c.values {
		f := c.proxy.Field(name)
		if modifier, ok := val.(Modifier); ok {
			val = modifier(f.Interface())
		}
		if f.Interface() != val {
			modified[name] = val
			f.Set(reflect.ValueOf(val))
		}
	}
	return modified
}

func (c *Changer) primary() sq.Eq {
	pks := sq.Eq{}
	for _, pk := range c.proxy.schema.xinfo.pk {
		pks[pk] = c.proxy.Field(pk).Interface()
	}
	return pks
}

func (c *Changer) prepare(clauses sq.Eq, where sq.Eq) sq.UpdateBuilder {
	return sq.Update(c.proxy.schema.table).SetMap(clauses).Where(where)
}

// Update saves object changes in db after version validation
func (c *Changer) Update(db DB) (updated bool, err error) {
	// load origin
	err = c.proxy.Load(db)
	if err != nil {
		return
	}
	oldv := c.proxy.Version()
	newv := oldv + 1
	// find changes
	clauses := c.modify()
	if len(clauses) == 0 {
		return
	}
	// set new version
	clauses[_version] = newv
	c.proxy.Field(_version).SetInt(newv)
	// set where condition
	where := c.primary()
	where[_version] = oldv
	// save
	result, err := exec(c.prepare(clauses, where), db)
	if err != nil {
		return
	}
	count, err := result.RowsAffected()
	updated = count == 1
	return
}

func makeChanger(p *Proxy, v Values) *Changer {
	return &Changer{p, v}
}

// Update saves object changes
func Update(db DB, p *Proxy, v Values) (bool, error) {
	return makeChanger(p, v).Update(db)
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.

// Package bencode implements bencoding of data as defined in BEP 3 using
// type assertion over reflection for performance.
package bencode

import (
	"bytes"
	"fmt"
	"io"
	"strconv"
	"time"
)

// Dict represents a bencode dictionary.
type Dict map[string]interface{}

// NewDict allocates the memory for a Dict.
func NewDict() Dict {
	return make(Dict)
}

// An Encoder writes Bencoded objects to an output stream.
type Encoder struct {
	w io.Writer
}

// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
	return &Encoder{w: w}
}

// Encode writes the bencoding of v to the stream.
func (enc *Encoder) Encode(v interface{}) error {
	return marshal(enc.w, v)
}

// Marshal returns the bencoding of v.
func Marshal(v interface{}) ([]byte, error) {
	buf := &bytes.Buffer{}
	err := marshal(buf, v)
	return buf.Bytes(), err
}

// Marshaler is the interface implemented by objects that can marshal
// themselves.
type Marshaler interface {
	MarshalBencode() ([]byte, error)
}

// marshal writes types bencoded to an io.Writer
func marshal(w io.Writer, data interface{}) error {
	switch v := data.(type) {
	case Marshaler:
		bencoded, err := v.MarshalBencode()
		if err != nil {
			return err
		}
		_, err = w.Write(bencoded)
		if err != nil {
			return err
		}

	case string:
		marshalString(w, v)

	case int:
		marshalInt(w, int64(v))

	case uint:
		marshalUint(w, uint64(v))

	case int64:
		marshalInt(w, v)

	case uint64:
		marshalUint(w, v)

	case []byte:
		w.Write(v)

	case time.Duration: // Assume seconds
		marshalInt(w, int64(v/time.Second))

	case Dict:
		w.Write([]byte{'d'})
		for key, val := range v {
			marshalString(w, key)
			err := marshal(w, val)
			if err != nil {
				return err
			}
		}
		w.Write([]byte{'e'})

	case []Dict:
		w.Write([]byte{'l'})
		for _, val := range v {
			err := marshal(w, val)
			if err != nil {
				return err
			}
		}
		w.Write([]byte{'e'})

	case []string:
		w.Write([]byte{'l'})
		for _, val := range v {
			err := marshal(w, val)
			if err != nil {
				return err
			}
		}
		w.Write([]byte{'e'})

	default:
		// Although not currently necessary,
		// should handle []interface{} manually; Go can't do it implicitly
		return fmt.Errorf("attempted to marshal unsupported type:\n%t", v)
	}

	return nil
}

func marshalInt(w io.Writer, v int64) {
	w.Write([]byte{'i'})
	w.Write([]byte(strconv.FormatInt(v, 10)))
	w.Write([]byte{'e'})
}

func marshalUint(w io.Writer, v uint64) {
	w.Write([]byte{'i'})
	w.Write([]byte(strconv.FormatUint(v, 10)))
	w.Write([]byte{'e'})
}

func marshalString(w io.Writer, v string) {
	w.Write([]byte(strconv.Itoa(len(v))))
	w.Write([]byte{':'})
	w.Write([]byte(v))
}
<commit_msg>fix tests<commit_after>// Copyright 2014 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.

// Package bencode implements bencoding of data as defined in BEP 3 using
// type assertion over reflection for performance.
package bencode

import (
	"bytes"
	"fmt"
	"io"
	"strconv"
	"time"
)

// Dict represents a bencode dictionary.
type Dict map[string]interface{}

// NewDict allocates the memory for a Dict.
func NewDict() Dict {
	return make(Dict)
}

// An Encoder writes Bencoded objects to an output stream.
type Encoder struct {
	w io.Writer
}

// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
	return &Encoder{w: w}
}

// Encode writes the bencoding of v to the stream.
func (enc *Encoder) Encode(v interface{}) error {
	return marshal(enc.w, v)
}

// Marshal returns the bencoding of v.
func Marshal(v interface{}) ([]byte, error) {
	buf := &bytes.Buffer{}
	err := marshal(buf, v)
	return buf.Bytes(), err
}

// Marshaler is the interface implemented by objects that can marshal
// themselves.
type Marshaler interface {
	MarshalBencode() ([]byte, error)
}

// marshal writes types bencoded to an io.Writer
func marshal(w io.Writer, data interface{}) error {
	switch v := data.(type) {
	case Marshaler:
		bencoded, err := v.MarshalBencode()
		if err != nil {
			return err
		}
		_, err = w.Write(bencoded)
		if err != nil {
			return err
		}

	case string:
		marshalString(w, v)

	case int:
		marshalInt(w, int64(v))

	case uint:
		marshalUint(w, uint64(v))

	case int64:
		marshalInt(w, v)

	case uint64:
		marshalUint(w, v)

	case []byte:
		w.Write(v)

	case time.Duration: // Assume seconds
		marshalInt(w, int64(v/time.Second))

	case Dict:
		marshal(w, map[string]interface{}(v))

	case []Dict:
		w.Write([]byte{'l'})
		for _, val := range v {
			err := marshal(w, val)
			if err != nil {
				return err
			}
		}
		w.Write([]byte{'e'})

	case map[string]interface{}:
		w.Write([]byte{'d'})
		for key, val := range v {
			marshalString(w, key)
			err := marshal(w, val)
			if err != nil {
				return err
			}
		}
		w.Write([]byte{'e'})

	case []string:
		w.Write([]byte{'l'})
		for _, val := range v {
			err := marshal(w, val)
			if err != nil {
				return err
			}
		}
		w.Write([]byte{'e'})

	default:
		// Although not currently necessary,
		// should handle []interface{} manually; Go can't do it implicitly
		return fmt.Errorf("attempted to marshal unsupported type:\n%t", v)
	}

	return nil
}

func marshalInt(w io.Writer, v int64) {
	w.Write([]byte{'i'})
	w.Write([]byte(strconv.FormatInt(v, 10)))
	w.Write([]byte{'e'})
}

func marshalUint(w io.Writer, v uint64) {
	w.Write([]byte{'i'})
	w.Write([]byte(strconv.FormatUint(v, 10)))
	w.Write([]byte{'e'})
}

func marshalString(w io.Writer, v string) {
	w.Write([]byte(strconv.Itoa(len(v))))
	w.Write([]byte{':'})
	w.Write([]byte(v))
}
<|endoftext|>


<commit_before>package goutils

type UploadHandler struct {}

func (m *UploadHandler)ServeHTTP(w http.ResponseWriter, req *http.Request)  {
	uri:=req.RequestURI
	if req.Method=="POST" {
		if "/upload"==uri {
			m.Upload(w,req)
		}else if "/streamUpload"==uri{
			m.StreamUpload(w,req)
		}
	}
}

func (m *UploadHandler) Upload(w http.ResponseWriter, req * http.Request)  {
	start:=time.Now()
	req.ParseForm()
	data:=req.FormValue("imgdata")
	b64data := data[strings.IndexByte(data, ',')+1:]
	enc:=base64.StdEncoding
	bs,derr:=enc.DecodeString(b64data)
	if goutils.CheckErr(derr) {
		fmt.Fprint(w, derr)
		return
	}
	gerr:=goutils.WriteFile("upload.png",bs)
	if goutils.CheckErr(gerr) {
		fmt.Fprint(w,gerr)
		return
	}
	fmt.Fprint(w,"success")
	fmt.Println("cost:",time.Now().Sub(start))
}

func (m *UploadHandler) StreamUpload(w http.ResponseWriter, req * http.Request)  {
	enc:=base64.StdEncoding
	file,err:=os.OpenFile("page.png",os.O_CREATE|os.O_WRONLY,0644)
	defer file.Close()
	if goutils.CheckErr(err) {
		fmt.Fprint(w, err)
		return
	}

	try:=make([]byte,120)
	peekR:=bufio.NewReader(req.Body)
	peekR.ReadBytes(',')

	start:=time.Now()
	allbytes:=make([]byte,0,req.ContentLength)
	for{
		n1,err1:=peekR.Read(try)
		if n1>0 {
			allbytes = append(allbytes,try[:n1]...)
		}
		if goutils.CheckErr(err1) {
			break
		}
	}

	dst:=make([]byte,len(allbytes)*2)
	n3,err:=enc.Decode(dst,allbytes)
	if !goutils.CheckErr(err) {
		file.Write(dst[:n3])
	}
	fmt.Fprint(w,"success")
	fmt.Println("cost:",time.Now().Sub(start))
}<commit_msg>upload<commit_after>package goutils
import (
	"net/http"
	"fmt"
	"encoding/base64"
	"os"
	"strings"
	"bufio"
	"time"
)

type UploadHandler struct {}

func (m *UploadHandler)ServeHTTP(w http.ResponseWriter, req *http.Request)  {
	uri:=req.RequestURI
	fmt.Println("URI:",uri)
	if req.Method=="POST" {

		if strings.HasSuffix(uri,"/upload") {
			m.Upload(w,req)
		}else if strings.HasSuffix(uri,"/streamUpload") {
			m.StreamUpload(w,req)
		}
	}
}

func (m *UploadHandler) Upload(w http.ResponseWriter, req * http.Request)  {
	start:=time.Now()
	req.ParseForm()
	data:=req.FormValue("imgdata")
	b64data := data[strings.IndexByte(data, ',')+1:]
	enc:=base64.StdEncoding
	bs,derr:=enc.DecodeString(b64data)
	if CheckErr(derr) {
		fmt.Fprint(w, derr)
		return
	}
	gerr:=WriteFile("MDFs/page.png",bs)
	if CheckErr(gerr) {
		fmt.Fprint(w,gerr)
		return
	}
	fmt.Fprint(w,"success")
	fmt.Println("cost:",time.Now().Sub(start))
}

func (m *UploadHandler) StreamUpload(w http.ResponseWriter, req * http.Request)  {
	enc:=base64.StdEncoding
	file,err:=os.OpenFile("MDFs/page.png",os.O_CREATE|os.O_WRONLY,0644)
	defer file.Close()
	if CheckErr(err) {
		fmt.Fprint(w, err)
		return
	}

	try:=make([]byte,120)
	peekR:=bufio.NewReader(req.Body)
	peekR.ReadBytes(',')

	start:=time.Now()
	allbytes:=make([]byte,0,req.ContentLength)
	for{
		n1,err1:=peekR.Read(try)
		if n1>0 {
			allbytes = append(allbytes,try[:n1]...)
		}
		if CheckErr(err1) {
			break
		}
	}

	dst:=make([]byte,len(allbytes)*2)
	n3,err:=enc.Decode(dst,allbytes)
	if !CheckErr(err) {
		file.Write(dst[:n3])
	}
	fmt.Fprint(w,"success")
	fmt.Println("cost:",time.Now().Sub(start))
}<|endoftext|>


<commit_before>// Copyright The OpenTelemetry Authors
//
// 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 lokiexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/lokiexporter"

import (
	"encoding/json"
	"fmt"

	"go.opentelemetry.io/collector/pdata/pcommon"
	"go.opentelemetry.io/collector/pdata/plog"
)

// JSON representation of the LogRecord as described by https://developers.google.com/protocol-buffers/docs/proto3#json

type lokiEntry struct {
	Name       string                 `json:"name,omitempty"`
	Body       json.RawMessage        `json:"body,omitempty"`
	TraceID    string                 `json:"traceid,omitempty"`
	SpanID     string                 `json:"spanid,omitempty"`
	Severity   string                 `json:"severity,omitempty"`
	Attributes map[string]interface{} `json:"attributes,omitempty"`
	Resources  map[string]interface{} `json:"resources,omitempty"`
}

func serializeBody(body pcommon.Value) ([]byte, error) {
	var str []byte
	var err error
	switch body.Type() {
	case pcommon.ValueTypeEmpty:
		// no body

	case pcommon.ValueTypeString:
		str, err = json.Marshal(body.StringVal())

	case pcommon.ValueTypeInt:
		str, err = json.Marshal(body.IntVal())

	case pcommon.ValueTypeDouble:
		str, err = json.Marshal(body.DoubleVal())

	case pcommon.ValueTypeBool:
		str, err = json.Marshal(body.BoolVal())

	case pcommon.ValueTypeMap:
		str, err = json.Marshal(body.MapVal().AsRaw())

	case pcommon.ValueTypeSlice:
		str, err = json.Marshal(attributeValueSliceAsRaw(body.SliceVal()))

	case pcommon.ValueTypeBytes:
		str, err = json.Marshal(body.MBytesVal())

	default:
		err = fmt.Errorf("unsuported body type to serialize")
	}
	return str, err
}

func encodeJSON(lr plog.LogRecord, res pcommon.Resource) (string, error) {
	var logRecord lokiEntry
	var jsonRecord []byte
	var err error
	var body []byte

	body, err = serializeBody(lr.Body())
	if err != nil {
		return "", err
	}
	logRecord = lokiEntry{
		Body:       body,
		TraceID:    lr.TraceID().HexString(),
		SpanID:     lr.SpanID().HexString(),
		Severity:   lr.SeverityText(),
		Attributes: lr.Attributes().AsRaw(),
		Resources:  res.Attributes().AsRaw(),
	}
	lr.Body().Type()

	jsonRecord, err = json.Marshal(logRecord)
	if err != nil {
		return "", err
	}
	return string(jsonRecord), nil
}

// Copied from pdata (es AttributeValueSlice) asRaw() since its not exported
func attributeValueSliceAsRaw(es pcommon.Slice) []interface{} {
	rawSlice := make([]interface{}, 0, es.Len())
	for i := 0; i < es.Len(); i++ {
		v := es.At(i)
		switch v.Type() {
		case pcommon.ValueTypeString:
			rawSlice = append(rawSlice, v.StringVal())
		case pcommon.ValueTypeInt:
			rawSlice = append(rawSlice, v.IntVal())
		case pcommon.ValueTypeDouble:
			rawSlice = append(rawSlice, v.DoubleVal())
		case pcommon.ValueTypeBool:
			rawSlice = append(rawSlice, v.BoolVal())
		case pcommon.ValueTypeBytes:
			rawSlice = append(rawSlice, v.MBytesVal())
		case pcommon.ValueTypeEmpty:
			rawSlice = append(rawSlice, nil)
		default:
			rawSlice = append(rawSlice, "<Invalid array value>")
		}
	}
	return rawSlice
}
<commit_msg>[exporter/loki] Remove function copied from core, use new API instead (#9991)<commit_after>// Copyright The OpenTelemetry Authors
//
// 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 lokiexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/lokiexporter"

import (
	"encoding/json"
	"fmt"

	"go.opentelemetry.io/collector/pdata/pcommon"
	"go.opentelemetry.io/collector/pdata/plog"
)

// JSON representation of the LogRecord as described by https://developers.google.com/protocol-buffers/docs/proto3#json

type lokiEntry struct {
	Name       string                 `json:"name,omitempty"`
	Body       json.RawMessage        `json:"body,omitempty"`
	TraceID    string                 `json:"traceid,omitempty"`
	SpanID     string                 `json:"spanid,omitempty"`
	Severity   string                 `json:"severity,omitempty"`
	Attributes map[string]interface{} `json:"attributes,omitempty"`
	Resources  map[string]interface{} `json:"resources,omitempty"`
}

func serializeBody(body pcommon.Value) ([]byte, error) {
	var str []byte
	var err error
	switch body.Type() {
	case pcommon.ValueTypeEmpty:
		// no body

	case pcommon.ValueTypeString:
		str, err = json.Marshal(body.StringVal())

	case pcommon.ValueTypeInt:
		str, err = json.Marshal(body.IntVal())

	case pcommon.ValueTypeDouble:
		str, err = json.Marshal(body.DoubleVal())

	case pcommon.ValueTypeBool:
		str, err = json.Marshal(body.BoolVal())

	case pcommon.ValueTypeMap:
		str, err = json.Marshal(body.MapVal().AsRaw())

	case pcommon.ValueTypeSlice:
		str, err = json.Marshal(body.SliceVal().AsRaw())

	case pcommon.ValueTypeBytes:
		str, err = json.Marshal(body.MBytesVal())

	default:
		err = fmt.Errorf("unsuported body type to serialize")
	}
	return str, err
}

func encodeJSON(lr plog.LogRecord, res pcommon.Resource) (string, error) {
	var logRecord lokiEntry
	var jsonRecord []byte
	var err error
	var body []byte

	body, err = serializeBody(lr.Body())
	if err != nil {
		return "", err
	}
	logRecord = lokiEntry{
		Body:       body,
		TraceID:    lr.TraceID().HexString(),
		SpanID:     lr.SpanID().HexString(),
		Severity:   lr.SeverityText(),
		Attributes: lr.Attributes().AsRaw(),
		Resources:  res.Attributes().AsRaw(),
	}
	lr.Body().Type()

	jsonRecord, err = json.Marshal(logRecord)
	if err != nil {
		return "", err
	}
	return string(jsonRecord), nil
}
<|endoftext|>


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

package main

import (
	"fmt"
	"math/rand"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus"
	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/coreos/go-systemd/util"
)

func TestServiceFile(t *testing.T) {
	if !util.IsRunningSystemd() {
		t.Skip("Systemd is not running on the host.")
	}

	ctx := newRktRunCtx()
	defer ctx.cleanup()

	r := rand.New(rand.NewSource(time.Now().UnixNano()))

	conn, err := dbus.New()
	if err != nil {
		t.Fatal(err)
	}

	image, err := filepath.Abs("rkt-inspect.aci")
	if err != nil {
		t.Fatal(err)
	}
	opts := "-- --print-msg=HelloWorld --sleep=1000"

	cmd := fmt.Sprintf("%s --insecure-skip-verify run --set-env=MESSAGE_LOOP=1000 %s %s", ctx.cmd(), image, opts)
	props := []dbus.Property{
		dbus.PropExecStart(strings.Split(cmd, " "), false),
	}
	target := fmt.Sprintf("rkt-testing-transient-%d.service", r.Int())

	reschan := make(chan string)
	_, err = conn.StartTransientUnit(target, "replace", props, reschan)
	if err != nil {
		t.Fatal(err)
	}

	job := <-reschan
	if job != "done" {
		t.Fatal("Job is not done:", job)
	}

	units, err := conn.ListUnits()

	var found bool
	for _, u := range units {
		if u.Name == target {
			found = true
			if u.ActiveState != "active" {
				t.Fatalf("Test unit %s not active: %s (target: %s)", u.Name, u.ActiveState, target)
			}
		}
	}

	if !found {
		t.Fatalf("Test unit not found in list")
	}

	// Run the unit for 10 seconds. You can check the logs manually in journalctl
	time.Sleep(10 * time.Second)

	// Stop the unit
	_, err = conn.StopUnit(target, "replace", reschan)
	if err != nil {
		t.Fatal(err)
	}

	// wait for StopUnit job to complete
	<-reschan

	units, err = conn.ListUnits()

	found = false
	for _, u := range units {
		if u.Name == target {
			found = true
		}
	}

	if found {
		t.Fatalf("Test unit found in list, should be stopped")
	}
}
<commit_msg>functional tests: Fix ServiceFileTest<commit_after>// Copyright 2015 The rkt Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"fmt"
	"math/rand"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/coreos/go-systemd/dbus"
	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/coreos/go-systemd/util"
)

func TestServiceFile(t *testing.T) {
	if !util.IsRunningSystemd() {
		t.Skip("Systemd is not running on the host.")
	}

	ctx := newRktRunCtx()
	defer ctx.cleanup()

	r := rand.New(rand.NewSource(time.Now().UnixNano()))

	conn, err := dbus.New()
	if err != nil {
		t.Fatal(err)
	}

	image, err := filepath.Abs("rkt-inspect.aci")
	if err != nil {
		t.Fatal(err)
	}
	opts := "-- --print-msg=HelloWorld --sleep=1000"

	cmd := fmt.Sprintf("%s --insecure-skip-verify run --mds-register=false --set-env=MESSAGE_LOOP=1000 %s %s", ctx.cmd(), image, opts)
	props := []dbus.Property{
		dbus.PropExecStart(strings.Split(cmd, " "), false),
	}
	target := fmt.Sprintf("rkt-testing-transient-%d.service", r.Int())

	reschan := make(chan string)
	_, err = conn.StartTransientUnit(target, "replace", props, reschan)
	if err != nil {
		t.Fatal(err)
	}

	job := <-reschan
	if job != "done" {
		t.Fatal("Job is not done:", job)
	}

	units, err := conn.ListUnits()

	var found bool
	for _, u := range units {
		if u.Name == target {
			found = true
			if u.ActiveState != "active" {
				t.Fatalf("Test unit %s not active: %s (target: %s)", u.Name, u.ActiveState, target)
			}
		}
	}

	if !found {
		t.Fatalf("Test unit not found in list")
	}

	// Run the unit for 10 seconds. You can check the logs manually in journalctl
	time.Sleep(10 * time.Second)

	// Stop the unit
	_, err = conn.StopUnit(target, "replace", reschan)
	if err != nil {
		t.Fatal(err)
	}

	// wait for StopUnit job to complete
	<-reschan

	units, err = conn.ListUnits()

	found = false
	for _, u := range units {
		if u.Name == target {
			found = true
		}
	}

	if found {
		t.Fatalf("Test unit found in list, should be stopped")
	}
}
<|endoftext|>


<commit_before>// (c) Copyright IBM Corp. 2021
// (c) Copyright Instana Inc. 2016

package instana

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"

	"github.com/instana/go-sensor/acceptor"
	"github.com/instana/go-sensor/autoprofile"
)

const (
	agentDiscoveryURL = "/com.instana.plugin.golang.discovery"
	agentTracesURL    = "/com.instana.plugin.golang/traces."
	agentDataURL      = "/com.instana.plugin.golang."
	agentEventURL     = "/com.instana.plugin.generic.event"
	agentProfilesURL  = "/com.instana.plugin.golang/profiles."
	agentDefaultHost  = "localhost"
	agentDefaultPort  = 42699
	agentHeader       = "Instana Agent"

	// SnapshotPeriod is the amount of time in seconds between snapshot reports.
	SnapshotPeriod             = 600
	snapshotCollectionInterval = SnapshotPeriod * time.Second
)

type agentResponse struct {
	Pid     uint32 `json:"pid"`
	HostID  string `json:"agentUuid"`
	Secrets struct {
		Matcher string   `json:"matcher"`
		List    []string `json:"list"`
	} `json:"secrets"`
	ExtraHTTPHeaders []string `json:"extraHeaders"`
}

type discoveryS struct {
	PID   int      `json:"pid"`
	Name  string   `json:"name"`
	Args  []string `json:"args"`
	Fd    string   `json:"fd"`
	Inode string   `json:"inode"`
}

type fromS struct {
	EntityID string `json:"e"`
	// Serverless agents fields
	Hostless      bool   `json:"hl,omitempty"`
	CloudProvider string `json:"cp,omitempty"`
	// Host agent fields
	HostID string `json:"h,omitempty"`
}

func newHostAgentFromS(pid int, hostID string) *fromS {
	return &fromS{
		EntityID: strconv.Itoa(pid),
		HostID:   hostID,
	}
}

func newServerlessAgentFromS(entityID, provider string) *fromS {
	return &fromS{
		EntityID:      entityID,
		Hostless:      true,
		CloudProvider: provider,
	}
}

type agentS struct {
	from *fromS
	host string
	port string

	fsm      *fsmS
	client   *http.Client
	snapshot *SnapshotCollector
	logger   LeveledLogger
}

func newAgent(serviceName, host string, port int, logger LeveledLogger) *agentS {
	if logger == nil {
		logger = defaultLogger
	}

	logger.Debug("initializing agent")

	agent := &agentS{
		from:   &fromS{},
		host:   host,
		port:   strconv.Itoa(port),
		client: &http.Client{Timeout: 5 * time.Second},
		snapshot: &SnapshotCollector{
			CollectionInterval: snapshotCollectionInterval,
			ServiceName:        serviceName,
		},
		logger: logger,
	}
	agent.fsm = newFSM(agent)

	return agent
}

// Ready returns whether the agent has finished the announcement and is ready to send data
func (agent *agentS) Ready() bool {
	return agent.fsm.fsm.Current() == "ready"
}

// SendMetrics sends collected entity data to the host agent
func (agent *agentS) SendMetrics(data acceptor.Metrics) error {
	pid, err := strconv.Atoi(agent.from.EntityID)
	if err != nil && agent.from.EntityID != "" {
		agent.logger.Debug("agent got malformed PID %q", agent.from.EntityID)
	}

	if _, err = agent.request(agent.makeURL(agentDataURL), "POST", acceptor.GoProcessData{
		PID:      pid,
		Snapshot: agent.snapshot.Collect(),
		Metrics:  data,
	}); err != nil {
		agent.logger.Error("failed to send metrics to the host agent: ", err)
		agent.reset()

		return err
	}

	return nil
}

// SendEvent sends an event using Instana Events API
func (agent *agentS) SendEvent(event *EventData) error {
	_, err := agent.request(agent.makeURL(agentEventURL), "POST", event)
	if err != nil {
		// do not reset the agent as it might be not initialized at this state yet
		agent.logger.Warn("failed to send event ", event.Title, " to the host agent: ", err)

		return err
	}

	return nil
}

// SendSpans sends collected spans to the host agent
func (agent *agentS) SendSpans(spans []Span) error {
	for i := range spans {
		spans[i].From = agent.from
	}

	_, err := agent.request(agent.makeURL(agentTracesURL), "POST", spans)
	if err != nil {
		agent.logger.Error("failed to send spans to the host agent: ", err)
		agent.reset()

		return err
	}

	return nil
}

// Flush is a noop for host agent
func (agent *agentS) Flush(ctx context.Context) error { return nil }

type hostAgentProfile struct {
	autoprofile.Profile
	ProcessID string `json:"pid"`
}

// SendProfiles sends profile data to the agent
func (agent *agentS) SendProfiles(profiles []autoprofile.Profile) error {
	agentProfiles := make([]hostAgentProfile, 0, len(profiles))
	for _, p := range profiles {
		agentProfiles = append(agentProfiles, hostAgentProfile{p, agent.from.EntityID})
	}

	_, err := agent.request(agent.makeURL(agentProfilesURL), "POST", agentProfiles)
	if err != nil {
		agent.logger.Error("failed to send profile data to the host agent: ", err)
		agent.reset()

		return err
	}

	return nil
}

func (agent *agentS) setLogger(l LeveledLogger) {
	agent.logger = l
}

func (agent *agentS) makeURL(prefix string) string {
	return agent.makeHostURL(agent.host, prefix)
}

func (agent *agentS) makeHostURL(host string, prefix string) string {
	var buffer bytes.Buffer

	buffer.WriteString("http://")
	buffer.WriteString(host)
	buffer.WriteString(":")
	buffer.WriteString(agent.port)
	buffer.WriteString(prefix)
	if prefix[len(prefix)-1:] == "." && agent.from.EntityID != "" {
		buffer.WriteString(agent.from.EntityID)
	}

	return buffer.String()
}

func (agent *agentS) head(url string) (string, error) {
	return agent.request(url, "HEAD", nil)
}

func (agent *agentS) request(url string, method string, data interface{}) (string, error) {
	return agent.fullRequestResponse(url, method, data, nil, "")
}

func (agent *agentS) requestResponse(url string, method string, data interface{}, ret interface{}) (string, error) {
	return agent.fullRequestResponse(url, method, data, ret, "")
}

func (agent *agentS) requestHeader(url string, method string, header string) (string, error) {
	return agent.fullRequestResponse(url, method, nil, nil, header)
}

func (agent *agentS) fullRequestResponse(url string, method string, data interface{}, body interface{}, header string) (string, error) {
	var j []byte
	var ret string
	var err error
	var resp *http.Response
	var req *http.Request

	if data != nil {
		j, err = json.Marshal(data)
	}

	if err == nil {
		if j != nil {
			req, err = http.NewRequest(method, url, bytes.NewBuffer(j))
		} else {
			req, err = http.NewRequest(method, url, nil)
		}

		// Uncomment this to dump json payloads
		// log.debug(bytes.NewBuffer(j))

		if err == nil {
			req.Header.Set("Content-Type", "application/json")
			resp, err = agent.client.Do(req)
			if err == nil {
				defer resp.Body.Close()

				if resp.StatusCode < 200 || resp.StatusCode >= 300 {
					err = errors.New(resp.Status)
				} else {
					if body != nil {
						var b []byte
						b, err = ioutil.ReadAll(resp.Body)
						json.Unmarshal(b, body)
					}

					if header != "" {
						ret = resp.Header.Get(header)
					}
				}
			}
		}
	}

	if err != nil {
		// Ignore errors while in announced stated (before ready) as
		// this is the time where the entity is registering in the Instana
		// backend and it will return 404 until it's done.
		if !agent.fsm.fsm.Is("announced") {
			agent.logger.Info("failed to send a request to ", url, ": ", err)
		}
	}

	return ret, err
}

func (agent *agentS) applyHostAgentSettings(resp agentResponse) {
	agent.from = newHostAgentFromS(int(resp.Pid), resp.HostID)

	if resp.Secrets.Matcher != "" {
		m, err := NamedMatcher(resp.Secrets.Matcher, resp.Secrets.List)
		if err != nil {
			agent.logger.Warn("failed to apply secrets matcher configuration: ", err)
		} else {
			sensor.options.Tracer.Secrets = m
		}
	}

	sensor.options.Tracer.CollectableHTTPHeaders = resp.ExtraHTTPHeaders
}

func (agent *agentS) setHost(host string) {
	agent.host = host
}

func (agent *agentS) reset() {
	agent.fsm.reset()
}
<commit_msg>Ignore the data race during agent initialization<commit_after>// (c) Copyright IBM Corp. 2021
// (c) Copyright Instana Inc. 2016

package instana

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"

	"github.com/instana/go-sensor/acceptor"
	"github.com/instana/go-sensor/autoprofile"
)

const (
	agentDiscoveryURL = "/com.instana.plugin.golang.discovery"
	agentTracesURL    = "/com.instana.plugin.golang/traces."
	agentDataURL      = "/com.instana.plugin.golang."
	agentEventURL     = "/com.instana.plugin.generic.event"
	agentProfilesURL  = "/com.instana.plugin.golang/profiles."
	agentDefaultHost  = "localhost"
	agentDefaultPort  = 42699
	agentHeader       = "Instana Agent"

	// SnapshotPeriod is the amount of time in seconds between snapshot reports.
	SnapshotPeriod             = 600
	snapshotCollectionInterval = SnapshotPeriod * time.Second
)

type agentResponse struct {
	Pid     uint32 `json:"pid"`
	HostID  string `json:"agentUuid"`
	Secrets struct {
		Matcher string   `json:"matcher"`
		List    []string `json:"list"`
	} `json:"secrets"`
	ExtraHTTPHeaders []string `json:"extraHeaders"`
}

type discoveryS struct {
	PID   int      `json:"pid"`
	Name  string   `json:"name"`
	Args  []string `json:"args"`
	Fd    string   `json:"fd"`
	Inode string   `json:"inode"`
}

type fromS struct {
	EntityID string `json:"e"`
	// Serverless agents fields
	Hostless      bool   `json:"hl,omitempty"`
	CloudProvider string `json:"cp,omitempty"`
	// Host agent fields
	HostID string `json:"h,omitempty"`
}

func newHostAgentFromS(pid int, hostID string) *fromS {
	return &fromS{
		EntityID: strconv.Itoa(pid),
		HostID:   hostID,
	}
}

func newServerlessAgentFromS(entityID, provider string) *fromS {
	return &fromS{
		EntityID:      entityID,
		Hostless:      true,
		CloudProvider: provider,
	}
}

type agentS struct {
	from *fromS
	host string
	port string

	fsm      *fsmS
	client   *http.Client
	snapshot *SnapshotCollector
	logger   LeveledLogger
}

//go:norace
func newAgent(serviceName, host string, port int, logger LeveledLogger) *agentS {
	if logger == nil {
		logger = defaultLogger
	}

	logger.Debug("initializing agent")

	agent := &agentS{
		from:   &fromS{},
		host:   host,
		port:   strconv.Itoa(port),
		client: &http.Client{Timeout: 5 * time.Second},
		snapshot: &SnapshotCollector{
			CollectionInterval: snapshotCollectionInterval,
			ServiceName:        serviceName,
		},
		logger: logger,
	}
	agent.fsm = newFSM(agent)

	return agent
}

// Ready returns whether the agent has finished the announcement and is ready to send data
func (agent *agentS) Ready() bool {
	return agent.fsm.fsm.Current() == "ready"
}

// SendMetrics sends collected entity data to the host agent
func (agent *agentS) SendMetrics(data acceptor.Metrics) error {
	pid, err := strconv.Atoi(agent.from.EntityID)
	if err != nil && agent.from.EntityID != "" {
		agent.logger.Debug("agent got malformed PID %q", agent.from.EntityID)
	}

	if _, err = agent.request(agent.makeURL(agentDataURL), "POST", acceptor.GoProcessData{
		PID:      pid,
		Snapshot: agent.snapshot.Collect(),
		Metrics:  data,
	}); err != nil {
		agent.logger.Error("failed to send metrics to the host agent: ", err)
		agent.reset()

		return err
	}

	return nil
}

// SendEvent sends an event using Instana Events API
func (agent *agentS) SendEvent(event *EventData) error {
	_, err := agent.request(agent.makeURL(agentEventURL), "POST", event)
	if err != nil {
		// do not reset the agent as it might be not initialized at this state yet
		agent.logger.Warn("failed to send event ", event.Title, " to the host agent: ", err)

		return err
	}

	return nil
}

// SendSpans sends collected spans to the host agent
func (agent *agentS) SendSpans(spans []Span) error {
	for i := range spans {
		spans[i].From = agent.from
	}

	_, err := agent.request(agent.makeURL(agentTracesURL), "POST", spans)
	if err != nil {
		agent.logger.Error("failed to send spans to the host agent: ", err)
		agent.reset()

		return err
	}

	return nil
}

// Flush is a noop for host agent
func (agent *agentS) Flush(ctx context.Context) error { return nil }

type hostAgentProfile struct {
	autoprofile.Profile
	ProcessID string `json:"pid"`
}

// SendProfiles sends profile data to the agent
func (agent *agentS) SendProfiles(profiles []autoprofile.Profile) error {
	agentProfiles := make([]hostAgentProfile, 0, len(profiles))
	for _, p := range profiles {
		agentProfiles = append(agentProfiles, hostAgentProfile{p, agent.from.EntityID})
	}

	_, err := agent.request(agent.makeURL(agentProfilesURL), "POST", agentProfiles)
	if err != nil {
		agent.logger.Error("failed to send profile data to the host agent: ", err)
		agent.reset()

		return err
	}

	return nil
}

func (agent *agentS) setLogger(l LeveledLogger) {
	agent.logger = l
}

func (agent *agentS) makeURL(prefix string) string {
	return agent.makeHostURL(agent.host, prefix)
}

func (agent *agentS) makeHostURL(host string, prefix string) string {
	var buffer bytes.Buffer

	buffer.WriteString("http://")
	buffer.WriteString(host)
	buffer.WriteString(":")
	buffer.WriteString(agent.port)
	buffer.WriteString(prefix)
	if prefix[len(prefix)-1:] == "." && agent.from.EntityID != "" {
		buffer.WriteString(agent.from.EntityID)
	}

	return buffer.String()
}

func (agent *agentS) head(url string) (string, error) {
	return agent.request(url, "HEAD", nil)
}

func (agent *agentS) request(url string, method string, data interface{}) (string, error) {
	return agent.fullRequestResponse(url, method, data, nil, "")
}

func (agent *agentS) requestResponse(url string, method string, data interface{}, ret interface{}) (string, error) {
	return agent.fullRequestResponse(url, method, data, ret, "")
}

func (agent *agentS) requestHeader(url string, method string, header string) (string, error) {
	return agent.fullRequestResponse(url, method, nil, nil, header)
}

func (agent *agentS) fullRequestResponse(url string, method string, data interface{}, body interface{}, header string) (string, error) {
	var j []byte
	var ret string
	var err error
	var resp *http.Response
	var req *http.Request

	if data != nil {
		j, err = json.Marshal(data)
	}

	if err == nil {
		if j != nil {
			req, err = http.NewRequest(method, url, bytes.NewBuffer(j))
		} else {
			req, err = http.NewRequest(method, url, nil)
		}

		// Uncomment this to dump json payloads
		// log.debug(bytes.NewBuffer(j))

		if err == nil {
			req.Header.Set("Content-Type", "application/json")
			resp, err = agent.client.Do(req)
			if err == nil {
				defer resp.Body.Close()

				if resp.StatusCode < 200 || resp.StatusCode >= 300 {
					err = errors.New(resp.Status)
				} else {
					if body != nil {
						var b []byte
						b, err = ioutil.ReadAll(resp.Body)
						json.Unmarshal(b, body)
					}

					if header != "" {
						ret = resp.Header.Get(header)
					}
				}
			}
		}
	}

	if err != nil {
		// Ignore errors while in announced stated (before ready) as
		// this is the time where the entity is registering in the Instana
		// backend and it will return 404 until it's done.
		if !agent.fsm.fsm.Is("announced") {
			agent.logger.Info("failed to send a request to ", url, ": ", err)
		}
	}

	return ret, err
}

func (agent *agentS) applyHostAgentSettings(resp agentResponse) {
	agent.from = newHostAgentFromS(int(resp.Pid), resp.HostID)

	if resp.Secrets.Matcher != "" {
		m, err := NamedMatcher(resp.Secrets.Matcher, resp.Secrets.List)
		if err != nil {
			agent.logger.Warn("failed to apply secrets matcher configuration: ", err)
		} else {
			sensor.options.Tracer.Secrets = m
		}
	}

	sensor.options.Tracer.CollectableHTTPHeaders = resp.ExtraHTTPHeaders
}

func (agent *agentS) setHost(host string) {
	agent.host = host
}

func (agent *agentS) reset() {
	agent.fsm.reset()
}
<|endoftext|>


<commit_before>/*

agorn is a wrapper around gorename for use with Acme.
It renames the entity under the cursor.

Usage:
	agorn [name]

Example:
	'agorn Foo' renames the entity under the cursor with 'Foo'.

gorename must be installed:
	% go get golang.org/x/tools/cmd/gorename
*/
package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"code.google.com/p/goplan9/plan9/acme"
)

type window struct {
	win    *acme.Win
	offset int
	name   string
}

func currentAcmeWin() (*acme.Win, error) {
	winid := os.Getenv("winid")
	if winid == "" {
		return nil, fmt.Errorf("$winid not set - not running inside acme?")
	}
	id, err := strconv.Atoi(winid)
	if err != nil {
		return nil, fmt.Errorf("invalid $winid %q", winid)
	}
	win, err := acme.Open(id, nil)
	if err != nil {
		return nil, fmt.Errorf("cannot open acme window: %v", err)
	}
	return win, nil
}

func currentWindow() (*window, error) {
	win, err := currentAcmeWin()
	if err != nil {
		return nil, err
	}
	_, _, err = win.ReadAddr()
	if err != nil {
		return nil, fmt.Errorf("cannot read address: %v", err)
	}
	err = win.Ctl("addr=dot")
	if err != nil {
		return nil, fmt.Errorf("cannot set addr=dot: %v", err)
	}
	q0, _, err := win.ReadAddr()
	if err != nil {
		return nil, fmt.Errorf("cannot read address: %v", err)
	}
	b, err := win.ReadAll("tag")
	if err != nil {
		return nil, fmt.Errorf("cannot read tag: %v", err)
	}
	tag := string(b)
	i := strings.Index(tag, " ")
	if i == -1 {
		return nil, fmt.Errorf("tag with no spaces")
	}
	body, err := readBody(win)
	if err != nil {
		return nil, fmt.Errorf("cannot read body: %v", err)
	}
	return &window{win: win, name: tag[0:i], offset: toByteOffset(body, q0)}, nil
}

// We would use win.ReadAll except for a bug in acme
// where it crashes when reading trying to read more
// than the negotiated 9P message size.
func readBody(win *acme.Win) ([]byte, error) {
	var body []byte
	buf := make([]byte, 8000)
	for {
		n, err := win.Read("body", buf)
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, err
		}
		body = append(body, buf[0:n]...)
	}
	return body, nil
}

func toByteOffset(b []byte, off int) int {
	r := 0
	for i := range string(b) {
		if r == off {
			return i
		}
		r++
	}
	return len(b)
}

func (w *window) showAddr(addr string) {
	w.win.Fprintf("addr", addr)
	w.win.Ctl("dot=addr")
	w.win.Ctl("show")
}

func fail(err error) {
	fmt.Fprintf(os.Stderr, "agorn: %v", err)
	os.Exit(1)
}

func main() {
	if len(os.Args) < 2 {
		fail(fmt.Errorf("usage: agorn [name]\n"))
	}
	to := os.Args[1]

	win, err := currentWindow()
	if err != nil {
		fail(err)
	}

	c := exec.Command("gorename", "-offset", fmt.Sprintf("%s:#%d", win.name, win.offset), "-to", to)
	b := new(bytes.Buffer)
	c.Stderr = b
	err = c.Run()
	if err != nil {
		fail(fmt.Errorf(b.String()))
	}

	win.win.Ctl("get")
	win.showAddr(fmt.Sprintf("#%d", win.offset))
}
<commit_msg>Fix usage: make clear that the name is not optional.<commit_after>/*

agorn is a wrapper around gorename for use with Acme.
It renames the entity under the cursor.

Usage:
	agorn name

Example:
	'agorn Foo' renames the entity under the cursor with 'Foo'.

gorename must be installed:
	% go get golang.org/x/tools/cmd/gorename
*/
package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"code.google.com/p/goplan9/plan9/acme"
)

type window struct {
	win    *acme.Win
	offset int
	name   string
}

func currentAcmeWin() (*acme.Win, error) {
	winid := os.Getenv("winid")
	if winid == "" {
		return nil, fmt.Errorf("$winid not set - not running inside acme?")
	}
	id, err := strconv.Atoi(winid)
	if err != nil {
		return nil, fmt.Errorf("invalid $winid %q", winid)
	}
	win, err := acme.Open(id, nil)
	if err != nil {
		return nil, fmt.Errorf("cannot open acme window: %v", err)
	}
	return win, nil
}

func currentWindow() (*window, error) {
	win, err := currentAcmeWin()
	if err != nil {
		return nil, err
	}
	_, _, err = win.ReadAddr()
	if err != nil {
		return nil, fmt.Errorf("cannot read address: %v", err)
	}
	err = win.Ctl("addr=dot")
	if err != nil {
		return nil, fmt.Errorf("cannot set addr=dot: %v", err)
	}
	q0, _, err := win.ReadAddr()
	if err != nil {
		return nil, fmt.Errorf("cannot read address: %v", err)
	}
	b, err := win.ReadAll("tag")
	if err != nil {
		return nil, fmt.Errorf("cannot read tag: %v", err)
	}
	tag := string(b)
	i := strings.Index(tag, " ")
	if i == -1 {
		return nil, fmt.Errorf("tag with no spaces")
	}
	body, err := readBody(win)
	if err != nil {
		return nil, fmt.Errorf("cannot read body: %v", err)
	}
	return &window{win: win, name: tag[0:i], offset: toByteOffset(body, q0)}, nil
}

// We would use win.ReadAll except for a bug in acme
// where it crashes when reading trying to read more
// than the negotiated 9P message size.
func readBody(win *acme.Win) ([]byte, error) {
	var body []byte
	buf := make([]byte, 8000)
	for {
		n, err := win.Read("body", buf)
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, err
		}
		body = append(body, buf[0:n]...)
	}
	return body, nil
}

func toByteOffset(b []byte, off int) int {
	r := 0
	for i := range string(b) {
		if r == off {
			return i
		}
		r++
	}
	return len(b)
}

func (w *window) showAddr(addr string) {
	w.win.Fprintf("addr", addr)
	w.win.Ctl("dot=addr")
	w.win.Ctl("show")
}

func fail(err error) {
	fmt.Fprintf(os.Stderr, "agorn: %v", err)
	os.Exit(1)
}

func main() {
	if len(os.Args) < 2 {
		fail(fmt.Errorf("usage: agorn name\n"))
	}
	to := os.Args[1]

	win, err := currentWindow()
	if err != nil {
		fail(err)
	}

	c := exec.Command("gorename", "-offset", fmt.Sprintf("%s:#%d", win.name, win.offset), "-to", to)
	b := new(bytes.Buffer)
	c.Stderr = b
	err = c.Run()
	if err != nil {
		fail(fmt.Errorf(b.String()))
	}

	win.win.Ctl("get")
	win.showAddr(fmt.Sprintf("#%d", win.offset))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"

	"github.com/gpahal/shlex"
)

var goPath = ""
var execCmd = ""
var envPath = ".gobu"
var globalVersion = "1.7"
var onlinePath = "https://storage.googleapis.com/golang/go%s.%s-%s.%s"

func userHomeDir() string {
	if runtime.GOOS == "windows" {
		home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
		if home == "" {
			home = os.Getenv("USERPROFILE")
		}
		return home
	}
	return os.Getenv("HOME")
}

func init() {
	p, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	goPath = p
	envPath = filepath.Join(userHomeDir(), envPath)

	flag.StringVar(&envPath, "env_path", envPath, "Location of GO instalation")
	flag.StringVar(&globalVersion, "version", globalVersion, "Version of Golang you wish to use")
	flag.StringVar(&goPath, "GOPATH", goPath, "Overide GOPATH")
	flag.StringVar(&execCmd, "exec", "", "Run command instead of default shell")
}

func createStore(version string) {
	os.MkdirAll(filepath.Join(envPath, version), 0755)
	os.MkdirAll(filepath.Join(envPath, version, "local"), 0755)
}

func runShell(version string) {
	if os.Getenv("GOBU") != "" {
		log.Fatalln("Already in boostraped env!")
	}
	os.Setenv("GOBU", "1")

	log.Println(">> You are now in a new GOBU shell. To exit, type 'exit'")
	defaultShell := resolveBinary(os.Getenv("SHELL"))

	run(version, defaultShell, []string{defaultShell})
	log.Println("Exited gobu shell")
}

func resolveBinary(bin string) string {
	if !filepath.IsAbs(bin) {
		rbin, err := exec.LookPath(bin)
		if err != nil {
			log.Panic(err)
		}
		return rbin
	}
	return bin
}

func run(version, cmd string, cmdArgs []string) *os.ProcessState {

	path := os.Getenv("PATH")
	cwd, err := os.Getwd()
	if err != nil {
		log.Panic(err)
	}
	goroot := filepath.Join(envPath, version, "go")

	os.Setenv("GO15VENDOREXPERIMENT", "1")
	os.Setenv("GOPATH", goPath)
	log.Println("GOPATH", goPath)
	os.Setenv("GOROOT", goroot)
	log.Println("GOROOT", goroot)
	// Sometimes we want to use tools from local install
	os.Setenv("PATH", goPath+"/bin:"+goroot+"/bin:"+path)

	pa := os.ProcAttr{
		Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
		Dir:   cwd,
	}

	proc, err := os.StartProcess(cmd, cmdArgs, &pa)
	if err != nil {
		log.Panic(err)
	}

	state, err := proc.Wait()
	if err != nil {
		log.Panic(err)
	}
	return state
}

func main() {
	flag.Parse()
	arch := runtime.GOARCH
	// Fix for special case of arm version naming
	if arch == "arm" {
		arch = "armv6l"
	}

	extension := "tar.gz"

	if runtime.GOOS == "windows" {
		extension = "zip"
	}

	onlinePath = fmt.Sprintf(onlinePath, globalVersion, runtime.GOOS, arch, extension)

	createStore(globalVersion)
	download(globalVersion)
	if execCmd != "" {
		execCmdParsed, err := shlex.Split(execCmd)
		if err != nil {
			log.Panic(err)
		}
		bin := resolveBinary(execCmdParsed[0])
		run(globalVersion, bin, execCmdParsed[:1])
	} else {
		runShell(globalVersion)
	}

}
<commit_msg>cmd.exe for windows<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"

	"github.com/gpahal/shlex"
)

var goPath = ""
var execCmd = ""
var envPath = ".gobu"
var globalVersion = "1.7"
var onlinePath = "https://storage.googleapis.com/golang/go%s.%s-%s.%s"

func userHomeDir() string {
	if runtime.GOOS == "windows" {
		home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
		if home == "" {
			home = os.Getenv("USERPROFILE")
		}
		return home
	}
	return os.Getenv("HOME")
}

func init() {
	p, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}
	goPath = p
	envPath = filepath.Join(userHomeDir(), envPath)

	flag.StringVar(&envPath, "env_path", envPath, "Location of GO instalation")
	flag.StringVar(&globalVersion, "version", globalVersion, "Version of Golang you wish to use")
	flag.StringVar(&goPath, "GOPATH", goPath, "Overide GOPATH")
	flag.StringVar(&execCmd, "exec", "", "Run command instead of default shell")
}

func createStore(version string) {
	os.MkdirAll(filepath.Join(envPath, version), 0755)
	os.MkdirAll(filepath.Join(envPath, version, "local"), 0755)
}

func runShell(version string) {
	if os.Getenv("GOBU") != "" {
		log.Fatalln("Already in boostraped env!")
	}
	os.Setenv("GOBU", "1")

	log.Println(">> You are now in a new GOBU shell. To exit, type 'exit'")
	defaultShell := resolveBinary(os.Getenv("SHELL"))

	if runtime.GOOS == "windows" {

		defaultShell = "cmd.exe" // TODO find parent process name
	}

	run(version, defaultShell, []string{defaultShell})
	log.Println("Exited gobu shell")
}

func resolveBinary(bin string) string {
	if !filepath.IsAbs(bin) {
		rbin, err := exec.LookPath(bin)
		if err != nil {
			log.Panic(err)
		}
		return rbin
	}
	return bin
}

func run(version, cmd string, cmdArgs []string) *os.ProcessState {

	path := os.Getenv("PATH")
	cwd, err := os.Getwd()
	if err != nil {
		log.Panic(err)
	}
	goroot := filepath.Join(envPath, version, "go")

	os.Setenv("GO15VENDOREXPERIMENT", "1")
	os.Setenv("GOPATH", goPath)
	log.Println("GOPATH", goPath)
	os.Setenv("GOROOT", goroot)
	log.Println("GOROOT", goroot)
	// Sometimes we want to use tools from local install
	os.Setenv("PATH", goPath+"/bin:"+goroot+"/bin:"+path)

	pa := os.ProcAttr{
		Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
		Dir:   cwd,
	}

	proc, err := os.StartProcess(cmd, cmdArgs, &pa)
	if err != nil {
		log.Panic(err)
	}

	state, err := proc.Wait()
	if err != nil {
		log.Panic(err)
	}
	return state
}

func main() {
	flag.Parse()
	arch := runtime.GOARCH
	// Fix for special case of arm version naming
	if arch == "arm" {
		arch = "armv6l"
	}

	extension := "tar.gz"

	if runtime.GOOS == "windows" {
		extension = "zip"
	}

	onlinePath = fmt.Sprintf(onlinePath, globalVersion, runtime.GOOS, arch, extension)

	createStore(globalVersion)
	download(globalVersion)
	if execCmd != "" {
		execCmdParsed, err := shlex.Split(execCmd)
		if err != nil {
			log.Panic(err)
		}
		bin := resolveBinary(execCmdParsed[0])
		run(globalVersion, bin, execCmdParsed[:1])
	} else {
		runShell(globalVersion)
	}

}
<|endoftext|>


<commit_before>/* NOTES: Needs to be optimized. Shouldn't be constantly moving around arrays.
 *        should instead be swapping pointers to those lists. That will be
 *        in next version.
 */

package gocluster

import (
	"errors"
	"math"
	"math/rand"
	"time"
)

type Cluster struct {
	Distance func(p1, p2 []float64) (float64, error)
}

// Function to randomly initialize clusters from input dataset.
// After initializing k clusters, runs Lloyd's Algorithm to find clusters
func (c Cluster) Km(entities [][]float64, k, maxIters int) ([][]float64, [][][]float64, error) {
	// create new random generator to avoid using the shared global object's Mutex lock
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	numEntities := len(entities)

	// verify that all points have same dimensions
	if c.sameDimensionality(entities) == false {
		return nil, nil, errors.New("Dimensions must all be of same size")
	}

	// initialize entities
	centers := make([][]float64, k)
	for i := 0; i < k; i++ {
		centers[i] = entities[r.Intn(numEntities)]
	}
	return c.lloydsAlgo(entities, centers, maxIters)
}

func (c Cluster) Kmpp(entities [][]float64, k, maxIters int) ([][]float64, [][][]float64, error) {
	// create new random generator to avoid using the shared global object's Mutex lock
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	numEntities := len(entities)

	// verify that all points have same dimensions
	if c.sameDimensionality(entities) == false {
		return nil, nil, errors.New("Dimensions must all be of same size")
	}

	centers := make([][]float64, k)
	d2 := make([]float64, numEntities) // distance squared
	centers[0] = entities[r.Intn(numEntities)]

	// iterate through rest of k to initialize other centers
	for i := 1; i < k; i++ {
		sum := 0.0
		for j := range entities {
			_, minDist := c.nearest(entities[j], centers[:i])
			d2[j] = minDist * minDist
			sum += d2[j]
		}

		// use find random number less than sum then iterate through d2 until index is found
		target := r.Float64() * sum
		j := 0
		for sum = d2[0]; sum < target; sum += d2[j] {
			j++
		}
		centers[i] = entities[j]
	}
	return c.lloydsAlgo(entities, centers, maxIters)
}

// Lloye's Algorithm for calculating k-means clustering
// called from Km
func (c Cluster) lloydsAlgo(entities, centers [][]float64, maxIters int) ([][]float64, [][][]float64, error) {
	numEntities := len(entities)

	// setup cluster groups
	clusters := make([][][]float64, len(centers))
	prevVariance := math.MaxFloat64

	// setup clusters
	// initial capacity of 10 may be too small. It will require doubling which
	// isn't ideal but will help lower overall memory if cluster sizes are small
	for i := range centers {
		clusters[i] = make([][]float64, 0, 10)
	}

	for i := 0; i < maxIters; i++ {
		// reset slices to zero
		for i := range centers {
			clusters[i] = clusters[i][:0]
		}

		curVariance := 0. // current variance
		for j := 0; j < numEntities; j++ {
			// get best cluster for each point
			minPt, minDist := c.nearest(entities[j], centers)
			clusters[minPt] = append(clusters[minPt], entities[j])
			curVariance += minDist
		}

		if prevVariance == curVariance {
			return centers, clusters, nil
		}

		// compute new centers
		for j := range clusters {
			centers[j] = c.updateCenter(clusters[j])
		}
		prevVariance = curVariance

	}
	return centers, clusters, nil
}

// update the cluster center given the points in the cluster
func (c Cluster) updateCenter(pts [][]float64) []float64 {
	if len(pts) == 0 {
		return make([]float64, 0)
	}

	dimensions := len(pts[0])
	numPts := len(pts)
	center := make([]float64, dimensions)

	for i := range pts {
		for j, v := range pts[i] {
			center[j] += v
		}
	}

	for i := range center {
		center[i] /= float64(numPts)
	}

	return center
}

// fine nearest center to given point
func (c Cluster) nearest(val []float64, centers [][]float64) (int, float64) {
	minDist, minPt := math.MaxFloat64, 0
	for l := range centers {
		// error caused when a cluster currently has no nodes (is a slice of size 0)
		dist, err := c.Distance(val, centers[l])
		if err == nil {
			if dist < minDist {
				minDist, minPt = dist, l
			}
		}
	}
	return minPt, minDist
}

// verify that pts are all of same size
func (c Cluster) sameDimensionality(pts [][]float64) bool {
	sz := len(pts[0])
	for i := range pts {
		if sz != len(pts[i]) {
			return false
		}
	}
	return true
}
<commit_msg>Removed comment based on incorrect assumption. Identified that slices are pointers so they aren't getting copied.<commit_after>package gocluster

import (
	"errors"
	"math"
	"math/rand"
	"time"
)

type Cluster struct {
	Distance func(p1, p2 []float64) (float64, error)
}

// Function to randomly initialize clusters from input dataset.
// After initializing k clusters, runs Lloyd's Algorithm to find clusters
func (c Cluster) Km(entities [][]float64, k, maxIters int) ([][]float64, [][][]float64, error) {
	// create new random generator to avoid using the shared global object's Mutex lock
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	numEntities := len(entities)

	// verify that all points have same dimensions
	if c.sameDimensionality(entities) == false {
		return nil, nil, errors.New("Dimensions must all be of same size")
	}

	// initialize entities
	centers := make([][]float64, k)
	for i := 0; i < k; i++ {
		centers[i] = entities[r.Intn(numEntities)]
	}
	return c.lloydsAlgo(entities, centers, maxIters)
}

func (c Cluster) Kmpp(entities [][]float64, k, maxIters int) ([][]float64, [][][]float64, error) {
	// create new random generator to avoid using the shared global object's Mutex lock
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	numEntities := len(entities)

	// verify that all points have same dimensions
	if c.sameDimensionality(entities) == false {
		return nil, nil, errors.New("Dimensions must all be of same size")
	}

	centers := make([][]float64, k)
	d2 := make([]float64, numEntities) // distance squared
	centers[0] = entities[r.Intn(numEntities)]

	// iterate through rest of k to initialize other centers
	for i := 1; i < k; i++ {
		sum := 0.0
		for j := range entities {
			_, minDist := c.nearest(entities[j], centers[:i])
			d2[j] = minDist * minDist
			sum += d2[j]
		}

		// use find random number less than sum then iterate through d2 until index is found
		target := r.Float64() * sum
		j := 0
		for sum = d2[0]; sum < target; sum += d2[j] {
			j++
		}
		centers[i] = entities[j]
	}
	return c.lloydsAlgo(entities, centers, maxIters)
}

// Lloye's Algorithm for calculating k-means clustering
// called from Km
func (c Cluster) lloydsAlgo(entities, centers [][]float64, maxIters int) ([][]float64, [][][]float64, error) {
	numEntities := len(entities)

	// setup cluster groups
	clusters := make([][][]float64, len(centers))
	prevVariance := math.MaxFloat64

	// setup clusters
	// initial capacity of 10 may be too small. It will require doubling which
	// isn't ideal but will help lower overall memory if cluster sizes are small
	for i := range centers {
		clusters[i] = make([][]float64, 0, 10)
	}

	for i := 0; i < maxIters; i++ {
		// reset slices to zero
		for i := range centers {
			clusters[i] = clusters[i][:0]
		}

		curVariance := 0. // current variance
		for j := 0; j < numEntities; j++ {
			// get best cluster for each point
			minPt, minDist := c.nearest(entities[j], centers)
			clusters[minPt] = append(clusters[minPt], entities[j])
			curVariance += minDist
		}

		if prevVariance == curVariance {
			return centers, clusters, nil
		}

		// compute new centers
		for j := range clusters {
			centers[j] = c.updateCenter(clusters[j])
		}
		prevVariance = curVariance

	}
	return centers, clusters, nil
}

// update the cluster center given the points in the cluster
func (c Cluster) updateCenter(pts [][]float64) []float64 {
	if len(pts) == 0 {
		return make([]float64, 0)
	}

	dimensions := len(pts[0])
	numPts := len(pts)
	center := make([]float64, dimensions)

	for i := range pts {
		for j, v := range pts[i] {
			center[j] += v
		}
	}

	for i := range center {
		center[i] /= float64(numPts)
	}

	return center
}

// fine nearest center to given point
func (c Cluster) nearest(val []float64, centers [][]float64) (int, float64) {
	minDist, minPt := math.MaxFloat64, 0
	for l := range centers {
		// error caused when a cluster currently has no nodes (is a slice of size 0)
		dist, err := c.Distance(val, centers[l])
		if err == nil {
			if dist < minDist {
				minDist, minPt = dist, l
			}
		}
	}
	return minPt, minDist
}

// verify that pts are all of same size
func (c Cluster) sameDimensionality(pts [][]float64) bool {
	sz := len(pts[0])
	for i := range pts {
		if sz != len(pts[i]) {
			return false
		}
	}
	return true
}
<|endoftext|>


<commit_before>// Package bot implements an IRC bot with plugins.
package bot

import (
	"log"
	"strings"
	"time"

	"github.com/StalkR/goircbot/lib/tls"
	"github.com/fluffle/goirc/client"
	"github.com/fluffle/goirc/state"
)

// Bot represents an IRC bot, with IRC client object, settings, commands.
type Bot interface {
	Run()                       // Run bot, reconnect if disconnect.
	Quit(msg string)            // Quit bot from IRC with a msg.
	Commands() *Commands        // For plugins to Add/Del commands.
	Action(t, msg string)       // Shortcut to Conn().Action()
	Connected() bool            // Shortcut to Conn().Connected()
	Me() *state.Nick            // Shortcut to Conn().Me()
	Mode(t string, m ...string) // Shortcut to Conn().Mode()
	Notice(t, msg string)       // Shortcut to Conn().Notice()
	Privmsg(t, msg string)      // Shortcut to Conn().Privmsg()
	Conn() *client.Conn         // Conn returns the underlying goirc client connection.
}

// NewBot creates a new Bot implementation with a set of parameters.
func NewBot(host string, ssl bool, nick, ident string, channels []string) *BotImpl {
	hostPort := strings.SplitN(host, ":", 2)
	cfg := &client.Config{
		Me:          state.NewNick(nick),
		NewNick:     func(s string) string { return s + "_" },
		PingFreq:    3 * time.Minute,
		QuitMessage: "I have to go.",
		Server:      host,
		SSL:         ssl,
		SSLConfig:   tls.Config(hostPort[0]),
		Version:     "Powered by GoIRCBot",
		Recover:     (*client.Conn).LogPanic,
		SplitLen:    450,
	}
	cfg.Me.Ident = ident
	cfg.Me.Name = nick

	conn := client.Client(cfg)
	conn.EnableStateTracking()
	b := &BotImpl{
		conn:      conn,
		reconnect: true,
		quit:      make(chan bool),
		commands:  NewCommands(),
	}

	// Join channels on connect and mark ourselves as a Bot.
	conn.HandleFunc("connected",
		func(conn *client.Conn, line *client.Line) {
			for _, channel := range channels {
				conn.Join(channel)
			}
			conn.Mode(conn.Me().Nick, "+B")
		})

	// Signal disconnect to Bot.Run so it can reconnect.
	conn.HandleFunc("disconnected",
		func(conn *client.Conn, line *client.Line) { b.quit <- true })

	conn.HandleFunc("privmsg",
		func(conn *client.Conn, line *client.Line) { b.commands.Handle(b, line) })

	b.commands.Add("help", Command{
		Help:    "show commands or detailed help",
		Handler: (b.commands).Help,
		Pub:     true,
		Priv:    true,
		Hidden:  false})

	return b
}

// BotImpl implements Bot.
type BotImpl struct {
	conn      *client.Conn
	reconnect bool
	quit      chan bool
	commands  *Commands
}

// Run starts the Bot by connecting it to IRC. It automatically reconnects.
func (b *BotImpl) Run() {
	for b.reconnect {
		if err := b.Conn().Connect(); err != nil {
			log.Println("Connection error:", err, "- reconnecting in 1 minute")
			time.Sleep(time.Minute)
			continue
		}

		// Wait on quit channel for a disconnect event.
		<-b.quit
	}
}

// Quit quits the bot from IRC (and no reconnect).
func (b *BotImpl) Quit(msg string) {
	b.reconnect = false
	b.conn.Quit(msg)
}

// Commands returns the underlying Commands.
func (b *BotImpl) Commands() *Commands { return b.commands }

// Shortcuts to b.Conn to ease mocking of Bot interface.
func (b *BotImpl) Action(t, msg string)       { b.Conn().Action(t, msg) }
func (b *BotImpl) Connected() bool            { return b.Conn().Connected() }
func (b *BotImpl) Me() *state.Nick            { return b.Conn().Me() }
func (b *BotImpl) Mode(t string, m ...string) { b.Conn().Mode(t, m...) }
func (b *BotImpl) Notice(t, msg string)       { b.Conn().Notice(t, msg) }
func (b *BotImpl) Privmsg(t, msg string)      { b.Conn().Privmsg(t, msg) }
func (b *BotImpl) Conn() *client.Conn         { return b.conn }
<commit_msg>try to fix issue with Go 1 on travis<commit_after>// Package bot implements an IRC bot with plugins.
package bot

import (
	"log"
	"strings"
	"time"

	"github.com/StalkR/goircbot/lib/tls"
	"github.com/fluffle/goirc/client"
	"github.com/fluffle/goirc/state"
)

// Bot represents an IRC bot, with IRC client object, settings, commands.
type Bot interface {
	Run()                       // Run bot, reconnect if disconnect.
	Quit(msg string)            // Quit bot from IRC with a msg.
	Commands() *Commands        // For plugins to Add/Del commands.
	Action(t, msg string)       // Shortcut to Conn().Action()
	Connected() bool            // Shortcut to Conn().Connected()
	Me() *state.Nick            // Shortcut to Conn().Me()
	Mode(t string, m ...string) // Shortcut to Conn().Mode()
	Notice(t, msg string)       // Shortcut to Conn().Notice()
	Privmsg(t, msg string)      // Shortcut to Conn().Privmsg()
	Conn() *client.Conn         // Conn returns the underlying goirc client connection.
}

// NewBot creates a new Bot implementation with a set of parameters.
func NewBot(host string, ssl bool, nick, ident string, channels []string) *BotImpl {
	hostPort := strings.SplitN(host, ":", 2)
	cfg := &client.Config{
		Me:          state.NewNick(nick),
		NewNick:     func(s string) string { return s + "_" },
		PingFreq:    3 * time.Minute,
		QuitMessage: "I have to go.",
		Server:      host,
		SSL:         ssl,
		SSLConfig:   tls.Config(hostPort[0]),
		Version:     "Powered by GoIRCBot",
		Recover:     (*client.Conn).LogPanic,
		SplitLen:    450,
	}
	cfg.Me.Ident = ident
	cfg.Me.Name = nick

	conn := client.Client(cfg)
	conn.EnableStateTracking()
	b := &BotImpl{
		conn:      conn,
		reconnect: true,
		quit:      make(chan bool),
		commands:  NewCommands(),
	}

	// Join channels on connect and mark ourselves as a Bot.
	conn.HandleFunc("connected",
		func(conn *client.Conn, line *client.Line) {
			for _, channel := range channels {
				conn.Join(channel)
			}
			conn.Mode(conn.Me().Nick, "+B")
		})

	// Signal disconnect to Bot.Run so it can reconnect.
	conn.HandleFunc("disconnected",
		func(conn *client.Conn, line *client.Line) { b.quit <- true })

	conn.HandleFunc("privmsg",
		func(conn *client.Conn, line *client.Line) { b.commands.Handle(b, line) })

	b.commands.Add("help", Command{
		Help:    "show commands or detailed help",
		Handler: func(e *Event) { b.commands.Help(e) },
		Pub:     true,
		Priv:    true,
		Hidden:  false})

	return b
}

// BotImpl implements Bot.
type BotImpl struct {
	conn      *client.Conn
	reconnect bool
	quit      chan bool
	commands  *Commands
}

// Run starts the Bot by connecting it to IRC. It automatically reconnects.
func (b *BotImpl) Run() {
	for b.reconnect {
		if err := b.Conn().Connect(); err != nil {
			log.Println("Connection error:", err, "- reconnecting in 1 minute")
			time.Sleep(time.Minute)
			continue
		}

		// Wait on quit channel for a disconnect event.
		<-b.quit
	}
}

// Quit quits the bot from IRC (and no reconnect).
func (b *BotImpl) Quit(msg string) {
	b.reconnect = false
	b.conn.Quit(msg)
}

// Commands returns the underlying Commands.
func (b *BotImpl) Commands() *Commands { return b.commands }

// Shortcuts to b.Conn to ease mocking of Bot interface.
func (b *BotImpl) Action(t, msg string)       { b.Conn().Action(t, msg) }
func (b *BotImpl) Connected() bool            { return b.Conn().Connected() }
func (b *BotImpl) Me() *state.Nick            { return b.Conn().Me() }
func (b *BotImpl) Mode(t string, m ...string) { b.Conn().Mode(t, m...) }
func (b *BotImpl) Notice(t, msg string)       { b.Conn().Notice(t, msg) }
func (b *BotImpl) Privmsg(t, msg string)      { b.Conn().Privmsg(t, msg) }
func (b *BotImpl) Conn() *client.Conn         { return b.conn }
<|endoftext|>