Browse Source

components: Fix some react warnings.

Definitely need to respect that you can't access this.setState() for params that are linkedEvent.
pull/269/head
Ryexandra 1 year ago
committed by GreatBearShark M
parent
commit
a19048507a
  1. BIN
      .DS_Store
  2. 3
      .gitignore
  3. 59
      .travis.yml
  4. 11
      README.md
  5. 40
      RELEASES.md
  6. 2
      ansible/VERSION
  7. 23
      ansible/templates/nginx.conf
  8. 7
      docker/chapo-dev/docker-compose.yml
  9. 9
      docker/chapo-prod/docker-compose.yml
  10. 3
      docker/dev/Dockerfile
  11. 3
      docker/dev/docker-compose.yml
  12. 1
      docker/federation-test/servers.sh
  13. 9
      docker/federation/docker-compose.yml
  14. 45
      docker/federation/nginx.conf
  15. 9
      docker/lemmy.hjson
  16. 4
      docker/prod/Dockerfile
  17. 44
      docker/prod/deploy.sh
  18. 2
      docker/prod/docker-compose.yml
  19. 122
      docker/travis/docker-compose.yml
  20. 5
      docker/travis/docker_push.sh
  21. 26
      docker/travis/run-tests.sh
  22. 2
      docs/src/about_guide.md
  23. 4
      docs/src/about_ranking.md
  24. 43
      docs/src/administration_backup_and_restore.md
  25. 2
      docs/src/administration_configuration.md
  26. 49
      docs/src/contributing_local_development.md
  27. 897
      docs/src/contributing_websocket_http_api.md
  28. 485
      server/Cargo.lock
  29. 8
      server/Cargo.toml
  30. 10
      server/config/config.hjson
  31. 14
      server/config/defaults.hjson
  32. 2
      server/lemmy_db/Cargo.toml
  33. 4
      server/lemmy_db/src/activity.rs
  34. 56
      server/lemmy_db/src/comment.rs
  35. 36
      server/lemmy_db/src/comment_view.rs
  36. 69
      server/lemmy_db/src/community.rs
  37. 29
      server/lemmy_db/src/community_view.rs
  38. 36
      server/lemmy_db/src/lib.rs
  39. 12
      server/lemmy_db/src/moderator.rs
  40. 4
      server/lemmy_db/src/password_reset_request.rs
  41. 55
      server/lemmy_db/src/post.rs
  42. 26
      server/lemmy_db/src/post_view.rs
  43. 60
      server/lemmy_db/src/private_message.rs
  44. 4
      server/lemmy_db/src/private_message_view.rs
  45. 92
      server/lemmy_db/src/schema.rs
  46. 16
      server/lemmy_db/src/site.rs
  47. 6
      server/lemmy_db/src/site_view.rs
  48. 47
      server/lemmy_db/src/user.rs
  49. 36
      server/lemmy_db/src/user_mention.rs
  50. 12
      server/lemmy_db/src/user_mention_view.rs
  51. 57
      server/lemmy_db/src/user_view.rs
  52. 2
      server/lemmy_utils/Cargo.toml
  53. 7
      server/lemmy_utils/src/lib.rs
  54. 26
      server/lemmy_utils/src/settings.rs
  55. 20
      server/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/down.sql
  56. 50
      server/migrations/2020-07-18-234519_add_unique_community_user_actor_ids/up.sql
  57. 16
      server/migrations/2020-08-02-020129_create_user_tags/up.sql
  58. 46
      server/migrations/2020-08-02-052800_add_sitemod_column/down.sql
  59. 47
      server/migrations/2020-08-02-052800_add_sitemod_column/up.sql
  60. 714
      server/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/down.sql
  61. 764
      server/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/up.sql
  62. 30
      server/src/api/claims.rs
  63. 592
      server/src/api/comment.rs
  64. 503
      server/src/api/community.rs
  65. 94
      server/src/api/mod.rs
  66. 679
      server/src/api/post.rs
  67. 210
      server/src/api/site.rs
  68. 806
      server/src/api/user.rs
  69. 27
      server/src/apub/activities.rs
  70. 80
      server/src/apub/comment.rs
  71. 150
      server/src/apub/community.rs
  72. 2
      server/src/apub/extensions/group_extensions.rs
  73. 5
      server/src/apub/extensions/page_extension.rs
  74. 5
      server/src/apub/extensions/signatures.rs
  75. 179
      server/src/apub/fetcher.rs
  76. 41
      server/src/apub/inbox/activities/announce.rs
  77. 125
      server/src/apub/inbox/activities/create.rs
  78. 225
      server/src/apub/inbox/activities/delete.rs
  79. 134
      server/src/apub/inbox/activities/dislike.rs
  80. 134
      server/src/apub/inbox/activities/like.rs
  81. 8
      server/src/apub/inbox/activities/mod.rs
  82. 225
      server/src/apub/inbox/activities/remove.rs
  83. 556
      server/src/apub/inbox/activities/undo.rs
  84. 127
      server/src/apub/inbox/activities/update.rs
  85. 67
      server/src/apub/inbox/community_inbox.rs
  86. 4
      server/src/apub/inbox/mod.rs
  87. 154
      server/src/apub/inbox/shared_inbox.rs
  88. 132
      server/src/apub/inbox/user_inbox.rs
  89. 66
      server/src/apub/mod.rs
  90. 95
      server/src/apub/post.rs
  91. 44
      server/src/apub/private_message.rs
  92. 1514
      server/src/apub/shared_inbox.rs
  93. 89
      server/src/apub/user.rs
  94. 53
      server/src/code_migrations.rs
  95. 106
      server/src/hcaptcha.rs
  96. 90
      server/src/lib.rs
  97. 5
      server/src/main.rs
  98. 13
      server/src/rate_limit/mod.rs
  99. 5
      server/src/rate_limit/rate_limiter.rs
  100. 12
      server/src/request.rs

BIN
.DS_Store

3
.gitignore

@ -16,3 +16,6 @@ ui/src/translations
# ide config
.idea/
.vscode/
target

59
.travis.yml

@ -1,35 +1,28 @@
language: rust
rust:
- stable
matrix:
allow_failures:
- rust: nightly
fast_finish: true
cache: cargo
before_cache:
- rm -rfv target/debug/incremental/lemmy_server-*
- rm -rfv target/debug/.fingerprint/lemmy_server-*
- rm -rfv target/debug/build/lemmy_server-*
- rm -rfv target/debug/deps/lemmy_server-*
- rm -rfv target/debug/lemmy_server.d
before_script:
- psql -c "create user lemmy with password 'password' superuser;" -U postgres
- psql -c 'create database lemmy with owner lemmy;' -U postgres
- rustup component add clippy --toolchain stable-x86_64-unknown-linux-gnu
before_install:
- cd server
script:
# Default checks, but fail if anything is detected
- cargo build
- cargo clippy -- -D clippy::style -D clippy::correctness -D clippy::complexity -D clippy::perf
- cargo install diesel_cli --no-default-features --features postgres --force
- diesel migration run
- cargo test --workspace
sudo: required
language: node_js
node_js:
- 14
services:
- docker
env:
matrix:
- DOCKER_COMPOSE_VERSION=1.25.5
global:
- DATABASE_URL=postgres://lemmy:[email protected]:5432/lemmy
- LEMMY_DATABASE_URL=postgres://lemmy:[email protected]:5432/lemmy
- RUST_TEST_THREADS=1
addons:
postgresql: "9.4"
- secure: nzmFoTxPn7OT+qcTULezSCT6B44j/q8RxERBQSr1FVXaCcDrBr6q9ewhGy7BHWP74r4qbif4m9r3sNELZCoFYFP3JwLnrZfX/xUwU8p61eFD2PMOJAdOywDxb94SvooOSnjBmxNvRsuqf6Zmnw378mbsSVCi9Xbx9jpoV4Jq8zKgO0M8WIl/lj2dijD95WIMrHcorbzKS3+2zW3LkPiC2bnfDAUmUDfaCj1gh9FCvzZMtrSxu7kxAeFCkR16TJUciIcGgag8rLHfxwG0h2uEJJ+3/62qCWUdgnj171oTE4ZRi0hdvt2HOY5wjHfS2y1ZxWYgo31uws3pyoTNeQZi0o7Q9Xe/4JXYZXvDfuscSZ9RiuhAstCVswtXPJJVVJQ9cdl5eX1TI0bz8eVRvRy4p40OIBjKiobkmRjl8sXjFbpYAIvFr+TgSa/K/bxm3POfI0B8bIHI85zFxUMrWt5i2IJ0dWvDNHrz+CWWKn1vVFYbBNPgDDHtE0P3LWLEioWFf+ULycjW8DefWc+b63Lf9SSaEE7FnX2mc+BaHCgubCDkJy9Au4xP8zQlJjgZwOdTedw5jvmwz3fqMZBpHypVUXzZs7cRhMWtQ7TAoGb8TOqXNgPEVW+BARNXl0wAamTgjt9v20x0wkp+/SLJwMNY+zvwmzxzd5R9TPgDOqyIRTU=
- secure: ALZqC4OYV315P7EZyk+c/PLJdneeU7jMC30TTzMcX3hospIu7naWekZ+HUnziFDQKZxIHWKZsq1R52DWhsERLrPF3SVa+QiXu8vTTPrETBWnu9VgyFzgdEbUKRas1X3qerEAHcNBms1EAl2FOiQM1k5EDygrClv4KWgyzntEtKJbN2UCFKxtoBSdMZA6fcGtCwffcj8uIAIP2NhZixbU+smVgVbpMpe6QEuuEoVlVrfH8iXxb8Gi+qkd0YIYAHkjtTqQ/nHuAUhcuEE0mORTNGPv7CmTwpuQiGCCdtySZc7Qq8z1x2y7RLy0+RVxM0PR8UV6iy4ipyTgZ6wTF30ksLDxOI3GlRaKF3F6kLErOiEiEUOqa+zLgUM0OLGTn+KLATQDx74in5NcKjKUAnkuxdZyuDbifvQb5tqfrGdXd22pzVZbielRJRW59ig0Nr5cxEpRtoRkoFKNk7o3XlD6JmIBjKn1UHkZ4H/oLUKIXT2qOP2fIEzgLjfpSuGwhvJRz1KRP49HYVl7Gkd45/RdZ519W0gnMkIrEaod90iXSFNTgmJTGeH0Mv0jHameN47PIT3c49MOy5Hj0XCHUPfc6qqrdGnliS5hTnrFThCfn5ZuSZxVdgGLJUQvV+D+5KDqjFdGyNGVGoEg0YdrDtGXmpojbyQDJAT7ToL3yIBF7co=
before_install:
# Install docker-compose
- sudo rm /usr/local/bin/docker-compose
- curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname
-s`-`uname -m` > docker-compose
- chmod +x docker-compose
- sudo mv docker-compose /usr/local/bin
# Change dir
- cd docker/travis
script:
- "./run-tests.sh"
deploy:
provider: script
script: bash docker_push.sh
on:
tags: true

11
README.md

@ -7,3 +7,14 @@
The goal is to contribute to the upstream [Lemmy](https://github.com/LemmyNet/lemmy) project while also trying to retain the r/CTH flavor that brought the community together in the first place.
Please make sure to visit the original readme for all of the information.
## Running in Docker
```
cd docker/dev
sudo ./docker_update.sh
sudo docker-compose down
# connect to the docker postgresql
psql -h localhost -p 5432 -U lemmy # password is password
```

40
RELEASES.md

@ -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)

2
ansible/VERSION

@ -1 +1 @@
v0.7.25
v0.7.41

23
ansible/templates/nginx.conf

@ -1,4 +1,3 @@
proxy_cache_path /var/cache/lemmy_frontend levels=1:2 keys_zone=lemmy_frontend_cache:10m max_size=100m use_temp_path=off;
limit_req_zone $binary_remote_addr zone=lemmy_ratelimit:10m rate=1r/s;
server {
@ -61,17 +60,13 @@ server {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Proxy Cache
proxy_cache lemmy_frontend_cache;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
proxy_cache_revalidate on;
proxy_cache_lock on;
proxy_cache_min_uses 5;
}
# Redirect pictshare images to pictrs
@ -79,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;

7
docker/chapo-dev/docker-compose.yml

@ -11,7 +11,7 @@ services:
- RUST_LOG=error
- LEMMY_DATABASE__PASSWORD=${LEMMYDEV_POSTGRES_PW}
- LEMMY_DATABASE__HOST=postgres-dev
- LEMMY_HOSTNAME=dev.chapo.chat
- LEMMY_HOSTNAME=${LEMMYDEV_LEMMY_HOSTNAME}
- LEMMY_PORT=8536
- LEMMY_EMAIL__SMTP_SERVER=mail.chapo.chat
- [email protected]
@ -19,7 +19,10 @@ services:
- LEMMY_EMAIL__SMTP_PASSWORD=${LEMMYDEV_SMTP_PASSWORD}
- LEMMY_EMAIL__USE_TLS=true
- LEMMY_JWT_SECRET=${LEMMYDEV_JWT_SECRET}
- HCAPTCHA_SECRET_KEY=${LEMMYDEV_HCAPTCHA_SECRET_KEY}
- LEMMY_CAPTCHA__ENABLED=true
- LEMMY_CAPTCHA__PROVIDER=hcaptcha
- LEMMY_CAPTHCA__HCAPTCHA_SECRET_KEY=${LEMMYDEV_HCAPTCHA_SECRET_KEY}
- LEMMY_CAPTCHA__HCAPTCHA_SITE_KEY=${LEMMYDEV_HCAPTCHA_SITE_KEY}
volumes:
- ./lemmy.hjson:/config/config.hjson:ro
depends_on:

9
docker/chapo-prod/docker-compose.yml

@ -12,7 +12,7 @@ services:
- LEMMY_DATABASE__PASSWORD=${LEMMYPROD_POSTGRES_PW}
- LEMMY_DATABASE__HOST=postgres-prod
- LEMMY_DATABASE__PORT=5433
- LEMMY_HOSTNAME=www.chapo.chat
- LEMMY_HOSTNAME=${LEMMYPROD_LEMMY_HOSTNAME}
- LEMMY_PORT=8546
- LEMMY_EMAIL__SMTP_SERVER=mail.chapo.chat
- [email protected]
@ -23,8 +23,13 @@ services:
- LEMMY_RATE_LIMIT__MESSAGE_PER_SECOND=30
- LEMMY_RATE_LIMIT__POST=12
- LEMMY_RATE_LIMIT__POST_PER_SECOND=600
- LEMMY_RATE_LIMIT__REGISTER=1
- LEMMY_RATE_LIMIT__REGISTER_PER_SECOND=86400
- LEMMY_JWT_SECRET=${LEMMYPROD_JWT_SECRET}
- HCAPTCHA_SECRET_KEY=${LEMMYPROD_HCAPTCHA_SECRET_KEY}
- LEMMY_CAPTCHA__ENABLED=true
- LEMMY_CAPTCHA__PROVIDER=hcaptcha
- LEMMY_CAPTHCA__HCAPTCHA_SECRET_KEY=${LEMMYPROD_HCAPTCHA_SECRET_KEY}
- LEMMY_CAPTCHA__HCAPTCHA_SITE_KEY=${LEMMYPROD_HCAPTCHA_SITE_KEY}
volumes:
- ./lemmy.hjson:/config/config.hjson:ro
depends_on:

3
docker/dev/Dockerfile

@ -41,6 +41,9 @@ FROM alpine:3.12
# Install libpq for postgres
RUN apk add libpq
# Install Espeak for captchas
RUN apk add espeak
# Copy resources
COPY server/config/defaults.hjson /config/defaults.hjson
COPY --from=rust /app/server/target/x86_64-unknown-linux-musl/debug/lemmy_server /app/lemmy

3
docker/dev/docker-compose.yml

@ -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

1
docker/federation-test/servers.sh

@ -1,6 +1,7 @@
#!/bin/bash
set -e
sudo docker-compose --file ../federation/docker-compose.yml --project-directory . down
sudo rm -rf volumes
pushd ../../server/

9
docker/federation/docker-compose.yml

@ -39,6 +39,9 @@ services:
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-alpha
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
@ -66,6 +69,9 @@ services:
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-beta
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
@ -93,6 +99,9 @@ services:
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-gamma
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:

45
docker/federation/nginx.conf

@ -17,24 +17,15 @@ http {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
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;
@ -57,24 +48,15 @@ http {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
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;
@ -97,24 +79,15 @@ http {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
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
docker/lemmy.hjson

@ -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

4
docker/prod/Dockerfile

@ -50,6 +50,10 @@ FROM alpine:3.12 as lemmy
# Install libpq for postgres
RUN apk add libpq
# Install Espeak for captchas
RUN apk add espeak
RUN addgroup -g 1000 lemmy
RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy

44
docker/prod/deploy.sh

@ -12,8 +12,6 @@ third_semver=$(echo $new_tag | cut -d "." -f 3)
# Setting the version on the front end
cd ../../
echo "export const version: string = '$new_tag';" > "ui/src/version.ts"
git add "ui/src/version.ts"
# Setting the version on the backend
echo "pub const VERSION: &str = \"$new_tag\";" > "server/src/version.rs"
git add "server/src/version.rs"
@ -26,35 +24,39 @@ cd docker/prod || exit
# Changing the docker-compose prod
sed -i "s/dessalines\/lemmy:.*/dessalines\/lemmy:$new_tag/" ../prod/docker-compose.yml
sed -i "s/dessalines\/lemmy:.*/dessalines\/lemmy:$new_tag/" ../../ansible/templates/docker-compose.yml
sed -i "s/dessalines\/lemmy:v.*/dessalines\/lemmy:$new_tag/" ../travis/docker_push.sh
git add ../prod/docker-compose.yml
git add ../../ansible/templates/docker-compose.yml
git add ../travis/docker_push.sh
# The commit
git commit -m"Version $new_tag"
git tag $new_tag
export COMPOSE_DOCKER_CLI_BUILD=1
export DOCKER_BUILDKIT=1
# Rebuilding docker
if [ $third_semver -eq 0 ]; then
# TODO get linux/arm/v7 build working
# Build for Raspberry Pi / other archs too
docker buildx build --platform linux/amd64,linux/arm64 ../../ \
--file Dockerfile \
--tag dessalines/lemmy:$new_tag \
--push
else
docker buildx build --platform linux/amd64 ../../ \
--file Dockerfile \
--tag dessalines/lemmy:$new_tag \
--push
fi
# Now doing the building on travis, but leave this in for when you need to do an arm build
# export COMPOSE_DOCKER_CLI_BUILD=1
# export DOCKER_BUILDKIT=1
# # Rebuilding docker
# if [ $third_semver -eq 0 ]; then
# # TODO get linux/arm/v7 build working
# # Build for Raspberry Pi / other archs too
# docker buildx build --platform linux/amd64,linux/arm64 ../../ \
# --file Dockerfile \
# --tag dessalines/lemmy:$new_tag \
# --push
# else
# docker buildx build --platform linux/amd64 ../../ \
# --file Dockerfile \
# --tag dessalines/lemmy:$new_tag \
# --push
# fi
# Push
git push origin $new_tag
git push
# Pushing to any ansible deploys
cd ../../../lemmy-ansible || exit
ansible-playbook -i prod playbooks/site.yml --vault-password-file vault_pass
# cd ../../../lemmy-ansible || exit
# ansible-playbook -i prod playbooks/site.yml --vault-password-file vault_pass

2
docker/prod/docker-compose.yml

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

122
docker/travis/docker-compose.yml

@ -0,0 +1,122 @@
version: '3.3'
services:
nginx:
image: nginx:1.17-alpine
ports:
- "8540:8540"
- "8550:8550"
- "8560:8560"
volumes:
# Hack to make this work from both docker/federation/ and docker/federation-test/
- ../federation/nginx.conf:/etc/nginx/nginx.conf
restart: on-failure
depends_on:
- lemmy-alpha
- pictrs
- lemmy-beta
- lemmy-gamma
- iframely
pictrs:
restart: always
image: asonix/pictrs:v0.1.13-r0
user: 991:991
volumes:
- ./volumes/pictrs_alpha:/mnt
lemmy-alpha:
image: dessalines/lemmy:travis
environment:
- LEMMY_HOSTNAME=lemmy-alpha:8540
- LEMMY_DATABASE_URL=postgres://lemmy:[email protected]_alpha:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma
- LEMMY_PORT=8540
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-alpha
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
- postgres_alpha
postgres_alpha:
image: postgres:12-alpine
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=password
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres_alpha:/var/lib/postgresql/data
lemmy-beta:
image: dessalines/lemmy:travis
environment:
- LEMMY_HOSTNAME=lemmy-beta:8550
- LEMMY_DATABASE_URL=postgres://lemmy:[email protected]_beta:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma
- LEMMY_PORT=8550
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-beta
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
- postgres_beta
postgres_beta:
image: postgres:12-alpine
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=password
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres_beta:/var/lib/postgresql/data
lemmy-gamma:
image: dessalines/lemmy:travis
environment:
- LEMMY_HOSTNAME=lemmy-gamma:8560
- LEMMY_DATABASE_URL=postgres://lemmy:[email protected]_gamma:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta
- LEMMY_PORT=8560
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-gamma
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
- postgres_gamma
postgres_gamma:
image: postgres:12-alpine
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=password
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres_gamma:/var/lib/postgresql/data
iframely:
image: dogbin/iframely:latest
volumes:
- ../iframely.config.local.js:/iframely/config.local.js:ro
restart: always

5
docker/travis/docker_push.sh

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

26
docker/travis/run-tests.sh

@ -0,0 +1,26 @@
#!/bin/bash
set -e
# make sure there are no old containers or old data around
sudo docker-compose down
sudo rm -rf volumes
mkdir -p volumes/pictrs_{alpha,beta,gamma}
sudo chown -R 991:991 volumes/pictrs_{alpha,beta,gamma}
sudo docker build ../../ --file ../prod/Dockerfile --tag dessalines/lemmy:travis
sudo docker-compose up -d
pushd ../../ui
echo "Waiting for Lemmy to start..."
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done
yarn
yarn api-test
popd
sudo docker-compose down
sudo rm -r volumes/

2
docs/src/about_guide.md

@ -35,6 +35,8 @@ Horizontal Rule <br>\--- | Horizontal Rule<br>\*\*\* | Horizontal Rule <br><hr>
\`Inline code\` with backticks | |`Inline code` with backticks
\`\`\`<br>\# code block <br>print '3 backticks or'<br>print 'indent 4 spaces' <br>\`\`\` | ····\# code block<br>····print '3 backticks or'<br>····print 'indent 4 spaces' | \# code block <br>print '3 backticks or'<br>print 'indent 4 spaces'
::: spoiler hidden or nsfw stuff<br>*a bunch of spoilers here*<br>::: | | <details><summary> hidden or nsfw stuff </summary><p><em>a bunch of spoilers here</em></p></details>
Some ~subscript~ text | | Some <sub>subscript</sub> text
Some ^superscript^ text | | Some <sup>superscript</sup> text
[CommonMark Tutorial](https://commonmark.org/help/tutorial/)

4
docs/src/about_ranking.md

@ -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.

43
docs/src/administration_backup_and_restore.md

@ -9,14 +9,14 @@ When using docker or ansible, there should be a `volumes` folder, which contains
To incrementally backup the DB to an `.sql` file, you can run:
```bash
docker exec -t FOLDERNAME_postgres_1 pg_dumpall -c -U lemmy > lemmy_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql
docker-compose exec postgres pg_dumpall -c -U lemmy > lemmy_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql
```
### A Sample backup script
```bash
#!/bin/sh
# DB Backup
ssh [email protected]_IP "docker exec -t FOLDERNAME_postgres_1 pg_dumpall -c -U lemmy" > ~/BACKUP_LOCATION/INSTANCE_NAME_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql
ssh [email protected]_IP "docker-compose exec postgres pg_dumpall -c -U lemmy" > ~/BACKUP_LOCATION/INSTANCE_NAME_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql
# Volumes folder Backup
rsync -avP -zz --rsync-path="sudo rsync" [email protected]_IP:/LEMMY_LOCATION/volumes ~/BACKUP_LOCATION/FOLDERNAME
@ -37,6 +37,45 @@ cat db_dump.sql | docker exec -i FOLDERNAME_postgres_1 psql -U lemmy # restore
docker exec -i FOLDERNAME_postgres_1 psql -U lemmy -c "alter user lemmy with password 'bleh'"
```
### Changing your domain name
If you haven't federated yet, you can change your domain name in the DB. **Warning: do not do this after you've federated, or it will break federation.**
Get into `psql` for your docker:
`docker-compose exec postgres psql -U lemmy`
```
-- Post
update post set ap_id = replace (ap_id, 'old_domain', 'new_domain');
update post set url = replace (url, 'old_domain', 'new_domain');
update post set body = replace (body, 'old_domain', 'new_domain');
update post set thumbnail_url = replace (thumbnail_url, 'old_domain', 'new_domain');
delete from post_aggregates_fast;
insert into post_aggregates_fast select * from post_aggregates_view;
-- Comments
update comment set ap_id = replace (ap_id, 'old_domain', 'new_domain');
update comment set content = replace (content, 'old_domain', 'new_domain');
delete from comment_aggregates_fast;
insert into comment_aggregates_fast select * from comment_aggregates_view;
-- User
update user_ set actor_id = replace (actor_id, 'old_domain', 'new_domain');
update user_ set avatar = replace (avatar, 'old_domain', 'new_domain');
delete from user_fast;
insert into user_fast select * from user_view;
-- Community
update community set actor_id = replace (actor_id, 'old_domain', 'new_domain');
delete from community_aggregates_fast;
insert into community_aggregates_fast select * from community_aggregates_view;
```
## More resources
- https://stackoverflow.com/questions/24718706/backup-restore-a-dockerized-postgresql-database

2
docs/src/administration_configuration.md

@ -5,7 +5,7 @@ The configuration is based on the file
This file also contains documentation for all the available options. To override the defaults, you
can copy the options you want to change into your local `config.hjson` file.
To use a different `config.hjson` location than the current directory, set the environment variable `LEMMY_CONFIG_LOCATION`.
To use a different `config.hjson` location than the current directory, set the environment variable `LEMMY_CONFIG_LOCATION`. Make sure you copy the `defaults.hjson` if you do this, otherwise you will be missing settings.
Additionally, you can override any config files with environment variables. These have the same
name as the config options, and are prefixed with `LEMMY_`. For example, you can override the

49
docs/src/contributing_local_development.md

@ -1,16 +1,26 @@
### Ubuntu
#### Build requirements:
### Install build requirements
#### Ubuntu
```
sudo apt install git cargo libssl-dev pkg-config libpq-dev yarn curl gnupg2 git
sudo apt install git cargo libssl-dev pkg-config libpq-dev yarn curl gnupg2 espeak
# install yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
```
#### Get the source code
#### macOS
Install Rust using [the recommended option on rust-lang.org](https://www.rust-lang.org/tools/install) (rustup).
Then, install [Homebrew](https://brew.sh/) if you don't already have it installed.
Finally, install Node and Yarn.
```
brew install node yarn
```
### Get the source code
```
git clone https://github.com/LemmyNet/lemmy.git
# or alternatively from gitea
@ -20,36 +30,49 @@ git clone https://github.com/LemmyNet/lemmy.git
All the following commands need to be run either in `lemmy/server` or `lemmy/ui`, as indicated
by the `cd` command.
#### Build the backend (Rust)
### Build the backend (Rust)
```
cd server
cargo build
# for development, use `cargo check` instead)
```
#### Build the frontend (Typescript)
### Build the frontend (Typescript)
```
cd ui
yarn
yarn build
```
#### Setup postgresql
### Setup postgresql
#### Ubuntu
```
sudo apt install postgresql
sudo systemctl start postgresql
# initialize postgres database
# Either execute server/db-init.sh, or manually initialize the postgres database:
sudo -u postgres psql -c "create user lemmy with password 'password' superuser;" -U postgres
sudo -u postgres psql -c 'create database lemmy with owner lemmy;' -U postgres
export LEMMY_DATABASE_URL=postgres://lemmy:[email protected]:5432/lemmy
# or execute server/db-init.sh
```
#### Run a local development instance
#### macOS
```
brew install postgresql
brew services start postgresql
/usr/local/opt/postgres/bin/createuser -s postgres
# Either execute server/db-init.sh, or manually initialize the postgres database:
psql -c "create user lemmy with password 'password' superuser;" -U postgres
psql -c 'create database lemmy with owner lemmy;' -U postgres
export LEMMY_DATABASE_URL=postgres://lemmy:[email protected]:5432/lemmy
```
### Run a local development instance
```
# run each of these in a seperate terminal
cd server && cargo run
ui & yarn start
cd ui && yarn start
```
Then open [localhost:4444](http://localhost:4444) in your browser. It will auto-refresh if you edit

897
docs/src/contributing_websocket_http_api.md
File diff suppressed because it is too large
View File

485
server/Cargo.lock
File diff suppressed because it is too large
View File

8
server/Cargo.toml

@ -17,9 +17,8 @@ members = [
lemmy_utils = { path = "./lemmy_utils" }
lemmy_db = { path = "./lemmy_db" }
# External deps
activitystreams-new = { git = "https://yerbamate.dev/asonix/activitystreams-new", branch = "main" }
activitystreams-ext = { git = "https://yerbamate.dev/asonix/activitystreams-ext", branch = "main" }
activitystreams = "0.7.0-alpha.3"
activitystreams-ext = "0.1.0-alpha.2"
actix = "0.10.0-alpha.2"
actix-files = "0.3.0-alpha.1"
actix-rt = "1.1.1"
@ -61,3 +60,6 @@ strum_macros = "0.18.0"
tokio = "0.2.21"
url = { version = "2.1.1", features = ["serde"] }
uuid = { version = "0.6", features = ["serde", "v4"] }
captcha = "0.0.7"
anyhow = "1.0.32"
thiserror = "1.0.20"

10
server/config/config.hjson

@ -1,5 +1,13 @@
{
hostname: "localhost:8536"
federation_enabled: true
federation_enabled: false
register_per_second: 1
captcha: {
enabled: true
provider: hcaptcha
difficulty: easy
hcaptcha_secret_key: "0x0000000000000000000000000000000000000000"
hcaptcha_site_key: "10000000-ffff-ffff-ffff-000000000001"
hcaptcha_verify_url: "https://hcaptcha.com/siteverify"
}
}

14
server/config/defaults.hjson

@ -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: {
@ -59,6 +65,14 @@
# comma seperated list of instances with which federation is allowed
allowed_instances: ""
}
captcha: {
enabled: true
provider: lemmy # Can be lemmy, hcaptcha
difficulty: medium # Can be easy, medium, or hard
hcaptcha_secret_key: "0x0000000000000000000000000000000000000000"
hcaptcha_site_key: "10000000-ffff-ffff-ffff-000000000001"
hcaptcha_verify_url: "https://hcaptcha.com/siteverify"
}
# # email sending configuration
# email: {
# # hostname and port of the smtp server

2
server/lemmy_db/Cargo.toml

@ -15,3 +15,5 @@ sha2 = "0.9"
bcrypt = "0.8.0"
url = { version = "2.1.1", features = ["serde"] }
uuid = { version = "0.6", features = ["serde", "v4"] }
lazy_static = "1.3.0"
regex = "1.3.5"

4
server/lemmy_db/src/activity.rs

@ -107,7 +107,9 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
sitemod: false,
banned: false,
updated: None,
show_nsfw: false,
@ -117,7 +119,7 @@ mod tests {
lang: "browser".into(),
show_avatars: true,
send_notifications_to_email: false,
actor_id: "http://fake.com".into(),
actor_id: "changeme_862362".into(),
bio: None,
local: true,
private_key: None,

56
server/lemmy_db/src/comment.rs

@ -97,14 +97,6 @@ impl Comment {
comment.filter(ap_id.eq(object_id)).first::<Self>(conn)
}
pub fn mark_as_read(conn: &PgConnection, comment_id: i32) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;
diesel::update(comment.find(comment_id))
.set(read.eq(true))
.get_result::<Self>(conn)
}
pub fn permadelete(conn: &PgConnection, comment_id: i32) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;
@ -116,6 +108,46 @@ impl Comment {
))
.get_result::<Self>(conn)
}
pub fn update_deleted(
conn: &PgConnection,
comment_id: i32,
new_deleted: bool,
) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;
diesel::update(comment.find(comment_id))
.set((deleted.eq(new_deleted), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
pub fn update_removed(
conn: &PgConnection,
comment_id: i32,
new_removed: bool,
) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;
diesel::update(comment.find(comment_id))
.set((removed.eq(new_removed), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
pub fn update_read(conn: &PgConnection, comment_id: i32, new_read: bool) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;
diesel::update(comment.find(comment_id))
.set(read.eq(new_read))
.get_result::<Self>(conn)
}
pub fn update_content(
conn: &PgConnection,
comment_id: i32,
new_content: &str,
) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;
diesel::update(comment.find(comment_id))
.set((content.eq(new_content), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
}
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Clone)]
@ -265,7 +297,9 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
sitemod: false,
banned: false,
updated: None,
show_nsfw: false,
@ -275,7 +309,7 @@ mod tests {
lang: "browser".into(),
show_avatars: true,
send_notifications_to_email: false,
actor_id: "http://fake.com".into(),
actor_id: "changeme_283687".into(),
bio: None,
local: true,
private_key: None,
@ -295,12 +329,14 @@ mod tests {
deleted: None,
updated: None,
nsfw: false,
actor_id: "http://fake.com".into(),
actor_id: "changeme_928738972".into(),
local: true,
private_key: None,
public_key: None,
last_refreshed_at: None,
published: None,
banner: None,
icon: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();

36
server/lemmy_db/src/comment_view.rs

@ -23,11 +23,13 @@ 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>,
creator_tags -> Nullable<Jsonb>,
@ -36,6 +38,7 @@ table! {
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -62,11 +65,13 @@ 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>,
creator_tags -> Nullable<Jsonb>,
@ -75,6 +80,7 @@ table! {
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -104,11 +110,13 @@ 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 creator_tags: Option<serde_json::Value>,
@ -117,6 +125,7 @@ pub struct CommentView {
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>,
@ -250,6 +259,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
@ -321,11 +333,13 @@ 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_tags -> Nullable<Jsonb>,
creator_community_tags -> Nullable<Jsonb>,
@ -334,6 +348,7 @@ table! {
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -364,11 +379,13 @@ 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_tags: Option<serde_json::Value>,
pub creator_community_tags: Option<serde_json::Value>,
@ -377,6 +394,7 @@ pub struct ReplyView {
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>,
@ -447,7 +465,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
@ -498,7 +516,9 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
sitemod: false,
banned: false,
updated: None,
show_nsfw: false,
@ -508,7 +528,7 @@ mod tests {
lang: "browser".into(),
show_avatars: true,
send_notifications_to_email: false,
actor_id: "http://fake.com".into(),
actor_id: "changeme_92873982".into(),
bio: None,
local: true,
private_key: None,
@ -528,12 +548,14 @@ mod tests {
deleted: None,
updated: None,
nsfw: false,
actor_id: "http://fake.com".into(),
actor_id: "changeme_7625376".into(),
local: true,
private_key: None,
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();
@ -594,6 +616,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,
@ -603,6 +626,7 @@ 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,
creator_tags: None,
@ -610,6 +634,7 @@ mod tests {
score: 1,
downvotes: 0,
hot_rank: 0,
hot_rank_active: 0,
upvotes: 1,
user_id: None,
my_vote: None,
@ -631,6 +656,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,
@ -640,6 +666,7 @@ 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,
creator_tags: None,
@ -647,6 +674,7 @@ mod tests {
score: 1,
downvotes: 0,
hot_rank: 0,
hot_rank_active: 0,
upvotes: 1,
user_id: Some(inserted_user.id),
my_vote: Some(1),
@ -665,6 +693,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)
@ -672,6 +701,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();

69
server/lemmy_db/src/community.rs

@ -1,5 +1,6 @@
use crate::{
community_settings::CommunitySettings,
naive_now,
schema::{community, community_follower, community_moderator, community_user_ban},
Bannable,
Crud,
@ -28,9 +29,10 @@ 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>,
}
// TODO add better delete, remove, lock actions here.
#[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize, Debug)]
#[table_name = "community"]
pub struct CommunityForm {
@ -49,6 +51,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 {
@ -104,6 +108,57 @@ impl Community {
pub fn get_settings(&self, conn: &PgConnection) -> Result<CommunitySettings, Error> {
CommunitySettings::read_from_community_id(&conn, self.id)
}
pub fn update_deleted(
conn: &PgConnection,
community_id: i32,
new_deleted: bool,
) -> Result<Self, Error> {
use crate::schema::community::dsl::*;
diesel::update(community.find(community_id))
.set((deleted.eq(new_deleted), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
pub fn update_removed(
conn: &PgConnection,
community_id: i32,
new_removed: bool,
) -> Result<Self, Error> {
use crate::schema::community::dsl::*;
diesel::update(community.find(community_id))
.set((removed.eq(new_removed), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
pub fn update_creator(
conn: &PgConnection,
community_id: i32,
new_creator_id: i32,
) -> Result<Self, Error> {
use crate::schema::community::dsl::*;
diesel::update(community.find(community_id))
.set((creator_id.eq(new_creator_id), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
fn community_mods_and_admins(conn: &PgConnection, community_id: i32) -> Result<Vec<i32>, Error> {
use crate::{community_view::CommunityModeratorView, user_view::UserView};
let mut mods_and_admins: Vec<i32> = Vec::new();
mods_and_admins.append(
&mut CommunityModeratorView::for_community(conn, community_id)
.map(|v| v.into_iter().map(|m| m.user_id).collect())?,
);
mods_and_admins
.append(&mut UserView::admins(conn).map(|v| v.into_iter().map(|a| a.id).collect())?);
Ok(mods_and_admins)
}
pub fn is_mod_or_admin(conn: &PgConnection, user_id: i32, community_id: i32) -> bool {
Self::community_mods_and_admins(conn, community_id)
.unwrap_or_default()
.contains(&user_id)
}
}
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
@ -253,7 +308,9 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
sitemod: false,
banned: false,
updated: None,
show_nsfw: false,
@ -263,7 +320,7 @@ mod tests {
lang: "browser".into(),
show_avatars: true,
send_notifications_to_email: false,
actor_id: "http://fake.com".into(),
actor_id: "changeme_8266238".into(),
bio: None,
local: true,