func MakeBarcode(rw http.ResponseWriter, req *http.Request) { var id = req.FormValue("id") var bigint *big.Int = big.NewInt(0) var code barcode.Barcode var uuid cassandra.UUID var err error if id == "" { http.NotFound(rw, req) return } uuid, err = cassandra.ParseUUID(id) if err != nil { log.Print("Error parsing UUID: ", err) rw.WriteHeader(http.StatusInternalServerError) rw.Write([]byte("Error parsing UUID: " + err.Error())) return } bigint.SetBytes([]byte(uuid)) id = bigint.String() code, err = code128.Encode(id) if err != nil { log.Print("Error generating barcode: ", err) rw.WriteHeader(http.StatusInternalServerError) rw.Write([]byte("Error generating barcode: " + err.Error())) return } code, err = barcode.Scale(code, code.Bounds().Max.X, 24*code.Bounds().Max.Y) if err != nil { log.Print("Error scaling barcode: ", err) rw.WriteHeader(http.StatusInternalServerError) rw.Write([]byte("Error scaling barcode: " + err.Error())) return } rw.Header().Set("Content-Type", "image/png") rw.Header().Set("Content-Disposition", "inline; filename="+uuid.String()+".png") err = png.Encode(rw, code) if err != nil { log.Print("Error writing out image: ", err) rw.Header().Set("Content-Type", "text/plain; charset=utf8") rw.Header().Set("Content-Disposition", "inline") rw.Write([]byte("Error writing out image: " + err.Error())) } }
// Get a list of all members which are currently in the trash. func (m *MembershipDB) EnumerateTrashedMembers(prev string, num int32) ([]*MemberWithKey, error) { var cp *cassandra.ColumnParent = cassandra.NewColumnParent() var pred *cassandra.SlicePredicate = cassandra.NewSlicePredicate() var r *cassandra.KeyRange = cassandra.NewKeyRange() var kss []*cassandra.KeySlice var ks *cassandra.KeySlice var rv []*MemberWithKey var err error // Fetch the protobuf column of the application column family. cp.ColumnFamily = "membership_archive" pred.ColumnNames = [][]byte{ []byte("pb_data"), } if len(prev) > 0 { var uuid cassandra.UUID if uuid, err = cassandra.ParseUUID(prev); err != nil { return rv, err } r.StartKey = append([]byte(archivePrefix), []byte(uuid)...) } else { r.StartKey = []byte(archivePrefix) } r.EndKey = []byte(archiveEnd) r.Count = num kss, err = m.conn.GetRangeSlices(cp, pred, r, cassandra.ConsistencyLevel_ONE) if err != nil { return rv, err } for _, ks = range kss { var member *MemberWithKey var scol *cassandra.ColumnOrSuperColumn var uuid cassandra.UUID = cassandra.UUIDFromBytes( ks.Key[len(archivePrefix):]) if len(ks.Columns) == 0 { continue } for _, scol = range ks.Columns { var col *cassandra.Column = scol.Column if string(col.Name) == "pb_data" { var agreement = new(MembershipAgreement) member = new(MemberWithKey) err = proto.Unmarshal(col.Value, agreement) proto.Merge(&member.Member, agreement.GetMemberData()) member.Key = uuid.String() } } if member != nil { rv = append(rv, member) } } return rv, nil }
// Retrieve an individual applicants data. func (m *MembershipDB) GetMembershipRequest(id, table, prefix string) (*MembershipAgreement, int64, error) { var uuid cassandra.UUID var member *MembershipAgreement = new(MembershipAgreement) var cp *cassandra.ColumnPath = cassandra.NewColumnPath() var r *cassandra.ColumnOrSuperColumn var err error if uuid, err = cassandra.ParseUUID(id); err != nil { return nil, 0, err } cp.ColumnFamily = table cp.Column = []byte("pb_data") // Retrieve the protobuf with all data from Cassandra. r, err = m.conn.Get( append([]byte(prefix), []byte(uuid)...), cp, cassandra.ConsistencyLevel_ONE) if err != nil { return nil, 0, err } // Decode the protobuf which was written to the column. err = proto.Unmarshal(r.Column.Value, member) return member, *r.Column.Timestamp, err }
// Move the record of the given applicant to a different column family. func (m *MembershipDB) moveRecordToTable( id, initiator, src_table, src_prefix, dst_table, dst_prefix string, ttl int32) error { var uuid cassandra.UUID var bmods map[string]map[string][]*cassandra.Mutation var now time.Time = time.Now() var member *MembershipAgreement var mutation *cassandra.Mutation = cassandra.NewMutation() var value []byte var timestamp int64 var err error uuid, err = cassandra.ParseUUID(id) if err != nil { return err } // First, retrieve the desired membership data. member, timestamp, err = m.GetMembershipRequest(id, src_table, src_prefix) if err != nil { return err } if dst_table == "membership_queue" && len(member.AgreementPdf) == 0 { return errors.New("No membership agreement scan has been uploaded") } // Fill in details concerning the approval. member.Metadata.ApproverUid = proto.String(initiator) member.Metadata.ApprovalTimestamp = proto.Uint64(uint64(now.Unix())) bmods = make(map[string]map[string][]*cassandra.Mutation) bmods[dst_prefix+string(uuid)] = make(map[string][]*cassandra.Mutation) bmods[dst_prefix+string(uuid)][dst_table] = make([]*cassandra.Mutation, 0) bmods[src_prefix+string(uuid)] = make(map[string][]*cassandra.Mutation) bmods[src_prefix+string(uuid)][src_table] = make([]*cassandra.Mutation, 0) value, err = proto.Marshal(member) if err != nil { return err } // Add the application protobuf to the membership data. bmods[dst_prefix+string(uuid)][dst_table] = append( bmods[dst_prefix+string(uuid)][dst_table], newCassandraMutationBytes("pb_data", value, &now, ttl)) // Delete the application data. mutation.Deletion = cassandra.NewDeletion() mutation.Deletion.Predicate = cassandra.NewSlicePredicate() mutation.Deletion.Predicate.ColumnNames = allColumns mutation.Deletion.Timestamp = ×tamp bmods[src_prefix+string(uuid)][src_table] = append( bmods[src_prefix+string(uuid)][src_table], mutation) return m.conn.AtomicBatchMutate(bmods, cassandra.ConsistencyLevel_QUORUM) }
func main() { var uuid cassandra.UUID var conn *cassandra.RetryCassandraClient var r *cassandra.ColumnOrSuperColumn var cp *cassandra.ColumnPath var err error var uuid_str, dbserver, dbname, columnfamily, column string flag.StringVar(&uuid_str, "uuid-string", "", "UUID string to look at") flag.StringVar(&dbserver, "cassandra-server", "localhost:9160", "Database server to look at") flag.StringVar(&dbname, "dbname", "sfmembersys", "Database name to look at") flag.StringVar(&columnfamily, "column-family", "", "Column family to look at") flag.StringVar(&column, "column-name", "", "Column name to look at") flag.Parse() uuid, err = cassandra.ParseUUID(uuid_str) if err != nil { log.Fatal(err) } conn, err = cassandra.NewRetryCassandraClient(dbserver) if err != nil { log.Fatal(err) } err = conn.SetKeyspace(dbname) if err != nil { log.Fatal(err) } cp = cassandra.NewColumnPath() cp.ColumnFamily = columnfamily cp.Column = []byte(column) r, err = conn.Get([]byte(uuid), cp, cassandra.ConsistencyLevel_ONE) if err != nil { log.Fatal(err) } log.Print(r.Column.Name, ": ", r.Column.Value, " (", r.Column.Timestamp, ")") }
// Add the membership agreement form scan to the given membership request // record. func (m *MembershipDB) StoreMembershipAgreement(id string, agreement_data []byte) error { var agreement *MembershipAgreement var bmods map[string]map[string][]*cassandra.Mutation var now = time.Now() var uuid cassandra.UUID var buuid []byte var value []byte var err error uuid, err = cassandra.ParseUUID(id) if err != nil { return err } buuid = append([]byte(applicationPrefix), []byte(uuid)...) agreement, _, err = m.GetMembershipRequest(id, "application", applicationPrefix) if err != nil { return err } agreement.AgreementPdf = agreement_data bmods = make(map[string]map[string][]*cassandra.Mutation) bmods[string(buuid)] = make(map[string][]*cassandra.Mutation) bmods[string(buuid)]["application"] = make([]*cassandra.Mutation, 0) value, err = proto.Marshal(agreement) if err != nil { return err } addMembershipRequestInfoBytes(bmods[string(buuid)], "pb_data", value, &now) addMembershipRequestInfoBytes(bmods[string(buuid)], "application_pdf", agreement_data, &now) return m.conn.AtomicBatchMutate( bmods, cassandra.ConsistencyLevel_QUORUM) }
// Get a list of all membership applications currently in the database. // Returns a set of "num" entries beginning after "prev". If "criterion" is // given, it will be compared against the name of the member. func (m *MembershipDB) EnumerateMembershipRequests(criterion, prev string, num int32) ( []*MemberWithKey, error) { var cp *cassandra.ColumnParent = cassandra.NewColumnParent() var pred *cassandra.SlicePredicate = cassandra.NewSlicePredicate() var r *cassandra.KeyRange = cassandra.NewKeyRange() var kss []*cassandra.KeySlice var ks *cassandra.KeySlice var rv []*MemberWithKey var err error // Fetch the name, street, city and fee columns of the application column family. cp.ColumnFamily = "application" pred.ColumnNames = [][]byte{ []byte("name"), []byte("street"), []byte("city"), []byte("fee"), []byte("fee_yearly"), } if len(prev) > 0 { var uuid cassandra.UUID if uuid, err = cassandra.ParseUUID(prev); err != nil { return rv, err } r.StartKey = append([]byte(applicationPrefix), []byte(uuid)...) } else { r.StartKey = []byte(applicationPrefix) } r.EndKey = []byte(applicationEnd) r.Count = num kss, err = m.conn.GetRangeSlices( cp, pred, r, cassandra.ConsistencyLevel_ONE) if err != nil { return rv, err } for _, ks = range kss { var member *MemberWithKey = new(MemberWithKey) var scol *cassandra.ColumnOrSuperColumn var uuid cassandra.UUID = cassandra.UUIDFromBytes( ks.Key[len(applicationPrefix):]) member.Key = uuid.String() if len(ks.Columns) == 0 { continue } for _, scol = range ks.Columns { var col *cassandra.Column = scol.Column if string(col.Name) == "name" { member.Name = proto.String(string(col.Value)) } else if string(col.Name) == "street" { member.Street = proto.String(string(col.Value)) } else if string(col.Name) == "city" { member.City = proto.String(string(col.Value)) } else if string(col.Name) == "fee" { member.Fee = proto.Uint64(binary.BigEndian.Uint64(col.Value)) } else if string(col.Name) == "fee_yearly" { member.FeeYearly = proto.Bool(col.Value[0] == 1) } } rv = append(rv, member) } return rv, nil }