<commit_before>package command

import (
	"fmt"
	"os"
	"strconv"
	"strings"
	"text/template"

	"github.com/timeglass/glass/_vendor/github.com/codegangsta/cli"
	"github.com/timeglass/glass/_vendor/github.com/hashicorp/errwrap"

	"github.com/timeglass/glass/config"
)

type Status struct {
	*command
}

func NewStatus() *Status {
	return &Status{newCommand()}
}

func (c *Status) Name() string {
	return "status"
}

func (c *Status) Description() string {
	return fmt.Sprintf("...")
}

func (c *Status) Usage() string {
	return "..."
}

func (c *Status) Flags() []cli.Flag {
	return []cli.Flag{
		cli.StringFlag{Name: "template,t", Value: "", Usage: "a template that allows for arbritary formatting of the time output"},
		cli.BoolFlag{Name: "commit-template", Usage: "use the commit template from the configuration, this overwrites and custom template using -t"},
	}
}

func (c *Status) Action() func(ctx *cli.Context) {
	return c.command.Action(c.Run)
}

func (c *Status) Run(ctx *cli.Context) error {
	dir, err := os.Getwd()
	if err != nil {
		return errwrap.Wrapf("Failed to fetch current working dir: {{err}}", err)
	}

	conf, err := config.ReadConfig(dir)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to read configuration: {{err}}"), err)
	}

	client := NewClient()

	c.Printf("Fetching daemon info...")
	dinfo, err := client.Info()
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to fetch daemon info, is it installed and running?: {{err}}"), err)
	}

	curr, _ := strconv.Atoi(strings.Replace(dinfo["newest_version"].(string), ".", "", 2))
	recent, _ := strconv.Atoi(strings.Replace(dinfo["version"].(string), ".", "", 2))
	if curr != 0 && recent > curr {
		c.Println("A new version is available, please upgrade: https://github.com/timeglass/glass/releases")
	}

	c.Printf("Fetching timer info...")

	timer, err := client.ReadTimer(dir)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to fetch timer: {{err}}"), err)
	}

	if reason := timer.HasFailed(); reason != "" {
		c.Printf("Timer has failed: %s", reason)
	} else {
		if timer.IsPaused() {
			c.Printf("Timer is currently: PAUSED")
		} else {
			c.Printf("Timer is currently: RUNNING")
		}
	}

	tmpls := ctx.String("template")
	if ctx.Bool("commit-template") {
		tmpls = conf.CommitMessage
	}

	//we got some template specified
	if tmpls != "" {

		//parse temlate and only report error if we're talking to a human
		tmpl, err := template.New("commit-msg").Parse(tmpls)
		if err != nil {
			return errwrap.Wrapf(fmt.Sprintf("Failed to parse commit_message: '%s' in configuration as a text/template: {{err}}", conf.CommitMessage), err)
		}

		//execute template and write to stdout
		err = tmpl.Execute(os.Stdout, timer.Time())
		if err != nil {
			return errwrap.Wrapf(fmt.Sprintf("Failed to execute commit_message: template for time '%s': {{err}}", timer.Time()), err)
		}

	} else {
		//just print
		c.Printf("Timer reads: %s", timer.Time())
	}

	return nil
}
<commit_msg>use actual version fields [spent 1m10s]<commit_after>package command

import (
	"fmt"
	"os"
	"strconv"
	"strings"
	"text/template"

	"github.com/timeglass/glass/_vendor/github.com/codegangsta/cli"
	"github.com/timeglass/glass/_vendor/github.com/hashicorp/errwrap"

	"github.com/timeglass/glass/config"
)

type Status struct {
	*command
}

func NewStatus() *Status {
	return &Status{newCommand()}
}

func (c *Status) Name() string {
	return "status"
}

func (c *Status) Description() string {
	return fmt.Sprintf("...")
}

func (c *Status) Usage() string {
	return "..."
}

func (c *Status) Flags() []cli.Flag {
	return []cli.Flag{
		cli.StringFlag{Name: "template,t", Value: "", Usage: "a template that allows for arbritary formatting of the time output"},
		cli.BoolFlag{Name: "commit-template", Usage: "use the commit template from the configuration, this overwrites and custom template using -t"},
	}
}

func (c *Status) Action() func(ctx *cli.Context) {
	return c.command.Action(c.Run)
}

func (c *Status) Run(ctx *cli.Context) error {
	dir, err := os.Getwd()
	if err != nil {
		return errwrap.Wrapf("Failed to fetch current working dir: {{err}}", err)
	}

	conf, err := config.ReadConfig(dir)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to read configuration: {{err}}"), err)
	}

	client := NewClient()

	c.Printf("Fetching daemon info...")
	dinfo, err := client.Info()
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to fetch daemon info, is it installed and running?: {{err}}"), err)
	}

	curr, _ := strconv.Atoi(strings.Replace(dinfo["version"].(string), ".", "", 2))
	recent, _ := strconv.Atoi(strings.Replace(dinfo["newest_version"].(string), ".", "", 2))
	if curr != 0 && recent > curr {
		c.Println("A new version is available, please upgrade: https://github.com/timeglass/glass/releases")
	}

	c.Printf("Fetching timer info...")

	timer, err := client.ReadTimer(dir)
	if err != nil {
		return errwrap.Wrapf(fmt.Sprintf("Failed to fetch timer: {{err}}"), err)
	}

	if reason := timer.HasFailed(); reason != "" {
		c.Printf("Timer has failed: %s", reason)
	} else {
		if timer.IsPaused() {
			c.Printf("Timer is currently: PAUSED")
		} else {
			c.Printf("Timer is currently: RUNNING")
		}
	}

	tmpls := ctx.String("template")
	if ctx.Bool("commit-template") {
		tmpls = conf.CommitMessage
	}

	//we got some template specified
	if tmpls != "" {

		//parse temlate and only report error if we're talking to a human
		tmpl, err := template.New("commit-msg").Parse(tmpls)
		if err != nil {
			return errwrap.Wrapf(fmt.Sprintf("Failed to parse commit_message: '%s' in configuration as a text/template: {{err}}", conf.CommitMessage), err)
		}

		//execute template and write to stdout
		err = tmpl.Execute(os.Stdout, timer.Time())
		if err != nil {
			return errwrap.Wrapf(fmt.Sprintf("Failed to execute commit_message: template for time '%s': {{err}}", timer.Time()), err)
		}

	} else {
		//just print
		c.Printf("Timer reads: %s", timer.Time())
	}

	return nil
}
<|endoftext|>


<commit_before>package dockerclient

import "time"

type ContainerConfig struct {
	Hostname        string
	Domainname      string
	User            string
	Memory          int64
	MemorySwap      int64
	CpuShares       int64
	Cpuset          string
	AttachStdin     bool
	AttachStdout    bool
	AttachStderr    bool
	PortSpecs       []string
	ExposedPorts    map[string]struct{}
	Tty             bool
	OpenStdin       bool
	StdinOnce       bool
	Env             []string
	Cmd             []string
	Image           string
	Labels          map[string]string
	Volumes         map[string]struct{}
	WorkingDir      string
	Entrypoint      []string
	NetworkDisabled bool
	OnBuild         []string

	// This is used only by the create command
	HostConfig HostConfig
}

type HostConfig struct {
	Binds           []string
	ContainerIDFile string
	LxcConf         []map[string]string
	Privileged      bool
	PortBindings    map[string][]PortBinding
	Links           []string
	PublishAllPorts bool
	Dns             []string
	DnsSearch       []string
	VolumesFrom     []string
	SecurityOpt     []string
	NetworkMode     string
	RestartPolicy   RestartPolicy
}

type ExecConfig struct {
	AttachStdin  bool
	AttachStdout bool
	AttachStderr bool
	Tty          bool
	Cmd          []string
	Container    string
	Detach       bool
}

type LogOptions struct {
	Follow     bool
	Stdout     bool
	Stderr     bool
	Timestamps bool
	Tail       int64
}

type RestartPolicy struct {
	Name              string
	MaximumRetryCount int64
}

type PortBinding struct {
	HostIp   string
	HostPort string
}

type ContainerInfo struct {
	Id      string
	Created string
	Path    string
	Name    string
	Args    []string
	ExecIDs []string
	Config  *ContainerConfig
	State   struct {
		Running    bool
		Paused     bool
		Restarting bool
		Pid        int
		ExitCode   int
		StartedAt  time.Time
		FinishedAt time.Time
		Ghost      bool
	}
	Image           string
	NetworkSettings struct {
		IpAddress   string
		IpPrefixLen int
		Gateway     string
		Bridge      string
		Ports       map[string][]PortBinding
	}
	SysInitPath    string
	ResolvConfPath string
	Volumes        map[string]string
	HostConfig     *HostConfig
}

type ContainerChanges struct {
	Path string
	Kind int
}

type Port struct {
	IP          string
	PrivatePort int
	PublicPort  int
	Type        string
}

type Container struct {
	Id         string
	Names      []string
	Image      string
	Command    string
	Created    int64
	Status     string
	Ports      []Port
	SizeRw     int64
	SizeRootFs int64
}

type Event struct {
	Id     string
	Status string
	From   string
	Time   int64
}

type Version struct {
	Version   string
	GitCommit string
	GoVersion string
}

type RespContainersCreate struct {
	Id       string
	Warnings []string
}

type Image struct {
	Created     int64
	Id          string
	ParentId    string
	RepoTags    []string
	Size        int64
	VirtualSize int64
}

type Info struct {
	ID              string
	Containers      int64
	Driver          string
	DriverStatus    [][]string
	ExecutionDriver string
	Images          int64
	KernelVersion   string
	OperatingSystem string
	NCPU            int64
	MemTotal        int64
	Name            string
	Labels          []string
}

type ImageDelete struct {
	Deleted  string
	Untagged string
}

// The following are types for the API stats endpoint
type ThrottlingData struct {
	// Number of periods with throttling active
	Periods uint64 `json:"periods"`
	// Number of periods when the container hit its throttling limit.
	ThrottledPeriods uint64 `json:"throttled_periods"`
	// Aggregate time the container was throttled for in nanoseconds.
	ThrottledTime uint64 `json:"throttled_time"`
}

type CpuUsage struct {
	// Total CPU time consumed.
	// Units: nanoseconds.
	TotalUsage uint64 `json:"total_usage"`
	// Total CPU time consumed per core.
	// Units: nanoseconds.
	PercpuUsage []uint64 `json:"percpu_usage"`
	// Time spent by tasks of the cgroup in kernel mode.
	// Units: nanoseconds.
	UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
	// Time spent by tasks of the cgroup in user mode.
	// Units: nanoseconds.
	UsageInUsermode uint64 `json:"usage_in_usermode"`
}

type CpuStats struct {
	CpuUsage       CpuUsage       `json:"cpu_usage"`
	SystemUsage    uint64         `json:"system_cpu_usage"`
	ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
}

type NetworkStats struct {
	RxBytes   uint64 `json:"rx_bytes"`
	RxPackets uint64 `json:"rx_packets"`
	RxErrors  uint64 `json:"rx_errors"`
	RxDropped uint64 `json:"rx_dropped"`
	TxBytes   uint64 `json:"tx_bytes"`
	TxPackets uint64 `json:"tx_packets"`
	TxErrors  uint64 `json:"tx_errors"`
	TxDropped uint64 `json:"tx_dropped"`
}

type MemoryStats struct {
	Usage    uint64            `json:"usage"`
	MaxUsage uint64            `json:"max_usage"`
	Stats    map[string]uint64 `json:"stats"`
	Failcnt  uint64            `json:"failcnt"`
	Limit    uint64            `json:"limit"`
}

type BlkioStatEntry struct {
	Major uint64 `json:"major"`
	Minor uint64 `json:"minor"`
	Op    string `json:"op"`
	Value uint64 `json:"value"`
}

type BlkioStats struct {
	// number of bytes tranferred to and from the block device
	IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive"`
	IoServicedRecursive     []BlkioStatEntry `json:"io_serviced_recursive"`
	IoQueuedRecursive       []BlkioStatEntry `json:"io_queue_recursive"`
	IoServiceTimeRecursive  []BlkioStatEntry `json:"io_service_time_recursive"`
	IoWaitTimeRecursive     []BlkioStatEntry `json:"io_wait_time_recursive"`
	IoMergedRecursive       []BlkioStatEntry `json:"io_merged_recursive"`
	IoTimeRecursive         []BlkioStatEntry `json:"io_time_recursive"`
	SectorsRecursive        []BlkioStatEntry `json:"sectors_recursive"`
}

type Stats struct {
	Read         time.Time    `json:"read"`
	NetworkStats NetworkStats `json:"network,omitempty"`
	CpuStats     CpuStats     `json:"cpu_stats,omitempty"`
	MemoryStats  MemoryStats  `json:"memory_stats,omitempty"`
	BlkioStats   BlkioStats   `json:"blkio_stats,omitempty"`
}
<commit_msg>Fix golint issues for IP* members.<commit_after>package dockerclient

import "time"

type ContainerConfig struct {
	Hostname        string
	Domainname      string
	User            string
	Memory          int64
	MemorySwap      int64
	CpuShares       int64
	Cpuset          string
	AttachStdin     bool
	AttachStdout    bool
	AttachStderr    bool
	PortSpecs       []string
	ExposedPorts    map[string]struct{}
	Tty             bool
	OpenStdin       bool
	StdinOnce       bool
	Env             []string
	Cmd             []string
	Image           string
	Labels          map[string]string
	Volumes         map[string]struct{}
	WorkingDir      string
	Entrypoint      []string
	NetworkDisabled bool
	OnBuild         []string

	// This is used only by the create command
	HostConfig HostConfig
}

type HostConfig struct {
	Binds           []string
	ContainerIDFile string
	LxcConf         []map[string]string
	Privileged      bool
	PortBindings    map[string][]PortBinding
	Links           []string
	PublishAllPorts bool
	Dns             []string
	DnsSearch       []string
	VolumesFrom     []string
	SecurityOpt     []string
	NetworkMode     string
	RestartPolicy   RestartPolicy
}

type ExecConfig struct {
	AttachStdin  bool
	AttachStdout bool
	AttachStderr bool
	Tty          bool
	Cmd          []string
	Container    string
	Detach       bool
}

type LogOptions struct {
	Follow     bool
	Stdout     bool
	Stderr     bool
	Timestamps bool
	Tail       int64
}

type RestartPolicy struct {
	Name              string
	MaximumRetryCount int64
}

type PortBinding struct {
	HostIp   string
	HostPort string
}

type ContainerInfo struct {
	Id      string
	Created string
	Path    string
	Name    string
	Args    []string
	ExecIDs []string
	Config  *ContainerConfig
	State   struct {
		Running    bool
		Paused     bool
		Restarting bool
		Pid        int
		ExitCode   int
		StartedAt  time.Time
		FinishedAt time.Time
		Ghost      bool
	}
	Image           string
	NetworkSettings struct {
		IPAddress   string `json:"IpAddress"`
		IPPrefixLen int    `json:"IpPrefixLen"`
		Gateway     string
		Bridge      string
		Ports       map[string][]PortBinding
	}
	SysInitPath    string
	ResolvConfPath string
	Volumes        map[string]string
	HostConfig     *HostConfig
}

type ContainerChanges struct {
	Path string
	Kind int
}

type Port struct {
	IP          string
	PrivatePort int
	PublicPort  int
	Type        string
}

type Container struct {
	Id         string
	Names      []string
	Image      string
	Command    string
	Created    int64
	Status     string
	Ports      []Port
	SizeRw     int64
	SizeRootFs int64
}

type Event struct {
	Id     string
	Status string
	From   string
	Time   int64
}

type Version struct {
	Version   string
	GitCommit string
	GoVersion string
}

type RespContainersCreate struct {
	Id       string
	Warnings []string
}

type Image struct {
	Created     int64
	Id          string
	ParentId    string
	RepoTags    []string
	Size        int64
	VirtualSize int64
}

type Info struct {
	ID              string
	Containers      int64
	Driver          string
	DriverStatus    [][]string
	ExecutionDriver string
	Images          int64
	KernelVersion   string
	OperatingSystem string
	NCPU            int64
	MemTotal        int64
	Name            string
	Labels          []string
}

type ImageDelete struct {
	Deleted  string
	Untagged string
}

// The following are types for the API stats endpoint
type ThrottlingData struct {
	// Number of periods with throttling active
	Periods uint64 `json:"periods"`
	// Number of periods when the container hit its throttling limit.
	ThrottledPeriods uint64 `json:"throttled_periods"`
	// Aggregate time the container was throttled for in nanoseconds.
	ThrottledTime uint64 `json:"throttled_time"`
}

type CpuUsage struct {
	// Total CPU time consumed.
	// Units: nanoseconds.
	TotalUsage uint64 `json:"total_usage"`
	// Total CPU time consumed per core.
	// Units: nanoseconds.
	PercpuUsage []uint64 `json:"percpu_usage"`
	// Time spent by tasks of the cgroup in kernel mode.
	// Units: nanoseconds.
	UsageInKernelmode uint64 `json:"usage_in_kernelmode"`
	// Time spent by tasks of the cgroup in user mode.
	// Units: nanoseconds.
	UsageInUsermode uint64 `json:"usage_in_usermode"`
}

type CpuStats struct {
	CpuUsage       CpuUsage       `json:"cpu_usage"`
	SystemUsage    uint64         `json:"system_cpu_usage"`
	ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
}

type NetworkStats struct {
	RxBytes   uint64 `json:"rx_bytes"`
	RxPackets uint64 `json:"rx_packets"`
	RxErrors  uint64 `json:"rx_errors"`
	RxDropped uint64 `json:"rx_dropped"`
	TxBytes   uint64 `json:"tx_bytes"`
	TxPackets uint64 `json:"tx_packets"`
	TxErrors  uint64 `json:"tx_errors"`
	TxDropped uint64 `json:"tx_dropped"`
}

type MemoryStats struct {
	Usage    uint64            `json:"usage"`
	MaxUsage uint64            `json:"max_usage"`
	Stats    map[string]uint64 `json:"stats"`
	Failcnt  uint64            `json:"failcnt"`
	Limit    uint64            `json:"limit"`
}

type BlkioStatEntry struct {
	Major uint64 `json:"major"`
	Minor uint64 `json:"minor"`
	Op    string `json:"op"`
	Value uint64 `json:"value"`
}

type BlkioStats struct {
	// number of bytes tranferred to and from the block device
	IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive"`
	IoServicedRecursive     []BlkioStatEntry `json:"io_serviced_recursive"`
	IoQueuedRecursive       []BlkioStatEntry `json:"io_queue_recursive"`
	IoServiceTimeRecursive  []BlkioStatEntry `json:"io_service_time_recursive"`
	IoWaitTimeRecursive     []BlkioStatEntry `json:"io_wait_time_recursive"`
	IoMergedRecursive       []BlkioStatEntry `json:"io_merged_recursive"`
	IoTimeRecursive         []BlkioStatEntry `json:"io_time_recursive"`
	SectorsRecursive        []BlkioStatEntry `json:"sectors_recursive"`
}

type Stats struct {
	Read         time.Time    `json:"read"`
	NetworkStats NetworkStats `json:"network,omitempty"`
	CpuStats     CpuStats     `json:"cpu_stats,omitempty"`
	MemoryStats  MemoryStats  `json:"memory_stats,omitempty"`
	BlkioStats   BlkioStats   `json:"blkio_stats,omitempty"`
}
<|endoftext|>


<commit_before>package tgbotapi

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
)

// APIResponse is a response from the Telegram API with the result stored raw.
type APIResponse struct {
	Ok          bool            `json:"ok"`
	Result      json.RawMessage `json:"result"`
	ErrorCode   int             `json:"error_code"`
	Description string          `json:"description"`
}

// Update is an update response, from GetUpdates.
type Update struct {
	UpdateID int     `json:"update_id"`
	Message  Message `json:"message"`
}

// User is a user, contained in Message and returned by GetSelf.
type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	UserName  string `json:"username"`
}

// String displays a simple text version of a user.
// It is normally a user's username,
// but falls back to a first/last name as available.
func (u *User) String() string {
	if u.UserName != "" {
		return u.UserName
	}

	name := u.FirstName
	if u.LastName != "" {
		name += " " + u.LastName
	}

	return name
}

// GroupChat is a group chat, and not currently in use.
type GroupChat struct {
	ID    int    `json:"id"`
	Title string `json:"title"`
}

// Chat is returned in Message, it contains information about the Chat a message was sent in.
type Chat struct {
	ID        int    `json:"id"`
	Type      string `json:"type"`
	Title     string `json:"title"`
	UserName  string `json:"username"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
}

// IsPrivate returns true if the Chat is a private conversation
func (c *Chat) IsPrivate() bool {
	return c.Type == "private"
}

// IsGroup returns true if the Chat is a group conversation
func (c *Chat) IsGroup() bool {
	return c.Type == "group"
}

// IsChannel returns true if the Chat is a channel
func (c *Chat) IsChannel() bool {
	return c.Type == "channel"
}

// Message is returned by almost every request, and contains data about almost anything.
type Message struct {
	MessageID           int         `json:"message_id"`
	From                User        `json:"from"`
	Date                int         `json:"date"`
	Chat                Chat        `json:"chat"`
	ForwardFrom         User        `json:"forward_from"`
	ForwardDate         int         `json:"forward_date"`
	ReplyToMessage      *Message    `json:"reply_to_message"`
	Text                string      `json:"text"`
	Audio               Audio       `json:"audio"`
	Document            Document    `json:"document"`
	Photo               []PhotoSize `json:"photo"`
	Sticker             Sticker     `json:"sticker"`
	Video               Video       `json:"video"`
	Voice               Voice       `json:"voice"`
	Caption             string      `json:"caption"`
	Contact             Contact     `json:"contact"`
	Location            Location    `json:"location"`
	NewChatParticipant  User        `json:"new_chat_participant"`
	LeftChatParticipant User        `json:"left_chat_participant"`
	NewChatTitle        string      `json:"new_chat_title"`
	NewChatPhoto        []PhotoSize `json:"new_chat_photo"`
	DeleteChatPhoto     bool        `json:"delete_chat_photo"`
	GroupChatCreated    bool        `json:"group_chat_created"`
}

// Time converts the message timestamp into a Time.
func (m *Message) Time() time.Time {
	return time.Unix(int64(m.Date), 0)
}

// IsGroup returns if the message was sent to a group.
func (m *Message) IsGroup() bool {
	return m.From.ID != m.Chat.ID
}

// IsCommand returns true if message starts from /
func (m *Message) IsCommand() bool {
	return m.Text != "" && m.Text[0] == '/'
}

// Command returns first word from message
func (m *Message) Command() string {
	return strings.Split(m.Text, " ")[0]
}

// PhotoSize contains information about photos, including ID and Width and Height.
type PhotoSize struct {
	FileID   string `json:"file_id"`
	Width    int    `json:"width"`
	Height   int    `json:"height"`
	FileSize int    `json:"file_size"`
}

// Audio contains information about audio,
// including ID, Duration, Performer and Title.
type Audio struct {
	FileID    string `json:"file_id"`
	Duration  int    `json:"duration"`
	Performer string `json:"performer"`
	Title     string `json:"title"`
	MimeType  string `json:"mime_type"`
	FileSize  int    `json:"file_size"`
}

// Document contains information about a document, including ID and a Thumbnail.
type Document struct {
	FileID    string    `json:"file_id"`
	Thumbnail PhotoSize `json:"thumb"`
	FileName  string    `json:"file_name"`
	MimeType  string    `json:"mime_type"`
	FileSize  int       `json:"file_size"`
}

// Sticker contains information about a sticker, including ID and Thumbnail.
type Sticker struct {
	FileID    string    `json:"file_id"`
	Width     int       `json:"width"`
	Height    int       `json:"height"`
	Thumbnail PhotoSize `json:"thumb"`
	FileSize  int       `json:"file_size"`
}

// Video contains information about a video, including ID and duration and Thumbnail.
type Video struct {
	FileID    string    `json:"file_id"`
	Width     int       `json:"width"`
	Height    int       `json:"height"`
	Duration  int       `json:"duration"`
	Thumbnail PhotoSize `json:"thumb"`
	MimeType  string    `json:"mime_type"`
	FileSize  int       `json:"file_size"`
}

// Voice contains information about a voice, including ID and duration.
type Voice struct {
	FileID   string `json:"file_id"`
	Duration int    `json:"duration"`
	MimeType string `json:"mime_type"`
	FileSize int    `json:"file_size"`
}

// Contact contains information about a contact, such as PhoneNumber and UserId.
type Contact struct {
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
	UserID      int    `json:"user_id"`
}

// Location contains information about a place, such as Longitude and Latitude.
type Location struct {
	Longitude float32 `json:"longitude"`
	Latitude  float32 `json:"latitude"`
}

// UserProfilePhotos contains information a set of user profile photos.
type UserProfilePhotos struct {
	TotalCount int         `json:"total_count"`
	Photos     []PhotoSize `json:"photos"`
}

// File contains information about a file to download from Telegram
type File struct {
	FileID   string `json:"file_id"`
	FileSize int    `json:"file_size"`
	FilePath string `json:"file_path"`
}

// Link returns a full path to the download URL for a File.
//
// It requires the Bot Token to create the link.
func (f *File) Link(token string) string {
	return fmt.Sprintf(FileEndpoint, token, f.FilePath)
}

// ReplyKeyboardMarkup allows the Bot to set a custom keyboard.
type ReplyKeyboardMarkup struct {
	Keyboard        [][]string `json:"keyboard"`
	ResizeKeyboard  bool       `json:"resize_keyboard"`
	OneTimeKeyboard bool       `json:"one_time_keyboard"`
	Selective       bool       `json:"selective"`
}

// ReplyKeyboardHide allows the Bot to hide a custom keyboard.
type ReplyKeyboardHide struct {
	HideKeyboard bool `json:"hide_keyboard"`
	Selective    bool `json:"selective"`
}

// ForceReply allows the Bot to have users directly reply to it without additional interaction.
type ForceReply struct {
	ForceReply bool `json:"force_reply"`
	Selective  bool `json:"selective"`
}
<commit_msg>update Message struct for new fields, add IsSuperGroup to Chat struct<commit_after>package tgbotapi

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
)

// APIResponse is a response from the Telegram API with the result stored raw.
type APIResponse struct {
	Ok          bool            `json:"ok"`
	Result      json.RawMessage `json:"result"`
	ErrorCode   int             `json:"error_code"`
	Description string          `json:"description"`
}

// Update is an update response, from GetUpdates.
type Update struct {
	UpdateID int     `json:"update_id"`
	Message  Message `json:"message"`
}

// User is a user, contained in Message and returned by GetSelf.
type User struct {
	ID        int    `json:"id"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	UserName  string `json:"username"`
}

// String displays a simple text version of a user.
// It is normally a user's username,
// but falls back to a first/last name as available.
func (u *User) String() string {
	if u.UserName != "" {
		return u.UserName
	}

	name := u.FirstName
	if u.LastName != "" {
		name += " " + u.LastName
	}

	return name
}

// GroupChat is a group chat, and not currently in use.
type GroupChat struct {
	ID    int    `json:"id"`
	Title string `json:"title"`
}

// Chat is returned in Message, it contains information about the Chat a message was sent in.
type Chat struct {
	ID        int    `json:"id"`
	Type      string `json:"type"`
	Title     string `json:"title"`
	UserName  string `json:"username"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
}

// IsPrivate returns true if the Chat is a private conversation
func (c *Chat) IsPrivate() bool {
	return c.Type == "private"
}

// IsGroup returns true if the Chat is a group conversation
func (c *Chat) IsGroup() bool {
	return c.Type == "group"
}

// IsSuperGroup returns true if the Chat is a supergroup conversation
func (c *Chat) IsSuperGroup() bool {
	return c.Type == "supergroup"
}

// IsChannel returns true if the Chat is a channel
func (c *Chat) IsChannel() bool {
	return c.Type == "channel"
}

// Message is returned by almost every request, and contains data about almost anything.
type Message struct {
	MessageID             int         `json:"message_id"`
	From                  User        `json:"from"`
	Date                  int         `json:"date"`
	Chat                  Chat        `json:"chat"`
	ForwardFrom           User        `json:"forward_from"`
	ForwardDate           int         `json:"forward_date"`
	ReplyToMessage        *Message    `json:"reply_to_message"`
	Text                  string      `json:"text"`
	Audio                 Audio       `json:"audio"`
	Document              Document    `json:"document"`
	Photo                 []PhotoSize `json:"photo"`
	Sticker               Sticker     `json:"sticker"`
	Video                 Video       `json:"video"`
	Voice                 Voice       `json:"voice"`
	Caption               string      `json:"caption"`
	Contact               Contact     `json:"contact"`
	Location              Location    `json:"location"`
	NewChatParticipant    User        `json:"new_chat_participant"`
	LeftChatParticipant   User        `json:"left_chat_participant"`
	NewChatTitle          string      `json:"new_chat_title"`
	NewChatPhoto          []PhotoSize `json:"new_chat_photo"`
	DeleteChatPhoto       bool        `json:"delete_chat_photo"`
	GroupChatCreated      bool        `json:"group_chat_created"`
	SuperGroupChatCreated bool        `json:"supergroup_chat_created"`
	ChannelChatCreated    bool        `json:"channel_chat_created"`
	MigrateToChatID       int         `json:"migrate_to_chat_id"`
	MigrateFromChatID     int         `json:"migrate_from_chat_id"`
}

// Time converts the message timestamp into a Time.
func (m *Message) Time() time.Time {
	return time.Unix(int64(m.Date), 0)
}

// IsGroup returns if the message was sent to a group.
func (m *Message) IsGroup() bool {
	return m.Chat.IsGroup()
}

// IsCommand returns true if message starts from /
func (m *Message) IsCommand() bool {
	return m.Text != "" && m.Text[0] == '/'
}

// Command returns first word from message
func (m *Message) Command() string {
	return strings.Split(m.Text, " ")[0]
}

// PhotoSize contains information about photos, including ID and Width and Height.
type PhotoSize struct {
	FileID   string `json:"file_id"`
	Width    int    `json:"width"`
	Height   int    `json:"height"`
	FileSize int    `json:"file_size"`
}

// Audio contains information about audio,
// including ID, Duration, Performer and Title.
type Audio struct {
	FileID    string `json:"file_id"`
	Duration  int    `json:"duration"`
	Performer string `json:"performer"`
	Title     string `json:"title"`
	MimeType  string `json:"mime_type"`
	FileSize  int    `json:"file_size"`
}

// Document contains information about a document, including ID and a Thumbnail.
type Document struct {
	FileID    string    `json:"file_id"`
	Thumbnail PhotoSize `json:"thumb"`
	FileName  string    `json:"file_name"`
	MimeType  string    `json:"mime_type"`
	FileSize  int       `json:"file_size"`
}

// Sticker contains information about a sticker, including ID and Thumbnail.
type Sticker struct {
	FileID    string    `json:"file_id"`
	Width     int       `json:"width"`
	Height    int       `json:"height"`
	Thumbnail PhotoSize `json:"thumb"`
	FileSize  int       `json:"file_size"`
}

// Video contains information about a video, including ID and duration and Thumbnail.
type Video struct {
	FileID    string    `json:"file_id"`
	Width     int       `json:"width"`
	Height    int       `json:"height"`
	Duration  int       `json:"duration"`
	Thumbnail PhotoSize `json:"thumb"`
	MimeType  string    `json:"mime_type"`
	FileSize  int       `json:"file_size"`
}

// Voice contains information about a voice, including ID and duration.
type Voice struct {
	FileID   string `json:"file_id"`
	Duration int    `json:"duration"`
	MimeType string `json:"mime_type"`
	FileSize int    `json:"file_size"`
}

// Contact contains information about a contact, such as PhoneNumber and UserId.
type Contact struct {
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
	UserID      int    `json:"user_id"`
}

// Location contains information about a place, such as Longitude and Latitude.
type Location struct {
	Longitude float32 `json:"longitude"`
	Latitude  float32 `json:"latitude"`
}

// UserProfilePhotos contains information a set of user profile photos.
type UserProfilePhotos struct {
	TotalCount int         `json:"total_count"`
	Photos     []PhotoSize `json:"photos"`
}

// File contains information about a file to download from Telegram
type File struct {
	FileID   string `json:"file_id"`
	FileSize int    `json:"file_size"`
	FilePath string `json:"file_path"`
}

// Link returns a full path to the download URL for a File.
//
// It requires the Bot Token to create the link.
func (f *File) Link(token string) string {
	return fmt.Sprintf(FileEndpoint, token, f.FilePath)
}

// ReplyKeyboardMarkup allows the Bot to set a custom keyboard.
type ReplyKeyboardMarkup struct {
	Keyboard        [][]string `json:"keyboard"`
	ResizeKeyboard  bool       `json:"resize_keyboard"`
	OneTimeKeyboard bool       `json:"one_time_keyboard"`
	Selective       bool       `json:"selective"`
}

// ReplyKeyboardHide allows the Bot to hide a custom keyboard.
type ReplyKeyboardHide struct {
	HideKeyboard bool `json:"hide_keyboard"`
	Selective    bool `json:"selective"`
}

// ForceReply allows the Bot to have users directly reply to it without additional interaction.
type ForceReply struct {
	ForceReply bool `json:"force_reply"`
	Selective  bool `json:"selective"`
}
<|endoftext|>


<commit_before>package gocsv

import (
	"encoding"
	"fmt"
	"reflect"
	"strconv"
)

// --------------------------------------------------------------------------
// Conversion interfaces

// TypeMarshaller is implemented by any value that has a MarshalCSV method
// This converter is used to convert the value to it string representation
type TypeMarshaller interface {
	MarshalCSV() (string, error)
}

// Stringer is implemented by any value that has a String method
// This converter is used to convert the value to it string representation
// This converter will be used if your value does not implement TypeMarshaller
type Stringer interface {
	String() string
}

// TypeUnmarshaller is implemented by any value that has an UnmarshalCSV method
// This converter is used to convert a string to your value representation of that string
type TypeUnmarshaller interface {
	UnmarshalCSV(string) error
}

var (
	stringerType        = reflect.TypeOf((*Stringer)(nil)).Elem()
	marshallerType      = reflect.TypeOf((*TypeMarshaller)(nil)).Elem()
	unMarshallerType    = reflect.TypeOf((*TypeUnmarshaller)(nil)).Elem()
	textMarshalerType   = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
	textUnMarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
)

// --------------------------------------------------------------------------
// Conversion helpers

func toString(in interface{}) (string, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		return inValue.String(), nil
	case reflect.Bool:
		b := inValue.Bool()
		if b {
			return "true", nil
		}
		return "false", nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return fmt.Sprintf("%v", inValue.Int()), nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return fmt.Sprintf("%v", inValue.Uint()), nil
	case reflect.Float32, reflect.Float64:
		return strconv.FormatFloat(inValue.Float(), byte('f'), 64, 64), nil
	}
	return "", fmt.Errorf("No known conversion from " + inValue.Type().String() + " to string")
}

func toBool(in interface{}) (bool, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		s := inValue.String()
		if s == "true" || s == "yes" || s == "1" {
			return true, nil
		} else if s == "false" || s == "no" || s == "0" {
			return false, nil
		}
	case reflect.Bool:
		return inValue.Bool(), nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		i := inValue.Int()
		if i != 0 {
			return true, nil
		}
		return false, nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		i := inValue.Uint()
		if i != 0 {
			return true, nil
		}
		return false, nil
	case reflect.Float32, reflect.Float64:
		f := inValue.Float()
		if f != 0 {
			return true, nil
		}
		return false, nil
	}
	return false, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to bool")
}

func toInt(in interface{}) (int64, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		return strconv.ParseInt(inValue.String(), 0, 64)
	case reflect.Bool:
		if inValue.Bool() {
			return 1, nil
		}
		return 0, nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return inValue.Int(), nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return int64(inValue.Uint()), nil
	case reflect.Float32, reflect.Float64:
		return int64(inValue.Float()), nil
	}
	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to int")
}

func toUint(in interface{}) (uint64, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		return strconv.ParseUint(inValue.String(), 0, 64)
	case reflect.Bool:
		if inValue.Bool() {
			return 1, nil
		}
		return 0, nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return uint64(inValue.Int()), nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return inValue.Uint(), nil
	case reflect.Float32, reflect.Float64:
		return uint64(inValue.Float()), nil
	}
	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to uint")
}

func toFloat(in interface{}) (float64, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		return strconv.ParseFloat(inValue.String(), 64)
	case reflect.Bool:
		if inValue.Bool() {
			return 1, nil
		}
		return 0, nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return float64(inValue.Int()), nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return float64(inValue.Uint()), nil
	case reflect.Float32, reflect.Float64:
		return inValue.Float(), nil
	}
	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to float")
}

func setField(field reflect.Value, value string) error {
	switch field.Kind() {
	case reflect.String:
		s, err := toString(value)
		if err != nil {
			return err
		}
		field.SetString(s)
	case reflect.Bool:
		b, err := toBool(value)
		if err != nil {
			return err
		}
		field.SetBool(b)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		i, err := toInt(value)
		if err != nil {
			return err
		}
		field.SetInt(i)
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		ui, err := toUint(value)
		if err != nil {
			return err
		}
		field.SetUint(ui)
	case reflect.Float32, reflect.Float64:
		f, err := toFloat(value)
		if err != nil {
			return err
		}
		field.SetFloat(f)
	default:
		return unmarshall(field, value)
	}
	return nil
}

func getFieldAsString(field reflect.Value) (str string, err error) {
	switch field.Kind() {
	case reflect.String:
		return field.String(), nil
	case reflect.Bool:
		str, err = toString(field.Bool())
		if err != nil {
			return str, err
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		str, err = toString(field.Int())
		if err != nil {
			return str, err
		}
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		str, err = toString(field.Uint())
		if err != nil {
			return str, err
		}
	case reflect.Float32, reflect.Float64:
		str, err = toString(field.Float())
		if err != nil {
			return str, err
		}
	default:
		return marshall(field)
	}
	return str, nil
}

// --------------------------------------------------------------------------
// Un/serializations helpers

func unmarshall(field reflect.Value, value string) error {
	dupField := field
	unMarshallIt := func(finalField reflect.Value) error {
		if finalField.CanInterface() && finalField.Type().Implements(unMarshallerType) {
			if err := finalField.Interface().(TypeUnmarshaller).UnmarshalCSV(value); err != nil {
				return err
			}
			return nil
		} else if finalField.CanInterface() && finalField.Type().Implements(textUnMarshalerType) { // Otherwise try to use TextMarshaller
			if err := finalField.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(value)); err != nil {
				return err
			}
		}
		return fmt.Errorf("No known conversion from string to " + field.Type().String() + ", " + field.Type().String() + " does not implements TypeUnmarshaller")
	}
	for dupField.Kind() == reflect.Interface || dupField.Kind() == reflect.Ptr {
		if dupField.IsNil() {
			dupField = reflect.New(field.Type().Elem())
			field.Set(dupField)
			return unMarshallIt(dupField)
			break
		}
		dupField = dupField.Elem()
	}
	if dupField.CanAddr() {
		return unMarshallIt(dupField.Addr())
	}
	return fmt.Errorf("No known conversion from string to " + field.Type().String() + ", " + field.Type().String() + " does not implements TypeUnmarshaller")
}

func marshall(field reflect.Value) (value string, err error) {
	dupField := field
	marshallIt := func(finalField reflect.Value) (string, error) {
		if finalField.CanInterface() && finalField.Type().Implements(marshallerType) { // Use TypeMarshaller when possible
			return finalField.Interface().(TypeMarshaller).MarshalCSV()
		} else if finalField.CanInterface() && finalField.Type().Implements(stringerType) { // Otherwise try to use Stringer
			return finalField.Interface().(Stringer).String(), nil
		} else if finalField.CanInterface() && finalField.Type().Implements(textMarshalerType) { // Otherwise try to use TextMarshaller
			text, err := finalField.Interface().(encoding.TextMarshaler).MarshalText()
			return string(text), err
		}

		return value, fmt.Errorf("No known conversion from " + field.Type().String() + " to string, " + field.Type().String() + " does not implements TypeMarshaller nor Stringer")
	}
	for dupField.Kind() == reflect.Interface || dupField.Kind() == reflect.Ptr {
		if dupField.IsNil() {
			return value, nil
		}
		dupField = dupField.Elem()
	}
	if dupField.CanAddr() {
		return marshallIt(dupField.Addr())
	}
	return value, fmt.Errorf("No known conversion from " + field.Type().String() + " to string, " + field.Type().String() + " does not implements TypeMarshaller nor Stringer")
}
<commit_msg>Changed output format for floats to not showing 64 decimals<commit_after>package gocsv

import (
	"encoding"
	"fmt"
	"reflect"
	"strconv"
)

// --------------------------------------------------------------------------
// Conversion interfaces

// TypeMarshaller is implemented by any value that has a MarshalCSV method
// This converter is used to convert the value to it string representation
type TypeMarshaller interface {
	MarshalCSV() (string, error)
}

// Stringer is implemented by any value that has a String method
// This converter is used to convert the value to it string representation
// This converter will be used if your value does not implement TypeMarshaller
type Stringer interface {
	String() string
}

// TypeUnmarshaller is implemented by any value that has an UnmarshalCSV method
// This converter is used to convert a string to your value representation of that string
type TypeUnmarshaller interface {
	UnmarshalCSV(string) error
}

var (
	stringerType        = reflect.TypeOf((*Stringer)(nil)).Elem()
	marshallerType      = reflect.TypeOf((*TypeMarshaller)(nil)).Elem()
	unMarshallerType    = reflect.TypeOf((*TypeUnmarshaller)(nil)).Elem()
	textMarshalerType   = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
	textUnMarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
)

// --------------------------------------------------------------------------
// Conversion helpers

func toString(in interface{}) (string, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		return inValue.String(), nil
	case reflect.Bool:
		b := inValue.Bool()
		if b {
			return "true", nil
		}
		return "false", nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return fmt.Sprintf("%v", inValue.Int()), nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return fmt.Sprintf("%v", inValue.Uint()), nil
	case reflect.Float32, reflect.Float64:
		return fmt.Sprintf("%v", inValue.Float()), nil
	}
	return "", fmt.Errorf("No known conversion from " + inValue.Type().String() + " to string")
}

func toBool(in interface{}) (bool, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		s := inValue.String()
		if s == "true" || s == "yes" || s == "1" {
			return true, nil
		} else if s == "false" || s == "no" || s == "0" {
			return false, nil
		}
	case reflect.Bool:
		return inValue.Bool(), nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		i := inValue.Int()
		if i != 0 {
			return true, nil
		}
		return false, nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		i := inValue.Uint()
		if i != 0 {
			return true, nil
		}
		return false, nil
	case reflect.Float32, reflect.Float64:
		f := inValue.Float()
		if f != 0 {
			return true, nil
		}
		return false, nil
	}
	return false, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to bool")
}

func toInt(in interface{}) (int64, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		return strconv.ParseInt(inValue.String(), 0, 64)
	case reflect.Bool:
		if inValue.Bool() {
			return 1, nil
		}
		return 0, nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return inValue.Int(), nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return int64(inValue.Uint()), nil
	case reflect.Float32, reflect.Float64:
		return int64(inValue.Float()), nil
	}
	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to int")
}

func toUint(in interface{}) (uint64, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		return strconv.ParseUint(inValue.String(), 0, 64)
	case reflect.Bool:
		if inValue.Bool() {
			return 1, nil
		}
		return 0, nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return uint64(inValue.Int()), nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return inValue.Uint(), nil
	case reflect.Float32, reflect.Float64:
		return uint64(inValue.Float()), nil
	}
	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to uint")
}

func toFloat(in interface{}) (float64, error) {
	inValue := reflect.ValueOf(in)

	switch inValue.Kind() {
	case reflect.String:
		return strconv.ParseFloat(inValue.String(), 64)
	case reflect.Bool:
		if inValue.Bool() {
			return 1, nil
		}
		return 0, nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return float64(inValue.Int()), nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return float64(inValue.Uint()), nil
	case reflect.Float32, reflect.Float64:
		return inValue.Float(), nil
	}
	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to float")
}

func setField(field reflect.Value, value string) error {
	switch field.Kind() {
	case reflect.String:
		s, err := toString(value)
		if err != nil {
			return err
		}
		field.SetString(s)
	case reflect.Bool:
		b, err := toBool(value)
		if err != nil {
			return err
		}
		field.SetBool(b)
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		i, err := toInt(value)
		if err != nil {
			return err
		}
		field.SetInt(i)
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		ui, err := toUint(value)
		if err != nil {
			return err
		}
		field.SetUint(ui)
	case reflect.Float32, reflect.Float64:
		f, err := toFloat(value)
		if err != nil {
			return err
		}
		field.SetFloat(f)
	default:
		return unmarshall(field, value)
	}
	return nil
}

func getFieldAsString(field reflect.Value) (str string, err error) {
	switch field.Kind() {
	case reflect.String:
		return field.String(), nil
	case reflect.Bool:
		str, err = toString(field.Bool())
		if err != nil {
			return str, err
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		str, err = toString(field.Int())
		if err != nil {
			return str, err
		}
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		str, err = toString(field.Uint())
		if err != nil {
			return str, err
		}
	case reflect.Float32, reflect.Float64:
		str, err = toString(field.Float())
		if err != nil {
			return str, err
		}
	default:
		return marshall(field)
	}
	return str, nil
}

// --------------------------------------------------------------------------
// Un/serializations helpers

func unmarshall(field reflect.Value, value string) error {
	dupField := field
	unMarshallIt := func(finalField reflect.Value) error {
		if finalField.CanInterface() && finalField.Type().Implements(unMarshallerType) {
			if err := finalField.Interface().(TypeUnmarshaller).UnmarshalCSV(value); err != nil {
				return err
			}
			return nil
		} else if finalField.CanInterface() && finalField.Type().Implements(textUnMarshalerType) { // Otherwise try to use TextMarshaller
			if err := finalField.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(value)); err != nil {
				return err
			}
		}
		return fmt.Errorf("No known conversion from string to " + field.Type().String() + ", " + field.Type().String() + " does not implements TypeUnmarshaller")
	}
	for dupField.Kind() == reflect.Interface || dupField.Kind() == reflect.Ptr {
		if dupField.IsNil() {
			dupField = reflect.New(field.Type().Elem())
			field.Set(dupField)
			return unMarshallIt(dupField)
			break
		}
		dupField = dupField.Elem()
	}
	if dupField.CanAddr() {
		return unMarshallIt(dupField.Addr())
	}
	return fmt.Errorf("No known conversion from string to " + field.Type().String() + ", " + field.Type().String() + " does not implements TypeUnmarshaller")
}

func marshall(field reflect.Value) (value string, err error) {
	dupField := field
	marshallIt := func(finalField reflect.Value) (string, error) {
		if finalField.CanInterface() && finalField.Type().Implements(marshallerType) { // Use TypeMarshaller when possible
			return finalField.Interface().(TypeMarshaller).MarshalCSV()
		} else if finalField.CanInterface() && finalField.Type().Implements(stringerType) { // Otherwise try to use Stringer
			return finalField.Interface().(Stringer).String(), nil
		} else if finalField.CanInterface() && finalField.Type().Implements(textMarshalerType) { // Otherwise try to use TextMarshaller
			text, err := finalField.Interface().(encoding.TextMarshaler).MarshalText()
			return string(text), err
		}

		return value, fmt.Errorf("No known conversion from " + field.Type().String() + " to string, " + field.Type().String() + " does not implements TypeMarshaller nor Stringer")
	}
	for dupField.Kind() == reflect.Interface || dupField.Kind() == reflect.Ptr {
		if dupField.IsNil() {
			return value, nil
		}
		dupField = dupField.Elem()
	}
	if dupField.CanAddr() {
		return marshallIt(dupField.Addr())
	}
	return value, fmt.Errorf("No known conversion from " + field.Type().String() + " to string, " + field.Type().String() + " does not implements TypeMarshaller nor Stringer")
}
<|endoftext|>


<commit_before>package commands

import (
	"errors"
	"fmt"
	"os"
	"text/tabwriter"

	circleci "github.com/mtchavez/circlecigo"
	"github.com/urfave/cli"
)

// BuildCmd - build project and interact with builds
var BuildCmd = cli.Command{
	Name:        "build",
	Usage:       "build project and interact with builds",
	Flags:       buildFlags,
	Action:      buildProjectAction,
	Subcommands: buildSubcommands,
}

var buildFlags = []cli.Flag{
	userFlag,
	projectFlag,
}

var buildSubcommands = []cli.Command{
	{
		Name:   "cancel",
		Usage:  "cancel a specific build",
		Action: buildCancelAction,
		Flags:  append(buildFlags, buildNumFlag),
	},
	{
		Name:   "retry",
		Usage:  "retry a specific build",
		Action: buildRetryAction,
		Flags:  append(buildFlags, buildNumFlag),
	},
}

func buildProjectAction(context *cli.Context) error {
	token := context.GlobalString("token")
	client := circleci.NewClient(token)
	build, resp := client.NewBuild(context.String("user"), context.String("project"), nil)
	if resp.Success() {
		padding := 1
		writer := tabwriter.NewWriter(os.Stdout, 0, 8, padding, '\t', tabwriter.AlignRight)
		fmt.Fprintln(writer, "Build\tBranch\tQueued\tURL")
		fmt.Fprintln(writer, fmt.Sprintf("%d\t%s\t%s\t%s\t", build.BuildNum, build.Branch, build.QueuedAt, build.BuildURL))
		writer.Flush()
		return nil
	}
	failed := errors.New("Failed to build")
	return failed
}

func buildCancelAction(context *cli.Context) error {
	token := context.GlobalString("token")
	buildNum := context.Int("num")
	client := circleci.NewClient(token)
	build, resp := client.CancelBuild(context.String("user"), context.String("project"), buildNum)
	if resp.Success() {
		padding := 1
		writer := tabwriter.NewWriter(os.Stdout, 0, 8, padding, '\t', tabwriter.AlignRight)
		fmt.Fprintln(writer, "Build\tBranch\tStatus\tURL")
		fmt.Fprintln(writer, fmt.Sprintf("%d\t%s\t%s\t%s\t", build.BuildNum, build.Branch, build.Status, build.BuildURL))
		writer.Flush()
		return nil
	}
	failed := errors.New("Failed to cancel build")
	return failed
}

func buildRetryAction(context *cli.Context) error {
	token := context.GlobalString("token")
	buildNum := context.Int("num")
	client := circleci.NewClient(token)
	build, resp := client.RetryBuild(context.String("user"), context.String("project"), buildNum)
	if resp.Success() {
		padding := 1
		writer := tabwriter.NewWriter(os.Stdout, 0, 8, padding, '\t', tabwriter.AlignRight)
		fmt.Fprintln(writer, "Build\tBranch\tStatus\tURL")
		fmt.Fprintln(writer, fmt.Sprintf("%d\t%s\t%s\t%s\t", build.BuildNum, build.Branch, build.Status, build.BuildURL))
		writer.Flush()
		return nil
	}
	failed := errors.New("Failed to retry build")
	return failed
}
<commit_msg>Build branch<commit_after>package commands

import (
	"errors"
	"fmt"
	"os"
	"text/tabwriter"

	circleci "github.com/mtchavez/circlecigo"
	"github.com/urfave/cli"
)

// BuildCmd - build project and interact with builds
var BuildCmd = cli.Command{
	Name:        "build",
	Usage:       "build project and interact with builds",
	Flags:       append(buildFlags, branchFlag),
	Action:      buildProjectAction,
	Subcommands: buildSubcommands,
}

var buildFlags = []cli.Flag{
	userFlag,
	projectFlag,
}

var buildSubcommands = []cli.Command{
	{
		Name:   "cancel",
		Usage:  "cancel a specific build",
		Action: buildCancelAction,
		Flags:  append(buildFlags, buildNumFlag),
	},
	{
		Name:   "retry",
		Usage:  "retry a specific build",
		Action: buildRetryAction,
		Flags:  append(buildFlags, buildNumFlag),
	},
}

func buildProjectAction(context *cli.Context) error {
	token := context.GlobalString("token")
	client := circleci.NewClient(token)
	user := context.String("user")
	project := context.String("project")
	branch := context.String("branch")
	var build *circleci.Build
	var resp *circleci.APIResponse
	if branch != "" {
		build, resp = client.BuildBranch(user, project, branch, nil)
	} else {
		build, resp = client.NewBuild(user, project, nil)
	}
	if resp.Success() {
		padding := 1
		writer := tabwriter.NewWriter(os.Stdout, 0, 8, padding, '\t', tabwriter.AlignRight)
		fmt.Fprintln(writer, "Build\tBranch\tQueued\tURL")
		fmt.Fprintln(writer, fmt.Sprintf("%d\t%s\t%s\t%s\t", build.BuildNum, build.Branch, build.QueuedAt, build.BuildURL))
		writer.Flush()
		return nil
	}
	failed := errors.New("Failed to build")
	return failed
}

func buildCancelAction(context *cli.Context) error {
	token := context.GlobalString("token")
	buildNum := context.Int("num")
	client := circleci.NewClient(token)
	build, resp := client.CancelBuild(context.String("user"), context.String("project"), buildNum)
	if resp.Success() {
		padding := 1
		writer := tabwriter.NewWriter(os.Stdout, 0, 8, padding, '\t', tabwriter.AlignRight)
		fmt.Fprintln(writer, "Build\tBranch\tStatus\tURL")
		fmt.Fprintln(writer, fmt.Sprintf("%d\t%s\t%s\t%s\t", build.BuildNum, build.Branch, build.Status, build.BuildURL))
		writer.Flush()
		return nil
	}
	failed := errors.New("Failed to cancel build")
	return failed
}

func buildRetryAction(context *cli.Context) error {
	token := context.GlobalString("token")
	buildNum := context.Int("num")
	client := circleci.NewClient(token)
	build, resp := client.RetryBuild(context.String("user"), context.String("project"), buildNum)
	if resp.Success() {
		padding := 1
		writer := tabwriter.NewWriter(os.Stdout, 0, 8, padding, '\t', tabwriter.AlignRight)
		fmt.Fprintln(writer, "Build\tBranch\tStatus\tURL")
		fmt.Fprintln(writer, fmt.Sprintf("%d\t%s\t%s\t%s\t", build.BuildNum, build.Branch, build.Status, build.BuildURL))
		writer.Flush()
		return nil
	}
	failed := errors.New("Failed to retry build")
	return failed
}
<|endoftext|>


<commit_before>package commands

import (
	"bytes"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/spf13/cobra"
)

var buildCmd = &cobra.Command{
	Use:   "build [output path]",
	Short: "Build caddy from the current state",
	Long:  `Build caddy from the current state`,
	Run:   BuildCaddy,
}

// Errors
var (
	ErrBuildSourceNotFound          = errors.New("Caddy source doesn't exist inside current GOPATH")
	ErrBuildOutputDirectoryNotFound = errors.New("Output directory doesn't exist")
)

func init() {
}

func BuildCaddy(cmd *cobra.Command, args []string) {
	outputPath, _ := os.Getwd()

	if len(args) > 0 {
		if filepath.IsAbs(args[0]) {
			outputPath = args[0]
		} else {
			outputPath = filepath.Join(outputPath, args[0])
		}
		args = args[1:]
	}

	outputPath = filepath.Join(outputPath, "customCaddy")

	if err := caddyBuild(caddyPath, outputPath, args...); err != nil {
		cmdError(cmd, err)
	}
}

func caddyBuild(caddy, output string, args ...string) error {
	cmd := exec.Command("go", append([]string{"build", "-o", output}, args...)...)
	cmd.Dir = caddy
	errBuf := new(bytes.Buffer)
	cmd.Stderr = errBuf
	cmd.Env = os.Environ()
	if err := cmd.Run(); err != nil {
		return err
	}
	fmt.Println("new caddy build:", output)

	return nil
}
<commit_msg>add .exe extension to customCaddy on Windows<commit_after>package commands

import (
	"bytes"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"

	"github.com/spf13/cobra"
)

var buildCmd = &cobra.Command{
	Use:   "build [output path]",
	Short: "Build caddy from the current state",
	Long:  `Build caddy from the current state`,
	Run:   BuildCaddy,
}

// Errors
var (
	ErrBuildSourceNotFound          = errors.New("Caddy source doesn't exist inside current GOPATH")
	ErrBuildOutputDirectoryNotFound = errors.New("Output directory doesn't exist")
)

func init() {
}

func BuildCaddy(cmd *cobra.Command, args []string) {
	outputPath, _ := os.Getwd()

	if len(args) > 0 {
		if filepath.IsAbs(args[0]) {
			outputPath = args[0]
		} else {
			outputPath = filepath.Join(outputPath, args[0])
		}
		args = args[1:]
	}

	var ext string
	if runtime.GOOS == "windows" {
		ext = ".exe"
	}
	outputPath = filepath.Join(outputPath, "customCaddy"+ext)

	if err := caddyBuild(caddyPath, outputPath, args...); err != nil {
		cmdError(cmd, err)
	}
}

func caddyBuild(caddy, output string, args ...string) error {
	cmd := exec.Command("go", append([]string{"build", "-o", output}, args...)...)
	cmd.Dir = caddy
	errBuf := new(bytes.Buffer)
	cmd.Stderr = errBuf
	cmd.Env = os.Environ()
	if err := cmd.Run(); err != nil {
		return err
	}
	fmt.Println("new caddy build:", output)

	return nil
}
<|endoftext|>


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

package commands

import (
	"fmt"
	"sort"
	"strings"
	"time"
)

const (
	barChar = "∎"
)

type report struct {
	avgTotal float64
	fastest  float64
	slowest  float64
	average  float64
	rps      float64

	results chan *result
	total   time.Duration

	statusCodeDist map[int]int
	lats           []float64
}

func newReport(size int, results chan *result) *report {
	return &report{
		statusCodeDist: make(map[int]int),
		results:        results,
	}
}

func (r *report) finalize(total time.Duration) {
	for {
		select {
		case res := <-r.results:
			r.lats = append(r.lats, res.duration.Seconds())
			r.avgTotal += res.duration.Seconds()
			r.statusCodeDist[res.statusCode]++
		default:
			r.total = total
			r.rps = float64(len(r.lats)) / r.total.Seconds()
			r.average = r.avgTotal / float64(len(r.lats))
			r.print()
			return
		}
	}
}

func (r *report) print() {
	if len(r.lats) > 0 {
		sort.Float64s(r.lats)
		r.fastest = r.lats[0]
		r.slowest = r.lats[len(r.lats)-1]
		fmt.Printf("\nSummary:\n")
		fmt.Printf("  Total:\t%4.4f secs.\n", r.total.Seconds())
		fmt.Printf("  Slowest:\t%4.4f secs.\n", r.slowest)
		fmt.Printf("  Fastest:\t%4.4f secs.\n", r.fastest)
		fmt.Printf("  Average:\t%4.4f secs.\n", r.average)
		fmt.Printf("  Requests/sec:\t%4.4f\n", r.rps)
		r.printStatusCodes()
		r.printHistogram()
		r.printLatencies()
	}
}

// Prints percentile latencies.
func (r *report) printLatencies() {
	pctls := []int{10, 25, 50, 75, 90, 95, 99}
	// Sort the array
	data := make([]float64, len(pctls))
	j := 0
	for i := 0; i < len(r.lats) && j < len(pctls); i++ {
		current := (i + 1) * 100 / len(r.lats)
		if current >= pctls[j] {
			data[j] = r.lats[i]
			j++
		}
	}
	fmt.Printf("\nLatency distribution:\n")
	for i := 0; i < len(pctls); i++ {
		if data[i] > 0 {
			fmt.Printf("  %v%% in %4.4f secs.\n", pctls[i], data[i])
		}
	}
}

func (r *report) printHistogram() {
	bc := 10
	buckets := make([]float64, bc+1)
	counts := make([]int, bc+1)
	bs := (r.slowest - r.fastest) / float64(bc)
	for i := 0; i < bc; i++ {
		buckets[i] = r.fastest + bs*float64(i)
	}
	buckets[bc] = r.slowest
	var bi int
	var max int
	for i := 0; i < len(r.lats); {
		if r.lats[i] <= buckets[bi] {
			i++
			counts[bi]++
			if max < counts[bi] {
				max = counts[bi]
			}
		} else if bi < len(buckets)-1 {
			bi++
		}
	}
	fmt.Printf("\nResponse time histogram:\n")
	for i := 0; i < len(buckets); i++ {
		// Normalize bar lengths.
		var barLen int
		if max > 0 {
			barLen = counts[i] * 40 / max
		}
		fmt.Printf("  %4.3f [%v]\t|%v\n", buckets[i], counts[i], strings.Repeat(barChar, barLen))
	}
}

// Prints status code distribution.
func (r *report) printStatusCodes() {
	fmt.Printf("\nStatus code distribution:\n")
	for code, num := range r.statusCodeDist {
		fmt.Printf("  [%d]\t%d responses\n", code, num)
	}
}
<commit_msg>Minor fix for latency percentiles.<commit_after>// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package commands

import (
	"fmt"
	"sort"
	"strings"
	"time"
)

const (
	barChar = "∎"
)

type report struct {
	avgTotal float64
	fastest  float64
	slowest  float64
	average  float64
	rps      float64

	results chan *result
	total   time.Duration

	statusCodeDist map[int]int
	lats           []float64
}

func newReport(size int, results chan *result) *report {
	return &report{
		statusCodeDist: make(map[int]int),
		results:        results,
	}
}

func (r *report) finalize(total time.Duration) {
	for {
		select {
		case res := <-r.results:
			r.lats = append(r.lats, res.duration.Seconds())
			r.avgTotal += res.duration.Seconds()
			r.statusCodeDist[res.statusCode]++
		default:
			r.total = total
			r.rps = float64(len(r.lats)) / r.total.Seconds()
			r.average = r.avgTotal / float64(len(r.lats))
			r.print()
			return
		}
	}
}

func (r *report) print() {
	if len(r.lats) > 0 {
		sort.Float64s(r.lats)
		r.fastest = r.lats[0]
		r.slowest = r.lats[len(r.lats)-1]
		fmt.Printf("\nSummary:\n")
		fmt.Printf("  Total:\t%4.4f secs.\n", r.total.Seconds())
		fmt.Printf("  Slowest:\t%4.4f secs.\n", r.slowest)
		fmt.Printf("  Fastest:\t%4.4f secs.\n", r.fastest)
		fmt.Printf("  Average:\t%4.4f secs.\n", r.average)
		fmt.Printf("  Requests/sec:\t%4.4f\n", r.rps)
		r.printStatusCodes()
		r.printHistogram()
		r.printLatencies()
	}
}

// Prints percentile latencies.
func (r *report) printLatencies() {
	pctls := []int{10, 25, 50, 75, 90, 95, 99}
	data := make([]float64, len(pctls))
	j := 0
	for i := 0; i < len(r.lats) && j < len(pctls); i++ {
		current := i * 100 / len(r.lats)
		if current >= pctls[j] {
			data[j] = r.lats[i]
			j++
		}
	}
	fmt.Printf("\nLatency distribution:\n")
	for i := 0; i < len(pctls); i++ {
		if data[i] > 0 {
			fmt.Printf("  %v%% in %4.4f secs.\n", pctls[i], data[i])
		}
	}
}

func (r *report) printHistogram() {
	bc := 10
	buckets := make([]float64, bc+1)
	counts := make([]int, bc+1)
	bs := (r.slowest - r.fastest) / float64(bc)
	for i := 0; i < bc; i++ {
		buckets[i] = r.fastest + bs*float64(i)
	}
	buckets[bc] = r.slowest
	var bi int
	var max int
	for i := 0; i < len(r.lats); {
		if r.lats[i] <= buckets[bi] {
			i++
			counts[bi]++
			if max < counts[bi] {
				max = counts[bi]
			}
		} else if bi < len(buckets)-1 {
			bi++
		}
	}
	fmt.Printf("\nResponse time histogram:\n")
	for i := 0; i < len(buckets); i++ {
		// Normalize bar lengths.
		var barLen int
		if max > 0 {
			barLen = counts[i] * 40 / max
		}
		fmt.Printf("  %4.3f [%v]\t|%v\n", buckets[i], counts[i], strings.Repeat(barChar, barLen))
	}
}

// Prints status code distribution.
func (r *report) printStatusCodes() {
	fmt.Printf("\nStatus code distribution:\n")
	for code, num := range r.statusCodeDist {
		fmt.Printf("  [%d]\t%d responses\n", code, num)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/liuxp0827/govpr"
	"github.com/liuxp0827/govpr/log"
	"github.com/liuxp0827/govpr/waveIO"
	"io/ioutil"
)

type engine struct {
	vprEngine *govpr.VPREngine
}

func NewEngine(sampleRate, delSilRange int, ubmFile, userModelFile string) (*engine, error) {
	vprEngine, err := govpr.NewVPREngine(sampleRate, delSilRange, false, ubmFile, userModelFile)
	if err != nil {
		return nil, err
	}
	return &engine{vprEngine: vprEngine}, nil
}

func (this *engine) DestroyEngine() {
	this.vprEngine = nil
}

func (this *engine) TrainSpeech(buffers [][]byte) error {

	var err error
	count := len(buffers)
	for i := 0; i < count; i++ {
		err = this.vprEngine.AddTrainBuffer(buffers[i])
		if err != nil {
			log.Error(err)
			return err
		}
	}

	defer this.vprEngine.ClearTrainBuffer()
	defer this.vprEngine.ClearAllBuffer()

	err = this.vprEngine.TrainModel()
	if err != nil {
		log.Error(err)
		return err
	}

	return nil
}

func (this *engine) RecSpeech(buffer []byte) (float64, error) {

	err := this.vprEngine.AddVerifyBuffer(buffer)
	defer this.vprEngine.ClearVerifyBuffer()
	if err != nil {
		log.Error(err)
		return -1.0, err
	}

	err = this.vprEngine.VerifyModel()
	if err != nil {
		log.Error(err)
		return -1.0, err
	}

	return this.vprEngine.GetScore(), nil
}

func main() {
	log.SetLevel(log.LevelDebug)

	vprEngine, err := NewEngine(16000, 50, "../ubm/ubm1", "model/test.dat")
	if err != nil {
		log.Fatal(err)
	}

	trainlist := []string{
		"wav/train/01_32468975.wav",
		"wav/train/02_58769423.wav",
		"wav/train/03_59682734.wav",
		"wav/train/04_64958273.wav",
		"wav/train/05_65432978.wav",
	}

	trainBuffer := make([][]byte, 0)

	for _, file := range trainlist {
		buf, err := loadWaveData(file)
		if err != nil {
			log.Error(err)
			return
		}
		trainBuffer = append(trainBuffer, buf)
	}

	err = vprEngine.TrainSpeech(trainBuffer)
	if err != nil {
		log.Fatal(err)
	}

	var threshold float64 = 1.0

	selfverifyBuffer, err := waveIO.WaveLoad("wav/verify/self_34986527.wav")
	if err != nil {
		log.Fatal(err)
	}

	self_score, err := vprEngine.RecSpeech(selfverifyBuffer)
	if err != nil {
		log.Fatal(err)
	}

	log.Infof("self score %f, pass? %v", self_score, self_score >= threshold)

	otherverifyBuffer, err := waveIO.WaveLoad("wav/verify/other_38974652.wav")
	if err != nil {
		log.Fatal(err)
	}

	other_score, err := vprEngine.RecSpeech(otherverifyBuffer)
	if err != nil {
		log.Fatal(err)
	}

	log.Infof("other score %f, pass? %v", other_score, other_score >= threshold)
}

func loadWaveData(file string) ([]byte, error) {
	data, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}
	// remove .wav header info 44 bits
	data = data[44:]
	return data, nil
}
<commit_msg>nothing<commit_after>package main

import (
	"github.com/liuxp0827/govpr"
	"github.com/liuxp0827/govpr/log"
	"github.com/liuxp0827/govpr/waveIO"
	"io/ioutil"
)

type engine struct {
	vprEngine *govpr.VPREngine
}

func NewEngine(sampleRate, delSilRange int, ubmFile, userModelFile string) (*engine, error) {
	vprEngine, err := govpr.NewVPREngine(sampleRate, delSilRange, false, ubmFile, userModelFile)
	if err != nil {
		return nil, err
	}
	return &engine{vprEngine: vprEngine}, nil
}

func (this *engine) DestroyEngine() {
	this.vprEngine = nil
}

func (this *engine) TrainSpeech(buffers [][]byte) error {

	var err error
	count := len(buffers)
	for i := 0; i < count; i++ {
		err = this.vprEngine.AddTrainBuffer(buffers[i])
		if err != nil {
			log.Error(err)
			return err
		}
	}

	defer this.vprEngine.ClearTrainBuffer()
	defer this.vprEngine.ClearAllBuffer()

	err = this.vprEngine.TrainModel()
	if err != nil {
		log.Error(err)
		return err
	}

	return nil
}

func (this *engine) RecSpeech(buffer []byte) (float64, error) {

	err := this.vprEngine.AddVerifyBuffer(buffer)
	defer this.vprEngine.ClearVerifyBuffer()
	if err != nil {
		log.Error(err)
		return -1.0, err
	}

	err = this.vprEngine.VerifyModel()
	if err != nil {
		log.Error(err)
		return -1.0, err
	}

	return this.vprEngine.GetScore(), nil
}

func main() {
	log.SetLevel(log.LevelDebug)

	vprEngine, err := NewEngine(16000, 50, "../ubm/ubm", "model/test.dat")
	if err != nil {
		log.Fatal(err)
	}

	trainlist := []string{
		"wav/train/01_32468975.wav",
		"wav/train/02_58769423.wav",
		"wav/train/03_59682734.wav",
		"wav/train/04_64958273.wav",
		"wav/train/05_65432978.wav",
	}

	trainBuffer := make([][]byte, 0)

	for _, file := range trainlist {
		buf, err := loadWaveData(file)
		if err != nil {
			log.Error(err)
			return
		}
		trainBuffer = append(trainBuffer, buf)
	}

	err = vprEngine.TrainSpeech(trainBuffer)
	if err != nil {
		log.Fatal(err)
	}

	var threshold float64 = 1.0

	selfverifyBuffer, err := waveIO.WaveLoad("wav/verify/self_34986527.wav")
	if err != nil {
		log.Fatal(err)
	}

	self_score, err := vprEngine.RecSpeech(selfverifyBuffer)
	if err != nil {
		log.Fatal(err)
	}

	log.Infof("self score %f, pass? %v", self_score, self_score >= threshold)

	otherverifyBuffer, err := waveIO.WaveLoad("wav/verify/other_38974652.wav")
	if err != nil {
		log.Fatal(err)
	}

	other_score, err := vprEngine.RecSpeech(otherverifyBuffer)
	if err != nil {
		log.Fatal(err)
	}

	log.Infof("other score %f, pass? %v", other_score, other_score >= threshold)
}

func loadWaveData(file string) ([]byte, error) {
	data, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}
	// remove .wav header info 44 bits
	data = data[44:]
	return data, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/athrunecho/zkteco"
	"github.com/northbright/pathhelper"
)

const (
	kaoqinFilePath = "./csv/attendance/attendance.csv"
)

func main() {
	var (
		k   *zkteco.Kaoqin
		err error
		p   string
		f   *os.File
	)

	if p, err = pathhelper.GetAbsPath(kaoqinFilePath); err != nil {
		fmt.Printf("GetAbsPatherr:%v\n", err)
		return

	}

	if k, err = zkteco.NewKaoqin(":6379", ""); err != nil {
		fmt.Printf("zkteco.NewKaoqin err: %v\n", err)
		return
	}
	if f, err = os.Open(p); err != nil {
		fmt.Printf("os.Open err: %v\n", err)
		return
	}
	defer f.Close()
	if err = k.UpdateAttendances(f); err != nil {
		fmt.Printf("GetCSVRecordserr:%v\n", err)
		return
	}

}
<commit_msg>Close the connection<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/athrunecho/zkteco"
	"github.com/northbright/pathhelper"
)

const (
	kaoqinFilePath = "./csv/attendance/attendance.csv"
)

func main() {
	var (
		k   *zkteco.Kaoqin
		err error
		p   string
		f   *os.File
	)

	if p, err = pathhelper.GetAbsPath(kaoqinFilePath); err != nil {
		fmt.Printf("GetAbsPatherr:%v\n", err)
		return

	}

	if k, err = zkteco.NewKaoqin(":6379", ""); err != nil {
		fmt.Printf("zkteco.NewKaoqin err: %v\n", err)
		return
	}
	if f, err = os.Open(p); err != nil {
		fmt.Printf("os.Open err: %v\n", err)
		return
	}
	defer f.Close()
	if err = k.UpdateAttendances(f); err != nil {
		fmt.Printf("GetCSVRecordserr:%v\n", err)
		return
	}
	defer k.Close()

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"runtime"
	"time"

	"github.com/smartystreets/go-disruptor"
)

const (
	BufferSize = 1024 * 64
	BufferMask = BufferSize - 1
	Iterations = 1000000 * 100
)

var ringBuffer = [BufferSize]int64{}

func main() {
	runtime.GOMAXPROCS(2)

	written, read := disruptor.NewCursor(), disruptor.NewCursor()
	started := time.Now()

	go consume(written, read, SampleConsumer{})
	publish(written, read)

	finished := time.Now()
	fmt.Println(Iterations, finished.Sub(started))

	time.Sleep(time.Millisecond * 10)
}

func publish(written, read *disruptor.Cursor) {
	previous := disruptor.InitialSequenceValue
	gate := disruptor.InitialSequenceValue

	for previous <= Iterations {
		next := previous + 1
		wrap := next - BufferSize

		for wrap > gate {
			gate = read.Sequence
		}

		ringBuffer[next&BufferMask] = next
		written.Sequence = next
		previous = next
	}
}

func consume(written, read *disruptor.Cursor, consumer disruptor.Consumer) {
	previous := int64(-1)
	upstream := disruptor.Barrier(written)
	idling := 0

	for previous < Iterations {
		lower := previous + 1
		upper := upstream.Read(lower)

		if lower <= upper {
			consumer.Consume(lower, upper)
			read.Sequence = upper
			previous = upper
		} else if upper = written.Sequence; lower <= upper {
			// TODO: gating strategy
		} else {
			// TODO: idling strategy
			idling++
		}

		time.Sleep(time.Nanosecond)
	}

	fmt.Println("Consumer idling", idling)
}

type SampleConsumer struct{}

func (this SampleConsumer) Consume(lower, upper int64) {
	for lower <= upper {
		if ringBuffer[lower&BufferMask] > 0 {
		}
		lower++
	}
}
<commit_msg>Consumer watches for race conditions.<commit_after>package main

import (
	"fmt"
	"runtime"
	"time"

	"github.com/smartystreets/go-disruptor"
)

const (
	BufferSize = 1024 * 64
	BufferMask = BufferSize - 1
	Iterations = 1000000 * 100
)

var ringBuffer = [BufferSize]int64{}

func main() {
	runtime.GOMAXPROCS(2)

	written, read := disruptor.NewCursor(), disruptor.NewCursor()
	started := time.Now()

	go consume(written, read, SampleConsumer{})
	publish(written, read)

	finished := time.Now()
	fmt.Println(Iterations, finished.Sub(started))

	time.Sleep(time.Millisecond * 10)
}

func publish(written, read *disruptor.Cursor) {
	previous := disruptor.InitialSequenceValue
	gate := disruptor.InitialSequenceValue

	for previous <= Iterations {
		next := previous + 1
		wrap := next - BufferSize

		for wrap > gate {
			gate = read.Sequence
		}

		ringBuffer[next&BufferMask] = next
		written.Sequence = next
		previous = next
	}
}

func consume(written, read *disruptor.Cursor, consumer disruptor.Consumer) {
	previous := int64(-1)
	upstream := disruptor.Barrier(written)
	idling := 0

	for previous < Iterations {
		lower := previous + 1
		upper := upstream.Read(lower)

		if lower <= upper {
			consumer.Consume(lower, upper)
			read.Sequence = upper
			previous = upper
		} else if upper = written.Sequence; lower <= upper {
			// TODO: gating strategy
		} else {
			// TODO: idling strategy
			idling++
		}

		time.Sleep(time.Nanosecond)
	}

	fmt.Println("Consumer idling", idling)
}

type SampleConsumer struct{}

func (this SampleConsumer) Consume(lower, upper int64) {
	for lower <= upper {
		message := ringBuffer[lower&BufferMask]
		if message != lower {
			fmt.Println("Race condition", message, lower)
			panic("Race condition")
		}
		lower++
	}
}
<|endoftext|>


<commit_before>package clock

import "testing"

const testVersion = 1

// Retired testVersions
// (none) 79937f6d58e25ebafe12d1cb4a9f88f4de70cfd6

func TestNewClock(t *testing.T) {
	if TestVersion != testVersion {
		t.Fatalf("Found TestVersion = %v, want %v", TestVersion, testVersion)
	}
	for _, n := range newTests {
		if got := New(n.h, n.m); got.String() != n.want {
			t.Fatalf("New(%d, %d) = %q, want %q", n.h, n.m, got, n.want)
		}
	}
	t.Log(len(newTests), "test cases")
}

func TestAddMinutes(t *testing.T) {
	for _, a := range addTests {
		if got := New(a.h, a.m).Add(a.a); got.String() != a.want {
			t.Fatalf("New(%d, %d).Add(%d) = %q, want %q",
				a.h, a.m, a.a, got, a.want)
		}
	}
	t.Log(len(addTests), "test cases")
}

func TestCompareClocks(t *testing.T) {
	for _, e := range eqTests {
		clock1 := New(e.c1.h, e.c1.m)
		clock2 := New(e.c2.h, e.c2.m)
		got := clock1 == clock2
		if got != e.want {
			t.Log("Clock1:", clock1)
			t.Log("Clock2:", clock2)
			op := map[bool]string{true: "==", false: "!="}
			t.Fatal("Clock1, clock2 compare", op[got], "want", op[e.want])
		}
	}
	t.Log(len(eqTests), "test cases")
}
<commit_msg>clock: add test program comments, improve failure message<commit_after>package clock

import (
	"reflect"
	"testing"
)

// Implement a Clock type with a constructor, a stringer, and an Add method.
// Add should also handle subtraction by accepting negative values.
// To satisfy the readme requirement about clocks being equal, values of
// your Clock type need to work with the == operator.
//
// It might help to study the time.Time type in the standard library
// (https://golang.org/pkg/time/#Time) as a model.  See how constructors there
// (Date and Now) return Time values rather than pointers.  Note also how
// most time.Time methods have value receivers rather that pointer recievers.
// For more background on this read
// https://github.com/golang/go/wiki/CodeReviewComments#receiver-type.

const testVersion = 1

// Retired testVersions
// (none) 79937f6d58e25ebafe12d1cb4a9f88f4de70cfd6

func TestNewClock(t *testing.T) {
	if TestVersion != testVersion {
		t.Fatalf("Found TestVersion = %v, want %v", TestVersion, testVersion)
	}
	for _, n := range newTests {
		if got := New(n.h, n.m); got.String() != n.want {
			t.Fatalf("New(%d, %d) = %q, want %q", n.h, n.m, got, n.want)
		}
	}
	t.Log(len(newTests), "test cases")
}

func TestAddMinutes(t *testing.T) {
	for _, a := range addTests {
		if got := New(a.h, a.m).Add(a.a); got.String() != a.want {
			t.Fatalf("New(%d, %d).Add(%d) = %q, want %q",
				a.h, a.m, a.a, got, a.want)
		}
	}
	t.Log(len(addTests), "test cases")
}

func TestCompareClocks(t *testing.T) {
	for _, e := range eqTests {
		clock1 := New(e.c1.h, e.c1.m)
		clock2 := New(e.c2.h, e.c2.m)
		got := clock1 == clock2
		if got != e.want {
			t.Log("Clock1:", clock1)
			t.Log("Clock2:", clock2)
			t.Logf("Clock1 == Clock2 is %t, want %t", got, e.want)
			if reflect.DeepEqual(clock1, clock2) {
				t.Log("(Hint: see comments in clock_test.go.)")
			}
			t.FailNow()
		}
	}
	t.Log(len(eqTests), "test cases")
}
<|endoftext|>


<commit_before>package common

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
)

// HTTPLog satisfies the http.RoundTripper interface and is used to
// customize the default Gophercloud RoundTripper to allow for logging.
type HTTPLog struct {
	Logger *logrus.Logger
	rt     http.RoundTripper
}

const httpTimeout = 15 * time.Second

// NewHTTPClient return a custom HTTP client that allows for logging relevant
// information before and after the HTTP request.
func NewHTTPClient() *http.Client {
	return &http.Client{
		Timeout: httpTimeout,
		Transport: &HTTPLog{
			rt:     http.DefaultTransport,
			Logger: Log.Logger,
		},
	}
}

// RoundTrip performs a round-trip HTTP request and logs relevant information about it.
func (hl *HTTPLog) RoundTrip(request *http.Request) (*http.Response, error) {
	defer func() {
		if request.Body != nil {
			request.Body.Close()
		}
	}()

	var err error

	if hl.Logger.Level == logrus.DebugLevel && request.Body != nil {
		request.Body, err = hl.logRequestBody(request.Body, request.Header)
		if err != nil {
			return nil, err
		}
	}

	// Don't log the token embedded in a cached auth token check
	url := request.URL.String()
	if strings.Contains(url, "tokens") {
		url = fmt.Sprintf("%s/%s/***", request.URL.Scheme, request.URL.Host)
	}

	hl.Logger.Debugf("Request: %s %s", request.Method, url)

	response, err := hl.rt.RoundTrip(request)
	if response == nil {
		return nil, err
	}

	responseBody, _ := hl.logResponseBody(response.Body, response.Header)
	response.Body = responseBody

	if response.StatusCode >= 400 {
		buf := bytes.NewBuffer([]byte{})
		body, _ := ioutil.ReadAll(io.TeeReader(response.Body, buf))
		hl.Logger.Infof("Response Error: %+v", string(body))
		bufWithClose := ioutil.NopCloser(buf)
		response.Body = bufWithClose
	}

	return response, err
}

func (hl *HTTPLog) logRequestBody(original io.ReadCloser, headers http.Header) (io.ReadCloser, error) {
	defer original.Close()

	var bs bytes.Buffer
	_, err := io.Copy(&bs, original)
	if err != nil {
		return nil, err
	}

	contentType := headers.Get("Content-Type")
	if strings.HasPrefix(contentType, "application/json") {
		debugInfo := hl.formatJSON(bs.Bytes())
		hl.Logger.Debugf("Request Options: %s", debugInfo)
	} else {
		hl.Logger.Debugf("Request Options: %s", bs.String())
	}

	return ioutil.NopCloser(strings.NewReader(bs.String())), nil
}

func (hl *HTTPLog) logResponseBody(original io.ReadCloser, headers http.Header) (io.ReadCloser, error) {
	defer original.Close()

	var bs bytes.Buffer
	_, err := io.Copy(&bs, original)
	if err != nil {
		return nil, err
	}

	contentType := headers.Get("Content-Type")
	if strings.HasPrefix(contentType, "application/json") {
		debugInfo := hl.formatJSON(bs.Bytes())
		if debugInfo != "" {
			hl.Logger.Debugf("Response Body: %s", debugInfo)
		}
	} else {
		hl.Logger.Debugf("Not logging because response body isn't JSON")
	}

	return ioutil.NopCloser(strings.NewReader(bs.String())), nil
}

func (hl *HTTPLog) formatJSON(raw []byte) string {
	var data map[string]interface{}

	err := json.Unmarshal(raw, &data)
	if err != nil {
		return string(raw)
	}

	pretty, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		return string(raw)
	}

	return string(pretty)
}
<commit_msg>Log the request id header<commit_after>package common

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
)

// HTTPLog satisfies the http.RoundTripper interface and is used to
// customize the default Gophercloud RoundTripper to allow for logging.
type HTTPLog struct {
	Logger *logrus.Logger
	rt     http.RoundTripper
}

const httpTimeout = 15 * time.Second

// NewHTTPClient return a custom HTTP client that allows for logging relevant
// information before and after the HTTP request.
func NewHTTPClient() *http.Client {
	return &http.Client{
		Timeout: httpTimeout,
		Transport: &HTTPLog{
			rt:     http.DefaultTransport,
			Logger: Log.Logger,
		},
	}
}

// RoundTrip performs a round-trip HTTP request and logs relevant information about it.
func (hl *HTTPLog) RoundTrip(request *http.Request) (*http.Response, error) {
	defer func() {
		if request.Body != nil {
			request.Body.Close()
		}
	}()

	var err error

	if hl.Logger.Level == logrus.DebugLevel && request.Body != nil {
		request.Body, err = hl.logRequestBody(request.Body, request.Header)
		if err != nil {
			return nil, err
		}
	}

	// Don't log the token embedded in a cached auth token check
	url := request.URL.String()
	if strings.Contains(url, "tokens") {
		url = fmt.Sprintf("%s/%s/***", request.URL.Scheme, request.URL.Host)
	}

	hl.Logger.Debugf("Request: %s %s", request.Method, url)

	response, err := hl.rt.RoundTrip(request)
	if response == nil {
		return nil, err
	}

	// Log the request id, if present
	for key, value := range response.Header {
		if strings.Contains(strings.ToLower(key), "request-id") {
			hl.Logger.Debugf("Request ID: %s", value)
			break
		}
	}

	responseBody, _ := hl.logResponseBody(response.Body, response.Header)
	response.Body = responseBody

	if response.StatusCode >= 400 {
		buf := bytes.NewBuffer([]byte{})
		body, _ := ioutil.ReadAll(io.TeeReader(response.Body, buf))
		hl.Logger.Infof("Response Error: %+v", string(body))
		bufWithClose := ioutil.NopCloser(buf)
		response.Body = bufWithClose
	}

	return response, err
}

func (hl *HTTPLog) logRequestBody(original io.ReadCloser, headers http.Header) (io.ReadCloser, error) {
	defer original.Close()

	var bs bytes.Buffer
	_, err := io.Copy(&bs, original)
	if err != nil {
		return nil, err
	}

	contentType := headers.Get("Content-Type")
	if strings.HasPrefix(contentType, "application/json") {
		debugInfo := hl.formatJSON(bs.Bytes())
		hl.Logger.Debugf("Request Options: %s", debugInfo)
	} else {
		hl.Logger.Debugf("Request Options: %s", bs.String())
	}

	return ioutil.NopCloser(strings.NewReader(bs.String())), nil
}

func (hl *HTTPLog) logResponseBody(original io.ReadCloser, headers http.Header) (io.ReadCloser, error) {
	defer original.Close()

	var bs bytes.Buffer
	_, err := io.Copy(&bs, original)
	if err != nil {
		return nil, err
	}

	contentType := headers.Get("Content-Type")
	if strings.HasPrefix(contentType, "application/json") {
		debugInfo := hl.formatJSON(bs.Bytes())
		if debugInfo != "" {
			hl.Logger.Debugf("Response Body: %s", debugInfo)
		}
	} else {
		hl.Logger.Debugf("Not logging because response body isn't JSON")
	}

	return ioutil.NopCloser(strings.NewReader(bs.String())), nil
}

func (hl *HTTPLog) formatJSON(raw []byte) string {
	var data map[string]interface{}

	err := json.Unmarshal(raw, &data)
	if err != nil {
		return string(raw)
	}

	pretty, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		return string(raw)
	}

	return string(pretty)
}
<|endoftext|>


<commit_before>package console

import (
	"fmt"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/getcarina/carina/common"
	"github.com/pkg/errors"
)

type tuple struct {
	key   string
	value interface{}
}

// Write prints text to the console
func Write(format string, a ...interface{}) {
	if common.Log.IsSilent {
		return
	}

	if !strings.HasSuffix(format, "\n") {
		format += "\n"
	}

	fmt.Printf(format, a...)
}

// WriteTable prints rows of tabular data to the console
func WriteTable(fields [][]string) {
	output := new(tabwriter.Writer)
	output.Init(os.Stdout, 0, 8, 1, '\t', 0)

	for _, row := range fields {
		writeInColumns(output, row)
	}
	output.Flush()
}

// WriteCluster prints the cluster data to the console
func WriteCluster(cluster common.Cluster) {
	output := new(tabwriter.Writer)
	output.Init(os.Stdout, 0, 8, 2, '\t', 0)

	fields := []tuple{
		tuple{"ID", cluster.GetID()},
		tuple{"Name", cluster.GetName()},
		tuple{"Status", cluster.GetStatus()},
		tuple{"Template", cluster.GetTemplate().GetName()},
		tuple{"Nodes", cluster.GetNodes()},
		tuple{"Details", cluster.GetStatusDetails()},
	}
	writeInRows(output, fields)
	output.Flush()
}

// WriteClusters prints the clusters data to the console
func WriteClusters(clusters []common.Cluster) {
	output := new(tabwriter.Writer)
	output.Init(os.Stdout, 0, 8, 1, '\t', 0)

	headerFields := []string{
		"ID",
		"Name",
		"Status",
		"Template",
		"Nodes",
	}
	writeInColumns(output, headerFields)

	for _, cluster := range clusters {
		fields := []string{
			cluster.GetID(),
			cluster.GetName(),
			cluster.GetStatus(),
			cluster.GetTemplate().GetName(),
			cluster.GetNodes(),
		}
		writeInColumns(output, fields)
	}

	output.Flush()
}

func writeInColumns(output *tabwriter.Writer, columns []string) {
	s := strings.Join(columns, "\t")
	b := []byte(s + "\n")
	_, err := output.Write(b)
	if err != nil {
		err = errors.Wrap(err, "Unable to write to console.")
		fmt.Println(err.Error())
	}
}

func writeInRows(output *tabwriter.Writer, rows []tuple) {
	for _, row := range rows {
		// Use the default string conversion when displaying the value
		val := fmt.Sprint(row.value)

		// Indent multi-line values
		val = strings.Replace(val, "\n", "\n\t", -1)

		_, err := fmt.Fprintf(output, "%s\t%s\n", row.key, val)
		if err != nil {
			err = errors.Wrap(err, "Unable to write to console.")
			fmt.Println(err.Error())
		}
	}
}
<commit_msg>Use spaces instead of tabs when printing tables<commit_after>package console

import (
	"fmt"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/getcarina/carina/common"
	"github.com/pkg/errors"
)

type tuple struct {
	key   string
	value interface{}
}

// Write prints text to the console
func Write(format string, a ...interface{}) {
	if common.Log.IsSilent {
		return
	}

	if !strings.HasSuffix(format, "\n") {
		format += "\n"
	}

	fmt.Printf(format, a...)
}

// WriteTable prints rows of tabular data to the console
func WriteTable(fields [][]string) {
	output := new(tabwriter.Writer)
	output.Init(os.Stdout, 0, 8, 1, ' ', 0)

	for _, row := range fields {
		writeInColumns(output, row)
	}
	output.Flush()
}

// WriteCluster prints the cluster data to the console
func WriteCluster(cluster common.Cluster) {
	output := new(tabwriter.Writer)
	output.Init(os.Stdout, 0, 8, 2, ' ', 0)

	fields := []tuple{
		tuple{"ID", cluster.GetID()},
		tuple{"Name", cluster.GetName()},
		tuple{"Status", cluster.GetStatus()},
		tuple{"Template", cluster.GetTemplate().GetName()},
		tuple{"Nodes", cluster.GetNodes()},
		tuple{"Details", cluster.GetStatusDetails()},
	}
	writeInRows(output, fields)
	output.Flush()
}

// WriteClusters prints the clusters data to the console
func WriteClusters(clusters []common.Cluster) {
	output := new(tabwriter.Writer)
	output.Init(os.Stdout, 0, 8, 1, ' ', 0)

	headerFields := []string{
		"ID",
		"Name",
		"Status",
		"Template",
		"Nodes",
	}
	writeInColumns(output, headerFields)

	for _, cluster := range clusters {
		fields := []string{
			cluster.GetID(),
			cluster.GetName(),
			cluster.GetStatus(),
			cluster.GetTemplate().GetName(),
			cluster.GetNodes(),
		}
		writeInColumns(output, fields)
	}

	output.Flush()
}

func writeInColumns(output *tabwriter.Writer, columns []string) {
	s := strings.Join(columns, "\t")
	b := []byte(s + "\n")
	_, err := output.Write(b)
	if err != nil {
		err = errors.Wrap(err, "Unable to write to console.")
		fmt.Println(err.Error())
	}
}

func writeInRows(output *tabwriter.Writer, rows []tuple) {
	for _, row := range rows {
		// Use the default string conversion when displaying the value
		val := fmt.Sprint(row.value)

		// Indent multi-line values
		val = strings.Replace(val, "\n", "\n\t", -1)

		_, err := fmt.Fprintf(output, "%s\t%s\n", row.key, val)
		if err != nil {
			err = errors.Wrap(err, "Unable to write to console.")
			fmt.Println(err.Error())
		}
	}
}
<|endoftext|>