<commit_before>package monitor_step_test

import (
	"errors"
	"net/http"
	"net/url"
	"time"

	"github.com/cloudfoundry-incubator/executor/sequence"
	"github.com/cloudfoundry-incubator/executor/sequence/fake_step"
	. "github.com/cloudfoundry-incubator/executor/steps/monitor_step"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/pivotal-golang/timer/fake_timer"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/ghttp"
)

var _ = Describe("MonitorStep", func() {
	var (
		check *fake_step.FakeStep

		healthyHookURL   *url.URL
		unhealthyHookURL *url.URL

		step sequence.Step

		hookServer *ghttp.Server
		logger     *lagertest.TestLogger
		timer      *fake_timer.FakeTimer
	)

	BeforeEach(func() {
		timer = fake_timer.NewFakeTimer(time.Now())
		check = new(fake_step.FakeStep)

		logger = lagertest.NewTestLogger("test")

		hookServer = ghttp.NewServer()

		healthyHookURL = &url.URL{
			Scheme: "http",
			Host:   hookServer.HTTPTestServer.Listener.Addr().String(),
			Path:   "/healthy",
		}

		unhealthyHookURL = &url.URL{
			Scheme: "http",
			Host:   hookServer.HTTPTestServer.Listener.Addr().String(),
			Path:   "/unhealthy",
		}
	})

	Describe("Perform", func() {
		expectCheckAfterInterval := func(d time.Duration) {
			previousCheckCount := check.PerformCallCount()

			timer.Elapse(d - 1*time.Microsecond)
			Consistently(check.PerformCallCount, 0.05).Should(Equal(previousCheckCount))

			timer.Elapse(1 * time.Microsecond)
			Eventually(check.PerformCallCount).Should(Equal(previousCheckCount + 1))
		}

		Context("when the healthy and unhealthy threshold is 2", func() {
			BeforeEach(func() {
				step = New(
					check,
					2,
					2,
					&http.Request{
						Method: "PUT",
						URL:    healthyHookURL,
					},
					&http.Request{
						Method: "PUT",
						URL:    unhealthyHookURL,
					},
					logger,
					timer,
				)
				go step.Perform()
			})

			AfterEach(func() {
				step.Cancel()
			})

			Context("when the check succeeds", func() {
				BeforeEach(func() {
					check.PerformReturns(nil)
					expectCheckAfterInterval(BaseInterval)
				})

				It("does not hit any endpoint", func() {
					Consistently(hookServer.ReceivedRequests()).Should(BeEmpty())
				})

				It("checks again after the same interval", func() {
					hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/healthy"))
					expectCheckAfterInterval(BaseInterval)
				})

				Context("when the next check fails", func() {
					BeforeEach(func() {
						check.PerformReturns(errors.New("nope"))
						hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/unhealthy"))
						expectCheckAfterInterval(BaseInterval)
					})

					It("checks again after the base interval", func() {
						expectCheckAfterInterval(BaseInterval)
					})
				})

				Context("when the second check succeeds, but hitting the healthy endpoint fails", func() {
					BeforeEach(func() {
						hookServer.AppendHandlers(func(w http.ResponseWriter, r *http.Request) {
							hookServer.HTTPTestServer.CloseClientConnections()
						})
						expectCheckAfterInterval(BaseInterval)
					})

					It("keeps calm and carries on", func() {
						Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
					})
				})

				Context("when the second check succeeds", func() {
					BeforeEach(func() {
						check.PerformReturns(nil)
						hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/healthy"))
						expectCheckAfterInterval(BaseInterval)
					})

					It("hits the healthy endpoint", func() {
						Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
					})

					It("checks again after double the interval", func() {
						expectCheckAfterInterval(2 * BaseInterval)
					})

					Context("when the third request succeeds", func() {
						BeforeEach(func() {
							check.PerformReturns(nil)
							expectCheckAfterInterval(BaseInterval * 2)
						})

						It("does not make another request to the healthy endpoint", func() {
							Consistently(hookServer.ReceivedRequests).Should(HaveLen(1))
						})

						Context("when the fourth request succeeds", func() {
							BeforeEach(func() {
								hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/healthy"))
								expectCheckAfterInterval(BaseInterval * 4)
							})

							It("hits the healthy endpoint a total of two times", func() {
								Eventually(hookServer.ReceivedRequests).Should(HaveLen(2))
							})

							It("continues to check with an exponential backoff, and eventually reaches a maximum interval", func() {
								hookServer.AllowUnhandledRequests = true
								expectCheckAfterInterval(BaseInterval * 8)
								expectCheckAfterInterval(BaseInterval * 16)
								expectCheckAfterInterval(BaseInterval * 32)
								expectCheckAfterInterval(BaseInterval * 60)

								for i := 0; i < 32; i++ {
									expectCheckAfterInterval(BaseInterval * 60)
								}
							})
						})
					})
				})
			})

			Context("when the check fails", func() {
				BeforeEach(func() {
					check.PerformReturns(errors.New("nope"))
					expectCheckAfterInterval(BaseInterval)
				})

				It("does not hit any endpoint", func() {
					Consistently(hookServer.ReceivedRequests()).Should(BeEmpty())
				})

				Context("and fails a second time", func() {
					BeforeEach(func() {
						hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/unhealthy"))
						expectCheckAfterInterval(BaseInterval)
					})

					It("hits the unhealthy endpoint", func() {
						Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
					})

					Context("and fails a third time", func() {
						BeforeEach(func() {
							expectCheckAfterInterval(BaseInterval)
						})

						It("does not hit the unhealthy endpoint again", func() {
							Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
							Consistently(hookServer.ReceivedRequests).Should(HaveLen(1))
						})

						Context("and fails a fourth time", func() {
							BeforeEach(func() {
								hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/unhealthy"))
								expectCheckAfterInterval(BaseInterval)
							})

							It("hits the unhealthy endpoint a second time", func() {
								Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(2))
							})
						})
					})
				})
			})

			Context("when the check succeeds, fails, succeeds, and fails", func() {
				BeforeEach(func() {
					check.PerformReturns(nil)
					expectCheckAfterInterval(BaseInterval)

					check.PerformReturns(errors.New("nope"))
					expectCheckAfterInterval(BaseInterval)

					check.PerformReturns(nil)
					expectCheckAfterInterval(BaseInterval)

					check.PerformReturns(errors.New("nope"))
					expectCheckAfterInterval(BaseInterval)
				})

				It("does not hit any endpoint", func() {
					Consistently(hookServer.ReceivedRequests).Should(BeEmpty())
				})
			})
		})

		Context("when the healthy and unhealthy thresholds are not specified", func() {
			BeforeEach(func() {
				step = New(
					check,
					0,
					0,
					&http.Request{
						Method: "PUT",
						URL:    healthyHookURL,
					},
					&http.Request{
						Method: "PUT",
						URL:    unhealthyHookURL,
					},
					logger,
					timer,
				)

				go step.Perform()
			})

			AfterEach(func() {
				step.Cancel()
			})

			Context("when the check succeeds", func() {
				BeforeEach(func() {
					check.PerformReturns(nil)
					hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/healthy"))
					expectCheckAfterInterval(BaseInterval)
				})

				It("hits the healthy endpoint", func() {
					Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
				})
			})

			Context("when the check fails", func() {
				BeforeEach(func() {
					check.PerformReturns(errors.New("nope"))
					hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/unhealthy"))
					expectCheckAfterInterval(BaseInterval)
				})

				It("hits the unhealthy endpoint", func() {
					Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
				})
			})
		})
	})

	Describe("Cancel", func() {
		BeforeEach(func() {
			step = New(
				check,
				2,
				2,
				&http.Request{
					Method: "PUT",
					URL:    healthyHookURL,
				},
				&http.Request{
					Method: "PUT",
					URL:    unhealthyHookURL,
				},
				logger,
				timer,
			)
		})

		It("interrupts the monitoring", func() {
			performResult := make(chan error)

			go func() { performResult <- step.Perform() }()

			step.Cancel()

			Eventually(performResult).Should(Receive())
		})
	})
})
<commit_msg>fix data race in monitor step<commit_after>package monitor_step_test

import (
	"errors"
	"net/http"
	"net/url"
	"time"

	"github.com/cloudfoundry-incubator/executor/sequence"
	"github.com/cloudfoundry-incubator/executor/sequence/fake_step"
	. "github.com/cloudfoundry-incubator/executor/steps/monitor_step"
	"github.com/pivotal-golang/lager/lagertest"
	"github.com/pivotal-golang/timer/fake_timer"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/ghttp"
)

var _ = Describe("MonitorStep", func() {
	var (
		check *fake_step.FakeStep

		healthyHookURL   *url.URL
		unhealthyHookURL *url.URL

		step sequence.Step

		hookServer *ghttp.Server
		logger     *lagertest.TestLogger
		timer      *fake_timer.FakeTimer
	)

	BeforeEach(func() {
		timer = fake_timer.NewFakeTimer(time.Now())
		check = new(fake_step.FakeStep)

		logger = lagertest.NewTestLogger("test")

		hookServer = ghttp.NewServer()

		healthyHookURL = &url.URL{
			Scheme: "http",
			Host:   hookServer.HTTPTestServer.Listener.Addr().String(),
			Path:   "/healthy",
		}

		unhealthyHookURL = &url.URL{
			Scheme: "http",
			Host:   hookServer.HTTPTestServer.Listener.Addr().String(),
			Path:   "/unhealthy",
		}
	})

	Describe("Perform", func() {
		expectCheckAfterInterval := func(d time.Duration) {
			previousCheckCount := check.PerformCallCount()

			timer.Elapse(d - 1*time.Microsecond)
			Consistently(check.PerformCallCount, 0.05).Should(Equal(previousCheckCount))

			timer.Elapse(1 * time.Microsecond)
			Eventually(check.PerformCallCount).Should(Equal(previousCheckCount + 1))
		}

		Context("when the healthy and unhealthy threshold is 2", func() {
			BeforeEach(func() {
				step = New(
					check,
					2,
					2,
					&http.Request{
						Method: "PUT",
						URL:    healthyHookURL,
					},
					&http.Request{
						Method: "PUT",
						URL:    unhealthyHookURL,
					},
					logger,
					timer,
				)
				go step.Perform()
			})

			AfterEach(func() {
				step.Cancel()
			})

			Context("when the check succeeds", func() {
				BeforeEach(func() {
					check.PerformReturns(nil)
					expectCheckAfterInterval(BaseInterval)
				})

				It("does not hit any endpoint", func() {
					Consistently(hookServer.ReceivedRequests()).Should(BeEmpty())
				})

				It("checks again after the same interval", func() {
					hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/healthy"))
					expectCheckAfterInterval(BaseInterval)
				})

				Context("when the next check fails", func() {
					BeforeEach(func() {
						check.PerformReturns(errors.New("nope"))
						hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/unhealthy"))
						expectCheckAfterInterval(BaseInterval)
					})

					It("checks again after the base interval", func() {
						expectCheckAfterInterval(BaseInterval)
					})
				})

				Context("when the second check succeeds, but hitting the healthy endpoint fails", func() {
					BeforeEach(func() {
						currentServer := hookServer

						hookServer.AppendHandlers(func(w http.ResponseWriter, r *http.Request) {
							currentServer.HTTPTestServer.CloseClientConnections()
						})

						expectCheckAfterInterval(BaseInterval)
					})

					It("keeps calm and carries on", func() {
						Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
					})
				})

				Context("when the second check succeeds", func() {
					BeforeEach(func() {
						check.PerformReturns(nil)
						hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/healthy"))
						expectCheckAfterInterval(BaseInterval)
					})

					It("hits the healthy endpoint", func() {
						Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
					})

					It("checks again after double the interval", func() {
						expectCheckAfterInterval(2 * BaseInterval)
					})

					Context("when the third request succeeds", func() {
						BeforeEach(func() {
							check.PerformReturns(nil)
							expectCheckAfterInterval(BaseInterval * 2)
						})

						It("does not make another request to the healthy endpoint", func() {
							Consistently(hookServer.ReceivedRequests).Should(HaveLen(1))
						})

						Context("when the fourth request succeeds", func() {
							BeforeEach(func() {
								hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/healthy"))
								expectCheckAfterInterval(BaseInterval * 4)
							})

							It("hits the healthy endpoint a total of two times", func() {
								Eventually(hookServer.ReceivedRequests).Should(HaveLen(2))
							})

							It("continues to check with an exponential backoff, and eventually reaches a maximum interval", func() {
								hookServer.AllowUnhandledRequests = true
								expectCheckAfterInterval(BaseInterval * 8)
								expectCheckAfterInterval(BaseInterval * 16)
								expectCheckAfterInterval(BaseInterval * 32)
								expectCheckAfterInterval(BaseInterval * 60)

								for i := 0; i < 32; i++ {
									expectCheckAfterInterval(BaseInterval * 60)
								}
							})
						})
					})
				})
			})

			Context("when the check fails", func() {
				BeforeEach(func() {
					check.PerformReturns(errors.New("nope"))
					expectCheckAfterInterval(BaseInterval)
				})

				It("does not hit any endpoint", func() {
					Consistently(hookServer.ReceivedRequests()).Should(BeEmpty())
				})

				Context("and fails a second time", func() {
					BeforeEach(func() {
						hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/unhealthy"))
						expectCheckAfterInterval(BaseInterval)
					})

					It("hits the unhealthy endpoint", func() {
						Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
					})

					Context("and fails a third time", func() {
						BeforeEach(func() {
							expectCheckAfterInterval(BaseInterval)
						})

						It("does not hit the unhealthy endpoint again", func() {
							Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
							Consistently(hookServer.ReceivedRequests).Should(HaveLen(1))
						})

						Context("and fails a fourth time", func() {
							BeforeEach(func() {
								hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/unhealthy"))
								expectCheckAfterInterval(BaseInterval)
							})

							It("hits the unhealthy endpoint a second time", func() {
								Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(2))
							})
						})
					})
				})
			})

			Context("when the check succeeds, fails, succeeds, and fails", func() {
				BeforeEach(func() {
					check.PerformReturns(nil)
					expectCheckAfterInterval(BaseInterval)

					check.PerformReturns(errors.New("nope"))
					expectCheckAfterInterval(BaseInterval)

					check.PerformReturns(nil)
					expectCheckAfterInterval(BaseInterval)

					check.PerformReturns(errors.New("nope"))
					expectCheckAfterInterval(BaseInterval)
				})

				It("does not hit any endpoint", func() {
					Consistently(hookServer.ReceivedRequests).Should(BeEmpty())
				})
			})
		})

		Context("when the healthy and unhealthy thresholds are not specified", func() {
			BeforeEach(func() {
				step = New(
					check,
					0,
					0,
					&http.Request{
						Method: "PUT",
						URL:    healthyHookURL,
					},
					&http.Request{
						Method: "PUT",
						URL:    unhealthyHookURL,
					},
					logger,
					timer,
				)

				go step.Perform()
			})

			AfterEach(func() {
				step.Cancel()
			})

			Context("when the check succeeds", func() {
				BeforeEach(func() {
					check.PerformReturns(nil)
					hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/healthy"))
					expectCheckAfterInterval(BaseInterval)
				})

				It("hits the healthy endpoint", func() {
					Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
				})
			})

			Context("when the check fails", func() {
				BeforeEach(func() {
					check.PerformReturns(errors.New("nope"))
					hookServer.AppendHandlers(ghttp.VerifyRequest("PUT", "/unhealthy"))
					expectCheckAfterInterval(BaseInterval)
				})

				It("hits the unhealthy endpoint", func() {
					Eventually(hookServer.ReceivedRequests, 10).Should(HaveLen(1))
				})
			})
		})
	})

	Describe("Cancel", func() {
		BeforeEach(func() {
			step = New(
				check,
				2,
				2,
				&http.Request{
					Method: "PUT",
					URL:    healthyHookURL,
				},
				&http.Request{
					Method: "PUT",
					URL:    unhealthyHookURL,
				},
				logger,
				timer,
			)
		})

		It("interrupts the monitoring", func() {
			performResult := make(chan error)

			go func() { performResult <- step.Perform() }()

			step.Cancel()

			Eventually(performResult).Should(Receive())
		})
	})
})
<|endoftext|>


<commit_before>package ics

import (
	"crypto/md5"
	"fmt"
	"time"
)

type Event struct {
	start         time.Time
	end           time.Time
	created       time.Time
	modified      time.Time
	alarmTime     time.Time
	importedId    string
	status        string
	description   string
	summary       string
	rrule         string
	class         string
	id            string
	sequence      int
	attendees     []Attendee
	wholeDayEvent bool
	inCalendar    *Calendar
	alarmCallback func()
}

func NewEvent() *Event {
	e := new(Event)
	e.attendees = []Attendee{}
	return e
}

func (e *Event) SetStart(start time.Time) *Event {
	e.start = start
	return e
}

func (e *Event) GetStart() time.Time {
	return e.start
}

func (e *Event) SetEnd(end time.Time) *Event {
	e.end = end
	return e
}

func (e *Event) GetEnd() time.Time {
	return e.end
}

func (e *Event) SetID(id string) *Event {
	e.id = id
	return e
}

func (e *Event) GetID() string {
	return e.id
}

func (e *Event) SetImportedID(id string) *Event {
	e.importedId = id
	return e
}

func (e *Event) GetImportedID() string {
	return e.importedId
}

func (e *Event) SetAttendee(a Attendee) *Event {
	e.attendees = append(e.attendees, a)
	return e
}
func (e *Event) SetAttendees(attendees []Attendee) *Event {
	e.attendees = append(e.attendees, attendees...)
	return e
}

func (e *Event) GetAttendees() []Attendee {
	return e.attendees
}

func (e *Event) SetClass(class string) *Event {
	e.class = class
	return e
}

func (e *Event) GetClass() string {
	return e.class
}

func (e *Event) SetCreated(created time.Time) *Event {
	e.created = created
	return e
}

func (e *Event) GetCreated() time.Time {
	return e.created
}

func (e *Event) SetLastModified(modified time.Time) *Event {
	e.modified = modified
	return e
}

func (e *Event) GetLastModified() time.Time {
	return e.modified
}

func (e *Event) SetSequence(sq int) *Event {
	e.sequence = sq
	return e
}

func (e *Event) GetSequence() int {
	return e.sequence
}

func (e *Event) SetStatus(status string) *Event {
	e.status = status
	return e
}

func (e *Event) GetStatus() string {
	return e.status
}

func (e *Event) SetSummary(summary string) *Event {
	e.summary = summary
	return e
}

func (e *Event) GetSummary() string {
	return e.summary
}

func (e *Event) SetDescription(description string) *Event {
	e.description = description
	return e
}

func (e *Event) GetDescription() string {
	return e.description
}

func (e *Event) SetRRule(rrule string) *Event {
	e.rrule = rrule
	return e
}

func (e *Event) GetRRule() string {
	return e.rrule
}

func (e *Event) Clone(string) *Event {
	return e
}

func (e *Event) SetAlarm(time string, callback func()) *Event {
	return e
}

func (e *Event) GetAlarm() string {
	return ""
}

func (e *Event) SetWholeDayEvent(wholeDay bool) *Event {
	e.wholeDayEvent = wholeDay
	return e
}

func (e *Event) GetWholeDayEvent() bool {
	return e.wholeDayEvent
}

func (e *Event) IsWholeDay() bool {
	return e.wholeDayEvent
}

//  generates an unique id for the event
func (e *Event) GenerateEventId() string {
	if e.GetImportedID() != "" {
		toBeHashed := fmt.Sprintf("%s%s%s%s", e.GetStart(), e.GetEnd(), e.GetImportedID())
		return fmt.Sprintf("%x", md5.Sum(stringToByte(toBeHashed)))
	} else {
		toBeHashed := fmt.Sprintf("%s%s%s%s", e.GetStart(), e.GetEnd(), e.GetSummary(), e.GetDescription())
		return fmt.Sprintf("%x", md5.Sum(stringToByte(toBeHashed)))
	}

}

func (e *Event) SetCalendar(cal *Calendar) *Event {
	e.inCalendar = cal
	return e
}

func (e *Event) GetCalendar() *Calendar {
	return e.inCalendar
}

func (e *Event) String() string {
	from := e.GetStart().Format(YmdHis)
	to := e.GetEnd().Format(YmdHis)
	summ := e.GetSummary()
	status := e.GetStatus()
	attendeeCount := len(e.GetAttendees())
	return fmt.Sprintf("Event(%s) from %s to %s about %s . %d people are invited to it", status, from, to, summ, attendeeCount)
}
<commit_msg>event alarm<commit_after>package ics

import (
	"crypto/md5"
	"fmt"
	"time"
)

type Event struct {
	start         time.Time
	end           time.Time
	created       time.Time
	modified      time.Time
	alarmTime     time.Duration
	importedId    string
	status        string
	description   string
	summary       string
	rrule         string
	class         string
	id            string
	sequence      int
	attendees     []Attendee
	wholeDayEvent bool
	inCalendar    *Calendar
	alarmCallback func(*Event)
}

func NewEvent() *Event {
	e := new(Event)
	e.attendees = []Attendee{}
	return e
}

func (e *Event) SetStart(start time.Time) *Event {
	e.start = start
	return e
}

func (e *Event) GetStart() time.Time {
	return e.start
}

func (e *Event) SetEnd(end time.Time) *Event {
	e.end = end
	return e
}

func (e *Event) GetEnd() time.Time {
	return e.end
}

func (e *Event) SetID(id string) *Event {
	e.id = id
	return e
}

func (e *Event) GetID() string {
	return e.id
}

func (e *Event) SetImportedID(id string) *Event {
	e.importedId = id
	return e
}

func (e *Event) GetImportedID() string {
	return e.importedId
}

func (e *Event) SetAttendee(a Attendee) *Event {
	e.attendees = append(e.attendees, a)
	return e
}
func (e *Event) SetAttendees(attendees []Attendee) *Event {
	e.attendees = append(e.attendees, attendees...)
	return e
}

func (e *Event) GetAttendees() []Attendee {
	return e.attendees
}

func (e *Event) SetClass(class string) *Event {
	e.class = class
	return e
}

func (e *Event) GetClass() string {
	return e.class
}

func (e *Event) SetCreated(created time.Time) *Event {
	e.created = created
	return e
}

func (e *Event) GetCreated() time.Time {
	return e.created
}

func (e *Event) SetLastModified(modified time.Time) *Event {
	e.modified = modified
	return e
}

func (e *Event) GetLastModified() time.Time {
	return e.modified
}

func (e *Event) SetSequence(sq int) *Event {
	e.sequence = sq
	return e
}

func (e *Event) GetSequence() int {
	return e.sequence
}

func (e *Event) SetStatus(status string) *Event {
	e.status = status
	return e
}

func (e *Event) GetStatus() string {
	return e.status
}

func (e *Event) SetSummary(summary string) *Event {
	e.summary = summary
	return e
}

func (e *Event) GetSummary() string {
	return e.summary
}

func (e *Event) SetDescription(description string) *Event {
	e.description = description
	return e
}

func (e *Event) GetDescription() string {
	return e.description
}

func (e *Event) SetRRule(rrule string) *Event {
	e.rrule = rrule
	return e
}

func (e *Event) GetRRule() string {
	return e.rrule
}

func (e *Event) Clone(string) *Event {
	return e
}

func (e *Event) SetAlarm(alarmAfter time.Duration, callback func(*Event)) *Event {
	e.alarmCallback = callback
	e.alarmTime = alarmAfter
	go func() {
		select {
		case <-time.After(alarmAfter):
			callback(e)
		}
	}()
	return e
}

func (e *Event) GetAlarm() string {
	return ""
}

func (e *Event) SetWholeDayEvent(wholeDay bool) *Event {
	e.wholeDayEvent = wholeDay
	return e
}

func (e *Event) GetWholeDayEvent() bool {
	return e.wholeDayEvent
}

func (e *Event) IsWholeDay() bool {
	return e.wholeDayEvent
}

//  generates an unique id for the event
func (e *Event) GenerateEventId() string {
	if e.GetImportedID() != "" {
		toBeHashed := fmt.Sprintf("%s%s%s%s", e.GetStart(), e.GetEnd(), e.GetImportedID())
		return fmt.Sprintf("%x", md5.Sum(stringToByte(toBeHashed)))
	} else {
		toBeHashed := fmt.Sprintf("%s%s%s%s", e.GetStart(), e.GetEnd(), e.GetSummary(), e.GetDescription())
		return fmt.Sprintf("%x", md5.Sum(stringToByte(toBeHashed)))
	}

}

func (e *Event) SetCalendar(cal *Calendar) *Event {
	e.inCalendar = cal
	return e
}

func (e *Event) GetCalendar() *Calendar {
	return e.inCalendar
}

func (e *Event) String() string {
	from := e.GetStart().Format(YmdHis)
	to := e.GetEnd().Format(YmdHis)
	summ := e.GetSummary()
	status := e.GetStatus()
	attendeeCount := len(e.GetAttendees())
	return fmt.Sprintf("Event(%s) from %s to %s about %s . %d people are invited to it", status, from, to, summ, attendeeCount)
}
<|endoftext|>


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

// Package eventhorizon is a CQRS/ES toolkit.
package eventhorizon

import (
	"errors"
	"fmt"
	"sync"
)

// Event is a domain event describing a change that has happened to an aggregate.
//
// An event struct and type name should:
//   1) Be in past tense (CustomerMoved)
//   2) Contain the intent (CustomerMoved vs CustomerAddressCorrected).
//
// The event should contain all the data needed when applying/handling it.
type Event interface {
	// AggregateID returns the ID of the aggregate that the event should be
	// applied to.
	AggregateID() UUID

	// AggregateType returns the type of the aggregate that the event can be
	// applied to.
	// AggregateType() string
	AggregateType() AggregateType

	// EventType returns the type of the event.
	// EventType() string
	EventType() EventType
}

// EventType is the type of an event, used as its unique identifier.
type EventType string

var events = make(map[EventType]func() Event)
var registerEventLock sync.RWMutex

// ErrEventNotRegistered is when no event factory was registered.
var ErrEventNotRegistered = errors.New("event not registered")

// RegisterEvent registers an event factory for a type. The factory is
// used to create concrete event types when loading from the database.
//
// An example would be:
//     RegisterEvent(func() Event { return &MyEvent{} })
func RegisterEvent(factory func() Event) {
	// TODO: Explore the use of reflect/gob for creating concrete types without
	// a factory func.

	// Check that the created event matches the type registered.
	event := factory()
	if event == nil {
		panic("eventhorizon: created event is nil")
	}
	eventType := event.EventType()
	if eventType == EventType("") {
		panic("eventhorizon: attempt to register empty event type")
	}

	registerEventLock.Lock()
	defer registerEventLock.Unlock()
	if _, ok := events[eventType]; ok {
		panic(fmt.Sprintf("eventhorizon: registering duplicate types for %q", eventType))
	}
	events[eventType] = factory
}

// CreateEvent creates an event of a type with an ID using the factory
// registered with RegisterEvent.
func CreateEvent(eventType EventType) (Event, error) {
	registerEventLock.RLock()
	defer registerEventLock.RUnlock()
	if factory, ok := events[eventType]; ok {
		return factory(), nil
	}
	return nil, ErrEventNotRegistered
}
<commit_msg>Remove unused code in comments<commit_after>// Copyright (c) 2014 - Max Ekman <max@looplab.se>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package eventhorizon is a CQRS/ES toolkit.
package eventhorizon

import (
	"errors"
	"fmt"
	"sync"
)

// Event is a domain event describing a change that has happened to an aggregate.
//
// An event struct and type name should:
//   1) Be in past tense (CustomerMoved)
//   2) Contain the intent (CustomerMoved vs CustomerAddressCorrected).
//
// The event should contain all the data needed when applying/handling it.
type Event interface {
	// AggregateID returns the ID of the aggregate that the event should be
	// applied to.
	AggregateID() UUID

	// AggregateType returns the type of the aggregate that the event can be
	// applied to.
	AggregateType() AggregateType

	// EventType returns the type of the event.
	EventType() EventType
}

// EventType is the type of an event, used as its unique identifier.
type EventType string

var events = make(map[EventType]func() Event)
var registerEventLock sync.RWMutex

// ErrEventNotRegistered is when no event factory was registered.
var ErrEventNotRegistered = errors.New("event not registered")

// RegisterEvent registers an event factory for a type. The factory is
// used to create concrete event types when loading from the database.
//
// An example would be:
//     RegisterEvent(func() Event { return &MyEvent{} })
func RegisterEvent(factory func() Event) {
	// TODO: Explore the use of reflect/gob for creating concrete types without
	// a factory func.

	// Check that the created event matches the type registered.
	event := factory()
	if event == nil {
		panic("eventhorizon: created event is nil")
	}
	eventType := event.EventType()
	if eventType == EventType("") {
		panic("eventhorizon: attempt to register empty event type")
	}

	registerEventLock.Lock()
	defer registerEventLock.Unlock()
	if _, ok := events[eventType]; ok {
		panic(fmt.Sprintf("eventhorizon: registering duplicate types for %q", eventType))
	}
	events[eventType] = factory
}

// CreateEvent creates an event of a type with an ID using the factory
// registered with RegisterEvent.
func CreateEvent(eventType EventType) (Event, error) {
	registerEventLock.RLock()
	defer registerEventLock.RUnlock()
	if factory, ok := events[eventType]; ok {
		return factory(), nil
	}
	return nil, ErrEventNotRegistered
}
<|endoftext|>


<commit_before>package spec

import(
	. "tritium"
	. "tritium/engine"
)

func RunTests() {
	eng := &Engine{}
	RunTest(eng, "blank_test")
}

func RunTest(eng Transformer, named string) bool {
	//eng.Run(transform, input, vars)
	println("Ran test!", named)
	return true
}<commit_msg>Need tp files in the spec<commit_after>package spec

import(
	tp "tritium/proto"
)

type Spec struct {
	Location string

	// Inputs
	Input string
	Vars map[string]string

	// Script
	script tp.Executable

	// Expected outputs
	Output string
	Exports [][]string
	Logs []string
}

func LoadTest(directory string) (*Spec) {
	return &Spec{
		Location: directory,
		Input: "hi",
		Vars: make(map[string]string, 0),

		Output: "hi",
		Exports: make([][]string, 0),
		Logs: make([]string, 0),
	}
}<|endoftext|>


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

package cmd

import (
	"agenda/entity"
	"fmt"
	"log"
	entity "github.com/LeungChiHo/agenda/tree/master/entity"
	"github.com/spf13/cobra"
)

// MeetingsClearCmd represents the MeetingsClear command
var MeetingsClearCmd = &cobra.Command{
	Use:   "clear",
	Short: "clear all the meeting created by the current user",
	Long: `you can clear all the meeting you have created`,
	Run: func(cmd *cobra.Command, args []string) {
		debugLog := log.New(logFile,"[Result]", log.Ldate|log.Ltime|log.Lshortfile)
		if entity.StartAgenda() == false {
			debugLog.Println("Fail, please log in")
			fmt.Println("Fail, please log in")
		}

		if entity.DeleteAllMeetings(entity.CurrentUser.Name) {
			debugLog.Println("Clear meeting successfully")
			fmt.Println("Clear meeting successfully")

		} else {
			debugLog.Println("Fail to clear meeting")
			fmt.Println("Fail to clear meeting")
		}
		entity.QuitAgenda()
	},
}

func init() {
	RootCmd.AddCommand(MeetingsClearCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// MeetingsClearCmd.PersistentFlags().String("foo", "", "A help for foo")
MeetingsClearCmd.Flags().StringP("username", "u", "", "new user's username")
	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// MeetingsClearCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
<commit_msg>Update MeetingsClear.go<commit_after>// Copyright © 2017 NAME HERE <EMAIL ADDRESS>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"log"
	entity "github.com/LeungChiHo/agenda/tree/master/entity"
	"github.com/spf13/cobra"
)

// MeetingsClearCmd represents the MeetingsClear command
var MeetingsClearCmd = &cobra.Command{
	Use:   "clear",
	Short: "clear all the meeting created by the current user",
	Long: `you can clear all the meeting you have created`,
	Run: func(cmd *cobra.Command, args []string) {
		debugLog := log.New(logFile,"[Result]", log.Ldate|log.Ltime|log.Lshortfile)
		if entity.StartAgenda() == false {
			debugLog.Println("Fail, please log in")
			fmt.Println("Fail, please log in")
		}

		if entity.DeleteAllMeetings(entity.CurrentUser.Name) {
			debugLog.Println("Clear meeting successfully")
			fmt.Println("Clear meeting successfully")

		} else {
			debugLog.Println("Fail to clear meeting")
			fmt.Println("Fail to clear meeting")
		}
		entity.QuitAgenda()
	},
}

func init() {
	RootCmd.AddCommand(MeetingsClearCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// MeetingsClearCmd.PersistentFlags().String("foo", "", "A help for foo")
MeetingsClearCmd.Flags().StringP("username", "u", "", "new user's username")
	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// MeetingsClearCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"image"
	"image/draw"
	_ "image/jpeg"
	"image/png"
	"io/ioutil"
	"os"

	"github.com/golang/freetype/truetype"
	"golang.org/x/image/font"
	"golang.org/x/image/math/fixed"
)

func mustGetImage(path string) image.Image {
	image, err := getImage(path)
	if err != nil {
		panic(err)
	}
	return image
}

func getImage(path string) (image.Image, error) {
	imageFd, err := os.Open(path)
	if err != nil {
		return image.Black, err
	}
	defer imageFd.Close()

	img, _, err := image.Decode(imageFd)
	if err != nil {
		return image.Black, err
	}
	return img, nil
}

func generateBasicTemplate() draw.Image {
	templateImage := mustGetImage("template.png")
	destinationImage := image.NewNRGBA(templateImage.Bounds())

	// put base template into our destination
	draw.Draw(
		destinationImage,
		destinationImage.Bounds(),
		templateImage,
		image.ZP,
		draw.Src,
	)
	return destinationImage
}

func writeBackground(destinationImage draw.Image) draw.Image {
	templateMask := mustGetImage("template_mask.png")
	backgroundImage := mustGetImage("background")

	draw.DrawMask(
		destinationImage,
		destinationImage.Bounds(),
		backgroundImage,
		image.ZP,
		templateMask,
		image.ZP,
		draw.Over,
	)

	return destinationImage
}

func getFont() *truetype.Font {
	fontFd, err := os.Open("Loveletter_TW.ttf")
	if err != nil {
		panic(err)
	}

	fontBytes, err := ioutil.ReadAll(fontFd)
	if err != nil {
		panic(err)
	}

	font, err := truetype.Parse(fontBytes)
	if err != nil {
		panic(err)
	}

	return font
}

const (
	fontSize              = 16.0
	baselineX             = 30
	baselineY             = 120
	textBackgroundPadding = 2
)

func writeText(textConfig []string, destinationImage draw.Image) draw.Image {
	if len(textConfig) > 3 {
		panic(errors.New("more than three captions specified"))
	}

	fontFace := truetype.NewFace(
		getFont(),
		&truetype.Options{Size: fontSize},
	)
	x0 := baselineX
	y1 := baselineY
	startPoint := fixed.P(x0, y1)
	drawer := &font.Drawer{
		Dst:  destinationImage,
		Src:  image.Black,
		Face: fontFace,
		Dot:  startPoint,
	}

	drawDistance := drawer.MeasureString(textConfig[0])
	paddingPixels := textBackgroundPadding
	borderRect := image.Rect(
		x0-paddingPixels,
		y1-fontFace.Metrics().Ascent.Round()-paddingPixels,
		x0+drawDistance.Round()+paddingPixels,
		y1+paddingPixels,
	)
	draw.DrawMask(
		destinationImage,
		destinationImage.Bounds(),
		image.White,
		image.ZP,
		borderRect,
		image.ZP,
		draw.Over,
	)
	drawer.DrawString(textConfig[0])

	return destinationImage
}

func writeImage(path string, image image.Image) error {
	fd, err := os.Create(path)
	if err != nil {
		return err
	}
	defer fd.Close()

	return png.Encode(fd, image)
}

func main() {
	destinationImage := writeText([]string{"foo bar"}, writeBackground(generateBasicTemplate()))
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(r)
			os.Exit(1)
		}
	}()

	err := writeImage("out.png", destinationImage)
	if err != nil {
		panic(err)
	}
}
<commit_msg>change font size to 14 instead of 16<commit_after>package main

import (
	"errors"
	"fmt"
	"image"
	"image/draw"
	_ "image/jpeg"
	"image/png"
	"io/ioutil"
	"os"

	"github.com/golang/freetype/truetype"
	"golang.org/x/image/font"
	"golang.org/x/image/math/fixed"
)

func mustGetImage(path string) image.Image {
	image, err := getImage(path)
	if err != nil {
		panic(err)
	}
	return image
}

func getImage(path string) (image.Image, error) {
	imageFd, err := os.Open(path)
	if err != nil {
		return image.Black, err
	}
	defer imageFd.Close()

	img, _, err := image.Decode(imageFd)
	if err != nil {
		return image.Black, err
	}
	return img, nil
}

func generateBasicTemplate() draw.Image {
	templateImage := mustGetImage("template.png")
	destinationImage := image.NewNRGBA(templateImage.Bounds())

	// put base template into our destination
	draw.Draw(
		destinationImage,
		destinationImage.Bounds(),
		templateImage,
		image.ZP,
		draw.Src,
	)
	return destinationImage
}

func writeBackground(destinationImage draw.Image) draw.Image {
	templateMask := mustGetImage("template_mask.png")
	backgroundImage := mustGetImage("background")

	draw.DrawMask(
		destinationImage,
		destinationImage.Bounds(),
		backgroundImage,
		image.ZP,
		templateMask,
		image.ZP,
		draw.Over,
	)

	return destinationImage
}

func getFont() *truetype.Font {
	fontFd, err := os.Open("Loveletter_TW.ttf")
	if err != nil {
		panic(err)
	}

	fontBytes, err := ioutil.ReadAll(fontFd)
	if err != nil {
		panic(err)
	}

	font, err := truetype.Parse(fontBytes)
	if err != nil {
		panic(err)
	}

	return font
}

const (
	fontSize              = 14.0
	baselineX             = 30
	baselineY             = 120
	textBackgroundPadding = 2
)

func writeText(textConfig []string, destinationImage draw.Image) draw.Image {
	if len(textConfig) > 3 {
		panic(errors.New("more than three captions specified"))
	}

	fontFace := truetype.NewFace(
		getFont(),
		&truetype.Options{Size: fontSize},
	)
	x0 := baselineX
	y1 := baselineY
	startPoint := fixed.P(x0, y1)
	drawer := &font.Drawer{
		Dst:  destinationImage,
		Src:  image.Black,
		Face: fontFace,
		Dot:  startPoint,
	}

	drawDistance := drawer.MeasureString(textConfig[0])
	paddingPixels := textBackgroundPadding
	borderRect := image.Rect(
		x0-paddingPixels,
		y1-fontFace.Metrics().Ascent.Round()-paddingPixels,
		x0+drawDistance.Round()+paddingPixels,
		y1+paddingPixels,
	)
	draw.DrawMask(
		destinationImage,
		destinationImage.Bounds(),
		image.White,
		image.ZP,
		borderRect,
		image.ZP,
		draw.Over,
	)
	drawer.DrawString(textConfig[0])

	return destinationImage
}

func writeImage(path string, image image.Image) error {
	fd, err := os.Create(path)
	if err != nil {
		return err
	}
	defer fd.Close()

	return png.Encode(fd, image)
}

func main() {
	destinationImage := writeText([]string{"foo bar"}, writeBackground(generateBasicTemplate()))
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(r)
			os.Exit(1)
		}
	}()

	err := writeImage("out.png", destinationImage)
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package popular

import (
	"errors"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/request"
	"socialapi/workers/common/response"
	"socialapi/workers/helper"
	"socialapi/workers/popularpost/popularpost"
	"socialapi/workers/populartopic/populartopic"
	"strconv"
	"time"
)

func getDateNumberAndYear(statisticName string) (int, int, error) {
	now := time.Now().UTC()
	// dateNumber is changing according to the statisticName
	// if it is monthly statistic, it will be month number March->3
	// if it is weekly statistic, it will be week number 48th week -> 48
	// if it is daily statistic, it will the day number of the year e.g last day-> 365+1
	switch statisticName {
	case "daily":
		return now.Year(), now.YearDay(), nil
	case "weekly":
		year, week := now.ISOWeek()
		return year, week, nil
	case "monthly":
		return now.Year(), int(now.Month()), nil
	default:
		return 0, 0, errors.New("Unknown statistic name")
	}
}

func getIds(key string, query *request.Query) ([]int64, error) {
	// limit-1 is important, because redis is using 0 based index
	popularIds := make([]int64, 0)
	listIds, err := helper.MustGetRedisConn().
		SortedSetReverseRange(
		key,
		query.Skip,
		query.Skip+query.Limit-1,
	)

	if err != nil {
		return popularIds, err
	}

	for _, listId := range listIds {
		val, err := strconv.ParseInt(string(listId.([]uint8)), 10, 64)
		if err == nil {
			popularIds = append(popularIds, val)
		}
	}

	return popularIds, nil
}

func ListTopics(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)

	statisticName := u.Query().Get("statisticName")

	year, dateNumber, err := getDateNumberAndYear(statisticName)
	if err != nil {
		return response.NewBadRequest(errors.New("Unknown statistic name"))
	}

	key := populartopic.PreparePopularTopicKey(
		query.GroupName,
		statisticName,
		year,
		dateNumber,
	)

	popularTopicIds, err := getIds(key, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularTopicIds, err = extendPopularTopicsIfNeeded(query, popularTopicIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	c := models.NewChannel()
	popularTopics, err := c.FetchByIds(popularTopicIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(
		models.PopulateChannelContainers(
			popularTopics,
			query.AccountId,
		),
	)
}

func extendPopularTopicsIfNeeded(query *request.Query, popularTopics []int64) ([]int64, error) {
	toBeAddedItemCount := query.Limit - len(popularTopics)

	if toBeAddedItemCount > 0 {
		normalChannels, err := fetchMoreChannels(query.GroupName, query.Limit)
		if err != nil {
			return popularTopics, err
		}

		for _, normalChannel := range normalChannels {
			exists := false
			for _, popularTopicId := range popularTopics {
				if normalChannel.Id == popularTopicId {
					exists = true
					break
				}
			}

			if !exists {
				popularTopics = append(popularTopics, normalChannel.Id)
				toBeAddedItemCount--
				if toBeAddedItemCount == 0 {
					break
				}
			}
		}
	}

	return popularTopics, nil
}

func fetchMoreChannels(group string, count int) ([]models.Channel, error) {
	q := request.NewQuery()
	q.GroupName = group
	q.Limit = count
	q.Type = models.Channel_TYPE_TOPIC
	q.SetDefaults()
	c := models.NewChannel()

	return c.List(q)
}

func ListPosts(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query.Type = models.ChannelMessage_TYPE_POST

	statisticName := u.Query().Get("statisticName")
	channelName := u.Query().Get("channelName")

	year, dateNumber, err := getDateNumberAndYear(statisticName)
	if err != nil {
		return response.NewBadRequest(errors.New("Unknown statistic name"))
	}

	key := popularpost.PreparePopularPostKey(
		query.GroupName,
		channelName,
		statisticName,
		year,
		dateNumber,
	)

	popularPostIds, err := getIds(key, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularPostIds, err = extendPopularPostsIfNeeded(query, popularPostIds, channelName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularPosts, err := models.NewChannelMessage().FetchByIds(popularPostIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	query.Limit = 3
	return response.HandleResultAndError(
		models.NewChannelMessage().BuildMessages(
			query,
			popularPosts,
		),
	)
}

func extendPopularPostsIfNeeded(query *request.Query, popularPostIds []int64, channelName string) ([]int64, error) {
	toBeAddedItemCount := query.Limit - len(popularPostIds)
	if toBeAddedItemCount > 0 {
		c := models.NewChannel()
		channelId, err := c.FetchChannelIdByNameAndGroupName(channelName, query.GroupName)
		if err != nil {
			return popularPostIds, err
		}

		normalPosts, err := models.NewChannelMessageList().FetchMessageIdsByChannelId(channelId, query)
		if err != nil {
			return popularPostIds, err
		}

		for _, normalPostId := range normalPosts {
			exists := false
			for _, popularPostId := range popularPostIds {
				if normalPostId == popularPostId {
					exists = true
					break
				}
			}

			if !exists {
				popularPostIds = append(popularPostIds, normalPostId)
				toBeAddedItemCount--
				if toBeAddedItemCount == 0 {
					break
				}
			}
		}
	}

	return popularPostIds, nil
}
<commit_msg>social; fix error name<commit_after>package popular

import (
	"errors"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/request"
	"socialapi/workers/common/response"
	"socialapi/workers/helper"
	"socialapi/workers/popularpost/popularpost"
	"socialapi/workers/populartopic/populartopic"
	"strconv"
	"time"
)

func getDateNumberAndYear(statisticName string) (int, int, error) {
	now := time.Now().UTC()
	// dateNumber is changing according to the statisticName
	// if it is monthly statistic, it will be month number March->3
	// if it is weekly statistic, it will be week number 48th week -> 48
	// if it is daily statistic, it will the day number of the year e.g last day-> 365+1
	switch statisticName {
	case "daily":
		return now.Year(), now.YearDay(), nil
	case "weekly":
		year, week := now.ISOWeek()
		return year, week, nil
	case "monthly":
		return now.Year(), int(now.Month()), nil
	default:
		return 0, 0, errors.New("Unknown statistic name")
	}
}

func getIds(key string, query *request.Query) ([]int64, error) {
	// limit-1 is important, because redis is using 0 based index
	popularIds := make([]int64, 0)
	listIds, err := helper.MustGetRedisConn().
		SortedSetReverseRange(
		key,
		query.Skip,
		query.Skip+query.Limit-1,
	)

	if err != nil {
		return popularIds, err
	}

	for _, listId := range listIds {
		val, err := strconv.ParseInt(string(listId.([]uint8)), 10, 64)
		if err == nil {
			popularIds = append(popularIds, val)
		}
	}

	return popularIds, nil
}

func ListTopics(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)

	statisticName := u.Query().Get("statisticName")

	year, dateNumber, err := getDateNumberAndYear(statisticName)
	if err != nil {
		return response.NewBadRequest(errors.New("unknown statistic name"))
	}

	key := populartopic.PreparePopularTopicKey(
		query.GroupName,
		statisticName,
		year,
		dateNumber,
	)

	popularTopicIds, err := getIds(key, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularTopicIds, err = extendPopularTopicsIfNeeded(query, popularTopicIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	c := models.NewChannel()
	popularTopics, err := c.FetchByIds(popularTopicIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(
		models.PopulateChannelContainers(
			popularTopics,
			query.AccountId,
		),
	)
}

func extendPopularTopicsIfNeeded(query *request.Query, popularTopics []int64) ([]int64, error) {
	toBeAddedItemCount := query.Limit - len(popularTopics)

	if toBeAddedItemCount > 0 {
		normalChannels, err := fetchMoreChannels(query.GroupName, query.Limit)
		if err != nil {
			return popularTopics, err
		}

		for _, normalChannel := range normalChannels {
			exists := false
			for _, popularTopicId := range popularTopics {
				if normalChannel.Id == popularTopicId {
					exists = true
					break
				}
			}

			if !exists {
				popularTopics = append(popularTopics, normalChannel.Id)
				toBeAddedItemCount--
				if toBeAddedItemCount == 0 {
					break
				}
			}
		}
	}

	return popularTopics, nil
}

func fetchMoreChannels(group string, count int) ([]models.Channel, error) {
	q := request.NewQuery()
	q.GroupName = group
	q.Limit = count
	q.Type = models.Channel_TYPE_TOPIC
	q.SetDefaults()
	c := models.NewChannel()

	return c.List(q)
}

func ListPosts(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query.Type = models.ChannelMessage_TYPE_POST

	statisticName := u.Query().Get("statisticName")
	channelName := u.Query().Get("channelName")

	year, dateNumber, err := getDateNumberAndYear(statisticName)
	if err != nil {
		return response.NewBadRequest(errors.New("Unknown statistic name"))
	}

	key := popularpost.PreparePopularPostKey(
		query.GroupName,
		channelName,
		statisticName,
		year,
		dateNumber,
	)

	popularPostIds, err := getIds(key, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularPostIds, err = extendPopularPostsIfNeeded(query, popularPostIds, channelName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularPosts, err := models.NewChannelMessage().FetchByIds(popularPostIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	query.Limit = 3
	return response.HandleResultAndError(
		models.NewChannelMessage().BuildMessages(
			query,
			popularPosts,
		),
	)
}

func extendPopularPostsIfNeeded(query *request.Query, popularPostIds []int64, channelName string) ([]int64, error) {
	toBeAddedItemCount := query.Limit - len(popularPostIds)
	if toBeAddedItemCount > 0 {
		c := models.NewChannel()
		channelId, err := c.FetchChannelIdByNameAndGroupName(channelName, query.GroupName)
		if err != nil {
			return popularPostIds, err
		}

		normalPosts, err := models.NewChannelMessageList().FetchMessageIdsByChannelId(channelId, query)
		if err != nil {
			return popularPostIds, err
		}

		for _, normalPostId := range normalPosts {
			exists := false
			for _, popularPostId := range popularPostIds {
				if normalPostId == popularPostId {
					exists = true
					break
				}
			}

			if !exists {
				popularPostIds = append(popularPostIds, normalPostId)
				toBeAddedItemCount--
				if toBeAddedItemCount == 0 {
					break
				}
			}
		}
	}

	return popularPostIds, nil
}
<|endoftext|>


<commit_before>package proxy

import (
	"bytes"
	"encoding/json"
	"github.com/fitstar/falcore"
	"github.com/fitstar/falcore/filter"
	"github.com/stuphlabs/pullcord/config"
	"github.com/stuphlabs/pullcord/util"
	"net/http"
)

type PassthruFilter struct {
	Host string
	Port int
	upstreamFilter *filter.Upstream
}

func init() {
	config.RegisterResourceType(
		"passthrufilter",
		func() json.Unmarshaler {
			return new(PassthruFilter)
		},
	)
}

func NewPassthruFilter(host string, port int) (*PassthruFilter) {
	return &PassthruFilter{
		host,
		port,
		filter.NewUpstream(
			filter.NewUpstreamTransport(
				host,
				port,
				0,
				nil,
			),
		),
	}
}

func (f *PassthruFilter) UnmarshalJSON(input []byte) (error) {
	var t struct {
		Host string
		Port int
	}

	dec := json.NewDecoder(bytes.NewReader(input))
	if e := dec.Decode(&t); e != nil {
		return e
	} else {
		f.Host = t.Host
		f.Port = t.Port
		f.upstreamFilter = filter.NewUpstream(
			filter.NewUpstreamTransport(
				f.Host,
				f.Port,
				0,
				nil,
			),
		)

		return nil
	}
}

// NewPassthruFilter generates a Falcore RequestFilter that proxies all requests
// that reach it back and forth to a given host and port.
//
// As such, this is the core of the proxying system.
func (f *PassthruFilter) FilterRequest(
	req *falcore.Request,
) (*http.Response) {
	if f.upstreamFilter == nil {
		return util.InternalServerError.FilterRequest(req)
	} else {
		return f.upstreamFilter.FilterRequest(req)
	}
}

<commit_msg>I realized that we could repair the passthru filter at this point.<commit_after>package proxy

import (
	"bytes"
	"encoding/json"
	"github.com/fitstar/falcore"
	"github.com/fitstar/falcore/filter"
	"github.com/stuphlabs/pullcord/config"
	"net/http"
)

type PassthruFilter struct {
	Host string
	Port int
	upstreamFilter *filter.Upstream
}

func init() {
	config.RegisterResourceType(
		"passthrufilter",
		func() json.Unmarshaler {
			return new(PassthruFilter)
		},
	)
}

func NewPassthruFilter(host string, port int) (*PassthruFilter) {
	return &PassthruFilter{
		host,
		port,
		filter.NewUpstream(
			filter.NewUpstreamTransport(
				host,
				port,
				0,
				nil,
			),
		),
	}
}

func (f *PassthruFilter) UnmarshalJSON(input []byte) (error) {
	var t struct {
		Host string
		Port int
	}

	dec := json.NewDecoder(bytes.NewReader(input))
	if e := dec.Decode(&t); e != nil {
		return e
	} else {
		f.Host = t.Host
		f.Port = t.Port
		f.upstreamFilter = filter.NewUpstream(
			filter.NewUpstreamTransport(
				f.Host,
				f.Port,
				0,
				nil,
			),
		)

		return nil
	}
}

// NewPassthruFilter generates a Falcore RequestFilter that proxies all requests
// that reach it back and forth to a given host and port.
//
// As such, this is the core of the proxying system.
func (f *PassthruFilter) FilterRequest(
	req *falcore.Request,
) (*http.Response) {
	if f.upstreamFilter == nil {
		f.upstreamFilter = filter.NewUpstream(
			filter.NewUpstreamTransport(
				f.Host,
				f.Port,
				0,
				nil,
			),
		)
	}

	return f.upstreamFilter.FilterRequest(req)
}

<|endoftext|>


<commit_before>package cmd

import (
	"strings"

	"go.uber.org/zap"

	"fmt"

	mapset "github.com/deckarep/golang-set"
	"github.com/pkg/errors"
	client "github.com/uphy/pentahotools/client"
	"github.com/uphy/pentahotools/table"
	"gopkg.in/cheggaaa/pb.v1"
)

// ExportUsers exports user list to the file.
func ExportUsers(file string, bar *pb.ProgressBar) error {
	bar.Prefix("List users")
	users, err := Client.ListUsers()
	if err != nil {
		return errors.Wrap(err, "failed to get the list of users.")
	}
	bar.Total = int64(len(*users))

	writer, err := table.NewWriter(file)
	if err != nil {
		return err
	}
	defer writer.Close()
	writer.WriteHeader(&[]string{"User", "Roles"})
	for _, user := range *users {
		bar.Prefix("Roles for " + user)
		roles, err := Client.ListRolesForUser(user)
		if err != nil {
			client.Logger.Warn("Failed to list roles for user.", zap.String("user", user))
			bar.Increment()
			continue
		}
		var filteredRoles []string
		for _, role := range *roles {
			if role == "Authenticated" {
				continue
			}
			filteredRoles = append(filteredRoles, role)
		}
		writer.WriteRow(&[]string{user, strings.Join(filteredRoles, ":")})
		bar.Increment()
	}
	return nil
}

// DeleteUsersInFile delete users in file
func DeleteUsersInFile(file string, deleteHomeDirectory bool, bar *pb.ProgressBar) error {
	userTable, err := NewUserTable(file)
	if err != nil {
		return errors.Wrap(err, "reading file failed")
	}
	defer userTable.Close()
	bar.Prefix("Read file")
	users := []string{}
	for {
		userRow := userTable.Read()
		if userRow == nil {
			break
		}
		users = append(users, userRow.Name)
	}
	if deleteHomeDirectory {
		bar.Total = int64(1 + len(users))
	}
	return DeleteUsers(users, deleteHomeDirectory, bar)
}

// DeleteUsers deletes users
func DeleteUsers(users []string, deleteHomeDirectory bool, bar *pb.ProgressBar) error {
	if deleteHomeDirectory {
		bar.Total = int64(1 + len(users))
	} else {
		bar.Total = 1
	}
	bar.Prefix("Delete users")
	err := Client.DeleteUsers(users...)
	if err != nil {
		return errors.Wrap(err, "failed to delete users")
	}
	bar.Increment()
	if deleteHomeDirectory {
		for _, user := range users {
			homeDirectory := fmt.Sprintf("/home/%s", user)
			bar.Prefix("Delete home directory: " + homeDirectory)
			err = Client.DeleteFiles(homeDirectory)
			if err != nil {
				client.Logger.Warn("Failed to delete home directory.", zap.String("homeDirectory", homeDirectory))
			}
			bar.Increment()
		}
	}
	return nil
}

// CreateUsersInFile registers users from a file
func CreateUsersInFile(file string, bar *pb.ProgressBar) error {
	// getting user names from the repository
	allUsersSetLower, err := listExistingUsers()
	if err != nil {
		return errors.Wrap(err, "failed to get the list of users")
	}
	usersNotInFileLower := allUsersSetLower.Clone()
	// getting role names from the repository
	allRolesSetLower, err := listExistingRoles()
	if err != nil {
		return errors.Wrap(err, "failed to get the list of roles")
	}

	userTable, err := NewUserTable(file)
	if err != nil {
		return errors.Wrap(err, "reading file failed")
	}
	defer userTable.Close()
	bar.Total = int64(userTable.GetCount())

	for {
		userRow := userTable.Read()
		if userRow == nil {
			break
		}
		bar.Prefix("User: " + userRow.Name)
		usersNotInFileLower.Remove(strings.ToLower(userRow.Name))

		currentRolesLower, currentRolesMap, err := listRolesForUser(userRow.Name)
		if err != nil {
			client.Logger.Warn("Failed to list roles for user.", zap.String("user", userRow.Name), zap.Error(err))
			continue
		}

		// create user and change password if needed
		if allUsersSetLower.Contains(strings.ToLower(userRow.Name)) {
			if len(password) > 0 {
				err = Client.UpdatePassword(userRow.Name, userRow.Password)
				if err != nil {
					client.Logger.Warn("Failed to update password.", zap.String("user", userRow.Name), zap.Error(err))
				}
			}
		} else {
			var p = userRow.Password
			if len(p) == 0 {
				p = Client.Password
			}
			err = Client.CreateUser(userRow.Name, p)
			if err != nil {
				client.Logger.Warn("Failed to create user.", zap.String("user", userRow.Name), zap.Error(err))
			}
		}

		// assign roles
		assigningRoles := []string{}
		for _, role := range userRow.Roles {
			roleLower := strings.ToLower(role)
			if !allRolesSetLower.Contains(roleLower) {
				err = Client.CreateRole(role)
				if err != nil {
					client.Logger.Warn("Failed to create role.", zap.String("role", role), zap.Error(err))
				}
			}
			if !currentRolesLower.Contains(roleLower) {
				assigningRoles = append(assigningRoles, role)
			}
		}
		if len(assigningRoles) > 0 {
			err = Client.AssignRolesToUser(userRow.Name, assigningRoles...)
			if err != nil {
				client.Logger.Warn("Failed to assign role to user.", zap.String("user", userRow.Name), zap.Strings("roles", assigningRoles), zap.Error(err))
			}
		}
		// remove roles
		removingRoles := []string{}
		for _, roleLower := range currentRolesLower.ToSlice() {
			roleLowerString := roleLower.(string)
			if !userRow.RoleSet.Contains(roleLower) && roleLowerString != "authenticated" {
				roleOriginal := currentRolesMap[roleLowerString]
				removingRoles = append(removingRoles, roleOriginal)
			}
		}
		if len(removingRoles) > 0 {
			err = Client.RemoveRolesFromUser(userRow.Name, removingRoles...)
			if err != nil {
				client.Logger.Warn("Failed to remove role from user.", zap.String("user", userRow.Name), zap.Strings("roles", assigningRoles), zap.Error(err))
			}
		}

		bar.Increment()
	}
	// Delete users not in the input file
	usersNotInFileLower.Remove("admin")
	if usersNotInFileLower.Cardinality() > 0 {
		bar.Total += int64(usersNotInFileLower.Cardinality())
		for _, user := range usersNotInFileLower.ToSlice() {
			userString := user.(string)
			bar.Prefix("Remove roles: " + userString)
			rolesSetLower, roleMap, err := listRolesForUser(userString)
			if err != nil {
				client.Logger.Warn("Failed to list the roles of the user which doesn't exist in the input file.", zap.String("user", userString), zap.String("file", file))
				bar.Increment()
				continue
			}
			var filteredRoles []string
			for _, role := range rolesSetLower.ToSlice() {
				if role == "authenticated" {
					continue
				}
				filteredRoles = append(filteredRoles, roleMap[role.(string)])
			}
			fmt.Println(filteredRoles)
			err = Client.RemoveRolesFromUser(userString, filteredRoles...)
			if err != nil {
				client.Logger.Warn("Failed to remove roles of the user which doesn't exist in the input file.", zap.String("user", userString), zap.String("roles", rolesSetLower.String()), zap.String("file", file))
				bar.Increment()
				continue
			}
			bar.Increment()
		}
	}
	return nil
}

func listRolesForUser(userName string) (mapset.Set, map[string]string, error) {
	roles, err := Client.ListRolesForUser(userName)
	if err != nil {
		return nil, nil, err
	}
	lowerToOriginalMap := map[string]string{}
	return stringArrayToSetIgnoreCase(roles, lowerToOriginalMap), lowerToOriginalMap, nil
}

func listExistingUsers() (mapset.Set, error) {
	users, err := Client.ListUsers()
	if err != nil {
		return nil, err
	}
	return stringArrayToSetIgnoreCase(users, nil), nil
}

func listExistingRoles() (mapset.Set, error) {
	roles, err := Client.ListAllRoles()
	if err != nil {
		return nil, err
	}
	return stringArrayToSetIgnoreCase(roles, nil), nil
}

func stringArrayToSetIgnoreCase(array *[]string, lowerToOriginalMap map[string]string) mapset.Set {
	set := mapset.NewSet()
	for _, elm := range *array {
		lower := strings.ToLower(elm)
		set.Add(lower)
		if lowerToOriginalMap != nil {
			lowerToOriginalMap[lower] = elm
		}

	}
	return set
}

// NewUserTable read UserTable from a file.
func NewUserTable(file string) (*UserTable, error) {
	var row []string
	row = make([]string, 3) // 3 columns; username, role, password

	// scan table
	tmpTable, err := table.NewReader(file)
	if err != nil {
		return nil, err
	}
	tmpUserTable := UserTable{table: tmpTable, row: row}
	defer tmpUserTable.Close()
	count := 0
	for {
		userRow := tmpUserTable.Read()
		if userRow == nil {
			break
		}
		count++
	}

	// create table
	table, err := table.NewReader(file)
	if err != nil {
		return nil, err
	}
	return &UserTable{table, row, count}, nil
}

// UserTable represents a list of users from table structure files.
type UserTable struct {
	table table.Reader
	row   []string
	count int
}

// GetCount gets the count of UserRows.
func (t *UserTable) GetCount() int {
	return t.count
}

// Read is a function reads a UserRow from the table.
func (t *UserTable) Read() *UserRow {
	for {
		if !t.table.ReadRow(&t.row) {
			return nil
		}
		userName := strings.TrimSpace(t.row[0])
		roles := strings.Split(strings.TrimSpace(t.row[1]), ":")
		roleSet := stringArrayToSetIgnoreCase(&roles, nil)
		password := strings.TrimSpace(t.row[2])
		if len(userName) == 0 {
			continue
		}
		return &UserRow{userName, roleSet, roles, password}
	}
}

// Close closes the source file of the UserTable.
func (t *UserTable) Close() error {
	return t.table.Close()
}

// UserRow represents a row of the UserTable.
type UserRow struct {
	Name     string
	RoleSet  mapset.Set
	Roles    []string
	Password string
}
<commit_msg>fix empty password problem.<commit_after>package cmd

import (
	"strings"

	"go.uber.org/zap"

	"fmt"

	mapset "github.com/deckarep/golang-set"
	"github.com/pkg/errors"
	client "github.com/uphy/pentahotools/client"
	"github.com/uphy/pentahotools/table"
	"gopkg.in/cheggaaa/pb.v1"
)

// ExportUsers exports user list to the file.
func ExportUsers(file string, bar *pb.ProgressBar) error {
	bar.Prefix("List users")
	users, err := Client.ListUsers()
	if err != nil {
		return errors.Wrap(err, "failed to get the list of users.")
	}
	bar.Total = int64(len(*users))

	writer, err := table.NewWriter(file)
	if err != nil {
		return err
	}
	defer writer.Close()
	writer.WriteHeader(&[]string{"User", "Roles"})
	for _, user := range *users {
		bar.Prefix("Roles for " + user)
		roles, err := Client.ListRolesForUser(user)
		if err != nil {
			client.Logger.Warn("Failed to list roles for user.", zap.String("user", user))
			bar.Increment()
			continue
		}
		var filteredRoles []string
		for _, role := range *roles {
			if role == "Authenticated" {
				continue
			}
			filteredRoles = append(filteredRoles, role)
		}
		writer.WriteRow(&[]string{user, strings.Join(filteredRoles, ":")})
		bar.Increment()
	}
	return nil
}

// DeleteUsersInFile delete users in file
func DeleteUsersInFile(file string, deleteHomeDirectory bool, bar *pb.ProgressBar) error {
	userTable, err := NewUserTable(file)
	if err != nil {
		return errors.Wrap(err, "reading file failed")
	}
	defer userTable.Close()
	bar.Prefix("Read file")
	users := []string{}
	for {
		userRow := userTable.Read()
		if userRow == nil {
			break
		}
		users = append(users, userRow.Name)
	}
	if deleteHomeDirectory {
		bar.Total = int64(1 + len(users))
	}
	return DeleteUsers(users, deleteHomeDirectory, bar)
}

// DeleteUsers deletes users
func DeleteUsers(users []string, deleteHomeDirectory bool, bar *pb.ProgressBar) error {
	if deleteHomeDirectory {
		bar.Total = int64(1 + len(users))
	} else {
		bar.Total = 1
	}
	bar.Prefix("Delete users")
	err := Client.DeleteUsers(users...)
	if err != nil {
		return errors.Wrap(err, "failed to delete users")
	}
	bar.Increment()
	if deleteHomeDirectory {
		for _, user := range users {
			homeDirectory := fmt.Sprintf("/home/%s", user)
			bar.Prefix("Delete home directory: " + homeDirectory)
			err = Client.DeleteFiles(homeDirectory)
			if err != nil {
				client.Logger.Warn("Failed to delete home directory.", zap.String("homeDirectory", homeDirectory))
			}
			bar.Increment()
		}
	}
	return nil
}

// CreateUsersInFile registers users from a file
func CreateUsersInFile(file string, bar *pb.ProgressBar) error {
	// getting user names from the repository
	allUsersSetLower, err := listExistingUsers()
	if err != nil {
		return errors.Wrap(err, "failed to get the list of users")
	}
	usersNotInFileLower := allUsersSetLower.Clone()
	// getting role names from the repository
	allRolesSetLower, err := listExistingRoles()
	if err != nil {
		return errors.Wrap(err, "failed to get the list of roles")
	}

	userTable, err := NewUserTable(file)
	if err != nil {
		return errors.Wrap(err, "reading file failed")
	}
	defer userTable.Close()
	bar.Total = int64(userTable.GetCount())

	for {
		userRow := userTable.Read()
		if userRow == nil {
			break
		}
		bar.Prefix("User: " + userRow.Name)
		usersNotInFileLower.Remove(strings.ToLower(userRow.Name))

		currentRolesLower, currentRolesMap, err := listRolesForUser(userRow.Name)
		if err != nil {
			client.Logger.Warn("Failed to list roles for user.", zap.String("user", userRow.Name), zap.Error(err))
			continue
		}

		// create user and change password if needed
		if allUsersSetLower.Contains(strings.ToLower(userRow.Name)) {
			if len(userRow.Password) > 0 {
				err = Client.UpdatePassword(userRow.Name, userRow.Password)
				if err != nil {
					client.Logger.Warn("Failed to update password.", zap.String("user", userRow.Name), zap.Error(err))
				}
			} else {
				client.Logger.Warn("UpdatePassword skipped.  Password column doesn't exist or the password is empty.", zap.String("user", userRow.Name))
			}
		} else {
			var p = userRow.Password
			if len(p) == 0 {
				p = Client.Password
			}
			err = Client.CreateUser(userRow.Name, p)
			if err != nil {
				client.Logger.Warn("Failed to create user.", zap.String("user", userRow.Name), zap.Error(err))
			}
		}

		// assign roles
		assigningRoles := []string{}
		for _, role := range userRow.Roles {
			roleLower := strings.ToLower(role)
			if !allRolesSetLower.Contains(roleLower) {
				err = Client.CreateRole(role)
				if err != nil {
					client.Logger.Warn("Failed to create role.", zap.String("role", role), zap.Error(err))
				}
			}
			if !currentRolesLower.Contains(roleLower) {
				assigningRoles = append(assigningRoles, role)
			}
		}
		if len(assigningRoles) > 0 {
			err = Client.AssignRolesToUser(userRow.Name, assigningRoles...)
			if err != nil {
				client.Logger.Warn("Failed to assign role to user.", zap.String("user", userRow.Name), zap.Strings("roles", assigningRoles), zap.Error(err))
			}
		}
		// remove roles
		removingRoles := []string{}
		for _, roleLower := range currentRolesLower.ToSlice() {
			roleLowerString := roleLower.(string)
			if !userRow.RoleSet.Contains(roleLower) && roleLowerString != "authenticated" {
				roleOriginal := currentRolesMap[roleLowerString]
				if strings.ToLower(userRow.Name) == "admin" && roleLower == "administrator" {
					client.Logger.Warn("User 'admin' should be 'administrator'.")
					continue
				}
				removingRoles = append(removingRoles, roleOriginal)
			}
		}
		if len(removingRoles) > 0 {
			err = Client.RemoveRolesFromUser(userRow.Name, removingRoles...)
			if err != nil {
				client.Logger.Warn("Failed to remove role from user.", zap.String("user", userRow.Name), zap.Strings("roles", assigningRoles), zap.Error(err))
			}
		}

		bar.Increment()
	}
	// Delete users not in the input file
	usersNotInFileLower.Remove("admin")
	if usersNotInFileLower.Cardinality() > 0 {
		bar.Total += int64(usersNotInFileLower.Cardinality())
		for _, user := range usersNotInFileLower.ToSlice() {
			userString := user.(string)
			bar.Prefix("Remove roles: " + userString)
			rolesSetLower, roleMap, err := listRolesForUser(userString)
			if err != nil {
				client.Logger.Warn("Failed to list the roles of the user which doesn't exist in the input file.", zap.String("user", userString), zap.String("file", file))
				bar.Increment()
				continue
			}
			var filteredRoles []string
			for _, role := range rolesSetLower.ToSlice() {
				if role == "authenticated" {
					continue
				}
				filteredRoles = append(filteredRoles, roleMap[role.(string)])
			}
			fmt.Println(filteredRoles)
			err = Client.RemoveRolesFromUser(userString, filteredRoles...)
			if err != nil {
				client.Logger.Warn("Failed to remove roles of the user which doesn't exist in the input file.", zap.String("user", userString), zap.String("roles", rolesSetLower.String()), zap.String("file", file))
				bar.Increment()
				continue
			}
			bar.Increment()
		}
	}
	return nil
}

func listRolesForUser(userName string) (mapset.Set, map[string]string, error) {
	roles, err := Client.ListRolesForUser(userName)
	if err != nil {
		return nil, nil, err
	}
	lowerToOriginalMap := map[string]string{}
	return stringArrayToSetIgnoreCase(roles, lowerToOriginalMap), lowerToOriginalMap, nil
}

func listExistingUsers() (mapset.Set, error) {
	users, err := Client.ListUsers()
	if err != nil {
		return nil, err
	}
	return stringArrayToSetIgnoreCase(users, nil), nil
}

func listExistingRoles() (mapset.Set, error) {
	roles, err := Client.ListAllRoles()
	if err != nil {
		return nil, err
	}
	return stringArrayToSetIgnoreCase(roles, nil), nil
}

func stringArrayToSetIgnoreCase(array *[]string, lowerToOriginalMap map[string]string) mapset.Set {
	set := mapset.NewSet()
	for _, elm := range *array {
		lower := strings.ToLower(elm)
		set.Add(lower)
		if lowerToOriginalMap != nil {
			lowerToOriginalMap[lower] = elm
		}

	}
	return set
}

// NewUserTable read UserTable from a file.
func NewUserTable(file string) (*UserTable, error) {
	var row []string
	row = make([]string, 3) // 3 columns; username, role, password

	// scan table
	tmpTable, err := table.NewReader(file)
	if err != nil {
		return nil, err
	}
	tmpUserTable := UserTable{table: tmpTable, row: row}
	defer tmpUserTable.Close()
	count := 0
	for {
		userRow := tmpUserTable.Read()
		if userRow == nil {
			break
		}
		count++
	}

	// create table
	table, err := table.NewReader(file)
	if err != nil {
		return nil, err
	}
	return &UserTable{table, row, count}, nil
}

// UserTable represents a list of users from table structure files.
type UserTable struct {
	table table.Reader
	row   []string
	count int
}

// GetCount gets the count of UserRows.
func (t *UserTable) GetCount() int {
	return t.count
}

// Read is a function reads a UserRow from the table.
func (t *UserTable) Read() *UserRow {
	for {
		if !t.table.ReadRow(&t.row) {
			return nil
		}
		userName := strings.TrimSpace(t.row[0])
		roles := strings.Split(strings.TrimSpace(t.row[1]), ":")
		roleSet := stringArrayToSetIgnoreCase(&roles, nil)
		password := strings.TrimSpace(t.row[2])
		if len(userName) == 0 {
			continue
		}
		return &UserRow{userName, roleSet, roles, password}
	}
}

// Close closes the source file of the UserTable.
func (t *UserTable) Close() error {
	return t.table.Close()
}

// UserRow represents a row of the UserTable.
type UserRow struct {
	Name     string
	RoleSet  mapset.Set
	Roles    []string
	Password string
}
<|endoftext|>


<commit_before>package popular

import (
	"errors"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/request"
	"socialapi/workers/common/response"
	"socialapi/workers/helper"
	"socialapi/workers/popularpost/popularpost"
	"socialapi/workers/populartopic/populartopic"
	"strconv"
	"time"
)

func getDateNumberAndYear(statisticName string) (int, int, error) {
	now := time.Now().UTC()
	// dateNumber is changing according to the statisticName
	// if it is monthly statistic, it will be month number March->3
	// if it is weekly statistic, it will be week number 48th week -> 48
	// if it is daily statistic, it will the day number of the year e.g last day-> 365+1
	switch statisticName {
	case "daily":
		return now.Year(), now.YearDay(), nil
	case "weekly":
		year, week := now.ISOWeek()
		return year, week, nil
	case "monthly":
		return now.Year(), int(now.Month()), nil
	default:
		return 0, 0, errors.New("Unknown statistic name")
	}
}

func getIds(key string, query *request.Query) ([]int64, error) {
	// limit-1 is important, because redis is using 0 based index
	popularIds := make([]int64, 0)
	listIds, err := helper.MustGetRedisConn().
		SortedSetReverseRange(
		key,
		query.Skip,
		query.Skip+query.Limit-1,
	)

	if err != nil {
		return popularIds, err
	}

	for _, listId := range listIds {
		val, err := strconv.ParseInt(string(listId.([]uint8)), 10, 64)
		if err == nil {
			popularIds = append(popularIds, val)
		}
	}

	return popularIds, nil
}

func ListTopics(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)

	statisticName := u.Query().Get("statisticName")

	year, dateNumber, err := getDateNumberAndYear(statisticName)
	if err != nil {
		return response.NewBadRequest(errors.New("unknown statistic name"))
	}

	key := populartopic.PreparePopularTopicKey(
		query.GroupName,
		statisticName,
		year,
		dateNumber,
	)

	popularTopicIds, err := getIds(key, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularTopicIds, err = extendPopularTopicsIfNeeded(query, popularTopicIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	c := models.NewChannel()
	channelList, err := c.FetchByIds(popularTopicIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	cc := models.NewChannelContainers()
	cc.PopulateWith(channelList, query.AccountId)

	return response.HandleResultAndError(cc, cc.Err())
}

func extendPopularTopicsIfNeeded(query *request.Query, popularTopics []int64) ([]int64, error) {
	toBeAddedItemCount := query.Limit - len(popularTopics)

	if toBeAddedItemCount > 0 {
		normalChannels, err := fetchMoreChannels(query)
		if err != nil {
			return popularTopics, err
		}

		for _, normalChannel := range normalChannels {
			exists := false
			for _, popularTopicId := range popularTopics {
				if normalChannel.Id == popularTopicId {
					exists = true
					break
				}
			}

			if !exists {
				popularTopics = append(popularTopics, normalChannel.Id)
				toBeAddedItemCount--
				if toBeAddedItemCount == 0 {
					break
				}
			}
		}
	}

	return popularTopics, nil
}

func fetchMoreChannels(query *request.Query) ([]models.Channel, error) {
	q := query.Clone()
	q.Type = models.Channel_TYPE_TOPIC

	return models.NewChannel().List(q)
}

func ListPosts(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query.Type = models.ChannelMessage_TYPE_POST

	channelName := u.Query().Get("channelName")
	skip := u.Query().Get("skip")

	i, err := strconv.Atoi(skip)
	if err != nil {
		i = 0
	}

	query.Skip = i

	keyname := popularpost.KeyName{
		GroupName: query.GroupName, ChannelName: channelName,
		Time: time.Now(),
	}
	key := keyname.Weekly()

	popularPostIds, err := getIds(key, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularPosts, err := models.NewChannelMessage().FetchByIds(popularPostIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	query.Limit = 3
	return response.HandleResultAndError(
		models.NewChannelMessage().BuildMessages(
			query,
			popularPosts,
		),
	)
}

func extendPopularPostsIfNeeded(query *request.Query, popularPostIds []int64, channelName string) ([]int64, error) {
	toBeAddedItemCount := query.Limit - len(popularPostIds)
	if toBeAddedItemCount > 0 {
		c := models.NewChannel()
		channelId, err := c.FetchChannelIdByNameAndGroupName(channelName, query.GroupName)
		if err != nil {
			return popularPostIds, err
		}

		normalPosts, err := models.NewChannelMessageList().FetchMessageIdsByChannelId(channelId, query)
		if err != nil {
			return popularPostIds, err
		}

		for _, normalPostId := range normalPosts {
			exists := false
			for _, popularPostId := range popularPostIds {
				if normalPostId == popularPostId {
					exists = true
					break
				}
			}

			if !exists {
				popularPostIds = append(popularPostIds, normalPostId)
				toBeAddedItemCount--
				if toBeAddedItemCount == 0 {
					break
				}
			}
		}
	}

	return popularPostIds, nil
}
<commit_msg>popularpost: remove unused code<commit_after>package popular

import (
	"errors"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/request"
	"socialapi/workers/common/response"
	"socialapi/workers/helper"
	"socialapi/workers/popularpost/popularpost"
	"socialapi/workers/populartopic/populartopic"
	"strconv"
	"time"
)

func getDateNumberAndYear(statisticName string) (int, int, error) {
	now := time.Now().UTC()
	// dateNumber is changing according to the statisticName
	// if it is monthly statistic, it will be month number March->3
	// if it is weekly statistic, it will be week number 48th week -> 48
	// if it is daily statistic, it will the day number of the year e.g last day-> 365+1
	switch statisticName {
	case "daily":
		return now.Year(), now.YearDay(), nil
	case "weekly":
		year, week := now.ISOWeek()
		return year, week, nil
	case "monthly":
		return now.Year(), int(now.Month()), nil
	default:
		return 0, 0, errors.New("Unknown statistic name")
	}
}

func getIds(key string, query *request.Query) ([]int64, error) {
	// limit-1 is important, because redis is using 0 based index
	popularIds := make([]int64, 0)
	listIds, err := helper.MustGetRedisConn().
		SortedSetReverseRange(
		key,
		query.Skip,
		query.Skip+query.Limit-1,
	)

	if err != nil {
		return popularIds, err
	}

	for _, listId := range listIds {
		val, err := strconv.ParseInt(string(listId.([]uint8)), 10, 64)
		if err == nil {
			popularIds = append(popularIds, val)
		}
	}

	return popularIds, nil
}

func ListTopics(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)

	statisticName := u.Query().Get("statisticName")

	year, dateNumber, err := getDateNumberAndYear(statisticName)
	if err != nil {
		return response.NewBadRequest(errors.New("unknown statistic name"))
	}

	key := populartopic.PreparePopularTopicKey(
		query.GroupName,
		statisticName,
		year,
		dateNumber,
	)

	popularTopicIds, err := getIds(key, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularTopicIds, err = extendPopularTopicsIfNeeded(query, popularTopicIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	c := models.NewChannel()
	channelList, err := c.FetchByIds(popularTopicIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	cc := models.NewChannelContainers()
	cc.PopulateWith(channelList, query.AccountId)

	return response.HandleResultAndError(cc, cc.Err())
}

func extendPopularTopicsIfNeeded(query *request.Query, popularTopics []int64) ([]int64, error) {
	toBeAddedItemCount := query.Limit - len(popularTopics)

	if toBeAddedItemCount > 0 {
		normalChannels, err := fetchMoreChannels(query)
		if err != nil {
			return popularTopics, err
		}

		for _, normalChannel := range normalChannels {
			exists := false
			for _, popularTopicId := range popularTopics {
				if normalChannel.Id == popularTopicId {
					exists = true
					break
				}
			}

			if !exists {
				popularTopics = append(popularTopics, normalChannel.Id)
				toBeAddedItemCount--
				if toBeAddedItemCount == 0 {
					break
				}
			}
		}
	}

	return popularTopics, nil
}

func fetchMoreChannels(query *request.Query) ([]models.Channel, error) {
	q := query.Clone()
	q.Type = models.Channel_TYPE_TOPIC

	return models.NewChannel().List(q)
}

func ListPosts(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query.Type = models.ChannelMessage_TYPE_POST

	channelName := u.Query().Get("channelName")
	skip := u.Query().Get("skip")

	i, err := strconv.Atoi(skip)
	if err != nil {
		i = 0
	}

	query.Skip = i

	keyname := popularpost.KeyName{
		GroupName: query.GroupName, ChannelName: channelName,
		Time: time.Now(),
	}
	key := keyname.Weekly()

	popularPostIds, err := getIds(key, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	popularPosts, err := models.NewChannelMessage().FetchByIds(popularPostIds)
	if err != nil {
		return response.NewBadRequest(err)
	}

	query.Limit = 3
	return response.HandleResultAndError(
		models.NewChannelMessage().BuildMessages(
			query,
			popularPosts,
		),
	)
}
<|endoftext|>


<commit_before>/*
Copyright 2011 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"sync"

	"camlistore.org/pkg/blobserver/dir"
	"camlistore.org/pkg/client"
	"camlistore.org/pkg/cmdmain"
	"camlistore.org/pkg/httputil"
	"camlistore.org/pkg/syncutil"
)

const buffered = 16 // arbitrary

var (
	flagProxyLocal = false
	flagHTTP       = flag.Bool("verbose_http", false, "show HTTP request summaries")
	flagHaveCache  = true
	flagBlobDir    = flag.String("blobdir", "", "If non-empty, the local directory to put blobs, instead of sending them over the network.")
)

var (
	uploaderOnce sync.Once
	uploader     *Uploader // initialized by getUploader
)

func init() {
	if debug, _ := strconv.ParseBool(os.Getenv("CAMLI_DEBUG")); debug {
		flag.BoolVar(&flagProxyLocal, "proxy_local", false, "If true, the HTTP_PROXY environment is also used for localhost requests. This can be helpful during debugging.")
		flag.BoolVar(&flagHaveCache, "havecache", true, "Use the 'have cache', a cache keeping track of what blobs the remote server should already have from previous uploads.")
	}
	cmdmain.ExtraFlagRegistration = func() {
		client.AddFlags()
	}
	cmdmain.PreExit = func() {
		if up := uploader; up != nil {
			up.Close()
			stats := up.Stats()
			log.Printf("Client stats: %s", stats.String())
			log.Printf("  #HTTP reqs: %d", up.transport.Requests())
		}
	}
}

func getUploader() *Uploader {
	uploaderOnce.Do(initUploader)
	return uploader
}

func initUploader() {
	up := newUploader()
	if flagHaveCache && *flagBlobDir == "" {
		gen, err := up.StorageGeneration()
		if err != nil {
			log.Printf("WARNING: not using local server inventory cache; failed to retrieve server's storage generation: %v", err)
		} else {
			up.haveCache = NewKvHaveCache(gen)
			up.Client.SetHaveCache(up.haveCache)
		}
	}
	uploader = up
}

func handleResult(what string, pr *client.PutResult, err error) error {
	if err != nil {
		log.Printf("Error putting %s: %s", what, err)
		cmdmain.ExitWithFailure = true
		return err
	}
	fmt.Println(pr.BlobRef.String())
	return nil
}

func getenvEitherCase(k string) string {
	if v := os.Getenv(strings.ToUpper(k)); v != "" {
		return v
	}
	return os.Getenv(strings.ToLower(k))
}

// proxyFromEnvironment is similar to http.ProxyFromEnvironment but it skips
// $NO_PROXY blacklist so it proxies every requests, including localhost
// requests.
func proxyFromEnvironment(req *http.Request) (*url.URL, error) {
	proxy := getenvEitherCase("HTTP_PROXY")
	if proxy == "" {
		return nil, nil
	}
	proxyURL, err := url.Parse(proxy)
	if err != nil || proxyURL.Scheme == "" {
		if u, err := url.Parse("http://" + proxy); err == nil {
			proxyURL = u
			err = nil
		}
	}
	if err != nil {
		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
	}
	return proxyURL, nil
}

func newUploader() *Uploader {
	var cc *client.Client
	if d := *flagBlobDir; d != "" {
		ss, err := dir.New(d)
		if err != nil {
			log.Fatalf("Error using dir %s as storage: %v", d, err)
		}
		cc = client.NewStorageClient(ss)
	} else {
		cc = client.NewOrFail()
	}
	if !*cmdmain.FlagVerbose {
		cc.SetLogger(nil)
	}

	proxy := http.ProxyFromEnvironment
	if flagProxyLocal {
		proxy = proxyFromEnvironment
	}
	tr := cc.TransportForConfig(
		&client.TransportConfig{
			Proxy:   proxy,
			Verbose: *flagHTTP,
		})
	httpStats, _ := tr.(*httputil.StatsTransport)
	cc.SetHTTPClient(&http.Client{Transport: tr})

	pwd, err := os.Getwd()
	if err != nil {
		log.Fatalf("os.Getwd: %v", err)
	}

	return &Uploader{
		Client:    cc,
		transport: httpStats,
		pwd:       pwd,
		fdGate:    syncutil.NewGate(100), // gate things that waste fds, assuming a low system limit
	}
}

func main() {
	cmdmain.Main()
}
<commit_msg>camput: move debug flag registration to its own func, for use by tests later.<commit_after>/*
Copyright 2011 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"sync"

	"camlistore.org/pkg/blobserver/dir"
	"camlistore.org/pkg/client"
	"camlistore.org/pkg/cmdmain"
	"camlistore.org/pkg/httputil"
	"camlistore.org/pkg/syncutil"
)

const buffered = 16 // arbitrary

var (
	flagProxyLocal = false
	flagHTTP       = flag.Bool("verbose_http", false, "show HTTP request summaries")
	flagHaveCache  = true
	flagBlobDir    = flag.String("blobdir", "", "If non-empty, the local directory to put blobs, instead of sending them over the network.")
)

var (
	uploaderOnce sync.Once
	uploader     *Uploader // initialized by getUploader
)

var debugFlagOnce sync.Once

func registerDebugFlags() {
	flag.BoolVar(&flagProxyLocal, "proxy_local", false, "If true, the HTTP_PROXY environment is also used for localhost requests. This can be helpful during debugging.")
	flag.BoolVar(&flagHaveCache, "havecache", true, "Use the 'have cache', a cache keeping track of what blobs the remote server should already have from previous uploads.")
}

func init() {
	if debug, _ := strconv.ParseBool(os.Getenv("CAMLI_DEBUG")); debug {
		debugFlagOnce.Do(registerDebugFlags)
	}
	cmdmain.ExtraFlagRegistration = func() {
		client.AddFlags()
	}
	cmdmain.PreExit = func() {
		if up := uploader; up != nil {
			up.Close()
			stats := up.Stats()
			log.Printf("Client stats: %s", stats.String())
			log.Printf("  #HTTP reqs: %d", up.transport.Requests())
		}
	}
}

func getUploader() *Uploader {
	uploaderOnce.Do(initUploader)
	return uploader
}

func initUploader() {
	up := newUploader()
	if flagHaveCache && *flagBlobDir == "" {
		gen, err := up.StorageGeneration()
		if err != nil {
			log.Printf("WARNING: not using local server inventory cache; failed to retrieve server's storage generation: %v", err)
		} else {
			up.haveCache = NewKvHaveCache(gen)
			up.Client.SetHaveCache(up.haveCache)
		}
	}
	uploader = up
}

func handleResult(what string, pr *client.PutResult, err error) error {
	if err != nil {
		log.Printf("Error putting %s: %s", what, err)
		cmdmain.ExitWithFailure = true
		return err
	}
	fmt.Println(pr.BlobRef.String())
	return nil
}

func getenvEitherCase(k string) string {
	if v := os.Getenv(strings.ToUpper(k)); v != "" {
		return v
	}
	return os.Getenv(strings.ToLower(k))
}

// proxyFromEnvironment is similar to http.ProxyFromEnvironment but it skips
// $NO_PROXY blacklist so it proxies every requests, including localhost
// requests.
func proxyFromEnvironment(req *http.Request) (*url.URL, error) {
	proxy := getenvEitherCase("HTTP_PROXY")
	if proxy == "" {
		return nil, nil
	}
	proxyURL, err := url.Parse(proxy)
	if err != nil || proxyURL.Scheme == "" {
		if u, err := url.Parse("http://" + proxy); err == nil {
			proxyURL = u
			err = nil
		}
	}
	if err != nil {
		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
	}
	return proxyURL, nil
}

func newUploader() *Uploader {
	var cc *client.Client
	var httpStats *httputil.StatsTransport
	if d := *flagBlobDir; d != "" {
		ss, err := dir.New(d)
		if err != nil {
			log.Fatalf("Error using dir %s as storage: %v", d, err)
		}
		cc = client.NewStorageClient(ss)
	} else {
		cc = client.NewOrFail()
		proxy := http.ProxyFromEnvironment
		if flagProxyLocal {
			proxy = proxyFromEnvironment
		}
		tr := cc.TransportForConfig(
			&client.TransportConfig{
				Proxy:   proxy,
				Verbose: *flagHTTP,
			})
		httpStats, _ = tr.(*httputil.StatsTransport)
		cc.SetHTTPClient(&http.Client{Transport: tr})
	}
	if !*cmdmain.FlagVerbose {
		cc.SetLogger(nil)
	}

	pwd, err := os.Getwd()
	if err != nil {
		log.Fatalf("os.Getwd: %v", err)
	}

	return &Uploader{
		Client:    cc,
		transport: httpStats,
		pwd:       pwd,
		fdGate:    syncutil.NewGate(100), // gate things that waste fds, assuming a low system limit
	}
}

func main() {
	cmdmain.Main()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"koding/tools/config"
	socialconfig "socialapi/config"
	followingfeed "socialapi/workers/followingfeed/lib"
	"socialapi/workers/helper"

	"github.com/jinzhu/gorm"
	"github.com/koding/bongo"
	"github.com/koding/logging"
	"github.com/koding/worker"
	"github.com/streadway/amqp"
)

var (
	Bongo       *bongo.Bongo
	log         logging.Logger
	conf        *config.Config
	flagProfile = flag.String("c", "", "Configuration profile from file")
	flagDebug   = flag.Bool("d", false, "Debug mode")
	handler     *followingfeed.FollowingFeedController
)

func main() {
	flag.Parse()
	if *flagProfile == "" {
		log.Fatal("Please define config file with -c", "")
	}

	conf = config.MustConfig(*flagProfile)

	// create logger for our package
	log = helper.CreateLogger("TopicFeedWorker", *flagDebug)

	// panics if not successful
	Bongo = helper.MustInitBongo(conf, log)
	// do not forgot to close the bongo connection
	defer Bongo.Close()

	handler = followingfeed.NewFollowingFeedController(log)

	listener := worker.NewListener("FollowingFeed", socialconfig.EventExchangeName)
	// blocking
	// listen for events
	listener.Listen(helper.NewRabbitMQ(conf, log), startHandler)
	// close consumer
	defer listener.Close()
}

func startHandler() func(delivery amqp.Delivery) {
	log.Info("Worker Started to Consume")
	return func(delivery amqp.Delivery) {
		err := handler.HandleEvent(delivery.Type, delivery.Body)
		switch err {
		case nil:
			delivery.Ack(false)
		case followingfeed.HandlerNotFoundErr:
			log.Notice("unknown event type (%s) recieved, \n deleting message from RMQ", delivery.Type)
			delivery.Ack(false)
		case gorm.RecordNotFound:
			log.Warning("Record not found in our db (%s) recieved, \n deleting message from RMQ", string(delivery.Body))
			delivery.Ack(false)
		default:
			// add proper error handling
			// instead of puttting message back to same queue, it is better
			// to put it to another maintenance queue/exchange
			log.Error("an error occured %s, \n putting message back to queue", err)
			// multiple false
			// reque true
			delivery.Nack(false, true)
		}
	}
}
<commit_msg>social: change koding/config to social/config<commit_after>package main

import (
	"flag"
	"socialapi/config"
	followingfeed "socialapi/workers/followingfeed/lib"
	"socialapi/workers/helper"

	"github.com/jinzhu/gorm"
	"github.com/koding/bongo"
	"github.com/koding/logging"
	"github.com/koding/worker"
	"github.com/streadway/amqp"
)

var (
	Bongo       *bongo.Bongo
	log         logging.Logger
	conf        *config.Config
	flagProfile = flag.String("c", "", "Configuration profile from file")
	flagDebug   = flag.Bool("d", false, "Debug mode")
	handler     *followingfeed.FollowingFeedController
)

func main() {
	flag.Parse()
	if *flagProfile == "" {
		log.Fatal("Please define config file with -c", "")
	}

	conf = config.Read(*flagProfile)

	// create logger for our package
	log = helper.CreateLogger("TopicFeedWorker", *flagDebug)

	// panics if not successful
	Bongo = helper.MustInitBongo(conf, log)
	// do not forgot to close the bongo connection
	defer Bongo.Close()

	handler = followingfeed.NewFollowingFeedController(log)

	listener := worker.NewListener("FollowingFeed", conf.EventExchangeName)
	// blocking
	// listen for events
	listener.Listen(helper.NewRabbitMQ(conf, log), startHandler)
	// close consumer
	defer listener.Close()
}

func startHandler() func(delivery amqp.Delivery) {
	log.Info("Worker Started to Consume")
	return func(delivery amqp.Delivery) {
		err := handler.HandleEvent(delivery.Type, delivery.Body)
		switch err {
		case nil:
			delivery.Ack(false)
		case followingfeed.HandlerNotFoundErr:
			log.Notice("unknown event type (%s) recieved, \n deleting message from RMQ", delivery.Type)
			delivery.Ack(false)
		case gorm.RecordNotFound:
			log.Warning("Record not found in our db (%s) recieved, \n deleting message from RMQ", string(delivery.Body))
			delivery.Ack(false)
		default:
			// add proper error handling
			// instead of puttting message back to same queue, it is better
			// to put it to another maintenance queue/exchange
			log.Error("an error occured %s, \n putting message back to queue", err)
			// multiple false
			// reque true
			delivery.Nack(false, true)
		}
	}
}
<|endoftext|>