<commit_before>package xmmsclient

// auto-generated

import (
	"bytes"
)

type Broadcast struct {
	result chan reply
}

func (b *Broadcast) Next() (XmmsValue, error) {
	__reply := <- b.result
	if __reply.err != nil {
		return nil, __reply.err
	}
	__buffer := bytes.NewBuffer(__reply.payload)
	return tryDeserialize(__buffer)
}

// This broadcast is triggered when the daemon is shutting down.
func (c *Client) BroadcastMainQuit() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(0)})
	return Broadcast{__chan}
}

// This broadcast is triggered when the playlist changes.
func (c *Client) BroadcastPlaylistChanged() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(1)})
	return Broadcast{__chan}
}

// This broadcast is triggered when the position in the playlist changes.
func (c *Client) BroadcastPlaylistCurrentPos() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(2)})
	return Broadcast{__chan}
}

// This broadcast is triggered when another playlist is loaded.
func (c *Client) BroadcastPlaylistLoaded() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(3)})
	return Broadcast{__chan}
}

// This broadcast is triggered when the value of any config property changes.
func (c *Client) BroadcastConfigValueChanged() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(4)})
	return Broadcast{__chan}
}

// This broadcast is triggered when the playback status changes.
func (c *Client) BroadcastPlaybackStatus() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(5)})
	return Broadcast{__chan}
}

// This broadcast is triggered when the playback volume changes.
func (c *Client) BroadcastPlaybackVolumeChanged() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(6)})
	return Broadcast{__chan}
}

// This broadcast is triggered when the played song's media ID changes.
func (c *Client) BroadcastPlaybackCurrentId() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(7)})
	return Broadcast{__chan}
}

// This broadcast is triggered when an entry is added to the medialib.
func (c *Client) BroadcastMedialibEntryAdded() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(9)})
	return Broadcast{__chan}
}

// This broadcast is triggered when the properties of a medialib entry are changed.
func (c *Client) BroadcastMedialibEntryChanged() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(10)})
	return Broadcast{__chan}
}

// This broadcast is triggered when a medialib entry is removed.
func (c *Client) BroadcastMedialibEntryRemoved() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(11)})
	return Broadcast{__chan}
}

// This broadcast is triggered when a collection is changed.
func (c *Client) BroadcastCollectionChanged() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(12)})
	return Broadcast{__chan}
}

// This broadcast is triggered when the status of the mediainfo reader changes.
func (c *Client) BroadcastMediainfoReaderStatus() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(13)})
	return Broadcast{__chan}
}

// This broadcast carries client-to-client messages.
func (c *Client) BroadcastCourierMessage() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(15)})
	return Broadcast{__chan}
}

// This broadcast is emitted when a client's services are ready.
func (c *Client) BroadcastCourierReady() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(16)})
	return Broadcast{__chan}
}

// This broadcast is emitted when a new client connects.
func (c *Client) BroadcastIpcManagerClientConnected() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(17)})
	return Broadcast{__chan}
}

// This broadcast is emitted when a client disconnects.
func (c *Client) BroadcastIpcManagerClientDisconnected() Broadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(18)})
	return Broadcast{__chan}
}
<commit_msg>Update auto-generated API.<commit_after>package xmmsclient

// auto-generated

import (
	"bytes"
)

type IntBroadcast struct {
	result chan reply
}

type StringBroadcast struct {
	result chan reply
}

type DictBroadcast struct {
	result chan reply
}

func (b *IntBroadcast) Next() (XmmsInt, error) {
	__reply := <- b.result
	if __reply.err != nil {
		return -1, __reply.err
	}
	__buffer := bytes.NewBuffer(__reply.payload)
	__value, __err := tryDeserialize(__buffer)
	if __err != nil {
		return -1, __err
	}
	return __value.(XmmsInt), nil
}

func (b *StringBroadcast) Next() (XmmsString, error) {
	__reply := <- b.result
	if __reply.err != nil {
		return "", __reply.err
	}
	__buffer := bytes.NewBuffer(__reply.payload)
	__value, __err := tryDeserialize(__buffer)
	if __err != nil {
		return "", __err
	}
	return __value.(XmmsString), nil
}

func (b *DictBroadcast) Next() (XmmsDict, error) {
	__reply := <- b.result
	if __reply.err != nil {
		return XmmsDict{}, __reply.err
	}
	__buffer := bytes.NewBuffer(__reply.payload)
	__value, __err := tryDeserialize(__buffer)
	if __err != nil {
		return XmmsDict{}, __err
	}
	return __value.(XmmsDict), nil
}

// This broadcast is triggered when the daemon is shutting down.
func (c *Client) BroadcastMainQuit() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(0)})
	return IntBroadcast{__chan}
}

// This broadcast is triggered when the playlist changes.
func (c *Client) BroadcastPlaylistChanged() DictBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(1)})
	return DictBroadcast{__chan}
}

// This broadcast is triggered when the position in the playlist changes.
func (c *Client) BroadcastPlaylistCurrentPos() DictBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(2)})
	return DictBroadcast{__chan}
}

// This broadcast is triggered when another playlist is loaded.
func (c *Client) BroadcastPlaylistLoaded() StringBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(3)})
	return StringBroadcast{__chan}
}

// This broadcast is triggered when the value of any config property changes.
func (c *Client) BroadcastConfigValueChanged() DictBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(4)})
	return DictBroadcast{__chan}
}

// This broadcast is triggered when the playback status changes.
func (c *Client) BroadcastPlaybackStatus() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(5)})
	return IntBroadcast{__chan}
}

// This broadcast is triggered when the playback volume changes.
func (c *Client) BroadcastPlaybackVolumeChanged() DictBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(6)})
	return DictBroadcast{__chan}
}

// This broadcast is triggered when the played song's media ID changes.
func (c *Client) BroadcastPlaybackCurrentId() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(7)})
	return IntBroadcast{__chan}
}

// This broadcast is triggered when an entry is added to the medialib.
func (c *Client) BroadcastMedialibEntryAdded() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(9)})
	return IntBroadcast{__chan}
}

// This broadcast is triggered when the properties of a medialib entry are changed.
func (c *Client) BroadcastMedialibEntryChanged() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(10)})
	return IntBroadcast{__chan}
}

// This broadcast is triggered when a medialib entry is removed.
func (c *Client) BroadcastMedialibEntryRemoved() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(11)})
	return IntBroadcast{__chan}
}

// This broadcast is triggered when a collection is changed.
func (c *Client) BroadcastCollectionChanged() DictBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(12)})
	return DictBroadcast{__chan}
}

// This broadcast is triggered when the status of the mediainfo reader changes.
func (c *Client) BroadcastMediainfoReaderStatus() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(13)})
	return IntBroadcast{__chan}
}

// This broadcast carries client-to-client messages.
func (c *Client) BroadcastCourierMessage() DictBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(15)})
	return DictBroadcast{__chan}
}

// This broadcast is emitted when a client's services are ready.
func (c *Client) BroadcastCourierReady() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(16)})
	return IntBroadcast{__chan}
}

// This broadcast is emitted when a new client connects.
func (c *Client) BroadcastIpcManagerClientConnected() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(17)})
	return IntBroadcast{__chan}
}

// This broadcast is emitted when a client disconnects.
func (c *Client) BroadcastIpcManagerClientDisconnected() IntBroadcast {
	__chan := c.dispatch(0, 33, XmmsList{XmmsInt(18)})
	return IntBroadcast{__chan}
}
<|endoftext|>


<commit_before>package dispatcher

import (
	"fmt"
	"socialapi/workers/helper"
	"socialapi/workers/realtime/models"
	"time"

	"github.com/koding/logging"
	"github.com/koding/rabbitmq"
	"github.com/streadway/amqp"
)

type Controller struct {
	Broker  *models.Broker
	Pubnub  *models.PubNub
	logger  logging.Logger
	rmqConn *amqp.Connection
}

func NewController(rmqConn *rabbitmq.RabbitMQ, pubnub *models.PubNub, broker *models.Broker) *Controller {

	return &Controller{
		Pubnub:  pubnub,
		Broker:  broker,
		logger:  helper.MustGetLogger(),
		rmqConn: rmqConn.Conn(),
	}
}

// DefaultErrHandler controls the errors, return false if an error occurred
func (c *Controller) DefaultErrHandler(delivery amqp.Delivery, err error) bool {
	c.logger.Error("an error occurred deleting dispatcher event: %s", err)
	delivery.Ack(false)
	return false
}

// UpdateChannel sends channel update events
func (c *Controller) UpdateChannel(pm *models.PushMessage) error {
	if ok := c.isPushMessageValid(pm); !ok {
		return nil
	}

	pm.EventId = createEventId()

	return c.Pubnub.UpdateChannel(pm)
}

func (c *Controller) isPushMessageValid(pm *models.PushMessage) bool {
	if pm.Channel.Id == 0 {
		c.logger.Error("Invalid request: channel id is not set")
		return false
	}

	if pm.EventName == "" {
		c.logger.Error("Invalid request: event name is not set")
		return false
	}

	if pm.Channel.Token == "" {
		c.logger.Error("Invalid request: token is not set")
		return false
	}

	return true
}

// UpdateMessage sends message update events
func (c *Controller) UpdateMessage(um *models.UpdateInstanceMessage) error {
	if um.Token == "" {
		c.logger.Error("Token is not set")
		return nil
	}

	um.EventId = createEventId()

	go func() {
		err := c.Broker.UpdateInstance(um)
		if err != nil {
			c.logger.Error("Could not push update instance message with id %d to broker: %s", um.Message.Id, err)
		}
	}()

	return c.Pubnub.UpdateInstance(um)
}

// NotifyUser sends user notifications to related channel
func (c *Controller) NotifyUser(nm *models.NotificationMessage) error {
	if nm.Account.Nickname == "" {
		c.logger.Error("Nickname is not set")
		return nil
	}

	nm.EventName = "message"
	nm.EventId = createEventId()

	return c.Pubnub.NotifyUser(nm)
}

func (c *Controller) RevokeChannelAccess(rca *models.RevokeChannelAccess) error {
	channel := models.Channel{
		Token: rca.ChannelToken,
	}
	pmc := models.NewPrivateMessageChannel(channel)

	for _, token := range rca.Tokens {
		a := &models.Authenticate{
			Account: &models.Account{Token: token},
		}
		if err := c.Pubnub.RevokeAccess(a, pmc); err != nil {
			return err
		}
	}

	return nil
}

func createEventId() string {
	return fmt.Sprintf("server-%d", time.Now().UnixNano())
}
<commit_msg>workers/cmd: dispatcher path is changed<commit_after><|endoftext|>


<commit_before>package api_test

import (
	"bufio"
	"bytes"
	"encoding/gob"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/http/httputil"

	"github.com/cloudfoundry-incubator/garden/warden"
	wfakes "github.com/cloudfoundry-incubator/garden/warden/fakes"
	"github.com/concourse/turbine/api/hijack"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("POST /builds/:guid/hijack", func() {
	var payload []byte

	var response *http.Response
	var conn net.Conn
	var encoder *gob.Encoder
	var br *bufio.Reader

	BeforeEach(func() {
		var err error

		payload, err = json.Marshal(warden.ProcessSpec{
			Path: "bash",
			Args: []string{"-l"},
		})
		Ω(err).ShouldNot(HaveOccurred())
	})

	JustBeforeEach(func() {
		var err error

		conn, err = net.Dial("tcp", server.Listener.Addr().String())
		Ω(err).ShouldNot(HaveOccurred())

		req, err := http.NewRequest("POST", server.URL+"/builds/some-build-guid/hijack", bytes.NewBuffer(payload))
		Ω(err).ShouldNot(HaveOccurred())

		client := httputil.NewClientConn(conn, nil)

		response, err = client.Do(req)
		Ω(err).ShouldNot(HaveOccurred())

		conn, br = client.Hijack()

		encoder = gob.NewEncoder(conn)
	})

	AfterEach(func() {
		conn.Close()
	})

	Context("when hijacking succeeds", func() {
		var process *wfakes.FakeProcess

		BeforeEach(func() {
			process = new(wfakes.FakeProcess)

			scheduler.HijackReturns(process, nil)
		})

		It("hijacks the build via the scheduler", func() {
			guid, spec, _ := scheduler.HijackArgsForCall(0)
			Ω(guid).Should(Equal("some-build-guid"))
			Ω(spec).Should(Equal(warden.ProcessSpec{
				Path: "bash",
				Args: []string{"-l"},
			}))
		})

		It("waits on the process", func() {
			Eventually(process.WaitCallCount).Should(Equal(1))
		})

		Context("when the process prints stdout and stderr", func() {
			BeforeEach(func() {
				scheduler.HijackStub = func(guid string, spec warden.ProcessSpec, io warden.ProcessIO) (warden.Process, error) {
					Ω(io.Stdout).ShouldNot(BeZero())
					Ω(io.Stderr).ShouldNot(BeZero())

					_, err := fmt.Fprintf(io.Stdout, "hello client out\n")
					Ω(err).ShouldNot(HaveOccurred())

					_, err = fmt.Fprintf(io.Stderr, "hello client err\n")
					Ω(err).ShouldNot(HaveOccurred())

					return new(wfakes.FakeProcess), nil
				}
			})

			It("streams stdout and stderr to the response", func() {
				line, err := br.ReadBytes('\n')
				Ω(err).ShouldNot(HaveOccurred())
				Ω(string(line)).Should(Equal("hello client out\n"))

				line, err = br.ReadBytes('\n')
				Ω(err).ShouldNot(HaveOccurred())
				Ω(string(line)).Should(Equal("hello client err\n"))
			})
		})

		Context("when a stdin payload is received", func() {
			BeforeEach(func() {
				process.WaitStub = func() (int, error) {
					select {}
				}
			})

			It("forwards to the process's stdin", func() {
				err := encoder.Encode(hijack.ProcessPayload{
					Stdin: []byte("some stdin\n"),
				})
				Ω(err).ShouldNot(HaveOccurred())

				_, _, io := scheduler.HijackArgsForCall(0)

				line, err := bufio.NewReader(io.Stdin).ReadBytes('\n')
				Ω(err).ShouldNot(HaveOccurred())
				Ω(string(line)).Should(Equal("some stdin\n"))
			})
		})

		Context("when a window size payload is received", func() {
			BeforeEach(func() {
				process.WaitStub = func() (int, error) {
					select {}
				}
			})

			It("forwards tty spec paylods to the process", func() {
				ttySpec := &warden.TTYSpec{
					WindowSize: &warden.WindowSize{
						Columns: 80,
						Rows:    24,
					},
				}

				err := encoder.Encode(hijack.ProcessPayload{
					TTYSpec: ttySpec,
				})
				Ω(err).ShouldNot(HaveOccurred())

				Eventually(process.SetTTYCallCount).Should(Equal(1))

				Ω(process.SetTTYArgsForCall(0)).Should(Equal(*ttySpec))
			})
		})

		Context("when the connection breaks", func() {
			It("closes the process's stdin", func() {
				conn.Close()

				_, _, io := scheduler.HijackArgsForCall(0)

				_, err := bufio.NewReader(io.Stdin).ReadBytes('\n')
				Ω(err).Should(HaveOccurred())
			})
		})

		Context("when the process exits", func() {
			It("closes the connection", func() {
				_, err := br.ReadBytes('\n')
				Ω(err).Should(HaveOccurred())
			})
		})
	})
})
<commit_msg>fix flaky hijack test<commit_after>package api_test

import (
	"bufio"
	"bytes"
	"encoding/gob"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/http/httputil"

	"github.com/cloudfoundry-incubator/garden/warden"
	wfakes "github.com/cloudfoundry-incubator/garden/warden/fakes"
	"github.com/concourse/turbine/api/hijack"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("POST /builds/:guid/hijack", func() {
	var payload []byte

	var response *http.Response
	var conn net.Conn
	var encoder *gob.Encoder
	var br *bufio.Reader

	BeforeEach(func() {
		var err error

		payload, err = json.Marshal(warden.ProcessSpec{
			Path: "bash",
			Args: []string{"-l"},
		})
		Ω(err).ShouldNot(HaveOccurred())
	})

	JustBeforeEach(func() {
		var err error

		conn, err = net.Dial("tcp", server.Listener.Addr().String())
		Ω(err).ShouldNot(HaveOccurred())

		req, err := http.NewRequest("POST", server.URL+"/builds/some-build-guid/hijack", bytes.NewBuffer(payload))
		Ω(err).ShouldNot(HaveOccurred())

		client := httputil.NewClientConn(conn, nil)

		response, err = client.Do(req)
		Ω(err).ShouldNot(HaveOccurred())

		conn, br = client.Hijack()

		encoder = gob.NewEncoder(conn)
	})

	AfterEach(func() {
		conn.Close()
	})

	Context("when hijacking succeeds", func() {
		var process *wfakes.FakeProcess

		BeforeEach(func() {
			process = new(wfakes.FakeProcess)

			scheduler.HijackReturns(process, nil)
		})

		It("hijacks the build via the scheduler", func() {
			guid, spec, _ := scheduler.HijackArgsForCall(0)
			Ω(guid).Should(Equal("some-build-guid"))
			Ω(spec).Should(Equal(warden.ProcessSpec{
				Path: "bash",
				Args: []string{"-l"},
			}))
		})

		It("waits on the process", func() {
			Eventually(process.WaitCallCount).Should(Equal(1))
		})

		Context("when the process prints stdout and stderr", func() {
			BeforeEach(func() {
				scheduler.HijackStub = func(guid string, spec warden.ProcessSpec, io warden.ProcessIO) (warden.Process, error) {
					Ω(io.Stdout).ShouldNot(BeZero())
					Ω(io.Stderr).ShouldNot(BeZero())

					_, err := fmt.Fprintf(io.Stdout, "hello client out\n")
					Ω(err).ShouldNot(HaveOccurred())

					_, err = fmt.Fprintf(io.Stderr, "hello client err\n")
					Ω(err).ShouldNot(HaveOccurred())

					return new(wfakes.FakeProcess), nil
				}
			})

			It("streams stdout and stderr to the response", func() {
				line, err := br.ReadBytes('\n')
				Ω(err).ShouldNot(HaveOccurred())
				Ω(string(line)).Should(Equal("hello client out\n"))

				line, err = br.ReadBytes('\n')
				Ω(err).ShouldNot(HaveOccurred())
				Ω(string(line)).Should(Equal("hello client err\n"))
			})
		})

		Context("when a stdin payload is received", func() {
			BeforeEach(func() {
				process.WaitStub = func() (int, error) {
					select {}
				}
			})

			It("forwards to the process's stdin", func() {
				err := encoder.Encode(hijack.ProcessPayload{
					Stdin: []byte("some stdin\n"),
				})
				Ω(err).ShouldNot(HaveOccurred())

				Eventually(scheduler.HijackCallCount).Should(Equal(1))

				_, _, io := scheduler.HijackArgsForCall(0)

				line, err := bufio.NewReader(io.Stdin).ReadBytes('\n')
				Ω(err).ShouldNot(HaveOccurred())
				Ω(string(line)).Should(Equal("some stdin\n"))
			})
		})

		Context("when a window size payload is received", func() {
			BeforeEach(func() {
				process.WaitStub = func() (int, error) {
					select {}
				}
			})

			It("forwards tty spec paylods to the process", func() {
				ttySpec := &warden.TTYSpec{
					WindowSize: &warden.WindowSize{
						Columns: 80,
						Rows:    24,
					},
				}

				err := encoder.Encode(hijack.ProcessPayload{
					TTYSpec: ttySpec,
				})
				Ω(err).ShouldNot(HaveOccurred())

				Eventually(process.SetTTYCallCount).Should(Equal(1))

				Ω(process.SetTTYArgsForCall(0)).Should(Equal(*ttySpec))
			})
		})

		Context("when the connection breaks", func() {
			It("closes the process's stdin", func() {
				conn.Close()

				_, _, io := scheduler.HijackArgsForCall(0)

				_, err := bufio.NewReader(io.Stdin).ReadBytes('\n')
				Ω(err).Should(HaveOccurred())
			})
		})

		Context("when the process exits", func() {
			It("closes the connection", func() {
				_, err := br.ReadBytes('\n')
				Ω(err).Should(HaveOccurred())
			})
		})
	})
})
<|endoftext|>


<commit_before>package mailman

import (
	"bytes"
	"fmt"
	"net/mail"
	"strconv"
	"strings"
	"time"

	"github.com/muesli/gomail"
	"github.com/mxk/go-imap/imap"

	"github.com/muesli/polly/api/db"
)

var (
	context *db.PollyContext
)

// SetupMailmanContext sets the context
func SetupMailmanContext(ctx *db.PollyContext) {
	context = ctx
}

func sendMail(tos []string, from, subject, body, mid, contenttype, contenttypetransfer string) {
	m := gomail.NewMessage()
	m.SetHeader("From", from)
	m.SetHeader("Subject", subject)
	m.SetHeader("Message-ID", mid)
	m.SetHeader("Errors-To", context.Config.Connections.Email.Mailman.BounceAddress)
	m.SetHeader("X-BeenThere", context.Config.Connections.Email.Mailman.Address)
	m.SetAddressHeader("To", context.Config.Connections.Email.Mailman.Address, context.Config.Connections.Email.Mailman.Name)
	m.SetAddressHeader("Envelope-Sender", context.Config.Connections.Email.Mailman.BounceAddress, context.Config.Connections.Email.Mailman.Name)
	m.SetAddressHeader("List-Id", context.Config.Connections.Email.Mailman.Address, context.Config.Connections.Email.Mailman.Name)

	if len(contenttype) > 0 {
		m.SetHeader("Content-Type", contenttype)
	}
	if len(contenttypetransfer) > 0 {
		m.SetHeader("Content-Transfer-Encoding", contenttypetransfer)
	}

	m.SetRawBody(body)

	d := gomail.NewDialer(context.Config.Connections.Email.SMTP.Server, context.Config.Connections.Email.SMTP.Port,
		context.Config.Connections.Email.SMTP.User, context.Config.Connections.Email.SMTP.Password)
	s, err := d.Dial()
	if err != nil {
		panic(err)
	}
	defer s.Close()

	err = s.Send(context.Config.Connections.Email.Mailman.Address, tos, m)
	if err != nil {
		panic(err)
	}
}

// RunLoop fetches mail and delivers them to recipients - forever
func RunLoop() {
	var (
		c   *imap.Client
		cmd *imap.Command
		rsp *imap.Response
	)

	// Connect to the server
	c, _ = imap.DialTLS(context.Config.Connections.Email.IMAP.Server+":"+strconv.FormatInt(int64(context.Config.Connections.Email.IMAP.Port), 10), nil)

	// Print server greeting (first response in the unilateral server data queue)
	fmt.Println("IMAP Server says hello:", c.Data[0].Info)
	c.Data = nil

	// Enable encryption, if supported by the server
	if c.Caps["STARTTLS"] {
		c.StartTLS(nil)
	}

	// Authenticate
	if c.State() == imap.Login {
		c.Login(context.Config.Connections.Email.IMAP.User, context.Config.Connections.Email.IMAP.Password)
	}

	// List all top-level mailboxes, wait for the command to finish
	cmd, _ = imap.Wait(c.List("", "%"))
	if cmd == nil {
		return
	}

	// Print mailbox information
	fmt.Println("\nTop-level mailboxes:")
	for _, rsp = range cmd.Data {
		fmt.Println("|--", rsp.MailboxInfo().Name)
	}

	// Check for new unilateral server data responses
	for _, rsp = range c.Data {
		fmt.Println("Server data:", rsp)
	}
	c.Data = nil

	mm, _ := context.GetMailman(context.Config.Connections.Email.Mailman.Address)
	for {
		// Open a mailbox (synchronous command - no need for imap.Wait)
		c.Select("INBOX", true)
		fmt.Printf("Mailbox status: %s (msgs: %d, last-seen: %d)\n", c.Mailbox.Name, c.Mailbox.Messages, mm.LastSeen)

		if mm.LastSeen == 0 {
			mm.LastSeen = uint64(c.Mailbox.Messages)
		}

		// Fetch new mails
		set, _ := imap.NewSeqSet("")
		set.Add(strconv.FormatUint(mm.LastSeen+1, 10) + ":*")
		cmd, _ = c.UIDFetch(set, "RFC822.HEADER", "RFC822.TEXT")

		// Process responses while the command is running
		fmt.Println("\nChecking mailman INBOX")
		for cmd.InProgress() {
			// Wait for the next response (no timeout)
			c.Recv(-1)

			// Process command data
			for _, rsp = range cmd.Data {
				header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
				body := string(imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.TEXT"]))
				if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
					from := msg.Header.Get("From")
					subj := msg.Header.Get("Subject")
					mid := msg.Header.Get("Message-ID")
					contenttype := msg.Header.Get("Content-Type")
					contenttypetrasnfer := msg.Header.Get("Content-Transfer-Encoding")

					fmt.Println("|-- From", from)
					fmt.Println("|-- Subject", subj)
					fmt.Println("|-- ID", mid)

					users, err := context.LoadAllUsers()
					if err != nil {
						panic(err)
					}
					tos := []string{}
					for _, user := range users {
						if !user.Activated {
							continue
						}
						tos = append(tos, user.Email)
					}

					if msg.Header.Get("X-BeenThere") != context.Config.Connections.Email.Mailman.Address && !strings.Contains(body, "X-BeenThere: "+context.Config.Connections.Email.Mailman.Address) {
						if len(tos) > 0 {
							sendMail(tos, from, subj, body, mid, contenttype, contenttypetrasnfer)
						}
					} else {
						fmt.Println("IGNORING MESSAGE!")
					}
					mm.LastSeen = uint64(rsp.MessageInfo().UID)
					mm.Update(context)
				}
			}

			cmd.Data = nil

			// Process unilateral server data
			for _, rsp = range c.Data {
				// fmt.Println("Server data:", rsp)
			}
			c.Data = nil
		}

		// Check command completion status
		if rsp, err := cmd.Result(imap.OK); err != nil {
			if err == imap.ErrAborted {
				fmt.Println("Fetch command aborted")
			} else {
				fmt.Println("Fetch error:", rsp.Info)
				return
			}
		}

		time.Sleep(1 * time.Minute)
	}
}
<commit_msg>Panic when IMAP login failed<commit_after>package mailman

import (
	"bytes"
	"fmt"
	"net/mail"
	"strconv"
	"strings"
	"time"

	"github.com/muesli/gomail"
	"github.com/mxk/go-imap/imap"

	"github.com/muesli/polly/api/db"
)

var (
	context *db.PollyContext
)

// SetupMailmanContext sets the context
func SetupMailmanContext(ctx *db.PollyContext) {
	context = ctx
}

func sendMail(tos []string, from, subject, body, mid, contenttype, contenttypetransfer string) {
	m := gomail.NewMessage()
	m.SetHeader("From", from)
	m.SetHeader("Subject", subject)
	m.SetHeader("Message-ID", mid)
	m.SetHeader("Errors-To", context.Config.Connections.Email.Mailman.BounceAddress)
	m.SetHeader("X-BeenThere", context.Config.Connections.Email.Mailman.Address)
	m.SetAddressHeader("To", context.Config.Connections.Email.Mailman.Address, context.Config.Connections.Email.Mailman.Name)
	m.SetAddressHeader("Envelope-Sender", context.Config.Connections.Email.Mailman.BounceAddress, context.Config.Connections.Email.Mailman.Name)
	m.SetAddressHeader("List-Id", context.Config.Connections.Email.Mailman.Address, context.Config.Connections.Email.Mailman.Name)

	if len(contenttype) > 0 {
		m.SetHeader("Content-Type", contenttype)
	}
	if len(contenttypetransfer) > 0 {
		m.SetHeader("Content-Transfer-Encoding", contenttypetransfer)
	}

	m.SetRawBody(body)

	d := gomail.NewDialer(context.Config.Connections.Email.SMTP.Server, context.Config.Connections.Email.SMTP.Port,
		context.Config.Connections.Email.SMTP.User, context.Config.Connections.Email.SMTP.Password)
	s, err := d.Dial()
	if err != nil {
		panic(err)
	}
	defer s.Close()

	err = s.Send(context.Config.Connections.Email.Mailman.Address, tos, m)
	if err != nil {
		panic(err)
	}
}

// RunLoop fetches mail and delivers them to recipients - forever
func RunLoop() {
	var (
		c   *imap.Client
		cmd *imap.Command
		rsp *imap.Response
		err error
	)

	// Connect to the server
	c, err = imap.DialTLS(context.Config.Connections.Email.IMAP.Server+":"+strconv.FormatInt(int64(context.Config.Connections.Email.IMAP.Port), 10), nil)
	if err != nil || c == nil || c.Data == nil {
		panic(err)
	}

	// Print server greeting (first response in the unilateral server data queue)
	fmt.Println("IMAP Server says hello:", c.Data[0].Info)
	c.Data = nil

	// Enable encryption, if supported by the server
	if c.Caps["STARTTLS"] {
		c.StartTLS(nil)
	}

	// Authenticate
	if c.State() == imap.Login {
		c.Login(context.Config.Connections.Email.IMAP.User, context.Config.Connections.Email.IMAP.Password)
	}

	// List all top-level mailboxes, wait for the command to finish
	cmd, _ = imap.Wait(c.List("", "%"))
	if cmd == nil {
		return
	}

	// Print mailbox information
	fmt.Println("\nTop-level mailboxes:")
	for _, rsp = range cmd.Data {
		fmt.Println("|--", rsp.MailboxInfo().Name)
	}

	// Check for new unilateral server data responses
	for _, rsp = range c.Data {
		fmt.Println("Server data:", rsp)
	}
	c.Data = nil

	mm, _ := context.GetMailman(context.Config.Connections.Email.Mailman.Address)
	for {
		// Open a mailbox (synchronous command - no need for imap.Wait)
		c.Select("INBOX", true)
		fmt.Printf("Mailbox status: %s (msgs: %d, last-seen: %d)\n", c.Mailbox.Name, c.Mailbox.Messages, mm.LastSeen)

		if mm.LastSeen == 0 {
			mm.LastSeen = uint64(c.Mailbox.Messages)
		}

		// Fetch new mails
		set, _ := imap.NewSeqSet("")
		set.Add(strconv.FormatUint(mm.LastSeen+1, 10) + ":*")
		cmd, _ = c.UIDFetch(set, "RFC822.HEADER", "RFC822.TEXT")

		// Process responses while the command is running
		fmt.Println("\nChecking mailman INBOX")
		for cmd.InProgress() {
			// Wait for the next response (no timeout)
			c.Recv(-1)

			// Process command data
			for _, rsp = range cmd.Data {
				header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
				body := string(imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.TEXT"]))
				if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
					from := msg.Header.Get("From")
					subj := msg.Header.Get("Subject")
					mid := msg.Header.Get("Message-ID")
					contenttype := msg.Header.Get("Content-Type")
					contenttypetrasnfer := msg.Header.Get("Content-Transfer-Encoding")

					fmt.Println("|-- From", from)
					fmt.Println("|-- Subject", subj)
					fmt.Println("|-- ID", mid)

					users, err := context.LoadAllUsers()
					if err != nil {
						panic(err)
					}
					tos := []string{}
					for _, user := range users {
						if !user.Activated {
							continue
						}
						tos = append(tos, user.Email)
					}

					if msg.Header.Get("X-BeenThere") != context.Config.Connections.Email.Mailman.Address && !strings.Contains(body, "X-BeenThere: "+context.Config.Connections.Email.Mailman.Address) {
						if len(tos) > 0 {
							sendMail(tos, from, subj, body, mid, contenttype, contenttypetrasnfer)
						}
					} else {
						fmt.Println("IGNORING MESSAGE!")
					}
					mm.LastSeen = uint64(rsp.MessageInfo().UID)
					mm.Update(context)
				}
			}

			cmd.Data = nil

			// Process unilateral server data
			for _, rsp = range c.Data {
				// fmt.Println("Server data:", rsp)
			}
			c.Data = nil
		}

		// Check command completion status
		if rsp, err := cmd.Result(imap.OK); err != nil {
			if err == imap.ErrAborted {
				fmt.Println("Fetch command aborted")
			} else {
				fmt.Println("Fetch error:", rsp.Info)
				return
			}
		}

		time.Sleep(1 * time.Minute)
	}
}
<|endoftext|>


<commit_before>package topic

import (
	"fmt"
	"github.com/appcelerator/amp/data/storage"
	"github.com/docker/docker/pkg/stringid"
	"github.com/golang/protobuf/proto"
	"github.com/nats-io/go-nats-streaming"
	"golang.org/x/net/context"
	"path"
	"strings"
)

const (
	topicsRootKey = "topics"
)

// Server is used to implement topic.TopicServer
type Server struct {
	Store storage.Interface
	Nats  stan.Conn
}

// Create implements topic.TopicServer
func (s *Server) Create(ctx context.Context, in *CreateRequest) (*CreateReply, error) {
	reply, err := s.List(ctx, &ListRequest{})
	if err != nil {
		return nil, err
	}
	for _, topic := range reply.Topics {
		if strings.EqualFold(topic.Name, in.Topic.Name) {
			return nil, fmt.Errorf("Topic already exists: %s", in.Topic.Name)
		}
	}
	topic := &TopicEntry{
		Id:   stringid.GenerateNonCryptoID(),
		Name: in.Topic.Name,
	}
	if err := s.Store.Create(ctx, path.Join(topicsRootKey, topic.Id), topic, nil, 0); err != nil {
		return nil, err
	}
	return &CreateReply{Topic: topic}, nil
}

// List implements topic.TopicServer
func (s *Server) List(ctx context.Context, in *ListRequest) (*ListReply, error) {
	var topics []proto.Message
	if err := s.Store.List(ctx, topicsRootKey, storage.Everything, &TopicEntry{}, &topics); err != nil {
		return nil, err
	}
	reply := &ListReply{}
	for _, topic := range topics {
		reply.Topics = append(reply.Topics, topic.(*TopicEntry))
	}
	return reply, nil
}

// Delete implements topic.TopicServer
func (s *Server) Delete(ctx context.Context, in *DeleteRequest) (*DeleteReply, error) {
	topic := &TopicEntry{}
	if err := s.Store.Get(ctx, path.Join(topicsRootKey, in.Id), topic, false); err != nil {
		return nil, fmt.Errorf("Topic not found: %s", in.Id)
	}

	if err := s.Store.Delete(ctx, path.Join(topicsRootKey, in.Id), false, nil); err != nil {
		return nil, err
	}

	return &DeleteReply{Topic: topic}, nil
}
<commit_msg>issue-572 (#584)<commit_after>package topic

import (
	"github.com/appcelerator/amp/data/storage"
	"github.com/docker/docker/pkg/stringid"
	"github.com/golang/protobuf/proto"
	"github.com/nats-io/go-nats-streaming"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"path"
	"strings"
)

const (
	topicsRootKey = "topics"
)

// Server is used to implement topic.TopicServer
type Server struct {
	Store storage.Interface
	Nats  stan.Conn
}

// Create implements topic.TopicServer
func (s *Server) Create(ctx context.Context, in *CreateRequest) (*CreateReply, error) {
	reply, err := s.List(ctx, &ListRequest{})
	if err != nil {
		return nil, err
	}
	for _, topic := range reply.Topics {
		if strings.EqualFold(topic.Name, in.Topic.Name) {
			return nil, grpc.Errorf(codes.AlreadyExists, "Topic already exists: %s", in.Topic.Name)
		}
	}
	topic := &TopicEntry{
		Id:   stringid.GenerateNonCryptoID(),
		Name: in.Topic.Name,
	}
	if err := s.Store.Create(ctx, path.Join(topicsRootKey, topic.Id), topic, nil, 0); err != nil {
		return nil, grpc.Errorf(codes.Internal, "%v", err)
	}
	return &CreateReply{Topic: topic}, nil
}

// List implements topic.TopicServer
func (s *Server) List(ctx context.Context, in *ListRequest) (*ListReply, error) {
	var topics []proto.Message
	if err := s.Store.List(ctx, topicsRootKey, storage.Everything, &TopicEntry{}, &topics); err != nil {
		return nil, grpc.Errorf(codes.Internal, "%v", err)
	}
	reply := &ListReply{}
	for _, topic := range topics {
		reply.Topics = append(reply.Topics, topic.(*TopicEntry))
	}
	return reply, nil
}

// Delete implements topic.TopicServer
func (s *Server) Delete(ctx context.Context, in *DeleteRequest) (*DeleteReply, error) {
	topic := &TopicEntry{}
	if err := s.Store.Get(ctx, path.Join(topicsRootKey, in.Id), topic, false); err != nil {
		return nil, grpc.Errorf(codes.NotFound, "Topic not found: %s", in.Id)
	}

	if err := s.Store.Delete(ctx, path.Join(topicsRootKey, in.Id), false, nil); err != nil {
		return nil, grpc.Errorf(codes.Internal, "%v", err)
	}

	return &DeleteReply{Topic: topic}, nil
}
<|endoftext|>


<commit_before>package version

// Version of Functions
var Version = "0.3.738"
<commit_msg>fnserver: v0.3.739 release [skip ci]<commit_after>package version

// Version of Functions
var Version = "0.3.739"
<|endoftext|>


<commit_before>package version

// Version of Functions
var Version = "0.3.425"
<commit_msg>fnserver: 0.3.426 release [skip ci]<commit_after>package version

// Version of Functions
var Version = "0.3.426"
<|endoftext|>


<commit_before>package version

// Version of Functions
var Version = "0.3.713"
<commit_msg>fnserver: v0.3.714 release [skip ci]<commit_after>package version

// Version of Functions
var Version = "0.3.714"
<|endoftext|>


<commit_before>package version

// Version of Functions
var Version = "0.3.715"
<commit_msg>fnserver: v0.3.716 release [skip ci]<commit_after>package version

// Version of Functions
var Version = "0.3.716"
<|endoftext|>


<commit_before>// Package errors exposes utils to deal with domain errors.
package errors

import "fmt"

// DomainError represents an error thrown by the domain.
type DomainError struct {
	Code    string  `json:"code"`
	Message string  `json:"message"`
	Errors  []error `json:"errors"`
}

func (err DomainError) Error() string {
	msg := fmt.Sprintf("%s - %s", err.Code, err.Message)

	for _, e := range err.Errors {
		msg = msg + "\n\t" + e.Error()
	}

	return msg
}

// NewDomainError instantiates a new domain error with given inner errors.
func NewDomainError(code string, message string, errors ...error) error {
	return &DomainError{
		Code:    code,
		Message: message,
		Errors:  errors,
	}
}
<commit_msg>Added omitempty to Errors array<commit_after>// Package errors exposes utils to deal with domain errors.
package errors

import "fmt"

// DomainError represents an error thrown by the domain.
type DomainError struct {
	Code    string  `json:"code"`
	Message string  `json:"message"`
	Errors  []error `json:"errors,omitempty"`
}

func (err DomainError) Error() string {
	msg := fmt.Sprintf("%s - %s", err.Code, err.Message)

	for _, e := range err.Errors {
		msg = msg + "\n\t" + e.Error()
	}

	return msg
}

// NewDomainError instantiates a new domain error with given inner errors.
func NewDomainError(code string, message string, errors ...error) error {
	return &DomainError{
		Code:    code,
		Message: message,
		Errors:  errors,
	}
}
<|endoftext|>


<commit_before>package otto

type _reference interface {
	GetBase() *_object
	GetValue() Value
	PutValue(Value) bool
	Name() string
	Strict() bool
	Delete()
}

type _reference_ struct {
    name string
	strict bool
}

func (self _reference_) GetBase() *_object {
	return nil
}

func (self _reference_) Name() string {
	return self.name
}

func (self _reference_) Strict() bool {
	return self.strict
}

func (self _reference_) Delete() {
	// TODO Does nothing, for now?
}

type _argumentReference struct {
	_reference_
    Base *_object
}

func newArgumentReference(base *_object, name string, strict bool) *_argumentReference {
	if base == nil {
		panic(hereBeDragons())
	}
	return &_argumentReference{
		Base: base,
		_reference_: _reference_{
			name: name,
			strict: strict,
		},
	}
}

func (self *_argumentReference) GetBase() *_object {
	return self.Base
}

func (self *_argumentReference) GetValue() Value {
	return self.Base.get(self.name)
}

func (self *_argumentReference) PutValue(value Value) bool {
	self.Base.set(self.name, value, self._reference_.strict)
	return true
}

type _objectReference struct {
	_reference_
    Base *_object
	node _node
}

func newObjectReference(base *_object, name string, strict bool, node _node) *_objectReference {
	return &_objectReference{
		Base: base,
		_reference_: _reference_{
			name: name,
			strict: strict,
		},
		node: node,
	}
}

func (self *_objectReference) GetBase() *_object {
	return self.Base
}

func (self *_objectReference) GetValue() Value {
	if self.Base == nil {
		panic(newReferenceError("notDefined", self.name, self.node))
	}
	return self.Base.get(self.name)
}

func (self *_objectReference) PutValue(value Value) bool {
	if self.Base == nil {
		return false
	}
	self.Base.set(self.name, value, self.Strict())
	return true
}

func (self *_objectReference) Delete() {
	if self.Base == nil {
		return
	}
	self.Base.delete(self.name, self.Strict())
}

type _primitiveReference struct {
	_reference_
    Base Value
	toObject func(Value) *_object
	baseObject *_object
}

func newPrimitiveReference(base Value, toObject func(Value) *_object, name string, strict bool) *_primitiveReference {
	return &_primitiveReference{
		Base: base,
		toObject: toObject,
		_reference_: _reference_{
			name: name,
			strict: strict,
		},
	}
}

func (self *_primitiveReference) baseAsObject() *_object {
	if self.baseObject == nil {
		self.baseObject = self.toObject(self.Base)
	}
	return self.baseObject
}

func (self *_primitiveReference) GetValue() Value {
	return self.baseAsObject().get(self.name)
}

func (self *_primitiveReference) PutValue(value Value) bool {
	self.baseAsObject().set(self.name, value, self.Strict())
	return true
}

<commit_msg>Take out (unused?) _primitiveReference<commit_after>package otto

type _reference interface {
	GetBase() *_object
	GetValue() Value
	PutValue(Value) bool
	Name() string
	Strict() bool
	Delete()
}

type _reference_ struct {
    name string
	strict bool
}

func (self _reference_) GetBase() *_object {
	return nil
}

func (self _reference_) Name() string {
	return self.name
}

func (self _reference_) Strict() bool {
	return self.strict
}

func (self _reference_) Delete() {
	panic("Here be dragons.")
}

type _argumentReference struct {
	_reference_
    Base *_object
}

func newArgumentReference(base *_object, name string, strict bool) *_argumentReference {
	if base == nil {
		panic(hereBeDragons())
	}
	return &_argumentReference{
		Base: base,
		_reference_: _reference_{
			name: name,
			strict: strict,
		},
	}
}

func (self *_argumentReference) GetBase() *_object {
	return self.Base
}

func (self *_argumentReference) GetValue() Value {
	return self.Base.get(self.name)
}

func (self *_argumentReference) PutValue(value Value) bool {
	self.Base.set(self.name, value, self._reference_.strict)
	return true
}

type _objectReference struct {
	_reference_
    Base *_object
	node _node
}

func newObjectReference(base *_object, name string, strict bool, node _node) *_objectReference {
	return &_objectReference{
		Base: base,
		_reference_: _reference_{
			name: name,
			strict: strict,
		},
		node: node,
	}
}

func (self *_objectReference) GetBase() *_object {
	return self.Base
}

func (self *_objectReference) GetValue() Value {
	if self.Base == nil {
		panic(newReferenceError("notDefined", self.name, self.node))
	}
	return self.Base.get(self.name)
}

func (self *_objectReference) PutValue(value Value) bool {
	if self.Base == nil {
		return false
	}
	self.Base.set(self.name, value, self.Strict())
	return true
}

func (self *_objectReference) Delete() {
	if self.Base == nil {
		return
	}
	self.Base.delete(self.name, self.Strict())
}
<|endoftext|>


<commit_before>package types

// currency.go defines the internal currency object. One design goal of the
// currency type is immutability: the currency type should be safe to pass
// directly to other objects and packages. The currency object should never
// have a negative value. The currency should never overflow. There is a
// maximum size value that can be encoded (around 10^10^20), however exceeding
// this value will not result in overflow.

import (
	"errors"
	"math"
	"math/big"

	"github.com/NebulousLabs/Sia/build"
)

type (
	// A Currency represents a number of siacoins or siafunds. Internally, a
	// Currency value is unbounded; however, Currency values sent over the wire
	// protocol are subject to a maximum size of 255 bytes (approximately 10^614).
	// Unlike the math/big library, whose methods modify their receiver, all
	// arithmetic Currency methods return a new value. Currency cannot be negative.
	Currency struct {
		i big.Int
	}
)

var (
	// ErrNegativeCurrency is the error that is returned if performing an
	// operation results in a negative currency.
	ErrNegativeCurrency = errors.New("negative currency not allowed")

	// ErrUint64Overflow is the error that is returned if converting to a
	// unit64 would cause an overflow.
	ErrUint64Overflow = errors.New("cannot return the uint64 of this currency - result is an overflow")

	// ZeroCurrency defines a currency of value zero.
	ZeroCurrency = NewCurrency64(0)
)

// NewCurrency creates a Currency value from a big.Int. Undefined behavior
// occurs if a negative input is used.
func NewCurrency(b *big.Int) (c Currency) {
	if b.Sign() < 0 {
		build.Critical(ErrNegativeCurrency)
	} else {
		c.i = *b
	}
	return
}

// NewCurrency64 creates a Currency value from a uint64.
func NewCurrency64(x uint64) (c Currency) {
	c.i.SetUint64(x)
	return
}

// Add returns a new Currency value c = x + y
func (x Currency) Add(y Currency) (c Currency) {
	c.i.Add(&x.i, &y.i)
	return
}

// Big returns the value of c as a *big.Int. Importantly, it does not provide
// access to the c's internal big.Int object, only a copy.
func (c Currency) Big() *big.Int {
	return new(big.Int).Set(&c.i)
}

// Cmp compares two Currency values. The return value follows the convention
// of math/big.
func (x Currency) Cmp(y Currency) int {
	return x.i.Cmp(&y.i)
}

// Cmp64 compares x to a uint64. The return value follows the convention of
// math/big.
func (x Currency) Cmp64(y uint64) int {
	return x.Cmp(NewCurrency64(y))
}

// Div returns a new Currency value c = x / y.
func (x Currency) Div(y Currency) (c Currency) {
	c.i.Div(&x.i, &y.i)
	return
}

// Div64 returns a new Currency value c = x / y.
func (x Currency) Div64(y uint64) (c Currency) {
	c.i.Div(&x.i, new(big.Int).SetUint64(y))
	return
}

// Equals returns true if x and y have the same value.
func (x Currency) Equals(y Currency) bool {
	return x.Cmp(y) == 0
}

// Equals64 returns true if x and y have the same value.
func (x Currency) Equals64(y uint64) bool {
	return x.Cmp64(y) == 0
}

// Mul returns a new Currency value c = x * y.
func (x Currency) Mul(y Currency) (c Currency) {
	c.i.Mul(&x.i, &y.i)
	return
}

// Mul64 returns a new Currency value c = x * y.
func (x Currency) Mul64(y uint64) (c Currency) {
	c.i.Mul(&x.i, new(big.Int).SetUint64(y))
	return
}

// COMPATv0.4.0 - until the first 10e3 blocks have been archived, MulFloat is
// needed while verifying the first set of blocks.
//
// MulFloat returns a new Currency value y = c * x, where x is a float64.
// Behavior is undefined when x is negative.
func (x Currency) MulFloat(y float64) (c Currency) {
	if y < 0 {
		build.Critical(ErrNegativeCurrency)
	} else {
		cRat := new(big.Rat).Mul(
			new(big.Rat).SetInt(&x.i),
			new(big.Rat).SetFloat64(y),
		)
		c.i.Div(cRat.Num(), cRat.Denom())
	}
	return
}

// MulRat returns a new Currency value c = x * y, where y is a big.Rat.
func (x Currency) MulRat(y *big.Rat) (c Currency) {
	if y.Sign() < 0 {
		build.Critical(ErrNegativeCurrency)
	} else {
		c.i.Mul(&x.i, y.Num())
		c.i.Div(&c.i, y.Denom())
	}
	return
}

// MulTax returns a new Currency value c = x * 0.039, where 0.039 is a big.Rat.
func (x Currency) MulTax() (c Currency) {
	c.i.Mul(&x.i, big.NewInt(39))
	c.i.Div(&c.i, big.NewInt(1000))
	return c
}

// RoundDown returns the largest multiple of y <= x.
func (x Currency) RoundDown(y Currency) (c Currency) {
	diff := new(big.Int).Mod(&x.i, &y.i)
	c.i.Sub(&x.i, diff)
	return
}

// IsZero returns true if the value is 0, false otherwise.
func (c Currency) IsZero() bool {
	return c.i.Sign() <= 0
}

// Sqrt returns a new Currency value y = sqrt(c). Result is rounded down to the
// nearest integer.
func (x Currency) Sqrt() (c Currency) {
	f, _ := new(big.Rat).SetInt(&x.i).Float64()
	sqrt := new(big.Rat).SetFloat64(math.Sqrt(f))
	c.i.Div(sqrt.Num(), sqrt.Denom())
	return
}

// Sub returns a new Currency value c = x - y. Behavior is undefined when
// x < y.
func (x Currency) Sub(y Currency) (c Currency) {
	if x.Cmp(y) < 0 {
		c = x
		build.Critical(ErrNegativeCurrency)
	} else {
		c.i.Sub(&x.i, &y.i)
	}
	return
}

// Uint64 converts a Currency to a uint64. An error is returned because this
// function is sometimes called on values that can be determined by users -
// rather than have all user-facing points do input checking, the input
// checking should happen at the base type. This minimizes the chances of a
// rogue user causing a build.Critical to be triggered.
func (c Currency) Uint64() (u uint64, err error) {
	if c.Cmp(NewCurrency64(math.MaxUint64)) > 0 {
		return 0, ErrUint64Overflow
	}
	return c.Big().Uint64(), nil
}
<commit_msg>Sub underflow results in ZeroCurrency instead of noop<commit_after>package types

// currency.go defines the internal currency object. One design goal of the
// currency type is immutability: the currency type should be safe to pass
// directly to other objects and packages. The currency object should never
// have a negative value. The currency should never overflow. There is a
// maximum size value that can be encoded (around 10^10^20), however exceeding
// this value will not result in overflow.

import (
	"errors"
	"math"
	"math/big"

	"github.com/NebulousLabs/Sia/build"
)

type (
	// A Currency represents a number of siacoins or siafunds. Internally, a
	// Currency value is unbounded; however, Currency values sent over the wire
	// protocol are subject to a maximum size of 255 bytes (approximately 10^614).
	// Unlike the math/big library, whose methods modify their receiver, all
	// arithmetic Currency methods return a new value. Currency cannot be negative.
	Currency struct {
		i big.Int
	}
)

var (
	// ErrNegativeCurrency is the error that is returned if performing an
	// operation results in a negative currency.
	ErrNegativeCurrency = errors.New("negative currency not allowed")

	// ErrUint64Overflow is the error that is returned if converting to a
	// unit64 would cause an overflow.
	ErrUint64Overflow = errors.New("cannot return the uint64 of this currency - result is an overflow")

	// ZeroCurrency defines a currency of value zero.
	ZeroCurrency = NewCurrency64(0)
)

// NewCurrency creates a Currency value from a big.Int. Undefined behavior
// occurs if a negative input is used.
func NewCurrency(b *big.Int) (c Currency) {
	if b.Sign() < 0 {
		build.Critical(ErrNegativeCurrency)
	} else {
		c.i = *b
	}
	return
}

// NewCurrency64 creates a Currency value from a uint64.
func NewCurrency64(x uint64) (c Currency) {
	c.i.SetUint64(x)
	return
}

// Add returns a new Currency value c = x + y
func (x Currency) Add(y Currency) (c Currency) {
	c.i.Add(&x.i, &y.i)
	return
}

// Big returns the value of c as a *big.Int. Importantly, it does not provide
// access to the c's internal big.Int object, only a copy.
func (c Currency) Big() *big.Int {
	return new(big.Int).Set(&c.i)
}

// Cmp compares two Currency values. The return value follows the convention
// of math/big.
func (x Currency) Cmp(y Currency) int {
	return x.i.Cmp(&y.i)
}

// Cmp64 compares x to a uint64. The return value follows the convention of
// math/big.
func (x Currency) Cmp64(y uint64) int {
	return x.Cmp(NewCurrency64(y))
}

// Div returns a new Currency value c = x / y.
func (x Currency) Div(y Currency) (c Currency) {
	c.i.Div(&x.i, &y.i)
	return
}

// Div64 returns a new Currency value c = x / y.
func (x Currency) Div64(y uint64) (c Currency) {
	c.i.Div(&x.i, new(big.Int).SetUint64(y))
	return
}

// Equals returns true if x and y have the same value.
func (x Currency) Equals(y Currency) bool {
	return x.Cmp(y) == 0
}

// Equals64 returns true if x and y have the same value.
func (x Currency) Equals64(y uint64) bool {
	return x.Cmp64(y) == 0
}

// Mul returns a new Currency value c = x * y.
func (x Currency) Mul(y Currency) (c Currency) {
	c.i.Mul(&x.i, &y.i)
	return
}

// Mul64 returns a new Currency value c = x * y.
func (x Currency) Mul64(y uint64) (c Currency) {
	c.i.Mul(&x.i, new(big.Int).SetUint64(y))
	return
}

// COMPATv0.4.0 - until the first 10e3 blocks have been archived, MulFloat is
// needed while verifying the first set of blocks.
//
// MulFloat returns a new Currency value y = c * x, where x is a float64.
// Behavior is undefined when x is negative.
func (x Currency) MulFloat(y float64) (c Currency) {
	if y < 0 {
		build.Critical(ErrNegativeCurrency)
	} else {
		cRat := new(big.Rat).Mul(
			new(big.Rat).SetInt(&x.i),
			new(big.Rat).SetFloat64(y),
		)
		c.i.Div(cRat.Num(), cRat.Denom())
	}
	return
}

// MulRat returns a new Currency value c = x * y, where y is a big.Rat.
func (x Currency) MulRat(y *big.Rat) (c Currency) {
	if y.Sign() < 0 {
		build.Critical(ErrNegativeCurrency)
	} else {
		c.i.Mul(&x.i, y.Num())
		c.i.Div(&c.i, y.Denom())
	}
	return
}

// MulTax returns a new Currency value c = x * 0.039, where 0.039 is a big.Rat.
func (x Currency) MulTax() (c Currency) {
	c.i.Mul(&x.i, big.NewInt(39))
	c.i.Div(&c.i, big.NewInt(1000))
	return c
}

// RoundDown returns the largest multiple of y <= x.
func (x Currency) RoundDown(y Currency) (c Currency) {
	diff := new(big.Int).Mod(&x.i, &y.i)
	c.i.Sub(&x.i, diff)
	return
}

// IsZero returns true if the value is 0, false otherwise.
func (c Currency) IsZero() bool {
	return c.i.Sign() <= 0
}

// Sqrt returns a new Currency value y = sqrt(c). Result is rounded down to the
// nearest integer.
func (x Currency) Sqrt() (c Currency) {
	f, _ := new(big.Rat).SetInt(&x.i).Float64()
	sqrt := new(big.Rat).SetFloat64(math.Sqrt(f))
	c.i.Div(sqrt.Num(), sqrt.Denom())
	return
}

// Sub returns a new Currency value c = x - y. Behavior is undefined when
// x < y.
func (x Currency) Sub(y Currency) (c Currency) {
	if x.Cmp(y) < 0 {
		c = ZeroCurrency
		build.Critical(ErrNegativeCurrency)
	} else {
		c.i.Sub(&x.i, &y.i)
	}
	return
}

// Uint64 converts a Currency to a uint64. An error is returned because this
// function is sometimes called on values that can be determined by users -
// rather than have all user-facing points do input checking, the input
// checking should happen at the base type. This minimizes the chances of a
// rogue user causing a build.Critical to be triggered.
func (c Currency) Uint64() (u uint64, err error) {
	if c.Cmp(NewCurrency64(math.MaxUint64)) > 0 {
		return 0, ErrUint64Overflow
	}
	return c.Big().Uint64(), nil
}
<|endoftext|>


<commit_before>package types

import "time"

// A JourneyQualification qualifies a Journey, see const declaration.
type JourneyQualification string

// JourneySomething qualify journeys
const (
	JourneyBest          JourneyQualification = "best"
	JourneyRapid                              = "rapid"
	JourneyComfort                            = "comfort"
	JourneyCar                                = "car"
	JourneyLessWalk                           = "less_fallback_walk"
	JourneyLessBike                           = "less_fallback_bike"
	JourneyLessBikeShare                      = "less_fallback_bss"
	JourneyFastest                            = "fastest"
	JourneyNoPTWalk                           = "non_pt_walk"
	JourneyNoPTBike                           = "non_pt_bike"
	JourneyNoPTBikeShare                      = "non_pt_bss"
)

// JourneyQualifications is a user-friendly map of all journey qualification
var JourneyQualifications = map[string]JourneyQualification{
	"Best":                                   JourneyBest,
	"Rapid":                                  JourneyRapid,
	"Comfort":                                JourneyComfort,
	"Car":                                    JourneyCar,
	"Less walking":                           JourneyLessWalk,
	"Less biking":                            JourneyLessBike,
	"Less bike sharing":                      JourneyLessBikeShare,
	"Fastest":                                JourneyFastest,
	"No public transit, prefer walking":      JourneyNoPTWalk,
	"No public transit, prefer biking":       JourneyNoPTBike,
	"No public transit, prefer bike-sharing": JourneyNoPTBikeShare,
}

// DateTimeFormat is the format used by the Navitia Api for use with time pkg.
// Few external use-cases but still there are some
const DateTimeFormat string = "20060102150405" // YYYYMMDDThhmmss

// A Journey holds information about a possible journey
type Journey struct {
	Duration  time.Duration `json:"duration"`
	Transfers uint          `json:"nb_transfers"`

	Departure time.Time `json:"departure_date_time"`
	Requested time.Time `json:"requested_date_time"`
	Arrival   time.Time `json:"arrival_date_time"`

	Sections []Section `json:"sections"`

	From Place `json:"from"`
	To   Place `json:"to"`

	Type JourneyQualification `json:"type"`

	Fare Fare `json:"fare"`

	//Status from the whole journey taking into acount the most disturbing information retrieved on every object used
	Status JourneyStatus
}

// JourneyStatus codes for known journey status information
// For example, reduced service, detours or moved stops.
type JourneyStatus string

// JourneyStatusXXX are known JourneyStatuse
const (
	JourneyStatusNoService         JourneyStatus = "NO_SERVICE"
	JourneyStatusReducedService                  = "REDUCED_SERVICE"
	JourneyStatusSignificantDelay                = "SIGNIFICANT_DELAY"
	JourneyStatusDetour                          = "DETOUR"
	JourneyStatusAdditionalService               = "ADDITIONAL_SERVICE"
	JourneyStatusModifiedService                 = "MODIFIED_SERVICE"
	JourneyStatusOtherEffect                     = "OTHER_EFFECT"
	JourneyStatusUnknownEffect                   = "UNKNOWN_EFFECT"
	JourneyStatusStopMoved                       = "STOP_MOVED"
)

// Fare is the fare of some thing
type Fare struct {
	Total Cost `json:"total"`
	Found bool `json:"found"`
}

// Cost is the cost of something
// I know value should NOT be float, but that's what the api gives us
type Cost struct {
	Value    float64 `json:"value"`
	Currency string  `json:"currency"`
}

// TravelerType is a Traveler's type
// Defines speeds & accessibility values for different types of people
type TravelerType string

// The defined types of the api
const (
	// A standard Traveler
	TravelerStandard TravelerType = "standard"

	// A slow walker
	TravelerSlowWalker = "slow_walker"

	// A fast walker
	TravelerFastWalker = "fast_walker"

	// A Traveler with luggage
	TravelerWithLuggage = "luggage"

	// A Traveler in a wheelchair
	TravelerInWheelchair = "wheelchair"
)
<commit_msg>Refactor Fare: eliminate cost type, use x/text/currency instead<commit_after>package types

import (
	"golang.org/x/text/currency"
	"time"
)

// A JourneyQualification qualifies a Journey, see const declaration.
type JourneyQualification string

// JourneySomething qualify journeys
const (
	JourneyBest          JourneyQualification = "best"
	JourneyRapid                              = "rapid"
	JourneyComfort                            = "comfort"
	JourneyCar                                = "car"
	JourneyLessWalk                           = "less_fallback_walk"
	JourneyLessBike                           = "less_fallback_bike"
	JourneyLessBikeShare                      = "less_fallback_bss"
	JourneyFastest                            = "fastest"
	JourneyNoPTWalk                           = "non_pt_walk"
	JourneyNoPTBike                           = "non_pt_bike"
	JourneyNoPTBikeShare                      = "non_pt_bss"
)

// JourneyQualifications is a user-friendly map of all journey qualification
var JourneyQualifications = map[string]JourneyQualification{
	"Best":                                   JourneyBest,
	"Rapid":                                  JourneyRapid,
	"Comfort":                                JourneyComfort,
	"Car":                                    JourneyCar,
	"Less walking":                           JourneyLessWalk,
	"Less biking":                            JourneyLessBike,
	"Less bike sharing":                      JourneyLessBikeShare,
	"Fastest":                                JourneyFastest,
	"No public transit, prefer walking":      JourneyNoPTWalk,
	"No public transit, prefer biking":       JourneyNoPTBike,
	"No public transit, prefer bike-sharing": JourneyNoPTBikeShare,
}

// DateTimeFormat is the format used by the Navitia Api for use with time pkg.
// Few external use-cases but still there are some
const DateTimeFormat string = "20060102150405" // YYYYMMDDThhmmss

// A Journey holds information about a possible journey
type Journey struct {
	Duration  time.Duration `json:"duration"`
	Transfers uint          `json:"nb_transfers"`

	Departure time.Time `json:"departure_date_time"`
	Requested time.Time `json:"requested_date_time"`
	Arrival   time.Time `json:"arrival_date_time"`

	Sections []Section `json:"sections"`

	From Place `json:"from"`
	To   Place `json:"to"`

	Type JourneyQualification `json:"type"`

	Fare Fare `json:"fare"`

	//Status from the whole journey taking into acount the most disturbing information retrieved on every object used
	Status JourneyStatus
}

// JourneyStatus codes for known journey status information
// For example, reduced service, detours or moved stops.
type JourneyStatus string

// JourneyStatusXXX are known JourneyStatuse
const (
	JourneyStatusNoService         JourneyStatus = "NO_SERVICE"
	JourneyStatusReducedService                  = "REDUCED_SERVICE"
	JourneyStatusSignificantDelay                = "SIGNIFICANT_DELAY"
	JourneyStatusDetour                          = "DETOUR"
	JourneyStatusAdditionalService               = "ADDITIONAL_SERVICE"
	JourneyStatusModifiedService                 = "MODIFIED_SERVICE"
	JourneyStatusOtherEffect                     = "OTHER_EFFECT"
	JourneyStatusUnknownEffect                   = "UNKNOWN_EFFECT"
	JourneyStatusStopMoved                       = "STOP_MOVED"
)

// Fare is the fare of some thing
type Fare struct {
	Total currency.Amount
	Found bool
}

// TravelerType is a Traveler's type
// Defines speeds & accessibility values for different types of people
type TravelerType string

// The defined types of the api
const (
	// A standard Traveler
	TravelerStandard TravelerType = "standard"

	// A slow walker
	TravelerSlowWalker = "slow_walker"

	// A fast walker
	TravelerFastWalker = "fast_walker"

	// A Traveler with luggage
	TravelerWithLuggage = "luggage"

	// A Traveler in a wheelchair
	TravelerInWheelchair = "wheelchair"
)
<|endoftext|>


<commit_before>package ui

import (
	"fmt"
	"image"
	"image/color"
	"os"
	"time"

	"github.com/bugsnag/bugsnag-go"
	"github.com/ninjasphere/gestic-tools/go-gestic-sdk"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/model"
	owm "github.com/ninjasphere/openweathermap"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/O4b03b"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/clock"
	"github.com/ninjasphere/sphere-go-led-controller/util"
)

var enableWeatherPane = config.MustBool("led.weather.enabled")
var weatherUpdateInterval = config.MustDuration("led.weather.updateInterval")
var temperatureDisplayTime = config.Duration(time.Second*5, "led.weather.temperatureDisplayTime")

var globalSite *model.Site
var timezone *time.Location

type WeatherPane struct {
	siteModel   *ninja.ServiceClient
	site        *model.Site
	getWeather  *time.Timer
	tempTimeout *time.Timer
	temperature bool
	weather     *owm.ForecastWeatherData
	image       util.Image
}

func NewWeatherPane(conn *ninja.Connection) *WeatherPane {

	pane := &WeatherPane{
		siteModel: conn.GetServiceClient("$home/services/SiteModel"),
		image:     util.LoadImage(util.ResolveImagePath("weather/loading.gif")),
	}

	pane.tempTimeout = time.AfterFunc(0, func() {
		pane.temperature = false
	})

	if !enableWeatherPane {
		return pane
	}

	var err error
	pane.weather, err = owm.NewForecast("C")
	if err != nil {
		log.Warningf("Failed to load weather api:", err)
		enableWeatherPane = false
	} else {
		go pane.GetWeather()
	}

	return pane
}

func (p *WeatherPane) GetWeather() {

	enableWeatherPane = false

	for {
		site := &model.Site{}
		err := p.siteModel.Call("fetch", config.MustString("siteId"), site, time.Second*5)

		if err == nil && (site.Longitude != nil || site.Latitude != nil) {
			p.site = site
			globalSite = site

			if site.TimeZoneID != nil {
				if timezone, err = time.LoadLocation(*site.TimeZoneID); err != nil {
					log.Warningf("error while setting timezone (%s): %s", *site.TimeZoneID, err)
					timezone, _ = time.LoadLocation("Local")
				}
			}
			break
		}

		log.Infof("Failed to get site, or site has no location.")

		time.Sleep(time.Second * 2)
	}

	for {

		p.weather.DailyByCoordinates(
			&owm.Coordinates{
				Longitude: *p.site.Longitude,
				Latitude:  *p.site.Latitude,
			},
			1,
		)

		if len(p.weather.List) > 0 {

			filename := util.ResolveImagePath("weather/" + p.weather.List[0].Weather[0].Icon + ".png")

			if _, err := os.Stat(filename); os.IsNotExist(err) {
				enableWeatherPane = false
				fmt.Printf("Couldn't load image for weather: %s", filename)
				bugsnag.Notify(fmt.Errorf("Unknown weather icon: %s", filename), p.weather)
			} else {
				p.image = util.LoadImage(filename)
				enableWeatherPane = true
			}
		}

		time.Sleep(weatherUpdateInterval)

	}

}

func (p *WeatherPane) IsEnabled() bool {
	return enableWeatherPane && p.weather.Unit != ""
}

func (p *WeatherPane) Gesture(gesture *gestic.GestureMessage) {
	if gesture.Tap.Active() {
		log.Infof("Weather tap!")

		p.temperature = true
		p.tempTimeout.Reset(temperatureDisplayTime)
	}
}

func (p *WeatherPane) Render() (*image.RGBA, error) {
	if p.temperature {
		img := image.NewRGBA(image.Rect(0, 0, 16, 16))

		drawText := func(text string, col color.RGBA, top int) {
			width := clock.Font.DrawString(img, 0, 8, text, color.Black)
			start := int(16 - width - 2)

			//spew.Dump("text", text, "width", width, "start", start)

			O4b03b.Font.DrawString(img, start, top, text, col)
		}

		if p.weather.City.Country == "US" || p.weather.City.Country == "United States of America" {
			drawText(fmt.Sprintf("%dF", int(p.weather.List[0].Temp.Max*(9/5)-459.67)), color.RGBA{253, 151, 32, 255}, 1)
			drawText(fmt.Sprintf("%dF", int(p.weather.List[0].Temp.Min*(9/5)-459.67)), color.RGBA{69, 175, 249, 255}, 8)
		} else {
			drawText(fmt.Sprintf("%dC", int(p.weather.List[0].Temp.Max-273.15)), color.RGBA{253, 151, 32, 255}, 1)
			drawText(fmt.Sprintf("%dC", int(p.weather.List[0].Temp.Min-273.15)), color.RGBA{69, 175, 249, 255}, 8)
		}

		return img, nil
	} else {
		return p.image.GetNextFrame(), nil
	}
}

func (p *WeatherPane) IsDirty() bool {
	return true
}
<commit_msg>Update WeatherPane.go<commit_after>package ui

import (
	"fmt"
	"image"
	"image/color"
	"os"
	"time"

	"github.com/bugsnag/bugsnag-go"
	"github.com/ninjasphere/gestic-tools/go-gestic-sdk"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/model"
	owm "github.com/ninjasphere/openweathermap"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/O4b03b"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/clock"
	"github.com/ninjasphere/sphere-go-led-controller/util"
)

var enableWeatherPane = config.MustBool("led.weather.enabled")
var weatherUpdateInterval = config.MustDuration("led.weather.updateInterval")
var temperatureDisplayTime = config.Duration(time.Second*5, "led.weather.temperatureDisplayTime")

var globalSite *model.Site
var timezone *time.Location

type WeatherPane struct {
	siteModel   *ninja.ServiceClient
	site        *model.Site
	getWeather  *time.Timer
	tempTimeout *time.Timer
	temperature bool
	weather     *owm.ForecastWeatherData
	image       util.Image
}

func NewWeatherPane(conn *ninja.Connection) *WeatherPane {

	pane := &WeatherPane{
		siteModel: conn.GetServiceClient("$home/services/SiteModel"),
		image:     util.LoadImage(util.ResolveImagePath("weather/loading.gif")),
	}

	pane.tempTimeout = time.AfterFunc(0, func() {
		pane.temperature = false
	})

	if !enableWeatherPane {
		return pane
	}

	var err error
	pane.weather, err = owm.NewForecast("C")
	if err != nil {
		log.Warningf("Failed to load weather api:", err)
		enableWeatherPane = false
	} else {
		go pane.GetWeather()
	}

	return pane
}

func (p *WeatherPane) GetWeather() {

	enableWeatherPane = false

	for {
		site := &model.Site{}
		err := p.siteModel.Call("fetch", config.MustString("siteId"), site, time.Second*5)

		if err == nil && (site.Longitude != nil || site.Latitude != nil) {
			p.site = site
			globalSite = site

			if site.TimeZoneID != nil {
				if timezone, err = time.LoadLocation(*site.TimeZoneID); err != nil {
					log.Warningf("error while setting timezone (%s): %s", *site.TimeZoneID, err)
					timezone, _ = time.LoadLocation("Local")
				}
			}
			break
		}

		log.Infof("Failed to get site, or site has no location.")

		time.Sleep(time.Second * 2)
	}

	for {

		p.weather.DailyByCoordinates(
			&owm.Coordinates{
				Longitude: *p.site.Longitude,
				Latitude:  *p.site.Latitude,
			},
			1,
		)

		if len(p.weather.List) > 0 {

			filename := util.ResolveImagePath("weather/" + p.weather.List[0].Weather[0].Icon + ".png")

			if _, err := os.Stat(filename); os.IsNotExist(err) {
				enableWeatherPane = false
				fmt.Printf("Couldn't load image for weather: %s", filename)
				bugsnag.Notify(fmt.Errorf("Unknown weather icon: %s", filename), p.weather)
			} else {
				p.image = util.LoadImage(filename)
				enableWeatherPane = true
			}
		}

		time.Sleep(weatherUpdateInterval)

	}

}

func (p *WeatherPane) IsEnabled() bool {
	return enableWeatherPane && p.weather.Unit != ""
}

func (p *WeatherPane) Gesture(gesture *gestic.GestureMessage) {
	if gesture.Tap.Active() {
		log.Infof("Weather tap!")

		p.temperature = true
		p.tempTimeout.Reset(temperatureDisplayTime)
	}
}

func (p *WeatherPane) Render() (*image.RGBA, error) {
	if p.temperature {
		img := image.NewRGBA(image.Rect(0, 0, 16, 16))

		drawText := func(text string, col color.RGBA, top int) {
			width := clock.Font.DrawString(img, 0, 8, text, color.Black)
			start := int(16 - width - 2)

			//spew.Dump("text", text, "width", width, "start", start)

			O4b03b.Font.DrawString(img, start, top, text, col)
		}

		if p.weather.City.Country == "US" || p.weather.City.Country == "United States of America" {
			drawText(fmt.Sprintf("%dF", int(p.weather.List[0].Temp.Max*(9.0/5)-459.67)), color.RGBA{253, 151, 32, 255}, 1)
			drawText(fmt.Sprintf("%dF", int(p.weather.List[0].Temp.Min*(9.0/5)-459.67)), color.RGBA{69, 175, 249, 255}, 8)
		} else {
			drawText(fmt.Sprintf("%dC", int(p.weather.List[0].Temp.Max-273.15)), color.RGBA{253, 151, 32, 255}, 1)
			drawText(fmt.Sprintf("%dC", int(p.weather.List[0].Temp.Min-273.15)), color.RGBA{69, 175, 249, 255}, 8)
		}

		return img, nil
	} else {
		return p.image.GetNextFrame(), nil
	}
}

func (p *WeatherPane) IsDirty() bool {
	return true
}
<|endoftext|>


<commit_before>package packa

import "fmt"

// New creates packa.
func New(x int) error {
	if x < 0 {
	}
	return nil
}

type temporaryError struct {
	value int
}

// Error implements error interface.
func (e *temporaryError) Error() string {
	return fmt.Sprintf("packa: temporary: value %v", e.value)
}

func (*temporaryError) temporary() bool {
	return true
}

type basicError struct {
	value int
}

// Error implements error interface.
func (e *basicError) Error() string {
	return fmt.Sprintf("packa: value %v", e.value)
}

// IsTemporary returns true if err is temporary.
func IsTemporary(err error) bool {
	type temporary interface {
		temporary() bool
	}
	te, ok := err.(temporary)
	return ok && te.Temporary()
}
<commit_msg>errors/custom: add New<commit_after>package packa

import "fmt"

// New creates packa.
func New(x int, max int) error {
	if x < 0 {
		return &temporaryError{value: x}
	}
	if x < max {
		return &basicError{value: x, max: max}
	}
	return nil
}

type temporaryError struct {
	value int
}

// Error implements error interface.
func (e *temporaryError) Error() string {
	return fmt.Sprintf("packa: temporary: value %v", e.value)
}

func (*temporaryError) temporary() bool {
	return true
}

type basicError struct {
	value int
}

// Error implements error interface.
func (e *basicError) Error() string {
	return fmt.Sprintf("packa: value %v", e.value)
}

// IsTemporary returns true if err is temporary.
func IsTemporary(err error) bool {
	type temporary interface {
		temporary() bool
	}
	te, ok := err.(temporary)
	return ok && te.Temporary()
}
<|endoftext|>


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

package user

import (
	"github.com/globocom/config"
	"github.com/globocom/gandalf/db"
	"github.com/globocom/gandalf/fs"
	"github.com/globocom/gandalf/repository"
	fstesting "github.com/globocom/tsuru/fs/testing"
	"io/ioutil"
	"labix.org/v2/mgo/bson"
	. "launchpad.net/gocheck"
	"os"
	"path"
	"testing"
)

func Test(t *testing.T) { TestingT(t) }

type S struct {
	rfs *fstesting.RecordingFs
}

var _ = Suite(&S{})

func (s *S) authKeysContent(c *C) string {
	authFile := path.Join(os.Getenv("HOME"), ".ssh", "authorized_keys")
	f, err := fs.Filesystem().OpenFile(authFile, os.O_RDWR, 0755)
	c.Assert(err, IsNil)
	b, err := ioutil.ReadAll(f)
	c.Assert(err, IsNil)
	return string(b)
}

func (s *S) clearAuthKeyFile() bool {
	f, err := s.rfs.OpenFile(authKey(), os.O_RDWR, 0755)
	if err != nil {
		return false
	}
	if err := f.Truncate(0); err != nil {
		return false
	}
	return true
}

func (s *S) SetUpSuite(c *C) {
	err := config.ReadConfigFile("../etc/gandalf.conf")
	c.Check(err, IsNil)
	config.Set("database:name", "gandalf_user_tests")
	db.Connect()
}

func (s *S) SetUpTest(c *C) {
	s.rfs = &fstesting.RecordingFs{}
	fs.Fsystem = s.rfs
}

func (s *S) TearDownTest(c *C) {
	s.clearAuthKeyFile()
}

func (s *S) TearDownSuite(c *C) {
	fs.Fsystem = nil
	db.Session.DB.DropDatabase()
}

func (s *S) TestNewUserReturnsAStructFilled(c *C) {
	u, err := New("someuser", map[string]string{"somekey": "id_rsa someKeyChars"})
	c.Assert(err, IsNil)
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	c.Assert(u.Name, Equals, "someuser")
	c.Assert(len(u.Keys), Not(Equals), 0)
}

func (s *S) TestNewUserShouldStoreUserInDatabase(c *C) {
	u, err := New("someuser", map[string]string{"somekey": "id_rsa someKeyChars"})
	c.Assert(err, IsNil)
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	err = db.Session.User().FindId(u.Name).One(&u)
	c.Assert(err, IsNil)
	c.Assert(u.Name, Equals, "someuser")
	c.Assert(len(u.Keys), Not(Equals), 0)
}

func (s *S) TestNewChecksIfUserIsValidBeforeStoring(c *C) {
	_, err := New("", map[string]string{})
	c.Assert(err, NotNil)
	got := err.Error()
	expected := "Validation Error: user name is not valid"
	c.Assert(got, Equals, expected)
}

func (s *S) TestNewWritesKeyInAuthorizedKeys(c *C) {
	u, err := New("piccolo", map[string]string{"somekey": "idrsakey piccolo@myhost"})
	c.Assert(err, IsNil)
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	keys := s.authKeysContent(c)
	c.Assert(keys, Matches, ".*idrsakey piccolo@myhost")
}

func (s *S) TestIsValidReturnsErrorWhenUserDoesNotHaveAName(c *C) {
	u := User{Keys: map[string]string{"somekey": "id_rsa foooBar"}}
	v, err := u.isValid()
	c.Assert(v, Equals, false)
	c.Assert(err, NotNil)
	expected := "Validation Error: user name is not valid"
	got := err.Error()
	c.Assert(got, Equals, expected)
}

func (s *S) TestIsValidShouldNotAcceptEmptyUserName(c *C) {
	u := User{Keys: map[string]string{"somekey": "id_rsa foooBar"}}
	v, err := u.isValid()
	c.Assert(v, Equals, false)
	c.Assert(err, NotNil)
	expected := "Validation Error: user name is not valid"
	got := err.Error()
	c.Assert(got, Equals, expected)
}

func (s *S) TestIsValidShouldAcceptEmailsAsUserName(c *C) {
	u := User{Name: "r2d2@gmail.com", Keys: map[string]string{"somekey": "id_rsa foooBar"}}
	v, err := u.isValid()
	c.Assert(err, IsNil)
	c.Assert(v, Equals, true)
}

func (s *S) TestRemove(c *C) {
	u, err := New("someuser", map[string]string{})
	c.Assert(err, IsNil)
	err = Remove(u.Name)
	c.Assert(err, IsNil)
	lenght, err := db.Session.User().FindId(u.Name).Count()
	c.Assert(err, IsNil)
	c.Assert(lenght, Equals, 0)
}

func (s *S) TestRemoveRemovesKeyFromAuthorizedKeysFile(c *C) {
	u, err := New("gandalf", map[string]string{"somekey": "gandalfkey gandalf@mordor"})
	c.Assert(err, IsNil)
	err = Remove(u.Name)
	c.Assert(err, IsNil)
	got := s.authKeysContent(c)
	c.Assert(got, Not(Matches), ".*gandalfkey gandalf@mordor")
}

func (s *S) TestRemoveInexistentUserReturnsDescriptiveMessage(c *C) {
	err := Remove("otheruser")
	c.Assert(err, ErrorMatches, "Could not remove user: not found")
}

func (s *S) TestRemoveDoesNotRemovesUserWhenUserIsTheOnlyOneAssciatedWithOneRepository(c *C) {
	u, err := New("silver", map[string]string{})
	c.Assert(err, IsNil)
	r := s.createRepo("run", []string{u.Name}, c)
	defer db.Session.Repository().Remove(bson.M{"_id": r.Name})
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	err = Remove(u.Name)
	c.Assert(err, ErrorMatches, "^Could not remove user: user is the only one with access to at least one of it's repositories$")
}

func (s *S) TestRemoveRevokesAccessToReposWithMoreThanOneUserAssociated(c *C) {
	u, r, r2 := s.userPlusRepos(c)
	defer db.Session.Repository().Remove(bson.M{"_id": r.Name})
	defer db.Session.Repository().Remove(bson.M{"_id": r2.Name})
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	err := Remove(u.Name)
	c.Assert(err, IsNil)
	s.retrieveRepos(r, r2, c)
	c.Assert(r.Users, DeepEquals, []string{"slot"})
	c.Assert(r2.Users, DeepEquals, []string{"cnot"})
}

func (s *S) retrieveRepos(r, r2 *repository.Repository, c *C) {
	err := db.Session.Repository().FindId(r.Name).One(&r)
	c.Assert(err, IsNil)
	err = db.Session.Repository().FindId(r2.Name).One(&r2)
	c.Assert(err, IsNil)
}

func (s *S) userPlusRepos(c *C) (*User, *repository.Repository, *repository.Repository) {
	u, err := New("silver", map[string]string{})
	c.Assert(err, IsNil)
	r := s.createRepo("run", []string{u.Name, "slot"}, c)
	r2 := s.createRepo("stay", []string{u.Name, "cnot"}, c)
	return u, &r, &r2
}

func (s *S) createRepo(name string, users []string, c *C) repository.Repository {
	r := repository.Repository{Name: name, Users: users}
	err := db.Session.Repository().Insert(&r)
	c.Assert(err, IsNil)
	return r
}

func (s *S) TestHandleAssociatedRepositoriesShouldRevokeAccessToRepoWithMoreThanOneUserAssociated(c *C) {
	u, r, r2 := s.userPlusRepos(c)
	defer db.Session.Repository().RemoveId(r.Name)
	defer db.Session.Repository().RemoveId(r2.Name)
	defer db.Session.User().RemoveId(u.Name)
	err := u.handleAssociatedRepositories()
	c.Assert(err, IsNil)
	s.retrieveRepos(r, r2, c)
	c.Assert(r.Users, DeepEquals, []string{"slot"})
	c.Assert(r2.Users, DeepEquals, []string{"cnot"})
}

func (s *S) TestHandleAssociateRepositoriesReturnsErrorWhenUserIsOnlyOneWithAccessToAtLeastOneRepo(c *C) {
	u, err := New("umi", map[string]string{})
	c.Assert(err, IsNil)
	r := s.createRepo("proj1", []string{"umi"}, c)
	defer db.Session.User().RemoveId(u.Name)
	defer db.Session.Repository().RemoveId(r.Name)
	err = u.handleAssociatedRepositories()
	expected := "^Could not remove user: user is the only one with access to at least one of it's repositories$"
	c.Assert(err, ErrorMatches, expected)
}

func (s *S) TestAddKeyShouldAppendKeyIntoUsersDocument(c *C) {
	u, err := New("umi", map[string]string{})
	defer db.Session.User().RemoveId(u.Name)
	k := map[string]string{"somekey": "ssh-rsa mykey umi@lolcats"}
	err = AddKey("umi", k)
	c.Assert(err, IsNil)
	err = db.Session.User().FindId(u.Name).One(&u)
	c.Assert(u.Keys, DeepEquals, k)
}

func (s *S) TestAddKeyShouldWriteKeyInAuthorizedKeys(c *C) {
	u, err := New("umi", map[string]string{})
	defer db.Session.User().RemoveId(u.Name)
	k := map[string]string{"somekey": "ssh-rsa mykey umi@lolcats"}
	err = AddKey("umi", k)
	c.Assert(err, IsNil)
	content := s.authKeysContent(c)
	c.Assert(content, Matches, ".* "+k["somekey"])
}

func (s *S) TestAddKeyShouldReturnCustomErrorWhenUserDoesNotExists(c *C) {
	err := AddKey("umi", map[string]string{"somekey": "ssh-rsa mykey umi@host"})
	c.Assert(err, ErrorMatches, `^User "umi" not found$`)
}

func (s *S) TestRemoveKeyShouldRemoveKeyFromUserDocument(c *C) {
	u, err := New("luke", map[string]string{"homekey": "ssh-rsa lukeskey@home"})
	c.Assert(err, IsNil)
	defer db.Session.User().RemoveId(u.Name)
	err = RemoveKey("luke", "homekey")
	c.Assert(err, IsNil)
	err = db.Session.User().FindId(u.Name).One(&u)
	c.Assert(err, IsNil)
	c.Assert(u.Keys, DeepEquals, map[string]string{})
}

func (s *S) TestRemoveKeyShouldRemoveFromAuthorizedKeysFile(c *C) {
	k := "ssh-rsa lukeskey@home"
	u, err := New("luke", map[string]string{"homekey": k})
	c.Assert(err, IsNil)
	defer db.Session.User().RemoveId(u.Name)
	err = RemoveKey("luke", "homekey")
	c.Assert(err, IsNil)
	content := s.authKeysContent(c)
	c.Assert(content, Not(Matches), ".* "+k)
}

func (s *S) TestRemoveKeyShouldReturnFormatedErrorMsgWhenKeyDoesNotExists(c *C) {
	u, err := New("luke", map[string]string{})
	c.Assert(err, IsNil)
	defer db.Session.User().RemoveId(u.Name)
	err = RemoveKey("luke", "homekey")
	c.Assert(err, ErrorMatches, `^Key "homekey" for user "luke" does not exists$`)
}

func (s *S) TestRemoveKeyShouldReturnFormatedErrorMsgWhenUserDoesNotExists(c *C) {
	err := RemoveKey("luke", "homekey")
	c.Assert(err, ErrorMatches, `^User "luke" does not exists$`)
}
<commit_msg>user: delete authorized_keys file on TearDownTest<commit_after>// Copyright 2013 gandalf authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package user

import (
	"github.com/globocom/config"
	"github.com/globocom/gandalf/db"
	"github.com/globocom/gandalf/fs"
	"github.com/globocom/gandalf/repository"
	fstesting "github.com/globocom/tsuru/fs/testing"
	"io/ioutil"
	"labix.org/v2/mgo/bson"
	. "launchpad.net/gocheck"
	"os"
	"path"
	"testing"
)

func Test(t *testing.T) { TestingT(t) }

type S struct {
	rfs *fstesting.RecordingFs
}

var _ = Suite(&S{})

func (s *S) authKeysContent(c *C) string {
	authFile := path.Join(os.Getenv("HOME"), ".ssh", "authorized_keys")
	f, err := fs.Filesystem().OpenFile(authFile, os.O_RDWR, 0755)
	c.Assert(err, IsNil)
	b, err := ioutil.ReadAll(f)
	c.Assert(err, IsNil)
	return string(b)
}

func (s *S) SetUpSuite(c *C) {
	err := config.ReadConfigFile("../etc/gandalf.conf")
	c.Check(err, IsNil)
	config.Set("database:name", "gandalf_user_tests")
	db.Connect()
}

func (s *S) SetUpTest(c *C) {
	s.rfs = &fstesting.RecordingFs{}
	fs.Fsystem = s.rfs
}

func (s *S) TearDownTest(c *C) {
	s.rfs.Remove(authKey())
}

func (s *S) TearDownSuite(c *C) {
	fs.Fsystem = nil
	db.Session.DB.DropDatabase()
}

func (s *S) TestNewUserReturnsAStructFilled(c *C) {
	u, err := New("someuser", map[string]string{"somekey": "id_rsa someKeyChars"})
	c.Assert(err, IsNil)
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	c.Assert(u.Name, Equals, "someuser")
	c.Assert(len(u.Keys), Not(Equals), 0)
}

func (s *S) TestNewUserShouldStoreUserInDatabase(c *C) {
	u, err := New("someuser", map[string]string{"somekey": "id_rsa someKeyChars"})
	c.Assert(err, IsNil)
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	err = db.Session.User().FindId(u.Name).One(&u)
	c.Assert(err, IsNil)
	c.Assert(u.Name, Equals, "someuser")
	c.Assert(len(u.Keys), Not(Equals), 0)
}

func (s *S) TestNewChecksIfUserIsValidBeforeStoring(c *C) {
	_, err := New("", map[string]string{})
	c.Assert(err, NotNil)
	got := err.Error()
	expected := "Validation Error: user name is not valid"
	c.Assert(got, Equals, expected)
}

func (s *S) TestNewWritesKeyInAuthorizedKeys(c *C) {
	u, err := New("piccolo", map[string]string{"somekey": "idrsakey piccolo@myhost"})
	c.Assert(err, IsNil)
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	keys := s.authKeysContent(c)
	c.Assert(keys, Matches, ".*idrsakey piccolo@myhost")
}

func (s *S) TestIsValidReturnsErrorWhenUserDoesNotHaveAName(c *C) {
	u := User{Keys: map[string]string{"somekey": "id_rsa foooBar"}}
	v, err := u.isValid()
	c.Assert(v, Equals, false)
	c.Assert(err, NotNil)
	expected := "Validation Error: user name is not valid"
	got := err.Error()
	c.Assert(got, Equals, expected)
}

func (s *S) TestIsValidShouldNotAcceptEmptyUserName(c *C) {
	u := User{Keys: map[string]string{"somekey": "id_rsa foooBar"}}
	v, err := u.isValid()
	c.Assert(v, Equals, false)
	c.Assert(err, NotNil)
	expected := "Validation Error: user name is not valid"
	got := err.Error()
	c.Assert(got, Equals, expected)
}

func (s *S) TestIsValidShouldAcceptEmailsAsUserName(c *C) {
	u := User{Name: "r2d2@gmail.com", Keys: map[string]string{"somekey": "id_rsa foooBar"}}
	v, err := u.isValid()
	c.Assert(err, IsNil)
	c.Assert(v, Equals, true)
}

func (s *S) TestRemove(c *C) {
	u, err := New("someuser", map[string]string{})
	c.Assert(err, IsNil)
	err = Remove(u.Name)
	c.Assert(err, IsNil)
	lenght, err := db.Session.User().FindId(u.Name).Count()
	c.Assert(err, IsNil)
	c.Assert(lenght, Equals, 0)
}

func (s *S) TestRemoveRemovesKeyFromAuthorizedKeysFile(c *C) {
	u, err := New("gandalf", map[string]string{"somekey": "gandalfkey gandalf@mordor"})
	c.Assert(err, IsNil)
	err = Remove(u.Name)
	c.Assert(err, IsNil)
	got := s.authKeysContent(c)
	c.Assert(got, Not(Matches), ".*gandalfkey gandalf@mordor")
}

func (s *S) TestRemoveInexistentUserReturnsDescriptiveMessage(c *C) {
	err := Remove("otheruser")
	c.Assert(err, ErrorMatches, "Could not remove user: not found")
}

func (s *S) TestRemoveDoesNotRemovesUserWhenUserIsTheOnlyOneAssciatedWithOneRepository(c *C) {
	u, err := New("silver", map[string]string{})
	c.Assert(err, IsNil)
	r := s.createRepo("run", []string{u.Name}, c)
	defer db.Session.Repository().Remove(bson.M{"_id": r.Name})
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	err = Remove(u.Name)
	c.Assert(err, ErrorMatches, "^Could not remove user: user is the only one with access to at least one of it's repositories$")
}

func (s *S) TestRemoveRevokesAccessToReposWithMoreThanOneUserAssociated(c *C) {
	u, r, r2 := s.userPlusRepos(c)
	defer db.Session.Repository().Remove(bson.M{"_id": r.Name})
	defer db.Session.Repository().Remove(bson.M{"_id": r2.Name})
	defer db.Session.User().Remove(bson.M{"_id": u.Name})
	err := Remove(u.Name)
	c.Assert(err, IsNil)
	s.retrieveRepos(r, r2, c)
	c.Assert(r.Users, DeepEquals, []string{"slot"})
	c.Assert(r2.Users, DeepEquals, []string{"cnot"})
}

func (s *S) retrieveRepos(r, r2 *repository.Repository, c *C) {
	err := db.Session.Repository().FindId(r.Name).One(&r)
	c.Assert(err, IsNil)
	err = db.Session.Repository().FindId(r2.Name).One(&r2)
	c.Assert(err, IsNil)
}

func (s *S) userPlusRepos(c *C) (*User, *repository.Repository, *repository.Repository) {
	u, err := New("silver", map[string]string{})
	c.Assert(err, IsNil)
	r := s.createRepo("run", []string{u.Name, "slot"}, c)
	r2 := s.createRepo("stay", []string{u.Name, "cnot"}, c)
	return u, &r, &r2
}

func (s *S) createRepo(name string, users []string, c *C) repository.Repository {
	r := repository.Repository{Name: name, Users: users}
	err := db.Session.Repository().Insert(&r)
	c.Assert(err, IsNil)
	return r
}

func (s *S) TestHandleAssociatedRepositoriesShouldRevokeAccessToRepoWithMoreThanOneUserAssociated(c *C) {
	u, r, r2 := s.userPlusRepos(c)
	defer db.Session.Repository().RemoveId(r.Name)
	defer db.Session.Repository().RemoveId(r2.Name)
	defer db.Session.User().RemoveId(u.Name)
	err := u.handleAssociatedRepositories()
	c.Assert(err, IsNil)
	s.retrieveRepos(r, r2, c)
	c.Assert(r.Users, DeepEquals, []string{"slot"})
	c.Assert(r2.Users, DeepEquals, []string{"cnot"})
}

func (s *S) TestHandleAssociateRepositoriesReturnsErrorWhenUserIsOnlyOneWithAccessToAtLeastOneRepo(c *C) {
	u, err := New("umi", map[string]string{})
	c.Assert(err, IsNil)
	r := s.createRepo("proj1", []string{"umi"}, c)
	defer db.Session.User().RemoveId(u.Name)
	defer db.Session.Repository().RemoveId(r.Name)
	err = u.handleAssociatedRepositories()
	expected := "^Could not remove user: user is the only one with access to at least one of it's repositories$"
	c.Assert(err, ErrorMatches, expected)
}

func (s *S) TestAddKeyShouldAppendKeyIntoUsersDocument(c *C) {
	u, err := New("umi", map[string]string{})
	defer db.Session.User().RemoveId(u.Name)
	k := map[string]string{"somekey": "ssh-rsa mykey umi@lolcats"}
	err = AddKey("umi", k)
	c.Assert(err, IsNil)
	err = db.Session.User().FindId(u.Name).One(&u)
	c.Assert(u.Keys, DeepEquals, k)
}

func (s *S) TestAddKeyShouldWriteKeyInAuthorizedKeys(c *C) {
	u, err := New("umi", map[string]string{})
	defer db.Session.User().RemoveId(u.Name)
	k := map[string]string{"somekey": "ssh-rsa mykey umi@lolcats"}
	err = AddKey("umi", k)
	c.Assert(err, IsNil)
	content := s.authKeysContent(c)
	c.Assert(content, Matches, ".* "+k["somekey"])
}

func (s *S) TestAddKeyShouldReturnCustomErrorWhenUserDoesNotExists(c *C) {
	err := AddKey("umi", map[string]string{"somekey": "ssh-rsa mykey umi@host"})
	c.Assert(err, ErrorMatches, `^User "umi" not found$`)
}

func (s *S) TestRemoveKeyShouldRemoveKeyFromUserDocument(c *C) {
	u, err := New("luke", map[string]string{"homekey": "ssh-rsa lukeskey@home"})
	c.Assert(err, IsNil)
	defer db.Session.User().RemoveId(u.Name)
	err = RemoveKey("luke", "homekey")
	c.Assert(err, IsNil)
	err = db.Session.User().FindId(u.Name).One(&u)
	c.Assert(err, IsNil)
	c.Assert(u.Keys, DeepEquals, map[string]string{})
}

func (s *S) TestRemoveKeyShouldRemoveFromAuthorizedKeysFile(c *C) {
	k := "ssh-rsa lukeskey@home"
	u, err := New("luke", map[string]string{"homekey": k})
	c.Assert(err, IsNil)
	defer db.Session.User().RemoveId(u.Name)
	err = RemoveKey("luke", "homekey")
	c.Assert(err, IsNil)
	content := s.authKeysContent(c)
	c.Assert(content, Not(Matches), ".* "+k)
}

func (s *S) TestRemoveKeyShouldReturnFormatedErrorMsgWhenKeyDoesNotExists(c *C) {
	u, err := New("luke", map[string]string{})
	c.Assert(err, IsNil)
	defer db.Session.User().RemoveId(u.Name)
	err = RemoveKey("luke", "homekey")
	c.Assert(err, ErrorMatches, `^Key "homekey" for user "luke" does not exists$`)
}

func (s *S) TestRemoveKeyShouldReturnFormatedErrorMsgWhenUserDoesNotExists(c *C) {
	err := RemoveKey("luke", "homekey")
	c.Assert(err, ErrorMatches, `^User "luke" does not exists$`)
}
<|endoftext|>


<commit_before>// Copyright 2015 Dorival Pedroso and Raul Durand. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package la implements routines and structures for linear algebra with
// matrices and vectors in dense and sparse formats (including complex)
package la

import (
	"bytes"
	"fmt"
	"math"
	"strings"

	"github.com/cpmech/gosl/io"
)

const PRINTZEROTOL = 1e-13

// PrintVec prints a vector
func PrintVec(name string, a []float64, format string, numpy bool) {
	if !io.Verbose {
		return
	}
	r := name + " = "
	if numpy {
		r += " array(["
	}
	for i := 0; i < len(a); i++ {
		if math.Abs(a[i]) <= PRINTZEROTOL {
			r += fmt.Sprintf(format, 0.0)
		} else {
			r += fmt.Sprintf(format, a[i])
		}
		if numpy {
			if i < len(a)-1 {
				r += ","
			}
		}
	}
	if numpy {
		r += "])"
	}
	fmt.Println(r)
}

// PrintMat prints a dense matrix
func PrintMat(name string, a [][]float64, format string, numpy bool) {
	if !io.Verbose {
		return
	}
	r := name + " ="
	if numpy {
		r += " array(["
	} else {
		r += "\n"
	}
	for i := 0; i < len(a); i++ {
		if numpy {
			r += "["
		}
		for j := 0; j < len(a[0]); j++ {
			r += fmt.Sprintf(format, a[i][j])
			if numpy {
				if j != len(a[0])-1 {
					r += ","
				}
			}
		}
		if numpy {
			if i == len(a)-1 {
				r += "]"
			} else {
				r += "],"
			}
		}
		if i != len(a)-1 {
			r += "\n"
		}
	}
	if numpy {
		r += "])"
	}
	fmt.Println(r)
}

// WriteSmat writes a smat matrix for vismatrix
func WriteSmat(fnkey string, a [][]float64, tol float64) {
	var bfa, bfb bytes.Buffer
	var nnz int = 0
	m := len(a)
	n := len(a[0])
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			if math.Abs(a[i][j]) > tol {
				fmt.Fprintf(&bfb, "  %d  %d  %g\n", i, j, a[i][j])
				nnz++
			}
		}
	}
	fmt.Fprintf(&bfa, "%d  %d  %d\n", m, n, nnz)
	io.WriteFile(fnkey+".smat", &bfa, &bfb)
}

// ReadSmat reads a smat matrix back
func ReadSmat(fn string) *Triplet {
	var t Triplet
	io.ReadLines(fn,
		func(idx int, line string) (stop bool) {
			r := strings.Fields(line)
			if idx == 0 {
				m, n, nnz := io.Atoi(r[0]), io.Atoi(r[1]), io.Atoi(r[2])
				t.Init(m, n, nnz)
			} else {
				t.Put(io.Atoi(r[0]), io.Atoi(r[1]), io.Atof(r[2]))
			}
			return
		})
	return &t
}

// PrintVecC prints a vector of complex numbers
func PrintVecC(name string, a []complex128, format, formatz string, numpy bool) {
	if !io.Verbose {
		return
	}
	r := name + " ="
	if numpy {
		r += " array(["
	}
	for i := 0; i < len(a); i++ {
		r += fmt.Sprintf(format, real(a[i]))
		r += fmt.Sprintf(formatz, imag(a[i]))
		if numpy {
			if i < len(a)-1 {
				r += ","
			}
		}
	}
	if numpy {
		r += "])"
	}
	fmt.Println(r)
}

// PrintMatC prints a matrix of complex numbers
func PrintMatC(name string, a [][]complex128, format, formatz string, numpy bool) {
	if !io.Verbose {
		return
	}
	r := name + " ="
	if numpy {
		r += " array(["
	} else {
		r += "\n"
	}
	for i := 0; i < len(a); i++ {
		if numpy {
			r += "["
		}
		for j := 0; j < len(a[0]); j++ {
			r += fmt.Sprintf(format, real(a[i][j]))
			r += fmt.Sprintf(formatz, imag(a[i][j]))
			if numpy {
				if j != len(a[0])-1 {
					r += ","
				}
			}
		}
		if numpy {
			if i == len(a)-1 {
				r += "]"
			} else {
				r += "],"
			}
		}
		r += "\n"
	}
	if numpy {
		r += "])"
	}
	fmt.Println(r)
}

// SmatTriplet writes a ".smat" file that can be visualised with vismatrix
func SmatTriplet(fnkey string, t *Triplet) {
	var bfa, bfb bytes.Buffer
	var nnz int
	for k := 0; k < t.pos; k++ {
		if math.Abs(t.x[k]) > 1e-16 {
			fmt.Fprintf(&bfb, "  %d  %d  %23.15e\n", t.i[k], t.j[k], t.x[k])
			nnz++
		}
	}
	fmt.Fprintf(&bfa, "%d  %d  %d\n", t.m, t.n, nnz)
	io.WriteFile(fnkey+".smat", &bfa, &bfb)
}

// SmatCCMatrix writes a ".smat" file that can be visualised with vismatrix
func SmatCCMatrix(fnkey string, a *CCMatrix) {
	var bfa, bfb bytes.Buffer
	var nnz int
	for j := 0; j < a.n; j++ {
		for p := a.p[j]; p < a.p[j+1]; p++ {
			if math.Abs(a.x[p]) > 1e-16 {
				fmt.Fprintf(&bfb, "  %d  %d  %23.15e\n", a.i[p], j, a.x[p])
				nnz++
			}
		}
	}
	fmt.Fprintf(&bfa, "%d  %d  %d\n", a.m, a.n, nnz)
	io.WriteFile(fnkey+".smat", &bfa, &bfb)
}
<commit_msg>print mat now ignores too small values<commit_after>// Copyright 2015 Dorival Pedroso and Raul Durand. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package la implements routines and structures for linear algebra with
// matrices and vectors in dense and sparse formats (including complex)
package la

import (
	"bytes"
	"fmt"
	"math"
	"strings"

	"github.com/cpmech/gosl/io"
)

const PRINTZEROTOL = 1e-13

// PrintVec prints a vector
func PrintVec(name string, a []float64, format string, numpy bool) {
	if !io.Verbose {
		return
	}
	r := name + " = "
	if numpy {
		r += " array(["
	}
	for i := 0; i < len(a); i++ {
		if math.Abs(a[i]) <= PRINTZEROTOL {
			r += fmt.Sprintf(format, 0.0)
		} else {
			r += fmt.Sprintf(format, a[i])
		}
		if numpy {
			if i < len(a)-1 {
				r += ","
			}
		}
	}
	if numpy {
		r += "])"
	}
	fmt.Println(r)
}

// PrintMat prints a dense matrix
func PrintMat(name string, a [][]float64, format string, numpy bool) {
	if !io.Verbose {
		return
	}
	r := name + " ="
	if numpy {
		r += " array(["
	} else {
		r += "\n"
	}
	for i := 0; i < len(a); i++ {
		if numpy {
			r += "["
		}
		for j := 0; j < len(a[0]); j++ {
			if math.Abs(a[i][j]) <= PRINTZEROTOL {
				r += fmt.Sprintf(format, 0.0)
			} else {
				r += fmt.Sprintf(format, a[i][j])
			}
			if numpy {
				if j != len(a[0])-1 {
					r += ","
				}
			}
		}
		if numpy {
			if i == len(a)-1 {
				r += "]"
			} else {
				r += "],"
			}
		}
		if i != len(a)-1 {
			r += "\n"
		}
	}
	if numpy {
		r += "])"
	}
	fmt.Println(r)
}

// WriteSmat writes a smat matrix for vismatrix
func WriteSmat(fnkey string, a [][]float64, tol float64) {
	var bfa, bfb bytes.Buffer
	var nnz int = 0
	m := len(a)
	n := len(a[0])
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			if math.Abs(a[i][j]) > tol {
				fmt.Fprintf(&bfb, "  %d  %d  %g\n", i, j, a[i][j])
				nnz++
			}
		}
	}
	fmt.Fprintf(&bfa, "%d  %d  %d\n", m, n, nnz)
	io.WriteFile(fnkey+".smat", &bfa, &bfb)
}

// ReadSmat reads a smat matrix back
func ReadSmat(fn string) *Triplet {
	var t Triplet
	io.ReadLines(fn,
		func(idx int, line string) (stop bool) {
			r := strings.Fields(line)
			if idx == 0 {
				m, n, nnz := io.Atoi(r[0]), io.Atoi(r[1]), io.Atoi(r[2])
				t.Init(m, n, nnz)
			} else {
				t.Put(io.Atoi(r[0]), io.Atoi(r[1]), io.Atof(r[2]))
			}
			return
		})
	return &t
}

// PrintVecC prints a vector of complex numbers
func PrintVecC(name string, a []complex128, format, formatz string, numpy bool) {
	if !io.Verbose {
		return
	}
	r := name + " ="
	if numpy {
		r += " array(["
	}
	for i := 0; i < len(a); i++ {
		r += fmt.Sprintf(format, real(a[i]))
		r += fmt.Sprintf(formatz, imag(a[i]))
		if numpy {
			if i < len(a)-1 {
				r += ","
			}
		}
	}
	if numpy {
		r += "])"
	}
	fmt.Println(r)
}

// PrintMatC prints a matrix of complex numbers
func PrintMatC(name string, a [][]complex128, format, formatz string, numpy bool) {
	if !io.Verbose {
		return
	}
	r := name + " ="
	if numpy {
		r += " array(["
	} else {
		r += "\n"
	}
	for i := 0; i < len(a); i++ {
		if numpy {
			r += "["
		}
		for j := 0; j < len(a[0]); j++ {
			r += fmt.Sprintf(format, real(a[i][j]))
			r += fmt.Sprintf(formatz, imag(a[i][j]))
			if numpy {
				if j != len(a[0])-1 {
					r += ","
				}
			}
		}
		if numpy {
			if i == len(a)-1 {
				r += "]"
			} else {
				r += "],"
			}
		}
		r += "\n"
	}
	if numpy {
		r += "])"
	}
	fmt.Println(r)
}

// SmatTriplet writes a ".smat" file that can be visualised with vismatrix
func SmatTriplet(fnkey string, t *Triplet) {
	var bfa, bfb bytes.Buffer
	var nnz int
	for k := 0; k < t.pos; k++ {
		if math.Abs(t.x[k]) > 1e-16 {
			fmt.Fprintf(&bfb, "  %d  %d  %23.15e\n", t.i[k], t.j[k], t.x[k])
			nnz++
		}
	}
	fmt.Fprintf(&bfa, "%d  %d  %d\n", t.m, t.n, nnz)
	io.WriteFile(fnkey+".smat", &bfa, &bfb)
}

// SmatCCMatrix writes a ".smat" file that can be visualised with vismatrix
func SmatCCMatrix(fnkey string, a *CCMatrix) {
	var bfa, bfb bytes.Buffer
	var nnz int
	for j := 0; j < a.n; j++ {
		for p := a.p[j]; p < a.p[j+1]; p++ {
			if math.Abs(a.x[p]) > 1e-16 {
				fmt.Fprintf(&bfb, "  %d  %d  %23.15e\n", a.i[p], j, a.x[p])
				nnz++
			}
		}
	}
	fmt.Fprintf(&bfa, "%d  %d  %d\n", a.m, a.n, nnz)
	io.WriteFile(fnkey+".smat", &bfa, &bfb)
}
<|endoftext|>