4 #[derive(Serialize, Deserialize)]
5 pub struct ListCategories;
7 #[derive(Serialize, Deserialize)]
8 pub struct ListCategoriesResponse {
10 categories: Vec<Category>
13 #[derive(Serialize, Deserialize)]
17 community_id: Option<i32>,
23 #[derive(Serialize, Deserialize)]
24 pub struct SearchResponse {
26 comments: Vec<CommentView>,
30 #[derive(Serialize, Deserialize)]
31 pub struct GetModlog {
32 mod_user_id: Option<i32>,
33 community_id: Option<i32>,
38 #[derive(Serialize, Deserialize)]
39 pub struct GetModlogResponse {
41 removed_posts: Vec<ModRemovePostView>,
42 locked_posts: Vec<ModLockPostView>,
43 removed_comments: Vec<ModRemoveCommentView>,
44 removed_communities: Vec<ModRemoveCommunityView>,
45 banned_from_community: Vec<ModBanFromCommunityView>,
46 banned: Vec<ModBanView>,
47 added_to_community: Vec<ModAddCommunityView>,
48 added: Vec<ModAddView>,
52 #[derive(Serialize, Deserialize)]
53 pub struct CreateSite {
55 description: Option<String>,
59 #[derive(Serialize, Deserialize)]
62 description: Option<String>,
66 #[derive(Serialize, Deserialize)]
70 #[derive(Serialize, Deserialize)]
71 pub struct SiteResponse {
76 #[derive(Serialize, Deserialize)]
77 pub struct GetSiteResponse {
79 site: Option<SiteView>,
80 admins: Vec<UserView>,
81 banned: Vec<UserView>,
84 impl Perform<ListCategoriesResponse> for Oper<ListCategories> {
85 fn perform(&self) -> Result<ListCategoriesResponse, Error> {
86 let _data: &ListCategories = &self.data;
87 let conn = establish_connection();
89 let categories: Vec<Category> = Category::list_all(&conn)?;
93 ListCategoriesResponse {
94 op: self.op.to_string(),
95 categories: categories
101 impl Perform<GetModlogResponse> for Oper<GetModlog> {
102 fn perform(&self) -> Result<GetModlogResponse, Error> {
103 let data: &GetModlog = &self.data;
104 let conn = establish_connection();
106 let removed_posts = ModRemovePostView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?;
107 let locked_posts = ModLockPostView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?;
108 let removed_comments = ModRemoveCommentView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?;
109 let banned_from_community = ModBanFromCommunityView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?;
110 let added_to_community = ModAddCommunityView::list(&conn, data.community_id, data.mod_user_id, data.page, data.limit)?;
112 // These arrays are only for the full modlog, when a community isn't given
113 let mut removed_communities = Vec::new();
114 let mut banned = Vec::new();
115 let mut added = Vec::new();
117 if data.community_id.is_none() {
118 removed_communities = ModRemoveCommunityView::list(&conn, data.mod_user_id, data.page, data.limit)?;
119 banned = ModBanView::list(&conn, data.mod_user_id, data.page, data.limit)?;
120 added = ModAddView::list(&conn, data.mod_user_id, data.page, data.limit)?;
126 op: self.op.to_string(),
127 removed_posts: removed_posts,
128 locked_posts: locked_posts,
129 removed_comments: removed_comments,
130 removed_communities: removed_communities,
131 banned_from_community: banned_from_community,
133 added_to_community: added_to_community,
140 impl Perform<SiteResponse> for Oper<CreateSite> {
141 fn perform(&self) -> Result<SiteResponse, Error> {
142 let data: &CreateSite = &self.data;
143 let conn = establish_connection();
145 let claims = match Claims::decode(&data.auth) {
146 Ok(claims) => claims.claims,
148 return Err(APIError::err(&self.op, "Not logged in."))?
152 if has_slurs(&data.name) ||
153 (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) {
154 return Err(APIError::err(&self.op, "No slurs"))?
157 let user_id = claims.id;
159 // Make sure user is an admin
160 if !UserView::read(&conn, user_id)?.admin {
161 return Err(APIError::err(&self.op, "Not an admin."))?
164 let site_form = SiteForm {
165 name: data.name.to_owned(),
166 description: data.description.to_owned(),
171 match Site::create(&conn, &site_form) {
174 return Err(APIError::err(&self.op, "Site exists already"))?
178 let site_view = SiteView::read(&conn)?;
182 op: self.op.to_string(),
190 impl Perform<SiteResponse> for Oper<EditSite> {
191 fn perform(&self) -> Result<SiteResponse, Error> {
192 let data: &EditSite = &self.data;
193 let conn = establish_connection();
195 let claims = match Claims::decode(&data.auth) {
196 Ok(claims) => claims.claims,
198 return Err(APIError::err(&self.op, "Not logged in."))?
202 if has_slurs(&data.name) ||
203 (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) {
204 return Err(APIError::err(&self.op, "No slurs"))?
207 let user_id = claims.id;
209 // Make sure user is an admin
210 if UserView::read(&conn, user_id)?.admin == false {
211 return Err(APIError::err(&self.op, "Not an admin."))?
214 let found_site = Site::read(&conn, 1)?;
216 let site_form = SiteForm {
217 name: data.name.to_owned(),
218 description: data.description.to_owned(),
219 creator_id: found_site.creator_id,
220 updated: Some(naive_now()),
223 match Site::update(&conn, 1, &site_form) {
226 return Err(APIError::err(&self.op, "Couldn't update site."))?
230 let site_view = SiteView::read(&conn)?;
234 op: self.op.to_string(),
241 impl Perform<GetSiteResponse> for Oper<GetSite> {
242 fn perform(&self) -> Result<GetSiteResponse, Error> {
243 let _data: &GetSite = &self.data;
244 let conn = establish_connection();
246 // It can return a null site in order to redirect
247 let site_view = match Site::read(&conn, 1) {
248 Ok(_site) => Some(SiteView::read(&conn)?),
252 let admins = UserView::admins(&conn)?;
253 let banned = UserView::banned(&conn)?;
257 op: self.op.to_string(),
266 impl Perform<SearchResponse> for Oper<Search> {
267 fn perform(&self) -> Result<SearchResponse, Error> {
268 let data: &Search = &self.data;
269 let conn = establish_connection();
271 let sort = SortType::from_str(&data.sort)?;
272 let type_ = SearchType::from_str(&data.type_)?;
274 let mut posts = Vec::new();
275 let mut comments = Vec::new();
278 SearchType::Posts => {
279 posts = PostView::list(&conn,
280 PostListingType::All,
284 Some(data.q.to_owned()),
291 SearchType::Comments => {
292 comments = CommentView::list(&conn,
296 Some(data.q.to_owned()),
302 SearchType::Both => {
303 posts = PostView::list(&conn,
304 PostListingType::All,
308 Some(data.q.to_owned()),
314 comments = CommentView::list(&conn,
318 Some(data.q.to_owned()),
330 op: self.op.to_string(),