1 use super::community_view::community_fast_view::BoxedQuery;
2 use crate::{fuzzy_search, limit_and_offset, MaybeOptional, SortType};
3 use diesel::{pg::Pg, result::Error, *};
4 use serde::{Deserialize, Serialize};
11 icon -> Nullable<Text>,
12 banner -> Nullable<Text>,
13 description -> Nullable<Text>,
17 published -> Timestamp,
18 updated -> Nullable<Timestamp>,
23 last_refreshed_at -> Timestamp,
24 creator_actor_id -> Text,
25 creator_local -> Bool,
26 creator_name -> Varchar,
27 creator_preferred_username -> Nullable<Varchar>,
28 creator_avatar -> Nullable<Text>,
29 category_name -> Varchar,
30 number_of_subscribers -> BigInt,
31 number_of_posts -> BigInt,
32 number_of_comments -> BigInt,
34 user_id -> Nullable<Int4>,
35 subscribed -> Nullable<Bool>,
40 community_fast_view (id) {
44 icon -> Nullable<Text>,
45 banner -> Nullable<Text>,
46 description -> Nullable<Text>,
50 published -> Timestamp,
51 updated -> Nullable<Timestamp>,
56 last_refreshed_at -> Timestamp,
57 creator_actor_id -> Text,
58 creator_local -> Bool,
59 creator_name -> Varchar,
60 creator_preferred_username -> Nullable<Varchar>,
61 creator_avatar -> Nullable<Text>,
62 category_name -> Varchar,
63 number_of_subscribers -> BigInt,
64 number_of_posts -> BigInt,
65 number_of_comments -> BigInt,
67 user_id -> Nullable<Int4>,
68 subscribed -> Nullable<Bool>,
73 community_moderator_view (id) {
77 published -> Timestamp,
78 user_actor_id -> Text,
81 user_preferred_username -> Nullable<Varchar>,
82 avatar -> Nullable<Text>,
83 community_actor_id -> Text,
84 community_local -> Bool,
85 community_name -> Varchar,
86 community_icon -> Nullable<Text>,
91 community_follower_view (id) {
95 published -> Timestamp,
96 user_actor_id -> Text,
99 user_preferred_username -> Nullable<Varchar>,
100 avatar -> Nullable<Text>,
101 community_actor_id -> Text,
102 community_local -> Bool,
103 community_name -> Varchar,
104 community_icon -> Nullable<Text>,
109 community_user_ban_view (id) {
111 community_id -> Int4,
113 published -> Timestamp,
114 user_actor_id -> Text,
116 user_name -> Varchar,
117 user_preferred_username -> Nullable<Varchar>,
118 avatar -> Nullable<Text>,
119 community_actor_id -> Text,
120 community_local -> Bool,
121 community_name -> Varchar,
122 community_icon -> Nullable<Text>,
126 #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, QueryableByName, Clone)]
127 #[table_name = "community_fast_view"]
128 pub struct CommunityView {
132 pub icon: Option<String>,
133 pub banner: Option<String>,
134 pub description: Option<String>,
135 pub category_id: i32,
138 pub published: chrono::NaiveDateTime,
139 pub updated: Option<chrono::NaiveDateTime>,
142 pub actor_id: String,
144 pub last_refreshed_at: chrono::NaiveDateTime,
145 pub creator_actor_id: String,
146 pub creator_local: bool,
147 pub creator_name: String,
148 pub creator_preferred_username: Option<String>,
149 pub creator_avatar: Option<String>,
150 pub category_name: String,
151 pub number_of_subscribers: i64,
152 pub number_of_posts: i64,
153 pub number_of_comments: i64,
155 pub user_id: Option<i32>,
156 pub subscribed: Option<bool>,
159 pub struct CommunityQueryBuilder<'a> {
160 conn: &'a PgConnection,
161 query: BoxedQuery<'a, Pg>,
163 from_user_id: Option<i32>,
165 search_term: Option<String>,
170 impl<'a> CommunityQueryBuilder<'a> {
171 pub fn create(conn: &'a PgConnection) -> Self {
172 use super::community_view::community_fast_view::dsl::*;
174 let query = community_fast_view.into_boxed();
176 CommunityQueryBuilder {
179 sort: &SortType::Hot,
188 pub fn sort(mut self, sort: &'a SortType) -> Self {
193 pub fn for_user<T: MaybeOptional<i32>>(mut self, from_user_id: T) -> Self {
194 self.from_user_id = from_user_id.get_optional();
198 pub fn show_nsfw(mut self, show_nsfw: bool) -> Self {
199 self.show_nsfw = show_nsfw;
203 pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
204 self.search_term = search_term.get_optional();
208 pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
209 self.page = page.get_optional();
213 pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
214 self.limit = limit.get_optional();
218 pub fn list(self) -> Result<Vec<CommunityView>, Error> {
219 use super::community_view::community_fast_view::dsl::*;
221 let mut query = self.query;
223 if let Some(search_term) = self.search_term {
224 let searcher = fuzzy_search(&search_term);
226 .filter(name.ilike(searcher.to_owned()))
227 .or_filter(title.ilike(searcher.to_owned()))
228 .or_filter(description.ilike(searcher));
231 // The view lets you pass a null user_id, if you're not logged in
233 SortType::New => query = query.order_by(published.desc()).filter(user_id.is_null()),
234 SortType::TopAll => match self.from_user_id {
235 Some(from_user_id) => {
237 .filter(user_id.eq(from_user_id))
238 .order_by((subscribed.asc(), number_of_subscribers.desc()))
242 .order_by(number_of_subscribers.desc())
243 .filter(user_id.is_null())
246 // Covers all other sorts, including hot
249 .order_by(hot_rank.desc())
250 .then_order_by(number_of_subscribers.desc())
251 .filter(user_id.is_null())
256 query = query.filter(nsfw.eq(false));
259 let (limit, offset) = limit_and_offset(self.page, self.limit);
263 .filter(removed.eq(false))
264 .filter(deleted.eq(false))
265 .load::<CommunityView>(self.conn)
272 from_community_id: i32,
273 from_user_id: Option<i32>,
274 ) -> Result<Self, Error> {
275 use super::community_view::community_fast_view::dsl::*;
277 let mut query = community_fast_view.into_boxed();
279 query = query.filter(id.eq(from_community_id));
281 // The view lets you pass a null user_id, if you're not logged in
282 if let Some(from_user_id) = from_user_id {
283 query = query.filter(user_id.eq(from_user_id));
285 query = query.filter(user_id.is_null());
288 query.first::<Self>(conn)
293 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
295 #[table_name = "community_moderator_view"]
296 pub struct CommunityModeratorView {
298 pub community_id: i32,
300 pub published: chrono::NaiveDateTime,
301 pub user_actor_id: String,
302 pub user_local: bool,
303 pub user_name: String,
304 pub user_preferred_username: Option<String>,
305 pub avatar: Option<String>,
306 pub community_actor_id: String,
307 pub community_local: bool,
308 pub community_name: String,
309 pub community_icon: Option<String>,
312 impl CommunityModeratorView {
313 pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
314 use super::community_view::community_moderator_view::dsl::*;
315 community_moderator_view
316 .filter(community_id.eq(for_community_id))
321 pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
322 use super::community_view::community_moderator_view::dsl::*;
323 community_moderator_view
324 .filter(user_id.eq(for_user_id))
331 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
333 #[table_name = "community_follower_view"]
334 pub struct CommunityFollowerView {
336 pub community_id: i32,
338 pub published: chrono::NaiveDateTime,
339 pub user_actor_id: String,
340 pub user_local: bool,
341 pub user_name: String,
342 pub user_preferred_username: Option<String>,
343 pub avatar: Option<String>,
344 pub community_actor_id: String,
345 pub community_local: bool,
346 pub community_name: String,
347 pub community_icon: Option<String>,
350 impl CommunityFollowerView {
351 pub fn for_community(conn: &PgConnection, from_community_id: i32) -> Result<Vec<Self>, Error> {
352 use super::community_view::community_follower_view::dsl::*;
353 community_follower_view
354 .filter(community_id.eq(from_community_id))
358 pub fn for_user(conn: &PgConnection, from_user_id: i32) -> Result<Vec<Self>, Error> {
359 use super::community_view::community_follower_view::dsl::*;
360 community_follower_view
361 .filter(user_id.eq(from_user_id))
367 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
369 #[table_name = "community_user_ban_view"]
370 pub struct CommunityUserBanView {
372 pub community_id: i32,
374 pub published: chrono::NaiveDateTime,
375 pub user_actor_id: String,
376 pub user_local: bool,
377 pub user_name: String,
378 pub user_preferred_username: Option<String>,
379 pub avatar: Option<String>,
380 pub community_actor_id: String,
381 pub community_local: bool,
382 pub community_name: String,
383 pub community_icon: Option<String>,
386 impl CommunityUserBanView {
390 from_community_id: i32,
391 ) -> Result<Self, Error> {
392 use super::community_view::community_user_ban_view::dsl::*;
393 community_user_ban_view
394 .filter(user_id.eq(from_user_id))
395 .filter(community_id.eq(from_community_id))