<commit_before>package gotumblr_test

import (
	"fmt"
	"github.com/MariaTerzieva/gotumblr"
)

func ExampleInfo() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	info := client.Info()
	fmt.Println(info["response"].(map[string]interface{})["blog"].(map[string]interface{})["name"])
	//Output:
	//the name of the user's blog here(e.g. blogname in blogname.tumblr.com)
}

func ExampleLikes() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	likes := client.Likes(map[string]string{})
	fmt.Println(likes["response"].(map[string]interface{})["liked_count"])
	//Output:
	//the count of the posts the user has liked here
}

func ExampleFollowing() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	following := client.Following(map[string]string{})
	fmt.Println(following["response"].(map[string]interface{})["total_blogs"])
	//Output:
	//the number of the blogs the user is following here
}

func ExampleDashboard() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	dashboard := client.Dashboard(map[string]string{"limit": "1"})
	fmt.Println(dashboard["response"].(map[string]interface{})["blog"].(map[string]interface{})["state"])
	//Output:
	//published
}

func ExampleTagged() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	tagged := client.Tagged("golang", map[string]string{"limit": "1"})
	fmt.Println(tagged["response"].(map[string]interface{})["blog"].(map[string]interface{})["state"])
	//Output:
	//published
}

func ExamplePosts() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	posts := client.Posts(blogname, "text", map[string]string{"limit": "1"})
	fmt.Println(posts["response"].(map[string]interface{})["blog"].(map[string]interface{})["total_posts"])
	//Output:
	//the number of all blog posts here; don't forget to change blogname according to your credentials!
}

func ExampleBlogInfo() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	blogInfo := client.BlogInfo(blogname)
	fmt.Println(blogInfo["response"].(map[string]interface{})["blog"].(map[string]interface{})["title"])
	//Output:
	//the title of the blog here; don't forget to change blogname according to your credentials!
}

func ExampleFollowers() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	followers := client.Followers(blogname, map[string]string{})
	fmt.Println(followers["response"].(map[string]interface{})["total_users"])
	//Output:
	//the number of all followers of the blog; don't forget to change blogname according to your credentials!
}

func ExampleBlogLikes() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	likes := client.BlogLikes(blogname, map[string]string{})
	fmt.Println(likes["response"].(map[string]interface{})["liked_count"])
	//Output:
	//the number of all blog likes here; don't forget to change blogname according to your credentials!
}

func ExampleQueue() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	queue := client.Queue(blogname, map[string]string{})
	fmt.Println(queue["response"].(map[string]interface{})["posts"])
	//Output:
	//an interface of all posts in the queue;  don't forget to change blogname according to your credentials!
}

func ExampleDrafts() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	drafts := client.Drafts(blogname, map[string]string{})
	fmt.Println(drafts["response"].(map[string]interface{})["posts"])
	//Output:
	//an interface of all posts in the drafts section;  don't forget to change blogname according to your credentials!
}

func ExampleSubmission() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	submission := client.Submission(blogname, map[string]string{})
	fmt.Println(submission["response"].(map[string]interface{})["posts"])
	//Output:
	//an interface of all posts in the submissions section;  don't forget to change blogname according to your credentials!
}

func ExampleAvatar() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	avatar := client.Avatar(blogname, 64)
	fmt.Println(avatar["meta"].(map[string]interface{})["status"])
	//Output:
	//301
}

func ExampleFollow() {
	blogname := "mgterzieva.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	follow := client.Follow(blogname)
	fmt.Println(follow["meta"].(map[string]interface{})["status"])
	//Output:
	//200
}

func ExampleUnfollow() {
	blogname := "mgterzieva.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	unfollow := client.Unfollow(blogname)
	fmt.Println(unfollow["meta"].(map[string]interface{})["status"])
	//Output:
	//200
}

func ExampleLike() {
	id := 72078164824
	reblogKey := "6l3e2pGL"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	like := client.Like(id, reblogKey)
	fmt.Println(like["meta"].(map[string]interface{})["status"])api tumblr
	//Output:
	//200
}

func ExampleUnlike() {
	id := 72078164824
	reblogKey := "6l3e2pGL"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	unlike := client.Unlike(id, reblogKey)
	fmt.Println(unlike["meta"].(map[string]interface{})["status"])
	//Output:
	//200
}

func ExampleReblog() {
	blogname := "example.tumblr.com"
	id := "72078164824"
	reblogKey := "6l3e2pGL"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	reblog := client.Reblog(blogname, map[string]string{"id": id, "reblog_key": reblogKey})
	fmt.Println(reblog["meta"].(map[string]interface{})["status"])
	//Output:
	//201
}
<commit_msg>Fix typo<commit_after>package gotumblr_test

import (
	"fmt"
	"github.com/MariaTerzieva/gotumblr"
)

func ExampleInfo() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	info := client.Info()
	fmt.Println(info["response"].(map[string]interface{})["blog"].(map[string]interface{})["name"])
	//Output:
	//the name of the user's blog here(e.g. blogname in blogname.tumblr.com)
}

func ExampleLikes() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	likes := client.Likes(map[string]string{})
	fmt.Println(likes["response"].(map[string]interface{})["liked_count"])
	//Output:
	//the count of the posts the user has liked here
}

func ExampleFollowing() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	following := client.Following(map[string]string{})
	fmt.Println(following["response"].(map[string]interface{})["total_blogs"])
	//Output:
	//the number of the blogs the user is following here
}

func ExampleDashboard() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	dashboard := client.Dashboard(map[string]string{"limit": "1"})
	fmt.Println(dashboard["response"].(map[string]interface{})["blog"].(map[string]interface{})["state"])
	//Output:
	//published
}

func ExampleTagged() {
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	tagged := client.Tagged("golang", map[string]string{"limit": "1"})
	fmt.Println(tagged["response"].(map[string]interface{})["blog"].(map[string]interface{})["state"])
	//Output:
	//published
}

func ExamplePosts() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	posts := client.Posts(blogname, "text", map[string]string{"limit": "1"})
	fmt.Println(posts["response"].(map[string]interface{})["blog"].(map[string]interface{})["total_posts"])
	//Output:
	//the number of all blog posts here; don't forget to change blogname according to your credentials!
}

func ExampleBlogInfo() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	blogInfo := client.BlogInfo(blogname)
	fmt.Println(blogInfo["response"].(map[string]interface{})["blog"].(map[string]interface{})["title"])
	//Output:
	//the title of the blog here; don't forget to change blogname according to your credentials!
}

func ExampleFollowers() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	followers := client.Followers(blogname, map[string]string{})
	fmt.Println(followers["response"].(map[string]interface{})["total_users"])
	//Output:
	//the number of all followers of the blog; don't forget to change blogname according to your credentials!
}

func ExampleBlogLikes() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	likes := client.BlogLikes(blogname, map[string]string{})
	fmt.Println(likes["response"].(map[string]interface{})["liked_count"])
	//Output:
	//the number of all blog likes here; don't forget to change blogname according to your credentials!
}

func ExampleQueue() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	queue := client.Queue(blogname, map[string]string{})
	fmt.Println(queue["response"].(map[string]interface{})["posts"])
	//Output:
	//an interface of all posts in the queue;  don't forget to change blogname according to your credentials!
}

func ExampleDrafts() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	drafts := client.Drafts(blogname, map[string]string{})
	fmt.Println(drafts["response"].(map[string]interface{})["posts"])
	//Output:
	//an interface of all posts in the drafts section;  don't forget to change blogname according to your credentials!
}

func ExampleSubmission() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	submission := client.Submission(blogname, map[string]string{})
	fmt.Println(submission["response"].(map[string]interface{})["posts"])
	//Output:
	//an interface of all posts in the submissions section;  don't forget to change blogname according to your credentials!
}

func ExampleAvatar() {
	blogname := "example.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	avatar := client.Avatar(blogname, 64)
	fmt.Println(avatar["meta"].(map[string]interface{})["status"])
	//Output:
	//301
}

func ExampleFollow() {
	blogname := "mgterzieva.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	follow := client.Follow(blogname)
	fmt.Println(follow["meta"].(map[string]interface{})["status"])
	//Output:
	//200
}

func ExampleUnfollow() {
	blogname := "mgterzieva.tumblr.com"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	unfollow := client.Unfollow(blogname)
	fmt.Println(unfollow["meta"].(map[string]interface{})["status"])
	//Output:
	//200
}

func ExampleLike() {
	id := 72078164824
	reblogKey := "6l3e2pGL"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	like := client.Like(id, reblogKey)
	fmt.Println(like["meta"].(map[string]interface{})["status"])
	//Output:
	//200
}

func ExampleUnlike() {
	id := 72078164824
	reblogKey := "6l3e2pGL"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	unlike := client.Unlike(id, reblogKey)
	fmt.Println(unlike["meta"].(map[string]interface{})["status"])
	//Output:
	//200
}

func ExampleReblog() {
	blogname := "example.tumblr.com"
	id := "72078164824"
	reblogKey := "6l3e2pGL"
	client := gotumblr.NewtumblrRestClient("consumer_key", "consumer_secret", "token", "token_secret", "callbackurl", "http://api.tumblr.com")
	reblog := client.Reblog(blogname, map[string]string{"id": id, "reblog_key": reblogKey})
	fmt.Println(reblog["meta"].(map[string]interface{})["status"])
	//Output:
	//201
}
<|endoftext|>


<commit_before>package mastodon_test

import (
	"context"
	"fmt"
	"log"

	"github.com/mattn/go-mastodon"
)

func ExampleApplication_RegisterApp() {
	app, err := mastodon.RegisterApp(context.Background(), &mastodon.AppConfig{
		Server:     "https://mstdn.jp",
		ClientName: "client-name",
		Scopes:     "read write follow",
		Website:    "https://github.com/mattn/go-mastodon",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("client-id    : %s\n", app.ClientID)
	fmt.Printf("client-secret: %s\n", app.ClientSecret)
}

func ExampleClient() {
	c := mastodon.NewClient(&mastodon.Config{
		Server:       "https://mstdn.jp",
		ClientID:     "client-id",
		ClientSecret: "client-secret",
	})
	err := c.Authenticate(context.Background(), "your-email", "your-password")
	if err != nil {
		log.Fatal(err)
	}
	timeline, err := c.GetTimelineHome(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	for i := len(timeline) - 1; i >= 0; i-- {
		fmt.Println(timeline[i])
	}
}
<commit_msg>Fix example<commit_after>package mastodon_test

import (
	"context"
	"fmt"
	"log"

	"github.com/mattn/go-mastodon"
)

func ExampleRegisterApp() {
	app, err := mastodon.RegisterApp(context.Background(), &mastodon.AppConfig{
		Server:     "https://mstdn.jp",
		ClientName: "client-name",
		Scopes:     "read write follow",
		Website:    "https://github.com/mattn/go-mastodon",
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("client-id    : %s\n", app.ClientID)
	fmt.Printf("client-secret: %s\n", app.ClientSecret)
}

func ExampleClient() {
	c := mastodon.NewClient(&mastodon.Config{
		Server:       "https://mstdn.jp",
		ClientID:     "client-id",
		ClientSecret: "client-secret",
	})
	err := c.Authenticate(context.Background(), "your-email", "your-password")
	if err != nil {
		log.Fatal(err)
	}
	timeline, err := c.GetTimelineHome(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	for i := len(timeline) - 1; i >= 0; i-- {
		fmt.Println(timeline[i])
	}
}
<|endoftext|>


<commit_before>package dns_test

import (
	"errors"
	"fmt"
	"github.com/miekg/dns"
	"log"
	"net"
)

// Retrieve the MX records for miek.nl.
func ExampleMX() {
	config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	c := new(dns.Client)
	m := new(dns.Msg)
	m.SetQuestion("miek.nl.", dns.TypeMX)
	m.RecursionDesired = true
	r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
	if err != nil {
		return
	}
	if r.Rcode != dns.RcodeSuccess {
		return
	}
	for _, a := range r.Answer {
		if mx, ok := a.(*dns.MX); ok {
			fmt.Printf("%s\n", mx.String())
		}
	}
}

// Retrieve the DNSKEY records of a zone and convert them
// to DS records for SHA1, SHA256 and SHA384.
func ExampleDS(zone string) {
	config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	c := new(dns.Client)
	m := new(dns.Msg)
	if zone == "" {
		zone = "miek.nl"
	}
	m.SetQuestion(dns.Fqdn(zone), dns.TypeDNSKEY)
	m.SetEdns0(4096, true)
	r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
	if err != nil {
		return
	}
	if r.Rcode != dns.RcodeSuccess {
		return
	}
	for _, k := range r.Answer {
		if key, ok := k.(*dns.DNSKEY); ok {
			for _, alg := range []int{dns.SHA1, dns.SHA256, dns.SHA384} {
				fmt.Printf("%s; %d\n", key.ToDS(alg).String(), key.Flags)
			}
		}
	}
}

const TypeAPAIR = 0x0F99

type APAIR struct {
	addr [2]net.IP
}

func NewAPAIR() dns.PrivateRdata { return new(APAIR) }

func (rd *APAIR) String() string { return rd.addr[0].String() + " " + rd.addr[1].String() }
func (rd *APAIR) ParseTextSlice(txt []string) error {
	if len(txt) != 2 {
		return errors.New("Two addresses required for APAIR")
	}
	for i, s := range txt {
		ip := net.ParseIP(s)
		if ip == nil {
			return errors.New("Invalid IP in APAIR text representation")
		}
		rd.addr[i] = ip
	}
	return nil
}

func (rd *APAIR) Pack(buf []byte) (int, error) {
	b := append([]byte(rd.addr[0]), []byte(rd.addr[1])...)
	n := copy(buf, b)
	if n != len(b) {
		return n, dns.ErrBuf
	}
	return n, nil
}

func (rd *APAIR) Unpack(buf []byte) (int, error) {
	ln := net.IPv4len * 2
	if len(buf) != ln {
		return 0, errors.New("Invalid length of APAIR rdata")
	}
	cp := make([]byte, ln)
	copy(cp, buf) // clone bytes to use them in IPs

	rd.addr[0] = net.IP(cp[:3])
	rd.addr[1] = net.IP(cp[4:])

	return len(buf), nil
}

func (rd *APAIR) CopyRdata(dest dns.PrivateRdata) error {
	cp := make([]byte, rd.RdataLen())
	_, err := rd.Pack(cp)
	if err != nil {
		return err
	}

	d := dest.(*APAIR)
	d.addr[0] = net.IP(cp[:3])
	d.addr[1] = net.IP(cp[4:])
	return nil
}

func (rd *APAIR) RdataLen() int {
	return net.IPv4len * 2
}

func ExampleNewPrivateRR() {
	dns.PrivateHandle("APAIR", TypeAPAIR, NewAPAIR)
	defer dns.PrivateHandleRemove(TypeAPAIR)

	rr, err := dns.NewRR("miek.nl. APAIR (1.2.3.4    1.2.3.5)")
	if err != nil {
		log.Fatal("Could not parse APAIR record: ", err)
	}
	fmt.Println(rr)
	// Output: miek.nl.	3600	IN	APAIR	1.2.3.4 1.2.3.5

	m := new(dns.Msg)
	m.Id = 12345
	m.SetQuestion("miek.nl.", TypeAPAIR)
	m.Answer = append(m.Answer, rr)

	fmt.Println(m)
	// ;; opcode: QUERY, status: NOERROR, id: 12345
	// ;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
	//
	// ;; QUESTION SECTION:
	// ;miek.nl.	IN	 APAIR
	//
	// ;; ANSWER SECTION:
	// miek.nl.	3600	IN	APAIR	1.2.3.4 1.2.3.5
}
<commit_msg>Lowercase error output<commit_after>package dns_test

import (
	"errors"
	"fmt"
	"github.com/miekg/dns"
	"log"
	"net"
)

// Retrieve the MX records for miek.nl.
func ExampleMX() {
	config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	c := new(dns.Client)
	m := new(dns.Msg)
	m.SetQuestion("miek.nl.", dns.TypeMX)
	m.RecursionDesired = true
	r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
	if err != nil {
		return
	}
	if r.Rcode != dns.RcodeSuccess {
		return
	}
	for _, a := range r.Answer {
		if mx, ok := a.(*dns.MX); ok {
			fmt.Printf("%s\n", mx.String())
		}
	}
}

// Retrieve the DNSKEY records of a zone and convert them
// to DS records for SHA1, SHA256 and SHA384.
func ExampleDS(zone string) {
	config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	c := new(dns.Client)
	m := new(dns.Msg)
	if zone == "" {
		zone = "miek.nl"
	}
	m.SetQuestion(dns.Fqdn(zone), dns.TypeDNSKEY)
	m.SetEdns0(4096, true)
	r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
	if err != nil {
		return
	}
	if r.Rcode != dns.RcodeSuccess {
		return
	}
	for _, k := range r.Answer {
		if key, ok := k.(*dns.DNSKEY); ok {
			for _, alg := range []int{dns.SHA1, dns.SHA256, dns.SHA384} {
				fmt.Printf("%s; %d\n", key.ToDS(alg).String(), key.Flags)
			}
		}
	}
}

const TypeAPAIR = 0x0F99

type APAIR struct {
	addr [2]net.IP
}

func NewAPAIR() dns.PrivateRdata { return new(APAIR) }

func (rd *APAIR) String() string { return rd.addr[0].String() + " " + rd.addr[1].String() }
func (rd *APAIR) ParseTextSlice(txt []string) error {
	if len(txt) != 2 {
		return errors.New("two addresses required for APAIR")
	}
	for i, s := range txt {
		ip := net.ParseIP(s)
		if ip == nil {
			return errors.New("invalid IP in APAIR text representation")
		}
		rd.addr[i] = ip
	}
	return nil
}

func (rd *APAIR) Pack(buf []byte) (int, error) {
	b := append([]byte(rd.addr[0]), []byte(rd.addr[1])...)
	n := copy(buf, b)
	if n != len(b) {
		return n, dns.ErrBuf
	}
	return n, nil
}

func (rd *APAIR) Unpack(buf []byte) (int, error) {
	ln := net.IPv4len * 2
	if len(buf) != ln {
		return 0, errors.New("invalid length of APAIR rdata")
	}
	cp := make([]byte, ln)
	copy(cp, buf) // clone bytes to use them in IPs

	rd.addr[0] = net.IP(cp[:3])
	rd.addr[1] = net.IP(cp[4:])

	return len(buf), nil
}

func (rd *APAIR) CopyRdata(dest dns.PrivateRdata) error {
	cp := make([]byte, rd.RdataLen())
	_, err := rd.Pack(cp)
	if err != nil {
		return err
	}

	d := dest.(*APAIR)
	d.addr[0] = net.IP(cp[:3])
	d.addr[1] = net.IP(cp[4:])
	return nil
}

func (rd *APAIR) RdataLen() int {
	return net.IPv4len * 2
}

func ExampleNewPrivateRR() {
	dns.PrivateHandle("APAIR", TypeAPAIR, NewAPAIR)
	defer dns.PrivateHandleRemove(TypeAPAIR)

	rr, err := dns.NewRR("miek.nl. APAIR (1.2.3.4    1.2.3.5)")
	if err != nil {
		log.Fatal("could not parse APAIR record: ", err)
	}
	fmt.Println(rr)
	// Output: miek.nl.	3600	IN	APAIR	1.2.3.4 1.2.3.5

	m := new(dns.Msg)
	m.Id = 12345
	m.SetQuestion("miek.nl.", TypeAPAIR)
	m.Answer = append(m.Answer, rr)

	fmt.Println(m)
	// ;; opcode: QUERY, status: NOERROR, id: 12345
	// ;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
	//
	// ;; QUESTION SECTION:
	// ;miek.nl.	IN	 APAIR
	//
	// ;; ANSWER SECTION:
	// miek.nl.	3600	IN	APAIR	1.2.3.4 1.2.3.5
}
<|endoftext|>


<commit_before>// Project Gonder.
// Author Supme
// Copyright Supme 2016
// License http://opensource.org/licenses/MIT MIT License
//
//  THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
//  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//  PURPOSE.
//
// Please see the License.txt file for more information.
//
package mailer

import (
	"github.com/supme/gonder/models"
	"bytes"
	"crypto/rand"
	"encoding/base64"
	"errors"
	"fmt"
//	_ "github.com/eaigner/dkim"
	"golang.org/x/net/proxy"
	"io/ioutil"
	"net"
	"net/http"
	"net/smtp"
	"strings"
	"golang.org/x/net/idna"
)

type (
	MailData struct {
		Iface 	     string
		Host         string
		From_email   string
		From_name    string
		To_email     string
		To_name      string
		Extra_header string
		Subject      string
		Html         string
		Attachments  []Attachment
		s	     	 proxy.Dialer
		n            net.Dialer
	}

	Attachment struct {
		Location string
		Name     string
	}
)

func (m *MailData) Send() error {
	var smx string
	var mx []*net.MX
	var conn net.Conn

	if m.Iface == "" {
		// default interface
		m.n = net.Dialer{}
	} else {
		if m.Iface[0:8] == "socks://" {
			m.Iface = m.Iface[8:]
			var err error
			m.s, err = proxy.SOCKS5("tcp", m.Iface, nil, proxy.FromEnvironment())
			if err != nil {
				return err
			}
		} else {
			connectAddr := net.ParseIP(m.Iface)
			tcpAddr := &net.TCPAddr{
				IP: connectAddr,
			}
			m.n = net.Dialer{LocalAddr: tcpAddr}
		}
	}

	//ToDo cache MX servers
	// trim space
	m.To_email = strings.TrimSpace(m.To_email)
	// punycode convert
	splitEmail := strings.Split(m.To_email, "@")
	if len(splitEmail) != 2 {
		return errors.New(fmt.Sprintf("Bad email"))
	}
	domain, err := idna.ToASCII(splitEmail[1])
	if err != nil {
		return errors.New(fmt.Sprintf("Domain name failed: %v\r\n", err))
	}
	m.To_email = strings.Split(m.To_email, "@")[0] + "@" + domain

	mx, err = net.LookupMX(domain)
	if err != nil {
		return errors.New(fmt.Sprintf("LookupMX failed: %v\r\n", err))
	} else {
		for i := range mx {
			smx := net.JoinHostPort(mx[i].Host, "25")
			// Set ip (from MX records) and port mail server
			if m.s != nil {
				conn, err = m.s.Dial("tcp", smx)
			} else {
				conn, err = m.n.Dial("tcp", smx)
			}
			if err == nil {
				break
			}
		}
	}
	if err != nil {
		return err
	}
	defer conn.Close()

	host, _, _ := net.SplitHostPort(smx)
	c, err := smtp.NewClient(conn, host)
	if err != nil {
		return err
	}

	if err := c.Hello(m.Host); err != nil {
		return err
	}

	// Set the sender and recipient first
	if err := c.Mail(m.From_email); err != nil {
		return err
	}

	if err := c.Rcpt(m.To_email); err != nil {
		return err
	}

	msg := m.makeMail()

	//dkim.New()

	w, err := c.Data()
	if err != nil {
		return err
	}
	_, err = fmt.Fprint(w, msg)
	if err != nil {
		return err
	}

	err = w.Close()
	if err != nil {
		return err
	}

	// Send the QUIT command and close the connection.
	return c.Quit()
}

func (m *MailData) makeMail() string {
	marker := makeMarker()

	var msg bytes.Buffer

	if m.From_name == "" {
		msg.WriteString(`From: ` + m.From_email + "\r\n")
	} else {
		msg.WriteString(`From: "` + encodeRFC2047(m.From_name) + `" <` + m.From_email + `>` +"\r\n")
	}

	if m.To_name == "" {
		msg.WriteString(`To: ` + m.To_email + "\r\n")
	} else {
		msg.WriteString(`To: "` + encodeRFC2047(m.To_name) + `" <` + m.To_email + `>` + "\r\n")
	}

	// -------------- head ----------------------------------------------------------

	msg.WriteString("Subject: " + encodeRFC2047(m.Subject) + "\r\n")
	msg.WriteString("MIME-Version: 1.0\r\n")
	msg.WriteString("Content-Type: multipart/mixed;\r\n	boundary=\"" + marker + "\"\r\n")
	msg.WriteString("X-Mailer: " + models.Config.Version + "\r\n")
	msg.WriteString(m.Extra_header + "\r\n")
	// ------------- /head ---------------------------------------------------------

	// ------------- body ----------------------------------------------------------
	msg.WriteString("\r\n--" + marker + "\r\nContent-Type: text/html; charset=\"utf-8\"\r\nContent-Transfer-Encoding: 8bit\r\n\r\n")
	msg.WriteString(m.Html)
	// ------------ /body ---------------------------------------------------------

	// ----------- attachments ----------------------------------------------------
	for _, file := range m.Attachments {

		msg.WriteString("\r\n--" + marker)
		//read and encode attachment
		content, err := ioutil.ReadFile(file.Location + file.Name)
		if err != nil {
			fmt.Println(err)
		}
		encoded := base64.StdEncoding.EncodeToString(content)

		//part 3 will be the attachment
		msg.WriteString(fmt.Sprintf("\r\nContent-Type: %s;\r\n	name=\"%s\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment;\r\n	filename=\"%s\"\r\n\r\n", http.DetectContentType(content), file.Name, file.Name))
		//split the encoded file in lines (doesn't matter, but low enough not to hit a max limit)
		lineMaxLength := 500
		nbrLines := len(encoded) / lineMaxLength
		for i := 0; i < nbrLines; i++ {
			msg.WriteString(encoded[i*lineMaxLength:(i+1)*lineMaxLength] + "\n")
		}

		//append last line in buffer
		msg.WriteString(encoded[nbrLines*lineMaxLength:])
		msg.WriteString("\r\n")

	}
	// ----------- /attachments ---------------------------------------------------

	return msg.String()
}

func makeMarker() string {
	b := make([]byte, 30)
	rand.Read(b)
	en := base64.StdEncoding // or URLEncoding
	d := make([]byte, en.EncodedLen(len(b)))
	en.Encode(d, b)
	return string(d)
}

func encodeRFC2047(s string) string {
	// use code from net/mail for rfc2047 encode any string
	// UTF-8 "Q" encoding
	b := bytes.NewBufferString("=?utf-8?q?")
	for i := 0; i < len(s); i++ {
		switch c := s[i]; {
		case c == ' ':
			b.WriteByte('_')
		case isVchar(c) && c != '=' && c != '?' && c != '_':
			b.WriteByte(c)
		default:
			fmt.Fprintf(b, "=%02X", c)
		}
	}
	b.WriteString("?= ")
	return b.String()
}

// isVchar returns true if c is an RFC 5322 VCHAR character.
func isVchar(c byte) bool {
	// Visible (printing) characters.
	return '!' <= c && c <= '~'
}
<commit_msg>small fix<commit_after>// Project Gonder.
// Author Supme
// Copyright Supme 2016
// License http://opensource.org/licenses/MIT MIT License
//
//  THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
//  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//  PURPOSE.
//
// Please see the License.txt file for more information.
//
package mailer

import (
	"github.com/supme/gonder/models"
	"bytes"
	"crypto/rand"
	"encoding/base64"
	"errors"
	"fmt"
//	_ "github.com/eaigner/dkim"
	"golang.org/x/net/proxy"
	"io/ioutil"
	"net"
	"net/http"
	"net/smtp"
	"strings"
	"golang.org/x/net/idna"
	"cmd/go/testdata/testinternal2/x/y/z/internal/w"
)

type (
	MailData struct {
		Iface 	     string
		Host         string
		From_email   string
		From_name    string
		To_email     string
		To_name      string
		Extra_header string
		Subject      string
		Html         string
		Attachments  []Attachment
		s	     	 proxy.Dialer
		n            net.Dialer
	}

	Attachment struct {
		Location string
		Name     string
	}
)

func (m *MailData) Send() error {
	var smx string
	var mx []*net.MX
	var conn net.Conn

	if m.Iface == "" {
		// default interface
		m.n = net.Dialer{}
	} else {
		if m.Iface[0:8] == "socks://" {
			m.Iface = m.Iface[8:]
			var err error
			m.s, err = proxy.SOCKS5("tcp", m.Iface, nil, proxy.FromEnvironment())
			if err != nil {
				return err
			}
		} else {
			connectAddr := net.ParseIP(m.Iface)
			tcpAddr := &net.TCPAddr{
				IP: connectAddr,
			}
			m.n = net.Dialer{LocalAddr: tcpAddr}
		}
	}

	//ToDo cache MX servers
	// trim space
	m.To_email = strings.TrimSpace(m.To_email)
	// punycode convert
	splitEmail := strings.Split(m.To_email, "@")
	if len(splitEmail) != 2 {
		return errors.New(fmt.Sprintf("Bad email"))
	}
	domain, err := idna.ToASCII(splitEmail[1])
	if err != nil {
		return errors.New(fmt.Sprintf("Domain name failed: %v\r\n", err))
	}
	m.To_email = strings.Split(m.To_email, "@")[0] + "@" + domain

	mx, err = net.LookupMX(domain)
	if err != nil {
		return errors.New(fmt.Sprintf("LookupMX failed: %v\r\n", err))
	} else {
		for i := range mx {
			smx := net.JoinHostPort(mx[i].Host, "25")
			// Set ip (from MX records) and port mail server
			if m.s != nil {
				conn, err = m.s.Dial("tcp", smx)
			} else {
				conn, err = m.n.Dial("tcp", smx)
			}
			if err == nil {
				break
			}
		}
	}
	if err != nil {
		return err
	}
	defer conn.Close()

	host, _, _ := net.SplitHostPort(smx)
	c, err := smtp.NewClient(conn, host)
	if err != nil {
		return err
	}

	if err := c.Hello(m.Host); err != nil {
		return err
	}

	// Set the sender and recipient first
	if err := c.Mail(m.From_email); err != nil {
		return err
	}

	if err := c.Rcpt(m.To_email); err != nil {
		return err
	}

	//dkim.New()

	w, err := c.Data()
	if err != nil {
		return err
	}
	_, err = fmt.Fprint(w, m.makeMail())
	if err != nil {
		return err
	}

	err = w.Close()
	if err != nil {
		return err
	}

	// Send the QUIT command and close the connection.
	return c.Quit()
}

func (m *MailData) makeMail() string {
	marker := makeMarker()

	var msg bytes.Buffer

	if m.From_name == "" {
		msg.WriteString(`From: ` + m.From_email + "\r\n")
	} else {
		msg.WriteString(`From: "` + encodeRFC2047(m.From_name) + `" <` + m.From_email + `>` +"\r\n")
	}

	if m.To_name == "" {
		msg.WriteString(`To: ` + m.To_email + "\r\n")
	} else {
		msg.WriteString(`To: "` + encodeRFC2047(m.To_name) + `" <` + m.To_email + `>` + "\r\n")
	}

	// -------------- head ----------------------------------------------------------

	msg.WriteString("Subject: " + encodeRFC2047(m.Subject) + "\r\n")
	msg.WriteString("MIME-Version: 1.0\r\n")
	msg.WriteString("Content-Type: multipart/mixed;\r\n	boundary=\"" + marker + "\"\r\n")
	msg.WriteString("X-Mailer: " + models.Config.Version + "\r\n")
	msg.WriteString(m.Extra_header + "\r\n")
	// ------------- /head ---------------------------------------------------------

	// ------------- body ----------------------------------------------------------
	msg.WriteString("\r\n--" + marker + "\r\nContent-Type: text/html; charset=\"utf-8\"\r\nContent-Transfer-Encoding: 8bit\r\n\r\n")
	msg.WriteString(m.Html)
	// ------------ /body ---------------------------------------------------------

	// ----------- attachments ----------------------------------------------------
	for _, file := range m.Attachments {

		msg.WriteString("\r\n--" + marker)
		//read and encode attachment
		content, err := ioutil.ReadFile(file.Location + file.Name)
		if err != nil {
			fmt.Println(err)
		}
		encoded := base64.StdEncoding.EncodeToString(content)

		//part 3 will be the attachment
		msg.WriteString(fmt.Sprintf("\r\nContent-Type: %s;\r\n	name=\"%s\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment;\r\n	filename=\"%s\"\r\n\r\n", http.DetectContentType(content), file.Name, file.Name))
		//split the encoded file in lines (doesn't matter, but low enough not to hit a max limit)
		lineMaxLength := 500
		nbrLines := len(encoded) / lineMaxLength
		for i := 0; i < nbrLines; i++ {
			msg.WriteString(encoded[i*lineMaxLength:(i+1)*lineMaxLength] + "\n")
		}

		//append last line in buffer
		msg.WriteString(encoded[nbrLines*lineMaxLength:])
		msg.WriteString("\r\n")

	}
	// ----------- /attachments ---------------------------------------------------

	return msg.String()
}

func makeMarker() string {
	b := make([]byte, 30)
	rand.Read(b)
	en := base64.StdEncoding // or URLEncoding
	d := make([]byte, en.EncodedLen(len(b)))
	en.Encode(d, b)
	return string(d)
}

func encodeRFC2047(s string) string {
	// use code from net/mail for rfc2047 encode any string
	// UTF-8 "Q" encoding
	b := bytes.NewBufferString("=?utf-8?q?")
	for i := 0; i < len(s); i++ {
		switch c := s[i]; {
		case c == ' ':
			b.WriteByte('_')
		case isVchar(c) && c != '=' && c != '?' && c != '_':
			b.WriteByte(c)
		default:
			fmt.Fprintf(b, "=%02X", c)
		}
	}
	b.WriteString("?= ")
	return b.String()
}

// isVchar returns true if c is an RFC 5322 VCHAR character.
func isVchar(c byte) bool {
	// Visible (printing) characters.
	return '!' <= c && c <= '~'
}
<|endoftext|>


<commit_before>package controllers

import (
    "database/sql"
    "github.com/orc/db"
    "github.com/orc/sessions"
    "github.com/orc/utils"
    "net/http"
    "strconv"
)

func (this *GridHandler) GetEventTypesByEventId() {
    if !sessions.CheckSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        http.Redirect(this.Response, this.Request, "/", http.StatusForbidden)
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    eventId, err := strconv.Atoi(request["event_id"].(string))
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    query := `SELECT event_types.id, event_types.name FROM events_types
        INNER JOIN events ON events.id = events_types.event_id
        INNER JOIN event_types ON event_types.id = events_types.type_id
        WHERE events.id = $1 ORDER BY event_types.id;`
    result := db.Query(query, []interface{}{eventId})

    utils.SendJSReply(map[string]interface{}{"result": "ok", "data": result}, this.Response)

}

func (this *GridHandler) ImportForms() {
    if !sessions.CheckSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        http.Redirect(this.Response, this.Request, "/", http.StatusForbidden)
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    eventId, err := strconv.Atoi(request["event_id"].(string))
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    for _, v := range request["event_types_ids"].([]interface{}) {
        typeId, err := strconv.Atoi(v.(string))
        if err != nil {
            utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
            return
        }

        query := `SELECT events.id FROM events
            INNER JOIN events_types ON events_types.event_id = events.id
            INNER JOIN event_types ON event_types.id = events_types.type_id
            WHERE event_types.id = $1 AND events.id <> $2
            ORDER BY id DESC LIMIT 1;`
        eventResult := db.Query(query, []interface{}{typeId, eventId})[0].(map[string]interface{})["id"].(int)

        query = `SELECT forms.id FROM forms
            INNER JOIN events_forms ON events_forms.form_id = forms.id
            INNER JOIN events ON events.id = events_forms.event_id
            WHERE events.id = $1 ORDER BY forms.id;`
        formsResult := db.Query(query, []interface{}{eventResult})

        for i := 0; i < len(formsResult); i++ {
            formId := int(formsResult[i].(map[string]interface{})["id"].(int))
            eventsForms := this.GetModel("events_forms")
            eventsForms.LoadWherePart(map[string]interface{}{"event_id": eventId, "form_id": formId})

            var eventFormId int
            err := db.SelectRow(eventsForms, []string{"id"}).Scan(&eventFormId)
            if err != sql.ErrNoRows {
                continue
            }

            eventsForms.LoadModelData(map[string]interface{}{"event_id":  eventId, "form_id": formId})
            db.QueryInsert(eventsForms, "").Scan()
        }
    }

    utils.SendJSReply(map[string]interface{}{"result": "ok"}, this.Response)
}
<commit_msg>form-import.go: it doesn't matter<commit_after>package controllers

import (
    "database/sql"
    "github.com/orc/db"
    "github.com/orc/sessions"
    "github.com/orc/utils"
    "net/http"
    "strconv"
)

func (this *GridHandler) GetEventTypesByEventId() {
    if !sessions.CheckSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        http.Redirect(this.Response, this.Request, "/", http.StatusForbidden)
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    eventId, err := strconv.Atoi(request["event_id"].(string))
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    query := `SELECT event_types.id, event_types.name FROM events_types
        INNER JOIN events ON events.id = events_types.event_id
        INNER JOIN event_types ON event_types.id = events_types.type_id
        WHERE events.id = $1 ORDER BY event_types.id;`
    result := db.Query(query, []interface{}{eventId})

    utils.SendJSReply(map[string]interface{}{"result": "ok", "data": result}, this.Response)
}

func (this *GridHandler) ImportForms() {
    if !sessions.CheckSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        http.Redirect(this.Response, this.Request, "/", http.StatusForbidden)
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    eventId, err := strconv.Atoi(request["event_id"].(string))
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    for _, v := range request["event_types_ids"].([]interface{}) {
        typeId, err := strconv.Atoi(v.(string))
        if err != nil {
            utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
            return
        }

        var lastEventId int
        query := `SELECT events.id FROM events
            INNER JOIN events_types ON events_types.event_id = events.id
            INNER JOIN event_types ON event_types.id = events_types.type_id
            WHERE event_types.id = $1 AND events.id <> $2
            ORDER BY id DESC LIMIT 1;`
        db.QueryRow(query, []interface{}{typeId, eventId}).Scan(&lastEventId)

        query = `SELECT forms.id FROM forms
            INNER JOIN events_forms ON events_forms.form_id = forms.id
            INNER JOIN events ON events.id = events_forms.event_id
            WHERE events.id = $1 ORDER BY forms.id;`
        formsResult := db.Query(query, []interface{}{lastEventId})

        for i := 0; i < len(formsResult); i++ {
            formId := int(formsResult[i].(map[string]interface{})["id"].(int))
            eventsForms := this.GetModel("events_forms")
            eventsForms.LoadWherePart(map[string]interface{}{"event_id": eventId, "form_id": formId})

            var eventFormId int
            err := db.SelectRow(eventsForms, []string{"id"}).Scan(&eventFormId)
            if err != sql.ErrNoRows {
                continue
            }

            eventsForms.LoadModelData(map[string]interface{}{"event_id":  eventId, "form_id": formId})
            db.QueryInsert(eventsForms, "").Scan()
        }
    }

    utils.SendJSReply(map[string]interface{}{"result": "ok"}, this.Response)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strings"
)

// HelpForHelp shows overall usage information for the BigV client, including a list of available commands.
func (cmds *CommandSet) HelpForHelp() {
	// TODO(telyn): write real usage information
	fmt.Println("bigv command-line client (the new, cool one)")
	fmt.Println()
	fmt.Println("There would be some usage output here if I had actually written any.")
	fmt.Println()
}

// Help implements the help command, which gives usage information specific to each command. Usage: bigv help [command]
func (cmds *CommandSet) Help(args []string) {
	if len(args) == 0 {
		cmds.HelpForHelp()
		return
	}

	// please try and keep these in alphabetical order
	switch strings.ToLower(args[0]) {
	case "config":
		cmds.HelpForConfig()
	case "debug":
		cmds.HelpForDebug()
	case "delete":
		cmds.HelpForDelete()
	case "exit":
		cmds.HelpForExitCodes()
	case "exit-codes":
		cmds.HelpForExitCodes()
	case "show":
		cmds.HelpForShow()
	}

}
<commit_msg>Write some real-ish usage information<commit_after>package main

import (
	"fmt"
	"strings"
)

// HelpForHelp shows overall usage information for the BigV client, including a list of available commands.
func (cmds *CommandSet) HelpForHelp() {
	fmt.Println("bigv command-line client (the new, cool one)")
	fmt.Println()
	fmt.Println("Usage")
	fmt.Println()
	fmt.Println("    go-bigv [flags] <command> [flags] [args]")
	fmt.Println()
	fmt.Println("Commands available")
	fmt.Println()
	fmt.Println("    help, config, create, debug, delete, list, show")
	fmt.Println("    AND MAYBE MORE OR FEWER - THIS LIST IS NOT FINAL")
	fmt.Println()
	fmt.Println("See `go-bigv help <command>` for help specific to a command")
	fmt.Println()
}

// Help implements the help command, which gives usage information specific to each command. Usage: bigv help [command]
func (cmds *CommandSet) Help(args []string) {
	if len(args) == 0 {
		cmds.HelpForHelp()
		return
	}

	// please try and keep these in alphabetical order
	switch strings.ToLower(args[0]) {
	case "config":
		cmds.HelpForConfig()
	case "debug":
		cmds.HelpForDebug()
	case "delete":
		cmds.HelpForDelete()
	case "exit":
		cmds.HelpForExitCodes()
	case "exit-codes":
		cmds.HelpForExitCodes()
	case "show":
		cmds.HelpForShow()
	}

}
<|endoftext|>


<commit_before>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

// package pointer provides helper method to quickly define pointer from basic go types
package pointer

// String creates a pointer to a string from a string value
func String(v string) *string {
	p := new(string)
	*p = v
	return p
}

// Int creates a pointer to an int from an int value
func Int(v int) *int {
	p := new(int)
	*p = v
	return p
}

// Uint creates a pointer to an unsigned int from an unsigned int value
func Uint(v uint) *uint {
	p := new(uint)
	*p = v
	return p
}

// Float64 creates a pointer to a float64 from a float64 value
func Float64(v float64) *float64 {
	p := new(float64)
	*p = v
	return p
}

// Bool creates a pointer to a boolean from a boolean value
func Bool(v bool) *bool {
	p := new(bool)
	*p = v
	return p
}
<commit_msg>Add a dump helper to utils pointer<commit_after>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

// package pointer provides helper method to quickly define pointer from basic go types
package pointer

import (
    "fmt"
    "reflect"
    "time"
)

// String creates a pointer to a string from a string value
func String(v string) *string {
	p := new(string)
	*p = v
	return p
}

// Int creates a pointer to an int from an int value
func Int(v int) *int {
	p := new(int)
	*p = v
	return p
}

// Uint creates a pointer to an unsigned int from an unsigned int value
func Uint(v uint) *uint {
	p := new(uint)
	*p = v
	return p
}

// Float64 creates a pointer to a float64 from a float64 value
func Float64(v float64) *float64 {
	p := new(float64)
	*p = v
	return p
}

// Bool creates a pointer to a boolean from a boolean value
func Bool(v bool) *bool {
	p := new(bool)
	*p = v
	return p
}

// DumpStruct print the content of a struct of pointers
func DumpPStruct(s interface{}) {
    v := reflect.ValueOf(s)

    if v.Kind() != reflect.Struct {
        fmt.Printf("Unable to dump: Not a struct.")
        return
    }

    for k := 0; k < v.NumField(); k += 1 {
        i := v.Field(k).Interface()
        fmt.Printf("%v: ", v.Type().Field(k).Name)

        switch t := i.(type) {
            case *bool:
                if t == nil {
                    fmt.Printf("nil\n")
                } else {
                    fmt.Printf("%+v\n", *t)
                }
            case *int:
                if t == nil {
                    fmt.Printf("nil\n")
                } else {
                    fmt.Printf("%+v\n", *t)
                }
            case *uint:
                if t == nil {
                    fmt.Printf("nil\n")
                } else {
                    fmt.Printf("%+v\n", *t)
                }
            case *string:
                if t == nil {
                    fmt.Printf("nil\n")
                } else {
                    fmt.Printf("%+v\n", *t)
                }
            case *float64:
                if t == nil {
                    fmt.Printf("nil\n")
                } else {
                    fmt.Printf("%+v\n", *t)
                }
            case *time.Time:
                if t == nil {
                    fmt.Printf("nil\n")
                } else {
                    fmt.Printf("%+v\n", *t)
                }
            default:
                fmt.Printf("unknown\n")
        }
    }
}

<|endoftext|>


<commit_before>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

// Package testing offers some handy methods to display check and cross symbols with colors in test
// logs.
package testing

import (
	"fmt"
	"testing"

	"github.com/apex/log"
)

func GetLogger(t *testing.T, tag string) log.Interface {
	logger := &log.Logger{
		Handler: NewLogHandler(t),
		Level:   log.DebugLevel,
	}
	return logger.WithField("tag", "Adapter")
}

// Ok displays a green check symbol
func Ok(t *testing.T, tag string) {
	t.Log(fmt.Sprintf("\033[32;1m\u2714 ok | %s\033[0m", tag))
}

// Ko fails the test and display a red cross symbol
func Ko(t *testing.T, format string, a ...interface{}) {
	t.Errorf("\033[31;1m\u2718 ko | \033[0m\033[31m%s\033[0m", fmt.Sprintf(format, a...))
	t.Fail()
}

// Desc displays the provided description in cyan
func Desc(t *testing.T, format string, a ...interface{}) {
	t.Logf("\033[36m%s\033[0m", fmt.Sprintf(format, a...))
}
<commit_msg>[test-handler] Use of fatal instead of basic log on utils/testing Ko()<commit_after>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

// Package testing offers some handy methods to display check and cross symbols with colors in test
// logs.
package testing

import (
	"fmt"
	"testing"

	"github.com/apex/log"
)

func GetLogger(t *testing.T, tag string) log.Interface {
	logger := &log.Logger{
		Handler: NewLogHandler(t),
		Level:   log.DebugLevel,
	}
	return logger.WithField("tag", "Adapter")
}

// Ok displays a green check symbol
func Ok(t *testing.T, tag string) {
	t.Log(fmt.Sprintf("\033[32;1m\u2714 ok | %s\033[0m", tag))
}

// Ko fails the test and display a red cross symbol
func Ko(t *testing.T, format string, a ...interface{}) {
	t.Fatalf("\033[31;1m\u2718 ko | \033[0m\033[31m%s\033[0m", fmt.Sprintf(format, a...))
}

// Desc displays the provided description in cyan
func Desc(t *testing.T, format string, a ...interface{}) {
	t.Logf("\033[36m%s\033[0m", fmt.Sprintf(format, a...))
}
<|endoftext|>


<commit_before>package osutil

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	fp "path/filepath"
	"syscall"
	"time"

	"github.com/hashicorp/errwrap"

	"github.com/yuuki1/droot/log"
)

func ExistsFile(file string) bool {
	f, err := os.Stat(file)
	return err == nil && !f.IsDir()
}

func ExistsDir(dir string) bool {
	if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() {
		return false
	}
	return true
}

func IsDirEmpty(dir string) (bool, error) {
	f, err := os.Open(dir)
	if err != nil {
		return false, errwrap.Wrapf(fmt.Sprintf("Failed to open %s", dir), err)
	}
	defer f.Close()

	_, err = f.Readdir(1)
	if err == io.EOF {
		return true, errwrap.Wrapf(fmt.Sprintf("Failed to readdir %s", dir), err)
	}
	return false, err // Either not empty or error, suits both cases
}

func RunCmd(name string, arg ...string) error {
	log.Debug("runcmd: ", name, arg)
	out, err := exec.Command(name, arg...).CombinedOutput()
	if len(out) > 0 {
		log.Debug(string(out))
	}
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to exec %s %s: {{err}}", name, arg), err)
	}
	return nil
}

func Cp(from, to string) error {
	if err := RunCmd("cp", "-p", from, to); err != nil {
		return err
	}
	return nil
}

func BindMount(src, dest string) error {
	if err := RunCmd("mount", "--bind", src, dest); err != nil {
		return err
	}
	return nil
}

func RObindMount(src, dest string) error {
	if err := RunCmd("mount", "-o", "remount,ro,bind", src, dest); err != nil {
		return err
	}
	return nil
}

func Mounted(mountpoint string) (bool, error) {
	mntpoint, err := os.Stat(mountpoint)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	parent, err := os.Stat(fp.Join(mountpoint, ".."))
	if err != nil {
		return false, err
	}
	mntpointSt := mntpoint.Sys().(*syscall.Stat_t)
	parentSt := parent.Sys().(*syscall.Stat_t)
	return mntpointSt.Dev != parentSt.Dev, nil
}

// Unmount will unmount the target filesystem, so long as it is mounted.
func Unmount(target string, flag int) error {
	if mounted, err := Mounted(target); err != nil || !mounted {
		return errwrap.Wrapf(fmt.Sprintf("Failed to unmount %s: {{err}}", target), err)
	}
	return ForceUnmount(target, flag)
}

// ForceUnmount will force an unmount of the target filesystem, regardless if
// it is mounted or not.
func ForceUnmount(target string, flag int) (err error) {
	// Simple retry logic for unmount
	for i := 0; i < 10; i++ {
		if err = syscall.Unmount(target, flag); err == nil {
			return errwrap.Wrapf(fmt.Sprintf("Failed to force unmount %s: {{err}}", target), err)
		}
		time.Sleep(100 * time.Millisecond)
	}
	return
}

// Mknod unless path does not exists.
func Mknod(path string, mode uint32, dev int) error {
	if ExistsFile(path) {
		return nil
	}
	if err := syscall.Mknod(path, mode, dev); err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to mknod %s: {{err}}", path), err)
	}
	return nil
}

// Symlink, but ignore already exists file.
func Symlink(oldname, newname string) error {
	if err := os.Symlink(oldname, newname); err != nil {
		// Ignore already created symlink
		if _, ok := err.(*os.LinkError); !ok {
			return errwrap.Wrapf(fmt.Sprintf("Failed to symlink %s %s: {{err}}", oldname, newname), err)
		}
	}
	return nil
}

func Execv(cmd string, args []string, env []string) error {
	name, err := exec.LookPath(cmd)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Not found %s: {{err}}", cmd), err)
	}

	log.Debug("exec: ", name, args)

	return syscall.Exec(name, args, env)
}
<commit_msg>Fix umount failure<commit_after>package osutil

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	fp "path/filepath"
	"syscall"
	"time"

	"github.com/hashicorp/errwrap"

	"github.com/yuuki1/droot/log"
)

func ExistsFile(file string) bool {
	f, err := os.Stat(file)
	return err == nil && !f.IsDir()
}

func ExistsDir(dir string) bool {
	if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() {
		return false
	}
	return true
}

func IsDirEmpty(dir string) (bool, error) {
	f, err := os.Open(dir)
	if err != nil {
		return false, errwrap.Wrapf(fmt.Sprintf("Failed to open %s", dir), err)
	}
	defer f.Close()

	_, err = f.Readdir(1)
	if err == io.EOF {
		return true, errwrap.Wrapf(fmt.Sprintf("Failed to readdir %s", dir), err)
	}
	return false, err // Either not empty or error, suits both cases
}

func RunCmd(name string, arg ...string) error {
	log.Debug("runcmd: ", name, arg)
	out, err := exec.Command(name, arg...).CombinedOutput()
	if len(out) > 0 {
		log.Debug(string(out))
	}
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to exec %s %s: {{err}}", name, arg), err)
	}
	return nil
}

func Cp(from, to string) error {
	if err := RunCmd("cp", "-p", from, to); err != nil {
		return err
	}
	return nil
}

func BindMount(src, dest string) error {
	if err := RunCmd("mount", "--bind", src, dest); err != nil {
		return err
	}
	return nil
}

func RObindMount(src, dest string) error {
	if err := RunCmd("mount", "-o", "remount,ro,bind", src, dest); err != nil {
		return err
	}
	return nil
}

func Mounted(mountpoint string) (bool, error) {
	mntpoint, err := os.Stat(mountpoint)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	parent, err := os.Stat(fp.Join(mountpoint, ".."))
	if err != nil {
		return false, err
	}
	mntpointSt := mntpoint.Sys().(*syscall.Stat_t)
	parentSt := parent.Sys().(*syscall.Stat_t)
	return mntpointSt.Dev != parentSt.Dev, nil
}

// Unmount will unmount the target filesystem, so long as it is mounted.
func Unmount(target string, flag int) error {
	if mounted, err := Mounted(target); err != nil || !mounted {
		return errwrap.Wrapf(fmt.Sprintf("Failed to unmount %s: {{err}}", target), err)
	}
	return ForceUnmount(target, flag)
}

// ForceUnmount will force an unmount of the target filesystem, regardless if
// it is mounted or not.
func ForceUnmount(target string, flag int) (err error) {
	// Simple retry logic for unmount
	for i := 0; i < 10; i++ {
		if err = syscall.Unmount(target, flag); err == nil {
			return err
		}
		time.Sleep(100 * time.Millisecond)
	}
	return
}

// Mknod unless path does not exists.
func Mknod(path string, mode uint32, dev int) error {
	if ExistsFile(path) {
		return nil
	}
	if err := syscall.Mknod(path, mode, dev); err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to mknod %s: {{err}}", path), err)
	}
	return nil
}

// Symlink, but ignore already exists file.
func Symlink(oldname, newname string) error {
	if err := os.Symlink(oldname, newname); err != nil {
		// Ignore already created symlink
		if _, ok := err.(*os.LinkError); !ok {
			return errwrap.Wrapf(fmt.Sprintf("Failed to symlink %s %s: {{err}}", oldname, newname), err)
		}
	}
	return nil
}

func Execv(cmd string, args []string, env []string) error {
	name, err := exec.LookPath(cmd)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Not found %s: {{err}}", cmd), err)
	}

	log.Debug("exec: ", name, args)

	return syscall.Exec(name, args, env)
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"os"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"

	"github.com/cvmfs/docker-graphdriver/daemon/lib"
)

var (
	convertAgain, overwriteLayer, convertSingularity bool
)

func init() {
	convertCmd.Flags().BoolVarP(&overwriteLayer, "overwrite-layers", "f", false, "overwrite the layer if they are already inside the CVMFS repository")
	convertCmd.Flags().BoolVarP(&convertAgain, "convert-again", "g", false, "convert again images that are already successfull converted")
	convertCmd.Flags().BoolVarP(&convertSingularity, "convert-singularity", "s", true, "also create a singularity images")
	rootCmd.AddCommand(convertCmd)
}

var convertCmd = &cobra.Command{
	Use:   "convert",
	Short: "Convert the wishes",
	Run: func(cmd *cobra.Command, args []string) {
		AliveMessage()
		defer lib.ExecCommand("docker", "system", "prune", "--force", "--all")

		wish, err := lib.GetAllWishes()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		for _, wish := range wish {
			fields := log.Fields{"input image": wish.InputName,
				"repository":   wish.CvmfsRepo,
				"output image": wish.OutputName}
			lib.Log().WithFields(fields).Info("Start conversion of wish")
			err = lib.ConvertWish(wish, convertAgain, overwriteLayer, convertSingularity)
			if err != nil {
				lib.LogE(err).WithFields(fields).Error("Error in converting wish, going on")
			}
		}
		os.Exit(0)
	},
}
<commit_msg>make convert take also a recipe<commit_after>package cmd

import (
	"fmt"
	"io/ioutil"
	"os"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"

	"github.com/cvmfs/docker-graphdriver/daemon/lib"
)

var (
	convertAgain, overwriteLayer, convertSingularity bool
)

func init() {
	convertCmd.Flags().BoolVarP(&overwriteLayer, "overwrite-layers", "f", false, "overwrite the layer if they are already inside the CVMFS repository")
	convertCmd.Flags().BoolVarP(&convertAgain, "convert-again", "g", false, "convert again images that are already successfull converted")
	convertCmd.Flags().BoolVarP(&convertSingularity, "convert-singularity", "s", true, "also create a singularity images")
	rootCmd.AddCommand(convertCmd)
}

var convertCmd = &cobra.Command{
	Use:   "convert",
	Short: "Convert the wishes",
	Run: func(cmd *cobra.Command, args []string) {
		AliveMessage()
		defer lib.ExecCommand("docker", "system", "prune", "--force", "--all")

		if len(args) < 1 {

			wish, err := lib.GetAllWishes()
			if err != nil {
				fmt.Println(err)
				os.Exit(1)
			}
			for _, wish := range wish {
				fields := log.Fields{"input image": wish.InputName,
					"repository":   wish.CvmfsRepo,
					"output image": wish.OutputName}
				lib.Log().WithFields(fields).Info("Start conversion of wish")
				err = lib.ConvertWish(wish, convertAgain, overwriteLayer, convertSingularity)
				if err != nil {
					lib.LogE(err).WithFields(fields).Error("Error in converting wish, going on")
				}
			}
			os.Exit(0)
		} else {

			data, err := ioutil.ReadFile(args[0])
			if err != nil {
				lib.LogE(err).Fatal("Impossible to read the recipe file")
				os.Exit(1)
			}
			recipe, err := lib.ParseYamlRecipeV1(data)
			if err != nil {
				lib.LogE(err).Fatal("Impossible to parse the recipe file")
				os.Exit(1)
			}
			for _, wish := range recipe.Wishes {
				fields := log.Fields{"input image": wish.InputName,
					"repository":   wish.CvmfsRepo,
					"output image": wish.OutputName}
				lib.Log().WithFields(fields).Info("Start conversion of wish")
				err = lib.ConvertWish(wish, convertAgain, overwriteLayer, convertSingularity)
				if err != nil {
					lib.LogE(err).WithFields(fields).Error("Error in converting wish, going on")
				}
			}

		}
	},
}
<|endoftext|>


<commit_before>package middleware

import (
	"net/http"

	"github.com/go-chi/chi"
)

// StripSlashes is a middleware that will match request paths with a trailing
// slash, strip it from the path and continue routing through the mux, if a route
// matches, then it will serve the handler.
//
// NOTE: StripSlashes middleware is *incompatible* with http.FileServer,
// see https://github.com/go-chi/chi/issues/343
func StripSlashes(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		var path string
		rctx := chi.RouteContext(r.Context())
		if rctx.RoutePath != "" {
			path = rctx.RoutePath
		} else {
			path = r.URL.Path
		}
		if len(path) > 1 && path[len(path)-1] == '/' {
			rctx.RoutePath = path[:len(path)-1]
		}
		next.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}

// RedirectSlashes is a middleware that will match request paths with a trailing
// slash and redirect to the same path, less the trailing slash.
func RedirectSlashes(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		var path string
		rctx := chi.RouteContext(r.Context())
		if rctx.RoutePath != "" {
			path = rctx.RoutePath
		} else {
			path = r.URL.Path
		}
		if len(path) > 1 && path[len(path)-1] == '/' {
			path = path[:len(path)-1]
			http.Redirect(w, r, path, 301)
			return
		}
		next.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}
<commit_msg>update docs for RedirectSlashes middleware<commit_after>package middleware

import (
	"net/http"

	"github.com/go-chi/chi"
)

// StripSlashes is a middleware that will match request paths with a trailing
// slash, strip it from the path and continue routing through the mux, if a route
// matches, then it will serve the handler.
func StripSlashes(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		var path string
		rctx := chi.RouteContext(r.Context())
		if rctx.RoutePath != "" {
			path = rctx.RoutePath
		} else {
			path = r.URL.Path
		}
		if len(path) > 1 && path[len(path)-1] == '/' {
			rctx.RoutePath = path[:len(path)-1]
		}
		next.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}

// RedirectSlashes is a middleware that will match request paths with a trailing
// slash and redirect to the same path, less the trailing slash.
//
// NOTE: RedirectSlashes middleware is *incompatible* with http.FileServer,
// see https://github.com/go-chi/chi/issues/343
func RedirectSlashes(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		var path string
		rctx := chi.RouteContext(r.Context())
		if rctx.RoutePath != "" {
			path = rctx.RoutePath
		} else {
			path = r.URL.Path
		}
		if len(path) > 1 && path[len(path)-1] == '/' {
			path = path[:len(path)-1]
			http.Redirect(w, r, path, 301)
			return
		}
		next.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"

	gnatsd "github.com/nats-io/gnatsd/server"
	"github.com/nats-io/go-nats"
)

// Quick and dirty app to read self reported memory from a server
// based on subscriptions.

var trace bool
var verbose bool
var singleSubj bool

func verbosef(format string, v ...interface{}) {
	if verbose {
		log.Printf(format, v...)
	}
}

func connect(urls string) (*nats.Conn, error) {
	opts := nats.DefaultOptions
	opts.Servers = strings.Split(urls, ",")

	opts.AsyncErrorCB = errorHandler
	opts.DisconnectedCB = disconnectedHandler
	opts.ReconnectedCB = reconnectedHandler
	opts.ClosedCB = closedHandler

	return opts.Connect()
}

func createSubscription(nc *nats.Conn, subject string) (*nats.Subscription, error) {

	// unique callback per sub, add some code
	mh := func(msg *nats.Msg) {
		log.Printf("Received message on %s.\n", msg.Subject)
	}

	verbosef("Subscribing to to %s.\n", subject)
	s, err := nc.Subscribe(subject, mh)
	if err != nil {
		return nil, err
	}

	verbosef("Subscribed to %s.\n", subject)
	return s, err
}

func usage() {
	log.Fatal("Usage: scale-client-emulator -cfg <config file> [-v VERBOSE]")
}

func disconnectedHandler(nc *nats.Conn) {
	if nc.LastError() != nil {
		log.Printf("connection disconnected: %v\n",
			nc.LastError())
	}
}

func reconnectedHandler(nc *nats.Conn) {
	log.Printf("reconnected to NATS Server at %q\n",
		nc.ConnectedUrl())
}

func closedHandler(nc *nats.Conn) {
	verbosef("connection has been closed\n")
}

func errorHandler(nc *nats.Conn, sub *nats.Subscription, err error) {
	log.Fatalf("asynchronous error on connection %s, subject %s: %s\n",
		nc.Opts.Name, sub.Subject, err)
}

func run(url, monURL, subject string, subcount int, isVerbose, isTraceVerbose bool) {
	verbose = isVerbose
	if isTraceVerbose {
		verbose = true
		trace = true
	}
	nc, err := connect(url)
	if err != nil {
		log.Fatalf("Couldn't connect:  %v\n", err)
	}

	var subj string
	for i := 1; i <= subcount; i++ {
		if singleSubj {
			subj = subject
		} else {
			subj = fmt.Sprintf("%s.%d", subject, i)
		}
		_, err = createSubscription(nc, subj)
		if err != nil {
			log.Fatalf("Couldn't subscribe:  %v\n", err)
		}
		if i%25000 == 0 {
			if err := printServerRSS(monURL, i); err != nil {
				log.Fatalf("Couldn't get server memory: %v", err)
			}
		}
	}

	if err := nc.Flush(); err != nil {
		log.Fatalf("Couldn't flush:  %v\n", err)
	}
}

var firstPrint bool

func printServerRSS(monURL string, subcount int) error {

	varz := &gnatsd.Varz{}
	HTTPClient := &http.Client{}

	verbosef("Getting data from monitor url: %s\n", monURL)
	resp, err := HTTPClient.Get(monURL)
	if resp != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		return fmt.Errorf("could not get stats from server: %v\n", err)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("could not read response body: %v\n", err)
	}

	err = json.Unmarshal(body, &varz)
	if err != nil {
		return fmt.Errorf("could not unmarshal json: %v\n", err)
	}

	if !firstPrint {
		firstPrint = true
		log.Printf("subcount, mem(rss)")
	}
	log.Printf("%d, %d\n", subcount, varz.Mem)

	return nil
}

func main() {
	var url = flag.String("url", "nats://localhost:4222", "nats server url")
	var murl = flag.String("murl", "http://localhost:6060", "Monitor url")
	var su = flag.String("subject", "foo", "base subject to use")
	var sc = flag.Int("subcount", 10000000, "number of subscribers")
	var vb = flag.Bool("V", false, "Verbose")
	var tb = flag.Bool("DV", false, "Verbose/Trace")
	var ss = flag.Bool("oneSubj", false, "Use a single subject.")

	log.SetFlags(0)
	flag.Parse()

	singleSubj = *ss
	mu := *murl + "/varz"

	run(*url, mu, *su, *sc, *vb, *tb)
}
<commit_msg>Increase run and print values<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"

	gnatsd "github.com/nats-io/gnatsd/server"
	"github.com/nats-io/go-nats"
)

// Quick and dirty app to read self reported memory from a server
// based on subscriptions.

var trace bool
var verbose bool
var singleSubj bool

func verbosef(format string, v ...interface{}) {
	if verbose {
		log.Printf(format, v...)
	}
}

func connect(urls string) (*nats.Conn, error) {
	opts := nats.DefaultOptions
	opts.Servers = strings.Split(urls, ",")

	opts.AsyncErrorCB = errorHandler
	opts.DisconnectedCB = disconnectedHandler
	opts.ReconnectedCB = reconnectedHandler
	opts.ClosedCB = closedHandler

	return opts.Connect()
}

func createSubscription(nc *nats.Conn, subject string) (*nats.Subscription, error) {

	// unique callback per sub, add some code
	mh := func(msg *nats.Msg) {
		log.Printf("Received message on %s.\n", msg.Subject)
	}

	verbosef("Subscribing to to %s.\n", subject)
	s, err := nc.Subscribe(subject, mh)
	if err != nil {
		return nil, err
	}

	verbosef("Subscribed to %s.\n", subject)
	return s, err
}

func usage() {
	log.Fatal("Usage: scale-client-emulator -cfg <config file> [-v VERBOSE]")
}

func disconnectedHandler(nc *nats.Conn) {
	if nc.LastError() != nil {
		log.Printf("connection disconnected: %v\n",
			nc.LastError())
	}
}

func reconnectedHandler(nc *nats.Conn) {
	log.Printf("reconnected to NATS Server at %q\n",
		nc.ConnectedUrl())
}

func closedHandler(nc *nats.Conn) {
	verbosef("connection has been closed\n")
}

func errorHandler(nc *nats.Conn, sub *nats.Subscription, err error) {
	log.Fatalf("asynchronous error on connection %s, subject %s: %s\n",
		nc.Opts.Name, sub.Subject, err)
}

func run(url, monURL, subject string, subcount int, isVerbose, isTraceVerbose bool) {
	verbose = isVerbose
	if isTraceVerbose {
		verbose = true
		trace = true
	}
	nc, err := connect(url)
	if err != nil {
		log.Fatalf("Couldn't connect:  %v\n", err)
	}

	var subj string
	for i := 1; i <= subcount; i++ {
		if singleSubj {
			subj = subject
		} else {
			subj = fmt.Sprintf("%s.%d", subject, i)
		}
		_, err = createSubscription(nc, subj)
		if err != nil {
			log.Fatalf("Couldn't subscribe:  %v\n", err)
		}
		if i%500000 == 0 {
			if err := printServerRSS(monURL, i); err != nil {
				log.Fatalf("Couldn't get server memory: %v", err)
			}
		}
	}

	if err := nc.Flush(); err != nil {
		log.Fatalf("Couldn't flush:  %v\n", err)
	}
}

var firstPrint bool

func printServerRSS(monURL string, subcount int) error {

	varz := &gnatsd.Varz{}
	HTTPClient := &http.Client{}

	verbosef("Getting data from monitor url: %s\n", monURL)
	resp, err := HTTPClient.Get(monURL)
	if resp != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		return fmt.Errorf("could not get stats from server: %v\n", err)
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("could not read response body: %v\n", err)
	}

	err = json.Unmarshal(body, &varz)
	if err != nil {
		return fmt.Errorf("could not unmarshal json: %v\n", err)
	}

	if !firstPrint {
		firstPrint = true
		log.Printf("subcount, mem(rss)")
	}
	log.Printf("%d, %d\n", subcount, varz.Mem)

	return nil
}

func main() {
	var url = flag.String("url", "nats://localhost:4222", "nats server url")
	var murl = flag.String("murl", "http://localhost:6060", "Monitor url")
	var su = flag.String("subject", "foo", "base subject to use")
	var sc = flag.Int("subcount", 30000000, "number of subscribers")
	var vb = flag.Bool("V", false, "Verbose")
	var tb = flag.Bool("DV", false, "Verbose/Trace")
	var ss = flag.Bool("oneSubj", false, "Use a single subject.")

	log.SetFlags(0)
	flag.Parse()

	singleSubj = *ss
	mu := *murl + "/varz"

	run(*url, mu, *su, *sc, *vb, *tb)
}
<|endoftext|>


<commit_before>package byteformat
import (
	"fmt"
	"errors"
	"strings"
)

var precision uint8 = 1
var printfFormat string = "%.2f"

var TooPrecise = errors.New("Precision must not exceed 5")
var UnknownUnit = errors.New("Unknown unit")

const (
	BYTE = float64(1)
	KILOBYTE = 1024 * BYTE
	MEGABYTE = 1024 * KILOBYTE
	GIGABYTE = 1024 * MEGABYTE
	TERABYTE = 1024 * GIGABYTE
	PETABYTE = 1024 * TERABYTE
	EXABYTE = 1024 * PETABYTE
)

func SetPrecision(precision uint8) error {
	if precision > 5 {
		return TooPrecise
	}
	precision = precision
	printfFormat = fmt.Sprintf("%%.%df", precision)
	return nil
}

func HumanizeSize(size uint64) string {
	val := float64(size)
	var unit byte

	switch {
	case val >= EXABYTE:
		unit = 'E'
		val /= EXABYTE
	case val >= PETABYTE:
		unit = 'P'
		val /= PETABYTE
	case val >= TERABYTE:
		unit = 'T'
		val /= TERABYTE
	case val >= GIGABYTE:
		unit = 'G'
		val /= GIGABYTE
	case val >= MEGABYTE:
		unit = 'M'
		val /= MEGABYTE
	case val >= KILOBYTE:
		unit = 'K'
		val /= KILOBYTE
	case val >= BYTE:
		unit = 'b'
	case val == 0:
		return "0"
	}

	ret := fmt.Sprintf(printfFormat, val)
	ret = strings.TrimRight(ret, "0")
	ret = strings.TrimRight(ret, ".")
	return fmt.Sprintf("%s%c", ret, unit)
}

func HumanizeBytes(size uint64) string {
	var runes []rune
	for l := 0; size > 0; l++ {
		digit := size % 10
		size = (size - digit) / 10

		if (l > 2) {
			runes = append(runes, ',')
			l = 0
		}

		runes = append(runes, rune(digit + '0'))
	}

	for i, j := 0, len(runes) - 1; i < j; i, j = i + 1, j - 1 {
        runes[i], runes[j] = runes[j], runes[i]
    }

	return string(runes)
}

func FromString(input string) (uint64, error) {
	var base float64
	var unit byte
	var ret int

	if ret, err := fmt.Sscanf(input, "%f%c", &base, &unit); ret != 2 && ret != 1 {
		fmt.Println(err)
		return 0, err
	}

	if ret == 1 {
		unit = 'b'
	}

	switch unit {
	case 'b', 'B':
		base *= BYTE
	case 'k', 'K':
		base *= KILOBYTE
	case 'm', 'M':
		base *= MEGABYTE
	case 'g', 'G':
		base *= GIGABYTE
	case 't', 'T':
		base *= TERABYTE
	case 'p', 'P':
		base *= PETABYTE
	case 'e', 'E':
		base *= EXABYTE
	default:
		return 0, UnknownUnit
	}

	return uint64(base), nil
}
<commit_msg>HumanizeBytes returned empty string when asked to humanize "0" bytes<commit_after>package byteformat
import (
	"fmt"
	"errors"
	"strings"
)

var precision uint8 = 1
var printfFormat string = "%.2f"

var TooPrecise = errors.New("Precision must not exceed 5")
var UnknownUnit = errors.New("Unknown unit")

const (
	BYTE = float64(1)
	KILOBYTE = 1024 * BYTE
	MEGABYTE = 1024 * KILOBYTE
	GIGABYTE = 1024 * MEGABYTE
	TERABYTE = 1024 * GIGABYTE
	PETABYTE = 1024 * TERABYTE
	EXABYTE = 1024 * PETABYTE
)

func SetPrecision(precision uint8) error {
	if precision > 5 {
		return TooPrecise
	}
	precision = precision
	printfFormat = fmt.Sprintf("%%.%df", precision)
	return nil
}

func HumanizeSize(size uint64) string {
	val := float64(size)
	var unit byte

	switch {
	case val >= EXABYTE:
		unit = 'E'
		val /= EXABYTE
	case val >= PETABYTE:
		unit = 'P'
		val /= PETABYTE
	case val >= TERABYTE:
		unit = 'T'
		val /= TERABYTE
	case val >= GIGABYTE:
		unit = 'G'
		val /= GIGABYTE
	case val >= MEGABYTE:
		unit = 'M'
		val /= MEGABYTE
	case val >= KILOBYTE:
		unit = 'K'
		val /= KILOBYTE
	case val >= BYTE:
		unit = 'b'
	case val == 0:
		return "0"
	}

	ret := fmt.Sprintf(printfFormat, val)
	ret = strings.TrimRight(ret, "0")
	ret = strings.TrimRight(ret, ".")
	return fmt.Sprintf("%s%c", ret, unit)
}

func HumanizeBytes(size uint64) string {
	var runes []rune
	for l := 0; size > 0; l++ {
		digit := size % 10
		size = (size - digit) / 10

		if (l > 2) {
			runes = append(runes, ',')
			l = 0
		}

		runes = append(runes, rune(digit + '0'))
	}
	if len(runes) == 0 {
		runes = append(runes, '0')
	}

	for i, j := 0, len(runes) - 1; i < j; i, j = i + 1, j - 1 {
        runes[i], runes[j] = runes[j], runes[i]
    }

	return string(runes)
}

func FromString(input string) (uint64, error) {
	var base float64
	var unit byte
	var ret int

	if ret, err := fmt.Sscanf(input, "%f%c", &base, &unit); ret != 2 && ret != 1 {
		fmt.Println(err)
		return 0, err
	}

	if ret == 1 {
		unit = 'b'
	}

	switch unit {
	case 'b', 'B':
		base *= BYTE
	case 'k', 'K':
		base *= KILOBYTE
	case 'm', 'M':
		base *= MEGABYTE
	case 'g', 'G':
		base *= GIGABYTE
	case 't', 'T':
		base *= TERABYTE
	case 'p', 'P':
		base *= PETABYTE
	case 'e', 'E':
		base *= EXABYTE
	default:
		return 0, UnknownUnit
	}

	return uint64(base), nil
}
<|endoftext|>


<commit_before>package dockerclient

import (
	"archive/tar"
	"bytes"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"regexp"
	"time"

	"github.com/dynport/dgtk/dockerclient/docker"
)

var (
	imageIdRegexp   = regexp.MustCompile("Successfully built (.*)")
	imageNameRegexp = regexp.MustCompile("([\\w.]+(?::\\d+)?/)?(\\w+)(:[\\w.]+)?")
)

// Get the list of all images available on the this host.
func (dh *Client) Images() (images []*docker.Image, e error) {
	e = dh.getJSON(dh.Address+"/images/json", &images)
	return images, e
}

// Get the details for image with the given id (either hash or name).
func (dh *Client) ImageDetails(id string) (imageDetails *docker.ImageDetails, e error) {
	imageDetails = &docker.ImageDetails{}
	return imageDetails, dh.getJSON(dh.Address+"/images/"+id+"/json", imageDetails)
}

// Get the given image's history.
func (dh *Client) ImageHistory(id string) (imageHistory *docker.ImageHistory, e error) {
	imageHistory = &docker.ImageHistory{}
	e = dh.getJSON(dh.Address+"/images/"+id+"/history", imageHistory)
	return imageHistory, e
}

type BuildImageOptions struct {
	Tag     string
	Quite   bool
	NoCache bool

	Callback func(s *JSONMessage)
}

func (opts *BuildImageOptions) encode() string {
	v := url.Values{}
	if opts != nil {
		if opts.Tag != "" {
			v.Add("t", opts.Tag)
		}
		if opts.NoCache {
			v.Add("nocache", "true")
		}
		if opts.Quite {
			v.Add("quiet", "true")
		}
	}
	return v.Encode()
}

// Create a new image from the given dockerfile. If name is non empty the new image is named accordingly. If a writer is
// given it is used to send the docker output to.
func (dh *Client) BuildDockerfile(dockerfile string, opts *BuildImageOptions) (imageId string, e error) {
	r, e := dh.createDockerfileArchive(dockerfile)
	if e != nil {
		return "", e
	}
	return dh.Build(r, opts)

}

// Build a container image from a tar or tar.gz Reader
func (dh *Client) Build(r io.Reader, opts *BuildImageOptions) (imageId string, e error) {
	u := dh.Address + "/build"
	if opts == nil {
		opts = &BuildImageOptions{}
	}
	if enc := opts.encode(); enc != "" {
		u += "?" + enc
	}
	rsp, e := dh.postWithContentType(u, "application/tar", r)
	if e != nil {
		return "", e
	}
	defer rsp.Body.Close()

	ib := &imageBuildResponseHandler{userHandler: opts.Callback}
	return ib.Run(rsp.Body)
}

// Tag the image with the given repository and tag. The tag is optional.
func (dh *Client) TagImage(imageId, repository, tag string) (e error) {
	if repository == "" {
		return fmt.Errorf("empty repository given")
	}
	url := dh.Address + "/images/" + imageId + "/tag?repo=" + repository

	if tag != "" {
		url += "&tag=" + tag
	}
	rsp, e := dh.post(url)
	if e != nil {
		return e
	}
	return rsp.Body.Close()
}

func (dh *Client) PullFromImage(image string) error {
	v := url.Values{"fromImage": {image}}
	rsp, e := dh.post(dh.Address + "/images/create?" + v.Encode())
	if e != nil {
		return e
	}
	defer rsp.Body.Close()

	return handleJSONStream(rsp.Body, handlePullImageMessage)
}

// Pull the given image from the registry (part of the image name).
func (dh *Client) PullImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	registry, repository, tag := splitImageName(name)

	reqURL := dh.Address + "/images/create"
	values := &url.Values{}
	values.Add("fromImage", registry+"/"+repository)
	values.Add("repo", repository)
	if registry != "" {
		values.Add("registry", registry)
	}
	if tag != "" {
		values.Add("tag", tag)
	}

	rsp, e := dh.post(reqURL + "?" + values.Encode())
	if e != nil {
		return e
	}
	defer rsp.Body.Close()

	return handleJSONStream(rsp.Body, handlePullImageMessage)
}

func handlePullImageMessage(msg *JSONMessage) {
	if e := msg.Err(); e != nil {
		log.Printf("error creating image: %s", e)
	}

	if msg.Status == "Download complete" {
		log.Printf("finished downloading %s", msg.Id)
	}
}

type PushImageOptions struct {
	Callback func(s *JSONMessage)
}

// Push the given image to the registry. The name should be <registry>/<repository>.
func (dh *Client) PushImage(name string, opts *PushImageOptions) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	if opts == nil {
		opts = &PushImageOptions{Callback: handlePullImageMessage}
	}

	registry, image, tag := splitImageName(name)
	if registry == "" {
		return fmt.Errorf("no registry given")
	}

	buf := &bytes.Buffer{}
	buf.WriteString(FAKE_AUTH)
	url := dh.Address + "/images/" + registry + "/" + image + "/push?tag=" + tag

	rsp, e := dh.postWithReader(url, buf)
	if e != nil {
		return e
	}
	defer rsp.Body.Close()

	return handleJSONStream(rsp.Body, opts.Callback)
}

// Delete the given image from the docker host.
func (dh *Client) DeleteImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	req, e := http.NewRequest("DELETE", dh.Address+"/images/"+name, nil)
	if e != nil {
		return e
	}

	resp, e := dh.Client.Do(req)
	if e != nil {
		return e
	}
	defer resp.Body.Close()

	if !success(resp) {
		return fmt.Errorf("failed to delete image %s", name)
	}
	return nil
}

func (self *Client) createDockerfileArchive(dockerfile string) (buf *bytes.Buffer, e error) {
	body := []byte(dockerfile)
	buf = new(bytes.Buffer)
	tw := tar.NewWriter(buf)
	header := &tar.Header{Name: "Dockerfile", Size: int64(len(body))}
	if e = tw.WriteHeader(header); e != nil {
		return nil, e
	}
	if _, e = tw.Write(body); e != nil {
		return nil, e
	}
	if e = tw.Close(); e != nil {
		return nil, e
	}
	return buf, nil
}

func (dh *Client) waitForTag(repository, tag string, timeout int) error {
	for {
		_, e := dh.ImageDetails(repository + ":" + tag)
		if e != nil {
			if e.Error() == "resource not found" {
				time.Sleep(1 * time.Second)
				continue
			}
			return e
		}
		return nil
	}
}

// Every image is named after the following pattern:
//   <registry>/<repository>:<tag>
// with registry being of the form "<hostname>:<port>" and repository being a string of [A-Za-z0-9_].
func splitImageName(name string) (registry, repository, tag string) {
	s := imageNameRegexp.FindStringSubmatch(name)
	if len(s[3]) > 0 {
		tag = s[3][1:]
	}
	repository = s[2]
	if len(s[1]) > 0 {
		registry = s[1][0 : len(s[1])-1]
	}
	return registry, repository, tag
}
<commit_msg>dockerclient: fix status codes when pulling images<commit_after>package dockerclient

import (
	"archive/tar"
	"bytes"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"regexp"
	"time"

	"github.com/dynport/dgtk/dockerclient/docker"
)

var (
	imageIdRegexp   = regexp.MustCompile("Successfully built (.*)")
	imageNameRegexp = regexp.MustCompile("([\\w.]+(?::\\d+)?/)?(\\w+)(:[\\w.]+)?")
)

// Get the list of all images available on the this host.
func (dh *Client) Images() (images []*docker.Image, e error) {
	e = dh.getJSON(dh.Address+"/images/json", &images)
	return images, e
}

// Get the details for image with the given id (either hash or name).
func (dh *Client) ImageDetails(id string) (imageDetails *docker.ImageDetails, e error) {
	imageDetails = &docker.ImageDetails{}
	return imageDetails, dh.getJSON(dh.Address+"/images/"+id+"/json", imageDetails)
}

// Get the given image's history.
func (dh *Client) ImageHistory(id string) (imageHistory *docker.ImageHistory, e error) {
	imageHistory = &docker.ImageHistory{}
	e = dh.getJSON(dh.Address+"/images/"+id+"/history", imageHistory)
	return imageHistory, e
}

type BuildImageOptions struct {
	Tag     string
	Quite   bool
	NoCache bool

	Callback func(s *JSONMessage)
}

func (opts *BuildImageOptions) encode() string {
	v := url.Values{}
	if opts != nil {
		if opts.Tag != "" {
			v.Add("t", opts.Tag)
		}
		if opts.NoCache {
			v.Add("nocache", "true")
		}
		if opts.Quite {
			v.Add("quiet", "true")
		}
	}
	return v.Encode()
}

// Create a new image from the given dockerfile. If name is non empty the new image is named accordingly. If a writer is
// given it is used to send the docker output to.
func (dh *Client) BuildDockerfile(dockerfile string, opts *BuildImageOptions) (imageId string, e error) {
	r, e := dh.createDockerfileArchive(dockerfile)
	if e != nil {
		return "", e
	}
	return dh.Build(r, opts)

}

// Build a container image from a tar or tar.gz Reader
func (dh *Client) Build(r io.Reader, opts *BuildImageOptions) (imageId string, e error) {
	u := dh.Address + "/build"
	if opts == nil {
		opts = &BuildImageOptions{}
	}
	if enc := opts.encode(); enc != "" {
		u += "?" + enc
	}
	rsp, e := dh.postWithContentType(u, "application/tar", r)
	if e != nil {
		return "", e
	}
	defer rsp.Body.Close()

	ib := &imageBuildResponseHandler{userHandler: opts.Callback}
	return ib.Run(rsp.Body)
}

// Tag the image with the given repository and tag. The tag is optional.
func (dh *Client) TagImage(imageId, repository, tag string) (e error) {
	if repository == "" {
		return fmt.Errorf("empty repository given")
	}
	url := dh.Address + "/images/" + imageId + "/tag?repo=" + repository

	if tag != "" {
		url += "&tag=" + tag
	}
	rsp, e := dh.post(url)
	if e != nil {
		return e
	}
	return rsp.Body.Close()
}

func (dh *Client) PullFromImage(image string) error {
	v := url.Values{"fromImage": {image}}
	rsp, e := dh.post(dh.Address + "/images/create?" + v.Encode())
	if e != nil {
		return e
	}
	defer rsp.Body.Close()
	if rsp.Status[0] != '2' {
		return fmt.Errorf("expected status 2xx, was %d", rsp.StatusCode)
	}
	return handleJSONStream(rsp.Body, handlePullImageMessage)
}

// Pull the given image from the registry (part of the image name).
func (dh *Client) PullImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	registry, repository, tag := splitImageName(name)

	reqURL := dh.Address + "/images/create"
	values := &url.Values{}
	values.Add("fromImage", registry+"/"+repository)
	values.Add("repo", repository)
	if registry != "" {
		values.Add("registry", registry)
	}
	if tag != "" {
		values.Add("tag", tag)
	}

	rsp, e := dh.post(reqURL + "?" + values.Encode())
	if e != nil {
		return e
	}
	defer rsp.Body.Close()
	if rsp.Status[0] != '2' {
		return fmt.Errorf("expected status 2xx, was %d", rsp.StatusCode)
	}
	return handleJSONStream(rsp.Body, handlePullImageMessage)
}

func handlePullImageMessage(msg *JSONMessage) {
	if e := msg.Err(); e != nil {
		log.Printf("error creating image: %s", e)
	}

	if msg.Status == "Download complete" {
		log.Printf("finished downloading %s", msg.Id)
	}
}

type PushImageOptions struct {
	Callback func(s *JSONMessage)
}

// Push the given image to the registry. The name should be <registry>/<repository>.
func (dh *Client) PushImage(name string, opts *PushImageOptions) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	if opts == nil {
		opts = &PushImageOptions{Callback: handlePullImageMessage}
	}

	registry, image, tag := splitImageName(name)
	if registry == "" {
		return fmt.Errorf("no registry given")
	}

	buf := &bytes.Buffer{}
	buf.WriteString(FAKE_AUTH)
	url := dh.Address + "/images/" + registry + "/" + image + "/push?tag=" + tag

	rsp, e := dh.postWithReader(url, buf)
	if e != nil {
		return e
	}
	defer rsp.Body.Close()

	return handleJSONStream(rsp.Body, opts.Callback)
}

// Delete the given image from the docker host.
func (dh *Client) DeleteImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	req, e := http.NewRequest("DELETE", dh.Address+"/images/"+name, nil)
	if e != nil {
		return e
	}

	resp, e := dh.Client.Do(req)
	if e != nil {
		return e
	}
	defer resp.Body.Close()

	if !success(resp) {
		return fmt.Errorf("failed to delete image %s", name)
	}
	return nil
}

func (self *Client) createDockerfileArchive(dockerfile string) (buf *bytes.Buffer, e error) {
	body := []byte(dockerfile)
	buf = new(bytes.Buffer)
	tw := tar.NewWriter(buf)
	header := &tar.Header{Name: "Dockerfile", Size: int64(len(body))}
	if e = tw.WriteHeader(header); e != nil {
		return nil, e
	}
	if _, e = tw.Write(body); e != nil {
		return nil, e
	}
	if e = tw.Close(); e != nil {
		return nil, e
	}
	return buf, nil
}

func (dh *Client) waitForTag(repository, tag string, timeout int) error {
	for {
		_, e := dh.ImageDetails(repository + ":" + tag)
		if e != nil {
			if e.Error() == "resource not found" {
				time.Sleep(1 * time.Second)
				continue
			}
			return e
		}
		return nil
	}
}

// Every image is named after the following pattern:
//   <registry>/<repository>:<tag>
// with registry being of the form "<hostname>:<port>" and repository being a string of [A-Za-z0-9_].
func splitImageName(name string) (registry, repository, tag string) {
	s := imageNameRegexp.FindStringSubmatch(name)
	if len(s[3]) > 0 {
		tag = s[3][1:]
	}
	repository = s[2]
	if len(s[1]) > 0 {
		registry = s[1][0 : len(s[1])-1]
	}
	return registry, repository, tag
}
<|endoftext|>


<commit_before>package search

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"

	iopt "github.com/algolia/algoliasearch-client-go/algolia/internal/opt"
	"github.com/algolia/algoliasearch-client-go/algolia/opt"
	"github.com/algolia/algoliasearch-client-go/algolia/transport"
)

func GenerateSecuredAPIKey(apiKey string, opts ...interface{}) (key string, err error) {
	message := transport.URLEncode(newSecuredAPIKeyParams(opts...))

	h := hmac.New(sha256.New, []byte(apiKey))
	h.Write([]byte(message))
	securedKey := hex.EncodeToString(h.Sum(nil))

	key = base64.StdEncoding.EncodeToString([]byte(securedKey + message))
	return
}

type securedAPIKeyParams struct {
	Referers        *opt.ReferersOption        `json:"referers,omitempty"`
	RestrictIndices *opt.RestrictIndicesOption `json:"restrictIndices,omitempty"`
	RestrictSources *opt.RestrictSourcesOption `json:"restrictSources,omitempty"`
	UserToken       *opt.UserTokenOption       `json:"userToken,omitempty"`
	ValidUntil      int64                      `json:"validUntil,omitempty"`
	QueryParams
}

func newSecuredAPIKeyParams(opts ...interface{}) securedAPIKeyParams {
	var validUntilInt int64
	if validUntil := iopt.ExtractValidUntil(opts...); validUntil != nil {
		validUntilInt = validUntil.Get().Unix()
	}
	return securedAPIKeyParams{
		Referers:        iopt.ExtractReferers(opts...),
		RestrictIndices: iopt.ExtractRestrictIndices(opts...),
		RestrictSources: iopt.ExtractRestrictSources(opts...),
		UserToken:       iopt.ExtractUserToken(opts...),
		ValidUntil:      validUntilInt,
		QueryParams:     newQueryParams(opts...),
	}
}
<commit_msg>fixed: correctly handle HMAC error on writing checksum<commit_after>package search

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"

	iopt "github.com/algolia/algoliasearch-client-go/algolia/internal/opt"
	"github.com/algolia/algoliasearch-client-go/algolia/opt"
	"github.com/algolia/algoliasearch-client-go/algolia/transport"
)

func GenerateSecuredAPIKey(apiKey string, opts ...interface{}) (string, error) {
	h := hmac.New(sha256.New, []byte(apiKey))

	message := transport.URLEncode(newSecuredAPIKeyParams(opts...))
	_, err := h.Write([]byte(message))
	if err != nil {
		return "", err
	}

	checksum := hex.EncodeToString(h.Sum(nil))
	key := base64.StdEncoding.EncodeToString([]byte(checksum + message))

	return key, nil
}

type securedAPIKeyParams struct {
	Referers        *opt.ReferersOption        `json:"referers,omitempty"`
	RestrictIndices *opt.RestrictIndicesOption `json:"restrictIndices,omitempty"`
	RestrictSources *opt.RestrictSourcesOption `json:"restrictSources,omitempty"`
	UserToken       *opt.UserTokenOption       `json:"userToken,omitempty"`
	ValidUntil      int64                      `json:"validUntil,omitempty"`
	QueryParams
}

func newSecuredAPIKeyParams(opts ...interface{}) securedAPIKeyParams {
	var validUntilInt int64
	if validUntil := iopt.ExtractValidUntil(opts...); validUntil != nil {
		validUntilInt = validUntil.Get().Unix()
	}
	return securedAPIKeyParams{
		Referers:        iopt.ExtractReferers(opts...),
		RestrictIndices: iopt.ExtractRestrictIndices(opts...),
		RestrictSources: iopt.ExtractRestrictSources(opts...),
		UserToken:       iopt.ExtractUserToken(opts...),
		ValidUntil:      validUntilInt,
		QueryParams:     newQueryParams(opts...),
	}
}
<|endoftext|>