Browse Source

Merge branch 'main' into federation-authorisation

pull/78/head
Felix Ableitner 8 months ago
parent
commit
0cc49e6ca9
77 changed files with 3628 additions and 1090 deletions
  1. +40
    -0
      RELEASES.md
  2. +1
    -1
      ansible/VERSION
  3. +0
    -12
      ansible/templates/nginx.conf
  4. +2
    -1
      docker/dev/docker-compose.yml
  5. +0
    -36
      docker/federation/nginx.conf
  6. +9
    -0
      docker/lemmy.hjson
  7. +1
    -1
      docker/prod/docker-compose.yml
  8. +2
    -2
      docker/travis/docker_push.sh
  9. +3
    -1
      docs/src/about_ranking.md
  10. +23
    -2
      docs/src/contributing_websocket_http_api.md
  11. +6
    -0
      server/config/defaults.hjson
  12. +1
    -0
      server/lemmy_db/src/activity.rs
  13. +3
    -0
      server/lemmy_db/src/comment.rs
  14. +30
    -1
      server/lemmy_db/src/comment_view.rs
  15. +9
    -0
      server/lemmy_db/src/community.rs
  16. +21
    -0
      server/lemmy_db/src/community_view.rs
  17. +15
    -0
      server/lemmy_db/src/lib.rs
  18. +4
    -0
      server/lemmy_db/src/moderator.rs
  19. +1
    -0
      server/lemmy_db/src/password_reset_request.rs
  20. +3
    -0
      server/lemmy_db/src/post.rs
  21. +21
    -0
      server/lemmy_db/src/post_view.rs
  22. +2
    -0
      server/lemmy_db/src/private_message.rs
  23. +4
    -0
      server/lemmy_db/src/private_message_view.rs
  24. +16
    -0
      server/lemmy_db/src/schema.rs
  25. +15
    -1
      server/lemmy_db/src/site.rs
  26. +6
    -0
      server/lemmy_db/src/site_view.rs
  27. +5
    -1
      server/lemmy_db/src/user.rs
  28. +4
    -0
      server/lemmy_db/src/user_mention.rs
  29. +12
    -0
      server/lemmy_db/src/user_mention_view.rs
  30. +13
    -0
      server/lemmy_db/src/user_view.rs
  31. +3
    -0
      server/lemmy_utils/src/settings.rs
  32. +704
    -0
      server/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/down.sql
  33. +748
    -0
      server/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/up.sql
  34. +20
    -1
      server/src/api/community.rs
  35. +17
    -12
      server/src/api/site.rs
  36. +16
    -5
      server/src/api/user.rs
  37. +29
    -1
      server/src/apub/community.rs
  38. +2
    -0
      server/src/apub/inbox/activities/delete.rs
  39. +2
    -0
      server/src/apub/inbox/activities/remove.rs
  40. +4
    -0
      server/src/apub/inbox/activities/undo.rs
  41. +29
    -7
      server/src/apub/user.rs
  42. +4
    -1
      server/src/code_migrations.rs
  43. +3
    -2
      server/src/main.rs
  44. +13
    -0
      server/src/rate_limit/mod.rs
  45. +1
    -0
      server/src/rate_limit/rate_limiter.rs
  46. +140
    -0
      server/src/routes/images.rs
  47. +1
    -0
      server/src/routes/mod.rs
  48. +1
    -1
      server/src/version.rs
  49. +16
    -0
      ui/assets/css/main.css
  50. +104
    -0
      ui/assets/css/themes/_variables.darkly.scss
  51. +1
    -35
      ui/assets/css/themes/darkly.min.css
  52. +1
    -1
      ui/src/api_tests/shared.ts
  53. +2
    -0
      ui/src/components/admin-settings.tsx
  54. +30
    -0
      ui/src/components/banner-icon-header.tsx
  55. +2
    -0
      ui/src/components/comment-node.tsx
  56. +0
    -2
      ui/src/components/communities.tsx
  57. +51
    -3
      ui/src/components/community-form.tsx
  58. +24
    -2
      ui/src/components/community-link.tsx
  59. +43
    -1
      ui/src/components/community.tsx
  60. +114
    -0
      ui/src/components/image-upload-form.tsx
  61. +26
    -3
      ui/src/components/main.tsx
  62. +75
    -46
      ui/src/components/navbar.tsx
  63. +714
    -638
      ui/src/components/post-listing.tsx
  64. +14
    -1
      ui/src/components/post.tsx
  65. +2
    -0
      ui/src/components/private-message-form.tsx
  66. +22
    -27
      ui/src/components/private-message.tsx
  67. +2
    -0
      ui/src/components/search.tsx
  68. +34
    -19
      ui/src/components/sidebar.tsx
  69. +50
    -0
      ui/src/components/site-form.tsx
  70. +4
    -1
      ui/src/components/sort-select.tsx
  71. +3
    -0
      ui/src/components/symbols.tsx
  72. +22
    -8
      ui/src/components/user-listing.tsx
  73. +182
    -202
      ui/src/components/user.tsx
  74. +26
    -0
      ui/src/interfaces.ts
  75. +33
    -6
      ui/src/utils.ts
  76. +6
    -1
      ui/translations/en.json
  77. +16
    -5
      ui/translations/it.json

+ 40
- 0
RELEASES.md View File

@ -1,3 +1,43 @@
# Lemmy v0.7.40 Pre-Release (2020-08-05)
We've [added a lot](https://github.com/LemmyNet/lemmy/compare/v0.7.40...v0.7.0) in this pre-release:
- New post sorts `Active` (previously called hot), and `Hot`. Active shows posts with recent comments, hot shows highly ranked posts.
- Customizeable site icon and banner, user icon and banner, and community icon and banner.
- Added user preferred names / display names, bios, and cakedays.
- User settings are now shared across browsers (a page refresh will pick up changes).
- Visual / Audio captchas through the lemmy API.
- Lots of UI prettiness.
- Lots of bug fixes.
- Lots of additional translations.
- Lots of federation prepping / additions / refactors.
This release removes the need for you to have a pictrs nginx route (the requests are now routed through lemmy directly). Follow the upgrade instructions below to replace your nginx with the new one.
## Upgrading
**With Ansible:**
```
# run these commands locally
git pull
cd ansible
ansible-playbook lemmy.yml
```
**With manual Docker installation:**
```
# run these commands on your server
cd /lemmy
wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/ansible/templates/nginx.conf
# Replace the {{ vars }}
sudo mv nginx.conf /etc/nginx/sites-enabled/lemmy.conf
sudo nginx -s reload
wget https://raw.githubusercontent.com/LemmyNet/lemmy/master/docker/prod/docker-compose.yml
sudo docker-compose up -d
```
# Lemmy v0.7.0 Release (2020-06-23)
This release replaces [pictshare](https://github.com/HaschekSolutions/pictshare)


+ 1
- 1
ansible/VERSION View File

@ -1 +1 @@
v0.7.39
v0.7.43

+ 0
- 12
ansible/templates/nginx.conf View File

@ -74,18 +74,6 @@ server {
return 301 /pictrs/image/$1;
}
# pict-rs images
location /pictrs {
location /pictrs/image {
proxy_pass http://0.0.0.0:8537/image;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Block the import
return 403;
}
location /iframely/ {
proxy_pass http://0.0.0.0:8061/;
proxy_set_header X-Real-IP $remote_addr;


+ 2
- 1
docker/dev/docker-compose.yml View File

@ -21,7 +21,8 @@ services:
postgres:
image: postgres:12-alpine
ports:
- "127.0.0.1:5432:5432"
# use a different port so it doesnt conflict with postgres running on the host
- "127.0.0.1:5433:5432"
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=password


+ 0
- 36
docker/federation/nginx.conf View File

@ -26,18 +26,6 @@ http {
proxy_set_header Connection "upgrade";
}
# pict-rs images
location /pictrs {
location /pictrs/image {
proxy_pass http://pictrs:8080/image;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Block the import
return 403;
}
location /iframely/ {
proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr;
@ -69,18 +57,6 @@ http {
proxy_set_header Connection "upgrade";
}
# pict-rs images
location /pictrs {
location /pictrs/image {
proxy_pass http://pictrs:8080/image;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Block the import
return 403;
}
location /iframely/ {
proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr;
@ -112,18 +88,6 @@ http {
proxy_set_header Connection "upgrade";
}
# pict-rs images
location /pictrs {
location /pictrs/image {
proxy_pass http://pictrs:8080/image;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Block the import
return 403;
}
location /iframely/ {
proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr;


+ 9
- 0
docker/lemmy.hjson View File

@ -2,6 +2,15 @@
# for more info about the config, check out the documentation
# https://dev.lemmy.ml/docs/administration_configuration.html
setup: {
# username for the admin user
admin_username: "lemmy"
# password for the admin user
admin_password: "lemmy"
# name of the site (can be changed later)
site_name: "lemmy-test"
}
# the domain name of your instance (eg "dev.lemmy.ml")
hostname: "my_domain"
# address where lemmy should listen for incoming requests


+ 1
- 1
docker/prod/docker-compose.yml View File

@ -12,7 +12,7 @@ services:
restart: always
lemmy:
image: dessalines/lemmy:v0.7.39
image: dessalines/lemmy:v0.7.43
ports:
- "127.0.0.1:8536:8536"
restart: always


+ 2
- 2
docker/travis/docker_push.sh View File

@ -1,5 +1,5 @@
#!/bin/sh
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
docker tag dessalines/lemmy:travis \
dessalines/lemmy:v0.7.39
docker push dessalines/lemmy:v0.7.39
dessalines/lemmy:v0.7.43
docker push dessalines/lemmy:v0.7.43

+ 3
- 1
docs/src/about_ranking.md View File

@ -18,7 +18,9 @@ Score = Upvotes - Downvotes
Time = time since submission (in hours)
Gravity = Decay gravity, 1.8 is default
```
- For posts, in order to bring up active posts, it uses the latest comment time (limited to a max creation age of a month ago)
- Lemmy uses the same `Rank` algorithm above, in two sorts: `Active`, and `Hot`.
- `Active` uses the post votes, and latest comment time (limited to two days).
- `Hot` uses the post votes, and the post published time.
- Use Max(1, score) to make sure all comments are affected by time decay.
- Add 3 to the score, so that everything that has less than 3 downvotes will seem new. Otherwise all new comments would stay at zero, near the bottom.
- The sign and abs of the score are necessary for dealing with the log of negative scores.


+ 23
- 2
docs/src/contributing_websocket_http_api.md View File

@ -330,7 +330,8 @@ curl -i -H \
These go wherever there is a `sort` field. The available sort types are:
- `Hot` - the hottest posts/communities, depending on votes, views, comments and publish date
- `Active` - the hottest posts/communities, depending on votes, and newest comment publish date.
- `Hot` - the hottest posts/communities, depending on votes and publish date.
- `New` - the newest posts/communities
- `TopDay` - the most upvoted posts/communities of the current day.
- `TopWeek` - the most upvoted posts/communities of the current week.
@ -482,7 +483,19 @@ These expire after 10 minutes.
theme: String, // Default 'darkly'
default_sort_type: i16, // The Sort types from above, zero indexed as a number
default_listing_type: i16, // Post listing types are `All, Subscribed, Community`
auth: String
lang: String,
avatar: Option<String>,
banner: Option<String>,
preferred_username: Option<String>,
email: Option<String>,
bio: Option<String>,
matrix_user_id: Option<String>,
new_password: Option<String>,
new_password_verify: Option<String>,
old_password: Option<String>,
show_avatars: bool,
send_notifications_to_email: bool,
auth: String,
}
}
```
@ -924,6 +937,8 @@ Search types are `All, Comments, Posts, Communities, Users, Url`
data: {
name: String,
description: Option<String>,
icon: Option<String>,
banner: Option<String>,
auth: String
}
}
@ -950,6 +965,8 @@ Search types are `All, Comments, Posts, Communities, Users, Url`
data: {
name: String,
description: Option<String>,
icon: Option<String>,
banner: Option<String>,
auth: String
}
}
@ -1105,6 +1122,8 @@ Search types are `All, Comments, Posts, Communities, Users, Url`
name: String,
title: String,
description: Option<String>,
icon: Option<String>,
banner: Option<String>,
category_id: i32 ,
auth: String
}
@ -1215,6 +1234,8 @@ Only mods can edit a community.
edit_id: i32,
title: String,
description: Option<String>,
icon: Option<String>,
banner: Option<String>,
category_id: i32,
auth: String
}


+ 6
- 0
server/config/defaults.hjson View File

@ -35,6 +35,8 @@
jwt_secret: "changeme"
# The location of the frontend
front_end_dir: "../ui/dist"
# address where pictrs is available
pictrs_url: "http://pictrs:8080"
# rate limits for various user actions, by user ip
rate_limit: {
# maximum number of messages created in interval
@ -49,6 +51,10 @@
register: 3
# interval length for registration limit
register_per_second: 3600
# maximum number of image uploads in interval
image: 6
# interval length for image uploads
image_per_second: 3600
}
# settings related to activitypub federation
federation: {


+ 1
- 0
server/lemmy_db/src/activity.rs View File

@ -107,6 +107,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,


+ 3
- 0
server/lemmy_db/src/comment.rs View File

@ -255,6 +255,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -291,6 +292,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
banner: None,
icon: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();


+ 30
- 1
server/lemmy_db/src/comment_view.rs View File

@ -23,17 +23,20 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
banned -> Bool,
banned_from_community -> Bool,
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Timestamp,
creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -60,17 +63,20 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
banned -> Bool,
banned_from_community -> Bool,
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Timestamp,
creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -100,17 +106,20 @@ pub struct CommentView {
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
pub banned: bool,
pub banned_from_community: bool,
pub creator_actor_id: String,
pub creator_local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_published: chrono::NaiveDateTime,
pub creator_avatar: Option<String>,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
pub hot_rank: i32,
pub hot_rank_active: i32,
pub user_id: Option<i32>,
pub my_vote: Option<i32>,
pub subscribed: Option<bool>,
@ -244,6 +253,9 @@ impl<'a> CommentQueryBuilder<'a> {
SortType::Hot => query
.order_by(hot_rank.desc())
.then_order_by(published.desc()),
SortType::Active => query
.order_by(hot_rank_active.desc())
.then_order_by(published.desc()),
SortType::New => query.order_by(published.desc()),
SortType::TopAll => query.order_by(score.desc()),
SortType::TopYear => query
@ -315,17 +327,20 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Varchar>,
banned -> Bool,
banned_from_community -> Bool,
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
creator_published -> Timestamp,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -356,17 +371,20 @@ pub struct ReplyView {
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
pub banned: bool,
pub banned_from_community: bool,
pub creator_actor_id: String,
pub creator_local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub creator_published: chrono::NaiveDateTime,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
pub hot_rank: i32,
pub hot_rank_active: i32,
pub user_id: Option<i32>,
pub my_vote: Option<i32>,
pub subscribed: Option<bool>,
@ -437,7 +455,7 @@ impl<'a> ReplyQueryBuilder<'a> {
}
query = match self.sort {
// SortType::Hot => query.order_by(hot_rank.desc()),
// SortType::Hot => query.order_by(hot_rank.desc()), // TODO why is this commented
SortType::New => query.order_by(published.desc()),
SortType::TopAll => query.order_by(score.desc()),
SortType::TopYear => query
@ -488,6 +506,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -524,6 +543,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();
@ -584,6 +605,7 @@ mod tests {
post_name: inserted_post.name.to_owned(),
community_id: inserted_community.id,
community_name: inserted_community.name.to_owned(),
community_icon: None,
parent_id: None,
removed: false,
deleted: false,
@ -593,11 +615,13 @@ mod tests {
published: inserted_comment.published,
updated: None,
creator_name: inserted_user.name.to_owned(),
creator_preferred_username: None,
creator_published: inserted_user.published,
creator_avatar: None,
score: 1,
downvotes: 0,
hot_rank: 0,
hot_rank_active: 0,
upvotes: 1,
user_id: None,
my_vote: None,
@ -619,6 +643,7 @@ mod tests {
post_name: inserted_post.name.to_owned(),
community_id: inserted_community.id,
community_name: inserted_community.name.to_owned(),
community_icon: None,
parent_id: None,
removed: false,
deleted: false,
@ -628,11 +653,13 @@ mod tests {
published: inserted_comment.published,
updated: None,
creator_name: inserted_user.name.to_owned(),
creator_preferred_username: None,
creator_published: inserted_user.published,
creator_avatar: None,
score: 1,
downvotes: 0,
hot_rank: 0,
hot_rank_active: 0,
upvotes: 1,
user_id: Some(inserted_user.id),
my_vote: Some(1),
@ -651,6 +678,7 @@ mod tests {
.list()
.unwrap();
read_comment_views_no_user[0].hot_rank = 0;
read_comment_views_no_user[0].hot_rank_active = 0;
let mut read_comment_views_with_user = CommentQueryBuilder::create(&conn)
.for_post_id(inserted_post.id)
@ -658,6 +686,7 @@ mod tests {
.list()
.unwrap();
read_comment_views_with_user[0].hot_rank = 0;
read_comment_views_with_user[0].hot_rank_active = 0;
let like_removed = CommentLike::remove(&conn, &comment_like_form).unwrap();
let num_deleted = Comment::delete(&conn, inserted_comment.id).unwrap();


+ 9
- 0
server/lemmy_db/src/community.rs View File

@ -28,6 +28,8 @@ pub struct Community {
pub private_key: Option<String>,
pub public_key: Option<String>,
pub last_refreshed_at: chrono::NaiveDateTime,
pub icon: Option<String>,
pub banner: Option<String>,
}
#[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize, Debug)]
@ -48,6 +50,8 @@ pub struct CommunityForm {
pub private_key: Option<String>,
pub public_key: Option<String>,
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
pub icon: Option<Option<String>>,
pub banner: Option<Option<String>>,
}
impl Crud<CommunityForm> for Community {
@ -299,6 +303,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -335,6 +340,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();
@ -356,6 +363,8 @@ mod tests {
private_key: None,
public_key: None,
last_refreshed_at: inserted_community.published,
icon: None,
banner: None,
};
let community_follower_form = CommunityFollowerForm {


+ 21
- 0
server/lemmy_db/src/community_view.rs View File

@ -8,6 +8,8 @@ table! {
id -> Int4,
name -> Varchar,
title -> Varchar,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
description -> Nullable<Text>,
category_id -> Int4,
creator_id -> Int4,
@ -22,6 +24,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
category_name -> Varchar,
number_of_subscribers -> BigInt,
@ -38,6 +41,8 @@ table! {
id -> Int4,
name -> Varchar,
title -> Varchar,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
description -> Nullable<Text>,
category_id -> Int4,
creator_id -> Int4,
@ -52,6 +57,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
category_name -> Varchar,
number_of_subscribers -> BigInt,
@ -72,10 +78,12 @@ table! {
user_actor_id -> Text,
user_local -> Bool,
user_name -> Varchar,
user_preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
}
}
@ -88,10 +96,12 @@ table! {
user_actor_id -> Text,
user_local -> Bool,
user_name -> Varchar,
user_preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
}
}
@ -104,10 +114,12 @@ table! {
user_actor_id -> Text,
user_local -> Bool,
user_name -> Varchar,
user_preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
}
}
@ -119,6 +131,8 @@ pub struct CommunityView {
pub id: i32,
pub name: String,
pub title: String,
pub icon: Option<String>,
pub banner: Option<String>,
pub description: Option<String>,
pub category_id: i32,
pub creator_id: i32,
@ -133,6 +147,7 @@ pub struct CommunityView {
pub creator_actor_id: String,
pub creator_local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub category_name: String,
pub number_of_subscribers: i64,
@ -288,10 +303,12 @@ pub struct CommunityModeratorView {
pub user_actor_id: String,
pub user_local: bool,
pub user_name: String,
pub user_preferred_username: Option<String>,
pub avatar: Option<String>,
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
}
impl CommunityModeratorView {
@ -324,10 +341,12 @@ pub struct CommunityFollowerView {
pub user_actor_id: String,
pub user_local: bool,
pub user_name: String,
pub user_preferred_username: Option<String>,
pub avatar: Option<String>,
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
}
impl CommunityFollowerView {
@ -358,10 +377,12 @@ pub struct CommunityUserBanView {
pub user_actor_id: String,
pub user_local: bool,
pub user_name: String,
pub user_preferred_username: Option<String>,
pub avatar: Option<String>,
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
}
impl CommunityUserBanView {


+ 15
- 0
server/lemmy_db/src/lib.rs View File

@ -134,6 +134,7 @@ pub fn get_database_url_from_env() -> Result<String, VarError> {
#[derive(EnumString, ToString, Debug, Serialize, Deserialize)]
pub enum SortType {
Active,
Hot,
New,
TopDay,
@ -180,6 +181,20 @@ pub fn is_email_regex(test: &str) -> bool {
EMAIL_REGEX.is_match(test)
}
pub fn diesel_option_overwrite(opt: &Option<String>) -> Option<Option<String>> {
match opt {
// An empty string is an erase
Some(unwrapped) => {
if !unwrapped.eq("") {
Some(Some(unwrapped.to_owned()))
} else {
Some(None)
}
}
None => None,
}
}
lazy_static! {
static ref EMAIL_REGEX: Regex =
Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap();


+ 4
- 0
server/lemmy_db/src/moderator.rs View File

@ -460,6 +460,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -487,6 +488,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -523,6 +525,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();


+ 1
- 0
server/lemmy_db/src/password_reset_request.rs View File

@ -95,6 +95,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,


+ 3
- 0
server/lemmy_db/src/post.rs View File

@ -316,6 +316,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -352,6 +353,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();


+ 21
- 0
server/lemmy_db/src/post_view.rs View File

@ -28,6 +28,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Timestamp,
creator_avatar -> Nullable<Text>,
banned -> Bool,
@ -35,6 +36,7 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
community_removed -> Bool,
community_deleted -> Bool,
community_nsfw -> Bool,
@ -43,6 +45,7 @@ table! {
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
newest_activity_time -> Timestamp,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
@ -76,6 +79,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Timestamp,
creator_avatar -> Nullable<Text>,
banned -> Bool,
@ -83,6 +87,7 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
community_removed -> Bool,
community_deleted -> Bool,
community_nsfw -> Bool,
@ -91,6 +96,7 @@ table! {
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
newest_activity_time -> Timestamp,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
@ -127,6 +133,7 @@ pub struct PostView {
pub creator_actor_id: String,
pub creator_local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_published: chrono::NaiveDateTime,
pub creator_avatar: Option<String>,
pub banned: bool,
@ -134,6 +141,7 @@ pub struct PostView {
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
pub community_removed: bool,
pub community_deleted: bool,
pub community_nsfw: bool,
@ -142,6 +150,7 @@ pub struct PostView {
pub upvotes: i64,
pub downvotes: i64,
pub hot_rank: i32,
pub hot_rank_active: i32,
pub newest_activity_time: chrono::NaiveDateTime,
pub user_id: Option<i32>,
pub my_vote: Option<i32>,
@ -289,6 +298,9 @@ impl<'a> PostQueryBuilder<'a> {
}
query = match self.sort {
SortType::Active => query
.then_order_by(hot_rank_active.desc())
.then_order_by(published.desc()),
SortType::Hot => query
.then_order_by(hot_rank.desc())
.then_order_by(published.desc()),
@ -405,6 +417,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
updated: None,
admin: false,
banned: false,
@ -441,6 +454,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();
@ -519,6 +534,7 @@ mod tests {
body: None,
creator_id: inserted_user.id,
creator_name: user_name.to_owned(),
creator_preferred_username: None,
creator_published: inserted_user.published,
creator_avatar: None,
banned: false,
@ -529,6 +545,7 @@ mod tests {
locked: false,
stickied: false,
community_name: community_name.to_owned(),
community_icon: None,
community_removed: false,
community_deleted: false,
community_nsfw: false,
@ -537,6 +554,7 @@ mod tests {
upvotes: 1,
downvotes: 0,
hot_rank: read_post_listing_no_user.hot_rank,
hot_rank_active: read_post_listing_no_user.hot_rank_active,
published: inserted_post.published,
newest_activity_time: inserted_post.published,
updated: None,
@ -569,12 +587,14 @@ mod tests {
stickied: false,
creator_id: inserted_user.id,
creator_name: user_name,
creator_preferred_username: None,
creator_published: inserted_user.published,
creator_avatar: None,
banned: false,
banned_from_community: false,
community_id: inserted_community.id,
community_name,
community_icon: None,
community_removed: false,
community_deleted: false,
community_nsfw: false,
@ -583,6 +603,7 @@ mod tests {
upvotes: 1,
downvotes: 0,
hot_rank: read_post_listing_with_user.hot_rank,
hot_rank_active: read_post_listing_with_user.hot_rank_active,
published: inserted_post.published,
newest_activity_time: inserted_post.published,
updated: None,


+ 2
- 0
server/lemmy_db/src/private_message.rs View File

@ -147,6 +147,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -174,6 +175,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,


+ 4
- 0
server/lemmy_db/src/private_message_view.rs View File

@ -16,10 +16,12 @@ table! {
ap_id -> Text,
local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
creator_actor_id -> Text,
creator_local -> Bool,
recipient_name -> Varchar,
recipient_preferred_username -> Nullable<Varchar>,
recipient_avatar -> Nullable<Text>,
recipient_actor_id -> Text,
recipient_local -> Bool,
@ -42,10 +44,12 @@ pub struct PrivateMessageView {
pub ap_id: String,
pub local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub creator_actor_id: String,
pub creator_local: bool,
pub recipient_name: String,
pub recipient_preferred_username: Option<String>,
pub recipient_avatar: Option<String>,
pub recipient_actor_id: String,
pub recipient_local: bool,


+ 16
- 0
server/lemmy_db/src/schema.rs View File

@ -52,17 +52,20 @@ table! {
community_actor_id -> Nullable<Varchar>,
community_local -> Nullable<Bool>,
community_name -> Nullable<Varchar>,
community_icon -> Nullable<Text>,
banned -> Nullable<Bool>,
banned_from_community -> Nullable<Bool>,
creator_actor_id -> Nullable<Varchar>,
creator_local -> Nullable<Bool>,
creator_name -> Nullable<Varchar>,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Nullable<Timestamp>,
creator_avatar -> Nullable<Text>,
score -> Nullable<Int8>,
upvotes -> Nullable<Int8>,
downvotes -> Nullable<Int8>,
hot_rank -> Nullable<Int4>,
hot_rank_active -> Nullable<Int4>,
}
}
@ -104,6 +107,8 @@ table! {
private_key -> Nullable<Text>,
public_key -> Nullable<Text>,
last_refreshed_at -> Timestamp,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
}
}
@ -112,6 +117,8 @@ table! {
id -> Int4,
name -> Nullable<Varchar>,
title -> Nullable<Varchar>,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
description -> Nullable<Text>,
category_id -> Nullable<Int4>,
creator_id -> Nullable<Int4>,
@ -126,6 +133,7 @@ table! {
creator_actor_id -> Nullable<Varchar>,
creator_local -> Nullable<Bool>,
creator_name -> Nullable<Varchar>,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
category_name -> Nullable<Varchar>,
number_of_subscribers -> Nullable<Int8>,
@ -319,6 +327,7 @@ table! {
creator_actor_id -> Nullable<Varchar>,
creator_local -> Nullable<Bool>,
creator_name -> Nullable<Varchar>,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Nullable<Timestamp>,
creator_avatar -> Nullable<Text>,
banned -> Nullable<Bool>,
@ -326,6 +335,7 @@ table! {
community_actor_id -> Nullable<Varchar>,
community_local -> Nullable<Bool>,
community_name -> Nullable<Varchar>,
community_icon -> Nullable<Text>,
community_removed -> Nullable<Bool>,
community_deleted -> Nullable<Bool>,
community_nsfw -> Nullable<Bool>,
@ -334,6 +344,7 @@ table! {
upvotes -> Nullable<Int8>,
downvotes -> Nullable<Int8>,
hot_rank -> Nullable<Int4>,
hot_rank_active -> Nullable<Int4>,
newest_activity_time -> Nullable<Timestamp>,
}
}
@ -392,6 +403,8 @@ table! {
enable_downvotes -> Bool,
open_registration -> Bool,
enable_nsfw -> Bool,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
}
}
@ -421,6 +434,7 @@ table! {
private_key -> Nullable<Text>,
public_key -> Nullable<Text>,
last_refreshed_at -> Timestamp,
banner -> Nullable<Text>,
}
}
@ -437,7 +451,9 @@ table! {
id -> Int4,
actor_id -> Nullable<Varchar>,
name -> Nullable<Varchar>,
preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
banner -> Nullable<Text>,
email -> Nullable<Text>,
matrix_user_id -> Nullable<Text>,
bio -> Nullable<Text>,


+ 15
- 1
server/lemmy_db/src/site.rs View File

@ -1,4 +1,4 @@
use crate::{schema::site, Crud};
use crate::{naive_now, schema::site, Crud};
use diesel::{dsl::*, result::Error, *};
use serde::{Deserialize, Serialize};
@ -14,6 +14,8 @@ pub struct Site {
pub enable_downvotes: bool,
pub open_registration: bool,
pub enable_nsfw: bool,
pub icon: Option<String>,
pub banner: Option<String>,
}
#[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize)]
@ -26,6 +28,9 @@ pub struct SiteForm {
pub enable_downvotes: bool,
pub open_registration: bool,
pub enable_nsfw: bool,
// when you want to null out a column, you have to send Some(None)), since sending None means you just don't want to update that column.
pub icon: Option<Option<String>>,
pub banner: Option<Option<String>>,
}
impl Crud<SiteForm> for Site {
@ -51,3 +56,12 @@ impl Crud<SiteForm> for Site {
.get_result::<Self>(conn)
}
}
impl Site {
pub fn transfer(conn: &PgConnection, new_creator_id: i32) -> Result<Self, Error> {
use crate::schema::site::dsl::*;
diesel::update(site.find(1))
.set((creator_id.eq(new_creator_id), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
}

+ 6
- 0
server/lemmy_db/src/site_view.rs View File

@ -12,7 +12,10 @@ table! {
enable_downvotes -> Bool,
open_registration -> Bool,
enable_nsfw -> Bool,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
number_of_users -> BigInt,
number_of_posts -> BigInt,
@ -35,7 +38,10 @@ pub struct SiteView {
pub enable_downvotes: bool,
pub open_registration: bool,
pub enable_nsfw: bool,
pub icon: Option<String>,
pub banner: Option<String>,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub number_of_users: i64,
pub number_of_posts: i64,


+ 5
- 1
server/lemmy_db/src/user.rs View File

@ -35,6 +35,7 @@ pub struct User_ {
pub private_key: Option<String>,
pub public_key: Option<String>,
pub last_refreshed_at: chrono::NaiveDateTime,
pub banner: Option<String>,
}
#[derive(Insertable, AsChangeset, Clone, Debug)]
@ -46,7 +47,7 @@ pub struct UserForm {
pub admin: bool,
pub banned: bool,
pub email: Option<String>,
pub avatar: Option<String>,
pub avatar: Option<Option<String>>,
pub updated: Option<chrono::NaiveDateTime>,
pub show_nsfw: bool,
pub theme: String,
@ -62,6 +63,7 @@ pub struct UserForm {
pub private_key: Option<String>,
pub public_key: Option<String>,
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
pub banner: Option<Option<String>>,
}
impl Crud<UserForm> for User_ {
@ -167,6 +169,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -195,6 +198,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
published: inserted_user.published,


+ 4
- 0
server/lemmy_db/src/user_mention.rs View File

@ -100,6 +100,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -127,6 +128,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -163,6 +165,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();


+ 12
- 0
server/lemmy_db/src/user_mention_view.rs View File

@ -23,14 +23,17 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
banned -> Bool,
banned_from_community -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
saved -> Nullable<Bool>,
@ -60,14 +63,17 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
banned -> Bool,
banned_from_community -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
saved -> Nullable<Bool>,
@ -100,14 +106,17 @@ pub struct UserMentionView {
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
pub banned: bool,
pub banned_from_community: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
pub hot_rank: i32,
pub hot_rank_active: i32,
pub user_id: Option<i32>,
pub my_vote: Option<i32>,
pub saved: Option<bool>,
@ -180,6 +189,9 @@ impl<'a> UserMentionQueryBuilder<'a> {
SortType::Hot => query
.order_by(hot_rank.desc())
.then_order_by(published.desc()),
SortType::Active => query
.order_by(hot_rank_active.desc())