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>,
127 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
129 #[table_name = "community_fast_view"]
130 pub struct CommunityView {
134 pub icon: Option<String>,
135 pub banner: Option<String>,
136 pub description: Option<String>,
137 pub category_id: i32,
140 pub published: chrono::NaiveDateTime,
141 pub updated: Option<chrono::NaiveDateTime>,
144 pub actor_id: String,
146 pub last_refreshed_at: chrono::NaiveDateTime,
147 pub creator_actor_id: String,
148 pub creator_local: bool,
149 pub creator_name: String,
150 pub creator_preferred_username: Option<String>,
151 pub creator_avatar: Option<String>,
152 pub category_name: String,
153 pub number_of_subscribers: i64,
154 pub number_of_posts: i64,
155 pub number_of_comments: i64,
157 pub user_id: Option<i32>,
158 pub subscribed: Option<bool>,
161 pub struct CommunityQueryBuilder<'a> {
162 conn: &'a PgConnection,
163 query: BoxedQuery<'a, Pg>,
165 from_user_id: Option<i32>,
167 search_term: Option<String>,
172 impl<'a> CommunityQueryBuilder<'a> {
173 pub fn create(conn: &'a PgConnection) -> Self {
174 use super::community_view::community_fast_view::dsl::*;
176 let query = community_fast_view.into_boxed();
178 CommunityQueryBuilder {
181 sort: &SortType::Hot,
190 pub fn sort(mut self, sort: &'a SortType) -> Self {
195 pub fn for_user<T: MaybeOptional<i32>>(mut self, from_user_id: T) -> Self {
196 self.from_user_id = from_user_id.get_optional();
200 pub fn show_nsfw(mut self, show_nsfw: bool) -> Self {
201 self.show_nsfw = show_nsfw;
205 pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
206 self.search_term = search_term.get_optional();
210 pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
211 self.page = page.get_optional();
215 pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
216 self.limit = limit.get_optional();
220 pub fn list(self) -> Result<Vec<CommunityView>, Error> {
221 use super::community_view::community_fast_view::dsl::*;
223 let mut query = self.query;
225 if let Some(search_term) = self.search_term {
226 let searcher = fuzzy_search(&search_term);
228 .filter(name.ilike(searcher.to_owned()))
229 .or_filter(title.ilike(searcher.to_owned()))
230 .or_filter(description.ilike(searcher));
233 // The view lets you pass a null user_id, if you're not logged in
237 .order_by(hot_rank.desc())
238 .then_order_by(number_of_subscribers.desc())
239 .filter(user_id.is_null())
241 SortType::New => query = query.order_by(published.desc()).filter(user_id.is_null()),
242 SortType::TopAll => match self.from_user_id {
243 Some(from_user_id) => {
245 .filter(user_id.eq(from_user_id))
246 .order_by((subscribed.asc(), number_of_subscribers.desc()))
250 .order_by(number_of_subscribers.desc())
251 .filter(user_id.is_null())
258 query = query.filter(nsfw.eq(false));
261 let (limit, offset) = limit_and_offset(self.page, self.limit);
265 .filter(removed.eq(false))
266 .filter(deleted.eq(false))
267 .load::<CommunityView>(self.conn)
274 from_community_id: i32,
275 from_user_id: Option<i32>,
276 ) -> Result<Self, Error> {
277 use super::community_view::community_fast_view::dsl::*;
279 let mut query = community_fast_view.into_boxed();
281 query = query.filter(id.eq(from_community_id));
283 // The view lets you pass a null user_id, if you're not logged in
284 if let Some(from_user_id) = from_user_id {
285 query = query.filter(user_id.eq(from_user_id));
287 query = query.filter(user_id.is_null());
290 query.first::<Self>(conn)
295 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
297 #[table_name = "community_moderator_view"]
298 pub struct CommunityModeratorView {
300 pub community_id: i32,
302 pub published: chrono::NaiveDateTime,
303 pub user_actor_id: String,
304 pub user_local: bool,
305 pub user_name: String,
306 pub user_preferred_username: Option<String>,
307 pub avatar: Option<String>,
308 pub community_actor_id: String,
309 pub community_local: bool,
310 pub community_name: String,
311 pub community_icon: Option<String>,
314 impl CommunityModeratorView {
315 pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
316 use super::community_view::community_moderator_view::dsl::*;
317 community_moderator_view
318 .filter(community_id.eq(for_community_id))
323 pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
324 use super::community_view::community_moderator_view::dsl::*;
325 community_moderator_view
326 .filter(user_id.eq(for_user_id))
333 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
335 #[table_name = "community_follower_view"]
336 pub struct CommunityFollowerView {
338 pub community_id: i32,
340 pub published: chrono::NaiveDateTime,
341 pub user_actor_id: String,
342 pub user_local: bool,
343 pub user_name: String,
344 pub user_preferred_username: Option<String>,
345 pub avatar: Option<String>,
346 pub community_actor_id: String,
347 pub community_local: bool,
348 pub community_name: String,
349 pub community_icon: Option<String>,
352 impl CommunityFollowerView {
353 pub fn for_community(conn: &PgConnection, from_community_id: i32) -> Result<Vec<Self>, Error> {
354 use super::community_view::community_follower_view::dsl::*;
355 community_follower_view
356 .filter(community_id.eq(from_community_id))
360 pub fn for_user(conn: &PgConnection, from_user_id: i32) -> Result<Vec<Self>, Error> {
361 use super::community_view::community_follower_view::dsl::*;
362 community_follower_view
363 .filter(user_id.eq(from_user_id))
369 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
371 #[table_name = "community_user_ban_view"]
372 pub struct CommunityUserBanView {
374 pub community_id: i32,
376 pub published: chrono::NaiveDateTime,
377 pub user_actor_id: String,
378 pub user_local: bool,
379 pub user_name: String,
380 pub user_preferred_username: Option<String>,
381 pub avatar: Option<String>,
382 pub community_actor_id: String,
383 pub community_local: bool,
384 pub community_name: String,
385 pub community_icon: Option<String>,
388 impl CommunityUserBanView {
389 pub fn for_community(conn: &PgConnection, from_community_id: i32) -> Result<Vec<Self>, Error> {
390 use super::community_view::community_user_ban_view::dsl::*;
391 community_user_ban_view
392 .filter(community_id.eq(from_community_id))
396 pub fn for_user(conn: &PgConnection, from_user_id: i32) -> Result<Vec<Self>, Error> {
397 use super::community_view::community_user_ban_view::dsl::*;
398 community_user_ban_view
399 .filter(user_id.eq(from_user_id))
406 from_community_id: i32,
407 ) -> Result<Self, Error> {
408 use super::community_view::community_user_ban_view::dsl::*;
409 community_user_ban_view
410 .filter(user_id.eq(from_user_id))
411 .filter(community_id.eq(from_community_id))