Add support for generic timeline #525
|
@ -5,7 +5,9 @@ CREATE TABLE timeline_definition(
|
|||
user_id integer REFERENCES users ON DELETE CASCADE,
|
||||
name VARCHAR NOT NULL,
|
||||
query VARCHAR NOT NULL,
|
||||
CONSTRAINT timeline_unique_user_name UNIQUE(user_id, name)
|
||||
ord integer NOT NULL,
|
||||
CONSTRAINT timeline_unique_user_name UNIQUE(user_id, name),
|
||||
CONSTRAINT timeline_unique_order UNIQUE(user_id, ord)
|
||||
);
|
||||
|
||||
CREATE TABLE timeline(
|
|
@ -5,7 +5,9 @@ CREATE TABLE timeline_definition(
|
|||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||||
name VARCHAR NOT NULL,
|
||||
query VARCHAR NOT NULL,
|
||||
CONSTRAINT timeline_unique_user_name UNIQUE(user_id, name)
|
||||
ord INTEGER NOT NULL,
|
||||
CONSTRAINT timeline_unique_user_name UNIQUE(user_id, name),
|
||||
CONSTRAINT timeline_unique_order UNIQUE(user_id, ord)
|
||||
);
|
||||
|
||||
CREATE TABLE timeline(
|
|
@ -1,6 +1,6 @@
|
|||
use activitypub::{actor::Group, collection::OrderedCollection, object::Image, CustomObject};
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl};
|
||||
use diesel::{self, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, SaveChangesDsl};
|
||||
use openssl::{
|
||||
hash::MessageDigest,
|
||||
pkey::{PKey, Private},
|
||||
|
@ -133,10 +133,8 @@ impl Blog {
|
|||
pub fn find_by_fqn(c: &PlumeRocket, fqn: &str) -> Result<Blog> {
|
||||
let from_db = blogs::table
|
||||
.filter(blogs::fqn.eq(fqn))
|
||||
.limit(1)
|
||||
.load::<Blog>(&*c.conn)?
|
||||
.into_iter()
|
||||
.next();
|
||||
.first(&*c.conn)
|
||||
.optional()?;
|
||||
if let Some(from_db) = from_db {
|
||||
Ok(from_db)
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use chrono::NaiveDateTime;
|
||||
use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||
use std::iter::Iterator;
|
||||
|
||||
use ap_url;
|
||||
use medias::Media;
|
||||
|
@ -44,11 +43,8 @@ impl Instance {
|
|||
pub fn get_local(conn: &Connection) -> Result<Instance> {
|
||||
instances::table
|
||||
.filter(instances::local.eq(true))
|
||||
.limit(1)
|
||||
.load::<Instance>(conn)?
|
||||
.into_iter()
|
||||
.nth(0)
|
||||
.ok_or(Error::NotFound)
|
||||
.first(conn)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
pub fn get_remotes(conn: &Connection) -> Result<Vec<Instance>> {
|
||||
|
@ -106,8 +102,7 @@ impl Instance {
|
|||
users::table
|
||||
.filter(users::instance_id.eq(self.id))
|
||||
.filter(users::is_admin.eq(true))
|
||||
.limit(1)
|
||||
.get_result::<User>(conn)
|
||||
.first(conn)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
|
|
|
@ -179,11 +179,8 @@ macro_rules! find_by {
|
|||
pub fn $fn(conn: &crate::Connection, $($col: $type),+) -> Result<Self> {
|
||||
$table::table
|
||||
$(.filter($table::$col.eq($col)))+
|
||||
.limit(1)
|
||||
.load::<Self>(conn)?
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or(Error::NotFound)
|
||||
.first(conn)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -229,11 +226,8 @@ macro_rules! get {
|
|||
pub fn get(conn: &crate::Connection, id: i32) -> Result<Self> {
|
||||
$table::table
|
||||
.filter($table::id.eq(id))
|
||||
.limit(1)
|
||||
.load::<Self>(conn)?
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or(Error::NotFound)
|
||||
.first(conn)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -286,11 +280,8 @@ macro_rules! last {
|
|||
pub fn last(conn: &crate::Connection) -> Result<Self> {
|
||||
$table::table
|
||||
.order_by($table::id.desc())
|
||||
.limit(1)
|
||||
.load::<Self>(conn)?
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or(Error::NotFound)
|
||||
.first(conn)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -104,20 +104,14 @@ impl List {
|
|||
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
lists::table
|
||||
.filter(lists::user_id.eq(user_id))
|
||||
.filter(lists::name.eq(name))
|
||||
.limit(1)
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.load::<Self>(conn)?
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.into_iter()
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.next()
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.ok_or(Error::NotFound)
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.first(conn)
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.map_err(Error::from)
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
} else {
|
||||
lists::table
|
||||
.filter(lists::user_id.is_null())
|
||||
.filter(lists::name.eq(name))
|
||||
.limit(1)
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.load::<Self>(conn)?
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.into_iter()
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.next()
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.ok_or(Error::NotFound)
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.first(conn)
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
.map_err(Error::from)
|
||||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|||
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
`Invalid` without the `e`
i dunno, this feels like an error… i dunno, this feels like an error…
trinity-1686a
commented
this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private this gives this module more visibility from the outer code, while keeping it private from other crates. It was probably necessary at some point, but rn it could be plain private
trinity-1686a
commented
I's a find by (list) name, in context of the given user (or instance if None) I's a find by (list) name, in context of the given user (or instance if None)
that needs either documentation or different names, because this way it's just way too confusing that needs either documentation or different names, because this way it's just way too confusing
|
|
@ -335,11 +335,8 @@ impl Post {
|
|||
use schema::blogs;
|
||||
blogs::table
|
||||
.filter(blogs::id.eq(self.blog_id))
|
||||
.limit(1)
|
||||
.load::<Blog>(conn)?
|
||||
.into_iter()
|
||||
.nth(0)
|
||||
.ok_or(Error::NotFound)
|
||||
.first(conn)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
pub fn count_likes(&self, conn: &Connection) -> Result<i64> {
|
||||
|
|
|
@ -219,6 +219,7 @@ table! {
|
|||
user_id -> Nullable<Int4>,
|
||||
name -> Varchar,
|
||||
query -> Varchar,
|
||||
ord -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,13 +9,14 @@ pub(crate) mod query;
|
|||
|
||||
use self::query::{Kind, QueryError, TimelineQuery};
|
||||
|
||||
#[derive(Clone, Queryable, Identifiable)]
|
||||
#[derive(Clone, Debug, PartialEq, Queryable, Identifiable, AsChangeset)]
|
||||
#[table_name = "timeline_definition"]
|
||||
pub struct Timeline {
|
||||
pub id: i32,
|
||||
pub user_id: Option<i32>,
|
||||
pub name: String,
|
||||
pub query: String,
|
||||
pub ord: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Insertable)]
|
||||
|
@ -24,6 +25,7 @@ pub struct NewTimeline {
|
|||
user_id: Option<i32>,
|
||||
name: String,
|
||||
query: String,
|
||||
ord: i32,
|
||||
}
|
||||
|
||||
#[derive(Default, Insertable)]
|
||||
|
@ -36,19 +38,45 @@ struct TimelineEntry {
|
|||
impl Timeline {
|
||||
insert!(timeline_definition, NewTimeline);
|
||||
get!(timeline_definition);
|
||||
find_by!(
|
||||
timeline_definition,
|
||||
find_by_name_and_user,
|
||||
user_id as Option<i32>,
|
||||
name as &str
|
||||
);
|
||||
list_by!(timeline_definition, list_for_user, user_id as Option<i32>);
|
||||
|
||||
pub fn find_by_name(conn: &Connection, user_id: Option<i32>, name: &str) -> Result<Self> {
|
||||
if let Some(user_id) = user_id {
|
||||
timeline_definition::table
|
||||
.filter(timeline_definition::user_id.eq(user_id))
|
||||
.filter(timeline_definition::name.eq(name))
|
||||
.first(conn)
|
||||
.map_err(Error::from)
|
||||
} else {
|
||||
timeline_definition::table
|
||||
.filter(timeline_definition::user_id.is_null())
|
||||
.filter(timeline_definition::name.eq(name))
|
||||
.first(conn)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
}
|
||||
trinity-1686a
commented
Welcome to the party! Welcome to the party!
Diesel consider that anything eq None unless we are that explicit
trinity-1686a
commented
I've tried for a few hours to add a I've tried for a few hours to add a `eq_optional` via some trait, but the best I got was "only" 4 compiler error, of which the shortest was 4 lines long. I'm giving up on this
kudos for trying. kudos for trying.
|
||||
|
||||
pub fn list_for_user(conn: &Connection, user_id: Option<i32>) -> Result<Vec<Self>> {
|
||||
if let Some(user_id) = user_id {
|
||||
timeline_definition::table
|
||||
.filter(timeline_definition::user_id.eq(user_id))
|
||||
.order(timeline_definition::ord.asc())
|
||||
.load::<Self>(conn)
|
||||
.map_err(Error::from)
|
||||
} else {
|
||||
timeline_definition::table
|
||||
.filter(timeline_definition::user_id.is_null())
|
||||
.order(timeline_definition::ord.asc())
|
||||
.load::<Self>(conn)
|
||||
.map_err(Error::from)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_for_user(
|
||||
conn: &Connection,
|
||||
user_id: i32,
|
||||
name: String,
|
||||
query_string: String,
|
||||
ord: i32,
|
||||
) -> Result<Timeline> {
|
||||
{
|
||||
let query = TimelineQuery::parse(&query_string)?; // verify the query is valid
|
||||
|
@ -79,6 +107,7 @@ impl Timeline {
|
|||
user_id: Some(user_id),
|
||||
name,
|
||||
query: query_string,
|
||||
ord,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -87,6 +116,7 @@ impl Timeline {
|
|||
conn: &Connection,
|
||||
name: String,
|
||||
query_string: String,
|
||||
ord: i32,
|
||||
) -> Result<Timeline> {
|
||||
{
|
||||
let query = TimelineQuery::parse(&query_string)?; // verify the query is valid
|
||||
|
@ -116,10 +146,17 @@ impl Timeline {
|
|||
user_id: None,
|
||||
name,
|
||||
query: query_string,
|
||||
ord,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn update(&self, conn: &Connection) -> Result<Self> {
|
||||
diesel::update(self).set(self).execute(conn)?;
|
||||
let timeline = Self::get(conn, self.id)?;
|
||||
Ok(timeline)
|
||||
}
|
||||
|
||||
pub fn get_latest(&self, conn: &Connection, count: i32) -> Result<Vec<Post>> {
|
||||
self.get_page(conn, (0, count))
|
||||
}
|
||||
|
@ -164,3 +201,89 @@ impl Timeline {
|
|||
query.matches(conn, self, post, kind)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use diesel::Connection;
|
||||
use tests::db;
|
||||
use users::tests as userTests;
|
||||
|
||||
#[test]
|
||||
fn test_timeline() {
|
||||
let conn = &db();
|
||||
conn.test_transaction::<_, (), _>(|| {
|
||||
let users = userTests::fill_database(conn);
|
||||
|
||||
assert!(Timeline::new_for_user(
|
||||
conn,
|
||||
users[0].id,
|
||||
"my timeline".to_owned(),
|
||||
"invalid keyword".to_owned(),
|
||||
2
|
||||
)
|
||||
.is_err());
|
||||
let mut tl1_u1 = Timeline::new_for_user(
|
||||
conn,
|
||||
users[0].id,
|
||||
"my timeline".to_owned(),
|
||||
"all".to_owned(),
|
||||
2,
|
||||
)
|
||||
.unwrap();
|
||||
let tl2_u1 = Timeline::new_for_user(
|
||||
conn,
|
||||
users[0].id,
|
||||
"another timeline".to_owned(),
|
||||
"followed".to_owned(),
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
let _tl1_u2 = Timeline::new_for_user(
|
||||
conn,
|
||||
users[1].id,
|
||||
"english posts".to_owned(),
|
||||
"lang in [en]".to_owned(),
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
let tl1_instance = Timeline::new_for_instance(
|
||||
conn,
|
||||
"english posts".to_owned(),
|
||||
"license in [cc]".to_owned(),
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(tl1_u1, Timeline::get(conn, tl1_u1.id).unwrap());
|
||||
assert_eq!(
|
||||
tl2_u1,
|
||||
Timeline::find_by_name(conn, Some(users[0].id), "another timeline")
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
tl1_instance,
|
||||
Timeline::find_by_name(conn, None, "english posts").unwrap()
|
||||
);
|
||||
|
||||
let tl_u1 = Timeline::list_for_user(conn, Some(users[0].id)).unwrap();
|
||||
assert_eq!(2, tl_u1.len());
|
||||
assert_eq!(tl2_u1, tl_u1[0]);
|
||||
haah haah
trinity-1686a
commented
I'm not good at this whole "giving name to lists" thing I'm not good at this whole "giving name to lists" thing
i disagree, i think you're very good 😸 i disagree, i think you're very good 😸
|
||||
assert_eq!(tl1_u1, tl_u1[1]);
|
||||
|
||||
let tl_instance = Timeline::list_for_user(conn, None).unwrap();
|
||||
assert_eq!(1, tl_instance.len());
|
||||
assert_eq!(tl1_instance, tl_instance[0]);
|
||||
|
||||
tl1_u1.ord = 0;
|
||||
let new_tl1_u1 = tl1_u1.update(conn).unwrap();
|
||||
|
||||
let tl_u1 = Timeline::list_for_user(conn, Some(users[0].id)).unwrap();
|
||||
assert_eq!(2, tl_u1.len());
|
||||
assert_eq!(new_tl1_u1, tl_u1[0]);
|
||||
assert_eq!(tl2_u1, tl_u1[1]);
|
||||
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use activitypub::{
|
|||
};
|
||||
use bcrypt;
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl};
|
||||
use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, SaveChangesDsl};
|
||||
use openssl::{
|
||||
hash::MessageDigest,
|
||||
pkey::{PKey, Private},
|
||||
|
@ -237,10 +237,8 @@ impl User {
|
|||
pub fn find_by_fqn(c: &PlumeRocket, fqn: &str) -> Result<User> {
|
||||
let from_db = users::table
|
||||
.filter(users::fqn.eq(fqn))
|
||||
.limit(1)
|
||||
.load::<User>(&*c.conn)?
|
||||
.into_iter()
|
||||
.next();
|
||||
.first(&*c.conn)
|
||||
.optional()?;
|
||||
if let Some(from_db) = from_db {
|
||||
Ok(from_db)
|
||||
} else {
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
mkdir bin
|
||||
cp target/release/{plume,plm} bin
|
||||
strip -s bin/*
|
||||
tar -cvzf plume.tar.gz bin/ static/ migrations/$FEATURES
|
||||
tar -cvzf plume.tar.gz bin/ static/
|
||||
|
|
Invalid
without thee
i dunno, this feels like an error…