-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,19 +17,24 @@ | |
// ID AccountID | ||
// Name string // full name of the account | ||
// Avatar string // a square picture for the account | ||
// Email string // email associated with account | ||
// PrimaryEmail string // email associated with account | ||
// Emails []string // other email accounts (should include "primary email") | ||
// } | ||
|
||
module.exports.account = exports.account = { | ||
'_id': 'hash1234', | ||
'name': 'Richard Feynman', | ||
'avatar': 'http://upload.wikimedia.org/wikipedia/en/4/42/Richard_Feynman_Nobel.jpg', | ||
'email': '[email protected]' | ||
'primaryEmail': '[email protected]', | ||
'emails': [ | ||
'[email protected]', | ||
'[email protected]' | ||
] | ||
} | ||
|
||
// User is an individual user, a Person. | ||
// type User struct { | ||
// Account // it is an account. | ||
// Account // it is an account. (this is "embedded here", Go uses composition instead of inheritance) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jbenet
Contributor
|
||
// OAuthTokens []string | ||
// } | ||
|
||
|
@@ -81,39 +86,96 @@ module.exports.conversation = exports.conversation = { | |
] | ||
} | ||
|
||
// it would be nice to leverage some "media schema" that | ||
// already exists rather than invent our own. It's likely | ||
// something that the Linked Data community has already | ||
// made | ||
// var MediaTypes = []string{ | ||
// "publication", // paper | ||
// "webpage", | ||
// "image", | ||
// ... | ||
// } | ||
|
||
// TODO Why is this an array, and not just a string? | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
adammarblestone-zz
|
||
// TODO Should we validate this using some sort of testing? | ||
// TODO What is this for, exactly? When is this used? | ||
|
||
module.exports.mediaTypes = exports.mediaTypes = [ | ||
'publication', 'webpage', 'image' | ||
] | ||
|
||
// // A MediaObject is a specific piece of media that's | ||
// // able to be viewed, referenced, and linked to. | ||
// // For example, a Paper, a webpage, or an image. | ||
// type MediaObject struct { | ||
// Entity // it is an entity | ||
|
||
// // all media objects must have | ||
// Title string | ||
// Type string // one of MediaTypes | ||
// Authors []string | ||
// SourceURL string // the source URL of the object. | ||
|
||
// // everything else (like DOI, etc) we can put in a big | ||
// // "metadata" sub-object (this just means an arbitrary json object) | ||
// Metadata map[string]interface{} | ||
// // TODO What does map[string]interface{} mean? | ||
This comment has been minimized.
Sorry, something went wrong. |
||
// } | ||
|
||
module.exports.mediaObject = exports.mediaObject = { | ||
'title': 'Boy with apple', | ||
'type': 'image', | ||
'authors': 'Johannes Van Hoyt The Younger', // ID? | ||
'sourceURL': 'http://www.mrtaylor.co.uk/static/images/appleboy_c.jpg', | ||
'metadata': { | ||
'bleep': 'blorp' | ||
} | ||
} | ||
|
||
// A Note is a piece of text related to a conversation. | ||
// type Note struct { | ||
// ID Entity | ||
|
||
// Text string | ||
// Owner []AccountID | ||
// Participants Membership | ||
// Author []AccountID | ||
// Conversation EntityID // link | ||
// } | ||
|
||
module.exports.note = exports.note = { | ||
'_id': 'hash4567', | ||
'text': 'Ever since I was little, I have always loved the sound of my own voice.', | ||
'owner': [ | ||
'author': [ | ||
'Richard Feynman' | ||
], | ||
'participants': [ | ||
'Richard Feynman', | ||
'Noam Chompsky' | ||
] | ||
'conversation': 'asfjklsjglw' | ||
} | ||
|
||
// Type of permission. | ||
// type PermType int | ||
// An Annotation is a piece of media affixed to another piece of media. | ||
// type Annotaton struct { | ||
// Entity // it is an entity | ||
// | ||
// Source EntityID // a MediaObject | ||
// Author AccountID // author of the annotation | ||
// } | ||
|
||
module.exports.annotation = exports.annotation = { | ||
'_id': 'ranodmhash', | ||
'source': 'asdfjlw', | ||
'author': 'lksdjfsl' | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
RichardLitt
Author
Member
|
||
|
||
// Type of permission. (this could be an int but may be ) | ||
// type PermType string | ||
|
||
// var ( | ||
// ReadPerm PermType = iota | ||
// WritePerm | ||
// SharePerm | ||
// ReadPerm PermType = "read" | ||
// WritePerm PermType = "write" | ||
// SharePerm PermType = "share" | ||
// ) | ||
|
||
// This is read | ||
module.exports.permission = exports.permission = 1 | ||
module.exports.permission = exports.permission = 'read' | ||
|
||
// Membership is a group of users that belong to an entity, | ||
// with associated permissions. For example, the participants | ||
|
@@ -124,3 +186,182 @@ module.exports.permission = exports.permission = 1 | |
// var ( | ||
// EntityPermissions map[AccountID][EntityID]PermType | ||
// ) | ||
|
||
// Membership is a group of users that belong to an entity, | ||
// with associated permissions. For example, the participants | ||
// of a conversation, or the members of a group. | ||
// type Membership map[AccountID]Permission | ||
|
||
// // links | ||
// type Link struct { | ||
// Src EntityID | ||
// Dst EntityID | ||
// Type string | ||
// } | ||
|
||
// // set of lower level functions. | ||
|
||
// // newID creates a new universal and uniformly distributed identifier. | ||
// // we can't just use the hash of the data, because we'd like to link | ||
// // to things even if the data changes. | ||
// // | ||
// // UUID is not secure: it is guessable, so since links may be used | ||
// // in "anyone with the link" type permissions, we'd like an unguessable | ||
// // identifier. | ||
// // | ||
// // So, we'll use hash functions. to preserve upgradeability, we'll use | ||
// // multihash -- https://github.com/jbenet/multihash -- and settle on using | ||
// // sha256-256 (i.e. 256 at 256 bits. | ||
// func newID() string { | ||
|
||
// // we first read some cryptographically secure randomness. | ||
// // (node and browsers have ways to do this easily) | ||
// randbuf := rand.Read(256) // read 256 bits of randomness | ||
|
||
// // then hash that-- sometimes RNGs are owned. | ||
// // (see https://github.com/jbenet/node-multihashing/) | ||
// hash := multihashing.digest(randbuf, 'sha256') | ||
|
||
// // store them as base32 for printability. | ||
// id := base32.encode(hash) | ||
// return id | ||
// } | ||
|
||
// // newUser makes and stores a new user account. | ||
// func newUser(name, avatar, email string) (User, error) { | ||
// // validate name | ||
// // validate avatar | ||
// // validate email | ||
|
||
// // FIRST, check another user by that email doesn't exist. | ||
// // WARNING: this requires consistency semantics. this is so | ||
// // common that couchdb probably has a way of handling it. | ||
// // (probably some sort of insert-or-query) | ||
// users := db.query({ | ||
// Type: "User", | ||
// Emails: []string{email}, // has email | ||
// }) // check if user email in use | ||
// if len(users) > 0 { | ||
// return nil, "email already in use" | ||
// } | ||
|
||
// u := User{ | ||
// ID: newID(), | ||
// Name: name, | ||
// Avatar: avatar, // have some sane default | ||
// PrimaryEmail: email, | ||
// Emails: []string{email}, | ||
// } | ||
|
||
// // let's talk about elsewhere how to put to the db, globals are not great, | ||
// // we just do it here for simplicity. | ||
// db.put(u) // save it. | ||
// return u | ||
// } | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
// // newConversation makes and stores a new conversation item. | ||
// func newConversation(author User, title string) Conversation { | ||
// // validate author | ||
// // validate title | ||
|
||
// c := Conversation{ | ||
// ID: newID(), | ||
// Title: title, | ||
// Owner: []string{author.ID}, | ||
// } | ||
|
||
// db.put(c) // save it. | ||
// return c | ||
// } | ||
|
||
// // newNote makes a new note and stores it. | ||
// func newNote(author User, conv Conversation, text string) Note { | ||
// // validate author | ||
// // validate conv | ||
// // validate text | ||
|
||
// n := Note{ | ||
// ID: newID(), | ||
// Text: text, | ||
// Author: author.ID, | ||
// Conversation: conv.ID, | ||
// Participants: Membership{ | ||
// author.ID: SharePerm, // put the author as a participant too. | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
adammarblestone-zz
|
||
// }, | ||
// } | ||
// db.put(n) | ||
// return n | ||
// } | ||
|
||
// // StartBlankConversation is what we do when users want to start a conversation | ||
// // from scratch, unassociated with media. that is, it's not coming from a paper, | ||
// // or an anotation, or anything. it's just a conversation from scratch. | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
adammarblestone-zz
|
||
// // | ||
// // we need to: | ||
// // - user u1 provides title, and note text (we'll make a first note, too) | ||
// // - create a new conversation c1 (with title, linked to u1) | ||
// // - save the conversation | ||
// // - create a new note n1 (linked to c1) | ||
// func StartBlankConversation(author User, title string, noteText string) (Conversation) { | ||
|
||
// // make new conversation, linked to author and with title. | ||
// c := newConversation(author, title) | ||
|
||
// // make a new note, linked to author, linked to conversation, and with noteText. | ||
// n := newNote(author, conversation, noteText) | ||
|
||
// return c, n | ||
// } | ||
|
||
// // GetConversationPosts returns all the Notes, and MediaObjects related to a given conversation | ||
// // these should be sorted chronologically | ||
// func GetConversationPosts(c Conversation) []*Entity { | ||
This comment has been minimized.
Sorry, something went wrong.
RichardLitt
Author
Member
|
||
|
||
// notes := db.query({ | ||
// Type: "Note", | ||
// Conversation: c.ID, | ||
// }) | ||
|
||
// // TODO: expand to include other media | ||
|
||
// // TODO: order logically (chronologically) | ||
|
||
// return notes | ||
// } | ||
|
||
// // GetConverationsForUser queries the database for all conversations that a user is a part of. | ||
// // This includes conversations the user created | ||
// func GetConversationsForUser(user User) ([]Conversation) { | ||
|
||
// convs := db.query({ | ||
// Type: "Conversation", | ||
// Membership: { | ||
// author.ID: // any Perm. | ||
// } | ||
// }) | ||
|
||
// return convs | ||
// } | ||
|
||
// // PostToConversation adds a note to a conversation | ||
// // TODO: generalize to include other things to link in (papers, etc) | ||
// func PostToConversation(author User, conv Conversation, noteText string) (Note, error) { | ||
// // validate author | ||
// // validate conv | ||
// // validate noteText | ||
|
||
// if !permHigher(conv.Participants[User.ID], "write") { | ||
// return nil, "no permission to post" | ||
// } | ||
|
||
// // make a new note, linked to author, linked to conversation, and with noteText. | ||
// n := newNote(author, conv, noteText) | ||
|
||
// // TODO: notifications to other participants | ||
|
||
// return n | ||
// } | ||
|
||
// func permHigher(a, b PermType) bool { | ||
// // check "read", "write", "share" matches. | ||
// } |
I'm not sure what this comment means for me: should I look up Go's implementation of types? How should I structure the user account object? @jbenet