<commit_before>// radius commands
package main

import (
	"io"
	"radiusd/config"
	"radiusd/model"
	"radiusd/queue"
	"radiusd/radius"
	"net"
)

func createSess(req *radius.Packet) model.Session {
	return model.Session{
		BytesIn: radius.DecodeFour(req.Attrs[radius.AcctInputOctets].Value),
		BytesOut: radius.DecodeFour(req.Attrs[radius.AcctOutputOctets].Value),
		PacketsIn: radius.DecodeFour(req.Attrs[radius.AcctInputPackets].Value),
		PacketsOut: radius.DecodeFour(req.Attrs[radius.AcctOutputPackets].Value),
		SessionID: string(req.Attrs[radius.AcctSessionId].Value),
		SessionTime: radius.DecodeFour(req.Attrs[radius.AcctSessionTime].Value),
		User: string(req.Attrs[radius.UserName].Value),
		NasIP: radius.DecodeIP(req.Attrs[radius.NASIPAddress].Value).String(),
	}
}

func auth(w io.Writer, req *radius.Packet) {
	if e := radius.ValidateAuthRequest(req); e != "" {
		config.Log.Printf("auth.begin e=%s", e)
		return
	}

	user := string(req.Attrs[radius.UserName].Value)
	raw := req.Attrs[radius.UserPassword].Value
	pass := radius.DecryptPassword(raw, req)

	if config.Verbose {
		config.Log.Printf("auth user=%s pass=%s", user, pass)
	}
	limits, e := model.Auth(user, pass)
	if e != nil {
		config.Log.Printf("auth.begin e=" + e.Error())
		return
	}

	conns, e := model.Conns(user)
	if e != nil {
		config.Log.Printf("auth.begin e=" + e.Error())
		return
	}
	if conns >= limits.SimultaneousUse {
		w.Write(radius.DefaultPacket(req, radius.AccessReject, "Max conns reached"))
		return
	}

	if limits.Ok {
		reply := []radius.PubAttr{}
		if limits.DedicatedIP != nil {
			reply = append(reply, radius.PubAttr{
				Type: radius.FramedIPAddress,
				Value: net.ParseIP(*limits.DedicatedIP).To4(),
			})
		}
		if limits.Ratelimit != nil {
			// 	MT-Rate-Limit = MikrotikRateLimit
			reply = append(reply, radius.VendorAttr{
				Type: radius.VendorSpecific,
				VendorId: radius.MikrotikVendor,
				Values: []radius.VendorAttrString{radius.VendorAttrString{
					Type: radius.MikrotikRateLimit,
					Value: *limits.Ratelimit,
				}},
			}.Encode())
		}

		reply = append(reply, radius.PubAttr{Type: radius.PortLimit, Value: radius.EncodeFour(limits.SimultaneousUse-conns)})
		w.Write(req.Response(radius.AccessAccept, reply))
		return
	}

	w.Write(radius.DefaultPacket(req, radius.AccessReject, "Invalid user/pass"))
}

func acctBegin(w io.Writer, req *radius.Packet) {
	if e := radius.ValidateAcctRequest(req); e != "" {
		config.Log.Printf("WARN: acct.begin err=" + e)
		return
	}
	if _, there := req.Attrs[radius.FramedIPAddress]; !there {
		config.Log.Printf("WARN: acct.begin missing FramedIPAddress")
		return
	}

	user := string(req.Attrs[radius.UserName].Value)
	sess := string(req.Attrs[radius.AcctSessionId].Value)
	nasIp := radius.DecodeIP(req.Attrs[radius.NASIPAddress].Value).String()
	clientIp := string(req.Attrs[radius.CallingStationId].Value)
	assignedIp := radius.DecodeIP(req.Attrs[radius.FramedIPAddress].Value).String()

	if config.Verbose {
		config.Log.Printf("acct.begin sess=%s for user=%s on nasIP=%s", sess, user, nasIp)
	}
	reply := []radius.PubAttr{}
	_, e := model.Limits(user)
	if e != nil {
		if e == model.ErrNoRows {
			config.Log.Printf("acct.begin received invalid user=" + user)
			return
		}
		config.Log.Printf("acct.begin e=" + e.Error())
		return
	}

	if e := model.SessionAdd(sess, user, nasIp, assignedIp, clientIp); e != nil {
		config.Log.Printf("acct.begin e=%s", e.Error())
		return
	}
	w.Write(req.Response(radius.AccountingResponse, reply))
}

func acctUpdate(w io.Writer, req *radius.Packet) {
	if e := radius.ValidateAcctRequest(req); e != "" {
		config.Log.Printf("acct.update e=" + e)
		return
	}

	sess := createSess(req)
	if config.Verbose {
		config.Log.Printf(
			"acct.update sess=%s for user=%s on NasIP=%s sessTime=%d octetsIn=%d octetsOut=%d",
			sess.SessionID, sess.User, sess.NasIP, sess.SessionTime, sess.BytesIn, sess.BytesOut,
		)
	}
	txn, e := model.Begin()
	if e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	if e := model.SessionUpdate(txn, sess); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	queue.Queue(sess.User, sess.BytesIn, sess.BytesOut)
	if e := txn.Commit(); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	w.Write(radius.DefaultPacket(req, radius.AccountingResponse, "Updated accounting."))
}

func acctStop(w io.Writer, req *radius.Packet) {
	if e := radius.ValidateAcctRequest(req); e != "" {
		config.Log.Printf("acct.stop e=" + e)
		return
	}
	user := string(req.Attrs[radius.UserName].Value)
	sess := string(req.Attrs[radius.AcctSessionId].Value)
	nasIp := radius.DecodeIP(req.Attrs[radius.NASIPAddress].Value).String()

	sessTime := radius.DecodeFour(req.Attrs[radius.AcctSessionTime].Value)
	octIn := radius.DecodeFour(req.Attrs[radius.AcctInputOctets].Value)
	octOut := radius.DecodeFour(req.Attrs[radius.AcctOutputOctets].Value)

	if config.Verbose {
		config.Log.Printf(
			"acct.stop sess=%s for user=%s sessTime=%d octetsIn=%d octetsOut=%d",
			sess, user, sessTime, octIn, octOut,
		)
	}

	txn, e := model.Begin()
	if e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	sessModel := createSess(req)
	if e := model.SessionUpdate(txn, sessModel); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	if e := model.SessionLog(txn, sess, user, nasIp); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	if e := model.SessionRemove(txn, sess, user, nasIp); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	queue.Queue(user, octIn, octOut)
	if e := txn.Commit(); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}

	w.Write(radius.DefaultPacket(req, radius.AccountingResponse, "Finished accounting."))
}
<commit_msg>Disable. Port-Limit attr as we don't use it<commit_after>// radius commands
package main

import (
	"io"
	"radiusd/config"
	"radiusd/model"
	"radiusd/queue"
	"radiusd/radius"
	"net"
)

func createSess(req *radius.Packet) model.Session {
	return model.Session{
		BytesIn: radius.DecodeFour(req.Attrs[radius.AcctInputOctets].Value),
		BytesOut: radius.DecodeFour(req.Attrs[radius.AcctOutputOctets].Value),
		PacketsIn: radius.DecodeFour(req.Attrs[radius.AcctInputPackets].Value),
		PacketsOut: radius.DecodeFour(req.Attrs[radius.AcctOutputPackets].Value),
		SessionID: string(req.Attrs[radius.AcctSessionId].Value),
		SessionTime: radius.DecodeFour(req.Attrs[radius.AcctSessionTime].Value),
		User: string(req.Attrs[radius.UserName].Value),
		NasIP: radius.DecodeIP(req.Attrs[radius.NASIPAddress].Value).String(),
	}
}

func auth(w io.Writer, req *radius.Packet) {
	if e := radius.ValidateAuthRequest(req); e != "" {
		config.Log.Printf("auth.begin e=%s", e)
		return
	}

	user := string(req.Attrs[radius.UserName].Value)
	raw := req.Attrs[radius.UserPassword].Value
	pass := radius.DecryptPassword(raw, req)

	if config.Verbose {
		config.Log.Printf("auth user=%s pass=%s", user, pass)
	}
	limits, e := model.Auth(user, pass)
	if e != nil {
		config.Log.Printf("auth.begin e=" + e.Error())
		return
	}

	conns, e := model.Conns(user)
	if e != nil {
		config.Log.Printf("auth.begin e=" + e.Error())
		return
	}
	if conns >= limits.SimultaneousUse {
		w.Write(radius.DefaultPacket(req, radius.AccessReject, "Max conns reached"))
		return
	}

	if limits.Ok {
		reply := []radius.PubAttr{}
		if limits.DedicatedIP != nil {
			reply = append(reply, radius.PubAttr{
				Type: radius.FramedIPAddress,
				Value: net.ParseIP(*limits.DedicatedIP).To4(),
			})
		}
		if limits.Ratelimit != nil {
			// 	MT-Rate-Limit = MikrotikRateLimit
			reply = append(reply, radius.VendorAttr{
				Type: radius.VendorSpecific,
				VendorId: radius.MikrotikVendor,
				Values: []radius.VendorAttrString{radius.VendorAttrString{
					Type: radius.MikrotikRateLimit,
					Value: *limits.Ratelimit,
				}},
			}.Encode())
		}

		//reply = append(reply, radius.PubAttr{Type: radius.PortLimit, Value: radius.EncodeFour(limits.SimultaneousUse-conns)})
		w.Write(req.Response(radius.AccessAccept, reply))
		return
	}

	w.Write(radius.DefaultPacket(req, radius.AccessReject, "Invalid user/pass"))
}

func acctBegin(w io.Writer, req *radius.Packet) {
	if e := radius.ValidateAcctRequest(req); e != "" {
		config.Log.Printf("WARN: acct.begin err=" + e)
		return
	}
	if _, there := req.Attrs[radius.FramedIPAddress]; !there {
		config.Log.Printf("WARN: acct.begin missing FramedIPAddress")
		return
	}

	user := string(req.Attrs[radius.UserName].Value)
	sess := string(req.Attrs[radius.AcctSessionId].Value)
	nasIp := radius.DecodeIP(req.Attrs[radius.NASIPAddress].Value).String()
	clientIp := string(req.Attrs[radius.CallingStationId].Value)
	assignedIp := radius.DecodeIP(req.Attrs[radius.FramedIPAddress].Value).String()

	if config.Verbose {
		config.Log.Printf("acct.begin sess=%s for user=%s on nasIP=%s", sess, user, nasIp)
	}
	reply := []radius.PubAttr{}
	_, e := model.Limits(user)
	if e != nil {
		if e == model.ErrNoRows {
			config.Log.Printf("acct.begin received invalid user=" + user)
			return
		}
		config.Log.Printf("acct.begin e=" + e.Error())
		return
	}

	if e := model.SessionAdd(sess, user, nasIp, assignedIp, clientIp); e != nil {
		config.Log.Printf("acct.begin e=%s", e.Error())
		return
	}
	w.Write(req.Response(radius.AccountingResponse, reply))
}

func acctUpdate(w io.Writer, req *radius.Packet) {
	if e := radius.ValidateAcctRequest(req); e != "" {
		config.Log.Printf("acct.update e=" + e)
		return
	}

	sess := createSess(req)
	if config.Verbose {
		config.Log.Printf(
			"acct.update sess=%s for user=%s on NasIP=%s sessTime=%d octetsIn=%d octetsOut=%d",
			sess.SessionID, sess.User, sess.NasIP, sess.SessionTime, sess.BytesIn, sess.BytesOut,
		)
	}
	txn, e := model.Begin()
	if e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	if e := model.SessionUpdate(txn, sess); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	queue.Queue(sess.User, sess.BytesIn, sess.BytesOut)
	if e := txn.Commit(); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	w.Write(radius.DefaultPacket(req, radius.AccountingResponse, "Updated accounting."))
}

func acctStop(w io.Writer, req *radius.Packet) {
	if e := radius.ValidateAcctRequest(req); e != "" {
		config.Log.Printf("acct.stop e=" + e)
		return
	}
	user := string(req.Attrs[radius.UserName].Value)
	sess := string(req.Attrs[radius.AcctSessionId].Value)
	nasIp := radius.DecodeIP(req.Attrs[radius.NASIPAddress].Value).String()

	sessTime := radius.DecodeFour(req.Attrs[radius.AcctSessionTime].Value)
	octIn := radius.DecodeFour(req.Attrs[radius.AcctInputOctets].Value)
	octOut := radius.DecodeFour(req.Attrs[radius.AcctOutputOctets].Value)

	if config.Verbose {
		config.Log.Printf(
			"acct.stop sess=%s for user=%s sessTime=%d octetsIn=%d octetsOut=%d",
			sess, user, sessTime, octIn, octOut,
		)
	}

	txn, e := model.Begin()
	if e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	sessModel := createSess(req)
	if e := model.SessionUpdate(txn, sessModel); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	if e := model.SessionLog(txn, sess, user, nasIp); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	if e := model.SessionRemove(txn, sess, user, nasIp); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}
	queue.Queue(user, octIn, octOut)
	if e := txn.Commit(); e != nil {
		config.Log.Printf("acct.update e=" + e.Error())
		return
	}

	w.Write(radius.DefaultPacket(req, radius.AccountingResponse, "Finished accounting."))
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"github.com/THUNDERGROOVE/census"
	"github.com/nlopes/slack"
	"log"
	"strings"
	"text/template"
)

var Commands = make(map[string]*Cmd)

const lookup = `
{{if .Character}}
({{.Faction.Name.En}}) {{if .Outfit.Alias }}[{{.Outfit.Alias}}]{{end}} {{.Name.First}} BR: {{.Battlerank.Rank}} :cert: {{.GetCerts}}\
Kills: {{.GetKills}} Deaths: {{.GetDeaths}} KDR: {{.KDR}}\
{{if .Outfit.Name}} Outfit: {{.Outfit.Name}} with {{.Outfit.MemberCount}} members {{end}}\
Defended: {{.GetFacilitiesDefended}} Captured: {{.GetFacilitiesCaptured}}\
{{else}}
Uh got nil character?
{{}}
`

const helpText = `Hi.  I'm stats-bot.  You can ask me to '!lookup <name>' or '!lookupeu <name>'`

type Global struct {
	*census.Character
	Dev bool
}

var lookupTmpl *template.Template

func init() {
	var err error
	lookupTmpl = template.New("")
	lookupTmpl, err = lookupTmpl.Parse(lookup)
	if err != nil {
		log.Fatalf("Template failed to compile: [%v]", err.Error())
	}
	RegisterCommand("help", func(bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
		Respond(helpText, out, ev)
	})

	RegisterCommand("lookup", func(bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
		LookupWith(Census, CensusEU, bot, out, ev)
	})
	RegisterCommand("lookupeu", func(bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
		LookupWith(CensusEU, Census, bot, out, ev)
	})
}

func LookupWith(c *census.Census, fallbackc *census.Census, bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
	args := strings.Split(ev.Text, " ")
	if len(args) <= 1 {
		Respond("Do you really expect me to lookup nothing?", out, ev)
		return
	}
	name := args[1]
	char, err := c.QueryCharacterByExactName(name)
	if err != nil {
		if strings.Contains(err.Error(), "Get") {
			Respond("ERROR: The server closed the connection on us.  The API is either down or we are being rate-limited", out, ev)
			return
		}
		log.Printf("Error getting character info: [%v] trying fallback", err.Error())

		char, err = fallbackc.QueryCharacterByExactName(name)
		if err != nil {
			if strings.Contains(err.Error(), "Get") {
				Respond("ERROR: The server closed the connection on us.  The API is either down or we are being rate-limited", out, ev)
				return
			}
		}
	}
	buff := bytes.NewBuffer([]byte(""))
	if err := lookupTmpl.Execute(buff, Global{Character: char, Dev: Dev}); err != nil {
		buff.WriteString("\nerror encountered" + err.Error())
	}
	Respond(buff.String(), out, ev)
}

type Cmd struct {
	name    string
	handler func(*slack.Slack, chan slack.OutgoingMessage, *slack.MessageEvent)
}

func RegisterCommand(name string, handler func(*slack.Slack, chan slack.OutgoingMessage, *slack.MessageEvent)) {
	cmd := new(Cmd)
	cmd.name = name
	cmd.handler = handler
	Commands[name] = cmd
}

func Dispatch(bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
	if bot.GetInfo().User.Id == ev.UserId {
		return
	}
	c := strings.ToLower(strings.Split(ev.Text, " ")[0])
	if len(ev.Text) == 0 {
		log.Printf("Got blank message")
		return
	}
	if ev.Text[0] == '!' {

		if v, ok := Commands[strings.TrimLeft(c, "!")]; ok {

			//log.Printf("[Dispatch] Sending to %v", v.name)
			v.handler(bot, out, ev)

		} else {
			log.Printf("[Dispatch] Unhandled command '%v' ev: '%v'", c, ev.Text)
			Respond("!I don't know what you want from me :( do 'help'?", out, ev)
		}
	}
}

func Respond(s string, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
	lines := strings.Split(s, "\")
	for _, v := range lines {
		o := slack.OutgoingMessage{}
		o.Text = v
		o.ChannelId = ev.ChannelId
		o.Type = ev.Type
		out <- o
	}
}

func parseURL(url string) string {
	url = strings.Split(url, "//")[1]
	url = strings.Split(url, ".slack.com/")[0]
	return url
}

func TKPercent(char *census.Character) float64 {
	kills := char.TeamKillsInLast(150)
	return (float64(kills) / 1000) * 100
}
<commit_msg>oopds<commit_after>package main

import (
	"bytes"
	"github.com/THUNDERGROOVE/census"
	"github.com/nlopes/slack"
	"log"
	"strings"
	"text/template"
)

var Commands = make(map[string]*Cmd)

const lookup = `
{{if .Character}}
({{.Faction.Name.En}}) {{if .Outfit.Alias }}[{{.Outfit.Alias}}]{{end}} {{.Name.First}} BR: {{.Battlerank.Rank}} :cert: {{.GetCerts}}\
Kills: {{.GetKills}} Deaths: {{.GetDeaths}} KDR: {{.KDR}}\
{{if .Outfit.Name}} Outfit: {{.Outfit.Name}} with {{.Outfit.MemberCount}} members {{end}}\
Defended: {{.GetFacilitiesDefended}} Captured: {{.GetFacilitiesCaptured}}\
{{else}}
Uh got nil character?
{{}}
`

const helpText = `Hi.  I'm stats-bot.  You can ask me to '!lookup <name>' or '!lookupeu <name>'`

type Global struct {
	*census.Character
	Dev bool
}

var lookupTmpl *template.Template

func init() {
	var err error
	lookupTmpl = template.New("")
	lookupTmpl, err = lookupTmpl.Parse(lookup)
	if err != nil {
		log.Fatalf("Template failed to compile: [%v]", err.Error())
	}
	RegisterCommand("help", func(bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
		Respond(helpText, out, ev)
	})

	RegisterCommand("lookup", func(bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
		LookupWith(Census, CensusEU, bot, out, ev)
	})
	RegisterCommand("lookupeu", func(bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
		LookupWith(CensusEU, Census, bot, out, ev)
	})
}

func LookupWith(c *census.Census, fallbackc *census.Census, bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
	args := strings.Split(ev.Text, " ")
	if len(args) <= 1 {
		Respond("Do you really expect me to lookup nothing?", out, ev)
		return
	}
	name := args[1]
	char, err := c.QueryCharacterByExactName(name)
	if err != nil {
		if strings.Contains(err.Error(), "Get") {
			Respond("ERROR: The server closed the connection on us.  The API is either down or we are being rate-limited", out, ev)
			return
		}
		log.Printf("Error getting character info: [%v] trying fallback", err.Error())

		char, err = fallbackc.QueryCharacterByExactName(name)
		if err != nil {
			if strings.Contains(err.Error(), "Get") {
				Respond("ERROR: The server closed the connection on us.  The API is either down or we are being rate-limited", out, ev)
				return
			}
		}
	}
	buff := bytes.NewBuffer([]byte(""))
	if err := lookupTmpl.Execute(buff, Global{Character: char, Dev: Dev}); err != nil {
		buff.WriteString("\nerror encountered" + err.Error())
	}
	Respond(buff.String(), out, ev)
}

type Cmd struct {
	name    string
	handler func(*slack.Slack, chan slack.OutgoingMessage, *slack.MessageEvent)
}

func RegisterCommand(name string, handler func(*slack.Slack, chan slack.OutgoingMessage, *slack.MessageEvent)) {
	cmd := new(Cmd)
	cmd.name = name
	cmd.handler = handler
	Commands[name] = cmd
}

func Dispatch(bot *slack.Slack, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
	if bot.GetInfo().User.Id == ev.UserId {
		return
	}
	c := strings.ToLower(strings.Split(ev.Text, " ")[0])
	if len(ev.Text) == 0 {
		log.Printf("Got blank message")
		return
	}
	if ev.Text[0] == '!' {

		if v, ok := Commands[strings.TrimLeft(c, "!")]; ok {

			//log.Printf("[Dispatch] Sending to %v", v.name)
			v.handler(bot, out, ev)

		} else {
			log.Printf("[Dispatch] Unhandled command '%v' ev: '%v'", c, ev.Text)
			Respond("!I don't know what you want from me :( do 'help'?", out, ev)
		}
	}
}

func Respond(s string, out chan slack.OutgoingMessage, ev *slack.MessageEvent) {
	lines := strings.Split(s, "\\")
	for _, v := range lines {
		o := slack.OutgoingMessage{}
		o.Text = v
		o.ChannelId = ev.ChannelId
		o.Type = ev.Type
		out <- o
	}
}

func parseURL(url string) string {
	url = strings.Split(url, "//")[1]
	url = strings.Split(url, ".slack.com/")[0]
	return url
}

func TKPercent(char *census.Character) float64 {
	kills := char.TeamKillsInLast(150)
	return (float64(kills) / 1000) * 100
}
<|endoftext|>


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

// Package wire contains directives for Wire code generation.
package wire

// ProviderSet is a marker type that collects a group of providers.
type ProviderSet struct{}

// NewSet creates a new provider set that includes the providers in
// its arguments. Each argument is either an exported function value,
// an exported struct (zero) value, a provider set, a call to Bind, a
// a call to Value, or a call to InterfaceValue.
func NewSet(...interface{}) ProviderSet {
	return ProviderSet{}
}

// Build is placed in the body of an injector function to declare the
// providers to use. Its arguments are the same as NewSet. Its return
// value is an error message that can be sent to panic.
//
// Examples:
//
//	func injector(ctx context.Context) (*sql.DB, error) {
//		wire.Build(otherpkg.FooSet, myProviderFunc)
//		return nil, nil
//	}
//
//	func injector(ctx context.Context) (*sql.DB, error) {
//		panic(wire.Build(otherpkg.FooSet, myProviderFunc))
//	}
func Build(...interface{}) string {
	return "implementation not generated, run wire"
}

// A Binding maps an interface to a concrete type.
type Binding struct{}

// Bind declares that a concrete type should be used to satisfy a
// dependency on the type of iface, which must be a pointer to an
// interface type.
//
// Example:
//
//	type Fooer interface {
//		Foo()
//	}
//
//	type MyFoo struct{}
//
//	func (MyFoo) Foo() {}
//
//	var MySet = wire.NewSet(
//		MyFoo{},
//		wire.Bind(new(Fooer), new(MyFoo)))
func Bind(iface, to interface{}) Binding {
	return Binding{}
}

// A ProvidedValue is an expression that is copied to the generated injector.
type ProvidedValue struct{}

// Value binds an expression to provide the type of the expression.
// The expression may not be an interface value; use InterfaceValue for that.
//
// Example:
//
//	var MySet = wire.NewSet(wire.Value([]string(nil)))
func Value(interface{}) ProvidedValue {
	return ProvidedValue{}
}

// InterfaceValue binds an expression to provide a specific interface type.
//
// Example:
//
//	var MySet = wire.NewSet(wire.InterfaceValue(new(io.Reader), os.Stdin))
func InterfaceValue(typ interface{}, x interface{}) ProvidedValue {
	return ProvidedValue{}
}
<commit_msg>wire: remove duplicated "a" (#561)<commit_after>// Copyright 2018 The Go Cloud Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package wire contains directives for Wire code generation.
package wire

// ProviderSet is a marker type that collects a group of providers.
type ProviderSet struct{}

// NewSet creates a new provider set that includes the providers in
// its arguments. Each argument is either an exported function value,
// an exported struct (zero) value, a provider set, a call to Bind,
// a call to Value, or a call to InterfaceValue.
func NewSet(...interface{}) ProviderSet {
	return ProviderSet{}
}

// Build is placed in the body of an injector function to declare the
// providers to use. Its arguments are the same as NewSet. Its return
// value is an error message that can be sent to panic.
//
// Examples:
//
//	func injector(ctx context.Context) (*sql.DB, error) {
//		wire.Build(otherpkg.FooSet, myProviderFunc)
//		return nil, nil
//	}
//
//	func injector(ctx context.Context) (*sql.DB, error) {
//		panic(wire.Build(otherpkg.FooSet, myProviderFunc))
//	}
func Build(...interface{}) string {
	return "implementation not generated, run wire"
}

// A Binding maps an interface to a concrete type.
type Binding struct{}

// Bind declares that a concrete type should be used to satisfy a
// dependency on the type of iface, which must be a pointer to an
// interface type.
//
// Example:
//
//	type Fooer interface {
//		Foo()
//	}
//
//	type MyFoo struct{}
//
//	func (MyFoo) Foo() {}
//
//	var MySet = wire.NewSet(
//		MyFoo{},
//		wire.Bind(new(Fooer), new(MyFoo)))
func Bind(iface, to interface{}) Binding {
	return Binding{}
}

// A ProvidedValue is an expression that is copied to the generated injector.
type ProvidedValue struct{}

// Value binds an expression to provide the type of the expression.
// The expression may not be an interface value; use InterfaceValue for that.
//
// Example:
//
//	var MySet = wire.NewSet(wire.Value([]string(nil)))
func Value(interface{}) ProvidedValue {
	return ProvidedValue{}
}

// InterfaceValue binds an expression to provide a specific interface type.
//
// Example:
//
//	var MySet = wire.NewSet(wire.InterfaceValue(new(io.Reader), os.Stdin))
func InterfaceValue(typ interface{}, x interface{}) ProvidedValue {
	return ProvidedValue{}
}
<|endoftext|>


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

package uuid

import (
	"encoding/binary"
	"fmt"
	"os"
)

// A Domain represents a Version 2 domain
type Domain byte

// Domain constants for DCE Security (Version 2) UUIDs.
const (
	Person = Domain(0)
	Group  = Domain(1)
	Org    = Domain(2)
)

// NewDCESecurity returns a DCE Security (Version 2) UUID.
//
// The domain should be one of Person, Group or Org.
// On a POSIX system the id should be the users UID for the Person
// domain and the users GID for the Group.  The meaning of id for
// the domain Org or on non-POSIX systems is site defined.
//
// For a given domain/id pair the same token may be returned for up to
// 7 minutes and 10 seconds.
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
	uuid, err := NewUUID()
	if err == nil {
		uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
		uuid[9] = byte(domain)
		binary.BigEndian.PutUint32(uuid[0:], id)
	}
	return uuid, err
}

// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
// domain with the id returned by os.Getuid.
//
//  NewDCEPerson(Person, uint32(os.Getuid()))
func NewDCEPerson() (UUID, error) {
	return NewDCESecurity(Person, uint32(os.Getuid()))
}

// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
// domain with the id returned by os.Getgid.
//
//  NewDCEGroup(Group, uint32(os.Getgid()))
func NewDCEGroup() (UUID, error) {
	return NewDCESecurity(Group, uint32(os.Getgid()))
}

// Domain returns the domain for a Version 2 UUID.  Domains are only defined
// for Version 2 UUIDs.
func (uuid UUID) Domain() Domain {
	return Domain(uuid[9])
}

// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
// UUIDs.
func (uuid UUID) ID() uint32 {
	return binary.BigEndian.Uint32(uuid[0:4])
}

func (d Domain) String() string {
	switch d {
	case Person:
		return "Person"
	case Group:
		return "Group"
	case Org:
		return "Org"
	}
	return fmt.Sprintf("Domain%d", int(d))
}
<commit_msg>A little error in the documentation of dce.go<commit_after>// Copyright 2016 Google Inc.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package uuid

import (
	"encoding/binary"
	"fmt"
	"os"
)

// A Domain represents a Version 2 domain
type Domain byte

// Domain constants for DCE Security (Version 2) UUIDs.
const (
	Person = Domain(0)
	Group  = Domain(1)
	Org    = Domain(2)
)

// NewDCESecurity returns a DCE Security (Version 2) UUID.
//
// The domain should be one of Person, Group or Org.
// On a POSIX system the id should be the users UID for the Person
// domain and the users GID for the Group.  The meaning of id for
// the domain Org or on non-POSIX systems is site defined.
//
// For a given domain/id pair the same token may be returned for up to
// 7 minutes and 10 seconds.
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
	uuid, err := NewUUID()
	if err == nil {
		uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
		uuid[9] = byte(domain)
		binary.BigEndian.PutUint32(uuid[0:], id)
	}
	return uuid, err
}

// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
// domain with the id returned by os.Getuid.
//
//  NewDCESecurity(Person, uint32(os.Getuid()))
func NewDCEPerson() (UUID, error) {
	return NewDCESecurity(Person, uint32(os.Getuid()))
}

// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
// domain with the id returned by os.Getgid.
//
//  NewDCESecurity(Group, uint32(os.Getgid()))
func NewDCEGroup() (UUID, error) {
	return NewDCESecurity(Group, uint32(os.Getgid()))
}

// Domain returns the domain for a Version 2 UUID.  Domains are only defined
// for Version 2 UUIDs.
func (uuid UUID) Domain() Domain {
	return Domain(uuid[9])
}

// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
// UUIDs.
func (uuid UUID) ID() uint32 {
	return binary.BigEndian.Uint32(uuid[0:4])
}

func (d Domain) String() string {
	switch d {
	case Person:
		return "Person"
	case Group:
		return "Group"
	case Org:
		return "Org"
	}
	return fmt.Sprintf("Domain%d", int(d))
}
<|endoftext|>


<commit_before>package charm

import (
	"archive/zip"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"syscall"
)

// The Dir type encapsulates access to data and operations
// on a charm directory.
type Dir struct {
	Path     string
	meta     *Meta
	config   *Config
	revision int
}

// Trick to ensure *Dir implements the Charm interface.
var _ Charm = (*Dir)(nil)

// ReadDir returns a Dir representing an expanded charm directory.
func ReadDir(path string) (dir *Dir, err error) {
	dir = &Dir{Path: path}
	file, err := os.Open(dir.join("metadata.yaml"))
	if err != nil {
		return nil, err
	}
	dir.meta, err = ReadMeta(file)
	file.Close()
	if err != nil {
		return nil, err
	}
	file, err = os.Open(dir.join("config.yaml"))
	if _, ok := err.(*os.PathError); ok {
		dir.config = NewConfig()
	} else if err != nil {
		return nil, err
	} else {
		dir.config, err = ReadConfig(file)
		file.Close()
		if err != nil {
			return nil, err
		}
	}
	if file, err = os.Open(dir.join("revision")); err == nil {
		_, err = fmt.Fscan(file, &dir.revision)
		file.Close()
		if err != nil {
			return nil, errors.New("invalid revision file")
		}
	} else {
		dir.revision = dir.meta.OldRevision
	}
	return dir, nil
}

// join builds a path rooted at the charm's expanded directory
// path and the extra path components provided.
func (dir *Dir) join(parts ...string) string {
	parts = append([]string{dir.Path}, parts...)
	return filepath.Join(parts...)
}

// Revision returns the revision number for the charm
// expanded in dir.
func (dir *Dir) Revision() int {
	return dir.revision
}

// Meta returns the Meta representing the metadata.yaml file
// for the charm expanded in dir.
func (dir *Dir) Meta() *Meta {
	return dir.meta
}

// Config returns the Config representing the config.yaml file
// for the charm expanded in dir.
func (dir *Dir) Config() *Config {
	return dir.config
}

// SetRevision changes the charm revision number. This affects
// the revision reported by Revision and the revision of the
// charm bundled by BundleTo.
// The revision file in the charm directory is not modified.
func (dir *Dir) SetRevision(revision int) {
	dir.revision = revision
}

// SetDiskRevision does the same as SetRevision but also changes
// the revision file in the charm directory.
func (dir *Dir) SetDiskRevision(revision int) error {
	dir.SetRevision(revision)
	file, err := os.OpenFile(dir.join("revision"), os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		return err
	}
	_, err = file.Write([]byte(strconv.Itoa(revision)))
	file.Close()
	return err
}

// BundleTo creates a charm file from the charm expanded in dir.
// It is conventional to give charm bundle files a ".charm" suffix.
func (dir *Dir) BundleTo(w io.Writer) (err error) {
	zipw := zip.NewWriter(w)
	defer zipw.Close()
	zp := zipPacker{zipw, dir.Path}
	zp.AddRevision(dir.revision)
	return filepath.Walk(dir.Path, zp.WalkFunc())
}

type zipPacker struct {
	*zip.Writer
	root string
}

func (zp *zipPacker) WalkFunc() filepath.WalkFunc {
	return func(path string, fi os.FileInfo, err error) error {
		return zp.visit(path, fi, err)
	}
}

func (zp *zipPacker) AddRevision(revision int) error {
	h := &zip.FileHeader{Name: "revision"}
	h.SetMode(syscall.S_IFREG | 0644)
	w, err := zp.CreateHeader(h)
	if err == nil {
		_, err = w.Write([]byte(strconv.Itoa(revision)))
	}
	return err
}

func (zp *zipPacker) visit(path string, fi os.FileInfo, err error) error {
	if err != nil {
		return err
	}
	relpath, err := filepath.Rel(zp.root, path)
	if err != nil {
		return err
	}
	method := zip.Deflate
	hidden := len(relpath) > 1 && relpath[0] == '.'
	if fi.IsDir() {
		if relpath == "build" {
			return filepath.SkipDir
		}
		if hidden {
			return filepath.SkipDir
		}
		relpath += "/"
		method = zip.Store
	}

	mode := fi.Mode()
	if err := checkFileType(relpath, mode); err != nil {
		return err
	}
	if mode&os.ModeSymlink != 0 {
		method = zip.Store
	}
	if hidden || relpath == "revision" {
		return nil
	}
	h := &zip.FileHeader{
		Name:   relpath,
		Method: method,
	}

	perm := os.FileMode(0644)
	if mode&os.ModeSymlink != 0 {
		perm = 0777
	} else if mode&0100 != 0 {
		perm = 0755
	}
	h.SetMode(mode&^0777 | perm)

	w, err := zp.CreateHeader(h)
	if err != nil || fi.IsDir() {
		return err
	}
	var data []byte
	if mode&os.ModeSymlink != 0 {
		target, err := os.Readlink(path)
		if err != nil {
			return err
		}
		if err := checkSymlinkTarget(zp.root, relpath, target); err != nil {
			return err
		}
		data = []byte(target)
	} else {
		data, err = ioutil.ReadFile(path)
		if err != nil {
			return err
		}
	}
	_, err = w.Write(data)
	return err
}

func checkFileType(path string, mode os.FileMode) error {
	e := "file has an unknown type: %q"
	switch mode & os.ModeType {
	case os.ModeDir, os.ModeSymlink, 0:
		return nil
	case os.ModeNamedPipe:
		e = "file is a named pipe: %q"
	case os.ModeSocket:
		e = "file is a socket: %q"
	case os.ModeDevice:
		e = "file is a device: %q"
	}
	return fmt.Errorf(e, path)
}
<commit_msg>small changes for review<commit_after>package charm

import (
	"archive/zip"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"syscall"
)

// The Dir type encapsulates access to data and operations
// on a charm directory.
type Dir struct {
	Path     string
	meta     *Meta
	config   *Config
	revision int
}

// Trick to ensure *Dir implements the Charm interface.
var _ Charm = (*Dir)(nil)

// ReadDir returns a Dir representing an expanded charm directory.
func ReadDir(path string) (dir *Dir, err error) {
	dir = &Dir{Path: path}
	file, err := os.Open(dir.join("metadata.yaml"))
	if err != nil {
		return nil, err
	}
	dir.meta, err = ReadMeta(file)
	file.Close()
	if err != nil {
		return nil, err
	}
	file, err = os.Open(dir.join("config.yaml"))
	if _, ok := err.(*os.PathError); ok {
		dir.config = NewConfig()
	} else if err != nil {
		return nil, err
	} else {
		dir.config, err = ReadConfig(file)
		file.Close()
		if err != nil {
			return nil, err
		}
	}
	if file, err = os.Open(dir.join("revision")); err == nil {
		_, err = fmt.Fscan(file, &dir.revision)
		file.Close()
		if err != nil {
			return nil, errors.New("invalid revision file")
		}
	} else {
		dir.revision = dir.meta.OldRevision
	}
	return dir, nil
}

// join builds a path rooted at the charm's expanded directory
// path and the extra path components provided.
func (dir *Dir) join(parts ...string) string {
	parts = append([]string{dir.Path}, parts...)
	return filepath.Join(parts...)
}

// Revision returns the revision number for the charm
// expanded in dir.
func (dir *Dir) Revision() int {
	return dir.revision
}

// Meta returns the Meta representing the metadata.yaml file
// for the charm expanded in dir.
func (dir *Dir) Meta() *Meta {
	return dir.meta
}

// Config returns the Config representing the config.yaml file
// for the charm expanded in dir.
func (dir *Dir) Config() *Config {
	return dir.config
}

// SetRevision changes the charm revision number. This affects
// the revision reported by Revision and the revision of the
// charm bundled by BundleTo.
// The revision file in the charm directory is not modified.
func (dir *Dir) SetRevision(revision int) {
	dir.revision = revision
}

// SetDiskRevision does the same as SetRevision but also changes
// the revision file in the charm directory.
func (dir *Dir) SetDiskRevision(revision int) error {
	dir.SetRevision(revision)
	file, err := os.OpenFile(dir.join("revision"), os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		return err
	}
	_, err = file.Write([]byte(strconv.Itoa(revision)))
	file.Close()
	return err
}

// BundleTo creates a charm file from the charm expanded in dir.
// By convention a charm bundle should have a ".charm" suffix.
func (dir *Dir) BundleTo(w io.Writer) (err error) {
	zipw := zip.NewWriter(w)
	defer zipw.Close()
	zp := zipPacker{zipw, dir.Path}
	zp.AddRevision(dir.revision)
	return filepath.Walk(dir.Path, zp.WalkFunc())
}

type zipPacker struct {
	*zip.Writer
	root string
}

func (zp *zipPacker) WalkFunc() filepath.WalkFunc {
	return func(path string, fi os.FileInfo, err error) error {
		return zp.visit(path, fi, err)
	}
}

func (zp *zipPacker) AddRevision(revision int) error {
	h := &zip.FileHeader{Name: "revision"}
	h.SetMode(syscall.S_IFREG | 0644)
	w, err := zp.CreateHeader(h)
	if err == nil {
		_, err = w.Write([]byte(strconv.Itoa(revision)))
	}
	return err
}

func (zp *zipPacker) visit(path string, fi os.FileInfo, err error) error {
	if err != nil {
		return err
	}
	relpath, err := filepath.Rel(zp.root, path)
	if err != nil {
		return err
	}
	method := zip.Deflate
	hidden := len(relpath) > 1 && relpath[0] == '.'
	if fi.IsDir() {
		if relpath == "build" {
			return filepath.SkipDir
		}
		if hidden {
			return filepath.SkipDir
		}
		relpath += "/"
		method = zip.Store
	}

	mode := fi.Mode()
	if err := checkFileType(relpath, mode); err != nil {
		return err
	}
	if mode&os.ModeSymlink != 0 {
		method = zip.Store
	}
	if hidden || relpath == "revision" {
		return nil
	}
	h := &zip.FileHeader{
		Name:   relpath,
		Method: method,
	}

	perm := os.FileMode(0644)
	if mode&os.ModeSymlink != 0 {
		perm = 0777
	} else if mode&0100 != 0 {
		perm = 0755
	}
	h.SetMode(mode&^0777 | perm)

	w, err := zp.CreateHeader(h)
	if err != nil || fi.IsDir() {
		return err
	}
	var data []byte
	if mode&os.ModeSymlink != 0 {
		target, err := os.Readlink(path)
		if err != nil {
			return err
		}
		if err := checkSymlinkTarget(zp.root, relpath, target); err != nil {
			return err
		}
		data = []byte(target)
	} else {
		data, err = ioutil.ReadFile(path)
		if err != nil {
			return err
		}
	}
	_, err = w.Write(data)
	return err
}

func checkFileType(path string, mode os.FileMode) error {
	e := "file has an unknown type: %q"
	switch mode & os.ModeType {
	case os.ModeDir, os.ModeSymlink, 0:
		return nil
	case os.ModeNamedPipe:
		e = "file is a named pipe: %q"
	case os.ModeSocket:
		e = "file is a socket: %q"
	case os.ModeDevice:
		e = "file is a device: %q"
	}
	return fmt.Errorf(e, path)
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package main

import (
	"fmt"
	"log"
	"os"
	"path"
	"sync"

	"github.com/jacobsa/gcloud/gcs"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
)

const dirSeparator = '/'

// A "directory" in GCS, defined by an object name prefix. All prefixes end
// with dirSeparator except for the special case of the root directory, where
// the prefix is the empty string.
type dir struct {
	bucket       gcs.Bucket
	objectPrefix string

	mu sync.RWMutex

	// A map from (relative) names of children to nodes for those children,
	// initialized from GCS the first time it is needed for a ReadDir, Lookup,
	// etc. All nodes within the map are of type *dir or *file.
	children map[string]fs.Node // GUARDED_BY(mu)
}

// Initialize d.children from GCS if it has not already been populated.
func (d *dir) initChildren(ctx context.Context) error {
	d.mu.Lock()
	defer d.mu.Unlock()

	// Have we already initialized the map?
	if d.children != nil {
		return nil
	}

	children := make(map[string]fs.Node)

	// List repeatedly until there is no more to list.
	query := &storage.Query{
		Delimiter: string(dirSeparator),
		Prefix:    d.objectPrefix,
	}

	for query != nil {
		// Grab one set of results.
		objects, err := d.bucket.ListObjects(ctx, query)
		if err != nil {
			return fmt.Errorf("bucket.ListObjects: %v", err)
		}

		// Extract objects as files.
		for _, o := range objects.Results {
			// Special case: the GCS storage browser's "New folder" button causes an
			// object with a trailing slash to be created. For example, if you make a
			// folder called "bar" within a folder called "foo", that creates an
			// object called "foo/bar/". (It seems like the redundant ones may be
			// removed eventually, but that's not relevant.)
			//
			// When we list the directory "foo/", we don't want to return the object
			// named "foo/" as if it were a file within the directory. So skip it.
			if o.Name == d.objectPrefix {
				continue
			}

			children[path.Base(o.Name)] = &file{
				bucket:     d.bucket,
				objectName: o.Name,
			}
		}

		// Extract prefixes as directories.
		for _, p := range objects.Prefixes {
			children[path.Base(p)] = &dir{
				bucket:       d.bucket,
				objectPrefix: p,
			}
		}

		// Move on to the next set of results.
		query = objects.Next
	}

	// Save the map.
	d.children = children

	return nil
}

func (d *dir) Attr() fuse.Attr {
	return fuse.Attr{
		// TODO(jacobsa): Expose ACLs from GCS?
		Mode: os.ModeDir | 0500,
	}
}

func (d *dir) readDir(ctx context.Context) (
	ents []fuse.Dirent, fuseErr fuse.Error) {
	log.Printf("ReadDir: [%s]/%s", d.bucket.Name(), d.objectPrefix)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		log.Println("d.initChildren:", err)
		return nil, fuse.EIO
	}

	// Read out the contents of the cache.
	d.mu.RLock()
	defer d.mu.RUnlock()

	for name, node := range d.children {
		ent := fuse.Dirent{
			Name: name,
		}

		if _, ok := node.(*dir); ok {
			ent.Type = fuse.DT_Dir
		} else {
			ent.Type = fuse.DT_File
		}

		ents = append(ents, ent)
	}

	return
}

func (d *dir) lookup(ctx context.Context, name string) (fs.Node, fuse.Error) {
	log.Printf("Lookup: ([%s]/%s) %s", d.bucket.Name(), d.objectPrefix, name)

	// Join the directory's prefix with this node's name to get the full name
	// that we expect to see in GCS (minus the slash that will be on it if it's a
	// prefix representing a directory).
	fullName := path.Join(d.objectPrefix, name)

	// We must determine whether this is a file or a directory. List objects
	// whose names start with fullName.
	//
	// HACK(jacobsa): As of 2015-02-05 the documentation here doesn't guarantee
	// that object listing results are ordered by object name:
	//
	//    https://cloud.google.com/storage/docs/json_api/v1/objects/list
	//
	// Therefore in theory we are not guaranteed to see the object name on the
	// first page of results. It is reasonable to assume however that the results
	// are in order. Still, even if that is the case, we may have trouble with
	// directories since there are characters before '/' that could be in a path
	// name. Perhaps we should be sending a separate request for fullName plus
	// the slash, as much as it pains me to do so.
	query := &storage.Query{
		Delimiter: string(dirSeparator),
		Prefix:    fullName,
	}

	objects, err := d.bucket.ListObjects(ctx, query)
	if err != nil {
		log.Println("bucket.ListObjects:", err)
		return nil, fuse.EIO
	}

	// Is there a matching file name?
	for _, o := range objects.Results {
		if o.Name == fullName {
			node := &file{
				bucket:     d.bucket,
				objectName: o.Name,
			}
			return node, nil
		}
	}

	// Is there a matching directory name?
	for _, p := range objects.Prefixes {
		if p == fullName+"/" {
			node := &dir{
				bucket:       d.bucket,
				objectPrefix: p,
			}

			return node, nil
		}
	}

	return nil, fuse.ENOENT
}

func (d *dir) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) {
	ctx, cancel := withIntr(context.Background(), intr)
	defer cancel()

	return d.readDir(ctx)
}

func (d *dir) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
	ctx, cancel := withIntr(context.Background(), intr)
	defer cancel()

	return d.lookup(ctx, name)
}
<commit_msg>Use the cache for Lookup, too.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package main

import (
	"fmt"
	"log"
	"os"
	"path"
	"sync"

	"github.com/jacobsa/gcloud/gcs"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
)

const dirSeparator = '/'

// A "directory" in GCS, defined by an object name prefix. All prefixes end
// with dirSeparator except for the special case of the root directory, where
// the prefix is the empty string.
type dir struct {
	bucket       gcs.Bucket
	objectPrefix string

	mu sync.RWMutex

	// A map from (relative) names of children to nodes for those children,
	// initialized from GCS the first time it is needed for a ReadDir, Lookup,
	// etc. All nodes within the map are of type *dir or *file.
	children map[string]fs.Node // GUARDED_BY(mu)
}

// Initialize d.children from GCS if it has not already been populated.
func (d *dir) initChildren(ctx context.Context) error {
	d.mu.Lock()
	defer d.mu.Unlock()

	// Have we already initialized the map?
	if d.children != nil {
		return nil
	}

	children := make(map[string]fs.Node)

	// List repeatedly until there is no more to list.
	query := &storage.Query{
		Delimiter: string(dirSeparator),
		Prefix:    d.objectPrefix,
	}

	for query != nil {
		// Grab one set of results.
		objects, err := d.bucket.ListObjects(ctx, query)
		if err != nil {
			return fmt.Errorf("bucket.ListObjects: %v", err)
		}

		// Extract objects as files.
		for _, o := range objects.Results {
			// Special case: the GCS storage browser's "New folder" button causes an
			// object with a trailing slash to be created. For example, if you make a
			// folder called "bar" within a folder called "foo", that creates an
			// object called "foo/bar/". (It seems like the redundant ones may be
			// removed eventually, but that's not relevant.)
			//
			// When we list the directory "foo/", we don't want to return the object
			// named "foo/" as if it were a file within the directory. So skip it.
			if o.Name == d.objectPrefix {
				continue
			}

			children[path.Base(o.Name)] = &file{
				bucket:     d.bucket,
				objectName: o.Name,
			}
		}

		// Extract prefixes as directories.
		for _, p := range objects.Prefixes {
			children[path.Base(p)] = &dir{
				bucket:       d.bucket,
				objectPrefix: p,
			}
		}

		// Move on to the next set of results.
		query = objects.Next
	}

	// Save the map.
	d.children = children

	return nil
}

func (d *dir) Attr() fuse.Attr {
	return fuse.Attr{
		// TODO(jacobsa): Expose ACLs from GCS?
		Mode: os.ModeDir | 0500,
	}
}

func (d *dir) readDir(ctx context.Context) (
	ents []fuse.Dirent, fuseErr fuse.Error) {
	log.Printf("ReadDir: [%s]/%s", d.bucket.Name(), d.objectPrefix)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		log.Println("d.initChildren:", err)
		return nil, fuse.EIO
	}

	// Read out the contents of the cache.
	d.mu.RLock()
	defer d.mu.RUnlock()

	for name, node := range d.children {
		ent := fuse.Dirent{
			Name: name,
		}

		if _, ok := node.(*dir); ok {
			ent.Type = fuse.DT_Dir
		} else {
			ent.Type = fuse.DT_File
		}

		ents = append(ents, ent)
	}

	return
}

func (d *dir) lookup(ctx context.Context, name string) (fs.Node, fuse.Error) {
	log.Printf("Lookup: ([%s]/%s) %s", d.bucket.Name(), d.objectPrefix, name)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		log.Println("d.initChildren:", err)
		return nil, fuse.EIO
	}

	// Find the object within the map.
	if n, ok := d.children[name]; ok {
		return n, nil
	}

	return nil, fuse.ENOENT
}

func (d *dir) ReadDir(intr fs.Intr) ([]fuse.Dirent, fuse.Error) {
	ctx, cancel := withIntr(context.Background(), intr)
	defer cancel()

	return d.readDir(ctx)
}

func (d *dir) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
	ctx, cancel := withIntr(context.Background(), intr)
	defer cancel()

	return d.lookup(ctx, name)
}
<|endoftext|>


<commit_before>// Package mux is a simple-mux, however, it provides a few nice features such as easy use of middleware and a router
// which doesn't automatically look at only prefixes (like the Go built-in mux).
//
// Middleware can be added to both prefixes and to endpoints, which means that the simple composability of this gives a
// lot of power. Inclusion of a middleware pipeline within the router also provides lots of power, plus less end-user
// code.
//
//     m := mux.New()
//
//     m.Get("/", func(w http.ResponseWriter, r *http.Request) {
//         w.WriteHeader(http.StatusOK)
//         w.Write([]byte("Home\n"))
//     })
//
//     log.Fatal(http.ListenAndServe(":8080", m))
//
// Inspired by a few other routers and middlewares such as:
//
//     • https://github.com/justinas/alice
//     • https://golang.org/pkg/net/http/#ServeMux
//     • https://github.com/gorilla/mux
//     • https://github.com/julienschmidt/httprouter
//     • https://github.com/pressly/chi
//     • https://github.com/dimfeld/httptreemux
//     • https://github.com/bmizerany/pat
//     • https://github.com/pilu/traffic
//     • https://github.com/rcrowley/go-tigertonic
//     • https://github.com/mikespook/possum
//     • https://github.com/zenazn/goji/
//     • https://github.com/gocraft/web
//
package mux
<commit_msg>More docs<commit_after>// Package mux is a simple(ish) mux, however, it provides a few nice features such as easy use of middleware and a
// router which doesn't automatically look at only prefixes (like the Go built-in mux). Everything is explicit and
// nothing is done for you. ie. we don't automatically redirec to a slash or non-slash version of each path, you need
// to do that yourself (or use github.com/gomiddleware/slash to help).
//
// There are two fundamentals at work here, middleware and handlers. Middleware is expected to either: (1) do something
// with the request/response/context on the way in, call the `next` middleware and optionally do something on the way
// out, or (2) deal with the request completely and not call the `next` middleware at all. It is up to the middleware to decide this.
//
// An example of middleware calling next might be adding a requestId in to each request's Context. An
//
// An example of middleware dealing with the request might be to check that a user is logged in, and if not, sending a
// redirect to "/", or sending back a 403.
//
// For the purposes of this library (and in general), a middleware is defined as one of these:
//
// • func(http.Handler) http.Handler
//
// • func(http.HandlerFunc) http.HandlerFunc
//
// For the purposes of this library (and in general), a handler is defined as:
//
// • http.Handler
//
// • func(http.ResponseWriter, *http.Request)
//
// To add middleware to any prefix, use:
//
//     m.Use("/prefix", middlewares...)
//
// To add a handler to any path, use one of Get/Post/Put/Patch/Delete/Options/Head such as:
//
//     m.Get("/path", [middlewares...,] handler)
//
// Of course, you can only add one handler to each route, and it must be the last thing you pass in.
//
// Don't worry that you are passing one of 4 types in to each method since they are organised at the time they are
// added, and not during the request cycle. Only type assertions are used and not reflection.
//
// Example
//
//     m := mux.New()
//
//     m.Use("/", logger.New())
//
//     m.Get("/", func(w http.ResponseWriter, r *http.Request) {
//         w.WriteHeader(http.StatusOK)
//         w.Write([]byte("Home\n"))
//     })
//
//     m.Get("/my/", checkUserIsSignedIn, userHomeHandler)
//
//     if m.Err != nil {
//         // ... something went wrong with a route
//     }
//
//     log.Fatal(http.ListenAndServe(":8080", m))
//
// More information and examples can be found at http://chilts.org/2017/01/27/gomiddleware-mux
//
package mux
<|endoftext|>


<commit_before>// Package is is a mini testing helper.
//
//     func TestSomething(t *testing.T) {
//       is := is.New(t)
//       obj, err := MethodBeingTested()
//       is.OK(obj, err) // list of objects, all must be OK
//       is.Equal(obj, "Hello world")
//     }
//
// OK
//
// The OK method asserts that the specified object is OK, which means
// different things for different types:
//
//     bool  - OK means not false
//     int   - OK means not zero
//     error - OK means nil
//     string - OK means not ""
//     everything else - OK means not nil
//
// Equal
//
// The Equal method asserts that two objects are effectively equal.
package is
<commit_msg>updated docs<commit_after>// Package is is a mini testing helper.
//
//     func TestSomething(t *testing.T) {
//       is := is.New(t)
//       obj, err := MethodBeingTested()
//       is.OK(obj, err) // list of objects, all must be OK
//       is.Equal(obj, "Hello world")
//     }
//
// is.OK
//
// is.OK asserts that the specified object is OK, which means
// different things for different types:
//
//     bool  - OK means not false
//     int   - OK means not zero
//     error - OK means nil
//     string - OK means not ""
//     everything else - OK means not nil
//
// is.Equal
//
// is.Equal asserts that two objects are effectively equal.
//
// is.Panic and is.PanicWith
//
// is.Panic and is.PanicWith asserts that the func() will panic.
// PanicWith specifies the panic text that is expected:
//
//     func TestInvalidArgs(t *testing.T) {
//       is := is.New(t)
//       is.Panic(func(){
//         SomeMethod(1)
//       })
//       is.PanicWith("invalid args, both cannot be nil", func(){
//         OtherMethod(nil, nil)
//       })
//     }
package is
<|endoftext|>


<commit_before>/*
Mongo Session Store follows the Gorilla Session implementation

Reason for creatio over using an existing library
	When the MongoDB database the sessions were being stored in was not reachable
	especially in the event of a database cycle other libraries would not
	restablish the database session; this library will.

Example Usage
	func foo(w http.ResponseWriter, r *http.Request) {

        // Coonect to MongoDB
        dbSess, err := mgo.Dial("localhost")
        if err != nil {
            panic(err)
        }
        defer dbSess.Close()

        store := mongostore.NewMongoStore(dbSess, "sessions", 3600, true,
            []byte("secret-key"))

        // Get a session.
        session, err := store.Get(r, "session-key")
        if err != nil {
            log.Println(err.Error())
        }

        // Add a value.
        session.Values["foo"] = "bar"

        // Save.
        if err = sessions.Save(r, w); err != nil {
            log.Printf("Error saving session: %v", err)
        }

        fmt.Fprintln(w, "ok")
    }

*/

package mongostore
<commit_msg>correct doc.go extra spaces<commit_after>/*
Mongo Session Store follows the Gorilla Session implementation

Reason for creation over using an existing library
	When the MongoDB database the sessions were being stored in was not reachable
	especially in the event of a database cycle other libraries would not
	restablish the database session; this library will.

Example Usage:

	func foo(w http.ResponseWriter, r *http.Request) {

        // Coonect to MongoDB
        dbSess, err := mgo.Dial("localhost")
        if err != nil {
            panic(err)
        }
        defer dbSess.Close()

        store := mongostore.NewMongoStore(dbSess, "sessions", 3600, true,
            []byte("secret-key"))

        // Get a session.
        session, err := store.Get(r, "session-key")
        if err != nil {
            log.Println(err.Error())
        }

        // Add a value.
        session.Values["foo"] = "bar"

        // Save.
        if err = sessions.Save(r, w); err != nil {
            log.Printf("Error saving session: %v", err)
        }

        fmt.Fprintln(w, "ok")
    }

*/
package mongostore
<|endoftext|>


<commit_before>/*
Package petrel provides a simple-to-use networking server and client,
with builtin request dispatch. It is intended to be unobtrusive and
easy to integrate into applications.

QUICK START

Instantiate a handler:

HOW IT WORKS

HANDLER.MSGR AND MSGS

Msgr is a buffered channel, capable of holding 32 Msgs. If the buffer
fills up, new messages are dropped on the floor to avoid blocking.

The exception to this is a message with a code of 599. It is allowed
to block, since it indicates that the listener socket has stopped
working. If a 599 is received, immediately halt the petrel instance.

Msg.Status tells you what has happened.

Which messages are sent to Msgr is determined by petrel.Config.Msglvl.

    * Fatal is fatal errors only (599)
    * Error adds all other Petrel errors (all 500s)
    * Conn adds messages about connection opens/closes
    * All adds everything else

Messages which are not errors according Petrel may have a Msg.Err
value other than nil. Client disconnects for instance, pass along the
socket read error which triggered them.

SHUTDOWN AND CLEANUP

When Server.Quit() is called, the instance stops accepting new
connections, and waits for all existing connections to terminate.

If the Server was configured with long timeouts (or no timeout at
all), then Quit() may block for a long time.

Once Quit() returns, the Server is fully shut down. If you are
recovering from a listener socket error (code 599), it is safe to
spawn a new Server at this point.
*/
package petrel
<commit_msg>doc.go should be folded into the README<commit_after><|endoftext|>


<commit_before>/*

Library that makes easier to write integration tests that depends on runnings daemons/services.

Example:

  // Create a Testd instance, informing where you want the logs to be saved,
  // the command to execute and its arguments.
  //
  daemon, err := testd.New("./tests/debug/daemon.log", "daemon", "arg1", "arg2")

  // Do your testing, that depends on the daemon being running.
  // When you are done testing, just call the Stop method.
  err := daemon.Stop()

  // Remember to do proper error handling, both on New and Stop.
*/
package testd
<commit_msg>just making it a little better<commit_after>/*

testd that makes easier to write integration tests that depends on runnings daemons/services.

Example:

  // Create a Testd instance, informing where you want the logs to be saved,
  // the command to execute and its arguments.
  //
  daemon, err := testd.New("./tests/debug/daemon.log", "daemon", "arg1", "arg2")

  // Do your testing, that depends on the daemon being running.
  // When you are done testing, just call the Stop method.
  err := daemon.Stop()

  // Remember to do proper error handling, both on New and Stop.
*/
package testd
<|endoftext|>


<commit_before>// Работа с внутренней базой для определения географических координат по данным вышек сотовой
// станции.
//
// Интерфейс запросов и ответов полностью совпадает с интерфейсом
// [github.com/geotrace/locator](https://github.com/geotrace/locator/), поэтому данная библиотека
// может использоваться как замена удаленных сервисов геолокации Mozilla, Yandex или Google.
// В качестве наполнения базы данных можно использовать данные, предоставляемые OpenCellID или
// Mozilla Locator.
//
// В качестве хранилища для данных используется MongoDB.
//
// В состав библиотеке так же входит программа
// [`lbs-import`](https://github.com/geotrace/lbs/tree/master/lbs-import), для импорта данных о
// сотовых вышках и их координатах, представленных в формате CSV.
package lbs
<commit_msg>doc fix<commit_after>// Работа с внутренней базой для определения географических координат по данным вышек сотовой
// станции.
//
// Интерфейс запросов и ответов полностью совпадает с интерфейсом github.com/geotrace/locator,
// поэтому данная библиотека может использоваться как замена удаленных сервисов геолокации Mozilla,
// Yandex или Google.
//
// В качестве наполнения базы данных можно использовать данные, предоставляемые OpenCellID или
// Mozilla Locator.
//
// В качестве хранилища для данных используется MongoDB.
//
// В состав библиотеке так же входит программа lbs-import, для импорта данных о сотовых вышках и их
// координатах, представленных в формате CSV.
package lbs
<|endoftext|>


<commit_before>// Copyright 2013 The XORM Authors. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

// Package xorm provides is a simple and powerful ORM for Go. It makes your
// database operation simple.

package xorm
<commit_msg>improved doc.go<commit_after>// Copyright 2013 The XORM Authors. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

// Package xorm provides is a simple and powerful ORM for Go. It makes
// database operation simple.
package xorm
<|endoftext|>


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

// Package tcell provides a lower-level, portable API for building
// programs that interact with terminals or consoles.  It works with
// both common (and many uncommon!) terminals or terminal emulators,
// and Windows console implementations.
//
// It provides support for up to 256 colors, text attributes, and box drawing
// elements.  A database of terminals built from a real terminfo database
// is provided, along with code to generate new database entries.
//
// Tcell offers very rich support for mice, dependent upon the terminal
// of course.  (Windows, XTerm, and iTerm 2 are known to work very well.)
//
// If the environment is not Unicode by default, such as an ISO8859 based
// locale or GB18030, Tcell can convert input and output, so that your
// terminal can operate in whatever locale is most convenient, while the
// application program can just assume "everything is UTF-8".  Reasonable
// defaults are used for updating characters to something suitable for
// display.  Unicode box drawing characters will be converted to use the
// alternate character set of your terminal, if native conversions are
// not available.  If no ACS is available, then some ASCII fallbacks will
// be used.
//
// Note that support for non-UTF-8 locales (other than C)  must be enabled
// by the application using RegisterEncoding() -- we don't have them all
// enabled by default to avoid bloating the application unneccessarily.
// (These days UTF-8 is good enough for almost everyone, and nobody should
// be using legacy locales anymore.)  Also, actual glyphs for various code
// point will only be displayed if your terminal or emulator (or the font
// the emulator is using) supports them.
//
// A rich set of keycodes is supported, with support for up to 65 function
// keys, and various other special keys.
package tcell
<commit_msg>fix spelling<commit_after>// Copyright 2018 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package tcell provides a lower-level, portable API for building
// programs that interact with terminals or consoles.  It works with
// both common (and many uncommon!) terminals or terminal emulators,
// and Windows console implementations.
//
// It provides support for up to 256 colors, text attributes, and box drawing
// elements.  A database of terminals built from a real terminfo database
// is provided, along with code to generate new database entries.
//
// Tcell offers very rich support for mice, dependent upon the terminal
// of course.  (Windows, XTerm, and iTerm 2 are known to work very well.)
//
// If the environment is not Unicode by default, such as an ISO8859 based
// locale or GB18030, Tcell can convert input and output, so that your
// terminal can operate in whatever locale is most convenient, while the
// application program can just assume "everything is UTF-8".  Reasonable
// defaults are used for updating characters to something suitable for
// display.  Unicode box drawing characters will be converted to use the
// alternate character set of your terminal, if native conversions are
// not available.  If no ACS is available, then some ASCII fallbacks will
// be used.
//
// Note that support for non-UTF-8 locales (other than C)  must be enabled
// by the application using RegisterEncoding() -- we don't have them all
// enabled by default to avoid bloating the application unnecessarily.
// (These days UTF-8 is good enough for almost everyone, and nobody should
// be using legacy locales anymore.)  Also, actual glyphs for various code
// point will only be displayed if your terminal or emulator (or the font
// the emulator is using) supports them.
//
// A rich set of keycodes is supported, with support for up to 65 function
// keys, and various other special keys.
package tcell
<|endoftext|>


<commit_before>/*
Go Fake It

Examples set seed in order for test to successfully return same results. In actual use you only need to set seed once.
*/
package gofakeit
<commit_msg>documentation - minor text update.<commit_after>/*
Go Fake It

Fake Data Generator. A large goal is to keep things extremely simple, clean, self contained, tested and documented.

Contributions are welcome as im sure things can always be better.
*/
package gofakeit
<|endoftext|>


<commit_before>/*
Package junos allows you to run commands on and configure Junos devices.

Establishing a session
    jnpr := junos.NewSession(host, user, password)
    defer jnpr.Close()

Locking the configuration.
	err := jnpr.Lock()
	if err != nil {
		log.Fatal(err)
	}

Loading a configuration file where the commands are in "set" format.
	err = jnpr.LoadConfig("config.txt", "set")
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

Commiting the configuration in multiple ways.
    err = jnpr.Commit()
    if err != nil {
        log.Fatal(err)
    }

    // Commit at a specific time (i.e. 3 PM)
    err = jnpr.CommitAt("15:00:00")
    if err != nil {
        log.Fatal(err)
    }

    // Rollback the config after 15 minutes if no other commit is issued.
    err = jnpr.CommitConfirmed(15)
    if err != nil {
        log.Fatal(err)
    }

Unlocking the configuration.
	err = jnpr.Unlock()
	if err != nil {
		log.Fatal(err)
	}

Compare the current configuration to a rollback config.
	diff, err := jnpr.RollbackDiff(3)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(diff)

The output from RollbackDiff() will be exactly as it is running the "| compare" command on the CLI:

    [edit forwarding-options helpers bootp server 192.168.10.2]
    -     routing-instance srx-vr;
    [edit forwarding-options helpers bootp server 192.168.10.3]
    -     routing-instance srx-vr;
    [edit security address-book global]
         address server1 { ... }
    +    address pc1 192.168.20.15/32;
    +    address pc2 192.168.22.7/32;

Rollback to an older configuration.
	err := jnpr.RollbackConfig(2)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

Run operational mode commands, such as "show."
	output, err := jnpr.Command("show version", "text")
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(output)

When you specify "text," the output will be formatted exactly as it is on the CLI:

    node0:
    --------------------------------------------------------------------------
    Hostname: firewall-1
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

    node1:
    --------------------------------------------------------------------------
    Hostname: firewall-2
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

*/
package junos
<commit_msg>Updated documentation<commit_after>/*
Package junos allows you to interact with Junos devices.

Establishing a session
    jnpr := junos.NewSession(host, user, password)
    defer jnpr.Close()

Locking the configuration.
	err := jnpr.Lock()
	if err != nil {
		log.Fatal(err)
	}

Loading a configuration file where the commands are in "set" format.
	err = jnpr.LoadConfig("config.txt", "set")
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

Commiting the configuration in multiple ways.
    err = jnpr.Commit()
    if err != nil {
        log.Fatal(err)
    }

    // Commit at a specific time (i.e. 3 PM)
    err = jnpr.CommitAt("15:00:00")
    if err != nil {
        log.Fatal(err)
    }

    // Rollback the config after 15 minutes if no other commit is issued.
    err = jnpr.CommitConfirmed(15)
    if err != nil {
        log.Fatal(err)
    }

Unlocking the configuration.
	err = jnpr.Unlock()
	if err != nil {
		log.Fatal(err)
	}

Compare the current configuration to a rollback config.
	diff, err := jnpr.RollbackDiff(3)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(diff)

The output from RollbackDiff() will be exactly as it is running the "| compare" command on the CLI:

    [edit forwarding-options helpers bootp server 192.168.10.2]
    -     routing-instance srx-vr;
    [edit forwarding-options helpers bootp server 192.168.10.3]
    -     routing-instance srx-vr;
    [edit security address-book global]
         address server1 { ... }
    +    address pc1 192.168.20.15/32;
    +    address pc2 192.168.22.7/32;

Rollback to an older configuration.
	err := jnpr.RollbackConfig(2)
	if err != nil {
		fmt.Printf("Error: %s", err)
	}

Run operational mode commands, such as "show."
	output, err := jnpr.Command("show version", "text")
	if err != nil {
		fmt.Printf("Error: %s", err)
	}
	fmt.Println(output)

When you specify "text," the output will be formatted exactly as it is on the CLI:

    node0:
    --------------------------------------------------------------------------
    Hostname: firewall-1
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

    node1:
    --------------------------------------------------------------------------
    Hostname: firewall-2
    Model: srx240h2
    JUNOS Software Release [12.1X47-D10.4]

*/
package junos
<|endoftext|>


<commit_before>/*
	Package counter implements some types of counters and a rate limit tracker

	Usage:

	A basic atomic(thread safe) counter:

		c := NewCounter(0)
		c.Add(1) // 1
		c.Value() // 1
		c.Set(5)
		c.Value() // 5
		c.Reset(1) // 5
		c.Value() // 1

	A DeltaCounter keeps track of the changes to the counter since last Reset

		d := NewDeltaCounter(0)
		d.Add(5) // 5
		d.Delta() // 5
		d.Reset(1) // 5
		d.Delta() // 0
		d.Value() // 1
		d.Add(-3)
		d.Delta() // -3
		d.Value() // -2

	A RateLimit tracks the rate of use of some resource.
	To limit the rate of use to let's say, 5 per minute.

		r := NewRateLimit(5, time.Minute)
		if r.Hit() {
			// rate limit exceeded
		}
		// normal code

	You will achieve grater precision with greater time deltas, so use
	60 / Minute instead of 1 / Second

		// Worse
		r := NewRateLimite(1, time.Second)
		// Better
		r := NewRateLimit(60, time.Minute)

*/
package counter
<commit_msg>doc typo<commit_after>/*
	Package counter implements some types of counters and a rate limit tracker

	Usage:

	A basic atomic(thread safe) counter:

		c := NewCounter(0)
		c.Add(1) // 1
		c.Value() // 1
		c.Set(5)
		c.Value() // 5
		c.Reset(1) // 5
		c.Value() // 1

	A DeltaCounter keeps track of the changes to the counter since last Reset

		d := NewDeltaCounter(0)
		d.Add(5) // 5
		d.Delta() // 5
		d.Reset(1) // 5
		d.Delta() // 0
		d.Value() // 1
		d.Add(-3)
		d.Delta() // -3
		d.Value() // -2

	A RateLimit tracks the rate of use of some resource.
	To limit the rate of use to let's say, 5 per minute.

		r := NewRateLimit(5, time.Minute)
		if r.Hit() {
			// rate limit exceeded
		}
		// normal code

	You will achieve greater precision with greater time deltas, so use
	60 / Minute instead of 1 / Second

		// Worse
		r := NewRateLimite(1, time.Second)
		// Better
		r := NewRateLimit(60, time.Minute)

*/
package counter
<|endoftext|>


<commit_before>/*
Package memsize computes the size of your object graph.

So you made a spiffy algorithm and it works really well, but geez it's using
way too much memory. Where did it all go? memsize to the rescue!

To get started, create a RootSet and add some roots:

    var rs memsize.RootSet
    rs.Add("my object", obj)
    rs.Add("some other object", obj2)

You can traverse the graph to get all the objects and their respective sizes:

    sizes := rs.Scan()
    fmt.Println(sizes.Total())

memsize can handle cycles just fine and tracks both private and public struct fields.
There are a few limitations though:

Channel buffers cannot be scanned

There is no way to get the content of a channel buffer without reading from the channel.
memsize will report size based on the cap of the channel, but can't tell you how much
memory is used its elements.
*/
package memsize
<commit_msg>memsize: document that closures can't be scanned<commit_after>/*
Package memsize computes the size of your object graph.

So you made a spiffy algorithm and it works really well, but geez it's using
way too much memory. Where did it all go? memsize to the rescue!

To get started, create a RootSet and add some roots:

    var rs memsize.RootSet
    rs.Add("my object", obj)
    rs.Add("some other object", obj2)

You can traverse the graph to get all the objects and their respective sizes:

    sizes := rs.Scan()
    fmt.Println(sizes.Total())

memsize can handle cycles just fine and tracks both private and public struct fields.
There are a few limitations though:

Channel buffers and closures cannot be scanned

There is no way to get the content of a channel buffer without reading from the channel.
memsize will report size based on the cap of the channel, but can't tell you how much
memory is used its elements.

Function closures cannot be inspected in any way.
*/
package memsize
<|endoftext|>


<commit_before>// Copyright 2016 Marcel Gotsch. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// Package goserv provides a fast, easy and minimalistic framework for
// web applications in Go.
//
// Getting Started
//
// Every goserv application starts with a single instance of goserv.Server. This
// instance is the entry point for all incoming requests.
//
//      server := goserv.NewServer()
//
// To start handling paths you must register handlers to paths using one of the Server's
// embedded Router functions, like Get.
//
//      server.Get("/", homeHandler)
//
// The first argument in the Get() call is the path for which the
// handler gets registered. To learn more about paths take a look at the Path section.
// As the name of the function suggests the requests are only getting dispatched to the handler
// if the request method is "GET". There are a lot more methods like this one available, just take
// a look at the documentation of the Router.
//
// At this point it is worth noting that goserv provides it's own Handler type using the
// goserv.ResponseWriter and goserv.Request. This means that all http.Handlers cannot
// be used with goserv without wrapping them in a goserv.Handler. To make this more convenient
// a function called WrapHTTPHandler exists.
//
//      server.Get("/", WrapHTTPHandler(httpHomeHandler))
//
// Sometimes it is useful to have handlers that are invoked all the time, also known as middleware.
// To register middleware use the Use() function.
//
//      server.Use(accessLogger)
//
// Path Syntax
//
// All Routes and Routers are registered under a path. This path is matched against the path
// of incoming requests.
//
// A Route created from "/mypath" will only match the request path if it is exactly
// "/mypath".
//
// In case that the Route should match everything starting with "/mypath" a wildcard
// can be appended to the path, i.e.
//	/mypath*
//
// The wildcard can be at any position in the path. It also possible to just use the wildcard
// as path.
//
// Sometimes it is necessary to capture values from parts of the request path, so called parameters.
// To include parameters in a Route the path must contain a named parameter, e.g.
//	/users/:user_id
//
// Parameters always start with a ":" after a "/". The name (without the leading ":") can contain
// alphanumeric symbols as well as "_" and "-". The number of parameters in a Route is not limited, but
// they must be separated by at least a single "/".
//	/:value1/:value2
//
// Routers allow you to register handlers for each parameter in a Route. Each handler gets invoked
// once per parameter and request. That means even though a Router may invoked multiple Routes the
// parameter handlers are invoked only once.
//
//      router.Get("/users/:user_id", handler)
//      router.Param("user_id", userIDHandler)
//
// When a Route processes a Request it automatically extracts the captured parameter values from the path
// and stores the values under their name in the .Param field of the Request.
//
// Strict vs non-strict Slash
//
// A Route can have either strict slash or non-strict slash behavior. In non-strict mode paths with or
// without a trailing slash are considered to be the same, i.e. a Route registered with "/mypath" in
// non-strict mode matches both "/mypath" and "/mypath/". In strict mode both
// paths are considered to be different.
//
// Order matters
//
// The order in which Handlers are registered does matter. An incoming request goes through in the
// exact same order. After each handler the Router checks wether an error was set on the
// ResponseWriter or if a response was written and ends the processing if necessary. In case of an error
// the Router forwards the request along with the error to its ErrorHandler, but only if one is available.
// All sub Routers have no ErrorHandler by default, so all errors are handled by the top level Server. It
// is possible though to handle errors in a sub Router by setting a custom ErrorHandler.
//
// A small example shows how requests are processed in a Router:
//
//      server.Use(A)
//      server.Get("/", B)
//      server.Use(C)
//      server.SubRouter("/sub", D)
//
// All incoming request will follow the order "ABCD". The
package goserv
<commit_msg>Improve doc.go<commit_after>// Copyright 2016 Marcel Gotsch. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// Package goserv provides a fast, easy and minimalistic framework for
// web applications in Go.
//
// Getting Started
//
// Every goserv application starts with a single instance of goserv.Server. This
// instance is the entry point for all incoming requests.
//
//      server := goserv.NewServer()
//
// To start handling paths you must register handlers to paths using one of the Server's
// embedded Router functions, like Get.
//
//      server.Get("/", homeHandler)
//
// The first argument in the Get() call is the path for which the
// handler gets registered. To learn more about paths take a look at the Path section.
// As the name of the function suggests the requests are only getting dispatched to the handler
// if the request method is "GET". There are a lot more methods like this one available, just take
// a look at the documentation of the Router.
//
// At this point it is worth noting that goserv provides it's own Handler type using the
// goserv.ResponseWriter and goserv.Request. This means that all http.Handlers cannot
// be used with goserv without wrapping them in a goserv.Handler. To make this more convenient
// a function called WrapHTTPHandler exists.
//
//      server.Get("/", WrapHTTPHandler(httpHomeHandler))
//
// Sometimes it is useful to have handlers that are invoked all the time, also known as middleware.
// To register middleware use the Use() function.
//
//      server.Use(accessLogger)
//
// Path Syntax
//
// All Routes and Routers are registered under a path. This path is matched against the path
// of incoming requests. A Route created from "/mypath" will only match the request path if it is exactly
// "/mypath". In case that the Route should match everything starting with "/mypath" a wildcard
// can be appended to the path, i.e.
//
//	/mypath*
//
// The wildcard can be at any position in the path. It is also possible to just use the wildcard
// as path.
//
// Sometimes it is necessary to capture values from parts of the request path, so called parameters.
// To include parameters in a Route the path must contain a named parameter, e.g.
//	/users/:user_id
//
// Parameters always start with a ":" after a "/". The name (without the leading ":") can contain
// alphanumeric symbols as well as "_" and "-". The number of parameters in a Route is not limited, but
// they must be separated by at least a single "/".
//	/:value1/:value2
//
// Routers allow you to register handlers for each parameter in a Route. Each handler gets invoked
// once per request. That means even though a Router may invoke multiple Routes the
// parameter handlers are invoked only once.
//
//      router.Get("/users/:user_id", handler)
//      router.Param("user_id", userIDHandler)
//
// When a Route processes a request it automatically extracts the captured parameter values from the path
// and stores the values under their name in the .Param field of the Request.
//
// Strict vs non-strict Slash
//
// A Route can have either strict slash or non-strict slash behavior. In non-strict mode paths with or
// without a trailing slash are considered to be the same, i.e. a Route registered with "/mypath" in
// non-strict mode matches both "/mypath" and "/mypath/". In strict mode both
// paths are considered to be different.
//
// Order matters
//
// The order in which Handlers are registered does matter. An incoming request goes through in the
// exact same order. After each handler the Router checks wether an error was set on the
// ResponseWriter or if a response was written and ends the processing if necessary. In case of an error
// the Router forwards the request along with the error to its ErrorHandler, but only if one is available.
// All sub Routers have no ErrorHandler by default, so all errors are handled by the top level Server. It
// is possible though to handle errors in a sub Router by setting a custom ErrorHandler.
//
// A small example shows how requests are processed in a Router:
//
//      server.Use(A)
//      server.Get("/", B)
//      server.Use(C)
//      server.SubRouter("/sub", D)
//
// All incoming request will follow the order "ABCD".
package goserv
<|endoftext|>


<commit_before>package eff

import (
	"errors"
	"math"
	"math/rand"

	"strconv"
)

const (
	// Version current semantic version of eff
	Version = "0.1.0"
)

// Point container for 2d points
type Point struct {
	X int
	Y int
}

// Scale returns a new scaled point
func (p *Point) Scale(s float64) Point {
	return Point{
		X: int(float64(p.X) * s),
		Y: int(float64(p.Y) * s),
	}
}

// Offset returns an offset point
func (p *Point) Offset(x int, y int) Point {
	return Point{
		X: p.X + x,
		Y: p.Y + y,
	}
}

// ScalePoints returns a new slice of scaled points
func ScalePoints(points []Point, s float64) []Point {
	var scaledPoints []Point
	for _, p := range points {
		scaledPoints = append(scaledPoints, p.Scale(s))
	}

	return scaledPoints
}

// OffsetPoints returns a new slice of offset points
func OffsetPoints(points []Point, x int, y int) []Point {
	var offsetPoints []Point
	for _, p := range points {
		offsetPoints = append(offsetPoints, p.Offset(x, y))
	}

	return offsetPoints
}

// Color container for argb colors
type Color struct {
	R int
	G int
	B int
	A int
}

// RandomColor genereate a random color struct.  The opacity is also random
func RandomColor() Color {
	return Color{
		R: rand.Intn(0xFF),
		G: rand.Intn(0xFF),
		B: rand.Intn(0xFF),
		A: 0xFF,
	}
}

// Black returns a color struct that is black
func Black() Color {
	return Color{
		R: 0x00,
		G: 0x00,
		B: 0x00,
		A: 0xFF,
	}
}

// White returns a color struct that is white
func White() Color {
	return Color{
		R: 0xFF,
		G: 0xFF,
		B: 0xFF,
		A: 0xFF,
	}
}

// ColorWithHex creates an eff color w/ a hex string in the formant "#FF00FF"
func ColorWithHex(hex string) (Color, error) {
	if hex[0] == '#' {
		hex = hex[1:]
	}

	if len(hex) < 6 {
		return Color{}, errors.New("Invalid hex color, too short")
	}

	r, err := strconv.ParseInt(hex[:2], 16, 32)
	if err != nil {
		return Color{}, err
	}

	g, err := strconv.ParseInt(hex[2:4], 16, 32)
	if err != nil {
		return Color{}, err
	}

	b, err := strconv.ParseInt(hex[4:6], 16, 32)
	if err != nil {
		return Color{}, err
	}

	return Color{
		R: int(r),
		G: int(g),
		B: int(b),
		A: 0xFF,
	}, nil
}

// Rect container for rectangle
type Rect struct {
	X int
	Y int
	W int
	H int
}

// Scale returns a new scaled Rect
func (r *Rect) Scale(s float64) Rect {
	return Rect{
		X: int(float64(r.X) * s),
		Y: int(float64(r.Y) * s),
		W: int(float64(r.W) * s),
		H: int(float64(r.H) * s),
	}
}

// LocalInside tests to see if rect is inside of this rect, assumes test rect has coordinates local to this rect
func (r *Rect) LocalInside(testRect Rect) bool {
	if testRect.X > r.W {
		return false
	}

	if testRect.Y > r.H {
		return false
	}

	if (testRect.X + testRect.W) < 0 {
		return false
	}

	if (testRect.Y + testRect.H) < 0 {
		return false
	}

	return true
}

// ScaleRects returns a new slice of scaled Rects
func ScaleRects(rects []Rect, s float64) []Rect {
	var scaledRects []Rect
	for _, r := range rects {
		scaledRects = append(scaledRects, r.Scale(s))
	}

	return scaledRects
}

// Font describes a ttf font
type Font interface {
	Path() string
	Size() int
}

// Image describes an image
type Image interface {
	Path() string
	Width() int
	Height() int
}

// Equals test to see if two rectangles occupy the same location exactly
func (r *Rect) Equals(otherRect Rect) bool {
	return (r.X == otherRect.X &&
		r.Y == otherRect.Y &&
		r.W == otherRect.W &&
		r.H == otherRect.H)
}

// Intersects check to see if a rectangle is inside of this rectangle
func (r *Rect) Intersects(otherRect Rect) bool {
	return (int(math.Abs(float64(r.X-otherRect.X)))*2 < (r.W + otherRect.W)) &&
		(int(math.Abs(float64(r.Y-otherRect.Y)))*2 < (r.H + otherRect.H))
}

// Inside check to see if a point inside of this rectangle
func (r *Rect) Inside(p Point) bool {
	return (p.X > r.X) && (p.X < (r.X + r.W)) && (p.Y > r.Y) && (p.Y < (r.Y + r.H))
}
<commit_msg>Added color addition function<commit_after>package eff

import (
	"errors"
	"math"
	"math/rand"

	"strconv"
)

const (
	// Version current semantic version of eff
	Version = "0.1.0"
)

// Point container for 2d points
type Point struct {
	X int
	Y int
}

// Scale returns a new scaled point
func (p *Point) Scale(s float64) Point {
	return Point{
		X: int(float64(p.X) * s),
		Y: int(float64(p.Y) * s),
	}
}

// Offset returns an offset point
func (p *Point) Offset(x int, y int) Point {
	return Point{
		X: p.X + x,
		Y: p.Y + y,
	}
}

// ScalePoints returns a new slice of scaled points
func ScalePoints(points []Point, s float64) []Point {
	var scaledPoints []Point
	for _, p := range points {
		scaledPoints = append(scaledPoints, p.Scale(s))
	}

	return scaledPoints
}

// OffsetPoints returns a new slice of offset points
func OffsetPoints(points []Point, x int, y int) []Point {
	var offsetPoints []Point
	for _, p := range points {
		offsetPoints = append(offsetPoints, p.Offset(x, y))
	}

	return offsetPoints
}

// Color container for argb colors
type Color struct {
	R int
	G int
	B int
	A int
}

// Add offset the rgb values of the color
func (c *Color) Add(v int) {
	c.R += v
	c.G += v
	c.B += v

	c.R = int(math.Min(0xFF, float64(c.R)))
	c.R = int(math.Max(0x00, float64(c.R)))
	c.G = int(math.Min(0xFF, float64(c.G)))
	c.G = int(math.Max(0x00, float64(c.G)))
	c.B = int(math.Min(0xFF, float64(c.B)))
	c.B = int(math.Max(0x00, float64(c.B)))
}

// RandomColor genereate a random color struct.  The opacity is also random
func RandomColor() Color {
	return Color{
		R: rand.Intn(0xFF),
		G: rand.Intn(0xFF),
		B: rand.Intn(0xFF),
		A: 0xFF,
	}
}

// Black returns a color struct that is black
func Black() Color {
	return Color{
		R: 0x00,
		G: 0x00,
		B: 0x00,
		A: 0xFF,
	}
}

// White returns a color struct that is white
func White() Color {
	return Color{
		R: 0xFF,
		G: 0xFF,
		B: 0xFF,
		A: 0xFF,
	}
}

// ColorWithHex creates an eff color w/ a hex string in the formant "#FF00FF"
func ColorWithHex(hex string) (Color, error) {
	if hex[0] == '#' {
		hex = hex[1:]
	}

	if len(hex) < 6 {
		return Color{}, errors.New("Invalid hex color, too short")
	}

	r, err := strconv.ParseInt(hex[:2], 16, 32)
	if err != nil {
		return Color{}, err
	}

	g, err := strconv.ParseInt(hex[2:4], 16, 32)
	if err != nil {
		return Color{}, err
	}

	b, err := strconv.ParseInt(hex[4:6], 16, 32)
	if err != nil {
		return Color{}, err
	}

	return Color{
		R: int(r),
		G: int(g),
		B: int(b),
		A: 0xFF,
	}, nil
}

// Rect container for rectangle
type Rect struct {
	X int
	Y int
	W int
	H int
}

// Scale returns a new scaled Rect
func (r *Rect) Scale(s float64) Rect {
	return Rect{
		X: int(float64(r.X) * s),
		Y: int(float64(r.Y) * s),
		W: int(float64(r.W) * s),
		H: int(float64(r.H) * s),
	}
}

// LocalInside tests to see if rect is inside of this rect, assumes test rect has coordinates local to this rect
func (r *Rect) LocalInside(testRect Rect) bool {
	if testRect.X > r.W {
		return false
	}

	if testRect.Y > r.H {
		return false
	}

	if (testRect.X + testRect.W) < 0 {
		return false
	}

	if (testRect.Y + testRect.H) < 0 {
		return false
	}

	return true
}

// ScaleRects returns a new slice of scaled Rects
func ScaleRects(rects []Rect, s float64) []Rect {
	var scaledRects []Rect
	for _, r := range rects {
		scaledRects = append(scaledRects, r.Scale(s))
	}

	return scaledRects
}

// Font describes a ttf font
type Font interface {
	Path() string
	Size() int
}

// Image describes an image
type Image interface {
	Path() string
	Width() int
	Height() int
}

// Equals test to see if two rectangles occupy the same location exactly
func (r *Rect) Equals(otherRect Rect) bool {
	return (r.X == otherRect.X &&
		r.Y == otherRect.Y &&
		r.W == otherRect.W &&
		r.H == otherRect.H)
}

// Intersects check to see if a rectangle is inside of this rectangle
func (r *Rect) Intersects(otherRect Rect) bool {
	return (int(math.Abs(float64(r.X-otherRect.X)))*2 < (r.W + otherRect.W)) &&
		(int(math.Abs(float64(r.Y-otherRect.Y)))*2 < (r.H + otherRect.H))
}

// Inside check to see if a point inside of this rectangle
func (r *Rect) Inside(p Point) bool {
	return (p.X > r.X) && (p.X < (r.X + r.W)) && (p.Y > r.Y) && (p.Y < (r.Y + r.H))
}
<|endoftext|>