<commit_before>package metrics

import (
	"reflect"
	"strconv"

	log "github.com/cihub/seelog"
	"github.com/fatih/structs"
	serverprotocol "github.com/stampzilla/stampzilla-go/nodes/stampzilla-server/protocol"
)

type Logger interface {
	Log(key string, value interface{})
	Commit(node interface{})
}

type Metrics struct {
	previous map[string]interface{}
	loggers  []Logger
	queue    chan interface{}
}

func New() *Metrics {
	return &Metrics{
		make(map[string]interface{}),
		nil,
		make(chan interface{}, 100),
	}
}
func (m *Metrics) AddLogger(l Logger) {
	log.Infof("Adding logger: %T\n", l)
	m.loggers = append(m.loggers, l)
}
func (m *Metrics) Start() {
	go m.worker()
}
func (m *Metrics) worker() {
	for s := range m.queue {
		m.update(s)
	}
}
func (m *Metrics) Update(s interface{}) {
	m.queue <- s
}

func (m *Metrics) update(s interface{}) {
	if len(m.loggers) == 0 {
		return
	}

	current := structToMetrics(s)
	if len(m.previous) == 0 {
		m.previous = current
		return
	}

	changed := false
	for k, v := range current {
		if m.isDiff(k, v) {
			log.Info("found diff. logging!")
			m.log(k, v)
			changed = true
		}
	}

	if changed {
		for _, l := range m.loggers {
			l.Commit(s)
		}
	}
	m.previous = current
}

func (m *Metrics) log(key string, value interface{}) {
	for _, l := range m.loggers {
		l.Log(key, value)
	}
}
func (m *Metrics) isDiff(k string, v interface{}) bool {
	if oldValue, ok := m.previous[k]; ok {
		if oldValue != v {
			return true
		}
	}
	return false
}

func structToMetrics(s interface{}) map[string]interface{} {
	flattened := make(map[string]interface{})
	baseName := ""
	if node, ok := s.(serverprotocol.Node); ok {
		//st := structs.New(node)
		baseName = node.Uuid
	}
	flatten(structs.Map(s), baseName, &flattened)
	return flattened
}

func flatten(inputJSON map[string]interface{}, lkey string, flattened *map[string]interface{}) {
	for rkey, value := range inputJSON {
		key := lkey + "_" + rkey
		if lkey == "" {
			key = rkey
		}

		if value == nil {
			continue
		}

		if structs.IsStruct(value) {
			//fmt.Println("Its a struct: ", value)
			value = structs.Map(value)
		}
		reflectValue := reflect.ValueOf(value)
		if reflectValue.Type().Kind() == reflect.Map {
			//fmt.Println("its a map: ", value)
			out := make(map[string]interface{})
			for _, b := range reflectValue.MapKeys() {
				out[b.String()] = reflectValue.MapIndex(b).Interface()
			}
			value = out
		}

		switch v := value.(type) {
		case map[string]interface{}:
			flatten(v, key, flattened)
		default:
			(*flattened)[key] = cast(v)
		}

	}
}

func cast(s interface{}) interface{} {
	switch v := s.(type) {
	case int:
		return v
		//return strconv.Itoa(v)
	case float64:
		//return strconv.FormatFloat(v, 'f', -1, 64)
		return v
	case string:
		if n, err := strconv.Atoi(v); err == nil {
			return n
		}
		return v
	case bool:
		if v {
			return 1
		}
		return 0
	}
	return ""
}
<commit_msg>dont remove previous from other nodes. just append new keys<commit_after>package metrics

import (
	"reflect"
	"strconv"

	log "github.com/cihub/seelog"
	"github.com/fatih/structs"
	serverprotocol "github.com/stampzilla/stampzilla-go/nodes/stampzilla-server/protocol"
)

type Logger interface {
	Log(key string, value interface{})
	Commit(node interface{})
}

type Metrics struct {
	previous map[string]interface{}
	loggers  []Logger
	queue    chan interface{}
}

func New() *Metrics {
	return &Metrics{
		make(map[string]interface{}),
		nil,
		make(chan interface{}, 100),
	}
}
func (m *Metrics) AddLogger(l Logger) {
	log.Infof("Adding logger: %T\n", l)
	m.loggers = append(m.loggers, l)
}
func (m *Metrics) Start() {
	go m.worker()
}
func (m *Metrics) worker() {
	for s := range m.queue {
		m.update(s)
	}
}
func (m *Metrics) Update(s interface{}) {
	m.queue <- s
}

func (m *Metrics) update(s interface{}) {
	if len(m.loggers) == 0 {
		return
	}

	current := structToMetrics(s)
	if len(m.previous) == 0 {
		m.previous = current
		return
	}

	changed := false
	for k, v := range current {
		if m.isDiff(k, v) {
			log.Info("found diff. logging!")
			m.log(k, v)
			changed = true
		}
	}

	if changed {
		for _, l := range m.loggers {
			l.Commit(s)
		}
	}
	m.updatePrevious(current)
}

func (m *Metrics) updatePrevious(s map[string]interface{}) {
	for k, v := range s {
		m.previous[k] = v
	}
}

func (m *Metrics) log(key string, value interface{}) {
	for _, l := range m.loggers {
		l.Log(key, value)
	}
}
func (m *Metrics) isDiff(k string, v interface{}) bool {
	if oldValue, ok := m.previous[k]; ok {
		if oldValue != v {
			return true
		}
	}
	return false
}

func structToMetrics(s interface{}) map[string]interface{} {
	flattened := make(map[string]interface{})
	baseName := ""
	if node, ok := s.(serverprotocol.Node); ok {
		//st := structs.New(node)
		baseName = node.Uuid
	}
	flatten(structs.Map(s), baseName, &flattened)
	return flattened
}

func flatten(inputJSON map[string]interface{}, lkey string, flattened *map[string]interface{}) {
	for rkey, value := range inputJSON {
		key := lkey + "_" + rkey
		if lkey == "" {
			key = rkey
		}

		if value == nil {
			continue
		}

		if structs.IsStruct(value) {
			//fmt.Println("Its a struct: ", value)
			value = structs.Map(value)
		}
		reflectValue := reflect.ValueOf(value)
		if reflectValue.Type().Kind() == reflect.Map {
			//fmt.Println("its a map: ", value)
			out := make(map[string]interface{})
			for _, b := range reflectValue.MapKeys() {
				out[b.String()] = reflectValue.MapIndex(b).Interface()
			}
			value = out
		}

		switch v := value.(type) {
		case map[string]interface{}:
			flatten(v, key, flattened)
		default:
			(*flattened)[key] = cast(v)
		}

	}
}

func cast(s interface{}) interface{} {
	switch v := s.(type) {
	case int:
		return v
		//return strconv.Itoa(v)
	case float64:
		//return strconv.FormatFloat(v, 'f', -1, 64)
		return v
	case string:
		if n, err := strconv.Atoi(v); err == nil {
			return n
		}
		return v
	case bool:
		if v {
			return 1
		}
		return 0
	}
	return ""
}
<|endoftext|>


<commit_before>package meta

import "crypto/md5"

// StreamInfo contains information about the FLAC audio stream, such as its
// sample rate and channel count. It must be  present as the first metadata
// block of a FLAC stream.
//
// ref: https://www.xiph.org/flac/format.html#metadata_block_streaminfo
type StreamInfo struct {
	// Minimum block size (in samples) used in the stream.
	BlockSizeMin uint16
	// Maximum block size (in samples) used in the stream.
	BlockSizeMax uint16
	// Minimum frame size in bytes; a 0 value implies unknown.
	FrameSizeMin uint32
	// Maximum frame size in bytes; a 0 value implies unknown.
	FrameSizeMax uint32
	// Sample rate in Hz; between 1 and 655350 Hz.
	SampleRate uint32
	// Number of channels; between 1 and 8 channels.
	NChannels uint8
	// Sample size in bits-per-sample; between 4 and 32 bits.
	BitsPerSample uint8
	// Total number of inter-channel samples in the stream. One second of 44.1
	// KHz audio will have 44100 samples regardless of the number of channels. A
	// 0 value implies unknown.
	NSamples uint64
	// MD5 checksum of the unencoded audio data.
	MD5sum [md5.BlockSize]uint8
}
<commit_msg>meta: Update StreamInfo doc comment.<commit_after>package meta

import "crypto/md5"

// StreamInfo contains the basic properties of a FLAC audio stream, such as its
// sample rate and channel count. It is the only mandatory metadata block and
// must be present as the first metadata block of a FLAC stream.
//
// ref: https://www.xiph.org/flac/format.html#metadata_block_streaminfo
type StreamInfo struct {
	// Minimum block size (in samples) used in the stream.
	BlockSizeMin uint16
	// Maximum block size (in samples) used in the stream.
	BlockSizeMax uint16
	// Minimum frame size in bytes; a 0 value implies unknown.
	FrameSizeMin uint32
	// Maximum frame size in bytes; a 0 value implies unknown.
	FrameSizeMax uint32
	// Sample rate in Hz; between 1 and 655350 Hz.
	SampleRate uint32
	// Number of channels; between 1 and 8 channels.
	NChannels uint8
	// Sample size in bits-per-sample; between 4 and 32 bits.
	BitsPerSample uint8
	// Total number of inter-channel samples in the stream. One second of 44.1
	// KHz audio will have 44100 samples regardless of the number of channels. A
	// 0 value implies unknown.
	NSamples uint64
	// MD5 checksum of the unencoded audio data.
	MD5sum [md5.BlockSize]uint8
}
<|endoftext|>


<commit_before>package ircClient

import (
	"fmt"
	"log"
	"time"

	"github.com/belak/irc"
	"github.com/khades/servbot/models"
	"github.com/khades/servbot/repos"
)

// IrcClient struct defines object that will send messages to a twitch server
type IrcClient struct {
	Client  *irc.Client
	Bounces map[string]time.Time
	Ready   bool
}

// SendDebounced prevents from sending data too frequent in public chat sending it to a PM
func (ircClient IrcClient) SendDebounced(message models.OutgoingDebouncedMessage) {
	key := fmt.Sprintf("%s-%s", message.Message.Channel, message.Command)
	if ircClient.Bounces == nil {
		ircClient.Bounces = make(map[string]time.Time)
	}
	bounce, found := ircClient.Bounces[key]
	if found && int(time.Now().Sub(bounce).Seconds()) < 15 {
		ircClient.SendPrivate(&message.Message)
	} else {
		ircClient.Bounces[key] = time.Now()
		ircClient.SendPublic(&models.OutgoingMessage{
			Channel: message.Message.Channel,
			Body:    message.Message.Body,
			User:    message.RedirectTo})
	}
}

// SendRaw is wrapper to Write
func (ircClient IrcClient) SendRaw(message string) {
	if ircClient.Ready {
		ircClient.Client.Write(message)
	}
}

// SendPublic writes data to a specified chat
func (ircClient IrcClient) SendPublic(message *models.OutgoingMessage) {
	if ircClient.Ready {
		if message.User != "" {
			ircClient.Client.Write(fmt.Sprintf("PRIVMSG #%s :@%s %s", message.Channel, message.User, message.Body))
		} else {
			ircClient.Client.Write(fmt.Sprintf("PRIVMSG #%s :%s", message.Channel, message.Body))
		}
	}
}

// SendPrivate writes data in private to a user
func (ircClient IrcClient) SendPrivate(message *models.OutgoingMessage) {
	if ircClient.Ready && message.User != "" {
		ircClient.Client.Write(fmt.Sprintf("PRIVMSG #jtv :/w %s Channel %s: %s", message.User, message.Channel, message.Body))
	}
}

// SendModsCommand runs mod command
func (ircClient IrcClient) SendModsCommand() {
	log.Println("Sending MODS")
	if ircClient.Ready {
		for _, value := range repos.Config.Channels {
			ircClient.SendPublic(&models.OutgoingMessage{Channel: value, Body: "/mods"})
		}
	}
}
<commit_msg>Fix: Disabling mods temporarily<commit_after>package ircClient

import (
	"fmt"
	"log"
	"time"

	"github.com/belak/irc"
	"github.com/khades/servbot/models"
)

// IrcClient struct defines object that will send messages to a twitch server
type IrcClient struct {
	Client  *irc.Client
	Bounces map[string]time.Time
	Ready   bool
}

// SendDebounced prevents from sending data too frequent in public chat sending it to a PM
func (ircClient IrcClient) SendDebounced(message models.OutgoingDebouncedMessage) {
	key := fmt.Sprintf("%s-%s", message.Message.Channel, message.Command)
	if ircClient.Bounces == nil {
		ircClient.Bounces = make(map[string]time.Time)
	}
	bounce, found := ircClient.Bounces[key]
	if found && int(time.Now().Sub(bounce).Seconds()) < 15 {
		ircClient.SendPrivate(&message.Message)
	} else {
		ircClient.Bounces[key] = time.Now()
		ircClient.SendPublic(&models.OutgoingMessage{
			Channel: message.Message.Channel,
			Body:    message.Message.Body,
			User:    message.RedirectTo})
	}
}

// SendRaw is wrapper to Write
func (ircClient IrcClient) SendRaw(message string) {
	if ircClient.Ready {
		ircClient.Client.Write(message)
	}
}

// SendPublic writes data to a specified chat
func (ircClient IrcClient) SendPublic(message *models.OutgoingMessage) {
	if ircClient.Ready {
		if message.User != "" {
			ircClient.Client.Write(fmt.Sprintf("PRIVMSG #%s :@%s %s", message.Channel, message.User, message.Body))
		} else {
			ircClient.Client.Write(fmt.Sprintf("PRIVMSG #%s :%s", message.Channel, message.Body))
		}
	}
}

// SendPrivate writes data in private to a user
func (ircClient IrcClient) SendPrivate(message *models.OutgoingMessage) {
	if ircClient.Ready && message.User != "" {
		ircClient.Client.Write(fmt.Sprintf("PRIVMSG #jtv :/w %s Channel %s: %s", message.User, message.Channel, message.Body))
	}
}

// SendModsCommand runs mod command
func (ircClient IrcClient) SendModsCommand() {
	log.Println("Sending MODS")
	// if ircClient.Ready {
	// 	for _, value := range repos.Config.Channels {
	// 		ircClient.SendPublic(&models.OutgoingMessage{Channel: value, Body: "/mods"})
	// 	}
	// }
}
<|endoftext|>


<commit_before>package sheet

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"

	"github.com/howeyc/sc/sheet/align"
)

// Load a sheet.
func (s *Sheet) Load() {
	if file, err := os.Open(s.Filename); err == nil {
		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			line := scanner.Text()
			if strings.HasPrefix(line, "#") || len(line) < 1 {
				continue
			}
			words := strings.Split(line, " ")
			cmd := ""
			adrs := Address("")
			val := ""
			if len(words) >= 2 {
				cmd = words[0]
				adrs = Address(words[1])
			}
			if len(words) >= 4 {
				val = strings.Join(words[3:], " ")
			}
			if len(val) > 1 && val[0] == '"' {
				val = val[1 : len(val)-1]
			}
			switch cmd {
			case "leftstring":
				s.SetCell(adrs, NewCell(val, align.AlignLeft, true))
			case "rightstrng":
				s.SetCell(adrs, NewCell(val, align.AlignRight, true))
			case "label":
				s.SetCell(adrs, NewCell(val, align.AlignCenter, true))
			case "let":
				s.SetCell(adrs, NewCell(val, align.AlignRight, false))
			case "goto":
				s.SelectedCell = adrs
			case "format":
				width, _ := strconv.ParseInt(words[2], 10, 64)
				precision, _ := strconv.ParseInt(words[3], 10, 64)
				ctype, _ := strconv.ParseInt(words[4], 10, 64)
				s.columnFormats[adrs.ColumnHeader()] = ColumnFormat{width: int(width), precision: int(precision), ctype: int(ctype)}
			}
		}
	}
}

// Write a cell as a line to a writer.
func (c *Cell) write(w io.Writer, address string) {
	if c.stringType && c.alignment == align.AlignLeft {
		fmt.Fprintf(w, "leftstring %s = \"%s\"\n", address, c.value)
	} else if c.stringType && c.alignment == align.AlignCenter {
		fmt.Fprintf(w, "label %s = \"%s\"\n", address, c.value)
	} else if c.stringType {
		fmt.Fprintf(w, "rightstring %s = \"%s\"\n", address, c.value)
	} else {
		fmt.Fprintf(w, "let %s = %s\n", address, c.value)
	}
}

// Writes the formats for all the defined columns in the sheet.
func (s *Sheet) writeFormats(w io.Writer) {
	for k, cFormat := range s.columnFormats {
		fmt.Fprintf(w, "format %s %d %d %d\n", k, cFormat.width, cFormat.precision, cFormat.ctype)
	}
}

// Save a sheet.
func (s *Sheet) Save() error {
	if outfile, err := os.Create(s.Filename); err == nil {
		fmt.Fprintln(outfile, "# This data file was generated by Spreadsheet Calculator.")
		fmt.Fprintln(outfile, "# You almost certainly shouldn't edit it.")
		fmt.Fprintln(outfile, "")

		s.writeFormats(outfile)

		for addr, cell := range s.data {
			cell.write(outfile, string(addr))
		}
		fmt.Fprintf(outfile, "goto %s A0", s.SelectedCell)
		outfile.Close()
		return nil
	} else {
		return err
	}
}
<commit_msg>Format string does not contain a row, only column.<commit_after>package sheet

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"

	"github.com/howeyc/sc/sheet/align"
)

// Load a sheet.
func (s *Sheet) Load() {
	if file, err := os.Open(s.Filename); err == nil {
		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			line := scanner.Text()
			if strings.HasPrefix(line, "#") || len(line) < 1 {
				continue
			}
			words := strings.Split(line, " ")
			cmd := ""
			adrs := Address("")
			val := ""
			if len(words) >= 2 {
				cmd = words[0]
				adrs = Address(words[1])
			}
			if len(words) >= 4 {
				val = strings.Join(words[3:], " ")
			}
			if len(val) > 1 && val[0] == '"' {
				val = val[1 : len(val)-1]
			}
			switch cmd {
			case "leftstring":
				s.SetCell(adrs, NewCell(val, align.AlignLeft, true))
			case "rightstrng":
				s.SetCell(adrs, NewCell(val, align.AlignRight, true))
			case "label":
				s.SetCell(adrs, NewCell(val, align.AlignCenter, true))
			case "let":
				s.SetCell(adrs, NewCell(val, align.AlignRight, false))
			case "goto":
				s.SelectedCell = adrs
			case "format":
				width, _ := strconv.ParseInt(words[2], 10, 64)
				precision, _ := strconv.ParseInt(words[3], 10, 64)
				ctype, _ := strconv.ParseInt(words[4], 10, 64)
				s.columnFormats[string(adrs)] = ColumnFormat{width: int(width), precision: int(precision), ctype: int(ctype)}
			}
		}
	}
}

// Write a cell as a line to a writer.
func (c *Cell) write(w io.Writer, address string) {
	if c.stringType && c.alignment == align.AlignLeft {
		fmt.Fprintf(w, "leftstring %s = \"%s\"\n", address, c.value)
	} else if c.stringType && c.alignment == align.AlignCenter {
		fmt.Fprintf(w, "label %s = \"%s\"\n", address, c.value)
	} else if c.stringType {
		fmt.Fprintf(w, "rightstring %s = \"%s\"\n", address, c.value)
	} else {
		fmt.Fprintf(w, "let %s = %s\n", address, c.value)
	}
}

// Writes the formats for all the defined columns in the sheet.
func (s *Sheet) writeFormats(w io.Writer) {
	for k, cFormat := range s.columnFormats {
		fmt.Fprintf(w, "format %s %d %d %d\n", k, cFormat.width, cFormat.precision, cFormat.ctype)
	}
}

// Save a sheet.
func (s *Sheet) Save() error {
	if outfile, err := os.Create(s.Filename); err == nil {
		fmt.Fprintln(outfile, "# This data file was generated by Spreadsheet Calculator.")
		fmt.Fprintln(outfile, "# You almost certainly shouldn't edit it.")
		fmt.Fprintln(outfile, "")

		s.writeFormats(outfile)

		for addr, cell := range s.data {
			cell.write(outfile, string(addr))
		}
		fmt.Fprintf(outfile, "goto %s A0", s.SelectedCell)
		outfile.Close()
		return nil
	} else {
		return err
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package leveldb

import (
	"leveldb/cache"
	"leveldb/comparer"
	"leveldb/filter"
	"leveldb/opt"
)

type iOptions struct {
	opt.Options
	s *session
}

func newIOptions(s *session, o opt.Options) *iOptions {
	p := &iOptions{Options: o, s: s}
	p.sanitize()
	return p
}

func (o *iOptions) sanitize() {
	if p := o.GetBlockCache(); p == nil {
		o.Options.SetBlockCache(cache.NewLRUCache(opt.DefaultBlockCacheSize))
	}

	if p := o.GetFilter(); p != nil {
		o.Options.SetFilter(&iFilter{p})
	}
}

func (o *iOptions) GetComparer() comparer.Comparer {
	return o.s.cmp
}

func (o *iOptions) SetComparer(cmp comparer.Comparer) error {
	return opt.ErrNotAllowed
}

func (o *iOptions) SetMaxOpenFiles(max int) error {
	err := o.Options.SetMaxOpenFiles(max)
	if err != nil {
		return err
	}
	o.s.tops.cache.SetCapacity(max)
	return nil
}

func (o *iOptions) SetBlockCache(cache cache.Cache) error {
	err := o.Options.SetBlockCache(cache)
	if err != nil {
		return err
	}
	o.s.tops.cache.Purge(nil)
	return nil
}

func (o *iOptions) SetFilter(p filter.Filter) error {
	if p != nil {
		p = &iFilter{p}
	}
	return o.Options.SetFilter(p)
}
<commit_msg>leveldb: options: SetBlockCache: purge old block cache<commit_after>// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package leveldb

import (
	"leveldb/cache"
	"leveldb/comparer"
	"leveldb/filter"
	"leveldb/opt"
)

type iOptions struct {
	opt.Options
	s *session
}

func newIOptions(s *session, o opt.Options) *iOptions {
	p := &iOptions{Options: o, s: s}
	p.sanitize()
	return p
}

func (o *iOptions) sanitize() {
	if p := o.GetBlockCache(); p == nil {
		o.Options.SetBlockCache(cache.NewLRUCache(opt.DefaultBlockCacheSize))
	}

	if p := o.GetFilter(); p != nil {
		o.Options.SetFilter(&iFilter{p})
	}
}

func (o *iOptions) GetComparer() comparer.Comparer {
	return o.s.cmp
}

func (o *iOptions) SetComparer(cmp comparer.Comparer) error {
	return opt.ErrNotAllowed
}

func (o *iOptions) SetMaxOpenFiles(max int) error {
	err := o.Options.SetMaxOpenFiles(max)
	if err != nil {
		return err
	}
	o.s.tops.cache.SetCapacity(max)
	return nil
}

func (o *iOptions) SetBlockCache(cache cache.Cache) error {
	oldcache := o.Options.GetBlockCache()
	err := o.Options.SetBlockCache(cache)
	if err != nil {
		return err
	}
	if oldcache != nil {
		oldcache.Purge(nil)
	}
	o.s.tops.cache.Purge(nil)
	return nil
}

func (o *iOptions) SetFilter(p filter.Filter) error {
	if p != nil {
		p = &iFilter{p}
	}
	return o.Options.SetFilter(p)
}
<|endoftext|>


<commit_before>package cmd

import (
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

// Version is the current version of the buffalo binary
const Version = "v0.11.0"

func init() {
	decorate("version", versionCmd)
	RootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of buffalo",
	Long:  `All software has versions.  This is buffalo's.`,
	Run: func(c *cobra.Command, args []string) {
		logrus.Infof("Buffalo version is: %s\n", Version)
	},
	// needed to override the root level pre-run func
	PersistentPreRunE: func(c *cobra.Command, args []string) error {
		return nil
	},
}
<commit_msg>setup for development<commit_after>package cmd

import (
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

// Version is the current version of the buffalo binary
// const Version = "v0.11.0"
const Version = "development"

func init() {
	decorate("version", versionCmd)
	RootCmd.AddCommand(versionCmd)
}

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of buffalo",
	Long:  `All software has versions.  This is buffalo's.`,
	Run: func(c *cobra.Command, args []string) {
		logrus.Infof("Buffalo version is: %s\n", Version)
	},
	// needed to override the root level pre-run func
	PersistentPreRunE: func(c *cobra.Command, args []string) error {
		return nil
	},
}
<|endoftext|>


<commit_before>package log

import (
	"encoding"
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"time"
	"unicode/utf8"
)

// JSONFormat implements Formatter for JSON Lines.
//
// http://jsonlines.org/
type JSONFormat struct {
	// Utsname can normally be left blank.
	// If not empty, the string is used instead of the hostname.
	// Utsname must match this regexp: ^[a-z][a-z0-9-]*$
	Utsname string
}

// String returns "json".
func (f JSONFormat) String() string {
	return "json"
}

// Format implements Formatter.Format.
func (f JSONFormat) Format(buf []byte, l *Logger, t time.Time, severity int,
	msg string, fields map[string]interface{}) ([]byte, error) {
	var err error

	// assume enough capacity for mandatory fields (except for msg).
	buf = append(buf, `{"topic":"`...)
	buf = append(buf, l.Topic()...)
	buf = append(buf, `","logged_at":"`...)
	buf = t.UTC().AppendFormat(buf, RFC3339Micro)
	buf = append(buf, `","severity":`...)
	if ss, ok := severityMap[severity]; ok {
		buf = append(buf, '"')
		buf = append(buf, ss...)
		buf = append(buf, '"')
	} else {
		buf = strconv.AppendInt(buf, int64(severity), 10)
	}
	buf = append(buf, `,"utsname":"`...)
	if len(f.Utsname) > 0 {
		buf = append(buf, f.Utsname...)
	} else {
		buf = append(buf, utsname...)
	}
	buf = append(buf, `","message":`...)
	buf, err = appendJSON(buf, msg)
	if err != nil {
		return nil, err
	}

	for k, v := range fields {
		if !IsValidKey(k) {
			return nil, ErrInvalidKey
		}

		if cap(buf) < (len(k) + 4) {
			return nil, ErrTooLarge
		}
		buf = append(buf, `,"`...)
		buf = append(buf, k...)
		buf = append(buf, `":`...)
		buf, err = appendJSON(buf, v)
		if err != nil {
			return nil, err
		}
	}

	for k, v := range l.Defaults() {
		if _, ok := fields[k]; ok {
			continue
		}

		if cap(buf) < (len(k) + 4) {
			return nil, ErrTooLarge
		}
		buf = append(buf, `,"`...)
		buf = append(buf, k...)
		buf = append(buf, `":`...)
		buf, err = appendJSON(buf, v)
		if err != nil {
			return nil, err
		}
	}

	if cap(buf) < 2 {
		return nil, ErrTooLarge
	}
	return append(buf, "}\n"...), nil
}

func appendJSON(buf []byte, v interface{}) ([]byte, error) {
	var err error

	switch t := v.(type) {
	case nil:
		if cap(buf) < 4 {
			return nil, ErrTooLarge
		}
		return append(buf, "null"...), nil
	case bool:
		if cap(buf) < 5 { // len("false")
			return nil, ErrTooLarge
		}
		return strconv.AppendBool(buf, t), nil
	case time.Time:
		// len("2006-01-02T15:04:05.000000Z07:00") + 2
		if cap(buf) < 34 {
			return nil, ErrTooLarge
		}
		buf = append(buf, '"')
		buf = t.UTC().AppendFormat(buf, RFC3339Micro)
		return append(buf, '"'), nil
	case int:
		// len("-9223372036854775807")
		if cap(buf) < 20 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, int64(t), 10), nil
	case int8:
		// len("-128")
		if cap(buf) < 4 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, int64(t), 10), nil
	case int16:
		// len("-32768")
		if cap(buf) < 6 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, int64(t), 10), nil
	case int32:
		// len("-2147483648")
		if cap(buf) < 11 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, int64(t), 10), nil
	case int64:
		// len("-9223372036854775807")
		if cap(buf) < 20 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, t, 10), nil
	case uint:
		// len("18446744073709551615")
		if cap(buf) < 20 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, uint64(t), 10), nil
	case uint8:
		// len("255")
		if cap(buf) < 3 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, uint64(t), 10), nil
	case uint16:
		// len("65535")
		if cap(buf) < 5 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, uint64(t), 10), nil
	case uint32:
		// len("4294967295")
		if cap(buf) < 10 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, uint64(t), 10), nil
	case uint64:
		// len("18446744073709551615")
		if cap(buf) < 20 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, t, 10), nil
	case float32:
		if cap(buf) < 256 {
			return nil, ErrTooLarge
		}
		return strconv.AppendFloat(buf, float64(t), 'f', -1, 32), nil
	case float64:
		if cap(buf) < 256 {
			return nil, ErrTooLarge
		}
		return strconv.AppendFloat(buf, t, 'f', -1, 64), nil
	case string:
		if !utf8.ValidString(t) {
			// the next line replaces invalid characters.
			t = string([]rune(t))
		}
		// escaped length = 2*len(t) + 2 double quotes
		if cap(buf) < (len(t)*2 + 2) {
			return nil, ErrTooLarge
		}
		return strconv.AppendQuote(buf, t), nil
	case json.Marshaler:
		s, err := t.MarshalJSON()
		if err != nil {
			return nil, err
		}
		if cap(buf) < len(s) {
			return nil, ErrTooLarge
		}
		// normalize for JSON Lines
		for i, b := range s {
			if b == '\n' || b == '\r' {
				s[i] = ' '
			}
		}
		return append(buf, s...), nil
	case encoding.TextMarshaler:
		// TextMarshaler encodes into UTF-8 string.
		s, err := t.MarshalText()
		if err != nil {
			return nil, err
		}
		if cap(buf) < (len(s)*2 + 2) {
			return nil, ErrTooLarge
		}
		return strconv.AppendQuote(buf, string(s)), nil
	case error:
		s := t.Error()
		if !utf8.ValidString(s) {
			// the next line replaces invalid characters.
			s = string([]rune(s))
		}
		// escaped length = 2*len(s) + 2 double quotes
		if cap(buf) < (len(s)*2 + 2) {
			return nil, ErrTooLarge
		}
		return strconv.AppendQuote(buf, s), nil
	}

	value := reflect.ValueOf(v)
	typ := value.Type()
	kind := typ.Kind()

	// string-keyed maps
	if kind == reflect.Map && typ.Key().Kind() == reflect.String {
		if cap(buf) < 1 {
			return nil, ErrTooLarge
		}
		buf = append(buf, '{')
		first := true
		for _, k := range value.MapKeys() {
			if !first {
				if cap(buf) < 1 {
					return nil, ErrTooLarge
				}
				buf = append(buf, ',')
			}
			buf, err = appendJSON(buf, k.String())
			if err != nil {
				return nil, err
			}
			if cap(buf) < 1 {
				return nil, ErrTooLarge
			}
			buf = append(buf, ':')
			buf, err = appendJSON(buf, value.MapIndex(k).Interface())
			if err != nil {
				return nil, err
			}
			first = false
		}
		if cap(buf) < 1 {
			return nil, ErrTooLarge
		}
		return append(buf, '}'), nil
	}

	// slices and arrays
	if kind == reflect.Slice || kind == reflect.Array {
		if cap(buf) < 1 {
			return nil, ErrTooLarge
		}
		buf = append(buf, '[')
		first := true
		for i := 0; i < value.Len(); i++ {
			if !first {
				if cap(buf) < 1 {
					return nil, ErrTooLarge
				}
				buf = append(buf, ',')
			}
			buf, err = appendJSON(buf, value.Index(i).Interface())
			if err != nil {
				return nil, err
			}
			first = false
		}
		if cap(buf) < 1 {
			return nil, ErrTooLarge
		}
		return append(buf, ']'), nil
	}

	// other types are just formatted as a string with "%#v".
	return appendJSON(buf, fmt.Sprintf("%#v", v))
}
<commit_msg>use strings.ToValidUTF8 to validate string<commit_after>package log

import (
	"encoding"
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

// JSONFormat implements Formatter for JSON Lines.
//
// http://jsonlines.org/
type JSONFormat struct {
	// Utsname can normally be left blank.
	// If not empty, the string is used instead of the hostname.
	// Utsname must match this regexp: ^[a-z][a-z0-9-]*$
	Utsname string
}

// String returns "json".
func (f JSONFormat) String() string {
	return "json"
}

// Format implements Formatter.Format.
func (f JSONFormat) Format(buf []byte, l *Logger, t time.Time, severity int,
	msg string, fields map[string]interface{}) ([]byte, error) {
	var err error

	// assume enough capacity for mandatory fields (except for msg).
	buf = append(buf, `{"topic":"`...)
	buf = append(buf, l.Topic()...)
	buf = append(buf, `","logged_at":"`...)
	buf = t.UTC().AppendFormat(buf, RFC3339Micro)
	buf = append(buf, `","severity":`...)
	if ss, ok := severityMap[severity]; ok {
		buf = append(buf, '"')
		buf = append(buf, ss...)
		buf = append(buf, '"')
	} else {
		buf = strconv.AppendInt(buf, int64(severity), 10)
	}
	buf = append(buf, `,"utsname":"`...)
	if len(f.Utsname) > 0 {
		buf = append(buf, f.Utsname...)
	} else {
		buf = append(buf, utsname...)
	}
	buf = append(buf, `","message":`...)
	buf, err = appendJSON(buf, msg)
	if err != nil {
		return nil, err
	}

	for k, v := range fields {
		if !IsValidKey(k) {
			return nil, ErrInvalidKey
		}

		if cap(buf) < (len(k) + 4) {
			return nil, ErrTooLarge
		}
		buf = append(buf, `,"`...)
		buf = append(buf, k...)
		buf = append(buf, `":`...)
		buf, err = appendJSON(buf, v)
		if err != nil {
			return nil, err
		}
	}

	for k, v := range l.Defaults() {
		if _, ok := fields[k]; ok {
			continue
		}

		if cap(buf) < (len(k) + 4) {
			return nil, ErrTooLarge
		}
		buf = append(buf, `,"`...)
		buf = append(buf, k...)
		buf = append(buf, `":`...)
		buf, err = appendJSON(buf, v)
		if err != nil {
			return nil, err
		}
	}

	if cap(buf) < 2 {
		return nil, ErrTooLarge
	}
	return append(buf, "}\n"...), nil
}

func appendJSON(buf []byte, v interface{}) ([]byte, error) {
	var err error

	switch t := v.(type) {
	case nil:
		if cap(buf) < 4 {
			return nil, ErrTooLarge
		}
		return append(buf, "null"...), nil
	case bool:
		if cap(buf) < 5 { // len("false")
			return nil, ErrTooLarge
		}
		return strconv.AppendBool(buf, t), nil
	case time.Time:
		// len("2006-01-02T15:04:05.000000Z07:00") + 2
		if cap(buf) < 34 {
			return nil, ErrTooLarge
		}
		buf = append(buf, '"')
		buf = t.UTC().AppendFormat(buf, RFC3339Micro)
		return append(buf, '"'), nil
	case int:
		// len("-9223372036854775807")
		if cap(buf) < 20 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, int64(t), 10), nil
	case int8:
		// len("-128")
		if cap(buf) < 4 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, int64(t), 10), nil
	case int16:
		// len("-32768")
		if cap(buf) < 6 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, int64(t), 10), nil
	case int32:
		// len("-2147483648")
		if cap(buf) < 11 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, int64(t), 10), nil
	case int64:
		// len("-9223372036854775807")
		if cap(buf) < 20 {
			return nil, ErrTooLarge
		}
		return strconv.AppendInt(buf, t, 10), nil
	case uint:
		// len("18446744073709551615")
		if cap(buf) < 20 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, uint64(t), 10), nil
	case uint8:
		// len("255")
		if cap(buf) < 3 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, uint64(t), 10), nil
	case uint16:
		// len("65535")
		if cap(buf) < 5 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, uint64(t), 10), nil
	case uint32:
		// len("4294967295")
		if cap(buf) < 10 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, uint64(t), 10), nil
	case uint64:
		// len("18446744073709551615")
		if cap(buf) < 20 {
			return nil, ErrTooLarge
		}
		return strconv.AppendUint(buf, t, 10), nil
	case float32:
		if cap(buf) < 256 {
			return nil, ErrTooLarge
		}
		return strconv.AppendFloat(buf, float64(t), 'f', -1, 32), nil
	case float64:
		if cap(buf) < 256 {
			return nil, ErrTooLarge
		}
		return strconv.AppendFloat(buf, t, 'f', -1, 64), nil
	case string:
		if !utf8.ValidString(t) {
			// the next line replaces invalid characters.
			t = strings.ToValidUTF8(t, string(utf8.RuneError))
		}
		// escaped length = 2*len(t) + 2 double quotes
		if cap(buf) < (len(t)*2 + 2) {
			return nil, ErrTooLarge
		}
		return strconv.AppendQuote(buf, t), nil
	case json.Marshaler:
		s, err := t.MarshalJSON()
		if err != nil {
			return nil, err
		}
		if cap(buf) < len(s) {
			return nil, ErrTooLarge
		}
		// normalize for JSON Lines
		for i, b := range s {
			if b == '\n' || b == '\r' {
				s[i] = ' '
			}
		}
		return append(buf, s...), nil
	case encoding.TextMarshaler:
		// TextMarshaler encodes into UTF-8 string.
		s, err := t.MarshalText()
		if err != nil {
			return nil, err
		}
		if cap(buf) < (len(s)*2 + 2) {
			return nil, ErrTooLarge
		}
		return strconv.AppendQuote(buf, string(s)), nil
	case error:
		s := t.Error()
		if !utf8.ValidString(s) {
			// the next line replaces invalid characters.
			s = strings.ToValidUTF8(s, string(utf8.RuneError))
		}
		// escaped length = 2*len(s) + 2 double quotes
		if cap(buf) < (len(s)*2 + 2) {
			return nil, ErrTooLarge
		}
		return strconv.AppendQuote(buf, s), nil
	}

	value := reflect.ValueOf(v)
	typ := value.Type()
	kind := typ.Kind()

	// string-keyed maps
	if kind == reflect.Map && typ.Key().Kind() == reflect.String {
		if cap(buf) < 1 {
			return nil, ErrTooLarge
		}
		buf = append(buf, '{')
		first := true
		for _, k := range value.MapKeys() {
			if !first {
				if cap(buf) < 1 {
					return nil, ErrTooLarge
				}
				buf = append(buf, ',')
			}
			buf, err = appendJSON(buf, k.String())
			if err != nil {
				return nil, err
			}
			if cap(buf) < 1 {
				return nil, ErrTooLarge
			}
			buf = append(buf, ':')
			buf, err = appendJSON(buf, value.MapIndex(k).Interface())
			if err != nil {
				return nil, err
			}
			first = false
		}
		if cap(buf) < 1 {
			return nil, ErrTooLarge
		}
		return append(buf, '}'), nil
	}

	// slices and arrays
	if kind == reflect.Slice || kind == reflect.Array {
		if cap(buf) < 1 {
			return nil, ErrTooLarge
		}
		buf = append(buf, '[')
		first := true
		for i := 0; i < value.Len(); i++ {
			if !first {
				if cap(buf) < 1 {
					return nil, ErrTooLarge
				}
				buf = append(buf, ',')
			}
			buf, err = appendJSON(buf, value.Index(i).Interface())
			if err != nil {
				return nil, err
			}
			first = false
		}
		if cap(buf) < 1 {
			return nil, ErrTooLarge
		}
		return append(buf, ']'), nil
	}

	// other types are just formatted as a string with "%#v".
	return appendJSON(buf, fmt.Sprintf("%#v", v))
}
<|endoftext|>


<commit_before>package brokers

import (
	"errors"

	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/log"
	"github.com/RichardKnop/machinery/v1/retry"
	"github.com/RichardKnop/machinery/v1/tasks"
)

// Broker represents a base broker structure
type Broker struct {
	cnf                 *config.Config
	registeredTaskNames []string
	retry               bool
	retryFunc           func(chan int)
	retryStopChan       chan int
	stopChan            chan int
}

// New creates new Broker instance
func New(cnf *config.Config) Broker {
	return Broker{cnf: cnf, retry: true}
}

// GetConfig returns config
func (b *Broker) GetConfig() *config.Config {
	return b.cnf
}

// StartConsuming enters a loop and waits for incoming messages
func (b *Broker) StartConsuming(consumerTag string, concurrency int, taskProcessor TaskProcessor) (bool, error) {
	return false, errors.New("Not implemented")
}

// Publish places a new message on the default queue
func (b *Broker) Publish(signature *tasks.Signature) error {
	return errors.New("Not implemented")
}

// StopConsuming quits the loop
func (b *Broker) StopConsuming() {
	//
}

// SetRegisteredTaskNames sets registered task names
func (b *Broker) SetRegisteredTaskNames(names []string) {
	b.registeredTaskNames = names
}

// IsTaskRegistered returns true if the task is registered with this broker
func (b *Broker) IsTaskRegistered(name string) bool {
	for _, registeredTaskName := range b.registeredTaskNames {
		if registeredTaskName == name {
			return true
		}
	}
	return false
}

// GetPendingTasks returns a slice of task.Signatures waiting in the queue
func (b *Broker) GetPendingTasks(queue string) ([]*tasks.Signature, error) {
	return nil, errors.New("Not implemented")
}

// startConsuming is a common part of StartConsuming method
func (b *Broker) startConsuming(consumerTag string, taskProcessor TaskProcessor) {
	if b.retryFunc == nil {
		b.retryFunc = retry.Closure()
	}

	b.stopChan = make(chan int)
	b.retryStopChan = make(chan int)
}

// startConsuming is a common part of StopConsuming
func (b *Broker) stopConsuming() {
	// Do not retry from now on
	b.retry = false
	// Stop the retry closure earlier
	select {
	case b.retryStopChan <- 1:
		log.WARNING.Print("Stopping retry closure.")
	default:
	}
	// Notifying the stop channel stops consuming of messages
	b.stopChan <- 1
}

// GetRegisteredTaskNames returns registered tasks names
func (b *Broker) GetRegisteredTaskNames() []string {
	return b.registeredTaskNames
}

// AdjustRoutingKey makes sure the routing key is correct.
// If the routing key is an empty string:
// a) set it to binding key for direct exchange type
// b) set it to default queue name
func AdjustRoutingKey(b Interface, s *tasks.Signature) {
	if s.RoutingKey != "" {
		return
	}

	if IsAMQP(b) && b.GetConfig().AMQP != nil && b.GetConfig().AMQP.ExchangeType == "direct" {
		// The routing algorithm behind a direct exchange is simple - a message goes
		// to the queues whose binding key exactly matches the routing key of the message.
		s.RoutingKey = b.GetConfig().AMQP.BindingKey
		return
	}

	s.RoutingKey = b.GetConfig().DefaultQueue
}

// IsAMQP returns true if the broker is AMQP
func IsAMQP(b Interface) bool {
	_, isAMQPBroker := b.(*AMQPBroker)
	return isAMQPBroker
}
<commit_msg>fix typo<commit_after>package brokers

import (
	"errors"

	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/log"
	"github.com/RichardKnop/machinery/v1/retry"
	"github.com/RichardKnop/machinery/v1/tasks"
)

// Broker represents a base broker structure
type Broker struct {
	cnf                 *config.Config
	registeredTaskNames []string
	retry               bool
	retryFunc           func(chan int)
	retryStopChan       chan int
	stopChan            chan int
}

// New creates new Broker instance
func New(cnf *config.Config) Broker {
	return Broker{cnf: cnf, retry: true}
}

// GetConfig returns config
func (b *Broker) GetConfig() *config.Config {
	return b.cnf
}

// StartConsuming enters a loop and waits for incoming messages
func (b *Broker) StartConsuming(consumerTag string, concurrency int, taskProcessor TaskProcessor) (bool, error) {
	return false, errors.New("Not implemented")
}

// Publish places a new message on the default queue
func (b *Broker) Publish(signature *tasks.Signature) error {
	return errors.New("Not implemented")
}

// StopConsuming quits the loop
func (b *Broker) StopConsuming() {
	//
}

// SetRegisteredTaskNames sets registered task names
func (b *Broker) SetRegisteredTaskNames(names []string) {
	b.registeredTaskNames = names
}

// IsTaskRegistered returns true if the task is registered with this broker
func (b *Broker) IsTaskRegistered(name string) bool {
	for _, registeredTaskName := range b.registeredTaskNames {
		if registeredTaskName == name {
			return true
		}
	}
	return false
}

// GetPendingTasks returns a slice of task.Signatures waiting in the queue
func (b *Broker) GetPendingTasks(queue string) ([]*tasks.Signature, error) {
	return nil, errors.New("Not implemented")
}

// startConsuming is a common part of StartConsuming method
func (b *Broker) startConsuming(consumerTag string, taskProcessor TaskProcessor) {
	if b.retryFunc == nil {
		b.retryFunc = retry.Closure()
	}

	b.stopChan = make(chan int)
	b.retryStopChan = make(chan int)
}

// stopConsuming is a common part of StopConsuming
func (b *Broker) stopConsuming() {
	// Do not retry from now on
	b.retry = false
	// Stop the retry closure earlier
	select {
	case b.retryStopChan <- 1:
		log.WARNING.Print("Stopping retry closure.")
	default:
	}
	// Notifying the stop channel stops consuming of messages
	b.stopChan <- 1
}

// GetRegisteredTaskNames returns registered tasks names
func (b *Broker) GetRegisteredTaskNames() []string {
	return b.registeredTaskNames
}

// AdjustRoutingKey makes sure the routing key is correct.
// If the routing key is an empty string:
// a) set it to binding key for direct exchange type
// b) set it to default queue name
func AdjustRoutingKey(b Interface, s *tasks.Signature) {
	if s.RoutingKey != "" {
		return
	}

	if IsAMQP(b) && b.GetConfig().AMQP != nil && b.GetConfig().AMQP.ExchangeType == "direct" {
		// The routing algorithm behind a direct exchange is simple - a message goes
		// to the queues whose binding key exactly matches the routing key of the message.
		s.RoutingKey = b.GetConfig().AMQP.BindingKey
		return
	}

	s.RoutingKey = b.GetConfig().DefaultQueue
}

// IsAMQP returns true if the broker is AMQP
func IsAMQP(b Interface) bool {
	_, isAMQPBroker := b.(*AMQPBroker)
	return isAMQPBroker
}
<|endoftext|>


<commit_before>// Submitted by Christopher Milan (christopherm99)

package main

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

func shuffle(a *[]int) {
    for i := len(*a) - 1; i > 0; i-- {
        j := rand.Intn(i + 1)
        (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
	}
}

func isSorted(a []int) bool {
    for i := 0; i < len(a)-1; i++ {
        if a[i+1] < a[i] {
            return false
        }
    }
    return true
}

func bogoSort(a *[]int) {
    for !isSorted(*a) {
        shuffle(a)
    }
}

func main() {
    rand.Seed(time.Now().UnixNano())
    a := []int{1, 3, 4, 2}
    bogoSort(&a)
    fmt.Println(a)
}
<commit_msg>Changed _all_ tabs to spaces<commit_after>// Submitted by Christopher Milan (christopherm99)

package main

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

func shuffle(a *[]int) {
    for i := len(*a) - 1; i > 0; i-- {
        j := rand.Intn(i + 1)
        (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
    }
}

func isSorted(a []int) bool {
    for i := 0; i < len(a)-1; i++ {
        if a[i+1] < a[i] {
            return false
        }
    }
    return true
}

func bogoSort(a *[]int) {
    for !isSorted(*a) {
        shuffle(a)
    }
}

func main() {
    rand.Seed(time.Now().UnixNano())
    a := []int{1, 3, 4, 2}
    bogoSort(&a)
    fmt.Println(a)
}
<|endoftext|>


<commit_before>// Package udp implements UDP test helpers. It lets you assert that certain
// strings must or must not be sent to a given local UDP listener.
package udp

import (
	"net"
	"strings"
	"testing"
)

var (
	addr     *string
	listener *net.UDPConn
)

type fn func()

// SetAddr sets the UDP port that will be listened on.
func SetAddr(a string) {
	addr = &a
}

func start(t *testing.T) {
	resAddr, err := net.ResolveUDPAddr("udp", *addr)
	if err != nil {
		t.Fatal(err)
	}
	listener, err = net.ListenUDP("udp", resAddr)
	if err != nil {
		t.Fatal(err)
	}
}

func stop(t *testing.T) {
	if err := listener.Close(); err != nil {
		t.Fatal(err)
	}
}

func getMessage(t *testing.T, body fn) string {
	start(t)
	defer stop(t)

	result := make(chan string)

	go func() {
		message := make([]byte, 1024)
		n, _, _ := listener.ReadFrom(message)
		result <- string(message[0:n])
	}()

	body()

	return <-result
}

func get(t *testing.T, match string, body fn) (got string, equals bool, contains bool) {
	got = getMessage(t, body)
	equals = got == match
	contains = strings.Contains(got, match)
	return got, equals, contains
}

// ShouldReceiveOnly will fire a test error if the given function doesn't send
// exactly the given string over UDP.
func ShouldReceiveOnly(t *testing.T, expected string, body fn) {
	got, equals, _ := get(t, expected, body)
	if !equals {
		t.Errorf("Expected %#v but got %#v instead", expected, got)
	}
}

// ShouldNotReceiveOnly will fire a test error if the given function sends
// exactly the given string over UDP.
func ShouldNotReceiveOnly(t *testing.T, notExpected string, body fn) {
	_, equals, _ := get(t, notExpected, body)
	if equals {
		t.Errorf("Expected not to get %v but did", notExpected)
	}
}

// ShouldReceive will fire a test error if the given function doesn't send the
// given string over UDP.
func ShouldReceive(t *testing.T, expected string, body fn) {
	got, _, contains := get(t, expected, body)
	if !contains {
		t.Errorf("Expected to find %#v but got %#v instead", expected, got)
	}
}

// ShouldNotReceive will fire a test error if the given function sends the
// given string over UDP.
func ShouldNotReceive(t *testing.T, expected string, body fn) {
	got, _, contains := get(t, expected, body)
	if contains {
		t.Errorf("Expected not to find %#v but got %#v", expected, got)
	}
}

// ShouldReceiveAll will fire a test error unless all of the given strings are
// sent over UDP.
func ShouldReceiveAll(t *testing.T, expected []string, body fn) {
	got := getMessage(t, body)
	for _, str := range expected {
		if !strings.Contains(got, str) {
			t.Errorf("Expected to find %#v but got %#v instead", str, got)
		}
	}
}

// ShouldNotReceiveAny will fire a test error if any of the given strings are
// sent over UDP.
func ShouldNotReceiveAny(t *testing.T, expected []string, body fn) {
	got := getMessage(t, body)
	for _, str := range expected {
		if strings.Contains(got, str) {
			t.Errorf("Expected not to find %#v but got %#v", str, got)
		}
	}
}
<commit_msg>Allow 32 KB packet.<commit_after>// Package udp implements UDP test helpers. It lets you assert that certain
// strings must or must not be sent to a given local UDP listener.
package udp

import (
	"net"
	"strings"
	"testing"
)

var (
	addr     *string
	listener *net.UDPConn
)

type fn func()

// SetAddr sets the UDP port that will be listened on.
func SetAddr(a string) {
	addr = &a
}

func start(t *testing.T) {
	resAddr, err := net.ResolveUDPAddr("udp", *addr)
	if err != nil {
		t.Fatal(err)
	}
	listener, err = net.ListenUDP("udp", resAddr)
	if err != nil {
		t.Fatal(err)
	}
}

func stop(t *testing.T) {
	if err := listener.Close(); err != nil {
		t.Fatal(err)
	}
}

func getMessage(t *testing.T, body fn) string {
	start(t)
	defer stop(t)

	result := make(chan string)

	go func() {
		message := make([]byte, 1024*32)
		n, _, _ := listener.ReadFrom(message)
		result <- string(message[0:n])
	}()

	body()

	return <-result
}

func get(t *testing.T, match string, body fn) (got string, equals bool, contains bool) {
	got = getMessage(t, body)
	equals = got == match
	contains = strings.Contains(got, match)
	return got, equals, contains
}

// ShouldReceiveOnly will fire a test error if the given function doesn't send
// exactly the given string over UDP.
func ShouldReceiveOnly(t *testing.T, expected string, body fn) {
	got, equals, _ := get(t, expected, body)
	if !equals {
		t.Errorf("Expected %#v but got %#v instead", expected, got)
	}
}

// ShouldNotReceiveOnly will fire a test error if the given function sends
// exactly the given string over UDP.
func ShouldNotReceiveOnly(t *testing.T, notExpected string, body fn) {
	_, equals, _ := get(t, notExpected, body)
	if equals {
		t.Errorf("Expected not to get %v but did", notExpected)
	}
}

// ShouldReceive will fire a test error if the given function doesn't send the
// given string over UDP.
func ShouldReceive(t *testing.T, expected string, body fn) {
	got, _, contains := get(t, expected, body)
	if !contains {
		t.Errorf("Expected to find %#v but got %#v instead", expected, got)
	}
}

// ShouldNotReceive will fire a test error if the given function sends the
// given string over UDP.
func ShouldNotReceive(t *testing.T, expected string, body fn) {
	got, _, contains := get(t, expected, body)
	if contains {
		t.Errorf("Expected not to find %#v but got %#v", expected, got)
	}
}

// ShouldReceiveAll will fire a test error unless all of the given strings are
// sent over UDP.
func ShouldReceiveAll(t *testing.T, expected []string, body fn) {
	got := getMessage(t, body)
	for _, str := range expected {
		if !strings.Contains(got, str) {
			t.Errorf("Expected to find %#v but got %#v instead", str, got)
		}
	}
}

// ShouldNotReceiveAny will fire a test error if any of the given strings are
// sent over UDP.
func ShouldNotReceiveAny(t *testing.T, expected []string, body fn) {
	got := getMessage(t, body)
	for _, str := range expected {
		if strings.Contains(got, str) {
			t.Errorf("Expected not to find %#v but got %#v", str, got)
		}
	}
}
<|endoftext|>


<commit_before>package command

import (
	"fmt"
	"os"
	"strings"

	"github.com/mitchellh/cli"
	"github.com/posener/complete"
)

var _ cli.Command = (*OperatorRaftSnapshotSaveCommand)(nil)
var _ cli.CommandAutocomplete = (*OperatorRaftSnapshotSaveCommand)(nil)

type OperatorRaftSnapshotSaveCommand struct {
	*BaseCommand
}

func (c *OperatorRaftSnapshotSaveCommand) Synopsis() string {
	return "Saves a snapshot of the current state of the Raft cluster into a file"
}

func (c *OperatorRaftSnapshotSaveCommand) Help() string {
	helpText := `
Usage: vault operator raft snapshot save <snapshot_file>

  Saves a snapshot of the current state of the Raft cluster into a file.

	  $ vault operator raft snapshot save raft.snap

` + c.Flags().Help()

	return strings.TrimSpace(helpText)
}

func (c *OperatorRaftSnapshotSaveCommand) Flags() *FlagSets {
	set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)

	return set
}

func (c *OperatorRaftSnapshotSaveCommand) AutocompleteArgs() complete.Predictor {
	return complete.PredictAnything
}

func (c *OperatorRaftSnapshotSaveCommand) AutocompleteFlags() complete.Flags {
	return c.Flags().Completions()
}

func (c *OperatorRaftSnapshotSaveCommand) Run(args []string) int {
	f := c.Flags()

	if err := f.Parse(args); err != nil {
		c.UI.Error(err.Error())
		return 1
	}

	path := ""

	args = f.Args()
	switch len(args) {
	case 1:
		path = strings.TrimSpace(args[0])
	default:
		c.UI.Error(fmt.Sprintf("Incorrect arguments (expected 1, got %d)", len(args)))
		return 1
	}

	if len(path) == 0 {
		c.UI.Error("Output file name is required")
		return 1
	}

	snapFile, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		c.UI.Error(fmt.Sprintf("Error opening output file: %s", err))
		return 2
	}
	defer snapFile.Close()

	client, err := c.Client()
	if err != nil {
		c.UI.Error(err.Error())
		return 2
	}

	err = client.Sys().RaftSnapshot(snapFile)
	if err != nil {
		c.UI.Error(fmt.Sprintf("Error taking the snapshot: %s", err))
		return 2
	}

	return 0
}
<commit_msg>Don't open a raft snapshot file until we have a successful snapshot response. (#9894)<commit_after>package command

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/mitchellh/cli"
	"github.com/posener/complete"
)

var _ cli.Command = (*OperatorRaftSnapshotSaveCommand)(nil)
var _ cli.CommandAutocomplete = (*OperatorRaftSnapshotSaveCommand)(nil)

type OperatorRaftSnapshotSaveCommand struct {
	*BaseCommand
}

func (c *OperatorRaftSnapshotSaveCommand) Synopsis() string {
	return "Saves a snapshot of the current state of the Raft cluster into a file"
}

func (c *OperatorRaftSnapshotSaveCommand) Help() string {
	helpText := `
Usage: vault operator raft snapshot save <snapshot_file>

  Saves a snapshot of the current state of the Raft cluster into a file.

	  $ vault operator raft snapshot save raft.snap

` + c.Flags().Help()

	return strings.TrimSpace(helpText)
}

func (c *OperatorRaftSnapshotSaveCommand) Flags() *FlagSets {
	set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)

	return set
}

func (c *OperatorRaftSnapshotSaveCommand) AutocompleteArgs() complete.Predictor {
	return complete.PredictAnything
}

func (c *OperatorRaftSnapshotSaveCommand) AutocompleteFlags() complete.Flags {
	return c.Flags().Completions()
}

func (c *OperatorRaftSnapshotSaveCommand) Run(args []string) int {
	f := c.Flags()

	if err := f.Parse(args); err != nil {
		c.UI.Error(err.Error())
		return 1
	}

	path := ""

	args = f.Args()
	switch len(args) {
	case 1:
		path = strings.TrimSpace(args[0])
	default:
		c.UI.Error(fmt.Sprintf("Incorrect arguments (expected 1, got %d)", len(args)))
		return 1
	}

	if len(path) == 0 {
		c.UI.Error("Output file name is required")
		return 1
	}

	w := &lazyOpenWriter{
		openFunc: func() (io.WriteCloser, error) {
			return os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
		},
	}

	client, err := c.Client()
	if err != nil {
		w.Close()
		c.UI.Error(err.Error())
		return 2
	}

	err = client.Sys().RaftSnapshot(w)
	if err != nil {
		w.Close()
		c.UI.Error(fmt.Sprintf("Error taking the snapshot: %s", err))
		return 2
	}

	err = w.Close()
	if err != nil {
		c.UI.Error(fmt.Sprintf("Error taking the snapshot: %s", err))
		return 2
	}
	return 0
}

type lazyOpenWriter struct {
	openFunc func() (io.WriteCloser, error)
	writer io.WriteCloser
}

func (l *lazyOpenWriter) Write(p []byte) (n int, err error) {
	if l.writer == nil {
		var err error
		l.writer, err = l.openFunc()
		if err != nil {
			return 0, err
		}
	}
	return l.writer.Write(p)
}

func (l *lazyOpenWriter) Close() error {
	if l.writer != nil {
		return l.writer.Close()
	}
	return nil
}<|endoftext|>


<commit_before>package main

// URL matching and regular expressions

import (
	"http"
	"log"
	"sre2.googlecode.com/hg/sre2"
	"strings"
)

type URLMatcher struct {
	fragments map[string]bool // a set of domain or domain+path URL fragments to test against
	regexes   map[string]sre2.Re
}

func newURLMatcher() *URLMatcher {
	m := new(URLMatcher)
	m.fragments = make(map[string]bool)
	m.regexes = make(map[string]sre2.Re)
	return m
}

// AddRule adds a rule to the matcher (unless it's already there).
func (m *URLMatcher) AddRule(rule string) {
	if rule[0] == '/' {
		// regular expression
		_, ok := m.regexes[rule]
		if ok {
			return
		}

		s := rule[1 : len(rule)-1]
		re, err := sre2.Parse("(?i)" + s)
		if err != nil {
			log.Printf("Error parsing URL regular expression %s: %v", rule, err)
			return
		}
		m.regexes[rule] = re
	}

	m.fragments[rule] = true
}

// MatchingRules returns a list of the rules that u matches.
// For consistency with phrase matching, it is a map with rules for keys
// and with all values equal to 1.
func (m *URLMatcher) MatchingRules(u *http.URL) map[string]int {
	result := make(map[string]int)

	s := u.String()
	for rule, re := range m.regexes {
		if re.Match(s) {
			result[rule] = 1
		}
	}

	host := strings.ToLower(u.Host)
	path := strings.ToLower(u.Path)

	// strip off the port number, if present
	colon := strings.LastIndex(host, ":")
	if colon != -1 {
		host = host[:colon]
	}

	// Test for matches of the host and of the domains it belongs to.
	s = host
	for {
		if m.fragments[s] {
			result[s] = 1
		}
		dot := strings.Index(s, ".")
		if dot == -1 {
			break
		}
		s = s[dot+1:]
	}

	// Test for matches with the path.
	s = host + path
	for {
		if m.fragments[s] {
			result[s] = 1
		}
		slash := strings.LastIndex(s[:len(s)-1], "/")
		if slash == -1 {
			break
		}
		s = s[:slash+1]
	}

	return result
}
<commit_msg>Switch from SRE2 to exp/regexp for regular expressions.<commit_after>package main

// URL matching and regular expressions

import (
	"http"
	"log"
	"exp/regexp"
	"strings"
)

type URLMatcher struct {
	fragments map[string]bool // a set of domain or domain+path URL fragments to test against
	regexes   map[string]*regexp.Regexp
}

func newURLMatcher() *URLMatcher {
	m := new(URLMatcher)
	m.fragments = make(map[string]bool)
	m.regexes = make(map[string]*regexp.Regexp)
	return m
}

// AddRule adds a rule to the matcher (unless it's already there).
func (m *URLMatcher) AddRule(rule string) {
	if rule[0] == '/' {
		// regular expression
		_, ok := m.regexes[rule]
		if ok {
			return
		}

		s := rule[1 : len(rule)-1]
		re, err := regexp.Compile("(?i:" + s + ")")
		if err != nil {
			log.Printf("Error parsing URL regular expression %s: %v", rule, err)
			return
		}
		m.regexes[rule] = re
	}

	m.fragments[rule] = true
}

// MatchingRules returns a list of the rules that u matches.
// For consistency with phrase matching, it is a map with rules for keys
// and with all values equal to 1.
func (m *URLMatcher) MatchingRules(u *http.URL) map[string]int {
	result := make(map[string]int)

	s := u.String()
	for rule, re := range m.regexes {
		if re.MatchString(s) {
			result[rule] = 1
		}
	}

	host := strings.ToLower(u.Host)
	path := strings.ToLower(u.Path)

	// strip off the port number, if present
	colon := strings.LastIndex(host, ":")
	if colon != -1 {
		host = host[:colon]
	}

	// Test for matches of the host and of the domains it belongs to.
	s = host
	for {
		if m.fragments[s] {
			result[s] = 1
		}
		dot := strings.Index(s, ".")
		if dot == -1 {
			break
		}
		s = s[dot+1:]
	}

	// Test for matches with the path.
	s = host + path
	for {
		if m.fragments[s] {
			result[s] = 1
		}
		slash := strings.LastIndex(s[:len(s)-1], "/")
		if slash == -1 {
			break
		}
		s = s[:slash+1]
	}

	return result
}
<|endoftext|>


<commit_before>// Tinkering with go, zmq, and Jupyter
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"

	zmq "github.com/pebbe/zmq4"
)

// MessageHeader is a Jupyter message header
// See: http://jupyter-client.readthedocs.org/en/latest/messaging.html
type MessageHeader struct {
	MessageID   string `json:"msg_id"`
	Username    string `json:"username"`
	Session     string `json:"session"`
	MessageType string `json:"msg_type"`
	Version     string `json:"version"`
}

// Message is a generic Jupyter message (not a wire message)
type Message struct {
	Header       MessageHeader          `json:"header"`
	ParentHeader MessageHeader          `json:"parent_header"`
	Metadata     map[string]interface{} `json:"metadata"`
	Content      map[string]interface{} `json:"content"`
}

// MimeBundle is a collection of mimetypes -> data
// Example:
//     'text/html' -> '
Hey!
'
//     'image/png' -> 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
type MimeBundle map[string]string

// ConnectionInfo represents the runtime connection data used by Jupyter kernels
type ConnectionInfo struct {
	IOPubPort       int    `json:"iopub_port"`
	StdinPort       int    `json:"stdin_port"`
	IP              string `json:"ip"`
	Transport       string `json:"transport"`
	HBPort          int    `json:"hb_port"`
	SignatureScheme string `json:"signature_scheme"`
	ShellPort       int    `json:"shell_port"`
	ControlPort     int    `json:"control_port"`
	Key             string `json:"key"`
}

// DELIMITER denotes the Jupyter multipart message
var DELIMITER = "<IDS|MSG>"

// ParseWireProtocol fills a Message with all the juicy Jupyter bits
func (m *Message) ParseWireProtocol(wireMessage [][]byte, key []byte) (err error) {
	var i int
	var el []byte

	// Wire protocol
	/**
		[
	  		b'u-u-i-d',         # zmq identity(ies)
	  		b'<IDS|MSG>',       # delimiter
	  		b'baddad42',        # HMAC signature
			b'{header}',        # serialized header dict
			b'{parent_header}', # serialized parent header dict
			b'{metadata}',      # serialized metadata dict
			b'{content}',       # serialized content dict
			b'blob',            # extra raw data buffer(s)
	  		...
		]
	*/
	// Determine where the delimiter is
	for i, el = range wireMessage {
		if string(el) == DELIMITER {
			break // Found our delimiter
		}
	}

	if string(wireMessage[i]) != DELIMITER {
		return errors.New("Couldn't find delimeter")
	}

	// Extract the zmq identiti(es)
	//identities := wireMessage[:delimiterLocation]

	// If the message was signed
	if len(key) != 0 {
		// TODO: Programmatic selection of scheme
		mac := hmac.New(sha256.New, key)
		for _, msgpart := range wireMessage[i+2 : i+6] {
			mac.Write(msgpart)
		}
		signature := make([]byte, hex.DecodedLen(len(wireMessage[i+1])))
		hex.Decode(signature, wireMessage[i+1])
		if !hmac.Equal(mac.Sum(nil), signature) {
			return errors.New("Invalid signature")
		}
	}

	json.Unmarshal(wireMessage[i+2], &m.Header)
	json.Unmarshal(wireMessage[i+3], &m.ParentHeader)
	json.Unmarshal(wireMessage[i+4], &m.Metadata)
	json.Unmarshal(wireMessage[i+5], &m.Content)

	return nil
}

// OpenConnectionFile is a helper method that opens a connection file and reads
// it into a ConnectionInfo struct
func OpenConnectionFile(filename string) (ConnectionInfo, error) {
	var connInfo ConnectionInfo
	connFile, err := os.Open(filename)
	if err != nil {
		return connInfo, fmt.Errorf("Couldn't open connection file: %v", err)
	}

	jsonParser := json.NewDecoder(connFile)

	if err = jsonParser.Decode(&connInfo); err != nil {
		return connInfo, fmt.Errorf("Couldn't parse connection file: %v", err)
	}

	return connInfo, nil
}

// JupyterSocket is a zmq.Socket with extra sauce
type JupyterSocket struct {
	ZMQSocket *zmq.Socket
	ConnInfo  ConnectionInfo
}

// ReadMessage reads a Jupyter Protocol Message
func (s *JupyterSocket) ReadMessage() (Message, error) {
	var message Message
	wireMessage, err := s.ZMQSocket.RecvMessageBytes(0)
	if err != nil {
		return message, fmt.Errorf("Error on receive: %v", err)
	}

	message.ParseWireProtocol(wireMessage, []byte(s.ConnInfo.Key))

	return message, nil
}

// Close shutdown zmq sockets
func (s *JupyterSocket) Close() {
	s.ZMQSocket.Close()
}

// NewIOPubSocket creates a new iopubsocket (SUB) with the connInfo given
func NewIOPubSocket(connInfo ConnectionInfo, subscribe string) (*JupyterSocket, error) {
	rawIOPubSocket, err := zmq.NewSocket(zmq.SUB)
	if err != nil {
		return nil, err
	}

	connectionString := fmt.Sprintf("%s://%s:%d",
		connInfo.Transport,
		connInfo.IP,
		connInfo.IOPubPort)

	rawIOPubSocket.Connect(connectionString)
	rawIOPubSocket.SetSubscribe("")

	iopub := &JupyterSocket{
		ZMQSocket: rawIOPubSocket,
		ConnInfo:  connInfo,
	}

	return iopub, nil
}

func main() {
	flag.Parse()
	if flag.NArg() < 1 {
		log.Fatalln("Need a connection file.")
	}

	// Expects a runtime kernel-*.json
	connInfo, err := OpenConnectionFile(flag.Arg(0))

	if err != nil {
		fmt.Errorf("%v\n", err)
		os.Exit(1)
	}

	iopub, err := NewIOPubSocket(connInfo, "")

	if err != nil {
		fmt.Errorf("Couldn't start the iopub socket: %v", err)
	}

	defer iopub.Close()

	for {
		message, err := iopub.ReadMessage()

		if err != nil {
			fmt.Errorf("%v\n", err)
			continue
		}

		//c, err := json.Marshal(message)
		//fmt.Println(string(c))

		_, ok := message.Content["data"]

		if !ok {
			continue
		}

		mimeBundle := (message.Content["data"]).(map[string]interface{})

		// There and back again
		b, err := json.Marshal(mimeBundle)
		fmt.Println(string(b))

	}

}
<commit_msg>Now the juno package!<commit_after>// Package juno implements light amounts of the Jupyter Messaging Protocol
package juno

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"

	zmq "github.com/pebbe/zmq4"
)

// MessageHeader is a Jupyter message header
// See: http://jupyter-client.readthedocs.org/en/latest/messaging.html
type MessageHeader struct {
	MessageID   string `json:"msg_id"`
	Username    string `json:"username"`
	Session     string `json:"session"`
	MessageType string `json:"msg_type"`
	Version     string `json:"version"`
}

// Message is a generic Jupyter message (not a wire message)
type Message struct {
	Header       MessageHeader          `json:"header"`
	ParentHeader MessageHeader          `json:"parent_header"`
	Metadata     map[string]interface{} `json:"metadata"`
	Content      map[string]interface{} `json:"content"`
}

// MimeBundle is a collection of mimetypes -> data
// Example:
//     'text/html' -> '
Hey!
'
//     'image/png' -> 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
type MimeBundle map[string]string

// ConnectionInfo represents the runtime connection data used by Jupyter kernels
type ConnectionInfo struct {
	IOPubPort       int    `json:"iopub_port"`
	StdinPort       int    `json:"stdin_port"`
	IP              string `json:"ip"`
	Transport       string `json:"transport"`
	HBPort          int    `json:"hb_port"`
	SignatureScheme string `json:"signature_scheme"`
	ShellPort       int    `json:"shell_port"`
	ControlPort     int    `json:"control_port"`
	Key             string `json:"key"`
}

// DELIMITER denotes the Jupyter multipart message
var DELIMITER = "<IDS|MSG>"

// ParseWireProtocol fills a Message with all the juicy Jupyter bits
func (m *Message) ParseWireProtocol(wireMessage [][]byte, key []byte) (err error) {
	var i int
	var el []byte

	// Wire protocol
	/**
		[
	  		b'u-u-i-d',         # zmq identity(ies)
	  		b'<IDS|MSG>',       # delimiter
	  		b'baddad42',        # HMAC signature
			b'{header}',        # serialized header dict
			b'{parent_header}', # serialized parent header dict
			b'{metadata}',      # serialized metadata dict
			b'{content}',       # serialized content dict
			b'blob',            # extra raw data buffer(s)
	  		...
		]
	*/
	// Determine where the delimiter is
	for i, el = range wireMessage {
		if string(el) == DELIMITER {
			break // Found our delimiter
		}
	}

	if string(wireMessage[i]) != DELIMITER {
		return errors.New("Couldn't find delimeter")
	}

	// Extract the zmq identiti(es)
	//identities := wireMessage[:delimiterLocation]

	// If the message was signed
	if len(key) != 0 {
		// TODO: Programmatic selection of scheme
		mac := hmac.New(sha256.New, key)
		for _, msgpart := range wireMessage[i+2 : i+6] {
			mac.Write(msgpart)
		}
		signature := make([]byte, hex.DecodedLen(len(wireMessage[i+1])))
		hex.Decode(signature, wireMessage[i+1])
		if !hmac.Equal(mac.Sum(nil), signature) {
			return errors.New("Invalid signature")
		}
	}

	json.Unmarshal(wireMessage[i+2], &m.Header)
	json.Unmarshal(wireMessage[i+3], &m.ParentHeader)
	json.Unmarshal(wireMessage[i+4], &m.Metadata)
	json.Unmarshal(wireMessage[i+5], &m.Content)

	return nil
}

// OpenConnectionFile is a helper method that opens a connection file and reads
// it into a ConnectionInfo struct
func OpenConnectionFile(filename string) (ConnectionInfo, error) {
	var connInfo ConnectionInfo
	connFile, err := os.Open(filename)
	if err != nil {
		return connInfo, fmt.Errorf("Couldn't open connection file: %v", err)
	}

	jsonParser := json.NewDecoder(connFile)

	if err = jsonParser.Decode(&connInfo); err != nil {
		return connInfo, fmt.Errorf("Couldn't parse connection file: %v", err)
	}

	return connInfo, nil
}

// JupyterSocket is a zmq.Socket with extra sauce
type JupyterSocket struct {
	ZMQSocket *zmq.Socket
	ConnInfo  ConnectionInfo
}

// ReadMessage reads a Jupyter Protocol Message
func (s *JupyterSocket) ReadMessage() (Message, error) {
	var message Message
	wireMessage, err := s.ZMQSocket.RecvMessageBytes(0)
	if err != nil {
		return message, fmt.Errorf("Error on receive: %v", err)
	}

	message.ParseWireProtocol(wireMessage, []byte(s.ConnInfo.Key))

	return message, nil
}

// Close shutdown zmq sockets
func (s *JupyterSocket) Close() {
	s.ZMQSocket.Close()
}

// NewIOPubSocket creates a new iopubsocket (SUB) with the connInfo given
func NewIOPubSocket(connInfo ConnectionInfo, subscribe string) (*JupyterSocket, error) {
	rawIOPubSocket, err := zmq.NewSocket(zmq.SUB)
	if err != nil {
		return nil, err
	}

	connectionString := fmt.Sprintf("%s://%s:%d",
		connInfo.Transport,
		connInfo.IP,
		connInfo.IOPubPort)

	rawIOPubSocket.Connect(connectionString)
	rawIOPubSocket.SetSubscribe("")

	iopub := &JupyterSocket{
		ZMQSocket: rawIOPubSocket,
		ConnInfo:  connInfo,
	}

	return iopub, nil
}

func main() {
	flag.Parse()
	if flag.NArg() < 1 {
		log.Fatalln("Need a connection file.")
	}

	// Expects a runtime kernel-*.json
	connInfo, err := OpenConnectionFile(flag.Arg(0))

	if err != nil {
		fmt.Errorf("%v\n", err)
		os.Exit(1)
	}

	iopub, err := NewIOPubSocket(connInfo, "")

	if err != nil {
		fmt.Errorf("Couldn't start the iopub socket: %v", err)
	}

	defer iopub.Close()

	for {
		message, err := iopub.ReadMessage()

		if err != nil {
			fmt.Errorf("%v\n", err)
			continue
		}

		c, err := json.Marshal(message)
		if err != nil {
			fmt.Println(string(c))
		}

	}

}
<|endoftext|>


<commit_before>package kami

import (
	"net/http"

	"github.com/dimfeld/httptreemux"
	"github.com/zenazn/goji/web/mutil"
	"golang.org/x/net/context"
)

var (
	// Context is the root "god object" from which every request's context will derive.
	Context = context.Background()

	// PanicHandler will, if set, be called on panics.
	// You can use kami.Exception(ctx) within the panic handler to get panic details.
	PanicHandler HandlerType
	// LogHandler will, if set, wrap every request and be called at the very end.
	LogHandler func(context.Context, mutil.WriterProxy, *http.Request)
)

var (
	routes    = newRouter()
	enable405 = true
)

func init() {
	// set up the default 404/405 handlers
	NotFound(nil)
	MethodNotAllowed(nil)
}

func newRouter() *httptreemux.TreeMux {
	r := httptreemux.New()
	r.RedirectBehavior = httptreemux.Redirect307
	r.RedirectMethodBehavior = map[string]httptreemux.RedirectBehavior{
		"GET": httptreemux.Redirect301,
	}
	return r
}

// Handler returns an http.Handler serving registered routes.
func Handler() http.Handler {
	return routes
}

// Handle registers an arbitrary method handler under the given path.
func Handle(method, path string, handler HandlerType) {
	routes.Handle(method, path, defaultBless(wrap(handler)))
}

// Get registers a GET handler under the given path.
func Get(path string, handler HandlerType) {
	Handle("GET", path, handler)
}

// Post registers a POST handler under the given path.
func Post(path string, handler HandlerType) {
	Handle("POST", path, handler)
}

// Put registers a PUT handler under the given path.
func Put(path string, handler HandlerType) {
	Handle("PUT", path, handler)
}

// Patch registers a PATCH handler under the given path.
func Patch(path string, handler HandlerType) {
	Handle("PATCH", path, handler)
}

// Head registers a HEAD handler under the given path.
func Head(path string, handler HandlerType) {
	Handle("HEAD", path, handler)
}

// Head registers a OPTIONS handler under the given path.
func Options(path string, handler HandlerType) {
	Handle("OPTIONS", path, handler)
}

// Delete registers a DELETE handler under the given path.
func Delete(path string, handler HandlerType) {
	Handle("DELETE", path, handler)
}

// NotFound registers a special handler for unregistered (404) paths.
// If handle is nil, use the default http.NotFound behavior.
func NotFound(handler HandlerType) {
	// set up the default handler if needed
	// we need to bless this so middleware will still run for a 404 request
	if handler == nil {
		handler = HandlerFunc(func(_ context.Context, w http.ResponseWriter, r *http.Request) {
			http.NotFound(w, r)
		})
	}

	h := defaultBless(wrap(handler))
	routes.NotFoundHandler = func(w http.ResponseWriter, r *http.Request) {
		h(w, r, nil)
	}
}

// MethodNotAllowed registers a special handler for automatically responding
// to invalid method requests (405).
func MethodNotAllowed(handler HandlerType) {
	if handler == nil {
		handler = HandlerFunc(func(_ context.Context, w http.ResponseWriter, r *http.Request) {
			http.Error(w,
				http.StatusText(http.StatusMethodNotAllowed),
				http.StatusMethodNotAllowed,
			)
		})
	}

	h := defaultBless(wrap(handler))
	routes.MethodNotAllowedHandler = func(w http.ResponseWriter, r *http.Request, methods map[string]httptreemux.HandlerFunc) {
		if !enable405 {
			routes.NotFoundHandler(w, r)
			return
		}
		h(w, r, nil)
	}
}

// EnableMethodNotAllowed enables or disables automatic Method Not Allowed handling.
// Note that this is enabled by default.
func EnableMethodNotAllowed(enabled bool) {
	enable405 = enabled
}

func defaultBless(k ContextHandler) httptreemux.HandlerFunc {
	return bless(k, &Context, defaultMW, &PanicHandler, &LogHandler)
}

// bless is the meat of kami.
// It wraps a ContextHandler into an httprouter compatible request,
// in order to run all the middleware and other special handlers.
func bless(h ContextHandler, base *context.Context, mw *wares, panicHandler *HandlerType, logHandler *func(context.Context, mutil.WriterProxy, *http.Request)) httptreemux.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		ctx := defaultContext(*base, r)
		if len(params) > 0 {
			ctx = newContextWithParams(ctx, params)
		}
		ranLogHandler := false // track this in case the log handler blows up

		var proxy mutil.WriterProxy
		if *logHandler != nil || mw.needsWrapper() {
			proxy = mutil.WrapWriter(w)
			w = proxy
		}

		if *panicHandler != nil {
			defer func() {
				if err := recover(); err != nil {
					ctx = newContextWithException(ctx, err)
					wrap(*panicHandler).ServeHTTPContext(ctx, w, r)

					if *logHandler != nil && !ranLogHandler {
						(*logHandler)(ctx, proxy, r)
						// should only happen if header hasn't been written
						proxy.WriteHeader(http.StatusInternalServerError)
					}
				}
			}()
		}

		ctx, ok := mw.run(ctx, w, r)
		if ok {
			h.ServeHTTPContext(ctx, w, r)
		}
		if proxy != nil {
			ctx = mw.after(ctx, proxy, r)
		}

		if *logHandler != nil {
			ranLogHandler = true
			(*logHandler)(ctx, proxy, r)
			// should only happen if header hasn't been written
			proxy.WriteHeader(http.StatusInternalServerError)
		}
	}
}

// Reset changes the root Context to context.Background().
// It removes every handler and all middleware.
func Reset() {
	Context = context.Background()
	PanicHandler = nil
	LogHandler = nil
	defaultMW = newWares()
	routes = newRouter()
	NotFound(nil)
	MethodNotAllowed(nil)
}
<commit_msg>don't use raw URL<commit_after>package kami

import (
	"net/http"

	"github.com/dimfeld/httptreemux"
	"github.com/zenazn/goji/web/mutil"
	"golang.org/x/net/context"
)

var (
	// Context is the root "god object" from which every request's context will derive.
	Context = context.Background()

	// PanicHandler will, if set, be called on panics.
	// You can use kami.Exception(ctx) within the panic handler to get panic details.
	PanicHandler HandlerType
	// LogHandler will, if set, wrap every request and be called at the very end.
	LogHandler func(context.Context, mutil.WriterProxy, *http.Request)
)

var (
	routes    = newRouter()
	enable405 = true
)

func init() {
	// set up the default 404/405 handlers
	NotFound(nil)
	MethodNotAllowed(nil)
}

func newRouter() *httptreemux.TreeMux {
	r := httptreemux.New()
	r.PathSource = httptreemux.URLPath
	r.RedirectBehavior = httptreemux.Redirect307
	r.RedirectMethodBehavior = map[string]httptreemux.RedirectBehavior{
		"GET": httptreemux.Redirect301,
	}
	return r
}

// Handler returns an http.Handler serving registered routes.
func Handler() http.Handler {
	return routes
}

// Handle registers an arbitrary method handler under the given path.
func Handle(method, path string, handler HandlerType) {
	routes.Handle(method, path, defaultBless(wrap(handler)))
}

// Get registers a GET handler under the given path.
func Get(path string, handler HandlerType) {
	Handle("GET", path, handler)
}

// Post registers a POST handler under the given path.
func Post(path string, handler HandlerType) {
	Handle("POST", path, handler)
}

// Put registers a PUT handler under the given path.
func Put(path string, handler HandlerType) {
	Handle("PUT", path, handler)
}

// Patch registers a PATCH handler under the given path.
func Patch(path string, handler HandlerType) {
	Handle("PATCH", path, handler)
}

// Head registers a HEAD handler under the given path.
func Head(path string, handler HandlerType) {
	Handle("HEAD", path, handler)
}

// Head registers a OPTIONS handler under the given path.
func Options(path string, handler HandlerType) {
	Handle("OPTIONS", path, handler)
}

// Delete registers a DELETE handler under the given path.
func Delete(path string, handler HandlerType) {
	Handle("DELETE", path, handler)
}

// NotFound registers a special handler for unregistered (404) paths.
// If handle is nil, use the default http.NotFound behavior.
func NotFound(handler HandlerType) {
	// set up the default handler if needed
	// we need to bless this so middleware will still run for a 404 request
	if handler == nil {
		handler = HandlerFunc(func(_ context.Context, w http.ResponseWriter, r *http.Request) {
			http.NotFound(w, r)
		})
	}

	h := defaultBless(wrap(handler))
	routes.NotFoundHandler = func(w http.ResponseWriter, r *http.Request) {
		h(w, r, nil)
	}
}

// MethodNotAllowed registers a special handler for automatically responding
// to invalid method requests (405).
func MethodNotAllowed(handler HandlerType) {
	if handler == nil {
		handler = HandlerFunc(func(_ context.Context, w http.ResponseWriter, r *http.Request) {
			http.Error(w,
				http.StatusText(http.StatusMethodNotAllowed),
				http.StatusMethodNotAllowed,
			)
		})
	}

	h := defaultBless(wrap(handler))
	routes.MethodNotAllowedHandler = func(w http.ResponseWriter, r *http.Request, methods map[string]httptreemux.HandlerFunc) {
		if !enable405 {
			routes.NotFoundHandler(w, r)
			return
		}
		h(w, r, nil)
	}
}

// EnableMethodNotAllowed enables or disables automatic Method Not Allowed handling.
// Note that this is enabled by default.
func EnableMethodNotAllowed(enabled bool) {
	enable405 = enabled
}

func defaultBless(k ContextHandler) httptreemux.HandlerFunc {
	return bless(k, &Context, defaultMW, &PanicHandler, &LogHandler)
}

// bless is the meat of kami.
// It wraps a ContextHandler into an httprouter compatible request,
// in order to run all the middleware and other special handlers.
func bless(h ContextHandler, base *context.Context, mw *wares, panicHandler *HandlerType, logHandler *func(context.Context, mutil.WriterProxy, *http.Request)) httptreemux.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		ctx := defaultContext(*base, r)
		if len(params) > 0 {
			ctx = newContextWithParams(ctx, params)
		}
		ranLogHandler := false // track this in case the log handler blows up

		var proxy mutil.WriterProxy
		if *logHandler != nil || mw.needsWrapper() {
			proxy = mutil.WrapWriter(w)
			w = proxy
		}

		if *panicHandler != nil {
			defer func() {
				if err := recover(); err != nil {
					ctx = newContextWithException(ctx, err)
					wrap(*panicHandler).ServeHTTPContext(ctx, w, r)

					if *logHandler != nil && !ranLogHandler {
						(*logHandler)(ctx, proxy, r)
						// should only happen if header hasn't been written
						proxy.WriteHeader(http.StatusInternalServerError)
					}
				}
			}()
		}

		ctx, ok := mw.run(ctx, w, r)
		if ok {
			h.ServeHTTPContext(ctx, w, r)
		}
		if proxy != nil {
			ctx = mw.after(ctx, proxy, r)
		}

		if *logHandler != nil {
			ranLogHandler = true
			(*logHandler)(ctx, proxy, r)
			// should only happen if header hasn't been written
			proxy.WriteHeader(http.StatusInternalServerError)
		}
	}
}

// Reset changes the root Context to context.Background().
// It removes every handler and all middleware.
func Reset() {
	Context = context.Background()
	PanicHandler = nil
	LogHandler = nil
	defaultMW = newWares()
	routes = newRouter()
	NotFound(nil)
	MethodNotAllowed(nil)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"syscall"
	"unsafe"
)

/*** defines ***/

const KILO_VERSION = "0.0.1"
const (
	ARROW_LEFT  = 1000 + iota
	ARROW_RIGHT = 1000 + iota
	ARROW_UP    = 1000 + iota
	ARROW_DOWN  = 1000 + iota
	HOME_KEY    = 1000 + iota
	END_KEY     = 1000 + iota
	PAGE_UP     = 1000 + iota
	PAGE_DOWN   = 1000 + iota
)

/*** data ***/

type Termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

type editorConfig struct {
	cx          int
	cy          int
	screenRows  int
	screenCols  int
	origTermios *Termios
}

type WinSize struct {
	Row    uint16
	Col    uint16
	Xpixel uint16
	Ypixel uint16
}

var E editorConfig

/*** terminal ***/

func die(err error) {
	disableRawMode()
	io.WriteString(os.Stdout, "\x1b[2J")
	io.WriteString(os.Stdout, "\x1b[H")
	log.Fatal(err)
}

func TcSetAttr(fd uintptr, termios *Termios) error {
	// TCSETS+1 == TCSETSW, because TCSAFLUSH doesn't exist
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func TcGetAttr(fd uintptr) *Termios {
	var termios = &Termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		log.Fatalf("Problem getting terminal attributes: %s\n", err)
	}
	return termios
}

func enableRawMode() {
	E.origTermios = TcGetAttr(os.Stdin.Fd())
	var raw Termios
	raw = *E.origTermios
	raw.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON
	raw.Oflag &^= syscall.OPOST
	raw.Cflag |= syscall.CS8
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG
	raw.Cc[syscall.VMIN+1] = 0
	raw.Cc[syscall.VTIME+1] = 1
	if e := TcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		log.Fatalf("Problem enabling raw mode: %s\n", e)
	}
}

func disableRawMode() {
	if e := TcSetAttr(os.Stdin.Fd(), E.origTermios); e != nil {
		log.Fatalf("Problem disabling raw mode: %s\n", e)
	}
}

func editorReadKey() int {
	var buffer [1]byte
	var cc int
	var err error
	for cc, err = os.Stdin.Read(buffer[:]); cc != 1; cc, err = os.Stdin.Read(buffer[:]) {
	}
	if err != nil {
		die(err)
	}
	if buffer[0] == '\x1b' {
		var seq [2]byte
		if cc, _ = os.Stdin.Read(seq[:]); cc != 2 {
			return '\x1b'
		}

		if seq[0] == '[' {
			if seq[1] >= '0' && seq[1] <= '9' {
				if cc, err = os.Stdin.Read(buffer[:]); cc != 1 {
					return '\x1b'
				}
				if buffer[0] == '~' {
					switch seq[1] {
					case '1':
						return HOME_KEY
					case '4':
						return END_KEY
					case '5':
						return PAGE_UP
					case '6':
						return PAGE_DOWN
					case '7':
						return HOME_KEY
					case '8':
						return END_KEY
					}
				}
				// XXX - what happens here?
			} else {
				switch seq[1] {
				case 'A':
					return ARROW_UP
				case 'B':
					return ARROW_DOWN
				case 'C':
					return ARROW_RIGHT
				case 'D':
					return ARROW_LEFT
				case 'H':
					return HOME_KEY
				case 'F':
					return END_KEY
				}
			}
		} else if seq[0] == '0' {
			switch seq[1] {
			case 'H':
				return HOME_KEY
			case 'F':
				return END_KEY
			}
		}

		return '\x1b'
	}
	return int(buffer[0])
}

func getCursorPosition(rows *int, cols *int) int {
	io.WriteString(os.Stdout, "\x1b[6n")
	var buffer [1]byte
	var buf []byte
	var cc int
	for cc, _ = os.Stdin.Read(buffer[:]); cc == 1; cc, _ = os.Stdin.Read(buffer[:]) {
		if buffer[0] == 'R' {
			break
		}
		buf = append(buf, buffer[0])
	}
	if string(buf[0:2]) != "\x1b[" {
		log.Printf("Failed to read rows;cols from tty\n")
		return -1
	}
	if n, e := fmt.Sscanf(string(buf[2:]), "%d;%d", rows, cols); n != 2 || e != nil {
		if e != nil {
			log.Printf("getCursorPosition: fmt.Sscanf() failed: %s\n", e)
		}
		if n != 2 {
			log.Printf("getCursorPosition: got %d items, wanted 2\n", n)
		}
		return -1
	}
	return 0
}

func getWindowSize(rows *int, cols *int) int {
	var w WinSize
	_, _, err := syscall.Syscall(syscall.SYS_IOCTL,
		os.Stdout.Fd(),
		syscall.TIOCGWINSZ,
		uintptr(unsafe.Pointer(&w)),
	)
	if err != 0 { // type syscall.Errno
		io.WriteString(os.Stdout, "\x1b[999C\x1b[999B")
		return getCursorPosition(rows, cols)
	} else {
		*rows = int(w.Row)
		*cols = int(w.Col)
		return 0
	}
	return -1
}

/*** input ***/

func editorMoveCursor(key int) {
	switch key {
	case ARROW_LEFT:
		if E.cx != 0 {
			E.cx--
		}
	case ARROW_RIGHT:
		if E.cx != E.screenCols-1 {
			E.cx++
		}
	case ARROW_UP:
		if E.cy != 0 {
			E.cy--
		}
	case ARROW_DOWN:
		if E.cy != E.screenRows-1 {
			E.cy++
		}
	}
}

func editorProcessKeypress() {
	c := editorReadKey()
	switch c {
	case ('q' & 0x1f):
		io.WriteString(os.Stdout, "\x1b[2J")
		io.WriteString(os.Stdout, "\x1b[H")
		disableRawMode()
		os.Exit(0)
	case PAGE_UP, PAGE_DOWN:
		dir := ARROW_DOWN
		if c == PAGE_UP {
			dir = ARROW_UP
		}
		for times := E.screenRows; times > 0; times-- {
			editorMoveCursor(dir)
		}
	case ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT:
		editorMoveCursor(c)
	}
}

/*** append buffer ***/

type abuf struct {
	buf []byte
}

func (p abuf) String() string {
	return string(p.buf)
}

func (p *abuf) abAppend(s string) {
	p.buf = append(p.buf, []byte(s)...)
}

/*** output ***/

func editorRefreshScreen() {
	var ab abuf
	ab.abAppend("\x1b[25l")
	ab.abAppend("\x1b[H")
	editorDrawRows(&ab)
	ab.abAppend(fmt.Sprintf("\x1b[%d;%dH", E.cy+1, E.cx+1))
	ab.abAppend("\x1b[25h")
	io.WriteString(os.Stdout, ab.String())
}

func editorDrawRows(ab *abuf) {
	for y := 0; y < E.screenRows-1; y++ {
		if y == E.screenRows/3 {
			w := fmt.Sprintf("Kilo editor -- version %s", KILO_VERSION)
			if len(w) > E.screenCols {
				w = w[0:E.screenCols]
			}
			pad := "~ "
			for padding := (E.screenCols - len(w)) / 2; padding > 0; padding-- {
				ab.abAppend(pad)
				pad = " "
			}
			ab.abAppend(w)
		} else {
			ab.abAppend("~")
		}
		ab.abAppend("\x1b[K")
		if y < E.screenRows-1 {
			ab.abAppend("\r\n")
		}
	}
}

/*** init ***/

func initEditor() {
	if getWindowSize(&E.screenRows, &E.screenCols) == -1 {
		die(fmt.Errorf("couldn't get screen size"))
	}
}

func main() {
	enableRawMode()
	defer disableRawMode()
	initEditor()

	for {
		editorRefreshScreen()
		editorProcessKeypress()
	}
}
<commit_msg>Step 53 - make Home and End keys do something<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"syscall"
	"unsafe"
)

/*** defines ***/

const KILO_VERSION = "0.0.1"
const (
	ARROW_LEFT  = 1000 + iota
	ARROW_RIGHT = 1000 + iota
	ARROW_UP    = 1000 + iota
	ARROW_DOWN  = 1000 + iota
	HOME_KEY    = 1000 + iota
	END_KEY     = 1000 + iota
	PAGE_UP     = 1000 + iota
	PAGE_DOWN   = 1000 + iota
)

/*** data ***/

type Termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

type editorConfig struct {
	cx          int
	cy          int
	screenRows  int
	screenCols  int
	origTermios *Termios
}

type WinSize struct {
	Row    uint16
	Col    uint16
	Xpixel uint16
	Ypixel uint16
}

var E editorConfig

/*** terminal ***/

func die(err error) {
	disableRawMode()
	io.WriteString(os.Stdout, "\x1b[2J")
	io.WriteString(os.Stdout, "\x1b[H")
	log.Fatal(err)
}

func TcSetAttr(fd uintptr, termios *Termios) error {
	// TCSETS+1 == TCSETSW, because TCSAFLUSH doesn't exist
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func TcGetAttr(fd uintptr) *Termios {
	var termios = &Termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		log.Fatalf("Problem getting terminal attributes: %s\n", err)
	}
	return termios
}

func enableRawMode() {
	E.origTermios = TcGetAttr(os.Stdin.Fd())
	var raw Termios
	raw = *E.origTermios
	raw.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON
	raw.Oflag &^= syscall.OPOST
	raw.Cflag |= syscall.CS8
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG
	raw.Cc[syscall.VMIN+1] = 0
	raw.Cc[syscall.VTIME+1] = 1
	if e := TcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		log.Fatalf("Problem enabling raw mode: %s\n", e)
	}
}

func disableRawMode() {
	if e := TcSetAttr(os.Stdin.Fd(), E.origTermios); e != nil {
		log.Fatalf("Problem disabling raw mode: %s\n", e)
	}
}

func editorReadKey() int {
	var buffer [1]byte
	var cc int
	var err error
	for cc, err = os.Stdin.Read(buffer[:]); cc != 1; cc, err = os.Stdin.Read(buffer[:]) {
	}
	if err != nil {
		die(err)
	}
	if buffer[0] == '\x1b' {
		var seq [2]byte
		if cc, _ = os.Stdin.Read(seq[:]); cc != 2 {
			return '\x1b'
		}

		if seq[0] == '[' {
			if seq[1] >= '0' && seq[1] <= '9' {
				if cc, err = os.Stdin.Read(buffer[:]); cc != 1 {
					return '\x1b'
				}
				if buffer[0] == '~' {
					switch seq[1] {
					case '1':
						return HOME_KEY
					case '4':
						return END_KEY
					case '5':
						return PAGE_UP
					case '6':
						return PAGE_DOWN
					case '7':
						return HOME_KEY
					case '8':
						return END_KEY
					}
				}
				// XXX - what happens here?
			} else {
				switch seq[1] {
				case 'A':
					return ARROW_UP
				case 'B':
					return ARROW_DOWN
				case 'C':
					return ARROW_RIGHT
				case 'D':
					return ARROW_LEFT
				case 'H':
					return HOME_KEY
				case 'F':
					return END_KEY
				}
			}
		} else if seq[0] == '0' {
			switch seq[1] {
			case 'H':
				return HOME_KEY
			case 'F':
				return END_KEY
			}
		}

		return '\x1b'
	}
	return int(buffer[0])
}

func getCursorPosition(rows *int, cols *int) int {
	io.WriteString(os.Stdout, "\x1b[6n")
	var buffer [1]byte
	var buf []byte
	var cc int
	for cc, _ = os.Stdin.Read(buffer[:]); cc == 1; cc, _ = os.Stdin.Read(buffer[:]) {
		if buffer[0] == 'R' {
			break
		}
		buf = append(buf, buffer[0])
	}
	if string(buf[0:2]) != "\x1b[" {
		log.Printf("Failed to read rows;cols from tty\n")
		return -1
	}
	if n, e := fmt.Sscanf(string(buf[2:]), "%d;%d", rows, cols); n != 2 || e != nil {
		if e != nil {
			log.Printf("getCursorPosition: fmt.Sscanf() failed: %s\n", e)
		}
		if n != 2 {
			log.Printf("getCursorPosition: got %d items, wanted 2\n", n)
		}
		return -1
	}
	return 0
}

func getWindowSize(rows *int, cols *int) int {
	var w WinSize
	_, _, err := syscall.Syscall(syscall.SYS_IOCTL,
		os.Stdout.Fd(),
		syscall.TIOCGWINSZ,
		uintptr(unsafe.Pointer(&w)),
	)
	if err != 0 { // type syscall.Errno
		io.WriteString(os.Stdout, "\x1b[999C\x1b[999B")
		return getCursorPosition(rows, cols)
	} else {
		*rows = int(w.Row)
		*cols = int(w.Col)
		return 0
	}
	return -1
}

/*** input ***/

func editorMoveCursor(key int) {
	switch key {
	case ARROW_LEFT:
		if E.cx != 0 {
			E.cx--
		}
	case ARROW_RIGHT:
		if E.cx != E.screenCols-1 {
			E.cx++
		}
	case ARROW_UP:
		if E.cy != 0 {
			E.cy--
		}
	case ARROW_DOWN:
		if E.cy != E.screenRows-1 {
			E.cy++
		}
	}
}

func editorProcessKeypress() {
	c := editorReadKey()
	switch c {
	case ('q' & 0x1f):
		io.WriteString(os.Stdout, "\x1b[2J")
		io.WriteString(os.Stdout, "\x1b[H")
		disableRawMode()
		os.Exit(0)
	case HOME_KEY:
		E.cx = 0
	case END_KEY:
		E.cx = E.screenCols - 1
	case PAGE_UP, PAGE_DOWN:
		dir := ARROW_DOWN
		if c == PAGE_UP {
			dir = ARROW_UP
		}
		for times := E.screenRows; times > 0; times-- {
			editorMoveCursor(dir)
		}
	case ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT:
		editorMoveCursor(c)
	}
}

/*** append buffer ***/

type abuf struct {
	buf []byte
}

func (p abuf) String() string {
	return string(p.buf)
}

func (p *abuf) abAppend(s string) {
	p.buf = append(p.buf, []byte(s)...)
}

/*** output ***/

func editorRefreshScreen() {
	var ab abuf
	ab.abAppend("\x1b[25l")
	ab.abAppend("\x1b[H")
	editorDrawRows(&ab)
	ab.abAppend(fmt.Sprintf("\x1b[%d;%dH", E.cy+1, E.cx+1))
	ab.abAppend("\x1b[25h")
	io.WriteString(os.Stdout, ab.String())
}

func editorDrawRows(ab *abuf) {
	for y := 0; y < E.screenRows-1; y++ {
		if y == E.screenRows/3 {
			w := fmt.Sprintf("Kilo editor -- version %s", KILO_VERSION)
			if len(w) > E.screenCols {
				w = w[0:E.screenCols]
			}
			pad := "~ "
			for padding := (E.screenCols - len(w)) / 2; padding > 0; padding-- {
				ab.abAppend(pad)
				pad = " "
			}
			ab.abAppend(w)
		} else {
			ab.abAppend("~")
		}
		ab.abAppend("\x1b[K")
		if y < E.screenRows-1 {
			ab.abAppend("\r\n")
		}
	}
}

/*** init ***/

func initEditor() {
	if getWindowSize(&E.screenRows, &E.screenCols) == -1 {
		die(fmt.Errorf("couldn't get screen size"))
	}
}

func main() {
	enableRawMode()
	defer disableRawMode()
	initEditor()

	for {
		editorRefreshScreen()
		editorProcessKeypress()
	}
}
<|endoftext|>


<commit_before>/*
   Nging is a toolbox for webmasters
   Copyright (C) 2018-present  Wenhui Shen <swh@admpub.com>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published
   by the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

package common

// IsCaptchaError 用户验证码错误
func IsCaptchaError(err error) bool {
	return err == ErrCaptcha
}

// IsUserNotLoggedIn 用户是否未登录
func IsUserNotLoggedIn(err error) bool {
	return err == ErrUserNotLoggedIn
}

// IsUserNotFound 用户是否不存在
func IsUserNotFound(err error) bool {
	return err == ErrUserNotFound
}

// IsUserNoPerm 用户是否没有操作权限
func IsUserNoPerm(err error) bool {
	return err == ErrUserNoPerm
}

// IsUserDisabled 用户是否被禁用
func IsUserDisabled(err error) bool {
	return err == ErrUserDisabled
}
<commit_msg>improved<commit_after>/*
   Nging is a toolbox for webmasters
   Copyright (C) 2018-present  Wenhui Shen <swh@admpub.com>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published
   by the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

package common

import (
	stdCode "github.com/webx-top/echo/code"
)

// IsCaptchaErrCode 是否验证码错误码
func IsCaptchaErrCode(code stdCode.Code) bool {
	return code == stdCode.CaptchaError
}

// IsCaptchaError 用户验证码错误
func IsCaptchaError(err error) bool {
	return err == ErrCaptcha
}

// IsUserNotLoggedIn 用户是否未登录
func IsUserNotLoggedIn(err error) bool {
	return err == ErrUserNotLoggedIn
}

// IsUserNotFound 用户是否不存在
func IsUserNotFound(err error) bool {
	return err == ErrUserNotFound
}

// IsUserNoPerm 用户是否没有操作权限
func IsUserNoPerm(err error) bool {
	return err == ErrUserNoPerm
}

// IsUserDisabled 用户是否被禁用
func IsUserDisabled(err error) bool {
	return err == ErrUserDisabled
}
<|endoftext|>