]> Untitled Git - lemmy.git/commitdiff
Adding User and Community types.
authorDessalines <tyhou13@gmx.com>
Mon, 4 Mar 2019 16:39:07 +0000 (08:39 -0800)
committerDessalines <tyhou13@gmx.com>
Mon, 4 Mar 2019 16:39:07 +0000 (08:39 -0800)
18 files changed:
API.md
README.md
server/migrations/2019-02-26-002946_create_user/up.sql
server/migrations/2019-02-27-170003_create_community/down.sql
server/migrations/2019-02-27-170003_create_community/up.sql
server/migrations/2019-02-27-170402_create_community_user/down.sql [deleted file]
server/migrations/2019-02-27-170402_create_community_user/up.sql [deleted file]
server/migrations/2019-03-03-163336_create_post/down.sql [new file with mode: 0644]
server/migrations/2019-03-03-163336_create_post/up.sql [new file with mode: 0644]
server/src/actions/community.rs [new file with mode: 0644]
server/src/actions/mod.rs
server/src/actions/post.rs [new file with mode: 0644]
server/src/actions/src/schema.rs [new file with mode: 0644]
server/src/actions/user.rs
server/src/activitypub.rs [deleted file]
server/src/lib.rs
server/src/models.rs
server/src/schema.rs

diff --git a/API.md b/API.md
index 47c57ac4b954f5139d831e36185165560024dfc8..8438cb9e7cdf4c1c3b9b81f89854469f8b2851b6 100644 (file)
--- a/API.md
+++ b/API.md
   "@context": "https://www.w3.org/ns/activitystreams",
   "type": "Person",
   "id": "https://rust-reddit-fediverse/api/v1/user/sally_smith",
-  "name": "sally_smith", // TODO can't find an activitypub vocab for alias.
+  "inbox": "https://rust-reddit-fediverse/api/v1/user/sally_smith/inbox",
+  "outbox": "https://rust-reddit-fediverse/api/v1/user/sally_smith/outbox",
+  "liked": "https://rust-reddit-fediverse/api/v1/user/sally_smith/liked",
+  "disliked": "https://rust-reddit-fediverse/api/v1/user/sally_smith/disliked",
+  "following": "https://rust-reddit-fediverse/api/v1/user/sally_smith/following",
+  "name": "sally_smith", 
+  "preferredUsername": "Sally",
   "icon"?: {
     "type": "Image",
     "name": "User icon",
@@ -63,7 +69,6 @@
 ```
 
 ### [Community / Group](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-group)
-
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
@@ -73,6 +78,7 @@
   "attributedTo": [ // The moderators
     "http://joe.example.org",
   ],
+  "followers": "https://rust-reddit-fediverse/api/v1/community/today_i_learned/followers",
   "startTime": "2014-12-31T23:00:00-08:00",
   "summary"?: "The group's tagline",
   "attachment: [{}] // TBD, these would be where strong types for custom styles, and images would work.
   "url": "https://news.blah.com"
   "attributedTo": "http://joe.example.org", // The poster
   "startTime": "2014-12-31T23:00:00-08:00",
-
 }
 ```
 
 ### [Post Listings / Ordered CollectionPage](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-orderedcollectionpage)
-
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Page 1 of Sally's front page",
   "type": "OrderedCollectionPage",
   "id": "https://rust-reddit-fediverse/api/v1/posts?type={all, best, front}&sort={}&page=1,
   "partOf": "http://example.org/foo",
 }
 ```
 ### [Comment Listings / Ordered CollectionPage](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-orderedcollectionpage)
-
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Page 1 of comments for",
   "type": "OrderedCollectionPage",
   "id": "https://rust-reddit-fediverse/api/v1/comments?type={all,user,community,post,parent_comment}&id=1&page=1,
   "partOf": "http://example.org/foo",
 ```
 ## Actions
 
+- These are all posts to a user's outbox.
+- The server then creates a post to the necessary inbox of the recipient, or the followers.
+- Whenever a user accesses the site, they do a get from their inbox.
+
 ### Comments
 
 #### [Create](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-create)
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally created a note",
   "type": "Create",
   "actor": id,
   "object": comment_id, or post_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally deleted a note",
   "type": "Delete",
   "actor": id,
   "object": comment_id, or post_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally created a note",
   "type": "Create",
   "actor": id,
   "object": comment_id, or post_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally read a comment",
   "type": "Read",
   "actor": user_id
   "object": comment_id
 ```
 
 #### [Like](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-like)
+- TODO: Should likes be notifications? IE, have a to?
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally liked a comment",
   "type": "Like",
   "actor": user_id
   "object": comment_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally disliked a comment",
   "type": "Dislike",
   "actor": user_id
   "object": comment_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally created a post",
   "type": "Create",
   "actor": id,
+  "to": community_id/followers
   "object": post_id
 }
 ```
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally deleted a post",
   "type": "Delete",
   "actor": id,
   "object": comment_id, or post_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally created a post",
   "type": "Create",
   "actor": id,
   "object": comment_id, or post_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally read a post",
   "type": "Read",
   "actor": user_id
   "object": post_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally created a community",
   "type": "Create",
   "actor": id,
   "object": community_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally deleted a community",
   "type": "Delete",
   "actor": id,
   "object": community_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally created a community",
   "type": "Create",
   "actor": id,
   "object": community_id
 }
 ```
 
-#### [Join](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-join)
+#### [Follow / Subscribe](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-follow)
+```
+{
+  "@context": "https://www.w3.org/ns/activitystreams",
+  "type": "Follow",
+  "actor": id
+  "object": community_id
+}
+```
+
+#### [Ignore/ Unsubscribe](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-ignore)
+```
+{
+  "@context": "https://www.w3.org/ns/activitystreams",
+  "type": "Follow",
+  "actor": id
+  "object": community_id
+}
+```
+#### [Join / Become a Mod](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-join)
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally joined a community",
   "type": "Join",
   "actor": user_id,
   "object": community_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally left a community",
   "type": "Leave",
   "actor": user_id,
   "object": community_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "The moderator blocked Sally from a group",
   "type": "Remove",
   "actor": mod_id,
   "object": user_id,
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally deleted a users comment",
   "type": "Delete",
   "actor": id,
   "object": community_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "Sally invited John to mod a community",
   "type": "Invite",
   "id": "https://rust-reddit-fediverse/api/v1/invite/1",
   "actor": sally_id,
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "John Accepted an invitation to mod a community",
   "type": "Accept",
   "actor": john_id,
   "object": invite_id
 ```
 {
   "@context": "https://www.w3.org/ns/activitystreams",
-  "summary": "John Rejected an invitation to mod a community",
   "type": "Reject",
   "actor": john_id,
   "object": invite_id
index 4802a905a0fe4736e7f81fb93437b9e0f5d17f51..9b61044a76aabe635ef8fdb591178e7b65bf5367 100644 (file)
--- a/README.md
+++ b/README.md
@@ -12,6 +12,8 @@ We have a twitter alternative (mastodon), a facebook alternative (friendica), so
 - Must have communities.
 - Must have threaded comments.
 - Must be federated: liking and following communities across instances.
+- Be live-updating: have a right pane for new comments, and a main pain for the full threaded view.
+  - Use websockets for post / gets to your own instance.
 
 ## Questions
 - How does voting work? Should we go back to the old way of showing up and downvote counts? Or just a score?
@@ -25,5 +27,7 @@ We have a twitter alternative (mastodon), a facebook alternative (friendica), so
 - Use the [activitypub crate.](https://docs.rs/activitypub/0.1.4/activitypub/)
 - https://docs.rs/activitypub/0.1.4/activitypub/
 - [Activitypub vocab.](https://www.w3.org/TR/activitystreams-vocabulary/)
+- [Activitypub main](https://www.w3.org/TR/activitypub/)
 - [Diesel to Postgres data types](https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html)
 - [helpful diesel examples](http://siciarz.net/24-days-rust-diesel/)
+- [Mastodan public key server example](https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/)
index 4f9984b7d01c08993602507df6e3553ce49fbb5b..a4ba1e8804aa8cdf77d37ce279079fe65a4571f3 100644 (file)
@@ -1,8 +1,10 @@
 create table user_ (
   id serial primary key,
   name varchar(20) not null,
-  password_encrypted varchar(200) not null,
-  email varchar(200),
+  preferred_username varchar(20),
+  password_encrypted text not null,
+  email text,
   icon bytea,
-  startTime timestamp not null default now()
-)
+  start_time timestamp not null default now()
+);
+
index 5e751d43698d26ba4f1b669a240c275080aac433..5e6065f8103e5a2ff2ac5e22d43e42f998c22ca2 100644 (file)
@@ -1 +1,3 @@
-drop table community
+drop table community_user;
+drop table community_follower;
+drop table community;
index c5eafc7b462089e5644185ccca967c6d6d69ceaf..692a5f06b7fd9e8c884c8c819e0eb1ea7a4587a4 100644 (file)
@@ -1,5 +1,19 @@
 create table community (
   id serial primary key,
   name varchar(20) not null,
-  starttime timestamp not null default now()
-)
+  start_time timestamp not null default now()
+);
+
+create table community_user (
+  id serial primary key,
+  community_id int references community on update cascade on delete cascade not null,
+  fedi_user_id text not null,
+  start_time timestamp not null default now()
+);
+
+create table community_follower (
+  id serial primary key,
+  community_id int references community on update cascade on delete cascade not null,
+  fedi_user_id text not null,
+  start_time timestamp not null default now()
+);
diff --git a/server/migrations/2019-02-27-170402_create_community_user/down.sql b/server/migrations/2019-02-27-170402_create_community_user/down.sql
deleted file mode 100644 (file)
index a1571c7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-drop table community_user;
--- drop type community_user_type;
diff --git a/server/migrations/2019-02-27-170402_create_community_user/up.sql b/server/migrations/2019-02-27-170402_create_community_user/up.sql
deleted file mode 100644 (file)
index f60eea4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
--- No support for types yet, so just do 0,1,2
--- create type community_user_type as enum ('creator', 'moderator', 'user');
-
-create table community_user (
-  id serial primary key,
-  fedi_user_id varchar(100) not null,
-  community_id int references community on update cascade on delete cascade,
-  community_user_type smallint not null default 2,
-  starttime timestamp not null default now()
-)
diff --git a/server/migrations/2019-03-03-163336_create_post/down.sql b/server/migrations/2019-03-03-163336_create_post/down.sql
new file mode 100644 (file)
index 0000000..a578396
--- /dev/null
@@ -0,0 +1,3 @@
+drop table post_like;
+drop table post_dislike;
+drop table post;
diff --git a/server/migrations/2019-03-03-163336_create_post/up.sql b/server/migrations/2019-03-03-163336_create_post/up.sql
new file mode 100644 (file)
index 0000000..4a811fa
--- /dev/null
@@ -0,0 +1,22 @@
+create table post (
+  id serial primary key,
+  name varchar(100) not null,
+  url text not null,
+  attributed_to text not null,
+  start_time timestamp not null default now()
+);
+
+create table post_like (
+  id serial primary key,
+  fedi_user_id text not null,
+  post_id int references post on update cascade on delete cascade,
+  start_time timestamp not null default now()
+);
+
+create table post_dislike (
+  id serial primary key,
+  fedi_user_id text not null,
+  post_id int references post on update cascade on delete cascade,
+  start_time timestamp not null default now()
+);
+
diff --git a/server/src/actions/community.rs b/server/src/actions/community.rs
new file mode 100644 (file)
index 0000000..6b0bea8
--- /dev/null
@@ -0,0 +1,197 @@
+extern crate diesel;
+use schema::{community, community_user, community_follower};
+use diesel::*;
+use diesel::result::Error;
+use {Crud, Followable, Joinable};
+
+#[derive(Queryable, Identifiable, PartialEq, Debug)]
+#[table_name="community"]
+pub struct Community {
+  pub id: i32,
+  pub name: String,
+  pub start_time: chrono::NaiveDateTime
+}
+
+#[derive(Insertable, AsChangeset, Clone, Copy)]
+#[table_name="community"]
+pub struct CommunityForm<'a> {
+    pub name: &'a str,
+}
+
+#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
+#[belongs_to(Community)]
+#[table_name = "community_user"]
+pub struct CommunityUser {
+  pub id: i32,
+  pub community_id: i32,
+  pub fedi_user_id: String,
+  pub start_time: chrono::NaiveDateTime
+}
+
+#[derive(Insertable, AsChangeset, Clone, Copy)]
+#[table_name="community_user"]
+pub struct CommunityUserForm<'a> {
+  pub community_id: &'a i32,
+  pub fedi_user_id: &'a str,
+}
+
+#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
+#[belongs_to(Community)]
+#[table_name = "community_follower"]
+pub struct CommunityFollower {
+  pub id: i32,
+  pub community_id: i32,
+  pub fedi_user_id: String,
+  pub start_time: chrono::NaiveDateTime
+}
+
+#[derive(Insertable, AsChangeset, Clone, Copy)]
+#[table_name="community_follower"]
+pub struct CommunityFollowerForm<'a> {
+  pub community_id: &'a i32,
+  pub fedi_user_id: &'a str,
+}
+
+
+impl<'a> Crud<CommunityForm<'a>> for Community {
+  fn read(conn: &PgConnection, community_id: i32) -> Community {
+    use schema::community::dsl::*;
+    community.find(community_id)
+      .first::<Community>(conn)
+      .expect("Error in query")
+  }
+
+  fn delete(conn: &PgConnection, community_id: i32) -> usize {
+    use schema::community::dsl::*;
+    diesel::delete(community.find(community_id))
+      .execute(conn)
+      .expect("Error deleting.")
+  }
+
+  fn create(conn: &PgConnection, new_community: CommunityForm) -> Result<Community, Error> {
+    use schema::community::dsl::*;
+      insert_into(community)
+        .values(new_community)
+        .get_result::<Community>(conn)
+  }
+
+  fn update(conn: &PgConnection, community_id: i32, new_community: CommunityForm) -> Community {
+    use schema::community::dsl::*;
+    diesel::update(community.find(community_id))
+      .set(new_community)
+      .get_result::<Community>(conn)
+      .expect(&format!("Unable to find {}", community_id))
+  }
+}
+
+impl<'a> Followable<CommunityFollowerForm<'a>> for CommunityFollower {
+  fn follow(conn: &PgConnection, community_follower_form: CommunityFollowerForm) -> Result<CommunityFollower, Error> {
+    use schema::community_follower::dsl::*;
+    insert_into(community_follower)
+      .values(community_follower_form)
+      .get_result::<CommunityFollower>(conn)
+  }
+  fn ignore(conn: &PgConnection, community_follower_form: CommunityFollowerForm) -> usize {
+    use schema::community_follower::dsl::*;
+    diesel::delete(community_follower
+      .filter(community_id.eq(community_follower_form.community_id))
+      .filter(fedi_user_id.eq(community_follower_form.fedi_user_id)))
+      .execute(conn)
+      .expect("Error deleting.")
+  }
+}
+
+impl<'a> Joinable<CommunityUserForm<'a>> for CommunityUser {
+  fn join(conn: &PgConnection, community_user_form: CommunityUserForm) -> Result<CommunityUser, Error> {
+    use schema::community_user::dsl::*;
+    insert_into(community_user)
+      .values(community_user_form)
+      .get_result::<CommunityUser>(conn)
+  }
+  fn leave(conn: &PgConnection, community_user_form: CommunityUserForm) -> usize {
+    use schema::community_user::dsl::*;
+    diesel::delete(community_user
+      .filter(community_id.eq(community_user_form.community_id))
+      .filter(fedi_user_id.eq(community_user_form.fedi_user_id)))
+      .execute(conn)
+      .expect("Error deleting.")
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use establish_connection;
+  use super::*;
+  use actions::user::*;
+  use Crud;
+ #[test]
+  fn test_crud() {
+    let conn = establish_connection();
+    
+    let new_community = CommunityForm {
+      name: "TIL".into(),
+    };
+
+    let inserted_community = Community::create(&conn, new_community).unwrap();
+
+    let expected_community = Community {
+      id: inserted_community.id,
+      name: "TIL".into(),
+      start_time: inserted_community.start_time
+    };
+
+    let new_user = UserForm {
+      name: "thom".into(),
+      preferred_username: None,
+      password_encrypted: "nope".into(),
+      email: None
+    };
+
+    let inserted_user = User_::create(&conn, new_user).unwrap();
+
+    let community_follower_form = CommunityFollowerForm {
+      community_id: &inserted_community.id,
+      fedi_user_id: "test".into()
+    };
+
+    let inserted_community_follower = CommunityFollower::follow(&conn, community_follower_form).unwrap();
+
+    let expected_community_follower = CommunityFollower {
+      id: inserted_community_follower.id,
+      community_id: inserted_community.id,
+      fedi_user_id: "test".into(),
+      start_time: inserted_community_follower.start_time
+    };
+    
+    let community_user_form = CommunityUserForm {
+      community_id: &inserted_community.id,
+      fedi_user_id: "test".into()
+    };
+
+    let inserted_community_user = CommunityUser::join(&conn, community_user_form).unwrap();
+
+    let expected_community_user = CommunityUser {
+      id: inserted_community_user.id,
+      community_id: inserted_community.id,
+      fedi_user_id: "test".into(),
+      start_time: inserted_community_user.start_time
+    };
+
+    let read_community = Community::read(&conn, inserted_community.id);
+    let updated_community = Community::update(&conn, inserted_community.id, new_community);
+    let ignored_community = CommunityFollower::ignore(&conn, community_follower_form);
+    let left_community = CommunityUser::leave(&conn, community_user_form);
+    let num_deleted = Community::delete(&conn, inserted_community.id);
+    User_::delete(&conn, inserted_user.id);
+
+    assert_eq!(expected_community, read_community);
+    assert_eq!(expected_community, inserted_community);
+    assert_eq!(expected_community, updated_community);
+    assert_eq!(expected_community_follower, inserted_community_follower);
+    assert_eq!(expected_community_user, inserted_community_user);
+    assert_eq!(1, ignored_community);
+    assert_eq!(1, left_community);
+    assert_eq!(1, num_deleted);
+
+  }
+}
index bc675369cb3313c45b4131d091af7675722d7dd8..df10dbbce42621c122f3414d53175260ce3c9450 100644 (file)
@@ -1,3 +1,3 @@
-use diesel::*;
 pub mod user;
-
+pub mod community;
+pub mod post;
diff --git a/server/src/actions/post.rs b/server/src/actions/post.rs
new file mode 100644 (file)
index 0000000..f939fc7
--- /dev/null
@@ -0,0 +1,95 @@
+extern crate diesel;
+use schema::user_;
+use diesel::*;
+use diesel::result::Error;
+use schema::user_::dsl::*;
+
+#[derive(Queryable, PartialEq, Debug)]
+pub struct User_ {
+  pub id: i32,
+  pub name: String,
+  pub preferred_username: Option<String>,
+  pub password_encrypted: String,
+  pub email: Option<String>,
+  pub icon: Option<Vec<u8>>,
+  pub start_time: chrono::NaiveDateTime
+}
+
+#[derive(Insertable, AsChangeset, Clone, Copy)]
+#[table_name="user_"]
+pub struct NewUser<'a> {
+    pub name: &'a str,
+    pub preferred_username: Option<&'a str>,
+    pub password_encrypted: &'a str,
+    pub email: Option<&'a str>,
+}
+
+pub fn read(conn: &PgConnection, user_id: i32) -> User_ {
+  user_.find(user_id)
+    .first::<User_>(conn)
+    .expect("Error in query")
+}
+
+pub fn delete(conn: &PgConnection, user_id: i32) -> usize {
+  diesel::delete(user_.find(user_id))
+    .execute(conn)
+    .expect("Error deleting.")
+}
+
+pub fn create(conn: &PgConnection, new_user: &NewUser) -> Result<User_, Error> {
+  let mut edited_user = new_user.clone();
+  // Add the rust crypt
+  edited_user.password_encrypted = "here";
+    // edited_user.password_encrypted;
+    insert_into(user_)
+      .values(edited_user)
+      .get_result::<User_>(conn)
+}
+
+pub fn update(conn: &PgConnection, user_id: i32, new_user: &NewUser) -> User_ {
+  let mut edited_user = new_user.clone();
+  edited_user.password_encrypted = "here";
+  diesel::update(user_.find(user_id))
+    .set(edited_user)
+    .get_result::<User_>(conn)
+    .expect(&format!("Unable to find user {}", user_id))
+}
+
+#[cfg(test)]
+mod tests {
+  use establish_connection;
+  use super::*;
+ #[test]
+  fn test_crud() {
+    let conn = establish_connection();
+    
+    let new_user = NewUser {
+      name: "thom".into(),
+      preferred_username: None,
+      password_encrypted: "nope".into(),
+      email: None
+    };
+
+    let inserted_user = create(&conn, &new_user).unwrap();
+
+    let expected_user = User_ {
+      id: inserted_user.id,
+      name: "thom".into(),
+      preferred_username: None,
+      password_encrypted: "here".into(),
+      email: None,
+      icon: None,
+      start_time: inserted_user.start_time
+    };
+    
+    let read_user = read(&conn, inserted_user.id);
+    let updated_user = update(&conn, inserted_user.id, &new_user);
+    let num_deleted = delete(&conn, inserted_user.id);
+
+    assert_eq!(expected_user, read_user);
+    assert_eq!(expected_user, inserted_user);
+    assert_eq!(expected_user, updated_user);
+    assert_eq!(1, num_deleted);
+
+  }
+}
diff --git a/server/src/actions/src/schema.rs b/server/src/actions/src/schema.rs
new file mode 100644 (file)
index 0000000..580b82e
--- /dev/null
@@ -0,0 +1,80 @@
+table! {
+    community (id) {
+        id -> Int4,
+        name -> Varchar,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    community_follower (id) {
+        id -> Int4,
+        fedi_user_id -> Text,
+        community_id -> Nullable<Int4>,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    community_user (id) {
+        id -> Int4,
+        fedi_user_id -> Text,
+        community_id -> Nullable<Int4>,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    post (id) {
+        id -> Int4,
+        name -> Varchar,
+        url -> Text,
+        attributed_to -> Text,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    post_dislike (id) {
+        id -> Int4,
+        fedi_user_id -> Text,
+        post_id -> Nullable<Int4>,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    post_like (id) {
+        id -> Int4,
+        fedi_user_id -> Text,
+        post_id -> Nullable<Int4>,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    user_ (id) {
+        id -> Int4,
+        name -> Varchar,
+        preferred_username -> Nullable<Varchar>,
+        password_encrypted -> Text,
+        email -> Nullable<Text>,
+        icon -> Nullable<Bytea>,
+        start_time -> Timestamp,
+    }
+}
+
+joinable!(community_follower -> community (community_id));
+joinable!(community_user -> community (community_id));
+joinable!(post_dislike -> post (post_id));
+joinable!(post_like -> post (post_id));
+
+allow_tables_to_appear_in_same_query!(
+    community,
+    community_follower,
+    community_user,
+    post,
+    post_dislike,
+    post_like,
+    user_,
+);
index 2a017fd285f01034304247aada4ee423f7b120ee..36222f834eb21a2e10a5537014223f150aa36482 100644 (file)
 extern crate diesel;
+extern crate activitypub;
 use schema::user_;
 use diesel::*;
 use diesel::result::Error;
 use schema::user_::dsl::*;
+// use self::activitypub::{context, actor::Person};
 use Crud;
 
-#[derive(Queryable, PartialEq, Debug)]
+#[derive(Queryable, Identifiable, PartialEq, Debug)]
+#[table_name="user_"]
 pub struct User_ {
   pub id: i32,
   pub name: String,
+  pub preferred_username: Option<String>,
   pub password_encrypted: String,
   pub email: Option<String>,
   pub icon: Option<Vec<u8>>,
   pub start_time: chrono::NaiveDateTime
 }
 
-#[derive(Insertable)]
+#[derive(Insertable, AsChangeset, Clone, Copy)]
 #[table_name="user_"]
-pub struct NewUser<'a> {
+pub struct UserForm<'a> {
     pub name: &'a str,
+    pub preferred_username: Option<&'a str>,
     pub password_encrypted: &'a str,
     pub email: Option<&'a str>,
 }
 
-impl Crud for User_ {
+impl<'a> Crud<UserForm<'a>> for User_ {
   fn read(conn: &PgConnection, user_id: i32) -> User_ {
     user_.find(user_id)
       .first::<User_>(conn)
       .expect("Error in query")
   }
-
- fn delete(conn: &PgConnection, user_id: i32) -> usize {
+  fn delete(conn: &PgConnection, user_id: i32) -> usize {
     diesel::delete(user_.find(user_id))
       .execute(conn)
       .expect("Error deleting.")
   }
-
-// fn create<NewUser>(conn: &PgConnection, mut new_user: NewUser) -> Result<User_, Error> {
+  fn create(conn: &PgConnection, form: UserForm) -> Result<User_, Error> {
+    let mut edited_user = form.clone();
+    // Add the rust crypt
+    edited_user.password_encrypted = "here";
+      // edited_user.password_encrypted;
+      insert_into(user_)
+        .values(edited_user)
+        .get_result::<User_>(conn)
+  }
+  fn update(conn: &PgConnection, user_id: i32, form: UserForm) -> User_ {
+    let mut edited_user = form.clone();
+    edited_user.password_encrypted = "here";
+    diesel::update(user_.find(user_id))
+      .set(edited_user)
+      .get_result::<User_>(conn)
+      .expect(&format!("Unable to find user {}", user_id))
+  }
 }
 
-pub fn create(conn: &PgConnection, mut new_user: NewUser) -> Result<User_, Error> {
-  new_user.password_encrypted = "here";
-    // new_user.password_encrypted;
-    insert_into(user_)
-      .values(new_user)
-      .get_result(conn)
-}
+
+// TODO
+// pub fn person(user: &User_) -> Person {
+//   let mut person  = Person::default();
+//   person.object_props.set_context_object(context());
+//   person.ap_actor_props.set_preferred_username_string("set".into());
+
+//   person
+// }
 
 #[cfg(test)]
 mod tests {
   use establish_connection;
-  use super::*;
+  use super::{User_, UserForm};
+  use Crud;
  #[test]
   fn test_crud() {
     let conn = establish_connection();
     
-    let new_user = NewUser {
+    let new_user = UserForm {
       name: "thom".into(),
+      preferred_username: None,
       password_encrypted: "nope".into(),
       email: None
     };
 
-    let inserted_user = create(&conn, new_user).unwrap();
+    let inserted_user = User_::create(&conn, new_user).unwrap();
 
     let expected_user = User_ {
       id: inserted_user.id,
       name: "thom".into(),
+      preferred_username: None,
       password_encrypted: "here".into(),
       email: None,
       icon: None,
       start_time: inserted_user.start_time
     };
-
+    
     let read_user = User_::read(&conn, inserted_user.id);
+    let updated_user = User_::update(&conn, inserted_user.id, new_user);
     let num_deleted = User_::delete(&conn, inserted_user.id);
-    
+
     assert_eq!(expected_user, read_user);
     assert_eq!(expected_user, inserted_user);
+    assert_eq!(expected_user, updated_user);
     assert_eq!(1, num_deleted);
-
   }
 }
diff --git a/server/src/activitypub.rs b/server/src/activitypub.rs
deleted file mode 100644 (file)
index 3e6c46e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-extern crate activitypub;
-extern crate failure;
-extern crate serde_json;
-
-// fn user -> Result<(), Error> {
-
-// }
index 77c8ee5e3510d20ef3319b25bcb88d752274a6f8..e8a67c3de78e30bbaf7d465448a34ecf65520ec5 100644 (file)
@@ -2,16 +2,35 @@
 extern crate diesel;
 extern crate dotenv;
 
-use diesel::prelude::*;
+use diesel::*;
 use diesel::pg::PgConnection;
+use diesel::result::Error;
 use dotenv::dotenv;
 use std::env;
 
 pub mod schema;
 pub mod models;
-pub mod activitypub;
 pub mod actions;
 
+// pub trait Likeable;
+pub trait Crud<T> {
+  fn create(conn: &PgConnection, form: T) -> Result<Self, Error> where Self: Sized;
+  fn read(conn: &PgConnection, id: i32) -> Self;
+  fn update(conn: &PgConnection, id: i32, form: T) -> Self;
+  fn delete(conn: &PgConnection, id: i32) -> usize;
+}
+
+pub trait Followable<T> {
+  fn follow(conn: &PgConnection, form: T) -> Result<Self, Error> where Self: Sized;
+  fn ignore(conn: &PgConnection, form: T) -> usize;
+}
+
+pub trait Joinable<T> {
+  fn join(conn: &PgConnection, form: T) -> Result<Self, Error> where Self: Sized;
+  fn leave(conn: &PgConnection, form: T) -> usize;
+}
+
+
 pub fn establish_connection() -> PgConnection {
   dotenv().ok();
 
@@ -21,21 +40,3 @@ pub fn establish_connection() -> PgConnection {
     .expect(&format!("Error connecting to {}", database_url))
 }
 
-trait Crud {
-  fn read(conn: &PgConnection, id: i32) -> Self;
-  fn delete(conn: &PgConnection, id: i32) -> usize;
-  // fn create<T: Insertable>(conn: &PgConnection, item: T) -> Result<Self, Error> where Self: Sized;
-}
-
-#[cfg(test)]
-mod tests {
-  #[test]
-  fn it_works() {
-    assert_eq!(2 + 2, 4);
-  }
-
-  #[test]
-  fn db_fetch() {
-
-  }
-}
index cb5eaef7056b0984cafd05d999b772de72330e9a..c895f3ea5cd737c1c43e540f9f8010f1273e82f0 100644 (file)
@@ -1,19 +1,19 @@
 
-enum CommunityUserType {
-  CREATOR = 0,
-  MODERATOR = 1,
-  USER = 2
-}
+// enum CommunityUserType {
+//   CREATOR = 0,
+//   MODERATOR = 1,
+//   USER = 2
+// }
 
-impl CommunityUserType {
-  fn from_u32(value: u32) -> CommunityUserType {
-    match value {
-      0 => CommunityUserType::CREATOR,
-      1 => CommunityUserType::MODERATOR,
-      2 => CommunityUserType::USER,
-      _ => panic!("Unknown value: {}", value),
-    }
-  }
-}
+// impl CommunityUserType {
+//   fn from_u32(value: u32) -> CommunityUserType {
+//     match value {
+//       0 => CommunityUserType::CREATOR,
+//       1 => CommunityUserType::MODERATOR,
+//       2 => CommunityUserType::USER,
+//       _ => panic!("Unknown value: {}", value),
+//     }
+//   }
+// }
 
 
index a9f37009f789d5f81deba895cc339c068aeff37f..cf90c04754dfa14ae9a6055e179e8769e69ddb64 100644 (file)
@@ -2,17 +2,53 @@ table! {
     community (id) {
         id -> Int4,
         name -> Varchar,
-        starttime -> Timestamp,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    community_follower (id) {
+        id -> Int4,
+        community_id -> Int4,
+        fedi_user_id -> Text,
+        start_time -> Timestamp,
     }
 }
 
 table! {
     community_user (id) {
         id -> Int4,
-        fedi_user_id -> Varchar,
-        community_id -> Nullable<Int4>,
-        community_user_type -> Int2,
-        starttime -> Timestamp,
+        community_id -> Int4,
+        fedi_user_id -> Text,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    post (id) {
+        id -> Int4,
+        name -> Varchar,
+        url -> Text,
+        attributed_to -> Text,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    post_dislike (id) {
+        id -> Int4,
+        fedi_user_id -> Text,
+        post_id -> Nullable<Int4>,
+        start_time -> Timestamp,
+    }
+}
+
+table! {
+    post_like (id) {
+        id -> Int4,
+        fedi_user_id -> Text,
+        post_id -> Nullable<Int4>,
+        start_time -> Timestamp,
     }
 }
 
@@ -20,17 +56,25 @@ table! {
     user_ (id) {
         id -> Int4,
         name -> Varchar,
-        password_encrypted -> Varchar,
-        email -> Nullable<Varchar>,
+        preferred_username -> Nullable<Varchar>,
+        password_encrypted -> Text,
+        email -> Nullable<Text>,
         icon -> Nullable<Bytea>,
-        starttime -> Timestamp,
+        start_time -> Timestamp,
     }
 }
 
+joinable!(community_follower -> community (community_id));
 joinable!(community_user -> community (community_id));
+joinable!(post_dislike -> post (post_id));
+joinable!(post_like -> post (post_id));
 
 allow_tables_to_appear_in_same_query!(
     community,
+    community_follower,
     community_user,
+    post,
+    post_dislike,
+    post_like,
     user_,
 );