<commit_before>// Copyright 2015 Davis Webb
// Copyright 2015 Luke Shumaker
// Copyright 2015 Guntas Grewal
// Copyright 2015 Mark Pundmann

package backend

import (
	"locale"
	"periwinkle"
	"strings"
)

// A Group or mailing list that users may subscribe to.
type Group struct {
	ID                 string         `json:"group_id"`
	ReadPublic         int            `json:"readpublic"`
	ReadConfirmed      int            `json:"readconfirmed"`
	ExistencePublic    int            `json:"existencepublic"`
	ExistenceConfirmed int            `json:"existenceconfirmed"`
	PostPublic         int            `json:"postpublic"`
	PostConfirmed      int            `json:"postconformed"`
	PostMember         int            `json:"postmember"`
	JoinPublic         int            `json:"joinpublic"`
	JoinConfirmed      int            `json:"joinconfirmed"`
	JoinMember         int            `json:"joinmember"`
	Subscriptions      []Subscription `json:"subscriptions"`
}

func (o Group) dbSchema(db *periwinkle.Tx) locale.Error {
	return locale.UntranslatedError(db.CreateTable(&o).Error)
}

func (o Group) dbSeed(db *periwinkle.Tx) locale.Error {
	existence := [2]int{2, 2}
	read := [2]int{2, 2}
	post := [3]int{1, 1, 1}
	join := [3]int{1, 1, 1}
	return locale.UntranslatedError(db.Create(&Group{
		ID:                 "test",
		ReadPublic:         read[0],
		ReadConfirmed:      read[1],
		ExistencePublic:    existence[0],
		ExistenceConfirmed: existence[1],
		PostPublic:         post[0],
		PostConfirmed:      post[1],
		PostMember:         post[2],
		JoinPublic:         join[0],
		JoinConfirmed:      join[1],
		JoinMember:         join[2],
		Subscriptions:      []Subscription{},
	}).Error)
}

func GetGroupByID(db *periwinkle.Tx, id string) *Group {
	id = strings.ToLower(id)
	var o Group
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		dbError(result.Error)
	}
	db.Model(&o).Related(&o.Subscriptions)
	return &o
}

func GetGroupsByMember(db *periwinkle.Tx, user User) []Group {
	subscriptions := user.GetSubscriptions(db)
	var groupIDs []string
	for _, sub := range subscriptions {
		groupIDs = append(groupIDs, sub.GroupID)
	}
	var groups []Group
	if len(groupIDs) > 0 {
		if err := db.Where("id IN (?)", groupIDs).Find(&groups).Error; err != nil {
			dbError(err)
		}
	} else {
		groups = make([]Group, 0)
	}
	groupsByID := make(map[string]Group)
	for _, group := range groups {
		groupsByID[group.ID] = group
	}

	groups = []Group{}
	for _, sub := range subscriptions {
		// only add group if user is confirmed member or
		// if group allows non confirmed members to see that it exists
		if sub.Confirmed || groupsByID[sub.GroupID].ExistenceConfirmed == 2 {
			groups = append(groups, groupsByID[sub.GroupID])
		}
	}
	return groups
}

func GetPublicAndSubscribedGroups(db *periwinkle.Tx, user User) []Group {
	groups := GetGroupsByMember(db, user)
	// also get public groups
	var publicgroups []Group
	if result := db.Where(&Group{ExistencePublic: 1}).Find(&publicgroups); result.Error != nil {
		if !result.RecordNotFound() {
			dbError(result.Error)
		}
	}
	// merge public groups and subscribed groups
	for _, publicgroup := range publicgroups {
		for _, group := range groups {
			if group.ID == publicgroup.ID {
				break
			}
		}
		groups = append(groups, publicgroup)
	}

	// return them
	return groups
}

func GetAllGroups(db *periwinkle.Tx) []Group {
	var o []Group
	if result := db.Find(&o); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		dbError(result.Error)
	}
	return o
}

func NewGroup(db *periwinkle.Tx, name string, existence []int, read []int, post []int, join []int) *Group {
	if name == "" {
		programmerError("Group name can't be empty")
	}
	name = strings.ToLower(name)
	subscriptions := make([]Subscription, 0)
	o := Group{
		ID:                 name,
		ReadPublic:         read[0],
		ReadConfirmed:      read[1],
		ExistencePublic:    existence[0],
		ExistenceConfirmed: existence[1],
		PostPublic:         post[0],
		PostConfirmed:      post[1],
		PostMember:         post[2],
		JoinPublic:         join[0],
		JoinConfirmed:      join[1],
		JoinMember:         join[2],
		Subscriptions:      subscriptions,
	}
	if err := db.Create(&o).Error; err != nil {
		dbError(err)
	}
	return &o
}

func (grp *Group) GetSubscriptions(db *periwinkle.Tx) []Subscription {
	var subscriptions []Subscription
	if result := db.Where("group_id = ?", grp.ID).Find(&subscriptions); result.Error != nil {
		if result.RecordNotFound() {
			return []Subscription{}
		}
		dbError(result.Error)
	}
	return subscriptions
}

func (grp *Group) GetSubscriberIDs(db *periwinkle.Tx) []string {
	subscriptions := grp.GetSubscriptions(db)
	addressIDs := make([]int64, len(subscriptions))
	for i, sub := range subscriptions {
		addressIDs[i] = sub.AddressID
	}
	var addresses []UserAddress
	if len(addressIDs) > 0 {
		if err := db.Where("id IN (?)", addressIDs).Find(&addresses).Error; err != nil {
			dbError(err)
		}
	} else {
		addresses = []UserAddress{}
	}
	userIDSet := map[string]bool{}
	for _, address := range addresses {
		userIDSet[address.UserID] = true
	}
	userIDs := make([]string, len(userIDSet))
	i := 0
	for userID := range userIDSet {
		userIDs[i] = userID
		i++
	}
	return userIDs
}

func (o *Group) Save(db *periwinkle.Tx) {
	if o.Subscriptions != nil {
		var oldSubscriptions []Subscription
		db.Model(o).Related(&oldSubscriptions)

		for _, oldsub := range oldSubscriptions {
			match := false

			for _, newsub := range o.Subscriptions {
				if newsub.AddressID == oldsub.AddressID {
					match = true
					break
				}
			}
			if !match {
				var o UserAddress
				db.First(&o, "id = ?", oldsub.AddressID)
				if o.Medium != "noop" && o.Medium != "admin" {
					if err := db.Where("address_id = ? AND group_id = ?", oldsub.AddressID, oldsub.GroupID).Delete(Subscription{}).Error; err != nil {
						dbError(err)
					}
				}
			}
		}

	}

	if err := db.Save(o).Error; err != nil {
		dbError(err)
	}

}

func (grp *Group) Delete(db *periwinkle.Tx) {
	if err := db.Delete(grp).Error; err != nil {
		dbError(err)
	}
}
<commit_msg>fixed problem with multiple groups showing up<commit_after>// Copyright 2015 Davis Webb
// Copyright 2015 Luke Shumaker
// Copyright 2015 Guntas Grewal
// Copyright 2015 Mark Pundmann

package backend

import (
	"locale"
	"periwinkle"
	"strings"
)

// A Group or mailing list that users may subscribe to.
type Group struct {
	ID                 string         `json:"group_id"`
	ReadPublic         int            `json:"readpublic"`
	ReadConfirmed      int            `json:"readconfirmed"`
	ExistencePublic    int            `json:"existencepublic"`
	ExistenceConfirmed int            `json:"existenceconfirmed"`
	PostPublic         int            `json:"postpublic"`
	PostConfirmed      int            `json:"postconformed"`
	PostMember         int            `json:"postmember"`
	JoinPublic         int            `json:"joinpublic"`
	JoinConfirmed      int            `json:"joinconfirmed"`
	JoinMember         int            `json:"joinmember"`
	Subscriptions      []Subscription `json:"subscriptions"`
}

func (o Group) dbSchema(db *periwinkle.Tx) locale.Error {
	return locale.UntranslatedError(db.CreateTable(&o).Error)
}

func (o Group) dbSeed(db *periwinkle.Tx) locale.Error {
	existence := [2]int{2, 2}
	read := [2]int{2, 2}
	post := [3]int{1, 1, 1}
	join := [3]int{1, 1, 1}
	return locale.UntranslatedError(db.Create(&Group{
		ID:                 "test",
		ReadPublic:         read[0],
		ReadConfirmed:      read[1],
		ExistencePublic:    existence[0],
		ExistenceConfirmed: existence[1],
		PostPublic:         post[0],
		PostConfirmed:      post[1],
		PostMember:         post[2],
		JoinPublic:         join[0],
		JoinConfirmed:      join[1],
		JoinMember:         join[2],
		Subscriptions:      []Subscription{},
	}).Error)
}

func GetGroupByID(db *periwinkle.Tx, id string) *Group {
	id = strings.ToLower(id)
	var o Group
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		dbError(result.Error)
	}
	db.Model(&o).Related(&o.Subscriptions)
	return &o
}

func GetGroupsByMember(db *periwinkle.Tx, user User) []Group {
	subscriptions := user.GetSubscriptions(db)
	var groupIDs []string
	for _, sub := range subscriptions {
		groupIDs = append(groupIDs, sub.GroupID)
	}
	var groups []Group
	if len(groupIDs) > 0 {
		if err := db.Where("id IN (?)", groupIDs).Find(&groups).Error; err != nil {
			dbError(err)
		}
	} else {
		groups = make([]Group, 0)
	}
	groupsByID := make(map[string]Group)
	for _, group := range groups {
		groupsByID[group.ID] = group
	}

	groupset := map[string]Group{}
	for _, sub := range subscriptions {
		// only add group if user is confirmed member or
		// if group allows non confirmed members to see that it exists
		if sub.Confirmed || groupsByID[sub.GroupID].ExistenceConfirmed == 2 {
			groupset[sub.GroupID] = groupsByID[sub.GroupID]
		}
	}
	var finalgroups []Group
	for _, group := range groupset {
		finalgroups = append(finalgroups, group)
	}

	return finalgroups
}

func GetPublicAndSubscribedGroups(db *periwinkle.Tx, user User) []Group {
	groups := GetGroupsByMember(db, user)
	// also get public groups
	var publicgroups []Group
	if result := db.Where(&Group{ExistencePublic: 1}).Find(&publicgroups); result.Error != nil {
		if !result.RecordNotFound() {
			dbError(result.Error)
		}
	}
	// merge public groups and subscribed groups
	for _, publicgroup := range publicgroups {
		for _, group := range groups {
			if group.ID == publicgroup.ID {
				break
			}
		}
		groups = append(groups, publicgroup)
	}

	// return them
	return groups
}

func GetAllGroups(db *periwinkle.Tx) []Group {
	var o []Group
	if result := db.Find(&o); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		dbError(result.Error)
	}
	return o
}

func NewGroup(db *periwinkle.Tx, name string, existence []int, read []int, post []int, join []int) *Group {
	if name == "" {
		programmerError("Group name can't be empty")
	}
	name = strings.ToLower(name)
	subscriptions := make([]Subscription, 0)
	o := Group{
		ID:                 name,
		ReadPublic:         read[0],
		ReadConfirmed:      read[1],
		ExistencePublic:    existence[0],
		ExistenceConfirmed: existence[1],
		PostPublic:         post[0],
		PostConfirmed:      post[1],
		PostMember:         post[2],
		JoinPublic:         join[0],
		JoinConfirmed:      join[1],
		JoinMember:         join[2],
		Subscriptions:      subscriptions,
	}
	if err := db.Create(&o).Error; err != nil {
		dbError(err)
	}
	return &o
}

func (grp *Group) GetSubscriptions(db *periwinkle.Tx) []Subscription {
	var subscriptions []Subscription
	if result := db.Where("group_id = ?", grp.ID).Find(&subscriptions); result.Error != nil {
		if result.RecordNotFound() {
			return []Subscription{}
		}
		dbError(result.Error)
	}
	return subscriptions
}

func (grp *Group) GetSubscriberIDs(db *periwinkle.Tx) []string {
	subscriptions := grp.GetSubscriptions(db)
	addressIDs := make([]int64, len(subscriptions))
	for i, sub := range subscriptions {
		addressIDs[i] = sub.AddressID
	}
	var addresses []UserAddress
	if len(addressIDs) > 0 {
		if err := db.Where("id IN (?)", addressIDs).Find(&addresses).Error; err != nil {
			dbError(err)
		}
	} else {
		addresses = []UserAddress{}
	}
	userIDSet := map[string]bool{}
	for _, address := range addresses {
		userIDSet[address.UserID] = true
	}
	userIDs := make([]string, len(userIDSet))
	i := 0
	for userID := range userIDSet {
		userIDs[i] = userID
		i++
	}
	return userIDs
}

func (o *Group) Save(db *periwinkle.Tx) {
	if o.Subscriptions != nil {
		var oldSubscriptions []Subscription
		db.Model(o).Related(&oldSubscriptions)

		for _, oldsub := range oldSubscriptions {
			match := false

			for _, newsub := range o.Subscriptions {
				if newsub.AddressID == oldsub.AddressID {
					match = true
					break
				}
			}
			if !match {
				var o UserAddress
				db.First(&o, "id = ?", oldsub.AddressID)
				if o.Medium != "noop" && o.Medium != "admin" {
					if err := db.Where("address_id = ? AND group_id = ?", oldsub.AddressID, oldsub.GroupID).Delete(Subscription{}).Error; err != nil {
						dbError(err)
					}
				}
			}
		}

	}

	if err := db.Save(o).Error; err != nil {
		dbError(err)
	}

}

func (grp *Group) Delete(db *periwinkle.Tx) {
	if err := db.Delete(grp).Error; err != nil {
		dbError(err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Davis Webb
// Copyright 2015 Luke Shumaker

package store

import (
	"github.com/jinzhu/gorm"
	he "httpentity"
	"httpentity/util"
	"io"
	"net/http"
	"strings"
	"time"
)

var _ he.NetEntity = &Session{}
var fileSession he.Entity = newFileSession()

// Model /////////////////////////////////////////////////////////////

type Session struct {
	Id       string    `json:"session_id"`
	UserId   string    `json:"user_id"`
	LastUsed time.Time `json:"-"`
}

func (o Session) schema(db *gorm.DB) {
	table := db.CreateTable(&o)
	table.AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT")
}

func NewSession(db *gorm.DB, user *User, password string) *Session {
	if user == nil || !user.CheckPassword(password) {
		return nil
	}
	o := Session{
		Id:       randomString(24),
		UserId:   user.Id,
		LastUsed: time.Now(),
	}
	if err := db.Create(&o).Error; err != nil {
		panic(err)
	}
	return &o
}

func GetSessionById(db *gorm.DB, id string) *Session {
	var o Session
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func (o *Session) Delete(db *gorm.DB) {
	db.Delete(o)
}

func (o *Session) Save(db *gorm.DB) {
	if err := db.Save(o).Error; err != nil {
		panic(err)
	}
}

// View //////////////////////////////////////////////////////////////

func (sess *Session) Encoders() map[string]func(io.Writer) error {
	return defaultEncoders(sess)
}

// File ("Controller") ///////////////////////////////////////////////

type t_fileSession struct {
	methods map[string]func(he.Request) he.Response
}

func newFileSession() t_fileSession {
	r := t_fileSession{}
	r.methods = map[string]func(he.Request) he.Response{
		"GET": func(req he.Request) he.Response {
			sess := req.Things["session"].(*Session)
			return he.StatusOK(sess)
		},
		"POST": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			badbody := he.StatusUnsupportedMediaType(heutil.NetString("submitted body not what expected"))
			hash, ok := req.Entity.(map[string]interface{}); if !ok { return badbody }
			username, ok := hash["username"].(string)      ; if !ok { return badbody }
			password, ok := hash["password"].(string)      ; if !ok { return badbody }
			if len(hash) != 2                                       { return badbody }

			var user *User
			if strings.Contains(username, "@") {
				user = GetUserByAddress(db, "email", username)
			} else {
				user = GetUserById(db, username)
			}

			sess := NewSession(db, user, password)
			if sess == nil {
				return he.StatusForbidden(heutil.NetString("Incorrect username/password"))
			} else {
				ret := he.StatusOK(sess)
				cookie := &http.Cookie{
					Name:     "session_id",
					Value:    sess.Id,
					Secure:   req.Scheme == "https",
					HttpOnly: req.Scheme == "http",
				}
				ret.Headers.Add("Set-Cookie", cookie.String())
				return ret
			}
		},
		"DELETE": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			if sess != nil {
				sess.Delete(db)
			}
			return he.StatusNoContent()
		},
	}
	return r
}

func (d t_fileSession) Methods() map[string]func(he.Request) he.Response {
	return d.methods
}

func (d t_fileSession) Subentity(name string, request he.Request) he.Entity {
	return nil
}
<commit_msg>switch session to the new entity format<commit_after>// Copyright 2015 Davis Webb
// Copyright 2015 Luke Shumaker

package store

import (
	"github.com/jinzhu/gorm"
	he "httpentity"
	"httpentity/util"
	"io"
	"net/http"
	"strings"
	"time"
)

var _ he.NetEntity = &Session{}
var fileSession he.Entity = newFileSession()

// Model /////////////////////////////////////////////////////////////

type Session struct {
	Id       string    `json:"session_id"`
	UserId   string    `json:"user_id"`
	LastUsed time.Time `json:"-"`
}

func (o Session) schema(db *gorm.DB) {
	table := db.CreateTable(&o)
	table.AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT")
}

func NewSession(db *gorm.DB, user *User, password string) *Session {
	if user == nil || !user.CheckPassword(password) {
		return nil
	}
	o := Session{
		Id:       randomString(24),
		UserId:   user.Id,
		LastUsed: time.Now(),
	}
	if err := db.Create(&o).Error; err != nil {
		panic(err)
	}
	return &o
}

func GetSessionById(db *gorm.DB, id string) *Session {
	var o Session
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	return &o
}

func (o *Session) Delete(db *gorm.DB) {
	db.Delete(o)
}

func (o *Session) Save(db *gorm.DB) {
	if err := db.Save(o).Error; err != nil {
		panic(err)
	}
}

// View //////////////////////////////////////////////////////////////

func (sess *Session) Encoders() map[string]func(io.Writer) error {
	return defaultEncoders(sess)
}

// File ("Controller") ///////////////////////////////////////////////

type t_fileSession struct {
	methods map[string]func(he.Request) he.Response
}

func newFileSession() t_fileSession {
	r := t_fileSession{}
	r.methods = map[string]func(he.Request) he.Response{
		"GET": func(req he.Request) he.Response {
			sess := req.Things["session"].(*Session)
			return he.StatusOK(sess)
		},
		"POST": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			type postfmt struct {
				Username string
				Password string
			}
			var entity postfmt
			httperr := safeDecodeJSON(req.Entity, &entity)
			if httperr != nil {
				return httperr.Response()
			}

			var user *User
			if strings.Contains(entity.Username, "@") {
				user = GetUserByAddress(db, "email", entity.Username)
			} else {
				user = GetUserById(db, entity.Username)
			}

			sess := NewSession(db, user, entity.Password)
			if sess == nil {
				return he.StatusForbidden(heutil.NetString("Incorrect username/password"))
			} else {
				ret := he.StatusOK(sess)
				cookie := &http.Cookie{
					Name:     "session_id",
					Value:    sess.Id,
					Secure:   req.Scheme == "https",
					HttpOnly: req.Scheme == "http",
				}
				ret.Headers.Add("Set-Cookie", cookie.String())
				return ret
			}
		},
		"DELETE": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			if sess != nil {
				sess.Delete(db)
			}
			return he.StatusNoContent()
		},
	}
	return r
}

func (d t_fileSession) Methods() map[string]func(he.Request) he.Response {
	return d.methods
}

func (d t_fileSession) Subentity(name string, request he.Request) he.Entity {
	return nil
}
<|endoftext|>


<commit_before>package controller

import (
	. "eaciit/wfdemo-git/library/core"
	. "eaciit/wfdemo-git/library/helper"
	. "eaciit/wfdemo-git/library/models"
	"eaciit/wfdemo-git/web/helper"
	"sort"
	"strings"
	"time"

	"github.com/eaciit/knot/knot.v1"
	tk "github.com/eaciit/toolkit"
)

type AnalyticMeteorologyController struct {
	App
}

func CreateAnalyticMeteorologyController() *AnalyticMeteorologyController {
	var controller = new(AnalyticMeteorologyController)
	return controller
}

func (m *AnalyticMeteorologyController) GetWindCorrelation(k *knot.WebContext) interface{} {
	k.Config.OutputType = knot.OutputJson

	var dataSeries []tk.M
	p := new(PayloadAnalytic)
	e := k.GetPayload(&p)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}
	tStart, tEnd, e := helper.GetStartEndDate(k, p.Period, p.DateStart, p.DateEnd)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	query := []tk.M{}
	pipes := []tk.M{}
	query = append(query, tk.M{"_id": tk.M{"$ne": ""}})
	query = append(query, tk.M{"dateinfo.dateid": tk.M{"$gte": tStart}})
	query = append(query, tk.M{"dateinfo.dateid": tk.M{"$lte": tEnd}})
	// query = append(query, tk.M{"avgwindspeed": tk.M{"$gte": 0.5}})
	if p.Project != "" {
		anProject := strings.Split(p.Project, "(")
		query = append(query, tk.M{"projectname": strings.TrimRight(anProject[0], " ")})
	}

	pipes = append(pipes, tk.M{"$match": tk.M{"$and": query}})
	pipes = append(pipes, tk.M{"$project": tk.M{"turbine": 1, "avgwindspeed": 1, "timestamp": 1}})

	csr, err := DB().Connection.NewQuery().From(new(ScadaData).TableName()).
		Command("pipe", pipes).Cursor(nil)

	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	allres := tk.M{}
	arrturbine := []string{}
	_tturbine := tk.M{}

	for {
		trx := new(ScadaData)
		e := csr.Fetch(trx, 1, false)
		if e != nil {
			break
		}

		dkey := trx.TimeStamp.Format("20060102030405")

		_tkm := allres.Get(trx.Turbine, tk.M{}).(tk.M)
		if trx.AvgWindSpeed != -99999.0 {
			_tkm.Set(dkey, tk.ToFloat64(trx.AvgWindSpeed, 6, tk.RoundingAuto))
		}

		allres.Set(trx.Turbine, _tkm)
		_tturbine.Set(trx.Turbine, 1)
	}

	for key, _ := range _tturbine {
		arrturbine = append(arrturbine, key)
	}

	sort.Strings(arrturbine)
	pturbine := append([]string{}, arrturbine...)
	arrturbine = append([]string{"Turbine"}, arrturbine...)

	if len(p.Turbine) > 0 {
		pturbine = []string{}
		for _, _v := range p.Turbine {
			pturbine = append(pturbine, tk.ToString(_v))
		}
	}

	for _, _turbine := range pturbine {
		_tkm := tk.M{}.Set("Turbine", _turbine)
		for i := 1; i < len(arrturbine); i++ {
			if arrturbine[i] != _turbine {
				_tkm.Set(arrturbine[i],
					GetCorrelation(allres.Get(_turbine, tk.M{}).(tk.M), allres.Get(arrturbine[i], tk.M{}).(tk.M)))
			} else {
				_tkm.Set(arrturbine[i], "")
			}
		}
		dataSeries = append(dataSeries, _tkm)
	}

	data := struct {
		Column []string
		Data   []tk.M
	}{
		Column: arrturbine,
		Data:   dataSeries,
	}

	return helper.CreateResult(true, data, "success")
}

func (c *AnalyticMeteorologyController) AverageWindSpeed(k *knot.WebContext) interface{} {
	k.Config.OutputType = knot.OutputJson

	type PayloadAvgWindSpeed struct {
		Period          string
		Project         string
		Turbine         []interface{}
		DateStart       time.Time
		DateEnd         time.Time
		SeriesBreakDown string
		TimeBreakDown   string
	}

	var (
		pipes    []tk.M
		metTower []tk.M
		turbines []tk.M
		list     []tk.M
	)

	p := new(PayloadAvgWindSpeed)
	e := k.GetPayload(&p)

	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	tStart, tEnd, e := helper.GetStartEndDate(k, p.Period, p.DateStart, p.DateEnd)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	match := tk.M{}

	match.Set("dateinfo.dateid", tk.M{"$gte": tStart, "$lte": tEnd})

	if p.Project != "" {
		anProject := strings.Split(p.Project, "(")
		match.Set("projectname", strings.TrimRight(anProject[0], " "))
	}

	if len(p.Turbine) > 0 {
		match.Set("turbine", tk.M{"$in": p.Turbine})
	}

	group := tk.M{
		"windspeed": tk.M{"$avg": "$avgwindspeed"},
	}

	groupID := tk.M{}

	if strings.ToLower(p.TimeBreakDown) == "date" {
		groupID.Set("dateid", "$dateinfo.dateid")
	} else if strings.ToLower(p.TimeBreakDown) == "monthly" {
		groupID.Set("monthdesc", "$dateinfo.monthdesc")
	}

	if strings.ToLower(p.SeriesBreakDown) == "byturbine" {
		groupID.Set("turbine", "$turbine")
	}

	group.Set("_id", groupID)

	pipes = append(pipes, tk.M{"$match": match})
	pipes = append(pipes, tk.M{"$group": group})
	pipes = append(pipes, tk.M{"$sort": tk.M{"_id": 1}})

	csr, e := DB().Connection.NewQuery().
		From(new(ScadaData).TableName()).
		Command("pipe", pipes).
		Cursor(nil)

	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	e = csr.Fetch(&list, 0, false)

	csr.Close()

	// log.Printf("scada: %#v \n", list)

	for _, val := range list {
		id := val.Get("_id").(tk.M)
		turVal := tk.M{}

		if id.GetString("dateid") == "" {
			turVal.Set("time", id.Get("dateid").(time.Time).Format("01 Feb 2006"))
		} else {
			turVal.Set("time", id.GetString("monthdesc"))
		}

		wind := val.GetFloat64("windspeed")
		turVal.Set("value", wind)

		if p.SeriesBreakDown == "byturbine" {
			turVal.Set("name", id.GetString("turbine"))
		} else {
			turVal.Set("name", "Summary")
		}

		turbines = append(turbines, turVal)
	}

	// met tower

	list = []tk.M{}

	match = tk.M{}

	match.Set("dateinfo.dateid", tk.M{"$gte": tStart, "$lte": tEnd})

	group = tk.M{
		"windspeed": tk.M{"$avg": "$vhubws90mavg"},
	}

	groupID = tk.M{}

	if strings.ToLower(p.TimeBreakDown) == "date" {
		groupID.Set("dateid", "$dateinfo.dateid")
	} else if strings.ToLower(p.TimeBreakDown) == "monthly" {
		groupID.Set("monthdesc", "$dateinfo.monthdesc")
	}

	group.Set("_id", groupID)

	pipes = []tk.M{}
	pipes = append(pipes, tk.M{"$match": match})
	pipes = append(pipes, tk.M{"$group": group})
	pipes = append(pipes, tk.M{"$sort": tk.M{"_id": 1}})

	csr, e = DB().Connection.NewQuery().
		From(new(MetTower).TableName()).
		Command("pipe", pipes).
		Cursor(nil)

	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	e = csr.Fetch(&list, 0, false)

	csr.Close()

	// log.Printf("met: %#v \n", list)

	for _, val := range list {
		id := val.Get("_id").(tk.M)
		turVal := tk.M{}

		if id.GetString("dateid") == "" {
			turVal.Set("time", id.Get("dateid").(time.Time).Format("01 Feb 2006"))
		} else {
			turVal.Set("time", id.GetString("monthdesc"))
		}

		wind := val.GetFloat64("windspeed")
		turVal.Set("name", "Met Tower")
		turVal.Set("value", wind)

		metTower = append(metTower, turVal)
	}

	data := struct {
		Data tk.M
	}{
		Data: tk.M{"mettower": metTower, "turbine": turbines},
	}

	return helper.CreateResult(true, data, "success")
}
<commit_msg>add dash replace empty character to blank value in grid<commit_after>package controller

import (
	. "eaciit/wfdemo-git/library/core"
	. "eaciit/wfdemo-git/library/helper"
	. "eaciit/wfdemo-git/library/models"
	"eaciit/wfdemo-git/web/helper"
	"sort"
	"strings"
	"time"

	"github.com/eaciit/knot/knot.v1"
	tk "github.com/eaciit/toolkit"
)

type AnalyticMeteorologyController struct {
	App
}

func CreateAnalyticMeteorologyController() *AnalyticMeteorologyController {
	var controller = new(AnalyticMeteorologyController)
	return controller
}

func (m *AnalyticMeteorologyController) GetWindCorrelation(k *knot.WebContext) interface{} {
	k.Config.OutputType = knot.OutputJson

	var dataSeries []tk.M
	p := new(PayloadAnalytic)
	e := k.GetPayload(&p)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}
	tStart, tEnd, e := helper.GetStartEndDate(k, p.Period, p.DateStart, p.DateEnd)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	query := []tk.M{}
	pipes := []tk.M{}
	query = append(query, tk.M{"_id": tk.M{"$ne": ""}})
	query = append(query, tk.M{"dateinfo.dateid": tk.M{"$gte": tStart}})
	query = append(query, tk.M{"dateinfo.dateid": tk.M{"$lte": tEnd}})
	// query = append(query, tk.M{"avgwindspeed": tk.M{"$gte": 0.5}})
	if p.Project != "" {
		anProject := strings.Split(p.Project, "(")
		query = append(query, tk.M{"projectname": strings.TrimRight(anProject[0], " ")})
	}

	pipes = append(pipes, tk.M{"$match": tk.M{"$and": query}})
	pipes = append(pipes, tk.M{"$project": tk.M{"turbine": 1, "avgwindspeed": 1, "timestamp": 1}})

	csr, err := DB().Connection.NewQuery().From(new(ScadaData).TableName()).
		Command("pipe", pipes).Cursor(nil)

	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	allres := tk.M{}
	arrturbine := []string{}
	_tturbine := tk.M{}

	for {
		trx := new(ScadaData)
		e := csr.Fetch(trx, 1, false)
		if e != nil {
			break
		}

		dkey := trx.TimeStamp.Format("20060102030405")

		_tkm := allres.Get(trx.Turbine, tk.M{}).(tk.M)
		if trx.AvgWindSpeed != -99999.0 {
			_tkm.Set(dkey, tk.ToFloat64(trx.AvgWindSpeed, 6, tk.RoundingAuto))
		}

		allres.Set(trx.Turbine, _tkm)
		_tturbine.Set(trx.Turbine, 1)
	}

	for key, _ := range _tturbine {
		arrturbine = append(arrturbine, key)
	}

	sort.Strings(arrturbine)
	pturbine := append([]string{}, arrturbine...)
	arrturbine = append([]string{"Turbine"}, arrturbine...)

	if len(p.Turbine) > 0 {
		pturbine = []string{}
		for _, _v := range p.Turbine {
			pturbine = append(pturbine, tk.ToString(_v))
		}
	}

	for _, _turbine := range pturbine {
		_tkm := tk.M{}.Set("Turbine", _turbine)
		for i := 1; i < len(arrturbine); i++ {
			if arrturbine[i] != _turbine {
				_tkm.Set(arrturbine[i],
					GetCorrelation(allres.Get(_turbine, tk.M{}).(tk.M), allres.Get(arrturbine[i], tk.M{}).(tk.M)))
			} else {
				_tkm.Set(arrturbine[i], "-")
			}
		}
		dataSeries = append(dataSeries, _tkm)
	}

	data := struct {
		Column []string
		Data   []tk.M
	}{
		Column: arrturbine,
		Data:   dataSeries,
	}

	return helper.CreateResult(true, data, "success")
}

func (c *AnalyticMeteorologyController) AverageWindSpeed(k *knot.WebContext) interface{} {
	k.Config.OutputType = knot.OutputJson

	type PayloadAvgWindSpeed struct {
		Period          string
		Project         string
		Turbine         []interface{}
		DateStart       time.Time
		DateEnd         time.Time
		SeriesBreakDown string
		TimeBreakDown   string
	}

	var (
		pipes    []tk.M
		metTower []tk.M
		turbines []tk.M
		list     []tk.M
	)

	p := new(PayloadAvgWindSpeed)
	e := k.GetPayload(&p)

	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	tStart, tEnd, e := helper.GetStartEndDate(k, p.Period, p.DateStart, p.DateEnd)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	match := tk.M{}

	match.Set("dateinfo.dateid", tk.M{"$gte": tStart, "$lte": tEnd})

	if p.Project != "" {
		anProject := strings.Split(p.Project, "(")
		match.Set("projectname", strings.TrimRight(anProject[0], " "))
	}

	if len(p.Turbine) > 0 {
		match.Set("turbine", tk.M{"$in": p.Turbine})
	}

	group := tk.M{
		"windspeed": tk.M{"$avg": "$avgwindspeed"},
	}

	groupID := tk.M{}

	if strings.ToLower(p.TimeBreakDown) == "date" {
		groupID.Set("dateid", "$dateinfo.dateid")
	} else if strings.ToLower(p.TimeBreakDown) == "monthly" {
		groupID.Set("monthdesc", "$dateinfo.monthdesc")
	}

	if strings.ToLower(p.SeriesBreakDown) == "byturbine" {
		groupID.Set("turbine", "$turbine")
	}

	group.Set("_id", groupID)

	pipes = append(pipes, tk.M{"$match": match})
	pipes = append(pipes, tk.M{"$group": group})
	pipes = append(pipes, tk.M{"$sort": tk.M{"_id": 1}})

	csr, e := DB().Connection.NewQuery().
		From(new(ScadaData).TableName()).
		Command("pipe", pipes).
		Cursor(nil)

	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	e = csr.Fetch(&list, 0, false)

	csr.Close()

	// log.Printf("scada: %#v \n", list)

	for _, val := range list {
		id := val.Get("_id").(tk.M)
		turVal := tk.M{}

		if id.GetString("dateid") == "" {
			turVal.Set("time", id.Get("dateid").(time.Time).Format("01 Feb 2006"))
		} else {
			turVal.Set("time", id.GetString("monthdesc"))
		}

		wind := val.GetFloat64("windspeed")
		turVal.Set("value", wind)

		if p.SeriesBreakDown == "byturbine" {
			turVal.Set("name", id.GetString("turbine"))
		} else {
			turVal.Set("name", "Summary")
		}

		turbines = append(turbines, turVal)
	}

	// met tower

	list = []tk.M{}

	match = tk.M{}

	match.Set("dateinfo.dateid", tk.M{"$gte": tStart, "$lte": tEnd})

	group = tk.M{
		"windspeed": tk.M{"$avg": "$vhubws90mavg"},
	}

	groupID = tk.M{}

	if strings.ToLower(p.TimeBreakDown) == "date" {
		groupID.Set("dateid", "$dateinfo.dateid")
	} else if strings.ToLower(p.TimeBreakDown) == "monthly" {
		groupID.Set("monthdesc", "$dateinfo.monthdesc")
	}

	group.Set("_id", groupID)

	pipes = []tk.M{}
	pipes = append(pipes, tk.M{"$match": match})
	pipes = append(pipes, tk.M{"$group": group})
	pipes = append(pipes, tk.M{"$sort": tk.M{"_id": 1}})

	csr, e = DB().Connection.NewQuery().
		From(new(MetTower).TableName()).
		Command("pipe", pipes).
		Cursor(nil)

	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	e = csr.Fetch(&list, 0, false)

	csr.Close()

	// log.Printf("met: %#v \n", list)

	for _, val := range list {
		id := val.Get("_id").(tk.M)
		turVal := tk.M{}

		if id.GetString("dateid") == "" {
			turVal.Set("time", id.Get("dateid").(time.Time).Format("01 Feb 2006"))
		} else {
			turVal.Set("time", id.GetString("monthdesc"))
		}

		wind := val.GetFloat64("windspeed")
		turVal.Set("name", "Met Tower")
		turVal.Set("value", wind)

		metTower = append(metTower, turVal)
	}

	data := struct {
		Data tk.M
	}{
		Data: tk.M{"mettower": metTower, "turbine": turbines},
	}

	return helper.CreateResult(true, data, "success")
}
<|endoftext|>


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

// Package sha512 implements the SHA384 and SHA512 hash algorithms as defined
// in FIPS 180-2.
package sha512

import (
	"crypto"
	"hash"
)

func init() {
	crypto.RegisterHash(crypto.SHA384, New384)
	crypto.RegisterHash(crypto.SHA512, New)
}

// The size of a SHA512 checksum in bytes.
const Size = 64

// The size of a SHA384 checksum in bytes.
const Size384 = 48

// The blocksize of SHA512 and SHA384 in bytes.
const BlockSize = 128

const (
	chunk     = 128
	init0     = 0x6a09e667f3bcc908
	init1     = 0xbb67ae8584caa73b
	init2     = 0x3c6ef372fe94f82b
	init3     = 0xa54ff53a5f1d36f1
	init4     = 0x510e527fade682d1
	init5     = 0x9b05688c2b3e6c1f
	init6     = 0x1f83d9abfb41bd6b
	init7     = 0x5be0cd19137e2179
	init0_384 = 0xcbbb9d5dc1059ed8
	init1_384 = 0x629a292a367cd507
	init2_384 = 0x9159015a3070dd17
	init3_384 = 0x152fecd8f70e5939
	init4_384 = 0x67332667ffc00b31
	init5_384 = 0x8eb44a8768581511
	init6_384 = 0xdb0c2e0d64f98fa7
	init7_384 = 0x47b5481dbefa4fa4
)

// digest represents the partial evaluation of a checksum.
type digest struct {
	h     [8]uint64
	x     [chunk]byte
	nx    int
	len   uint64
	is384 bool // mark if this digest is SHA-384
}

func (d *digest) Reset() {
	if !d.is384 {
		d.h[0] = init0
		d.h[1] = init1
		d.h[2] = init2
		d.h[3] = init3
		d.h[4] = init4
		d.h[5] = init5
		d.h[6] = init6
		d.h[7] = init7
	} else {
		d.h[0] = init0_384
		d.h[1] = init1_384
		d.h[2] = init2_384
		d.h[3] = init3_384
		d.h[4] = init4_384
		d.h[5] = init5_384
		d.h[6] = init6_384
		d.h[7] = init7_384
	}
	d.nx = 0
	d.len = 0
}

// New returns a new hash.Hash computing the SHA512 checksum.
func New() hash.Hash {
	d := new(digest)
	d.Reset()
	return d
}

// New384 returns a new hash.Hash computing the SHA384 checksum.
func New384() hash.Hash {
	d := new(digest)
	d.is384 = true
	d.Reset()
	return d
}

func (d *digest) Size() int {
	if !d.is384 {
		return Size
	}
	return Size384
}

func (d *digest) BlockSize() int { return BlockSize }

func (d *digest) Write(p []byte) (nn int, err error) {
	nn = len(p)
	d.len += uint64(nn)
	if d.nx > 0 {
		n := len(p)
		if n > chunk-d.nx {
			n = chunk - d.nx
		}
		for i := 0; i < n; i++ {
			d.x[d.nx+i] = p[i]
		}
		d.nx += n
		if d.nx == chunk {
			block(d, d.x[0:])
			d.nx = 0
		}
		p = p[n:]
	}
	if len(p) >= chunk {
		n := len(p) &^ (chunk - 1)
		block(d, p[:n])
		p = p[n:]
	}
	if len(p) > 0 {
		d.nx = copy(d.x[:], p)
	}
	return
}

func (d0 *digest) Sum(in []byte) []byte {
	// Make a copy of d0 so that caller can keep writing and summing.
	d := new(digest)
	*d = *d0
	hash := d.checkSum()
	if d.is384 {
		return append(in, hash[:Size384]...)
	}
	return append(in, hash[:]...)
}

func (d *digest) checkSum() [Size]byte {
	// Padding.  Add a 1 bit and 0 bits until 112 bytes mod 128.
	len := d.len
	var tmp [128]byte
	tmp[0] = 0x80
	if len%128 < 112 {
		d.Write(tmp[0 : 112-len%128])
	} else {
		d.Write(tmp[0 : 128+112-len%128])
	}

	// Length in bits.
	len <<= 3
	for i := uint(0); i < 16; i++ {
		tmp[i] = byte(len >> (120 - 8*i))
	}
	d.Write(tmp[0:16])

	if d.nx != 0 {
		panic("d.nx != 0")
	}

	h := d.h[:]
	if d.is384 {
		h = d.h[:6]
	}

	var digest [Size]byte
	for i, s := range h {
		digest[i*8] = byte(s >> 56)
		digest[i*8+1] = byte(s >> 48)
		digest[i*8+2] = byte(s >> 40)
		digest[i*8+3] = byte(s >> 32)
		digest[i*8+4] = byte(s >> 24)
		digest[i*8+5] = byte(s >> 16)
		digest[i*8+6] = byte(s >> 8)
		digest[i*8+7] = byte(s)
	}

	return digest
}

// Sum returns the SHA512 checksum of the data.
func Sum512(data []byte) [Size]byte {
	var d digest
	d.Reset()
	d.Write(data)
	return d.checkSum()
}

// Sum384 returns the SHA384 checksum of the data.
func Sum384(data []byte) (sum384 [Size384]byte) {
	var d digest
	d.is384 = true
	d.Reset()
	d.Write(data)
	sum := d.checkSum()
	copy(sum384[:], sum[:Size384])
	return
}
<commit_msg>crypto/sha512: update comment for the Sum512 function.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package sha512 implements the SHA384 and SHA512 hash algorithms as defined
// in FIPS 180-2.
package sha512

import (
	"crypto"
	"hash"
)

func init() {
	crypto.RegisterHash(crypto.SHA384, New384)
	crypto.RegisterHash(crypto.SHA512, New)
}

// The size of a SHA512 checksum in bytes.
const Size = 64

// The size of a SHA384 checksum in bytes.
const Size384 = 48

// The blocksize of SHA512 and SHA384 in bytes.
const BlockSize = 128

const (
	chunk     = 128
	init0     = 0x6a09e667f3bcc908
	init1     = 0xbb67ae8584caa73b
	init2     = 0x3c6ef372fe94f82b
	init3     = 0xa54ff53a5f1d36f1
	init4     = 0x510e527fade682d1
	init5     = 0x9b05688c2b3e6c1f
	init6     = 0x1f83d9abfb41bd6b
	init7     = 0x5be0cd19137e2179
	init0_384 = 0xcbbb9d5dc1059ed8
	init1_384 = 0x629a292a367cd507
	init2_384 = 0x9159015a3070dd17
	init3_384 = 0x152fecd8f70e5939
	init4_384 = 0x67332667ffc00b31
	init5_384 = 0x8eb44a8768581511
	init6_384 = 0xdb0c2e0d64f98fa7
	init7_384 = 0x47b5481dbefa4fa4
)

// digest represents the partial evaluation of a checksum.
type digest struct {
	h     [8]uint64
	x     [chunk]byte
	nx    int
	len   uint64
	is384 bool // mark if this digest is SHA-384
}

func (d *digest) Reset() {
	if !d.is384 {
		d.h[0] = init0
		d.h[1] = init1
		d.h[2] = init2
		d.h[3] = init3
		d.h[4] = init4
		d.h[5] = init5
		d.h[6] = init6
		d.h[7] = init7
	} else {
		d.h[0] = init0_384
		d.h[1] = init1_384
		d.h[2] = init2_384
		d.h[3] = init3_384
		d.h[4] = init4_384
		d.h[5] = init5_384
		d.h[6] = init6_384
		d.h[7] = init7_384
	}
	d.nx = 0
	d.len = 0
}

// New returns a new hash.Hash computing the SHA512 checksum.
func New() hash.Hash {
	d := new(digest)
	d.Reset()
	return d
}

// New384 returns a new hash.Hash computing the SHA384 checksum.
func New384() hash.Hash {
	d := new(digest)
	d.is384 = true
	d.Reset()
	return d
}

func (d *digest) Size() int {
	if !d.is384 {
		return Size
	}
	return Size384
}

func (d *digest) BlockSize() int { return BlockSize }

func (d *digest) Write(p []byte) (nn int, err error) {
	nn = len(p)
	d.len += uint64(nn)
	if d.nx > 0 {
		n := len(p)
		if n > chunk-d.nx {
			n = chunk - d.nx
		}
		for i := 0; i < n; i++ {
			d.x[d.nx+i] = p[i]
		}
		d.nx += n
		if d.nx == chunk {
			block(d, d.x[0:])
			d.nx = 0
		}
		p = p[n:]
	}
	if len(p) >= chunk {
		n := len(p) &^ (chunk - 1)
		block(d, p[:n])
		p = p[n:]
	}
	if len(p) > 0 {
		d.nx = copy(d.x[:], p)
	}
	return
}

func (d0 *digest) Sum(in []byte) []byte {
	// Make a copy of d0 so that caller can keep writing and summing.
	d := new(digest)
	*d = *d0
	hash := d.checkSum()
	if d.is384 {
		return append(in, hash[:Size384]...)
	}
	return append(in, hash[:]...)
}

func (d *digest) checkSum() [Size]byte {
	// Padding.  Add a 1 bit and 0 bits until 112 bytes mod 128.
	len := d.len
	var tmp [128]byte
	tmp[0] = 0x80
	if len%128 < 112 {
		d.Write(tmp[0 : 112-len%128])
	} else {
		d.Write(tmp[0 : 128+112-len%128])
	}

	// Length in bits.
	len <<= 3
	for i := uint(0); i < 16; i++ {
		tmp[i] = byte(len >> (120 - 8*i))
	}
	d.Write(tmp[0:16])

	if d.nx != 0 {
		panic("d.nx != 0")
	}

	h := d.h[:]
	if d.is384 {
		h = d.h[:6]
	}

	var digest [Size]byte
	for i, s := range h {
		digest[i*8] = byte(s >> 56)
		digest[i*8+1] = byte(s >> 48)
		digest[i*8+2] = byte(s >> 40)
		digest[i*8+3] = byte(s >> 32)
		digest[i*8+4] = byte(s >> 24)
		digest[i*8+5] = byte(s >> 16)
		digest[i*8+6] = byte(s >> 8)
		digest[i*8+7] = byte(s)
	}

	return digest
}

// Sum512 returns the SHA512 checksum of the data.
func Sum512(data []byte) [Size]byte {
	var d digest
	d.Reset()
	d.Write(data)
	return d.checkSum()
}

// Sum384 returns the SHA384 checksum of the data.
func Sum384(data []byte) (sum384 [Size384]byte) {
	var d digest
	d.is384 = true
	d.Reset()
	d.Write(data)
	sum := d.checkSum()
	copy(sum384[:], sum[:Size384])
	return
}
<|endoftext|>


<commit_before>package immutabletag

import (
	"encoding/json"
	"github.com/goharbor/harbor/src/pkg/immutabletag/dao"
	dao_model "github.com/goharbor/harbor/src/pkg/immutabletag/dao/model"
	"github.com/goharbor/harbor/src/pkg/immutabletag/model"
)

var (
	// Mgr is a global variable for the default immutablerule manager implementation
	Mgr = NewDefaultRuleManager()
)

// Manager ...
type Manager interface {
	// CreateImmutableRule creates the Immutable Rule
	CreateImmutableRule(m *model.Metadata) (int64, error)
	// UpdateImmutableRule update the immutable rules
	UpdateImmutableRule(projectID int64, ir *model.Metadata) (int64, error)
	// EnableImmutableRule enable/disable immutable rules
	EnableImmutableRule(id int64, enabled bool) (int64, error)
	// GetImmutableRule get immutable rule
	GetImmutableRule(id int64) (*model.Metadata, error)
	// QueryImmutableRuleByProjectID get all immutable rule by project
	QueryImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error)
	// QueryEnabledImmutableRuleByProjectID get all enabled immutable rule by project
	QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error)
	// DeleteImmutableRule delete the immutable rule
	DeleteImmutableRule(id int64) (int64, error)
}

type defaultRuleManager struct {
	dao dao.ImmutableRuleDao
}

func (drm *defaultRuleManager) CreateImmutableRule(ir *model.Metadata) (int64, error) {
	daoRule := &dao_model.ImmutableRule{}
	daoRule.Disabled = ir.Disabled
	daoRule.ProjectID = ir.ProjectID
	data, _ := json.Marshal(ir)
	daoRule.TagFilter = string(data)
	return drm.dao.CreateImmutableRule(daoRule)
}

func (drm *defaultRuleManager) UpdateImmutableRule(projectID int64, ir *model.Metadata) (int64, error) {
	daoRule := &dao_model.ImmutableRule{}
	data, _ := json.Marshal(ir)
	daoRule.ID = ir.ID
	daoRule.TagFilter = string(data)
	return drm.dao.UpdateImmutableRule(projectID, daoRule)
}

func (drm *defaultRuleManager) EnableImmutableRule(id int64, enabled bool) (int64, error) {
	return drm.dao.ToggleImmutableRule(id, enabled)
}

func (drm *defaultRuleManager) GetImmutableRule(id int64) (*model.Metadata, error) {
	daoRule, err := drm.dao.GetImmutableRule(id)
	if err != nil {
		return nil, err
	}
	rule := &model.Metadata{}
	if err = json.Unmarshal([]byte(daoRule.TagFilter), rule); err != nil {
		return nil, err
	}
	rule.ID = daoRule.ID
	rule.Disabled = daoRule.Disabled
	return rule, nil
}

func (drm *defaultRuleManager) QueryImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error) {
	daoRules, err := drm.dao.QueryImmutableRuleByProjectID(projectID)
	if err != nil {
		return nil, err
	}
	var rules []model.Metadata
	for _, daoRule := range daoRules {
		rule := model.Metadata{}
		if err = json.Unmarshal([]byte(daoRule.TagFilter), &rule); err != nil {
			return nil, err
		}
		rule.ID = daoRule.ID
		rule.Disabled = daoRule.Disabled
		rules = append(rules, rule)
	}
	return rules, nil
}

func (drm *defaultRuleManager) QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error) {
	daoRules, err := drm.dao.QueryEnabledImmutableRuleByProjectID(projectID)
	if err != nil {
		return nil, err
	}
	var rules []model.Metadata
	for _, daoRule := range daoRules {
		rule := model.Metadata{}
		if err = json.Unmarshal([]byte(daoRule.TagFilter), &rule); err != nil {
			return nil, err
		}
		rule.ID = daoRule.ID
		rules = append(rules, rule)
	}
	return rules, nil
}

func (drm *defaultRuleManager) DeleteImmutableRule(id int64) (int64, error) {
	return drm.dao.DeleteImmutableRule(id)
}

// NewDefaultRuleManager return a new instance of defaultRuleManager
func NewDefaultRuleManager() Manager {
	return &defaultRuleManager{
		dao: dao.New(),
	}
}
<commit_msg>Fix immutable rule sequence to list API<commit_after>package immutabletag

import (
	"encoding/json"
	"github.com/goharbor/harbor/src/pkg/immutabletag/dao"
	dao_model "github.com/goharbor/harbor/src/pkg/immutabletag/dao/model"
	"github.com/goharbor/harbor/src/pkg/immutabletag/model"
	"sort"
)

var (
	// Mgr is a global variable for the default immutablerule manager implementation
	Mgr = NewDefaultRuleManager()
)

// Manager ...
type Manager interface {
	// CreateImmutableRule creates the Immutable Rule
	CreateImmutableRule(m *model.Metadata) (int64, error)
	// UpdateImmutableRule update the immutable rules
	UpdateImmutableRule(projectID int64, ir *model.Metadata) (int64, error)
	// EnableImmutableRule enable/disable immutable rules
	EnableImmutableRule(id int64, enabled bool) (int64, error)
	// GetImmutableRule get immutable rule
	GetImmutableRule(id int64) (*model.Metadata, error)
	// QueryImmutableRuleByProjectID get all immutable rule by project
	QueryImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error)
	// QueryEnabledImmutableRuleByProjectID get all enabled immutable rule by project
	QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error)
	// DeleteImmutableRule delete the immutable rule
	DeleteImmutableRule(id int64) (int64, error)
}

type defaultRuleManager struct {
	dao dao.ImmutableRuleDao
}

func (drm *defaultRuleManager) CreateImmutableRule(ir *model.Metadata) (int64, error) {
	daoRule := &dao_model.ImmutableRule{}
	daoRule.Disabled = ir.Disabled
	daoRule.ProjectID = ir.ProjectID
	data, _ := json.Marshal(ir)
	daoRule.TagFilter = string(data)
	return drm.dao.CreateImmutableRule(daoRule)
}

func (drm *defaultRuleManager) UpdateImmutableRule(projectID int64, ir *model.Metadata) (int64, error) {
	daoRule := &dao_model.ImmutableRule{}
	data, _ := json.Marshal(ir)
	daoRule.ID = ir.ID
	daoRule.TagFilter = string(data)
	return drm.dao.UpdateImmutableRule(projectID, daoRule)
}

func (drm *defaultRuleManager) EnableImmutableRule(id int64, enabled bool) (int64, error) {
	return drm.dao.ToggleImmutableRule(id, enabled)
}

func (drm *defaultRuleManager) GetImmutableRule(id int64) (*model.Metadata, error) {
	daoRule, err := drm.dao.GetImmutableRule(id)
	if err != nil {
		return nil, err
	}
	rule := &model.Metadata{}
	if err = json.Unmarshal([]byte(daoRule.TagFilter), rule); err != nil {
		return nil, err
	}
	rule.ID = daoRule.ID
	rule.Disabled = daoRule.Disabled
	return rule, nil
}

func (drm *defaultRuleManager) QueryImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error) {
	daoRules, err := drm.dao.QueryImmutableRuleByProjectID(projectID)
	if err != nil {
		return nil, err
	}
	var rules []model.Metadata
	for _, daoRule := range daoRules {
		rule := model.Metadata{}
		if err = json.Unmarshal([]byte(daoRule.TagFilter), &rule); err != nil {
			return nil, err
		}
		rule.ID = daoRule.ID
		rule.Disabled = daoRule.Disabled
		rules = append(rules, rule)
	}
	sort.Slice(rules, func(i, j int) bool {
		return rules[i].ID < rules[j].ID
	})
	return rules, nil
}

func (drm *defaultRuleManager) QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error) {
	daoRules, err := drm.dao.QueryEnabledImmutableRuleByProjectID(projectID)
	if err != nil {
		return nil, err
	}
	var rules []model.Metadata
	for _, daoRule := range daoRules {
		rule := model.Metadata{}
		if err = json.Unmarshal([]byte(daoRule.TagFilter), &rule); err != nil {
			return nil, err
		}
		rule.ID = daoRule.ID
		rules = append(rules, rule)
	}
	return rules, nil
}

func (drm *defaultRuleManager) DeleteImmutableRule(id int64) (int64, error) {
	return drm.dao.DeleteImmutableRule(id)
}

// NewDefaultRuleManager return a new instance of defaultRuleManager
func NewDefaultRuleManager() Manager {
	return &defaultRuleManager{
		dao: dao.New(),
	}
}
<|endoftext|>


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

// Native Client system calls.

package syscall

const OS = "nacl"

// Auto-generated

//sys	Chmod(path string, mode int) (errno int)
//sys	Clock() (clock int)
//sys	Close(fd int) (errno int)
//sys	Exit(code int)
//sys	Fstat(fd int, stat *Stat_t) (errno int)
//sys	Getdents(fd int, buf []byte) (n int, errno int)
//sys	Getpid() (pid int)
//sys	Gettimeofday(tv *Timeval) (errno int)
//sys	Open(path string, mode int, perm int) (fd int, errno int)
//sys	Read(fd int, p []byte) (n int, errno int)
//sys	read(fd int, buf *byte, nbuf int) (n int, errno int)
//sys	Stat(path string, stat *Stat_t) (errno int)
//sys	Write(fd int, p []byte) (n int, errno int)

//sys	MultimediaInit(subsys int) (errno int)
//sys	MultimediaShutdown() (errno int)

//sys	CondCreate() (cv int, errno int)
//sys	CondWait(cv int, mutex int) (errno int)
//sys	CondSignal(cv int) (errno int)
//sys	CondBroadcast(cv int) (errno int)
//sys	CondTimedWaitAbs(cv int, mutex int, abstime *Timespec) (errno int)
//sys	MutexCreate() (mutex int, errno int)
//sys	MutexLock(mutex int) (errno int)
//sys	MutexUnlock(mutex int) (errno int)
//sys	MutexTryLock(mutex int) (errno int) = SYS_MUTEX_TRYLOCK
//sys	SemCreate() (sema int, errno int)
//sys	SemWait(sema int) (errno int)
//sys	SemPost(sema int) (errno int)
//sys	VideoInit(dx int, dy int) (errno int)
//sys	VideoUpdate(data *uint32) (errno int)
//sys	VideoPollEvent(ev *byte) (errno int)
//sys	VideoShutdown() (errno int)
//sys	AudioInit(fmt int, nreq int, data *int) (errno int)
//sys	AudioShutdown() (errno int)
//sys	AudioStream(data *uint16, size *uintptr) (errno int)

// Hand-written

func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
	// Offset passed to system call is 32 bits.  Failure of vision by NaCl.
	if int64(int32(offset)) != offset {
		return 0, ERANGE
	}
	o, _, e := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
	return int64(o), int(e)
}

// Sleep by waiting on a condition variable that will never be signaled.
// TODO(rsc): Replace when NaCl adds a proper sleep system call.
var tcv, tmu int

func init() {
	tmu, _ = MutexCreate()
	tcv, _ = CondCreate()
}

func Sleep(ns int64) (errno int) {
	ts := NsecToTimespec(ns)
	var tv Timeval
	if errno = Gettimeofday(&tv); errno != 0 {
		return
	}
	ts.Sec += tv.Sec
	ts.Nsec += tv.Usec * 1000
	switch {
	case ts.Nsec >= 1e9:
		ts.Nsec -= 1e9
		ts.Sec++
	case ts.Nsec <= -1e9:
		ts.Nsec += 1e9
		ts.Sec--
	}
	if errno = MutexLock(tmu); errno != 0 {
		return
	}
	errno = CondTimedWaitAbs(tcv, tmu, &ts)
	if e := MutexUnlock(tmu); e != 0 && errno == 0 {
		errno = e
	}
	return
}

// Implemented in NaCl but not here; maybe later:
//	SYS_IOCTL
//	SYS_IMC_*
//	SYS_MMAP ???
//	SYS_SRPC_*
//	SYS_SYSCONF

// Implemented in NaCl but not here; used by runtime instead:
//	SYS_SYSBRK
//	SYS_MMAP
//	SYS_MUNMAP
//	SYS_THREAD_*
//	SYS_TLS_*
//	SYS_SCHED_YIELD

// #define'd in NaCl but not picked up by mkerrors_nacl.sh.

const EWOULDBLOCK = EAGAIN

// Not implemented in NaCl but needed to compile other packages.

const (
	SIGTRAP = 5
)

func Pipe(p []int) (errno int) { return ENACL }

func fcntl(fd, cmd, arg int) (val int, errno int) {
	return 0, ENACL
}

func Pread(fd int, p []byte, offset int64) (n int, errno int) {
	return 0, ENACL
}

func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
	return 0, ENACL
}

func Mkdir(path string, mode int) (errno int) { return ENACL }

func Lstat(path string, stat *Stat_t) (errno int) {
	return Stat(path, stat)
}

func Chdir(path string) (errno int) { return ENACL }

func Fchdir(fd int) (errno int) { return ENACL }

func Unlink(path string) (errno int) { return ENACL }

func Rmdir(path string) (errno int) { return ENACL }

func Link(oldpath, newpath string) (errno int) {
	return ENACL
}

func Symlink(path, link string) (errno int) { return ENACL }

func Readlink(path string, buf []byte) (n int, errno int) {
	return 0, ENACL
}

func Rename(oldpath, newpath string) (errno int) {
	return ENACL
}

func Fchmod(fd int, mode int) (errno int) { return ENACL }

func Chown(path string, uid int, gid int) (errno int) {
	return ENACL
}

func Lchown(path string, uid int, gid int) (errno int) {
	return ENACL
}

func Fchown(fd int, uid int, gid int) (errno int) {
	return ENACL
}

func Utimes(path string, tv []Timeval) (errno int) {
	return ENACL
}

func Futimes(fd int, tv []Timeval) (errno int) {
	return ENACL
}

func Truncate(name string, size int64) (errno int) {
	return ENACL
}

func Ftruncate(fd int, length int64) (errno int) {
	return ENACL
}

// NaCL doesn't actually implement Getwd, but it also
// don't implement Chdir, so the fallback algorithm
// fails worse than calling Getwd does.

const ImplementsGetwd = true

func Getwd() (wd string, errno int) { return "", ENACL }

func Getuid() (uid int) { return -1 }

func Geteuid() (euid int) { return -1 }

func Getgid() (gid int) { return -1 }

func Getegid() (egid int) { return -1 }

func Getppid() (ppid int) { return -1 }

func Getgroups() (gids []int, errno int) { return nil, ENACL }

type Sockaddr interface {
	sockaddr()
}

type SockaddrInet4 struct {
	Port int
	Addr [4]byte
}

func (*SockaddrInet4) sockaddr() {}

type SockaddrInet6 struct {
	Port int
	Addr [16]byte
}

func (*SockaddrInet6) sockaddr() {}

type SockaddrUnix struct {
	Name string
}

func (*SockaddrUnix) sockaddr() {}

const (
	AF_INET = 1 + iota
	AF_INET6
	AF_UNIX
	IPPROTO_TCP
	SOCK_DGRAM
	SOCK_STREAM
	SOL_SOCKET
	SOMAXCONN
	SO_DONTROUTE
	SO_KEEPALIVE
	SO_LINGER
	SO_RCVBUF
	SO_REUSEADDR
	SO_SNDBUF
	TCP_NODELAY
	WNOHANG
	WSTOPPED
	PTRACE_TRACEME
	SO_BROADCAST = 0
	SHUT_RDWR    = 0
)

func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
	return 0, nil, ENACL
}

func Getsockname(fd int) (sa Sockaddr, errno int) {
	return nil, ENACL
}

func Getpeername(fd int) (sa Sockaddr, errno int) {
	return nil, ENACL
}

func Bind(fd int, sa Sockaddr) (errno int) { return ENACL }

func Connect(fd int, sa Sockaddr) (errno int) { return ENACL }

func Socket(domain, typ, proto int) (fd, errno int) {
	return 0, ENACL
}

func SetsockoptInt(fd, level, opt int, value int) (errno int) {
	return ENACL
}

func Shutdown(fd, how int) (errno int) { return ENACL }

func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) {
	return 0, nil, ENACL
}

func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) {
	return ENACL
}

func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
	return ENACL
}

type Linger struct {
	Onoff  int32
	Linger int32
}

func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
	return ENACL
}

func Listen(s int, n int) (errno int) { return ENACL }

type Rusage struct {
	Utime    Timeval
	Stime    Timeval
	Maxrss   int32
	Ixrss    int32
	Idrss    int32
	Isrss    int32
	Minflt   int32
	Majflt   int32
	Nswap    int32
	Inblock  int32
	Oublock  int32
	Msgsnd   int32
	Msgrcv   int32
	Nsignals int32
	Nvcsw    int32
	Nivcsw   int32
}

func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
	return 0, ENACL
}

type WaitStatus uint32

func (WaitStatus) Exited() bool { return false }

func (WaitStatus) ExitStatus() int { return -1 }

func (WaitStatus) Signal() int { return -1 }

func (WaitStatus) CoreDump() bool { return false }

func (WaitStatus) Stopped() bool { return false }

func (WaitStatus) Continued() bool { return false }

func (WaitStatus) StopSignal() int { return -1 }

func (WaitStatus) Signaled() bool { return false }

func (WaitStatus) TrapCause() int { return -1 }
<commit_msg>fix build - nacl stubs<commit_after>// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Native Client system calls.

package syscall

const OS = "nacl"

// Auto-generated

//sys	Chmod(path string, mode int) (errno int)
//sys	Clock() (clock int)
//sys	Close(fd int) (errno int)
//sys	Exit(code int)
//sys	Fstat(fd int, stat *Stat_t) (errno int)
//sys	Getdents(fd int, buf []byte) (n int, errno int)
//sys	Getpid() (pid int)
//sys	Gettimeofday(tv *Timeval) (errno int)
//sys	Open(path string, mode int, perm int) (fd int, errno int)
//sys	Read(fd int, p []byte) (n int, errno int)
//sys	read(fd int, buf *byte, nbuf int) (n int, errno int)
//sys	Stat(path string, stat *Stat_t) (errno int)
//sys	Write(fd int, p []byte) (n int, errno int)

//sys	MultimediaInit(subsys int) (errno int)
//sys	MultimediaShutdown() (errno int)

//sys	CondCreate() (cv int, errno int)
//sys	CondWait(cv int, mutex int) (errno int)
//sys	CondSignal(cv int) (errno int)
//sys	CondBroadcast(cv int) (errno int)
//sys	CondTimedWaitAbs(cv int, mutex int, abstime *Timespec) (errno int)
//sys	MutexCreate() (mutex int, errno int)
//sys	MutexLock(mutex int) (errno int)
//sys	MutexUnlock(mutex int) (errno int)
//sys	MutexTryLock(mutex int) (errno int) = SYS_MUTEX_TRYLOCK
//sys	SemCreate() (sema int, errno int)
//sys	SemWait(sema int) (errno int)
//sys	SemPost(sema int) (errno int)
//sys	VideoInit(dx int, dy int) (errno int)
//sys	VideoUpdate(data *uint32) (errno int)
//sys	VideoPollEvent(ev *byte) (errno int)
//sys	VideoShutdown() (errno int)
//sys	AudioInit(fmt int, nreq int, data *int) (errno int)
//sys	AudioShutdown() (errno int)
//sys	AudioStream(data *uint16, size *uintptr) (errno int)

// Hand-written

func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
	// Offset passed to system call is 32 bits.  Failure of vision by NaCl.
	if int64(int32(offset)) != offset {
		return 0, ERANGE
	}
	o, _, e := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
	return int64(o), int(e)
}

// Sleep by waiting on a condition variable that will never be signaled.
// TODO(rsc): Replace when NaCl adds a proper sleep system call.
var tcv, tmu int

func init() {
	tmu, _ = MutexCreate()
	tcv, _ = CondCreate()
}

func Sleep(ns int64) (errno int) {
	ts := NsecToTimespec(ns)
	var tv Timeval
	if errno = Gettimeofday(&tv); errno != 0 {
		return
	}
	ts.Sec += tv.Sec
	ts.Nsec += tv.Usec * 1000
	switch {
	case ts.Nsec >= 1e9:
		ts.Nsec -= 1e9
		ts.Sec++
	case ts.Nsec <= -1e9:
		ts.Nsec += 1e9
		ts.Sec--
	}
	if errno = MutexLock(tmu); errno != 0 {
		return
	}
	errno = CondTimedWaitAbs(tcv, tmu, &ts)
	if e := MutexUnlock(tmu); e != 0 && errno == 0 {
		errno = e
	}
	return
}

// Implemented in NaCl but not here; maybe later:
//	SYS_IOCTL
//	SYS_IMC_*
//	SYS_MMAP ???
//	SYS_SRPC_*
//	SYS_SYSCONF

// Implemented in NaCl but not here; used by runtime instead:
//	SYS_SYSBRK
//	SYS_MMAP
//	SYS_MUNMAP
//	SYS_THREAD_*
//	SYS_TLS_*
//	SYS_SCHED_YIELD

// #define'd in NaCl but not picked up by mkerrors_nacl.sh.

const EWOULDBLOCK = EAGAIN

// Not implemented in NaCl but needed to compile other packages.

const (
	SIGTRAP = 5
)

func Pipe(p []int) (errno int) { return ENACL }

func fcntl(fd, cmd, arg int) (val int, errno int) {
	return 0, ENACL
}

func Pread(fd int, p []byte, offset int64) (n int, errno int) {
	return 0, ENACL
}

func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
	return 0, ENACL
}

func Mkdir(path string, mode int) (errno int) { return ENACL }

func Lstat(path string, stat *Stat_t) (errno int) {
	return Stat(path, stat)
}

func Chdir(path string) (errno int) { return ENACL }

func Fchdir(fd int) (errno int) { return ENACL }

func Unlink(path string) (errno int) { return ENACL }

func Rmdir(path string) (errno int) { return ENACL }

func Link(oldpath, newpath string) (errno int) {
	return ENACL
}

func Symlink(path, link string) (errno int) { return ENACL }

func Readlink(path string, buf []byte) (n int, errno int) {
	return 0, ENACL
}

func Rename(oldpath, newpath string) (errno int) {
	return ENACL
}

func Fchmod(fd int, mode int) (errno int) { return ENACL }

func Chown(path string, uid int, gid int) (errno int) {
	return ENACL
}

func Lchown(path string, uid int, gid int) (errno int) {
	return ENACL
}

func Fchown(fd int, uid int, gid int) (errno int) {
	return ENACL
}

func Utimes(path string, tv []Timeval) (errno int) {
	return ENACL
}

func Futimes(fd int, tv []Timeval) (errno int) {
	return ENACL
}

func Truncate(name string, size int64) (errno int) {
	return ENACL
}

func Ftruncate(fd int, length int64) (errno int) {
	return ENACL
}

// NaCL doesn't actually implement Getwd, but it also
// don't implement Chdir, so the fallback algorithm
// fails worse than calling Getwd does.

const ImplementsGetwd = true

func Getwd() (wd string, errno int) { return "", ENACL }

func Getuid() (uid int) { return -1 }

func Geteuid() (euid int) { return -1 }

func Getgid() (gid int) { return -1 }

func Getegid() (egid int) { return -1 }

func Getppid() (ppid int) { return -1 }

func Getgroups() (gids []int, errno int) { return nil, ENACL }

type Sockaddr interface {
	sockaddr()
}

type SockaddrInet4 struct {
	Port int
	Addr [4]byte
}

func (*SockaddrInet4) sockaddr() {}

type SockaddrInet6 struct {
	Port int
	Addr [16]byte
}

func (*SockaddrInet6) sockaddr() {}

type SockaddrUnix struct {
	Name string
}

func (*SockaddrUnix) sockaddr() {}

const (
	AF_INET = 1 + iota
	AF_INET6
	AF_UNIX
	IPPROTO_TCP
	SOCK_DGRAM
	SOCK_STREAM
	SOCK_RAW
	SOL_SOCKET
	SOMAXCONN
	SO_DONTROUTE
	SO_KEEPALIVE
	SO_LINGER
	SO_RCVBUF
	SO_REUSEADDR
	SO_SNDBUF
	TCP_NODELAY
	WNOHANG
	WSTOPPED
	PTRACE_TRACEME
	SO_BROADCAST = 0
	SHUT_RDWR    = 0
)

func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
	return 0, nil, ENACL
}

func Getsockname(fd int) (sa Sockaddr, errno int) {
	return nil, ENACL
}

func Getpeername(fd int) (sa Sockaddr, errno int) {
	return nil, ENACL
}

func Bind(fd int, sa Sockaddr) (errno int) { return ENACL }

func BindToDevice(fd int, device string) (errno int) { return ENACL }

func Connect(fd int, sa Sockaddr) (errno int) { return ENACL }

func Socket(domain, typ, proto int) (fd, errno int) {
	return 0, ENACL
}

func SetsockoptInt(fd, level, opt int, value int) (errno int) {
	return ENACL
}

func Shutdown(fd, how int) (errno int) { return ENACL }

func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) {
	return 0, nil, ENACL
}

func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) {
	return ENACL
}

func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
	return ENACL
}

type Linger struct {
	Onoff  int32
	Linger int32
}

func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
	return ENACL
}

func Listen(s int, n int) (errno int) { return ENACL }

type Rusage struct {
	Utime    Timeval
	Stime    Timeval
	Maxrss   int32
	Ixrss    int32
	Idrss    int32
	Isrss    int32
	Minflt   int32
	Majflt   int32
	Nswap    int32
	Inblock  int32
	Oublock  int32
	Msgsnd   int32
	Msgrcv   int32
	Nsignals int32
	Nvcsw    int32
	Nivcsw   int32
}

func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
	return 0, ENACL
}

type WaitStatus uint32

func (WaitStatus) Exited() bool { return false }

func (WaitStatus) ExitStatus() int { return -1 }

func (WaitStatus) Signal() int { return -1 }

func (WaitStatus) CoreDump() bool { return false }

func (WaitStatus) Stopped() bool { return false }

func (WaitStatus) Continued() bool { return false }

func (WaitStatus) StopSignal() int { return -1 }

func (WaitStatus) Signaled() bool { return false }

func (WaitStatus) TrapCause() int { return -1 }
<|endoftext|>


<commit_before>package generate

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"

	"github.com/spf13/cobra"
	"github.com/stretchr/testify/require"
)

func TestGenerateActionArgsComplete(t *testing.T) {
	dir := os.TempDir()
	packagePath := filepath.Join(dir, "src", "sample")
	os.MkdirAll(packagePath, 0755)
	os.Chdir(packagePath)

	r := require.New(t)

	cmd := cobra.Command{}

	e := ActionCmd.RunE(&cmd, []string{})
	r.NotNil(e)

	e = ActionCmd.RunE(&cmd, []string{"nodes"})
	r.NotNil(e)

	os.Mkdir("actions", 0755)
	ioutil.WriteFile("actions/app.go", appGo, 0755)

	e = ActionCmd.RunE(&cmd, []string{"nodes", "show"})
	r.Nil(e)
}

func TestGenerateActionActionsFolderExists(t *testing.T) {
	dir := os.TempDir()
	packagePath := filepath.Join(dir, "src", "sample")
	os.MkdirAll(packagePath, 0755)
	os.Chdir(packagePath)

	os.RemoveAll("actions")
	os.RemoveAll("templates")

	r := require.New(t)
	cmd := cobra.Command{}

	e := ActionCmd.RunE(&cmd, []string{"comments", "show", "edit"})
	r.NotNil(e)

	os.Mkdir("actions", 0755)
	ioutil.WriteFile("actions/app.go", appGo, 0755)

	e = ActionCmd.RunE(&cmd, []string{"comments", "show", "edit"})
	r.Nil(e)

	data, _ := ioutil.ReadFile("actions/comments.go")
	r.Contains(string(data), "package actions")
	r.Contains(string(data), `import "github.com/gobuffalo/buffalo"`)
	r.Contains(string(data), "func CommentsShow(c buffalo.Context) error {")
	r.Contains(string(data), "func CommentsEdit(c buffalo.Context) error {")
	r.Contains(string(data), `r.HTML("comments/edit.html")`)
	r.Contains(string(data), `c.Render(200, r.HTML("comments/show.html"))`)

	data, _ = ioutil.ReadFile("templates/comments/show.html")
	r.Contains(string(data), "
Comments#Show
")
}

func TestGenerateActionActionsFileExists(t *testing.T) {
	dir := os.TempDir()
	packagePath := filepath.Join(dir, "src", "sample")
	os.MkdirAll(packagePath, 0755)
	os.Chdir(packagePath)

	os.Mkdir("actions", 0755)
	ioutil.WriteFile("actions/app.go", appGo, 0755)
	r := require.New(t)
	cmd := cobra.Command{}
	usersContent := `package actions
import "log"

func UsersShow(c buffalo.Context) error {
    log.Println("Something Here!")
    return c.Render(200, r.String("OK"))
}
`
	ioutil.WriteFile("actions/users.go", []byte(usersContent), 0755)

	e := ActionCmd.RunE(&cmd, []string{"users", "show"})
	r.Nil(e)

	data, _ := ioutil.ReadFile("actions/users.go")
	r.Contains(string(data), "log.Println(")
	r.Contains(string(data), "func UsersShow")

}

func TestGenerateNewActionWithExistingActions(t *testing.T) {
	dir := os.TempDir()
	packagePath := filepath.Join(dir, "src", "sample")
	os.MkdirAll(packagePath, 0755)
	os.Chdir(packagePath)

	os.RemoveAll("actions")
	os.RemoveAll("templates")

	os.Mkdir("actions", 0755)
	ioutil.WriteFile("actions/app.go", appGo, 0755)
	r := require.New(t)
	cmd := cobra.Command{}
	e := ActionCmd.RunE(&cmd, []string{"posts", "show", "edit"})
	r.Nil(e)

	data, _ := ioutil.ReadFile("actions/posts.go")
	r.Contains(string(data), "package actions")
	r.Contains(string(data), "github.com/gobuffalo/buffalo")
	r.Contains(string(data), "func PostsShow(c buffalo.Context) error {")
	r.Contains(string(data), "func PostsEdit(c buffalo.Context) error {")
	r.Contains(string(data), `r.HTML("posts/edit.html")`)
	r.Contains(string(data), `c.Render(200, r.HTML("posts/show.html"))`)

	e = ActionCmd.RunE(&cmd, []string{"posts", "list"})
	r.Nil(e)

	data, _ = ioutil.ReadFile("actions/posts.go")
	r.Contains(string(data), "package actions")
	r.Contains(string(data), "github.com/gobuffalo/buffalo")
	r.Contains(string(data), "func PostsShow(c buffalo.Context) error {")
	r.Contains(string(data), "func PostsEdit(c buffalo.Context) error {")
	r.Contains(string(data), "func PostsList(c buffalo.Context) error {")
	r.Contains(string(data), `c.Render(200, r.HTML("posts/list.html"))`)

	data, _ = ioutil.ReadFile("templates/posts/list.html")
	r.Contains(string(data), "
Posts#List
")

	data, _ = ioutil.ReadFile("actions/Posts_test.go")
	r.Contains(string(data), "package actions_test")
	r.Contains(string(data), "func (as *ActionSuite) Test_Posts_Show() {")
	r.Contains(string(data), "func (as *ActionSuite) Test_Posts_Edit() {")
	r.Contains(string(data), "func (as *ActionSuite) Test_Posts_List() {")
}

var appGo = []byte(`
package actions
var app *buffalo.App
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: "test",
		})
		app.GET("/", func (c buffalo.Context) error {
			return c.Render(200, r.String("hello"))
		})
	}

	return app
}
`)
<commit_msg>fixed typo<commit_after>package generate

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"

	"github.com/spf13/cobra"
	"github.com/stretchr/testify/require"
)

func TestGenerateActionArgsComplete(t *testing.T) {
	dir := os.TempDir()
	packagePath := filepath.Join(dir, "src", "sample")
	os.MkdirAll(packagePath, 0755)
	os.Chdir(packagePath)

	r := require.New(t)

	cmd := cobra.Command{}

	e := ActionCmd.RunE(&cmd, []string{})
	r.NotNil(e)

	e = ActionCmd.RunE(&cmd, []string{"nodes"})
	r.NotNil(e)

	os.Mkdir("actions", 0755)
	ioutil.WriteFile("actions/app.go", appGo, 0755)

	e = ActionCmd.RunE(&cmd, []string{"nodes", "show"})
	r.Nil(e)
}

func TestGenerateActionActionsFolderExists(t *testing.T) {
	dir := os.TempDir()
	packagePath := filepath.Join(dir, "src", "sample")
	os.MkdirAll(packagePath, 0755)
	os.Chdir(packagePath)

	os.RemoveAll("actions")
	os.RemoveAll("templates")

	r := require.New(t)
	cmd := cobra.Command{}

	e := ActionCmd.RunE(&cmd, []string{"comments", "show", "edit"})
	r.NotNil(e)

	os.Mkdir("actions", 0755)
	ioutil.WriteFile("actions/app.go", appGo, 0755)

	e = ActionCmd.RunE(&cmd, []string{"comments", "show", "edit"})
	r.Nil(e)

	data, _ := ioutil.ReadFile("actions/comments.go")
	r.Contains(string(data), "package actions")
	r.Contains(string(data), `import "github.com/gobuffalo/buffalo"`)
	r.Contains(string(data), "func CommentsShow(c buffalo.Context) error {")
	r.Contains(string(data), "func CommentsEdit(c buffalo.Context) error {")
	r.Contains(string(data), `r.HTML("comments/edit.html")`)
	r.Contains(string(data), `c.Render(200, r.HTML("comments/show.html"))`)

	data, _ = ioutil.ReadFile("templates/comments/show.html")
	r.Contains(string(data), "
Comments#Show
")
}

func TestGenerateActionActionsFileExists(t *testing.T) {
	dir := os.TempDir()
	packagePath := filepath.Join(dir, "src", "sample")
	os.MkdirAll(packagePath, 0755)
	os.Chdir(packagePath)

	os.Mkdir("actions", 0755)
	ioutil.WriteFile("actions/app.go", appGo, 0755)
	r := require.New(t)
	cmd := cobra.Command{}
	usersContent := `package actions
import "log"

func UsersShow(c buffalo.Context) error {
    log.Println("Something Here!")
    return c.Render(200, r.String("OK"))
}
`
	ioutil.WriteFile("actions/users.go", []byte(usersContent), 0755)

	e := ActionCmd.RunE(&cmd, []string{"users", "show"})
	r.Nil(e)

	data, _ := ioutil.ReadFile("actions/users.go")
	r.Contains(string(data), "log.Println(")
	r.Contains(string(data), "func UsersShow")

}

func TestGenerateNewActionWithExistingActions(t *testing.T) {
	dir := os.TempDir()
	packagePath := filepath.Join(dir, "src", "sample")
	os.MkdirAll(packagePath, 0755)
	os.Chdir(packagePath)

	os.RemoveAll("actions")
	os.RemoveAll("templates")

	os.Mkdir("actions", 0755)
	ioutil.WriteFile("actions/app.go", appGo, 0755)
	r := require.New(t)
	cmd := cobra.Command{}
	e := ActionCmd.RunE(&cmd, []string{"posts", "show", "edit"})
	r.Nil(e)

	data, _ := ioutil.ReadFile("actions/posts.go")
	r.Contains(string(data), "package actions")
	r.Contains(string(data), "github.com/gobuffalo/buffalo")
	r.Contains(string(data), "func PostsShow(c buffalo.Context) error {")
	r.Contains(string(data), "func PostsEdit(c buffalo.Context) error {")
	r.Contains(string(data), `r.HTML("posts/edit.html")`)
	r.Contains(string(data), `c.Render(200, r.HTML("posts/show.html"))`)

	e = ActionCmd.RunE(&cmd, []string{"posts", "list"})
	r.Nil(e)

	data, _ = ioutil.ReadFile("actions/posts.go")
	r.Contains(string(data), "package actions")
	r.Contains(string(data), "github.com/gobuffalo/buffalo")
	r.Contains(string(data), "func PostsShow(c buffalo.Context) error {")
	r.Contains(string(data), "func PostsEdit(c buffalo.Context) error {")
	r.Contains(string(data), "func PostsList(c buffalo.Context) error {")
	r.Contains(string(data), `c.Render(200, r.HTML("posts/list.html"))`)

	data, _ = ioutil.ReadFile("templates/posts/list.html")
	r.Contains(string(data), "
Posts#List
")

	data, _ = ioutil.ReadFile("actions/posts_test.go")
	r.Contains(string(data), "package actions_test")
	r.Contains(string(data), "func (as *ActionSuite) Test_Posts_Show() {")
	r.Contains(string(data), "func (as *ActionSuite) Test_Posts_Edit() {")
	r.Contains(string(data), "func (as *ActionSuite) Test_Posts_List() {")
}

var appGo = []byte(`
package actions
var app *buffalo.App
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: "test",
		})
		app.GET("/", func (c buffalo.Context) error {
			return c.Render(200, r.String("hello"))
		})
	}

	return app
}
`)
<|endoftext|>


<commit_before>package workspace

import (
	"errors"
	"fmt"
	uc "github.com/unicorn-engine/unicorn/bindings/go/unicorn"
)

// naturally, x86 specific. mode-agnostic.
type RegisterSnapshot struct {
	regs [uc.X86_REG_ENDING - uc.X86_REG_INVALID]uint64
}

func SnapshotRegisters(emu *Emulator) (*RegisterSnapshot, error) {
	var regs RegisterSnapshot
	for i := uc.X86_REG_INVALID + 1; i < uc.X86_REG_ENDING; i++ {
		r, e := emu.u.RegRead(i)
		if e != nil {
			return nil, e
		}
		regs.regs[i] = r
	}
	return &regs, nil
}

func RestoreRegisterSnapshot(emu *Emulator, regs *RegisterSnapshot) error {
	for i := uc.X86_REG_INVALID + 1; i < uc.X86_REG_ENDING; i++ {
		e := emu.u.RegWrite(i, regs.regs[i])
		if e != nil {
			return e
		}
	}
	return nil
}

func SnapshotMemory(emu *Emulator) (*MemorySnapshot, error) {
	return CreateMemorySnapshot(emu)
}

// until i figure out how this is best used,
// the currentAddressSpace of `snapshot` *must* be be this emu.
func RestoreMemorySnapshot(emu *Emulator, as *MemorySnapshot) error {
	e := as.RevertAddressSpace(emu)
	if e != nil {
		return e
	}

	e = as.Revert()
	check(e)

	return nil
}

// x86 specific. mode-agnostic.
type Snapshot struct {
	hook      CloseableHook
	emu       *Emulator
	memory    *MemorySnapshot
	registers *RegisterSnapshot
}

var ErrSnapshotHookAlreadyActive = errors.New("Snapshot hook already active")

func HookSnapshot(emu *Emulator, snap *Snapshot) error {
	if snap.hook != nil {
		return ErrSnapshotHookAlreadyActive
	}

	h, e := emu.HookMemWrite(func(access int, addr VA, size int, value int64) {
		for i := uint64(addr); i < uint64(addr)+uint64(size); i += PAGE_SIZE {
			snap.memory.MarkDirty(VA(i))
		}
	})
	check(e)
	if e != nil {
		return e
	}

	snap.hook = h
	return nil
}

var ErrSnapshotHookNotActive = errors.New("Snapshot hook not active")

func UnhookSnapshot(emu *Emulator, snap *Snapshot) error {
	if snap.hook == nil {
		return ErrSnapshotHookNotActive
	}

	e := snap.hook.Close()
	snap.hook = nil
	return e
}

func CreateSnapshot(emu *Emulator) (*Snapshot, error) {
	regs, e := SnapshotRegisters(emu)
	if e != nil {
		return nil, e
	}

	mem, e := SnapshotMemory(emu)
	if e != nil {
		return nil, e
	}

	snap := &Snapshot{
		hook:      nil,
		memory:    mem,
		registers: regs,
	}

	return snap, nil
}

func RestoreSnapshot(emu *Emulator, snap *Snapshot) error {
	e := RestoreRegisterSnapshot(emu, snap.registers)
	check(e)
	if e != nil {
		// we're in a bad state here
		return e
	}
	e = RestoreMemorySnapshot(emu, snap.memory)
	if e != nil {
		// we're in a bad state here
		return e
	}
	return nil
}

func (snap Snapshot) String() string {
	return fmt.Sprintf("snapshot: eip=0x%x", snap.registers.regs[uc.X86_REG_EIP])
}
<commit_msg>snapshot: add initial snapshot manager<commit_after>package workspace

import (
	"errors"
	"fmt"
	uc "github.com/unicorn-engine/unicorn/bindings/go/unicorn"
)

// naturally, x86 specific. mode-agnostic.
type RegisterSnapshot struct {
	regs [uc.X86_REG_ENDING - uc.X86_REG_INVALID]uint64
}

func SnapshotRegisters(emu *Emulator) (*RegisterSnapshot, error) {
	var regs RegisterSnapshot
	for i := uc.X86_REG_INVALID + 1; i < uc.X86_REG_ENDING; i++ {
		r, e := emu.u.RegRead(i)
		if e != nil {
			return nil, e
		}
		regs.regs[i] = r
	}
	return &regs, nil
}

func RestoreRegisterSnapshot(emu *Emulator, regs *RegisterSnapshot) error {
	for i := uc.X86_REG_INVALID + 1; i < uc.X86_REG_ENDING; i++ {
		e := emu.u.RegWrite(i, regs.regs[i])
		if e != nil {
			return e
		}
	}
	return nil
}

func SnapshotMemory(emu *Emulator) (*MemorySnapshot, error) {
	return CreateMemorySnapshot(emu)
}

// until i figure out how this is best used,
// the currentAddressSpace of `snapshot` *must* be be this emu.
func RestoreMemorySnapshot(emu *Emulator, as *MemorySnapshot) error {
	e := as.RevertAddressSpace(emu)
	if e != nil {
		return e
	}

	e = as.Revert()
	check(e)

	return nil
}

// x86 specific. mode-agnostic.
type Snapshot struct {
	hook      CloseableHook
	emu       *Emulator
	memory    *MemorySnapshot
	registers *RegisterSnapshot
}

var ErrSnapshotHookAlreadyActive = errors.New("Snapshot hook already active")

func HookSnapshot(emu *Emulator, snap *Snapshot) error {
	if snap.hook != nil {
		return ErrSnapshotHookAlreadyActive
	}

	h, e := emu.HookMemWrite(func(access int, addr VA, size int, value int64) {
		for i := uint64(addr); i < uint64(addr)+uint64(size); i += PAGE_SIZE {
			snap.memory.MarkDirty(VA(i))
		}
	})
	check(e)
	if e != nil {
		return e
	}

	snap.hook = h
	return nil
}

var ErrSnapshotHookNotActive = errors.New("Snapshot hook not active")

func UnhookSnapshot(emu *Emulator, snap *Snapshot) error {
	if snap.hook == nil {
		return ErrSnapshotHookNotActive
	}

	e := snap.hook.Close()
	snap.hook = nil
	return e
}

func CreateSnapshot(emu *Emulator) (*Snapshot, error) {
	regs, e := SnapshotRegisters(emu)
	if e != nil {
		return nil, e
	}

	mem, e := SnapshotMemory(emu)
	if e != nil {
		return nil, e
	}

	snap := &Snapshot{
		hook:      nil,
		memory:    mem,
		registers: regs,
	}

	return snap, nil
}

func RestoreSnapshot(emu *Emulator, snap *Snapshot) error {
	e := RestoreRegisterSnapshot(emu, snap.registers)
	check(e)
	if e != nil {
		// we're in a bad state here
		return e
	}
	e = RestoreMemorySnapshot(emu, snap.memory)
	if e != nil {
		// we're in a bad state here
		return e
	}
	return nil
}

func (snap Snapshot) String() string {
	return fmt.Sprintf("snapshot: eip=0x%x", snap.registers.regs[uc.X86_REG_EIP])
}

/************* SnapshotManager *******************/

type SnapshotManagerCookie uint64

type snapshotManagerState struct {
	snap *Snapshot
	c    SnapshotManagerCookie
}

type SnapshotManager struct {
	emu     *Emulator
	states  []*snapshotManagerState
	counter uint64
}

func NewSnapshotManager(emu *Emulator) (*SnapshotManager, error) {
	t := &SnapshotManager{
		emu:     emu,
		states:  make([]*snapshotManagerState, 0),
		counter: 1,
	}

	// prime initial state
	_, e := t.Push()
	check(e)

	return t, nil
}

func (t *SnapshotManager) Close() error {
	for len(t.states) > 1 {
		_, e := t.Pop()
		check(e)
	}
	check(UnhookSnapshot(t.emu, t.states[0].snap))
	t.states = nil
	return nil
}

func (t *SnapshotManager) Push() (SnapshotManagerCookie, error) {
	c := SnapshotManagerCookie(t.counter)
	t.counter++

	if len(t.states) > 0 {
		currentState := t.states[len(t.states)-1]
		// don't check this, because we might unhook
		//  the initial state multiple times
		UnhookSnapshot(t.emu, currentState.snap)
	}

	snap, e := CreateSnapshot(t.emu)
	check(e)

	check(HookSnapshot(t.emu, snap))

	state := &snapshotManagerState{
		snap: snap,
		c:    c,
	}

	t.states = append(t.states, state)

	return c, nil
}

var ErrSnapshotNotActive = errors.New("Snapshot not active")

func (t *SnapshotManager) RevertToHead() error {
	if len(t.states) == 0 {
		panic(ErrSnapshotNotActive)
	}

	state := t.states[len(t.states)-1]
	return RestoreSnapshot(t.emu, state.snap)
}

func (t *SnapshotManager) Pop() (SnapshotManagerCookie, error) {
	if len(t.states) == 0 {
		panic(ErrSnapshotNotActive)
	}

	state := t.states[len(t.states)-1]

	if len(t.states) > 1 {
		check(UnhookSnapshot(t.emu, state.snap))

		t.states = t.states[:len(t.states)-1]

		prevState := t.states[len(t.states)-1]
		check(HookSnapshot(t.emu, prevState.snap))
	}
	return state.c, nil
}

func (t *SnapshotManager) GetCurrentCookie() (SnapshotManagerCookie, error) {
	if len(t.states) == 0 {
		panic(ErrSnapshotNotActive)
	}

	state := t.states[len(t.states)-1]
	return state.c, nil
}

var ErrSnapshotNotFound = errors.New("Snapshot cookie not found")

func (t *SnapshotManager) RevertUntil(c SnapshotManagerCookie) error {
	var lastCookie SnapshotManagerCookie
	for {
		check(t.RevertToHead())

		cookie, e := t.GetCurrentCookie()
		check(e)

		if cookie == c {
			break
		}
		// ensure we don't get stuck on the initial state
		if cookie == lastCookie {
			return ErrSnapshotNotFound
		}
		lastCookie = cookie

		_, e = t.Pop()
		check(e)
	}
	return nil
}

func (t *SnapshotManager) WithTempExcursion(f func() error) error {
	beforeCookie, e := t.Push()
	check(e)

	var ret error
	e = f()
	if e != nil {
		ret = e
	}

	check(t.RevertUntil(beforeCookie))
	_, e = t.Pop()
	check(e)

	return ret
}
<|endoftext|>


<commit_before>package main // import "github.com/mvanholsteijn/paas-monitor"

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/shirou/gopsutil/cpu"
	"hash/crc32"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sort"
	"strings"
)

var port string

func environmentHandler(w http.ResponseWriter, r *http.Request) {
	var variables map[string]string
	variables = make(map[string]string)

	for _, e := range os.Environ() {
		pair := strings.Split(e, "=")
		variables[pair[0]] = pair[1]
	}

	js, err := json.Marshal(variables)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	etag := fmt.Sprintf("%x", crc32.ChecksumIEEE(js))

	if match := r.Header.Get("If-None-Match"); match != "" {
		if strings.Contains(match, etag) {
			w.WriteHeader(http.StatusNotModified)
			return
		}
	}

	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Cache-Control", "public, max-age=60")
	w.Header().Set("ETag", etag)
	w.Write(js)
}

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

	var variables map[string]string

	variables = make(map[string]string)
	variables["url"] = r.URL.String()
	variables["proto"] = r.Proto
	variables["host"] = r.Host
	variables["method"] = r.Method
	variables["request-uri"] = r.RequestURI
	variables["remote-addr"] = r.RemoteAddr

	js, err := json.Marshal(variables)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

var healthy = true

func healthHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	if healthy {
		fmt.Fprintf(w, "ok")
	} else {
		http.Error(w, "service toggled to unhealthy", http.StatusServiceUnavailable)
	}
}

var quitLoad = make(chan bool, 1)

func burnCPU() {
	for {
		select {
		case <-quitLoad:
			return
		default:
		}
	}
}

func increaseCpuLoadHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	go burnCPU()
	fmt.Fprintf(w, "CPU load increased\n")
}

func decreaseCpuLoadHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	select {
	case quitLoad <- true:
		fmt.Fprintf(w, "CPU load decreased\n")
	default:
		fmt.Fprintf(w, "no additional CPU load decreased\n")
	}
}

func toggleHealthHandler(w http.ResponseWriter, r *http.Request) {
	healthy = !healthy
	fmt.Fprintf(w, "toggled health to %v", healthy)
}

func stopHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	w.Header().Set("Content-Length", "0")
	if f, ok := w.(http.Flusher); ok {
		f.Flush()
	} else {
		log.Println("Damn, no flush")
	}
	os.Exit(1)
}

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

	hdr := r.Header
	hdr["Host"] = []string{r.Host}
	hdr["Content-Type"] = []string{r.Header.Get("Content-Type")}
	hdr["User-Agent"] = []string{r.UserAgent()}

	js, err := json.Marshal(hdr)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func cpuInfoHandler(w http.ResponseWriter, r *http.Request) {
	js, err := json.Marshal(cpus)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

var (
	count = 0
	cpus  InfoStatArray
)

type InfoStatArray []cpu.InfoStat

func (a InfoStatArray) Len() int {
	return len(a)
}

func (a InfoStatArray) Less(i, j int) bool {
	return strings.Compare(a[i].PhysicalID, a[j].PhysicalID) == -1
}

func (a InfoStatArray) Swap(i, j int) {
	old := a[i]
	a[i] = a[j]
	a[j] = old
}

func getCpuInfo() {
	var err error
	cpus, err = cpu.Info()
	if err != nil {
		log.Printf("failed to get cpu info, %s", err)
		cpus = make([]cpu.InfoStat, 0)
	}
	sort.Sort(cpus)
}

func statusHandler(w http.ResponseWriter, r *http.Request) {
	variables := make(map[string]interface{})

	hostName, _ := os.Hostname()
	release := os.Getenv("RELEASE")
	message := os.Getenv("MESSAGE")
	if message == "" {
		message = "Hello World"
	} else {
		message = os.ExpandEnv(message)
	}
	count = count + 1

	variables["key"] = fmt.Sprintf("%s:%s", hostName, port)
	variables["release"] = release
	variables["servercount"] = fmt.Sprintf("%d", count)
	variables["message"] = message
	variables["healthy"] = healthy
	variables["cpu"] = nil

	percentage, err := cpu.Percent(0, true)
	if err == nil {
		total := 0
		for i := 0; i < len(percentage); i++ {
			total = total + int(percentage[i])
		}
		variables["cpu"] = int(total / len(percentage))
	}

	variables["cpu_id"] = ""
	if len(cpus) > 0  {
		variables["cpu_id"] = cpus[0].PhysicalID
	}

	js, err := json.Marshal(variables)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Connection", "close")
	w.Write(js)
}

func main() {
	var dir string
	dir = os.Getenv("APPDIR")
	if dir == "" {
		dir = "."
	}
	fs := http.FileServer(http.Dir(dir + "/public"))

	getCpuInfo()
	http.Handle("/", fs)
	http.HandleFunc("/environment", environmentHandler)
	http.HandleFunc("/status", statusHandler)
	http.HandleFunc("/header", headerHandler)
	http.HandleFunc("/health", healthHandler)
	http.HandleFunc("/toggle-health", toggleHealthHandler)
	http.HandleFunc("/request", requestHandler)
	http.HandleFunc("/stop", stopHandler)
	http.HandleFunc("/increase-cpu", increaseCpuLoadHandler)
	http.HandleFunc("/decrease-cpu", decreaseCpuLoadHandler)
	http.HandleFunc("/cpus", cpuInfoHandler)

	portEnvName := flag.String("port-env-name", "", "the environment variable name overriding the listen port")
	portSpecified := flag.String("port", "", "the port to listen, override the environment name")
	healthCheck := flag.Bool("check", false, "check whether the service is listening")
	flag.Parse()

	if *portSpecified != "" && *portEnvName != "" {
		log.Fatalf("specify either -port or -port-env-name, but not both.\n")
	}

	if *portSpecified != "" {
		port = *portSpecified
	} else {
		if *portEnvName != "" && os.Getenv(*portEnvName) != "" {
			port = os.Getenv(*portEnvName)
		} else {
			if *portEnvName != "" {
				log.Fatalf("environment variable '%s' is not set with a port override\n", *portEnvName)
			}
			port = os.Getenv("PORT")
			if port == "" {
				port = "1337"
			}
		}
	}

	if *healthCheck {
		resp, err := http.Get("http://0.0.0.0:" + port + "/health")
		if err != nil {
			log.Fatal(fmt.Errorf("%s", err))
		}
		if resp.StatusCode == 200 {
			os.Exit(0)
		} else {
			defer resp.Body.Close()
			body, err := ioutil.ReadAll(resp.Body)
			if err == nil {
				fmt.Printf("%s\n", body)
			}
			log.Fatal(fmt.Errorf("expected status code 200, got %d", resp.StatusCode))
		}
	} else {
		log.Printf("listening on port %s\n", port)
		err := http.ListenAndServe(":"+port, nil)
		log.Fatal("%s", err)
	}
}
<commit_msg>generate new hostname if running under Cloud Run/kNative<commit_after>package main // import "github.com/mvanholsteijn/paas-monitor"

import (
	"crypto/rand"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/shirou/gopsutil/cpu"
	"hash/crc32"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sort"
	"strings"
)

var port string
var hostName string

func environmentHandler(w http.ResponseWriter, r *http.Request) {
	var variables map[string]string
	variables = make(map[string]string)

	for _, e := range os.Environ() {
		pair := strings.Split(e, "=")
		variables[pair[0]] = pair[1]
	}

	js, err := json.Marshal(variables)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	etag := fmt.Sprintf("%x", crc32.ChecksumIEEE(js))

	if match := r.Header.Get("If-None-Match"); match != "" {
		if strings.Contains(match, etag) {
			w.WriteHeader(http.StatusNotModified)
			return
		}
	}

	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Cache-Control", "public, max-age=60")
	w.Header().Set("ETag", etag)
	w.Write(js)
}

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

	var variables map[string]string

	variables = make(map[string]string)
	variables["url"] = r.URL.String()
	variables["proto"] = r.Proto
	variables["host"] = r.Host
	variables["method"] = r.Method
	variables["request-uri"] = r.RequestURI
	variables["remote-addr"] = r.RemoteAddr

	js, err := json.Marshal(variables)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

var healthy = true

func healthHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	if healthy {
		fmt.Fprintf(w, "ok")
	} else {
		http.Error(w, "service toggled to unhealthy", http.StatusServiceUnavailable)
	}
}

var quitLoad = make(chan bool, 1)

func burnCPU() {
	for {
		select {
		case <-quitLoad:
			return
		default:
		}
	}
}

func increaseCpuLoadHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	go burnCPU()
	fmt.Fprintf(w, "CPU load increased\n")
}

func decreaseCpuLoadHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	select {
	case quitLoad <- true:
		fmt.Fprintf(w, "CPU load decreased\n")
	default:
		fmt.Fprintf(w, "no additional CPU load decreased\n")
	}
}

func toggleHealthHandler(w http.ResponseWriter, r *http.Request) {
	healthy = !healthy
	fmt.Fprintf(w, "toggled health to %v", healthy)
}

func stopHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	w.Header().Set("Content-Length", "0")
	if f, ok := w.(http.Flusher); ok {
		f.Flush()
	} else {
		log.Println("Damn, no flush")
	}
	os.Exit(1)
}

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

	hdr := r.Header
	hdr["Host"] = []string{r.Host}
	hdr["Content-Type"] = []string{r.Header.Get("Content-Type")}
	hdr["User-Agent"] = []string{r.UserAgent()}

	js, err := json.Marshal(hdr)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func cpuInfoHandler(w http.ResponseWriter, r *http.Request) {
	js, err := json.Marshal(cpus)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

var (
	count = 0
	cpus  InfoStatArray
)

type InfoStatArray []cpu.InfoStat

func (a InfoStatArray) Len() int {
	return len(a)
}

func (a InfoStatArray) Less(i, j int) bool {
	return strings.Compare(a[i].PhysicalID, a[j].PhysicalID) == -1
}

func (a InfoStatArray) Swap(i, j int) {
	old := a[i]
	a[i] = a[j]
	a[j] = old
}

func getCpuInfo() {
	var err error
	cpus, err = cpu.Info()
	if err != nil {
		log.Printf("failed to get cpu info, %s", err)
		cpus = make([]cpu.InfoStat, 0)
	}
	sort.Sort(cpus)
}

func statusHandler(w http.ResponseWriter, r *http.Request) {
	variables := make(map[string]interface{})

	release := os.Getenv("RELEASE")
	message := os.Getenv("MESSAGE")
	if message == "" {
		message = "Hello World"
	} else {
		message = os.ExpandEnv(message)
	}
	count = count + 1

	variables["key"] = fmt.Sprintf("%s:%s", hostName, port)
	variables["release"] = release
	variables["servercount"] = fmt.Sprintf("%d", count)
	variables["message"] = message
	variables["healthy"] = healthy
	variables["cpu"] = nil

	percentage, err := cpu.Percent(0, true)
	if err == nil {
		total := 0
		for i := 0; i < len(percentage); i++ {
			total = total + int(percentage[i])
		}
		variables["cpu"] = int(total / len(percentage))
	}

	variables["cpu_id"] = ""
	if len(cpus) > 0 {
		variables["cpu_id"] = cpus[0].PhysicalID
	}

	js, err := json.Marshal(variables)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Connection", "close")
	w.Write(js)
}

func newUUID() (string, error) {
	uuid := make([]byte, 16)
	n, err := io.ReadFull(rand.Reader, uuid)
	if n != len(uuid) || err != nil {
		return "", err
	}
	// variant bits; see section 4.1.1
	uuid[8] = uuid[8]&^0xc0 | 0x80
	// version 4 (pseudo-random); see section 4.1.3
	uuid[6] = uuid[6]&^0xf0 | 0x40
	return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
}

func main() {
	var dir string
	dir = os.Getenv("APPDIR")
	if dir == "" {
		dir = "."
	}
	fs := http.FileServer(http.Dir(dir + "/public"))

	hostName, _ = os.Hostname()
	if os.Getenv("K_REVISION") != "" {
		uuid, err := newUUID()
		if err != nil {
			log.Fatal("failed to generate uuid, %s", err)
		}
		// if running in Cloud Run use a random hostName, otherwise it is localhost
		hostName = fmt.Sprintf("%s-%s", os.Getenv("K_REVISION"), uuid)
	}

	getCpuInfo()
	http.Handle("/", fs)
	http.HandleFunc("/environment", environmentHandler)
	http.HandleFunc("/status", statusHandler)
	http.HandleFunc("/header", headerHandler)
	http.HandleFunc("/health", healthHandler)
	http.HandleFunc("/toggle-health", toggleHealthHandler)
	http.HandleFunc("/request", requestHandler)
	http.HandleFunc("/stop", stopHandler)
	http.HandleFunc("/increase-cpu", increaseCpuLoadHandler)
	http.HandleFunc("/decrease-cpu", decreaseCpuLoadHandler)
	http.HandleFunc("/cpus", cpuInfoHandler)

	portEnvName := flag.String("port-env-name", "", "the environment variable name overriding the listen port")
	portSpecified := flag.String("port", "", "the port to listen, override the environment name")
	healthCheck := flag.Bool("check", false, "check whether the service is listening")
	flag.Parse()

	if *portSpecified != "" && *portEnvName != "" {
		log.Fatalf("specify either -port or -port-env-name, but not both.\n")
	}

	if *portSpecified != "" {
		port = *portSpecified
	} else {
		if *portEnvName != "" && os.Getenv(*portEnvName) != "" {
			port = os.Getenv(*portEnvName)
		} else {
			if *portEnvName != "" {
				log.Fatalf("environment variable '%s' is not set with a port override\n", *portEnvName)
			}
			port = os.Getenv("PORT")
			if port == "" {
				port = "1337"
			}
		}
	}

	if *healthCheck {
		resp, err := http.Get("http://0.0.0.0:" + port + "/health")
		if err != nil {
			log.Fatal(fmt.Errorf("%s", err))
		}
		if resp.StatusCode == 200 {
			os.Exit(0)
		} else {
			defer resp.Body.Close()
			body, err := ioutil.ReadAll(resp.Body)
			if err == nil {
				fmt.Printf("%s\n", body)
			}
			log.Fatal(fmt.Errorf("expected status code 200, got %d", resp.StatusCode))
		}
	} else {
		log.Printf("listening on port %s\n", port)
		err := http.ListenAndServe(":"+port, nil)
		log.Fatal("%s", err)
	}
}
<|endoftext|>