"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",
password_encrypted text not null,
email text,
icon bytea,
- start_time timestamp not null default now()
-);
-
+ published timestamp not null default now(),
+ updated timestamp
+)
create table community (
id serial primary key,
name varchar(20) not null,
- start_time timestamp not null default now()
+ published timestamp not null default now(),
+ updated timestamp
);
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()
+ published 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()
+ published timestamp not null default now()
);
name varchar(100) not null,
url text not null,
attributed_to text not null,
- start_time timestamp not null default now()
+ published timestamp not null default now(),
+ updated timestamp
);
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()
+ published 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()
+ published timestamp not null default now()
);
pub struct Community {
pub id: i32,
pub name: String,
- pub start_time: chrono::NaiveDateTime
+ pub published: chrono::NaiveDateTime,
+ pub updated: Option<chrono::NaiveDateTime>
}
#[derive(Insertable, AsChangeset, Clone, Copy)]
#[table_name="community"]
pub struct CommunityForm<'a> {
- pub name: &'a str,
+ pub name: &'a str,
+ pub updated: Option<&'a chrono::NaiveDateTime>
}
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
pub id: i32,
pub community_id: i32,
pub fedi_user_id: String,
- pub start_time: chrono::NaiveDateTime
+ pub published: chrono::NaiveDateTime,
}
#[derive(Insertable, AsChangeset, Clone, Copy)]
pub id: i32,
pub community_id: i32,
pub fedi_user_id: String,
- pub start_time: chrono::NaiveDateTime
+ pub published: chrono::NaiveDateTime,
}
#[derive(Insertable, AsChangeset, Clone, Copy)]
let new_community = CommunityForm {
name: "TIL".into(),
+ updated: None
};
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
+ published: inserted_community.published,
+ updated: None
};
let new_user = UserForm {
name: "thom".into(),
preferred_username: None,
password_encrypted: "nope".into(),
- email: None
+ email: None,
+ updated: None
};
let inserted_user = User_::create(&conn, new_user).unwrap();
id: inserted_community_follower.id,
community_id: inserted_community.id,
fedi_user_id: "test".into(),
- start_time: inserted_community_follower.start_time
+ published: inserted_community_follower.published
};
let community_user_form = CommunityUserForm {
id: inserted_community_user.id,
community_id: inserted_community.id,
fedi_user_id: "test".into(),
- start_time: inserted_community_user.start_time
+ published: inserted_community_user.published
};
let read_community = Community::read(&conn, inserted_community.id);
-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);
-
- }
-}
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, Identifiable, PartialEq, Debug)]
pub password_encrypted: String,
pub email: Option<String>,
pub icon: Option<Vec<u8>>,
- pub start_time: chrono::NaiveDateTime
+ pub published: chrono::NaiveDateTime,
+ pub updated: Option<chrono::NaiveDateTime>
}
#[derive(Insertable, AsChangeset, Clone, Copy)]
pub preferred_username: Option<&'a str>,
pub password_encrypted: &'a str,
pub email: Option<&'a str>,
+ pub updated: Option<&'a chrono::NaiveDateTime>
}
impl<'a> Crud<UserForm<'a>> for User_ {
}
}
-
-// 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;
name: "thom".into(),
preferred_username: None,
password_encrypted: "nope".into(),
- email: None
+ email: None,
+ updated: None
};
let inserted_user = User_::create(&conn, new_user).unwrap();
password_encrypted: "here".into(),
email: None,
icon: None,
- start_time: inserted_user.start_time
+ published: inserted_user.published,
+ updated: None
};
let read_user = User_::read(&conn, inserted_user.id);
--- /dev/null
+extern crate activitypub;
+use self::activitypub::{context, actor::Person};
+use actions::user::User_;
+
+impl User_ {
+ pub fn person(&self) -> Person {
+ use {Settings, to_datetime_utc};
+ let base_url = &format!("{}/user/{}", Settings::get().api_endpoint(), self.name);
+ let mut person = Person::default();
+ person.object_props.set_context_object(context()).ok();
+ person.object_props.set_id_string(base_url.to_string()).ok();
+ person.object_props.set_name_string(self.name.to_owned()).ok();
+ person.object_props.set_published_utctime(to_datetime_utc(self.published)).ok();
+ if let Some(i) = self.updated {
+ person.object_props.set_updated_utctime(to_datetime_utc(i)).ok();
+ }
+ // person.object_props.summary = self.summary;
+
+ person.ap_actor_props.set_inbox_string(format!("{}/inbox", &base_url)).ok();
+ person.ap_actor_props.set_outbox_string(format!("{}/outbox", &base_url)).ok();
+ person.ap_actor_props.set_following_string(format!("{}/following", &base_url)).ok();
+ person.ap_actor_props.set_liked_string(format!("{}/liked", &base_url)).ok();
+ if let Some(i) = &self.preferred_username {
+ person.ap_actor_props.set_preferred_username_string(i.to_string()).ok();
+ }
+
+ person
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::activitypub::{context, actor::Person};
+ use super::User_;
+ use naive_now;
+
+ #[test]
+ fn test_person() {
+ let expected_user = User_ {
+ id: 52,
+ name: "thom".into(),
+ preferred_username: None,
+ password_encrypted: "here".into(),
+ email: None,
+ icon: None,
+ published: naive_now(),
+ updated: None
+ };
+
+ let person = expected_user.person();
+
+ // let expected_person = Person {
+ // };
+
+ assert_eq!("http://0.0.0.0/api/v1/user/thom", person.object_props.id_string().unwrap());
+
+ }
+}
+
#[macro_use]
extern crate diesel;
extern crate dotenv;
+extern crate chrono;
use diesel::*;
use diesel::pg::PgConnection;
use std::env;
pub mod schema;
-pub mod models;
+pub mod apub;
pub mod actions;
// pub trait Likeable;
fn leave(conn: &PgConnection, form: T) -> usize;
}
-
pub fn establish_connection() -> PgConnection {
- dotenv().ok();
+ let db_url = Settings::get().db_url;
+ PgConnection::establish(&db_url)
+ .expect(&format!("Error connecting to {}", db_url))
+}
+
+pub struct Settings {
+ db_url: String,
+ hostname: String
+}
+
+impl Settings {
+ fn get() -> Self {
+ dotenv().ok();
+ Settings {
+ db_url: env::var("DATABASE_URL")
+ .expect("DATABASE_URL must be set"),
+ hostname: env::var("HOSTNAME").unwrap_or("http://0.0.0.0".to_string())
+ }
+ }
+ fn api_endpoint(&self) -> String {
+ format!("{}/api/v1", self.hostname)
+ }
+}
+
+use chrono::{DateTime, NaiveDateTime, Utc};
+pub fn to_datetime_utc(ndt: NaiveDateTime) -> DateTime<Utc> {
+ DateTime::<Utc>::from_utc(ndt, Utc)
+}
- let database_url = env::var("DATABASE_URL")
- .expect("DATABASE_URL must be set");
- PgConnection::establish(&database_url)
- .expect(&format!("Error connecting to {}", database_url))
+pub fn naive_now() -> NaiveDateTime {
+ chrono::prelude::Utc::now().naive_utc()
}
+#[cfg(test)]
+mod tests {
+ use Settings;
+ #[test]
+ fn test_api() {
+ assert_eq!(Settings::get().api_endpoint(), "http://0.0.0.0/api/v1");
+ }
+}
+++ /dev/null
-
-// 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),
-// }
-// }
-// }
-
-
community (id) {
id -> Int4,
name -> Varchar,
- start_time -> Timestamp,
+ published -> Timestamp,
+ updated -> Nullable<Timestamp>,
}
}
id -> Int4,
community_id -> Int4,
fedi_user_id -> Text,
- start_time -> Timestamp,
+ published -> Timestamp,
}
}
id -> Int4,
community_id -> Int4,
fedi_user_id -> Text,
- start_time -> Timestamp,
+ published -> Timestamp,
}
}
name -> Varchar,
url -> Text,
attributed_to -> Text,
- start_time -> Timestamp,
+ published -> Timestamp,
+ updated -> Nullable<Timestamp>,
}
}
id -> Int4,
fedi_user_id -> Text,
post_id -> Nullable<Int4>,
- start_time -> Timestamp,
+ published -> Timestamp,
}
}
id -> Int4,
fedi_user_id -> Text,
post_id -> Nullable<Int4>,
- start_time -> Timestamp,
+ published -> Timestamp,
}
}
password_encrypted -> Text,
email -> Nullable<Text>,
icon -> Nullable<Bytea>,
- start_time -> Timestamp,
+ published -> Timestamp,
+ updated -> Nullable<Timestamp>,
}
}