<commit_before>package bot

import "github.com/nlopes/slack"
import "strings"
import "math/rand"

func postResponse(bot *BaseBot, channel string, emoji string, name string, response string) {
	bot.PostMessage(channel, response, slack.PostMessageParameters{
		AsUser:    false,
		IconEmoji: emoji,
		Username:  name,
	})
}

func randomResponse(bot *BaseBot, channel string, emoji string, name string, responses []string) {
	response := responses[rand.Intn(len(responses))]
	postResponse(bot, channel, emoji, name, response)
}

var (
	anduinresp []string = []string{
		"안녕하세요!",
		"감사합니다!",
		"이게... 아닌데...",
		"빛이 당신을 태울 것입니다!",
		"정말 잘하셨어요.",
		"죄송합니다.",
	}
	yayoiresp []string = []string{
		"ζ*'ヮ')ζ 웃우─!",
		"ζ° ͜ʖ ͡° ζ/ 웃우─! 프로듀서 로우탓-치!",
		"ζ*'ヮ')ζ / 프로듀사 하이탓-치! 이예이!",
		"ζ*'ヮ')ζ 오늘은 숙주나물 축제에요!",
		"ζ*'ヮ')ζ 저기, 타카츠키 야요이, 14세입니다. 저, 집이 빈곤해서, 저도 무언가 할 수 있는게 없을까 생각해서 아이돌이 되보려고 했습니다. 잘 부탁드립니다! 이에이!",
		"ζ*'ヮ')ζ타카츠키 야요이, 14세입니다-! 저, 건강이 장점이니까, 아무리 많은 일이어도 걱정 없어요. 그러니까 척척 일해나가서, 같이 톱 아이돌을 목표해주세요. 에헤헤♪",
		"ζ*'ヮ')ζ 타카츠키 야요이에요! 조금이라도 집안에 보탬이 되지 않을까 해서 아이돌을 시작했어요. 저, 건강과 의욕만큼은 분명하니까, 프로듀스 잘 부탁드려요! 에헤헷♪",
		"ζ*'ヮ')ζ 최근 상점가에서 쇼핑을 하고 있으면, 누가 말을 거는 일이 많아졌어요-. 이것도, 아이돌로서 유명해졌다는 걸까나! 웃우-, 프로듀서 감사합니다-!",
		"ζ*'ヮ')ζ 수영복을 입으면, 청소로 젖어도 갈아입지 않아도 괜찮아서 득일까나! 프로듀서도 수영복으로 갈아입어서, 같이 놀지 않을래요? 아, 물론 청소를 끝내는 것이 우선이에요-!",
		"ζ*'ヮ')ζ 이 옷, 팔랑팔랑~ 둥실둥실~ 거려서, 왠지 제가 아닌 것 같아요-. 조금 쑥스러울지도! 에헤헤.... 프로듀서, 저, 팔랑팔랑하고 둥실둥실 거리는 거, 어울리나요-?",
		"ζ*'ヮ')ζ 프, 프로듀서. 미아 오리씨들이 저를 따라버려서, 모두가 뒤를 쫒아 오고 있어요-! 어...어쩌면 좋죠-! 하앗, 저기, 모두? 저는 엄마가 아니에요-!",
		"ζ*'ヮ')ζ 프로듀서, 봐주세요-! 오리씨와 오리 엄마와 개구리씨와 돼지씨와... 그리고... 어쨌든, 잔뜩 잔뜩 있는 모두와 노래할게요-♪ 에헤헷, 귀여워요-!",
		"ζ*'ヮ')ζ 에헤헷, 늑대씨 의상이에요-! 커흠-, 먹어버릴테다-! ...앗, 사실은 먹지 않을테니까 무서워하지 말아주세요~! 상냥한 늑대씨가 되고 싶으니깐요!",
	}
	guguresp []string = []string{
		"구구구",
		"@scarlet9",
	}
)

func specialResponses(bot *BaseBot, e *slack.MessageEvent) {
	// ignore all bot_message
	if e.SubType == "bot_message" {
		return
	}

	if strings.Contains(e.Text, "72") || strings.Contains(e.Text, "치하야") || strings.Contains(e.Text, "큿") {
		postResponse(bot, e.Channel, ":kutt:", "치하야", "큿")
	}
	if strings.Contains(e.Text, "크킄") {
		postResponse(bot, e.Channel, ":chuni:", "Dark Flame Master", "흐콰한다")
	}
	if strings.Contains(e.Text, "안두인") {
		randomResponse(bot, e.Channel, ":anduin:", "안두인", anduinresp)
	}
	if strings.Contains(e.Text, "웃우") {
		randomResponse(bot, e.Channel, ":yayoyee:", "타카츠키 야요이", yayoiresp)
	}
	if strings.Contains(e.Text, "혼란하다 혼란해") {
		postResponse(bot, e.Channel, ":honse:", "혼세마왕", "혼세혼세")
	}
	if strings.Contains(e.Text, "비둘기") {
		randomResponse(bot, e.Channel, ":gugu:", "비둘기", guguresp)
	}
}
<commit_msg>bot message parse<commit_after>package bot

import "github.com/nlopes/slack"
import "strings"
import "math/rand"

func postResponse(bot *BaseBot, channel string, emoji string, name string, response string) {
	bot.PostMessage(channel, response, slack.PostMessageParameters{
		AsUser:    false,
		IconEmoji: emoji,
		Username:  name,
		Parse:     "full",
	})
}

func randomResponse(bot *BaseBot, channel string, emoji string, name string, responses []string) {
	response := responses[rand.Intn(len(responses))]
	postResponse(bot, channel, emoji, name, response)
}

var (
	anduinresp []string = []string{
		"안녕하세요!",
		"감사합니다!",
		"이게... 아닌데...",
		"빛이 당신을 태울 것입니다!",
		"정말 잘하셨어요.",
		"죄송합니다.",
	}
	yayoiresp []string = []string{
		"ζ*'ヮ')ζ 웃우─!",
		"ζ° ͜ʖ ͡° ζ/ 웃우─! 프로듀서 로우탓-치!",
		"ζ*'ヮ')ζ / 프로듀사 하이탓-치! 이예이!",
		"ζ*'ヮ')ζ 오늘은 숙주나물 축제에요!",
		"ζ*'ヮ')ζ 저기, 타카츠키 야요이, 14세입니다. 저, 집이 빈곤해서, 저도 무언가 할 수 있는게 없을까 생각해서 아이돌이 되보려고 했습니다. 잘 부탁드립니다! 이에이!",
		"ζ*'ヮ')ζ타카츠키 야요이, 14세입니다-! 저, 건강이 장점이니까, 아무리 많은 일이어도 걱정 없어요. 그러니까 척척 일해나가서, 같이 톱 아이돌을 목표해주세요. 에헤헤♪",
		"ζ*'ヮ')ζ 타카츠키 야요이에요! 조금이라도 집안에 보탬이 되지 않을까 해서 아이돌을 시작했어요. 저, 건강과 의욕만큼은 분명하니까, 프로듀스 잘 부탁드려요! 에헤헷♪",
		"ζ*'ヮ')ζ 최근 상점가에서 쇼핑을 하고 있으면, 누가 말을 거는 일이 많아졌어요-. 이것도, 아이돌로서 유명해졌다는 걸까나! 웃우-, 프로듀서 감사합니다-!",
		"ζ*'ヮ')ζ 수영복을 입으면, 청소로 젖어도 갈아입지 않아도 괜찮아서 득일까나! 프로듀서도 수영복으로 갈아입어서, 같이 놀지 않을래요? 아, 물론 청소를 끝내는 것이 우선이에요-!",
		"ζ*'ヮ')ζ 이 옷, 팔랑팔랑~ 둥실둥실~ 거려서, 왠지 제가 아닌 것 같아요-. 조금 쑥스러울지도! 에헤헤.... 프로듀서, 저, 팔랑팔랑하고 둥실둥실 거리는 거, 어울리나요-?",
		"ζ*'ヮ')ζ 프, 프로듀서. 미아 오리씨들이 저를 따라버려서, 모두가 뒤를 쫒아 오고 있어요-! 어...어쩌면 좋죠-! 하앗, 저기, 모두? 저는 엄마가 아니에요-!",
		"ζ*'ヮ')ζ 프로듀서, 봐주세요-! 오리씨와 오리 엄마와 개구리씨와 돼지씨와... 그리고... 어쨌든, 잔뜩 잔뜩 있는 모두와 노래할게요-♪ 에헤헷, 귀여워요-!",
		"ζ*'ヮ')ζ 에헤헷, 늑대씨 의상이에요-! 커흠-, 먹어버릴테다-! ...앗, 사실은 먹지 않을테니까 무서워하지 말아주세요~! 상냥한 늑대씨가 되고 싶으니깐요!",
	}
	guguresp []string = []string{
		"구구구",
		"@scarlet9",
	}
)

func specialResponses(bot *BaseBot, e *slack.MessageEvent) {
	// ignore all bot_message
	if e.SubType == "bot_message" {
		return
	}

	if strings.Contains(e.Text, "72") || strings.Contains(e.Text, "치하야") || strings.Contains(e.Text, "큿") {
		postResponse(bot, e.Channel, ":kutt:", "치하야", "큿")
	}
	if strings.Contains(e.Text, "크킄") {
		postResponse(bot, e.Channel, ":chuni:", "Dark Flame Master", "흐콰한다")
	}
	if strings.Contains(e.Text, "안두인") {
		randomResponse(bot, e.Channel, ":anduin:", "안두인", anduinresp)
	}
	if strings.Contains(e.Text, "웃우") {
		randomResponse(bot, e.Channel, ":yayoyee:", "타카츠키 야요이", yayoiresp)
	}
	if strings.Contains(e.Text, "혼란하다 혼란해") {
		postResponse(bot, e.Channel, ":honse:", "혼세마왕", "혼세혼세")
	}
	if strings.Contains(e.Text, "비둘기") {
		randomResponse(bot, e.Channel, ":gugu:", "비둘기", guguresp)
	}
}
<|endoftext|>


<commit_before>package uploads

import (
	"time"

	"github.com/materials-commons/mcstore/pkg/app"
	"github.com/materials-commons/mcstore/pkg/db"
	"github.com/materials-commons/mcstore/pkg/db/dai"
	"github.com/materials-commons/mcstore/pkg/db/schema"
	"github.com/materials-commons/mcstore/pkg/domain"
)

// A CreateRequest requests a new upload id be created for
// the given parameters.
type CreateRequest struct {
	User        string
	DirectoryID string
	ProjectID   string
	Host        string
	Birthtime   time.Time
}

// CreateService creates new upload requests
type CreateService interface {
	Create(req CreateRequest) (*schema.Upload, error)
}

// createService implements the CreateService interface using
// the dai services.
type createService struct {
	dirs     dai.Dirs
	projects dai.Projects
	uploads  dai.Uploads
	access   domain.Access
}

// NewCreateService creates a new createService. It uses db.RSessionMust() to get
// a session to connect to the database. It will panic if it cannot connect to
// the database.
func NewCreateService() *createService {
	session := db.RSessionMust()
	access := domain.NewAccess(dai.NewRGroups(session), dai.NewRFiles(session), dai.NewRUsers(session))
	return &createService{
		dirs:     dai.NewRDirs(session),
		projects: dai.NewRProjects(session),
		uploads:  dai.NewRUploads(session),
		access:   access,
	}
}

// NewCreateServiceFrom creates a new instance of the createService using the passed in dai and access parameters.
func NewCreateServiceFrom(dirs dai.Dirs, projects dai.Projects, uploads dai.Uploads, access domain.Access) *createService {
	return &createService{
		dirs:     dirs,
		projects: projects,
		uploads:  uploads,
		access:   access,
	}
}

// Create will create a new Upload request. It validates and checks access to the given project
// and directory.
func (s *createService) Create(req CreateRequest) (*schema.Upload, error) {
	proj, err := s.getProj(req.ProjectID, req.User)
	if err != nil {
		return nil, err
	}

	dir, err := s.getDir(req.DirectoryID, proj.ID, req.User)
	if err != nil {
		return nil, err
	}

	upload := schema.CUpload().
		Owner(req.User).
		Project(req.ProjectID, proj.Name).
		Directory(req.DirectoryID, dir.Name).
		Host(req.Host).
		Create()
	return s.uploads.Insert(&upload)
}

// getProj retrieves the project with the given projectID. It checks that the
// given user has access to that project.
func (s *createService) getProj(projectID, user string) (*schema.Project, error) {
	project, err := s.projects.ByID(projectID)
	switch {
	case err != nil:
		return nil, err
	case !s.access.AllowedByOwner(project.Owner, user):
		return nil, app.ErrNoAccess
	default:
		return project, nil
	}
}

// getDir retrieves the directory with the given directoryID. It checks access to the
// directory and validates that the directory exists in the given project.
func (s *createService) getDir(directoryID, projectID, user string) (*schema.Directory, error) {
	dir, err := s.dirs.ByID(directoryID)
	switch {
	case err != nil:
		return nil, err
	case !s.access.AllowedByOwner(dir.Owner, user):
		return nil, app.ErrNoAccess
	case !s.projects.HasDirectory(projectID, directoryID):
		return nil, app.ErrInvalid
	default:
		return dir, nil
	}
}
<commit_msg>Add FileName, FileSize and RemoteCtime to the service.<commit_after>package uploads

import (
	"time"

	"github.com/materials-commons/mcstore/pkg/app"
	"github.com/materials-commons/mcstore/pkg/db"
	"github.com/materials-commons/mcstore/pkg/db/dai"
	"github.com/materials-commons/mcstore/pkg/db/schema"
	"github.com/materials-commons/mcstore/pkg/domain"
)

// A CreateRequest requests a new upload id be created for
// the given parameters.
type CreateRequest struct {
	User        string
	DirectoryID string
	ProjectID   string
	FileName    string
	FileSize    int64
	FileCTime   time.Time
	Host        string
	Birthtime   time.Time
}

// CreateService creates new upload requests
type CreateService interface {
	Create(req CreateRequest) (*schema.Upload, error)
}

// createService implements the CreateService interface using
// the dai services.
type createService struct {
	dirs     dai.Dirs
	projects dai.Projects
	uploads  dai.Uploads
	access   domain.Access
}

// NewCreateService creates a new createService. It uses db.RSessionMust() to get
// a session to connect to the database. It will panic if it cannot connect to
// the database.
func NewCreateService() *createService {
	session := db.RSessionMust()
	access := domain.NewAccess(dai.NewRGroups(session), dai.NewRFiles(session), dai.NewRUsers(session))
	return &createService{
		dirs:     dai.NewRDirs(session),
		projects: dai.NewRProjects(session),
		uploads:  dai.NewRUploads(session),
		access:   access,
	}
}

// NewCreateServiceFrom creates a new instance of the createService using the passed in dai and access parameters.
func NewCreateServiceFrom(dirs dai.Dirs, projects dai.Projects, uploads dai.Uploads, access domain.Access) *createService {
	return &createService{
		dirs:     dirs,
		projects: projects,
		uploads:  uploads,
		access:   access,
	}
}

// Create will create a new Upload request. It validates and checks access to the given project
// and directory.
func (s *createService) Create(req CreateRequest) (*schema.Upload, error) {
	proj, err := s.getProj(req.ProjectID, req.User)
	if err != nil {
		return nil, err
	}

	dir, err := s.getDir(req.DirectoryID, proj.ID, req.User)
	if err != nil {
		return nil, err
	}

	upload := schema.CUpload().
		Owner(req.User).
		Project(req.ProjectID, proj.Name).
		Directory(req.DirectoryID, dir.Name).
		Host(req.Host).
		FName(req.FileName).
		FSize(req.FileSize).
		FRemoteCTime(req.FileCTime).
		Create()
	return s.uploads.Insert(&upload)
}

// getProj retrieves the project with the given projectID. It checks that the
// given user has access to that project.
func (s *createService) getProj(projectID, user string) (*schema.Project, error) {
	project, err := s.projects.ByID(projectID)
	switch {
	case err != nil:
		return nil, err
	case !s.access.AllowedByOwner(project.Owner, user):
		return nil, app.ErrNoAccess
	default:
		return project, nil
	}
}

// getDir retrieves the directory with the given directoryID. It checks access to the
// directory and validates that the directory exists in the given project.
func (s *createService) getDir(directoryID, projectID, user string) (*schema.Directory, error) {
	dir, err := s.dirs.ByID(directoryID)
	switch {
	case err != nil:
		return nil, err
	case !s.access.AllowedByOwner(dir.Owner, user):
		return nil, app.ErrNoAccess
	case !s.projects.HasDirectory(projectID, directoryID):
		return nil, app.ErrInvalid
	default:
		return dir, nil
	}
}
<|endoftext|>


<commit_before>package newrelic_platform_go

import (
	"log"
)

type ComponentData interface{}
type IComponent interface {
	Harvest(plugin INewrelicPlugin) ComponentData
	SetDuration(duration int)
	AddMetrica(model IMetrica)
	ClearSentData()
}

type PluginComponent struct {
	Name          string                  `json:"name"`
	GUID          string                  `json:"guid"`
	Duration      int                     `json:"duration"`
	Metrics       map[string]MetricaValue `json:"metrics"`
	MetricaModels []IMetrica              `json:"-"`
}

func NewPluginComponent(name string, guid string) *PluginComponent {
	c := &PluginComponent{
		Name: name,
		GUID: guid,
	}
	return c
}

func (component *PluginComponent) AddMetrica(model IMetrica) {
	component.MetricaModels = append(component.MetricaModels, model)
}

func (component *PluginComponent) ClearSentData() {
	component.Metrics = nil
}

func (component *PluginComponent) SetDuration(duration int) {
	component.Duration = duration
}

func (component *PluginComponent) Harvest(plugin INewrelicPlugin) ComponentData {
	component.Metrics = make(map[string]MetricaValue, len(component.MetricaModels))
	for i := 0; i < len(component.MetricaModels); i++ {
		model := component.MetricaModels[i]
		metricaKey := plugin.GetMetricaKey(model)

		if newValue, err := model.GetValue(); err == nil {
			if existMetric, ok := component.Metrics[metricaKey]; ok {
				if floatExistVal, ok := existMetric.(float64); ok {
					component.Metrics[metricaKey] = NewAggregatedMetricaValue(floatExistVal, newValue)
				} else if aggregatedValue, ok := existMetric.(*AggregatedMetricaValue); ok {
					aggregatedValue.Aggregate(newValue)
				} else {
					panic("Invalid type in metrica value")
				}
			} else {
				component.Metrics[metricaKey] = newValue
			}
		} else {
			log.Printf("Can not get metrica: %v, got error:%#v", model.GetName(), err)
		}
	}
	return component
}
<commit_msg>Update component.go<commit_after>package newrelic_platform_go

import (
	"log"
	"math"
)

type ComponentData interface{}
type IComponent interface {
	Harvest(plugin INewrelicPlugin) ComponentData
	SetDuration(duration int)
	AddMetrica(model IMetrica)
	ClearSentData()
}

type PluginComponent struct {
	Name          string                  `json:"name"`
	GUID          string                  `json:"guid"`
	Duration      int                     `json:"duration"`
	Metrics       map[string]MetricaValue `json:"metrics"`
	MetricaModels []IMetrica              `json:"-"`
}

func NewPluginComponent(name string, guid string) *PluginComponent {
	c := &PluginComponent{
		Name: name,
		GUID: guid,
	}
	return c
}

func (component *PluginComponent) AddMetrica(model IMetrica) {
	component.MetricaModels = append(component.MetricaModels, model)
}

func (component *PluginComponent) ClearSentData() {
	component.Metrics = nil
}

func (component *PluginComponent) SetDuration(duration int) {
	component.Duration = duration
}

func (component *PluginComponent) Harvest(plugin INewrelicPlugin) ComponentData {
	component.Metrics = make(map[string]MetricaValue, len(component.MetricaModels))
	for i := 0; i < len(component.MetricaModels); i++ {
		model := component.MetricaModels[i]
		metricaKey := plugin.GetMetricaKey(model)

		if newValue, err := model.GetValue(); err == nil {
		        if math.IsInf(newValue, 0) || math.IsNaN(newValue) {
                                newValue = 0
                        }

			if existMetric, ok := component.Metrics[metricaKey]; ok {
				if floatExistVal, ok := existMetric.(float64); ok {
					component.Metrics[metricaKey] = NewAggregatedMetricaValue(floatExistVal, newValue)
				} else if aggregatedValue, ok := existMetric.(*AggregatedMetricaValue); ok {
					aggregatedValue.Aggregate(newValue)
				} else {
					panic("Invalid type in metrica value")
				}
			} else {
				component.Metrics[metricaKey] = newValue
			}
		} else {
			log.Printf("Can not get metrica: %v, got error:%#v", model.GetName(), err)
		}
	}
	return component
}
<|endoftext|>


<commit_before>package GoSDK

import (
	"encoding/json"
	"fmt"
	"net/url"
)

const (
	_DATA_PREAMBLE = "/api/v/1/data/"
)

func (u *UserClient) InsertData(collection_id string, data interface{}) error {
	return insertdata(u, collection_id, data)
}

func (d *DevClient) InsertData(collection_id string, data interface{}) error {
	return insertdata(d, collection_id, data)
}

func insertdata(c cbClient, collection_id string, data interface{}) error {
	creds, err := c.credentials()
	if err != nil {
		return err
	}
	resp, err := post(_DATA_PREAMBLE+collection_id, data, creds)
	if err != nil {
		return fmt.Errorf("Error inserting: %v", err)
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("Error inserting: %v", resp.Body)
	}
	return nil
}

func (u *UserClient) GetData(collection_id string, query *Query) (map[string]interface{}, error) {
	return getdata(u, collection_id, query)
}

func (d *DevClient) GetData(collection_id string, query *Query) (map[string]interface{}, error) {
	return getdata(d, collection_id, query)
}

func getdata(c cbClient, collection_id string, query *Query) (map[string]interface{}, error) {
	creds, err := c.credentials()
	if err != nil {
		return nil, err
	}
	query_map := query.serialize()
	query_bytes, err := json.Marshal(query_map)
	if err != nil {
		return nil, err
	}
	qry := map[string]string{
		"query": string(query_bytes),
	}
	resp, err := get(_DATA_PREAMBLE+collection_id, qry, creds)
	if err != nil {
		return nil, fmt.Errorf("Error getting data: %v", err)
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("Error getting data: %v", resp.Body)
	}
	return resp.Body.(map[string]interface{}), nil
}

func (u *UserClient) UpdateData(collection_id string, query *Query, changes map[string]interface{}) error {
	err := updatedata(u, collection_id, query, changes)
	return err
}

func (d *DevClient) UpdateData(collection_id string, query *Query, changes map[string]interface{}) error {
	err := updatedata(d, collection_id, query, changes)
	return err
}

func updatedata(c cbClient, collection_id string, query *Query, changes map[string]interface{}) error {
	qry := query.serialize()
	body := map[string]interface{}{
		"query": qry,
		"$set":  changes,
	}
	creds, err := c.credentials()
	if err != nil {
		return err
	}
	resp, err := put(_DATA_PREAMBLE+collection_id, body, creds)
	if err != nil {
		return fmt.Errorf("Error updating data: %v", err)
	}n
	if resp.StatusCode != 200 {
		return fmt.Errorf("Error updating data: %v", resp.Body)
	}
	return nil
}

func (u *UserClient) DeleteData(collection_id string, query [][]map[string]interface{}) error {
	return deletedata(u, collection_id, query)
}

func (d *DevClient) DeleteData(collection_id string, query [][]map[string]interface{}) error {
	return deletedata(d, collection_id, query)
}

func deletedata(c cbClient, collection_id string, query [][]map[string]interface{}) error {
	var qry map[string]string
	if query != nil {
		b, jsonErr := json.Marshal(query)
		if jsonErr != nil {
			return fmt.Errorf("JSON Encoding error: %v", jsonErr)
		}
		qryStr := url.QueryEscape(string(b))
		qry = map[string]string{"query": qryStr}
	} else {
		return fmt.Errorf("Must supply a query to delete")
	}
	creds, err := c.credentials()
	if err != nil {
		return err
	}
	resp, err := delete(_DATA_PREAMBLE+collection_id, qry, creds)
	if err != nil {
		return fmt.Errorf("Error deleting data: %v", err)
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("Error deleting data: %v", resp.Body)
	}
	return nil
}
<commit_msg>leaking characters from this bucket<commit_after>package GoSDK

import (
	"encoding/json"
	"fmt"
	"net/url"
)

const (
	_DATA_PREAMBLE = "/api/v/1/data/"
)

func (u *UserClient) InsertData(collection_id string, data interface{}) error {
	return insertdata(u, collection_id, data)
}

func (d *DevClient) InsertData(collection_id string, data interface{}) error {
	return insertdata(d, collection_id, data)
}

func insertdata(c cbClient, collection_id string, data interface{}) error {
	creds, err := c.credentials()
	if err != nil {
		return err
	}
	resp, err := post(_DATA_PREAMBLE+collection_id, data, creds)
	if err != nil {
		return fmt.Errorf("Error inserting: %v", err)
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("Error inserting: %v", resp.Body)
	}
	return nil
}

func (u *UserClient) GetData(collection_id string, query *Query) (map[string]interface{}, error) {
	return getdata(u, collection_id, query)
}

func (d *DevClient) GetData(collection_id string, query *Query) (map[string]interface{}, error) {
	return getdata(d, collection_id, query)
}

func getdata(c cbClient, collection_id string, query *Query) (map[string]interface{}, error) {
	creds, err := c.credentials()
	if err != nil {
		return nil, err
	}
	query_map := query.serialize()
	query_bytes, err := json.Marshal(query_map)
	if err != nil {
		return nil, err
	}
	qry := map[string]string{
		"query": string(query_bytes),
	}
	resp, err := get(_DATA_PREAMBLE+collection_id, qry, creds)
	if err != nil {
		return nil, fmt.Errorf("Error getting data: %v", err)
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("Error getting data: %v", resp.Body)
	}
	return resp.Body.(map[string]interface{}), nil
}

func (u *UserClient) UpdateData(collection_id string, query *Query, changes map[string]interface{}) error {
	err := updatedata(u, collection_id, query, changes)
	return err
}

func (d *DevClient) UpdateData(collection_id string, query *Query, changes map[string]interface{}) error {
	err := updatedata(d, collection_id, query, changes)
	return err
}

func updatedata(c cbClient, collection_id string, query *Query, changes map[string]interface{}) error {
	qry := query.serialize()
	body := map[string]interface{}{
		"query": qry,
		"$set":  changes,
	}
	creds, err := c.credentials()
	if err != nil {
		return err
	}
	resp, err := put(_DATA_PREAMBLE+collection_id, body, creds)
	if err != nil {
		return fmt.Errorf("Error updating data: %v", err)
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("Error updating data: %v", resp.Body)
	}
	return nil
}

func (u *UserClient) DeleteData(collection_id string, query [][]map[string]interface{}) error {
	return deletedata(u, collection_id, query)
}

func (d *DevClient) DeleteData(collection_id string, query [][]map[string]interface{}) error {
	return deletedata(d, collection_id, query)
}

func deletedata(c cbClient, collection_id string, query [][]map[string]interface{}) error {
	var qry map[string]string
	if query != nil {
		b, jsonErr := json.Marshal(query)
		if jsonErr != nil {
			return fmt.Errorf("JSON Encoding error: %v", jsonErr)
		}
		qryStr := url.QueryEscape(string(b))
		qry = map[string]string{"query": qryStr}
	} else {
		return fmt.Errorf("Must supply a query to delete")
	}
	creds, err := c.credentials()
	if err != nil {
		return err
	}
	resp, err := delete(_DATA_PREAMBLE+collection_id, qry, creds)
	if err != nil {
		return fmt.Errorf("Error deleting data: %v", err)
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("Error deleting data: %v", resp.Body)
	}
	return nil
}
<|endoftext|>


<commit_before>package encoding

import (
	"image"
	"reflect"
	"testing"
)

type T struct {
	X string
	Y int
	Z int `gorethink:"-"`
}

type U struct {
	Alphabet string `gorethink:"alpha"`
}

type V struct {
	F1 interface{}
	F2 int32
	F3 string
}

type tx struct {
	x int
}

var txType = reflect.TypeOf((*tx)(nil)).Elem()

// Test data structures for anonymous fields.

type Point struct {
	Z int
}

type Top struct {
	Level0 int
	Embed0
	*Embed0a
	*Embed0b `gorethink:"e,omitempty"` // treated as named
	Embed0c  `gorethink:"-"`           // ignored
	Loop
	Embed0p // has Point with X, Y, used
	Embed0q // has Point with Z, used
}

type Embed0 struct {
	Level1a int // overridden by Embed0a's Level1a with tag
	Level1b int // used because Embed0a's Level1b is renamed
	Level1c int // used because Embed0a's Level1c is ignored
	Level1d int // annihilated by Embed0a's Level1d
	Level1e int `gorethink:"x"` // annihilated by Embed0a.Level1e
}

type Embed0a struct {
	Level1a int `gorethink:"Level1a,omitempty"`
	Level1b int `gorethink:"LEVEL1B,omitempty"`
	Level1c int `gorethink:"-"`
	Level1d int // annihilated by Embed0's Level1d
	Level1f int `gorethink:"x"` // annihilated by Embed0's Level1e
}

type Embed0b Embed0

type Embed0c Embed0

type Embed0p struct {
	image.Point
}

type Embed0q struct {
	Point
}

type Loop struct {
	Loop1 int `gorethink:",omitempty"`
	Loop2 int `gorethink:",omitempty"`
	*Loop
}

// From reflect test:
// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
type S5 struct {
	S6
	S7
	S8
}

type S6 struct {
	X int
}

type S7 S6

type S8 struct {
	S9
}

type S9 struct {
	X int
	Y int
}

// From reflect test:
// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
type S10 struct {
	S11
	S12
	S13
}

type S11 struct {
	S6
}

type S12 struct {
	S6
}

type S13 struct {
	S8
}

type decodeTest struct {
	in  interface{}
	ptr interface{}
	out interface{}
	err error
}

type Ambig struct {
	// Given "hello", the first match should win.
	First  int `gorethink:"HELLO"`
	Second int `gorethink:"Hello"`
}

var decodeTests = []decodeTest{
	// basic types
	{in: true, ptr: new(bool), out: true},
	{in: 1, ptr: new(int), out: 1},
	{in: 1.2, ptr: new(float64), out: 1.2},
	{in: -5, ptr: new(int16), out: int16(-5)},
	{in: 2, ptr: new(string), out: string("2")},
	{in: float64(2.0), ptr: new(interface{}), out: float64(2.0)},
	{in: string("2"), ptr: new(interface{}), out: string("2")},
	{in: "a\u1234", ptr: new(string), out: "a\u1234"},
	{in: map[string]interface{}{"X": []interface{}{1, 2, 3}, "Y": 4}, ptr: new(T), out: T{}, err: &DecodeTypeError{"array", reflect.TypeOf("")}},
	{in: map[string]interface{}{"x": 1}, ptr: new(tx), out: tx{}},
	{in: map[string]interface{}{"F1": float64(1), "F2": 2, "F3": 3}, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: string("3")}},
	{in: map[string]interface{}{"F1": string("1"), "F2": 2, "F3": 3}, ptr: new(V), out: V{F1: string("1"), F2: int32(2), F3: string("3")}},
	{
		in:  map[string]interface{}{"k1": int64(1), "k2": "s", "k3": []interface{}{int64(1), 2.0, 3e-3}, "k4": map[string]interface{}{"kk1": "s", "kk2": int64(2)}},
		out: map[string]interface{}{"k1": int64(1), "k2": "s", "k3": []interface{}{int64(1), 2.0, 3e-3}, "k4": map[string]interface{}{"kk1": "s", "kk2": int64(2)}},
		ptr: new(interface{}),
	},

	// Z has a "-" tag.
	{in: map[string]interface{}{"Y": 1, "Z": 2}, ptr: new(T), out: T{Y: 1}},

	{in: map[string]interface{}{"alpha": "abc", "alphabet": "xyz"}, ptr: new(U), out: U{Alphabet: "abc"}},
	{in: map[string]interface{}{"alpha": "abc"}, ptr: new(U), out: U{Alphabet: "abc"}},
	{in: map[string]interface{}{"alphabet": "xyz"}, ptr: new(U), out: U{}},

	// array tests
	{in: []interface{}{1, 2, 3}, ptr: new([3]int), out: [3]int{1, 2, 3}},
	{in: []interface{}{1, 2, 3}, ptr: new([1]int), out: [1]int{1}},
	{in: []interface{}{1, 2, 3}, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}},

	// empty array to interface test
	{in: []interface{}{}, ptr: new([]interface{}), out: []interface{}{}},
	{in: map[string]interface{}{"T": []interface{}{}}, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}},

	{
		in: map[string]interface{}{
			"Level0":  1,
			"Level1b": 2,
			"Level1c": 3,
			"level1d": 4,
			"Level1a": 5,
			"LEVEL1B": 6,
			"e": map[string]interface{}{
				"Level1a": 8,
				"Level1b": 9,
				"Level1c": 10,
				"Level1d": 11,
				"x":       12,
			},
			"Loop1": 13,
			"Loop2": 14,
			"X":     15,
			"Y":     16,
			"Z":     17,
		},
		ptr: new(Top),
		out: Top{
			Level0: 1,
			Embed0: Embed0{
				Level1b: 2,
				Level1c: 3,
			},
			Embed0a: &Embed0a{
				Level1a: 5,
				Level1b: 6,
			},
			Embed0b: &Embed0b{
				Level1a: 8,
				Level1b: 9,
				Level1c: 10,
				Level1d: 11,
				Level1e: 12,
			},
			Loop: Loop{
				Loop1: 13,
				Loop2: 14,
			},
			Embed0p: Embed0p{
				Point: image.Point{X: 15, Y: 16},
			},
			Embed0q: Embed0q{
				Point: Point{Z: 17},
			},
		},
	},
	{
		in:  map[string]interface{}{"hello": 1},
		ptr: new(Ambig),
		out: Ambig{First: 1},
	},

	{
		in:  map[string]interface{}{"X": 1, "Y": 2},
		ptr: new(S5),
		out: S5{S8: S8{S9: S9{Y: 2}}},
	},
	{
		in:  map[string]interface{}{"X": 1, "Y": 2},
		ptr: new(S10),
		out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},
	},
}

func TestDecode(t *testing.T) {
	for i, tt := range decodeTests {
		if tt.ptr == nil {
			continue
		}

		// v = new(right-type)
		v := reflect.New(reflect.TypeOf(tt.ptr).Elem())

		if err := Decode(v.Interface(), tt.in); !reflect.DeepEqual(err, tt.err) {
			t.Errorf("#%d: got error %v want %v", i, err, tt.err)
			continue
		} else if !reflect.DeepEqual(v.Elem().Interface(), tt.out) {
			t.Errorf("#%d: mismatch\nhave: %+v\nwant: %+v", i, v.Elem().Interface(), tt.out)
			continue
		}

		// Check round trip.
		if tt.err == nil {
			enc, err := Encode(v.Interface())
			if err != nil {
				t.Errorf("#%d: error re-marshaling: %v", i, err)
				continue
			}
			vv := reflect.New(reflect.TypeOf(tt.ptr).Elem())

			if err := Decode(vv.Interface(), enc); err != nil {
				t.Errorf("#%d: error re-decodeing: %v", i, err)
				continue
			}
			if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) {
				t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface())
				continue
			}
		}
	}
}

func TestStringKind(t *testing.T) {
	type aMap map[string]int

	var m1, m2 map[string]int
	m1 = map[string]int{
		"foo": 42,
	}

	data, err := Encode(m1)
	if err != nil {
		t.Errorf("Unexpected error encoding: %v", err)
	}

	err = Decode(&m2, data)
	if err != nil {
		t.Errorf("Unexpected error decoding: %v", err)
	}

	if !reflect.DeepEqual(m1, m2) {
		t.Error("Items should be equal after encoding and then decoding")
	}

}

var decodeTypeErrorTests = []struct {
	dest interface{}
	src  interface{}
}{
	{new(string), map[interface{}]interface{}{"user": "name"}},
	{new(error), map[interface{}]interface{}{}},
	{new(error), []interface{}{}},
	{new(error), ""},
	{new(error), 123},
	{new(error), true},
}

func TestDecodeTypeError(t *testing.T) {
	for _, item := range decodeTypeErrorTests {
		err := Decode(item.dest, item.src)
		if _, ok := err.(*DecodeTypeError); !ok {
			t.Errorf("expected type error for Decode(%q, type %T): got %T",
				item.src, item.dest, err)
		}
	}
}

// Test handling of unexported fields that should be ignored.
type unexportedFields struct {
	Name string
	m    map[string]interface{} `gorethink:"-"`
	m2   map[string]interface{} `gorethink:"abcd"`
}

func TestDecodeUnexported(t *testing.T) {
	input := map[string]interface{}{
		"Name": "Bob",
		"m": map[string]interface{}{
			"x": 123,
		},
		"m2": map[string]interface{}{
			"y": 123,
		},
		"abcd": map[string]interface{}{
			"z": 789,
		},
	}
	want := &unexportedFields{Name: "Bob"}

	out := &unexportedFields{}
	err := Decode(out, input)
	if err != nil {
		t.Errorf("got error %v, expected nil", err)
	}
	if !reflect.DeepEqual(out, want) {
		t.Errorf("got %q, want %q", out, want)
	}
}

type Foo struct {
	FooBar interface{} `gorethink:"foobar"`
}
type Bar struct {
	Baz int `gorethink:"baz"`
}
<commit_msg>Fixed error returning decode tests<commit_after>package encoding

import (
	"image"
	"reflect"
	"testing"
)

type T struct {
	X string
	Y int
	Z int `gorethink:"-"`
}

type U struct {
	Alphabet string `gorethink:"alpha"`
}

type V struct {
	F1 interface{}
	F2 int32
	F3 string
}

type tx struct {
	x int
}

var txType = reflect.TypeOf((*tx)(nil)).Elem()

// Test data structures for anonymous fields.

type Point struct {
	Z int
}

type Top struct {
	Level0 int
	Embed0
	*Embed0a
	*Embed0b `gorethink:"e,omitempty"` // treated as named
	Embed0c  `gorethink:"-"`           // ignored
	Loop
	Embed0p // has Point with X, Y, used
	Embed0q // has Point with Z, used
}

type Embed0 struct {
	Level1a int // overridden by Embed0a's Level1a with tag
	Level1b int // used because Embed0a's Level1b is renamed
	Level1c int // used because Embed0a's Level1c is ignored
	Level1d int // annihilated by Embed0a's Level1d
	Level1e int `gorethink:"x"` // annihilated by Embed0a.Level1e
}

type Embed0a struct {
	Level1a int `gorethink:"Level1a,omitempty"`
	Level1b int `gorethink:"LEVEL1B,omitempty"`
	Level1c int `gorethink:"-"`
	Level1d int // annihilated by Embed0's Level1d
	Level1f int `gorethink:"x"` // annihilated by Embed0's Level1e
}

type Embed0b Embed0

type Embed0c Embed0

type Embed0p struct {
	image.Point
}

type Embed0q struct {
	Point
}

type Loop struct {
	Loop1 int `gorethink:",omitempty"`
	Loop2 int `gorethink:",omitempty"`
	*Loop
}

// From reflect test:
// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
type S5 struct {
	S6
	S7
	S8
}

type S6 struct {
	X int
}

type S7 S6

type S8 struct {
	S9
}

type S9 struct {
	X int
	Y int
}

// From reflect test:
// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
type S10 struct {
	S11
	S12
	S13
}

type S11 struct {
	S6
}

type S12 struct {
	S6
}

type S13 struct {
	S8
}

type decodeTest struct {
	in  interface{}
	ptr interface{}
	out interface{}
	err error
}

type Ambig struct {
	// Given "hello", the first match should win.
	First  int `gorethink:"HELLO"`
	Second int `gorethink:"Hello"`
}

var decodeTests = []decodeTest{
	// basic types
	{in: true, ptr: new(bool), out: true},
	{in: 1, ptr: new(int), out: 1},
	{in: 1.2, ptr: new(float64), out: 1.2},
	{in: -5, ptr: new(int16), out: int16(-5)},
	{in: 2, ptr: new(string), out: string("2")},
	{in: float64(2.0), ptr: new(interface{}), out: float64(2.0)},
	{in: string("2"), ptr: new(interface{}), out: string("2")},
	{in: "a\u1234", ptr: new(string), out: "a\u1234"},
	{in: map[string]interface{}{"X": []interface{}{1, 2, 3}, "Y": 4}, ptr: new(T), out: T{}, err: &DecodeTypeError{"array", reflect.TypeOf("")}},
	{in: map[string]interface{}{"x": 1}, ptr: new(tx), out: tx{}},
	{in: map[string]interface{}{"F1": float64(1), "F2": 2, "F3": 3}, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: string("3")}},
	{in: map[string]interface{}{"F1": string("1"), "F2": 2, "F3": 3}, ptr: new(V), out: V{F1: string("1"), F2: int32(2), F3: string("3")}},
	{
		in:  map[string]interface{}{"k1": int64(1), "k2": "s", "k3": []interface{}{int64(1), 2.0, 3e-3}, "k4": map[string]interface{}{"kk1": "s", "kk2": int64(2)}},
		out: map[string]interface{}{"k1": int64(1), "k2": "s", "k3": []interface{}{int64(1), 2.0, 3e-3}, "k4": map[string]interface{}{"kk1": "s", "kk2": int64(2)}},
		ptr: new(interface{}),
	},

	// Z has a "-" tag.
	{in: map[string]interface{}{"Y": 1, "Z": 2}, ptr: new(T), out: T{Y: 1}},

	{in: map[string]interface{}{"alpha": "abc", "alphabet": "xyz"}, ptr: new(U), out: U{Alphabet: "abc"}},
	{in: map[string]interface{}{"alpha": "abc"}, ptr: new(U), out: U{Alphabet: "abc"}},
	{in: map[string]interface{}{"alphabet": "xyz"}, ptr: new(U), out: U{}},

	// array tests
	{in: []interface{}{1, 2, 3}, ptr: new([3]int), out: [3]int{1, 2, 3}},
	{in: []interface{}{1, 2, 3}, ptr: new([1]int), out: [1]int{1}},
	{in: []interface{}{1, 2, 3}, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}},

	// empty array to interface test
	{in: []interface{}{}, ptr: new([]interface{}), out: []interface{}{}},
	{in: map[string]interface{}{"T": []interface{}{}}, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}},

	{
		in: map[string]interface{}{
			"Level0":  1,
			"Level1b": 2,
			"Level1c": 3,
			"level1d": 4,
			"Level1a": 5,
			"LEVEL1B": 6,
			"e": map[string]interface{}{
				"Level1a": 8,
				"Level1b": 9,
				"Level1c": 10,
				"Level1d": 11,
				"x":       12,
			},
			"Loop1": 13,
			"Loop2": 14,
			"X":     15,
			"Y":     16,
			"Z":     17,
		},
		ptr: new(Top),
		out: Top{
			Level0: 1,
			Embed0: Embed0{
				Level1b: 2,
				Level1c: 3,
			},
			Embed0a: &Embed0a{
				Level1a: 5,
				Level1b: 6,
			},
			Embed0b: &Embed0b{
				Level1a: 8,
				Level1b: 9,
				Level1c: 10,
				Level1d: 11,
				Level1e: 12,
			},
			Loop: Loop{
				Loop1: 13,
				Loop2: 14,
			},
			Embed0p: Embed0p{
				Point: image.Point{X: 15, Y: 16},
			},
			Embed0q: Embed0q{
				Point: Point{Z: 17},
			},
		},
	},
	{
		in:  map[string]interface{}{"hello": 1},
		ptr: new(Ambig),
		out: Ambig{First: 1},
	},

	{
		in:  map[string]interface{}{"X": 1, "Y": 2},
		ptr: new(S5),
		out: S5{S8: S8{S9: S9{Y: 2}}},
	},
	{
		in:  map[string]interface{}{"X": 1, "Y": 2},
		ptr: new(S10),
		out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},
	},
}

func TestDecode(t *testing.T) {
	for i, tt := range decodeTests {
		if tt.ptr == nil {
			continue
		}

		// v = new(right-type)
		v := reflect.New(reflect.TypeOf(tt.ptr).Elem())

		err := Decode(v.Interface(), tt.in)
		if tt.err != nil {
			if !reflect.DeepEqual(err, tt.err) {
				t.Errorf("#%d: got error %v want %v", i, err, tt.err)
			}

			continue
		}

		if !reflect.DeepEqual(v.Elem().Interface(), tt.out) {
			t.Errorf("#%d: mismatch\nhave: %+v\nwant: %+v", i, v.Elem().Interface(), tt.out)
			continue
		}

		// Check round trip.
		if tt.err == nil {
			enc, err := Encode(v.Interface())
			if err != nil {
				t.Errorf("#%d: error re-marshaling: %v", i, err)
				continue
			}
			vv := reflect.New(reflect.TypeOf(tt.ptr).Elem())

			if err := Decode(vv.Interface(), enc); err != nil {
				t.Errorf("#%d: error re-decodeing: %v", i, err)
				continue
			}
			if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) {
				t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface())
				continue
			}
		}
	}
}

func TestStringKind(t *testing.T) {
	type aMap map[string]int

	var m1, m2 map[string]int
	m1 = map[string]int{
		"foo": 42,
	}

	data, err := Encode(m1)
	if err != nil {
		t.Errorf("Unexpected error encoding: %v", err)
	}

	err = Decode(&m2, data)
	if err != nil {
		t.Errorf("Unexpected error decoding: %v", err)
	}

	if !reflect.DeepEqual(m1, m2) {
		t.Error("Items should be equal after encoding and then decoding")
	}

}

var decodeTypeErrorTests = []struct {
	dest interface{}
	src  interface{}
}{
	{new(string), map[interface{}]interface{}{"user": "name"}},
	{new(error), map[interface{}]interface{}{}},
	{new(error), []interface{}{}},
	{new(error), ""},
	{new(error), 123},
	{new(error), true},
}

func TestDecodeTypeError(t *testing.T) {
	for _, item := range decodeTypeErrorTests {
		err := Decode(item.dest, item.src)
		if _, ok := err.(*DecodeTypeError); !ok {
			t.Errorf("expected type error for Decode(%q, type %T): got %T",
				item.src, item.dest, err)
		}
	}
}

// Test handling of unexported fields that should be ignored.
type unexportedFields struct {
	Name string
	m    map[string]interface{} `gorethink:"-"`
	m2   map[string]interface{} `gorethink:"abcd"`
}

func TestDecodeUnexported(t *testing.T) {
	input := map[string]interface{}{
		"Name": "Bob",
		"m": map[string]interface{}{
			"x": 123,
		},
		"m2": map[string]interface{}{
			"y": 123,
		},
		"abcd": map[string]interface{}{
			"z": 789,
		},
	}
	want := &unexportedFields{Name: "Bob"}

	out := &unexportedFields{}
	err := Decode(out, input)
	if err != nil {
		t.Errorf("got error %v, expected nil", err)
	}
	if !reflect.DeepEqual(out, want) {
		t.Errorf("got %q, want %q", out, want)
	}
}

type Foo struct {
	FooBar interface{} `gorethink:"foobar"`
}
type Bar struct {
	Baz int `gorethink:"baz"`
}
<|endoftext|>


<commit_before>package date

import "fmt"
import "time"

const dateNoTimeFormat = "2006.01.02"

// All these FooPdt functions should be renamed FooPacificTime; they're not specific to
// dayight savings.
func InPdt(t time.Time) time.Time {
	pdt, _ := time.LoadLocation("America/Los_Angeles")
	return t.In(pdt)
}

func NowInPdt() time.Time {	return InPdt(time.Now()) }

func ParseInPdt(format string, value string) (time.Time, error) {
	pdt, err1 := time.LoadLocation("America/Los_Angeles")
	if err1 != nil { return time.Now(), err1 }
	t,err2 := time.ParseInLocation(format, value, pdt)
	if err2 != nil { return NowInPdt(), err2 }
	return t, nil
}

func Time2Datestring(t time.Time) string {
	return InPdt(t).Format(dateNoTimeFormat)
}

func ArbitraryDatestring2MidnightPdt(s string, fmt string) time.Time {
	pdt, _ := time.LoadLocation("America/Los_Angeles")
	t,_ := time.ParseInLocation(fmt, s, pdt)
	return t
}

func Datestring2MidnightPdt(s string) time.Time {
	return ArbitraryDatestring2MidnightPdt(s, dateNoTimeFormat)
}

// Round off to 00:00:00 today (i.e. most recent midnight)
// Can't use time.Round(24*time.Hour); it operates in UTC, so rounds into weird boundaries
func AtLocalMidnight(in time.Time) time.Time {
	return time.Date(in.Year(), in.Month(), in.Day(), 0, 0, 0, 0, in.Location())
}

// A 'window' is a pair of times spanning 24h, respecting the timezone of the input.
// start will be midnight (00:00:00) that day; end is 24h later, i.e. 00:00:00 the next day
func WindowForTime(t time.Time) (start time.Time, end time.Time) {
	start = AtLocalMidnight(t)
	end = start.Add(24 * time.Hour)
	return
}

// Get the window for all in the seconds in the month which contains the time
func MonthWindowForTime(t time.Time) (start time.Time, end time.Time) {
	ref := InPdt(t)
	start = time.Date(ref.Year(), ref.Month(), 1, 0,0,0,0, ref.Location()) // first second of month
	end = start.AddDate(0,1,0).Add(-1 * time.Second) // one month forward, one second back
	return
}

// Return all midnights inbetween s & e - not including s or e if they happen to be midnight.
// Caller should ensure s and e are in the same timezone.
func IntermediateMidnights(s,e time.Time) (ret []time.Time) {
	if s.Equal(e)  { return }
	if !e.After(s) { panic(fmt.Sprintf("IntermediateMidnights: start>end: %s, %s", s, e)) }

	_, m := WindowForTime(s)  // init: get first midnight that follows s
	for m.Before(e) {
		ret = append(ret, m)
		m = m.AddDate(0,0,1)  // This works cleanly through Daylight Savings transitions.
	}

	return
}

// Convenience helpers
func WindowForToday() (start time.Time, end time.Time) {
	return WindowForTime(NowInPdt())
}

func WindowForYesterday() (start time.Time, end time.Time) {
	return WindowForTime(NowInPdt().AddDate(0,0,-1))
}

// Returns a list of time buckets, of given duration, that the inputs span. Each bucket is
// returned as the time-instant that begins the bucket.
func Timeslots(s,e time.Time, d time.Duration) []time.Time {
	ret := []time.Time{}

	// time.Round rounds to nearest (rounds up as tiebreaker), so subtract half to ensure round down
	for t := s.Add(-1 * d/2).Round(d); !t.After(e); t = t.Add(d) {
		ret = append(ret, t)
	}

	return ret
}

func RoundDuration(d time.Duration) time.Duration {
	return time.Duration(int64(d.Seconds())) * time.Second
}
<commit_msg>Extra convenience function<commit_after>package date

import "fmt"
import "time"

const dateNoTimeFormat = "2006.01.02"

// All these FooPdt functions should be renamed FooPacificTime; they're not specific to
// dayight savings.
func InPdt(t time.Time) time.Time {
	pdt, _ := time.LoadLocation("America/Los_Angeles")
	return t.In(pdt)
}

func NowInPdt() time.Time {	return InPdt(time.Now()) }

func ParseInPdt(format string, value string) (time.Time, error) {
	pdt, err1 := time.LoadLocation("America/Los_Angeles")
	if err1 != nil { return time.Now(), err1 }
	t,err2 := time.ParseInLocation(format, value, pdt)
	if err2 != nil { return NowInPdt(), err2 }
	return t, nil
}

func Time2Datestring(t time.Time) string {
	return InPdt(t).Format(dateNoTimeFormat)
}

func ArbitraryDatestring2MidnightPdt(s string, fmt string) time.Time {
	pdt, _ := time.LoadLocation("America/Los_Angeles")
	t,_ := time.ParseInLocation(fmt, s, pdt)
	return t
}

func Datestring2MidnightPdt(s string) time.Time {
	return ArbitraryDatestring2MidnightPdt(s, dateNoTimeFormat)
}

// Round off to 00:00:00 today (i.e. most recent midnight)
// Can't use time.Round(24*time.Hour); it operates in UTC, so rounds into weird boundaries
func AtLocalMidnight(in time.Time) time.Time {
	return time.Date(in.Year(), in.Month(), in.Day(), 0, 0, 0, 0, in.Location())
}

// A 'window' is a pair of times spanning 24h, respecting the timezone of the input.
// start will be midnight (00:00:00) that day; end is 24h later, i.e. 00:00:00 the next day
func WindowForTime(t time.Time) (start time.Time, end time.Time) {
	start = AtLocalMidnight(t)
	end = start.Add(24 * time.Hour)
	return
}

// Get the window for all in the seconds in the month which contains the time
func MonthWindowForTime(t time.Time) (start time.Time, end time.Time) {
	ref := InPdt(t)
	start = time.Date(ref.Year(), ref.Month(), 1, 0,0,0,0, ref.Location()) // first second of month
	end = start.AddDate(0,1,0).Add(-1 * time.Second) // one month forward, one second back
	return
}

// Return all midnights inbetween s & e - not including s or e if they happen to be midnight.
// Caller should ensure s and e are in the same timezone.
func IntermediateMidnights(s,e time.Time) (ret []time.Time) {
	if s.Equal(e)  { return }
	if !e.After(s) { panic(fmt.Sprintf("IntermediateMidnights: start>end: %s, %s", s, e)) }

	_, m := WindowForTime(s)  // init: get first midnight that follows s
	for m.Before(e) {
		ret = append(ret, m)
		m = m.AddDate(0,0,1)  // This works cleanly through Daylight Savings transitions.
	}

	return
}

// Convenience helpers
func WindowForToday() (start time.Time, end time.Time) {
	return WindowForTime(NowInPdt())
}

func WindowForYesterday() (start time.Time, end time.Time) {
	return WindowForTime(NowInPdt().AddDate(0,0,-1))
}

// Returns a list of time buckets, of given duration, that the inputs span. Each bucket is
// returned as the time-instant that begins the bucket.
func Timeslots(s,e time.Time, d time.Duration) []time.Time {
	ret := []time.Time{}

	// time.Round rounds to nearest (rounds up as tiebreaker), so subtract half to ensure round down
	for t := s.Add(-1 * d/2).Round(d); !t.After(e); t = t.Add(d) {
		ret = append(ret, t)
	}

	return ret
}

func RoundDuration(d time.Duration) time.Duration {
	return time.Duration(int64(d.Seconds())) * time.Second
}

func DateRangeToPacificTimeWindows(sStr,eStr string) [][]time.Time {
	start := ArbitraryDatestring2MidnightPdt(sStr, "2006/01/02").Add(-1 * time.Second)
	end   := ArbitraryDatestring2MidnightPdt(eStr, "2006/01/02").Add(1 * time.Second)

	ret := [][]time.Time{}

	for _,day := range IntermediateMidnights(start,end) {
		s,e := WindowForTime(day)
		e = e.Add(-1 * time.Second)
		ret = append(ret, []time.Time{s,e})
	}

	return ret
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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

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

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

package mungers

import (
	"fmt"
	"regexp"
	"time"

	"k8s.io/contrib/mungegithub/features"
	"k8s.io/contrib/mungegithub/github"
	"k8s.io/contrib/mungegithub/mungers/mungerutil"

	"github.com/golang/glog"
	githubapi "github.com/google/go-github/github"
	"github.com/spf13/cobra"
)

const (
	day              = time.Hour * 24
	keepOpenLabel    = "keep-open"
	stalePullRequest = 90 * day // Close the PR if no human interaction for `stalePullRequest`
	startWarning     = 60 * day
	remindWarning    = 30 * day
	closingComment   = `This PR hasn't been active in %s. Closing this PR. Please reopen if you would like to work towards merging this change, if/when the PR is ready for the next round of review.

%s
You can add 'keep-open' label to prevent this from happening again, or add a comment to keep it open another 90 days`
	warningComment = `This PR hasn't been active in %s. It will be closed in %s (%s).

%s
You can add 'keep-open' label to prevent this from happening, or add a comment to keep it open another 90 days`
)

var (
	closingCommentRE = regexp.MustCompile(`This PR hasn't been active in \d+ days?\..*label to prevent this from happening again`)
	warningCommentRE = regexp.MustCompile(`This PR hasn't been active in \d+ days?\..*be closed in \d+ days`)
)

// CloseStalePR will ask the Bot to close any PullRequest that didn't
// have any human interactions in `stalePullRequest` duration.
//
// This is done by checking both review and issue comments, and by
// ignoring comments done with a bot name. We also consider re-open on the PR.
type CloseStalePR struct{}

func init() {
	s := CloseStalePR{}
	RegisterMungerOrDie(s)
	RegisterStaleComments(s)
}

// Name is the name usable in --pr-mungers
func (CloseStalePR) Name() string { return "close-stale-pr" }

// RequiredFeatures is a slice of 'features' that must be provided
func (CloseStalePR) RequiredFeatures() []string { return []string{} }

// Initialize will initialize the munger
func (CloseStalePR) Initialize(config *github.Config, features *features.Features) error {
	return nil
}

// EachLoop is called at the start of every munge loop
func (CloseStalePR) EachLoop() error { return nil }

// AddFlags will add any request flags to the cobra `cmd`
func (CloseStalePR) AddFlags(cmd *cobra.Command, config *github.Config) {}

func findLastHumanPullRequestUpdate(obj *github.MungeObject) (*time.Time, error) {
	pr, err := obj.GetPR()
	if err != nil {
		return nil, err
	}

	comments, err := obj.ListReviewComments()
	if err != nil {
		return nil, err
	}

	lastHuman := pr.CreatedAt
	for i := range comments {
		comment := comments[i]
		if comment.User == nil || comment.User.Login == nil || comment.CreatedAt == nil || comment.Body == nil {
			continue
		}
		if *comment.User.Login == botName || *comment.User.Login == jenkinsBotName {
			continue
		}
		if lastHuman.Before(*comment.UpdatedAt) {
			lastHuman = comment.UpdatedAt
		}
	}

	return lastHuman, nil
}

func findLastHumanIssueUpdate(obj *github.MungeObject) (*time.Time, error) {
	lastHuman := obj.Issue.CreatedAt

	comments, err := obj.ListComments()
	if err != nil {
		return nil, err
	}

	for i := range comments {
		comment := comments[i]
		if !validComment(comment) {
			continue
		}
		if mergeBotComment(comment) || jenkinsBotComment(comment) {
			continue
		}
		if lastHuman.Before(*comment.UpdatedAt) {
			lastHuman = comment.UpdatedAt
		}
	}

	return lastHuman, nil
}

func findLastInterestingEventUpdate(obj *github.MungeObject) (*time.Time, error) {
	lastInteresting := obj.Issue.CreatedAt

	events, err := obj.GetEvents()
	if err != nil {
		return nil, err
	}

	for i := range events {
		event := events[i]
		if event.Event == nil || *event.Event != "reopened" {
			continue
		}

		if lastInteresting.Before(*event.CreatedAt) {
			lastInteresting = event.CreatedAt
		}
	}

	return lastInteresting, nil
}

func findLastModificationTime(obj *github.MungeObject) (*time.Time, error) {
	lastHumanIssue, err := findLastHumanIssueUpdate(obj)
	if err != nil {
		return nil, err
	}
	lastHumanPR, err := findLastHumanPullRequestUpdate(obj)
	if err != nil {
		return nil, err
	}
	lastInterestingEvent, err := findLastInterestingEventUpdate(obj)
	if err != nil {
		return nil, err
	}

	lastModif := lastHumanPR
	if lastHumanIssue.After(*lastModif) {
		lastModif = lastHumanIssue
	}
	if lastInterestingEvent.After(*lastModif) {
		lastModif = lastInterestingEvent
	}

	return lastModif, nil
}

func findLatestWarningComment(obj *github.MungeObject) *githubapi.IssueComment {
	var lastFoundComment *githubapi.IssueComment

	comments, err := obj.ListComments()
	if err != nil {
		return nil
	}

	for i := range comments {
		comment := comments[i]
		if !validComment(comment) {
			continue
		}
		if !mergeBotComment(comment) {
			continue
		}

		if !warningCommentRE.MatchString(*comment.Body) {
			continue
		}

		if lastFoundComment == nil || lastFoundComment.CreatedAt.Before(*comment.UpdatedAt) {
			if lastFoundComment != nil {
				obj.DeleteComment(lastFoundComment)
			}
			lastFoundComment = comment
		}
	}

	return lastFoundComment
}

func durationToDays(duration time.Duration) string {
	days := duration / day
	dayString := "days"
	if days == 1 || days == -1 {
		dayString = "day"
	}
	return fmt.Sprintf("%d %s", days, dayString)
}

func closePullRequest(obj *github.MungeObject, inactiveFor time.Duration) {
	mention := mungerutil.GetIssueUsers(obj.Issue).AllUsers().Mention().Join()
	if mention != "" {
		mention = "cc " + mention + "\n"
	}

	comment := findLatestWarningComment(obj)
	if comment != nil {
		obj.DeleteComment(comment)
	}

	obj.WriteComment(fmt.Sprintf(closingComment, durationToDays(inactiveFor), mention))
	obj.ClosePR()
}

func postWarningComment(obj *github.MungeObject, inactiveFor time.Duration, closeIn time.Duration) {
	mention := mungerutil.GetIssueUsers(obj.Issue).AllUsers().Mention().Join()
	if mention != "" {
		mention = "cc " + mention + "\n"
	}

	closeDate := time.Now().Add(closeIn).Format("Jan 2, 2006")

	obj.WriteComment(fmt.Sprintf(
		warningComment,
		durationToDays(inactiveFor),
		durationToDays(closeIn),
		closeDate,
		mention,
	))
}

func checkAndWarn(obj *github.MungeObject, inactiveFor time.Duration, closeIn time.Duration) {
	if closeIn < day {
		// We are going to close the PR in less than a day. Too late to warn
		return
	}
	comment := findLatestWarningComment(obj)
	if comment == nil {
		// We don't already have the comment. Post it
		postWarningComment(obj, inactiveFor, closeIn)
	} else if time.Since(*comment.UpdatedAt) > remindWarning {
		// It's time to warn again
		obj.DeleteComment(comment)
		postWarningComment(obj, inactiveFor, closeIn)
	} else {
		// We already have a warning, and it's not expired. Do nothing
	}
}

// Munge is the workhorse that will actually close the PRs
func (CloseStalePR) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if obj.HasLabel(keepOpenLabel) {
		return
	}

	lastModif, err := findLastModificationTime(obj)
	if err != nil {
		glog.Errorf("Failed to find last modification: %v", err)
		return
	}

	closeIn := -time.Since(lastModif.Add(stalePullRequest))
	inactiveFor := time.Since(*lastModif)
	if closeIn <= 0 {
		closePullRequest(obj, inactiveFor)
	} else if closeIn <= startWarning {
		checkAndWarn(obj, inactiveFor, closeIn)
	} else {
		// Pull-request is active. Remove previous potential warning
		comment := findLatestWarningComment(obj)
		if comment != nil {
			obj.DeleteComment(comment)
		}
	}
}

func (CloseStalePR) isStaleComment(obj *github.MungeObject, comment *githubapi.IssueComment) bool {
	if !mergeBotComment(comment) {
		return false
	}

	if !closingCommentRE.MatchString(*comment.Body) {
		return false
	}

	return true
}

// StaleComments returns a slice of stale comments
func (s CloseStalePR) StaleComments(obj *github.MungeObject, comments []*githubapi.IssueComment) []*githubapi.IssueComment {
	return forEachCommentTest(obj, comments, s.isStaleComment)
}
<commit_msg>Stop processing the pull-request if Github fails<commit_after>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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

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

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

package mungers

import (
	"fmt"
	"regexp"
	"time"

	"k8s.io/contrib/mungegithub/features"
	"k8s.io/contrib/mungegithub/github"
	"k8s.io/contrib/mungegithub/mungers/mungerutil"

	"github.com/golang/glog"
	githubapi "github.com/google/go-github/github"
	"github.com/spf13/cobra"
)

const (
	day              = time.Hour * 24
	keepOpenLabel    = "keep-open"
	stalePullRequest = 90 * day // Close the PR if no human interaction for `stalePullRequest`
	startWarning     = 60 * day
	remindWarning    = 30 * day
	closingComment   = `This PR hasn't been active in %s. Closing this PR. Please reopen if you would like to work towards merging this change, if/when the PR is ready for the next round of review.

%s
You can add 'keep-open' label to prevent this from happening again, or add a comment to keep it open another 90 days`
	warningComment = `This PR hasn't been active in %s. It will be closed in %s (%s).

%s
You can add 'keep-open' label to prevent this from happening, or add a comment to keep it open another 90 days`
)

var (
	closingCommentRE = regexp.MustCompile(`This PR hasn't been active in \d+ days?\..*label to prevent this from happening again`)
	warningCommentRE = regexp.MustCompile(`This PR hasn't been active in \d+ days?\..*be closed in \d+ days?`)
)

// CloseStalePR will ask the Bot to close any PullRequest that didn't
// have any human interactions in `stalePullRequest` duration.
//
// This is done by checking both review and issue comments, and by
// ignoring comments done with a bot name. We also consider re-open on the PR.
type CloseStalePR struct{}

func init() {
	s := CloseStalePR{}
	RegisterMungerOrDie(s)
	RegisterStaleComments(s)
}

// Name is the name usable in --pr-mungers
func (CloseStalePR) Name() string { return "close-stale-pr" }

// RequiredFeatures is a slice of 'features' that must be provided
func (CloseStalePR) RequiredFeatures() []string { return []string{} }

// Initialize will initialize the munger
func (CloseStalePR) Initialize(config *github.Config, features *features.Features) error {
	return nil
}

// EachLoop is called at the start of every munge loop
func (CloseStalePR) EachLoop() error { return nil }

// AddFlags will add any request flags to the cobra `cmd`
func (CloseStalePR) AddFlags(cmd *cobra.Command, config *github.Config) {}

func findLastHumanPullRequestUpdate(obj *github.MungeObject) (*time.Time, error) {
	pr, err := obj.GetPR()
	if err != nil {
		return nil, err
	}

	comments, err := obj.ListReviewComments()
	if err != nil {
		return nil, err
	}

	lastHuman := pr.CreatedAt
	for i := range comments {
		comment := comments[i]
		if comment.User == nil || comment.User.Login == nil || comment.CreatedAt == nil || comment.Body == nil {
			continue
		}
		if *comment.User.Login == botName || *comment.User.Login == jenkinsBotName {
			continue
		}
		if lastHuman.Before(*comment.UpdatedAt) {
			lastHuman = comment.UpdatedAt
		}
	}

	return lastHuman, nil
}

func findLastHumanIssueUpdate(obj *github.MungeObject) (*time.Time, error) {
	lastHuman := obj.Issue.CreatedAt

	comments, err := obj.ListComments()
	if err != nil {
		return nil, err
	}

	for i := range comments {
		comment := comments[i]
		if !validComment(comment) {
			continue
		}
		if mergeBotComment(comment) || jenkinsBotComment(comment) {
			continue
		}
		if lastHuman.Before(*comment.UpdatedAt) {
			lastHuman = comment.UpdatedAt
		}
	}

	return lastHuman, nil
}

func findLastInterestingEventUpdate(obj *github.MungeObject) (*time.Time, error) {
	lastInteresting := obj.Issue.CreatedAt

	events, err := obj.GetEvents()
	if err != nil {
		return nil, err
	}

	for i := range events {
		event := events[i]
		if event.Event == nil || *event.Event != "reopened" {
			continue
		}

		if lastInteresting.Before(*event.CreatedAt) {
			lastInteresting = event.CreatedAt
		}
	}

	return lastInteresting, nil
}

func findLastModificationTime(obj *github.MungeObject) (*time.Time, error) {
	lastHumanIssue, err := findLastHumanIssueUpdate(obj)
	if err != nil {
		return nil, err
	}
	lastHumanPR, err := findLastHumanPullRequestUpdate(obj)
	if err != nil {
		return nil, err
	}
	lastInterestingEvent, err := findLastInterestingEventUpdate(obj)
	if err != nil {
		return nil, err
	}

	lastModif := lastHumanPR
	if lastHumanIssue.After(*lastModif) {
		lastModif = lastHumanIssue
	}
	if lastInterestingEvent.After(*lastModif) {
		lastModif = lastInterestingEvent
	}

	return lastModif, nil
}

// Find the last warning comment that the bot has posted.
// It can return an empty comment if it fails to find one, even if there are no errors.
func findLatestWarningComment(obj *github.MungeObject) (*githubapi.IssueComment, error) {
	var lastFoundComment *githubapi.IssueComment

	comments, err := obj.ListComments()
	if err != nil {
		return nil, err
	}

	for i := range comments {
		comment := comments[i]
		if !validComment(comment) {
			continue
		}
		if !mergeBotComment(comment) {
			continue
		}

		if !warningCommentRE.MatchString(*comment.Body) {
			continue
		}

		if lastFoundComment == nil || lastFoundComment.CreatedAt.Before(*comment.UpdatedAt) {
			if lastFoundComment != nil {
				obj.DeleteComment(lastFoundComment)
			}
			lastFoundComment = comment
		}
	}

	return lastFoundComment, nil
}

func durationToDays(duration time.Duration) string {
	days := duration / day
	dayString := "days"
	if days == 1 || days == -1 {
		dayString = "day"
	}
	return fmt.Sprintf("%d %s", days, dayString)
}

func closePullRequest(obj *github.MungeObject, inactiveFor time.Duration) {
	mention := mungerutil.GetIssueUsers(obj.Issue).AllUsers().Mention().Join()
	if mention != "" {
		mention = "cc " + mention + "\n"
	}

	comment, err := findLatestWarningComment(obj)
	if err != nil {
		glog.Error("Failed to findLatestWarningComment: ", err)
		return
	}
	if comment != nil {
		obj.DeleteComment(comment)
	}

	obj.WriteComment(fmt.Sprintf(closingComment, durationToDays(inactiveFor), mention))
	obj.ClosePR()
}

func postWarningComment(obj *github.MungeObject, inactiveFor time.Duration, closeIn time.Duration) {
	mention := mungerutil.GetIssueUsers(obj.Issue).AllUsers().Mention().Join()
	if mention != "" {
		mention = "cc " + mention + "\n"
	}

	closeDate := time.Now().Add(closeIn).Format("Jan 2, 2006")

	obj.WriteComment(fmt.Sprintf(
		warningComment,
		durationToDays(inactiveFor),
		durationToDays(closeIn),
		closeDate,
		mention,
	))
}

func checkAndWarn(obj *github.MungeObject, inactiveFor time.Duration, closeIn time.Duration) {
	if closeIn < day {
		// We are going to close the PR in less than a day. Too late to warn
		return
	}
	comment, err := findLatestWarningComment(obj)
	if err != nil {
		glog.Error("Failed to findLatestWarningComment: ", err)
		return
	}
	if comment == nil {
		// We don't already have the comment. Post it
		postWarningComment(obj, inactiveFor, closeIn)
	} else if time.Since(*comment.UpdatedAt) > remindWarning {
		// It's time to warn again
		obj.DeleteComment(comment)
		postWarningComment(obj, inactiveFor, closeIn)
	} else {
		// We already have a warning, and it's not expired. Do nothing
	}
}

// Munge is the workhorse that will actually close the PRs
func (CloseStalePR) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	if obj.HasLabel(keepOpenLabel) {
		return
	}

	lastModif, err := findLastModificationTime(obj)
	if err != nil {
		glog.Errorf("Failed to find last modification: %v", err)
		return
	}

	closeIn := -time.Since(lastModif.Add(stalePullRequest))
	inactiveFor := time.Since(*lastModif)
	if closeIn <= 0 {
		closePullRequest(obj, inactiveFor)
	} else if closeIn <= startWarning {
		checkAndWarn(obj, inactiveFor, closeIn)
	} else {
		// Pull-request is active. Remove previous potential warning
		// Ignore potential errors, we just want to remove old comments ...
		comment, _ := findLatestWarningComment(obj)
		if comment != nil {
			obj.DeleteComment(comment)
		}
	}
}

func (CloseStalePR) isStaleComment(obj *github.MungeObject, comment *githubapi.IssueComment) bool {
	if !mergeBotComment(comment) {
		return false
	}

	if !closingCommentRE.MatchString(*comment.Body) {
		return false
	}

	return true
}

// StaleComments returns a slice of stale comments
func (s CloseStalePR) StaleComments(obj *github.MungeObject, comments []*githubapi.IssueComment) []*githubapi.IssueComment {
	return forEachCommentTest(obj, comments, s.isStaleComment)
}
<|endoftext|>


<commit_before>package daemon

import (
	"os"
	"runtime"
	"sync/atomic"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/container"
	"github.com/docker/docker/dockerversion"
	"github.com/docker/docker/pkg/fileutils"
	"github.com/docker/docker/pkg/parsers/kernel"
	"github.com/docker/docker/pkg/parsers/operatingsystem"
	"github.com/docker/docker/pkg/platform"
	"github.com/docker/docker/pkg/sysinfo"
	"github.com/docker/docker/pkg/system"
	"github.com/docker/docker/registry"
	"github.com/docker/docker/utils"
	"github.com/docker/docker/volume/drivers"
	"github.com/docker/engine-api/types"
	"github.com/docker/go-connections/sockets"
)

// SystemInfo returns information about the host server the daemon is running on.
func (daemon *Daemon) SystemInfo() (*types.Info, error) {
	kernelVersion := "<unknown>"
	if kv, err := kernel.GetKernelVersion(); err != nil {
		logrus.Warnf("Could not get kernel version: %v", err)
	} else {
		kernelVersion = kv.String()
	}

	operatingSystem := "<unknown>"
	if s, err := operatingsystem.GetOperatingSystem(); err != nil {
		logrus.Warnf("Could not get operating system name: %v", err)
	} else {
		operatingSystem = s
	}

	// Don't do containerized check on Windows
	if runtime.GOOS != "windows" {
		if inContainer, err := operatingsystem.IsContainerized(); err != nil {
			logrus.Errorf("Could not determine if daemon is containerized: %v", err)
			operatingSystem += " (error determining if containerized)"
		} else if inContainer {
			operatingSystem += " (containerized)"
		}
	}

	meminfo, err := system.ReadMemInfo()
	if err != nil {
		logrus.Errorf("Could not read system memory info: %v", err)
	}

	sysInfo := sysinfo.New(true)

	var cRunning, cPaused, cStopped int32
	daemon.containers.ApplyAll(func(c *container.Container) {
		switch c.StateString() {
		case "paused":
			atomic.AddInt32(&cPaused, 1)
		case "running":
			atomic.AddInt32(&cRunning, 1)
		default:
			atomic.AddInt32(&cStopped, 1)
		}
	})

	v := &types.Info{
		ID:                 daemon.ID,
		Containers:         int(cRunning + cPaused + cStopped),
		ContainersRunning:  int(cRunning),
		ContainersPaused:   int(cPaused),
		ContainersStopped:  int(cStopped),
		Images:             len(daemon.imageStore.Map()),
		Driver:             daemon.GraphDriverName(),
		DriverStatus:       daemon.layerStore.DriverStatus(),
		Plugins:            daemon.showPluginsInfo(),
		IPv4Forwarding:     !sysInfo.IPv4ForwardingDisabled,
		BridgeNfIptables:   !sysInfo.BridgeNFCallIPTablesDisabled,
		BridgeNfIP6tables:  !sysInfo.BridgeNFCallIP6TablesDisabled,
		Debug:              utils.IsDebugEnabled(),
		NFd:                fileutils.GetTotalUsedFds(),
		NGoroutines:        runtime.NumGoroutine(),
		SystemTime:         time.Now().Format(time.RFC3339Nano),
		ExecutionDriver:    daemon.ExecutionDriver().Name(),
		LoggingDriver:      daemon.defaultLogConfig.Type,
		CgroupDriver:       daemon.getCgroupDriver(),
		NEventsListener:    daemon.EventsService.SubscribersCount(),
		KernelVersion:      kernelVersion,
		OperatingSystem:    operatingSystem,
		IndexServerAddress: registry.IndexServer,
		OSType:             platform.OSType,
		Architecture:       platform.Architecture,
		RegistryConfig:     daemon.RegistryService.ServiceConfig(),
		NCPU:               runtime.NumCPU(),
		MemTotal:           meminfo.MemTotal,
		DockerRootDir:      daemon.configStore.Root,
		Labels:             daemon.configStore.Labels,
		ExperimentalBuild:  utils.ExperimentalBuild(),
		ServerVersion:      dockerversion.Version,
		ClusterStore:       daemon.configStore.ClusterStore,
		ClusterAdvertise:   daemon.configStore.ClusterAdvertise,
		HTTPProxy:          sockets.GetProxyEnv("http_proxy"),
		HTTPSProxy:         sockets.GetProxyEnv("https_proxy"),
		NoProxy:            sockets.GetProxyEnv("no_proxy"),
	}

	// TODO Windows. Refactor this more once sysinfo is refactored into
	// platform specific code. On Windows, sysinfo.cgroupMemInfo and
	// sysinfo.cgroupCpuInfo will be nil otherwise and cause a SIGSEGV if
	// an attempt is made to access through them.
	if runtime.GOOS != "windows" {
		v.MemoryLimit = sysInfo.MemoryLimit
		v.SwapLimit = sysInfo.SwapLimit
		v.KernelMemory = sysInfo.KernelMemory
		v.OomKillDisable = sysInfo.OomKillDisable
		v.CPUCfsPeriod = sysInfo.CPUCfsPeriod
		v.CPUCfsQuota = sysInfo.CPUCfsQuota
		v.CPUShares = sysInfo.CPUShares
		v.CPUSet = sysInfo.Cpuset
	}

	if hostname, err := os.Hostname(); err == nil {
		v.Name = hostname
	}

	return v, nil
}

// SystemVersion returns version information about the daemon.
func (daemon *Daemon) SystemVersion() types.Version {
	v := types.Version{
		Version:      dockerversion.Version,
		GitCommit:    dockerversion.GitCommit,
		GoVersion:    runtime.Version(),
		Os:           runtime.GOOS,
		Arch:         runtime.GOARCH,
		BuildTime:    dockerversion.BuildTime,
		Experimental: utils.ExperimentalBuild(),
	}

	if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
		v.KernelVersion = kernelVersion.String()
	}

	return v
}

func (daemon *Daemon) showPluginsInfo() types.PluginsInfo {
	var pluginsInfo types.PluginsInfo

	pluginsInfo.Volume = volumedrivers.GetDriverList()

	networkDriverList := daemon.GetNetworkDriverList()
	for nd := range networkDriverList {
		pluginsInfo.Network = append(pluginsInfo.Network, nd)
	}

	pluginsInfo.Authorization = daemon.configStore.AuthorizationPlugins

	return pluginsInfo
}
<commit_msg>handle kernel version error in version api<commit_after>package daemon

import (
	"os"
	"runtime"
	"sync/atomic"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/container"
	"github.com/docker/docker/dockerversion"
	"github.com/docker/docker/pkg/fileutils"
	"github.com/docker/docker/pkg/parsers/kernel"
	"github.com/docker/docker/pkg/parsers/operatingsystem"
	"github.com/docker/docker/pkg/platform"
	"github.com/docker/docker/pkg/sysinfo"
	"github.com/docker/docker/pkg/system"
	"github.com/docker/docker/registry"
	"github.com/docker/docker/utils"
	"github.com/docker/docker/volume/drivers"
	"github.com/docker/engine-api/types"
	"github.com/docker/go-connections/sockets"
)

// SystemInfo returns information about the host server the daemon is running on.
func (daemon *Daemon) SystemInfo() (*types.Info, error) {
	kernelVersion := "<unknown>"
	if kv, err := kernel.GetKernelVersion(); err != nil {
		logrus.Warnf("Could not get kernel version: %v", err)
	} else {
		kernelVersion = kv.String()
	}

	operatingSystem := "<unknown>"
	if s, err := operatingsystem.GetOperatingSystem(); err != nil {
		logrus.Warnf("Could not get operating system name: %v", err)
	} else {
		operatingSystem = s
	}

	// Don't do containerized check on Windows
	if runtime.GOOS != "windows" {
		if inContainer, err := operatingsystem.IsContainerized(); err != nil {
			logrus.Errorf("Could not determine if daemon is containerized: %v", err)
			operatingSystem += " (error determining if containerized)"
		} else if inContainer {
			operatingSystem += " (containerized)"
		}
	}

	meminfo, err := system.ReadMemInfo()
	if err != nil {
		logrus.Errorf("Could not read system memory info: %v", err)
	}

	sysInfo := sysinfo.New(true)

	var cRunning, cPaused, cStopped int32
	daemon.containers.ApplyAll(func(c *container.Container) {
		switch c.StateString() {
		case "paused":
			atomic.AddInt32(&cPaused, 1)
		case "running":
			atomic.AddInt32(&cRunning, 1)
		default:
			atomic.AddInt32(&cStopped, 1)
		}
	})

	v := &types.Info{
		ID:                 daemon.ID,
		Containers:         int(cRunning + cPaused + cStopped),
		ContainersRunning:  int(cRunning),
		ContainersPaused:   int(cPaused),
		ContainersStopped:  int(cStopped),
		Images:             len(daemon.imageStore.Map()),
		Driver:             daemon.GraphDriverName(),
		DriverStatus:       daemon.layerStore.DriverStatus(),
		Plugins:            daemon.showPluginsInfo(),
		IPv4Forwarding:     !sysInfo.IPv4ForwardingDisabled,
		BridgeNfIptables:   !sysInfo.BridgeNFCallIPTablesDisabled,
		BridgeNfIP6tables:  !sysInfo.BridgeNFCallIP6TablesDisabled,
		Debug:              utils.IsDebugEnabled(),
		NFd:                fileutils.GetTotalUsedFds(),
		NGoroutines:        runtime.NumGoroutine(),
		SystemTime:         time.Now().Format(time.RFC3339Nano),
		ExecutionDriver:    daemon.ExecutionDriver().Name(),
		LoggingDriver:      daemon.defaultLogConfig.Type,
		CgroupDriver:       daemon.getCgroupDriver(),
		NEventsListener:    daemon.EventsService.SubscribersCount(),
		KernelVersion:      kernelVersion,
		OperatingSystem:    operatingSystem,
		IndexServerAddress: registry.IndexServer,
		OSType:             platform.OSType,
		Architecture:       platform.Architecture,
		RegistryConfig:     daemon.RegistryService.ServiceConfig(),
		NCPU:               runtime.NumCPU(),
		MemTotal:           meminfo.MemTotal,
		DockerRootDir:      daemon.configStore.Root,
		Labels:             daemon.configStore.Labels,
		ExperimentalBuild:  utils.ExperimentalBuild(),
		ServerVersion:      dockerversion.Version,
		ClusterStore:       daemon.configStore.ClusterStore,
		ClusterAdvertise:   daemon.configStore.ClusterAdvertise,
		HTTPProxy:          sockets.GetProxyEnv("http_proxy"),
		HTTPSProxy:         sockets.GetProxyEnv("https_proxy"),
		NoProxy:            sockets.GetProxyEnv("no_proxy"),
	}

	// TODO Windows. Refactor this more once sysinfo is refactored into
	// platform specific code. On Windows, sysinfo.cgroupMemInfo and
	// sysinfo.cgroupCpuInfo will be nil otherwise and cause a SIGSEGV if
	// an attempt is made to access through them.
	if runtime.GOOS != "windows" {
		v.MemoryLimit = sysInfo.MemoryLimit
		v.SwapLimit = sysInfo.SwapLimit
		v.KernelMemory = sysInfo.KernelMemory
		v.OomKillDisable = sysInfo.OomKillDisable
		v.CPUCfsPeriod = sysInfo.CPUCfsPeriod
		v.CPUCfsQuota = sysInfo.CPUCfsQuota
		v.CPUShares = sysInfo.CPUShares
		v.CPUSet = sysInfo.Cpuset
	}

	if hostname, err := os.Hostname(); err == nil {
		v.Name = hostname
	}

	return v, nil
}

// SystemVersion returns version information about the daemon.
func (daemon *Daemon) SystemVersion() types.Version {
	v := types.Version{
		Version:      dockerversion.Version,
		GitCommit:    dockerversion.GitCommit,
		GoVersion:    runtime.Version(),
		Os:           runtime.GOOS,
		Arch:         runtime.GOARCH,
		BuildTime:    dockerversion.BuildTime,
		Experimental: utils.ExperimentalBuild(),
	}

	kernelVersion := "<unknown>"
	if kv, err := kernel.GetKernelVersion(); err != nil {
		logrus.Warnf("Could not get kernel version: %v", err)
	} else {
		kernelVersion = kv.String()
	}
	v.KernelVersion = kernelVersion

	return v
}

func (daemon *Daemon) showPluginsInfo() types.PluginsInfo {
	var pluginsInfo types.PluginsInfo

	pluginsInfo.Volume = volumedrivers.GetDriverList()

	networkDriverList := daemon.GetNetworkDriverList()
	for nd := range networkDriverList {
		pluginsInfo.Network = append(pluginsInfo.Network, nd)
	}

	pluginsInfo.Authorization = daemon.configStore.AuthorizationPlugins

	return pluginsInfo
}
<|endoftext|>


<commit_before>/*
 Copyright 2016 Padduck, LLC

 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 environments

import (
	"errors"
	"io"
	"os"
	"os/exec"
	"strconv"
	"sync"
	"syscall"
	"time"

	"github.com/gorilla/websocket"
	"github.com/pufferpanel/pufferd/config"
	ppError "github.com/pufferpanel/pufferd/errors"
	"github.com/pufferpanel/pufferd/logging"
	"github.com/pufferpanel/pufferd/utils"
	"github.com/shirou/gopsutil/process"
	"fmt"
)

type standard struct {
	RootDirectory string
	ConsoleBuffer utils.Cache
	WSManager     utils.WebSocketManager
	mainProcess   *exec.Cmd
	stdInWriter   io.Writer
	wait          sync.WaitGroup
}

func (s *standard) Execute(cmd string, args []string) (stdOut []byte, err error) {
	stdOut = make([]byte, 0)
	err = s.ExecuteAsync(cmd, args)
	if err != nil {
		return
	}
	err = s.WaitForMainProcess()
	return
}

func (s *standard) ExecuteAsync(cmd string, args []string) (err error) {
	if s.IsRunning() {
		err = errors.New("A process is already running (" + strconv.Itoa(s.mainProcess.Process.Pid) + ")")
		return
	}
	s.mainProcess = exec.Command(cmd, args...)
	s.mainProcess.Dir = s.RootDirectory
	s.mainProcess.Env = append(os.Environ(), "HOME="+s.RootDirectory)
	wrapper := s.createWrapper()
	s.mainProcess.Stdout = wrapper
	s.mainProcess.Stderr = wrapper
	pipe, err := s.mainProcess.StdinPipe()
	if err != nil {
		logging.Error("Error starting process", err)
	}
	s.stdInWriter = pipe
	s.wait = sync.WaitGroup{}
	s.wait.Add(1)
	err = s.mainProcess.Start()
	go func() {
		s.mainProcess.Wait()
		s.wait.Done()
	}()
	if err != nil && err.Error() != "exit status 1" {
		logging.Error("Error starting process", err)
	}
	return
}

func (s *standard) ExecuteInMainProcess(cmd string) (err error) {
	if !s.IsRunning() {
		err = errors.New("Main process has not been started")
		return
	}
	stdIn := s.stdInWriter
	_, err = io.WriteString(stdIn, cmd+"\r")
	return
}

func (s *standard) Kill() (err error) {
	if !s.IsRunning() {
		return
	}
	err = s.mainProcess.Process.Kill()
	s.mainProcess.Process.Release()
	s.mainProcess = nil
	return
}

func (s *standard) Create() error {
	return os.Mkdir(s.RootDirectory, 0755)
}

func (s *standard) Update() error {
	return nil
}

func (s *standard) Delete() (err error) {
	err = os.RemoveAll(s.RootDirectory)
	return
}

func (s *standard) IsRunning() (isRunning bool) {
	isRunning = s.mainProcess != nil && s.mainProcess.Process != nil
	if isRunning {
		process, pErr := os.FindProcess(s.mainProcess.Process.Pid)
		if process == nil || pErr != nil {
			isRunning = false
		} else if process.Signal(syscall.Signal(0)) != nil {
			isRunning = false
		}
	}
	return
}

func (s *standard) WaitForMainProcess() error {
	return s.WaitForMainProcessFor(0)
}

func (s *standard) WaitForMainProcessFor(timeout int) (err error) {
	if s.IsRunning() {
		if timeout > 0 {
			var timer = time.AfterFunc(time.Duration(timeout)*time.Millisecond, func() {
				err = s.Kill()
			})
			s.wait.Wait()
			timer.Stop()
		} else {
			s.wait.Wait()
		}
	}
	return
}

func (s *standard) GetRootDirectory() string {
	return s.RootDirectory
}

func (s *standard) GetConsole() (console []string, epoch int64) {
	console, epoch = s.ConsoleBuffer.Read()
	return
}

func (s *standard) GetConsoleFrom(time int64) (console []string, epoch int64) {
	console, epoch = s.ConsoleBuffer.ReadFrom(time)
	return
}

func (s *standard) AddListener(ws *websocket.Conn) {
	s.WSManager.Register(ws)
}

func (s *standard) GetStats() (map[string]interface{}, error) {
	if !s.IsRunning() {
		return nil, ppError.NewServerOffline()
	}
	process, err := process.NewProcess(int32(s.mainProcess.Process.Pid))
	if err != nil {
		return nil, err
	}
	resultMap := make(map[string]interface{})
	memMap, _ := process.MemoryInfo()
	resultMap["memory"] = memMap.RSS
	cpu, _ := process.Percent(time.Millisecond * 50)
	resultMap["cpu"] = cpu
	return resultMap, nil
}

func (s *standard) DisplayToConsole(msg string, data ...interface{}) {
	if len(data) == 0 {
		fmt.Fprint(s.ConsoleBuffer, msg)
	} else {
		fmt.Fprintf(s.ConsoleBuffer, msg, data...)
	}
}

func (s *standard) createWrapper() io.Writer {
	if config.Get("forward") == "true" {
		return io.MultiWriter(os.Stdout, s.ConsoleBuffer, s.WSManager)
	}
	return io.MultiWriter(s.ConsoleBuffer, s.WSManager)
}
<commit_msg>Print out started PID<commit_after>/*
 Copyright 2016 Padduck, LLC

 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 environments

import (
	"errors"
	"io"
	"os"
	"os/exec"
	"strconv"
	"sync"
	"syscall"
	"time"

	"github.com/gorilla/websocket"
	"github.com/pufferpanel/pufferd/config"
	ppError "github.com/pufferpanel/pufferd/errors"
	"github.com/pufferpanel/pufferd/logging"
	"github.com/pufferpanel/pufferd/utils"
	"github.com/shirou/gopsutil/process"
	"fmt"
)

type standard struct {
	RootDirectory string
	ConsoleBuffer utils.Cache
	WSManager     utils.WebSocketManager
	mainProcess   *exec.Cmd
	stdInWriter   io.Writer
	wait          sync.WaitGroup
}

func (s *standard) Execute(cmd string, args []string) (stdOut []byte, err error) {
	stdOut = make([]byte, 0)
	err = s.ExecuteAsync(cmd, args)
	if err != nil {
		return
	}
	err = s.WaitForMainProcess()
	return
}

func (s *standard) ExecuteAsync(cmd string, args []string) (err error) {
	if s.IsRunning() {
		err = errors.New("A process is already running (" + strconv.Itoa(s.mainProcess.Process.Pid) + ")")
		return
	}
	s.mainProcess = exec.Command(cmd, args...)
	s.mainProcess.Dir = s.RootDirectory
	s.mainProcess.Env = append(os.Environ(), "HOME="+s.RootDirectory)
	wrapper := s.createWrapper()
	s.mainProcess.Stdout = wrapper
	s.mainProcess.Stderr = wrapper
	pipe, err := s.mainProcess.StdinPipe()
	if err != nil {
		logging.Error("Error starting process", err)
	}
	s.stdInWriter = pipe
	s.wait = sync.WaitGroup{}
	s.wait.Add(1)
	err = s.mainProcess.Start()
	go func() {
		s.mainProcess.Wait()
		s.wait.Done()
	}()
	if err != nil && err.Error() != "exit status 1" {
		logging.Error("Error starting process", err)
	}
	logging.Debug("Process started (" + strconv.Itoa(s.mainProcess.Process.Pid) + ")")
	return
}

func (s *standard) ExecuteInMainProcess(cmd string) (err error) {
	if !s.IsRunning() {
		err = errors.New("Main process has not been started")
		return
	}
	stdIn := s.stdInWriter
	_, err = io.WriteString(stdIn, cmd+"\r")
	return
}

func (s *standard) Kill() (err error) {
	if !s.IsRunning() {
		return
	}
	err = s.mainProcess.Process.Kill()
	s.mainProcess.Process.Release()
	s.mainProcess = nil
	return
}

func (s *standard) Create() error {
	return os.Mkdir(s.RootDirectory, 0755)
}

func (s *standard) Update() error {
	return nil
}

func (s *standard) Delete() (err error) {
	err = os.RemoveAll(s.RootDirectory)
	return
}

func (s *standard) IsRunning() (isRunning bool) {
	isRunning = s.mainProcess != nil && s.mainProcess.Process != nil
	if isRunning {
		process, pErr := os.FindProcess(s.mainProcess.Process.Pid)
		if process == nil || pErr != nil {
			isRunning = false
		} else if process.Signal(syscall.Signal(0)) != nil {
			isRunning = false
		}
	}
	return
}

func (s *standard) WaitForMainProcess() error {
	return s.WaitForMainProcessFor(0)
}

func (s *standard) WaitForMainProcessFor(timeout int) (err error) {
	if s.IsRunning() {
		if timeout > 0 {
			var timer = time.AfterFunc(time.Duration(timeout)*time.Millisecond, func() {
				err = s.Kill()
			})
			s.wait.Wait()
			timer.Stop()
		} else {
			s.wait.Wait()
		}
	}
	return
}

func (s *standard) GetRootDirectory() string {
	return s.RootDirectory
}

func (s *standard) GetConsole() (console []string, epoch int64) {
	console, epoch = s.ConsoleBuffer.Read()
	return
}

func (s *standard) GetConsoleFrom(time int64) (console []string, epoch int64) {
	console, epoch = s.ConsoleBuffer.ReadFrom(time)
	return
}

func (s *standard) AddListener(ws *websocket.Conn) {
	s.WSManager.Register(ws)
}

func (s *standard) GetStats() (map[string]interface{}, error) {
	if !s.IsRunning() {
		return nil, ppError.NewServerOffline()
	}
	process, err := process.NewProcess(int32(s.mainProcess.Process.Pid))
	if err != nil {
		return nil, err
	}
	resultMap := make(map[string]interface{})
	memMap, _ := process.MemoryInfo()
	resultMap["memory"] = memMap.RSS
	cpu, _ := process.Percent(time.Millisecond * 50)
	resultMap["cpu"] = cpu
	return resultMap, nil
}

func (s *standard) DisplayToConsole(msg string, data ...interface{}) {
	if len(data) == 0 {
		fmt.Fprint(s.ConsoleBuffer, msg)
	} else {
		fmt.Fprintf(s.ConsoleBuffer, msg, data...)
	}
}

func (s *standard) createWrapper() io.Writer {
	if config.Get("forward") == "true" {
		return io.MultiWriter(os.Stdout, s.ConsoleBuffer, s.WSManager)
	}
	return io.MultiWriter(s.ConsoleBuffer, s.WSManager)
}
<|endoftext|>


<commit_before>package main

import (
	"strings"
 )

type MultiMatcher interface {
	MatchString(pattern string) bool
}

type PolarizedMultiMatcher struct {
	matcher MultiMatcher
	polar bool
}

type StringMatcher struct {
	str string
}

func (str StringMatcher) MatchString(pattern string) bool {
	return strings.Contains( str.str, pattern )
}

<commit_msg>Fix StringMatcher match problem<commit_after>package main

import (
	"strings"
 )

type MultiMatcher interface {
	MatchString(testee string) bool
}

type PolarizedMultiMatcher struct {
	matcher MultiMatcher
	polar bool
}

type StringMatcher struct {
	str string
}

func (str StringMatcher) MatchString(testee string) bool {
	return strings.Contains( testee, str.str )
}

<|endoftext|>


<commit_before>package mumbleGO

import "testing"
import "fmt"
import "bytes"

func TestBufCreation(t *testing.T) {
	value := bytes.NewBufferString("00000000000000000003a6K")
	//var value = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xa6K"
	var time uint64 = 239179
	if x := createBuf(time); x != value {
		t.Errorf("Bytes are not correct")

	}
	fmt.Printf("% x", value)
	fmt.Println("")
	fmt.Printf("% x", createBuf(time))
	fmt.Println("")

}

// func TestSqrt(t *testing.T) {
// 	const in, out = 4, 2
// 	if x := Sqrt(in); x != out {
// 		t.Errorf("Sqrt(%v) = %v, want %v", in, x, out)
// 	}
// }
<commit_msg>working byte conversion<commit_after>package mumbleGO

import (
	"encoding/hex"
	"fmt"
	"testing"
)

func TestBufCreation(t *testing.T) {
	var time uint64 = 239179
	fmt.Println()
	if x := hex.EncodeToString(createBuf(time).Bytes()); x != "00000000000000000003a64b" {
		t.Errorf("Bytes are not correct")
	}
}
<|endoftext|>


<commit_before>/**********************************
***  Middleware Chaining in Go  ***
***  Code is under MIT license  ***
***    Code by CodingFerret     ***
*** 	github.com/squiidz      ***
***********************************/

package mw

import (
	"log"
	"net/http"
	"os"
	"runtime"
	"runtime/debug"
)

const (
	DELETE = "41m"
	GET    = "42m"
	POST   = "44m"
)

var (
	LOG = log.New(os.Stdout, "||CLAW|| ", 2)
)

// Very simple Console Logger
func Logger(next http.Handler) http.Handler {
	p := runtime.GOOS
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		switch req.Method {
		case "GET":
			if p != "windows" {
				output(GET, req)
			} else {
				LOG.Printf("[%s] %s %s", req.Method, req.RemoteAddr, req.RequestURI)
			}
		case "POST":
			if p != "windows" {
				output(POST, req)
			} else {
				LOG.Printf("[%s] %s %s", req.Method, req.RemoteAddr, req.RequestURI)
			}
		case "DELETE":
			if p != "windows" {
				output(DELETE, req)
			} else {
				LOG.Printf("[%s] %s %s", req.Method, req.RemoteAddr, req.RequestURI)
			}
		}
		next.ServeHTTP(rw, req)
	})
}

// Set the color
func output(meth string, req *http.Request) {
	LOG.Printf("\x1b[%s[%s]\x1b[0m %s %s", meth, req.Method, req.RemoteAddr, req.RequestURI)
}

// Recovery Middleware
func Recovery(next http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		defer func() {
			if err := recover(); err != nil {
				rw.WriteHeader(http.StatusInternalServerError)
				stack := debug.Stack()
				log.Printf("PANIC: %s\n%s", err, stack)

			}
		}()
		next.ServeHTTP(rw, req)
	})
}
<commit_msg>minor changes<commit_after>/**********************************
***  Middleware Chaining in Go  ***
***  Code is under MIT license  ***
***    Code by CodingFerret     ***
*** 	github.com/squiidz      ***
***********************************/

package mw

import (
	"compress/gzip"
	"io"
	"log"
	"net/http"
	"os"
	"runtime"
	"runtime/debug"
)

const (
	DELETE = "41m"
	GET    = "42m"
	POST   = "44m"
)

var (
	LOG = log.New(os.Stdout, "||CLAW|| ", 2)
)

// Very simple Console Logger
func Logger(next http.Handler) http.Handler {
	p := runtime.GOOS
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		switch req.Method {
		case "GET":
			if p != "windows" {
				output(GET, req)
			} else {
				LOG.Printf("[%s] %s %s", req.Method, req.RemoteAddr, req.RequestURI)
			}
		case "POST":
			if p != "windows" {
				output(POST, req)
			} else {
				LOG.Printf("[%s] %s %s", req.Method, req.RemoteAddr, req.RequestURI)
			}
		case "DELETE":
			if p != "windows" {
				output(DELETE, req)
			} else {
				LOG.Printf("[%s] %s %s", req.Method, req.RemoteAddr, req.RequestURI)
			}
		}
		next.ServeHTTP(rw, req)
	})
}

// Set the color
func output(meth string, req *http.Request) {
	LOG.Printf("\x1b[%s[%s]\x1b[0m %s %s", meth, req.Method, req.RemoteAddr, req.RequestURI)
}

// Recovery Middleware
func Recovery(next http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		defer func() {
			if err := recover(); err != nil {
				rw.WriteHeader(http.StatusInternalServerError)
				stack := debug.Stack()
				log.Printf("PANIC: %s\n%s", err, stack)

			}
		}()
		next.ServeHTTP(rw, req)
	})
}

type zipResponse struct {
	io.Writer
	http.ResponseWriter
}

func (z zipResponse) Write(b []byte) (int, error) {
	if z.Header().Get("Content-Type") == "" {
		z.Header().Set("Content-Type", http.DetectContentType(b))
	}
	return z.Writer.Write(b)
}

// Compressing Middleware
func Zipper(next http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		rw.Header().Set("Content-Encoding", "gzip")

		crw := gzip.NewWriter(rw)
		defer crw.Close()

		zrw := zipResponse{Writer: crw, ResponseWriter: rw}
		next.ServeHTTP(zrw, req)
	})
}
<|endoftext|>


<commit_before>package conductor

import (
	"encoding/json"
	"net/http"
)

// ReadJSON reads data from request body to the interface provided.
func ReadJSON(r *http.Request, data interface{}) error {
	body := make([]byte, r.ContentLength)

	if _, err := r.Body.Read(body); err != nil {
		return err
	}

	if err := json.Unmarshal(body, data); err != nil {
		return err
	}

	return nil
}

// WriteJSON writes data as JSON to the output writer.
// Data expected to be able to be marshaled to JSON.
func WriteJSON(w http.ResponseWriter, data interface{}) error {
	output, err := json.MarshalIndent(data, "", "\t")
	if err != nil {
		return err
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(output)
	return nil
}
<commit_msg>Use spaces for indentation for WriteJSON<commit_after>package conductor

import (
	"encoding/json"
	"net/http"
)

// ReadJSON reads data from request body to the interface provided.
func ReadJSON(r *http.Request, data interface{}) error {
	body := make([]byte, r.ContentLength)

	if _, err := r.Body.Read(body); err != nil {
		return err
	}

	if err := json.Unmarshal(body, data); err != nil {
		return err
	}

	return nil
}

// WriteJSON writes data as JSON to the output writer.
// Data expected to be able to be marshaled to JSON.
func WriteJSON(w http.ResponseWriter, data interface{}) error {
	output, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		return err
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(output)
	return nil
}
<|endoftext|>