From ec1187f94a8b0af72a7521cd7ecfd5a1e3b43d63 Mon Sep 17 00:00:00 2001 From: Alec Warner Date: Tue, 18 Oct 2016 18:28:12 -0700 Subject: Start tracking tools for tracking members. --- foundation.gentoo.org/golang/members/Makefile | 5 + foundation.gentoo.org/golang/members/list.go | 33 +++++++ foundation.gentoo.org/golang/members/main.go | 22 +++++ foundation.gentoo.org/golang/members/member.proto | 16 ++++ sites/foundation_tracker/Makefile | 5 + sites/foundation_tracker/member.proto | 16 ++++ .../golang/members/data/Makefile | 5 + .../golang/members/data/member.pb.go | 105 +++++++++++++++++++++ .../golang/members/data/member.proto | 26 +++++ .../golang/members/importers/ldap.go | 9 ++ src/foundation.gentoo.org/golang/members/main.go | 22 +++++ .../golang/members/maintenance/memberroll.go | 73 ++++++++++++++ 12 files changed, 337 insertions(+) create mode 100644 foundation.gentoo.org/golang/members/Makefile create mode 100644 foundation.gentoo.org/golang/members/list.go create mode 100644 foundation.gentoo.org/golang/members/main.go create mode 100644 foundation.gentoo.org/golang/members/member.proto create mode 100644 sites/foundation_tracker/Makefile create mode 100644 sites/foundation_tracker/member.proto create mode 100644 src/foundation.gentoo.org/golang/members/data/Makefile create mode 100644 src/foundation.gentoo.org/golang/members/data/member.pb.go create mode 100644 src/foundation.gentoo.org/golang/members/data/member.proto create mode 100644 src/foundation.gentoo.org/golang/members/importers/ldap.go create mode 100644 src/foundation.gentoo.org/golang/members/main.go create mode 100644 src/foundation.gentoo.org/golang/members/maintenance/memberroll.go diff --git a/foundation.gentoo.org/golang/members/Makefile b/foundation.gentoo.org/golang/members/Makefile new file mode 100644 index 0000000..b050cf8 --- /dev/null +++ b/foundation.gentoo.org/golang/members/Makefile @@ -0,0 +1,5 @@ +member.pb.go: + protoc --go_out ./ member.proto + +clean: + rm member.pb.go diff --git a/foundation.gentoo.org/golang/members/list.go b/foundation.gentoo.org/golang/members/list.go new file mode 100644 index 0000000..c997f45 --- /dev/null +++ b/foundation.gentoo.org/golang/members/list.go @@ -0,0 +1,33 @@ +package members + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/google/subcommands" + "golang.org/x/net/context" +) + +type listCmd struct { + membersListPath string +} + +func (*listCmd) Name() string { return "list" } +func (*listCmd) Synopsis() string { return "list members to stdout." } +func (*listCmd) Usage() string { + return `print --membersListPath /path/to/members` +} + +func (p *listCmd) SetFlags(f *flag.FlagSet) { + f.StringVar(&p.membersListPath, "membersListPath", './members', "path to members list") +} + +func (p *listCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus { + for _, arg := range f.Args() { + fmt.Printf("%s ", arg) + } + fmt.Println() + return subcommands.ExitSuccess +} diff --git a/foundation.gentoo.org/golang/members/main.go b/foundation.gentoo.org/golang/members/main.go new file mode 100644 index 0000000..c726053 --- /dev/null +++ b/foundation.gentoo.org/golang/members/main.go @@ -0,0 +1,22 @@ +package members + +import ( + "flag" + "os" + "strings" + + "github.com/google/subcommands" + "golang.org/x/net/context" +) + + +func main() { + subcommands.Register(subcommands.HelpCommand(), "") + subcommands.Register(subcommands.FlagsCommand(), "") + subcommands.Register(subcommands.CommandsCommand(), "") + subcommands.Register(&list.ListCmd{}, "") + + flag.Parse() + ctx := context.Background() + os.Exit(int(subcommands.Execute(ctx))) +} diff --git a/foundation.gentoo.org/golang/members/member.proto b/foundation.gentoo.org/golang/members/member.proto new file mode 100644 index 0000000..22969af --- /dev/null +++ b/foundation.gentoo.org/golang/members/member.proto @@ -0,0 +1,16 @@ +message Member { + // Unique idenfier for each member. + optional int64 id = 1; + + // Email information + repeated string email = 2; + + // Name + repeated string name = 3; + + // microsecond timestamp of joining. + optional int64 join_timestamp_us = 4; + + // microsecond timestamp of any elections member participated in + repeated int64 voted_in_election = 5; +} diff --git a/sites/foundation_tracker/Makefile b/sites/foundation_tracker/Makefile new file mode 100644 index 0000000..b050cf8 --- /dev/null +++ b/sites/foundation_tracker/Makefile @@ -0,0 +1,5 @@ +member.pb.go: + protoc --go_out ./ member.proto + +clean: + rm member.pb.go diff --git a/sites/foundation_tracker/member.proto b/sites/foundation_tracker/member.proto new file mode 100644 index 0000000..22969af --- /dev/null +++ b/sites/foundation_tracker/member.proto @@ -0,0 +1,16 @@ +message Member { + // Unique idenfier for each member. + optional int64 id = 1; + + // Email information + repeated string email = 2; + + // Name + repeated string name = 3; + + // microsecond timestamp of joining. + optional int64 join_timestamp_us = 4; + + // microsecond timestamp of any elections member participated in + repeated int64 voted_in_election = 5; +} diff --git a/src/foundation.gentoo.org/golang/members/data/Makefile b/src/foundation.gentoo.org/golang/members/data/Makefile new file mode 100644 index 0000000..b050cf8 --- /dev/null +++ b/src/foundation.gentoo.org/golang/members/data/Makefile @@ -0,0 +1,5 @@ +member.pb.go: + protoc --go_out ./ member.proto + +clean: + rm member.pb.go diff --git a/src/foundation.gentoo.org/golang/members/data/member.pb.go b/src/foundation.gentoo.org/golang/members/data/member.pb.go new file mode 100644 index 0000000..3d39f40 --- /dev/null +++ b/src/foundation.gentoo.org/golang/members/data/member.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go. +// source: member.proto +// DO NOT EDIT! + +/* +Package data is a generated protocol buffer package. + +It is generated from these files: + member.proto + +It has these top-level messages: + MemberRoll + Member +*/ +package data + +import proto "github.com/golang/protobuf/proto" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = math.Inf + +type MemberRoll struct { + // When we add a new member, they should receive this ID. + // We rely on clients to increment this ID during add operations. + NextMemberId *int64 `protobuf:"varint,1,opt,name=nextMemberId" json:"nextMemberId,omitempty"` + // The list of members, if any. + Members []*Member `protobuf:"bytes,2,rep,name=members" json:"members,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MemberRoll) Reset() { *m = MemberRoll{} } +func (m *MemberRoll) String() string { return proto.CompactTextString(m) } +func (*MemberRoll) ProtoMessage() {} + +func (m *MemberRoll) GetNextMemberId() int64 { + if m != nil && m.NextMemberId != nil { + return *m.NextMemberId + } + return 0 +} + +func (m *MemberRoll) GetMembers() []*Member { + if m != nil { + return m.Members + } + return nil +} + +type Member struct { + // Unique idenfier for each member. + Id *int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + // Email information + Email []string `protobuf:"bytes,2,rep,name=email" json:"email,omitempty"` + // Name + Name []string `protobuf:"bytes,3,rep,name=name" json:"name,omitempty"` + // microsecond timestamp of joining. + JoinTimestampUs *int64 `protobuf:"varint,4,opt,name=join_timestamp_us" json:"join_timestamp_us,omitempty"` + // microsecond timestamp of any elections member participated in + VotedInElection []int64 `protobuf:"varint,5,rep,name=voted_in_election" json:"voted_in_election,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Member) Reset() { *m = Member{} } +func (m *Member) String() string { return proto.CompactTextString(m) } +func (*Member) ProtoMessage() {} + +func (m *Member) GetId() int64 { + if m != nil && m.Id != nil { + return *m.Id + } + return 0 +} + +func (m *Member) GetEmail() []string { + if m != nil { + return m.Email + } + return nil +} + +func (m *Member) GetName() []string { + if m != nil { + return m.Name + } + return nil +} + +func (m *Member) GetJoinTimestampUs() int64 { + if m != nil && m.JoinTimestampUs != nil { + return *m.JoinTimestampUs + } + return 0 +} + +func (m *Member) GetVotedInElection() []int64 { + if m != nil { + return m.VotedInElection + } + return nil +} + +func init() { +} diff --git a/src/foundation.gentoo.org/golang/members/data/member.proto b/src/foundation.gentoo.org/golang/members/data/member.proto new file mode 100644 index 0000000..2e35208 --- /dev/null +++ b/src/foundation.gentoo.org/golang/members/data/member.proto @@ -0,0 +1,26 @@ +package data; + +message MemberRoll { + // When we add a new member, they should receive this ID. + // We rely on clients to increment this ID during add operations. + optional int64 nextMemberId = 1; + // The list of members, if any. + repeated Member members = 2; +} + +message Member { + // Unique idenfier for each member. + optional int64 id = 1; + + // Email information + repeated string email = 2; + + // Name + repeated string name = 3; + + // microsecond timestamp of joining. + optional int64 join_timestamp_us = 4; + + // microsecond timestamp of any elections member participated in + repeated int64 voted_in_election = 5; +} diff --git a/src/foundation.gentoo.org/golang/members/importers/ldap.go b/src/foundation.gentoo.org/golang/members/importers/ldap.go new file mode 100644 index 0000000..02db9b0 --- /dev/null +++ b/src/foundation.gentoo.org/golang/members/importers/ldap.go @@ -0,0 +1,9 @@ +package ldap + +import ( + "gopkg.in/ldap.v2" +) + +func listDevs(ldap.v2.Conn) { + +} diff --git a/src/foundation.gentoo.org/golang/members/main.go b/src/foundation.gentoo.org/golang/members/main.go new file mode 100644 index 0000000..18e7f65 --- /dev/null +++ b/src/foundation.gentoo.org/golang/members/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "flag" + "os" + + "foundation.gentoo.org/golang/members/maintenance" + "github.com/google/subcommands" + "golang.org/x/net/context" +) + + +func main() { + subcommands.Register(subcommands.HelpCommand(), "") + subcommands.Register(subcommands.FlagsCommand(), "") + subcommands.Register(subcommands.CommandsCommand(), "") + subcommands.Register(&maintenance.ListCmd{}, "") + + flag.Parse() + ctx := context.Background() + os.Exit(int(subcommands.Execute(ctx))) +} diff --git a/src/foundation.gentoo.org/golang/members/maintenance/memberroll.go b/src/foundation.gentoo.org/golang/members/maintenance/memberroll.go new file mode 100644 index 0000000..05017ea --- /dev/null +++ b/src/foundation.gentoo.org/golang/members/maintenance/memberroll.go @@ -0,0 +1,73 @@ +package maintenance + +import ( + "io/ioutil" + + "github.com/golang/protobuf/proto" + pb "foundation.gentoo.org/golang/members/data" +) + +// Struct MemberRoll defines operations on a MemberRoll +// and holds the underlying data. +type MemberRoll struct { + roll *pb.MemberRoll +} + +// Create a new memberRoll from a file. +func NewMemberRoll (path string) (*MemberRoll, error) { + in, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + // something + } + r := &pb.MemberRoll{} + if err = proto.Unmarshal(in, r); err != nil { + return nil, err + // something + } + mr := &MemberRoll{roll: r} + return mr, nil +} + +// NewEmptyMemberRoll creates an empty MemberRoll +func NewEmptyMemberRoll() (*MemberRoll) { + // The first member gets ID 1. + return &MemberRoll{ + roll: &pb.MemberRoll { + NextMemberId: proto.Int64(1), + }, + } +} + +// Save will write the MemberRoll to file at path. +func (mr *MemberRoll) Save(path string) (bool, error) { + bytes, err := proto.Marshal(mr.roll) + if err != nil { return false, err } + if err = ioutil.WriteFile(path, bytes, 0644); err != nil { + return false, err + } + return true, nil +} + +// GetMaxMemberId computes the largest ID amongst a memberroll. +// This works by assuming members are not removed from a roll. +func (mr *MemberRoll) GetMaxMemberId() (int64) { + var id int64 = 0; + for _, member := range (mr.roll.GetMembers()) { + member_id := member.GetId() + if member_id > id { + id = member_id + } + } + return id +} + +func (mr *MemberRoll) GetNextMemberId() (int64) { + id := mr.GetNextMemberId() + // If the member roll lost its ID (not a required field.) + // Recalculate based on existing membership. + if id == 0 { + id = mr.GetMaxMemberId() + } + return id +} -- cgit v1.2.3-65-gdbad