diff --git a/docker-compose.yml b/docker-compose.yml
index 935a2e48b..38d404a12 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -8,7 +8,7 @@ services:
- "./:/service"
environment:
- DATABASE_URL=postgresql://postgres@postgres:5432
- - MASTER_KEY=${MASTER_KEY:XuxGqp5NyygJrM24b5gt3YgyvFVGdQnwVDwLzLwpu3eQwY}
+ - MASTER_KEY=XuxGqp5NyygJrM24b5gt3YgyvFVGdQnwVDwLzLwpu3eQwY
- REDIS_URL=redis://redis
- DOMAIN=127.0.0.1
- SITE_NAME=Drama
diff --git a/files/__main__.py b/files/__main__.py
index 2cd233d96..899b23eaa 100644
--- a/files/__main__.py
+++ b/files/__main__.py
@@ -73,7 +73,7 @@ r=redis.Redis(host=environ.get("REDIS_URL", "redis://127.0.0.1"), decode_respon
limiter = Limiter(
app,
key_func=get_ipaddr,
- default_limits=["50/minute"],
+ default_limits=["3/second;30/minute;100/hour"],
headers_enabled=True,
strategy="fixed-window"
)
diff --git a/files/assets/css/main.css b/files/assets/css/main.css
index 3615f5e19..88b151217 100644
--- a/files/assets/css/main.css
+++ b/files/assets/css/main.css
@@ -4119,7 +4119,6 @@ th {
.modal-header {
border-bottom: none;
- background-color: var(--gray-400);
border-top-left-radius: 0.35rem;
border-top-right-radius: 0.35rem;
padding: 0.5rem 1rem;
@@ -4139,7 +4138,6 @@ th {
.modal-footer {
border: none;
- background-color: var(--gray-400);
border-bottom-right-radius: 0.35rem;
border-bottom-left-radius: 0.35rem;
}
@@ -4439,7 +4437,7 @@ th {
}
.modal .comment-actions .list-group-item:focus, .modal .comment-actions .list-group-item:hover {
- background-color: var(--gray-300);
+ background-color: var(--gray-300) !important;
}
.modal .comment-actions a {
@@ -5629,6 +5627,18 @@ blockquote p {
color: orange !important;
}
+.text-silver {
+ color: silver !important;
+}
+
+.text-gold {
+ color: gold !important;
+}
+
+.text-green {
+ color: green !important;
+}
+
.timeline-Widget {
max-height: 500px !important;
overflow-y: scroll !important;
diff --git a/files/assets/css/midnight.css b/files/assets/css/midnight.css
index e98890bea..46c4379a7 100644
--- a/files/assets/css/midnight.css
+++ b/files/assets/css/midnight.css
@@ -35,4 +35,8 @@ body, .navbar-light, .navbar-dark, .card, .modal-content, .comment-write textare
.tooltip-inner {
color: #383838 !important;
+}
+
+.modal .comment-actions .list-group-item {
+ background-color: var(--gray-600)!important;
}
\ No newline at end of file
diff --git a/files/assets/images/PCM/banner.webp b/files/assets/images/PCM/banner.webp
index fa00b5874..87ca22139 100644
Binary files a/files/assets/images/PCM/banner.webp and b/files/assets/images/PCM/banner.webp differ
diff --git a/files/assets/images/PCM/cached.webp b/files/assets/images/PCM/cached.webp
index fa00b5874..87ca22139 100644
Binary files a/files/assets/images/PCM/cached.webp and b/files/assets/images/PCM/cached.webp differ
diff --git a/files/assets/images/PCM/cover.webp b/files/assets/images/PCM/cover.webp
index 2d784b88d..5786f7748 100644
Binary files a/files/assets/images/PCM/cover.webp and b/files/assets/images/PCM/cover.webp differ
diff --git a/files/assets/images/PCM/headericon.webp b/files/assets/images/PCM/headericon.webp
index 573602e3e..5786f7748 100644
Binary files a/files/assets/images/PCM/headericon.webp and b/files/assets/images/PCM/headericon.webp differ
diff --git a/files/assets/images/PCM/icon.webp b/files/assets/images/PCM/icon.webp
index 573602e3e..5786f7748 100644
Binary files a/files/assets/images/PCM/icon.webp and b/files/assets/images/PCM/icon.webp differ
diff --git a/files/assets/images/PCM/logo.webp b/files/assets/images/PCM/logo.webp
index 90ae5f5e0..5786f7748 100644
Binary files a/files/assets/images/PCM/logo.webp and b/files/assets/images/PCM/logo.webp differ
diff --git a/files/assets/images/PCM/preview.webp b/files/assets/images/PCM/preview.webp
index fa00b5874..87ca22139 100644
Binary files a/files/assets/images/PCM/preview.webp and b/files/assets/images/PCM/preview.webp differ
diff --git a/files/assets/images/badges/alt.webp b/files/assets/images/badges/alt.webp
new file mode 100644
index 000000000..d9f1566a9
Binary files /dev/null and b/files/assets/images/badges/alt.webp differ
diff --git a/files/assets/images/badges/artist.webp b/files/assets/images/badges/artist.webp
new file mode 100644
index 000000000..8d9ff99c2
Binary files /dev/null and b/files/assets/images/badges/artist.webp differ
diff --git a/files/assets/images/badges/background.webp b/files/assets/images/badges/background.webp
new file mode 100644
index 000000000..753949e50
Binary files /dev/null and b/files/assets/images/badges/background.webp differ
diff --git a/files/assets/images/badges/eye.webp b/files/assets/images/badges/eye.webp
new file mode 100644
index 000000000..aa197ddd5
Binary files /dev/null and b/files/assets/images/badges/eye.webp differ
diff --git a/files/assets/images/badges/merchant.webp b/files/assets/images/badges/merchant.webp
new file mode 100644
index 000000000..373460b30
Binary files /dev/null and b/files/assets/images/badges/merchant.webp differ
diff --git a/files/assets/images/badges/patron.webp b/files/assets/images/badges/patron.webp
new file mode 100644
index 000000000..016d87e0a
Binary files /dev/null and b/files/assets/images/badges/patron.webp differ
diff --git a/files/assets/images/defaultpictures/100.webp b/files/assets/images/defaultpictures/100.webp
index ec70bd86e..5260df0ff 100644
Binary files a/files/assets/images/defaultpictures/100.webp and b/files/assets/images/defaultpictures/100.webp differ
diff --git a/files/assets/images/defaultpictures/101.webp b/files/assets/images/defaultpictures/101.webp
index 556ecd7f2..77245529d 100644
Binary files a/files/assets/images/defaultpictures/101.webp and b/files/assets/images/defaultpictures/101.webp differ
diff --git a/files/assets/images/defaultpictures/102.webp b/files/assets/images/defaultpictures/102.webp
index 8d71c1667..be33d8f9f 100644
Binary files a/files/assets/images/defaultpictures/102.webp and b/files/assets/images/defaultpictures/102.webp differ
diff --git a/files/assets/images/defaultpictures/103.webp b/files/assets/images/defaultpictures/103.webp
index 623ce8272..60b6ab855 100644
Binary files a/files/assets/images/defaultpictures/103.webp and b/files/assets/images/defaultpictures/103.webp differ
diff --git a/files/assets/images/defaultpictures/104.webp b/files/assets/images/defaultpictures/104.webp
index f7bbc93cf..02b5a27c3 100644
Binary files a/files/assets/images/defaultpictures/104.webp and b/files/assets/images/defaultpictures/104.webp differ
diff --git a/files/assets/images/defaultpictures/105.webp b/files/assets/images/defaultpictures/105.webp
index 69bd6636e..006cf79db 100644
Binary files a/files/assets/images/defaultpictures/105.webp and b/files/assets/images/defaultpictures/105.webp differ
diff --git a/files/assets/images/defaultpictures/106.webp b/files/assets/images/defaultpictures/106.webp
index 965512b4c..0a0968b55 100644
Binary files a/files/assets/images/defaultpictures/106.webp and b/files/assets/images/defaultpictures/106.webp differ
diff --git a/files/assets/images/defaultpictures/107.webp b/files/assets/images/defaultpictures/107.webp
index ba407ff30..843e55b13 100644
Binary files a/files/assets/images/defaultpictures/107.webp and b/files/assets/images/defaultpictures/107.webp differ
diff --git a/files/assets/images/defaultpictures/108.webp b/files/assets/images/defaultpictures/108.webp
index 9fc84eb8e..6d60ecab4 100644
Binary files a/files/assets/images/defaultpictures/108.webp and b/files/assets/images/defaultpictures/108.webp differ
diff --git a/files/assets/images/defaultpictures/109.webp b/files/assets/images/defaultpictures/109.webp
index 8b1246378..d02de58e8 100644
Binary files a/files/assets/images/defaultpictures/109.webp and b/files/assets/images/defaultpictures/109.webp differ
diff --git a/files/assets/images/defaultpictures/110.webp b/files/assets/images/defaultpictures/110.webp
index 8c68e7236..4e4c307fa 100644
Binary files a/files/assets/images/defaultpictures/110.webp and b/files/assets/images/defaultpictures/110.webp differ
diff --git a/files/assets/images/defaultpictures/111.webp b/files/assets/images/defaultpictures/111.webp
index c5926b634..b0831ddb3 100644
Binary files a/files/assets/images/defaultpictures/111.webp and b/files/assets/images/defaultpictures/111.webp differ
diff --git a/files/assets/images/defaultpictures/112.webp b/files/assets/images/defaultpictures/112.webp
index 8e9d9813a..f85a364d0 100644
Binary files a/files/assets/images/defaultpictures/112.webp and b/files/assets/images/defaultpictures/112.webp differ
diff --git a/files/assets/images/defaultpictures/113.webp b/files/assets/images/defaultpictures/113.webp
index 7ba482bd0..5b6adbc7d 100644
Binary files a/files/assets/images/defaultpictures/113.webp and b/files/assets/images/defaultpictures/113.webp differ
diff --git a/files/assets/images/defaultpictures/114.webp b/files/assets/images/defaultpictures/114.webp
index fe809584d..0ded5d53a 100644
Binary files a/files/assets/images/defaultpictures/114.webp and b/files/assets/images/defaultpictures/114.webp differ
diff --git a/files/assets/images/defaultpictures/115.webp b/files/assets/images/defaultpictures/115.webp
index 6e64d77e7..2b0410b0e 100644
Binary files a/files/assets/images/defaultpictures/115.webp and b/files/assets/images/defaultpictures/115.webp differ
diff --git a/files/assets/images/defaultpictures/116.webp b/files/assets/images/defaultpictures/116.webp
index 6a894c39d..7caea0303 100644
Binary files a/files/assets/images/defaultpictures/116.webp and b/files/assets/images/defaultpictures/116.webp differ
diff --git a/files/assets/images/defaultpictures/117.webp b/files/assets/images/defaultpictures/117.webp
index 04b5bcd11..1959d67b0 100644
Binary files a/files/assets/images/defaultpictures/117.webp and b/files/assets/images/defaultpictures/117.webp differ
diff --git a/files/assets/images/defaultpictures/118.webp b/files/assets/images/defaultpictures/118.webp
index 3e3b8b83a..a82d533da 100644
Binary files a/files/assets/images/defaultpictures/118.webp and b/files/assets/images/defaultpictures/118.webp differ
diff --git a/files/assets/images/defaultpictures/119.webp b/files/assets/images/defaultpictures/119.webp
index 6e8131c46..c1e0d0bcc 100644
Binary files a/files/assets/images/defaultpictures/119.webp and b/files/assets/images/defaultpictures/119.webp differ
diff --git a/files/assets/images/defaultpictures/120.webp b/files/assets/images/defaultpictures/120.webp
index 2187c131c..a50074a74 100644
Binary files a/files/assets/images/defaultpictures/120.webp and b/files/assets/images/defaultpictures/120.webp differ
diff --git a/files/assets/images/defaultpictures/121.webp b/files/assets/images/defaultpictures/121.webp
index 82e8d3b07..fb11b90f0 100644
Binary files a/files/assets/images/defaultpictures/121.webp and b/files/assets/images/defaultpictures/121.webp differ
diff --git a/files/assets/images/defaultpictures/122.webp b/files/assets/images/defaultpictures/122.webp
index 9ad923ed5..671faa6be 100644
Binary files a/files/assets/images/defaultpictures/122.webp and b/files/assets/images/defaultpictures/122.webp differ
diff --git a/files/assets/images/defaultpictures/123.webp b/files/assets/images/defaultpictures/123.webp
index 9bcdd24c1..e042e7837 100644
Binary files a/files/assets/images/defaultpictures/123.webp and b/files/assets/images/defaultpictures/123.webp differ
diff --git a/files/assets/images/defaultpictures/124.webp b/files/assets/images/defaultpictures/124.webp
index 4a40e7b00..da8051a3d 100644
Binary files a/files/assets/images/defaultpictures/124.webp and b/files/assets/images/defaultpictures/124.webp differ
diff --git a/files/assets/images/defaultpictures/125.webp b/files/assets/images/defaultpictures/125.webp
index 3752dcdae..fd2cda082 100644
Binary files a/files/assets/images/defaultpictures/125.webp and b/files/assets/images/defaultpictures/125.webp differ
diff --git a/files/assets/images/defaultpictures/126.webp b/files/assets/images/defaultpictures/126.webp
index aca6f6b1f..1869749bc 100644
Binary files a/files/assets/images/defaultpictures/126.webp and b/files/assets/images/defaultpictures/126.webp differ
diff --git a/files/assets/images/defaultpictures/127.webp b/files/assets/images/defaultpictures/127.webp
index 3466dc3bb..f7bf50e3c 100644
Binary files a/files/assets/images/defaultpictures/127.webp and b/files/assets/images/defaultpictures/127.webp differ
diff --git a/files/assets/images/defaultpictures/128.webp b/files/assets/images/defaultpictures/128.webp
index 1e3a2fe03..6a622cf27 100644
Binary files a/files/assets/images/defaultpictures/128.webp and b/files/assets/images/defaultpictures/128.webp differ
diff --git a/files/assets/images/defaultpictures/129.webp b/files/assets/images/defaultpictures/129.webp
index 42d737558..acf93c155 100644
Binary files a/files/assets/images/defaultpictures/129.webp and b/files/assets/images/defaultpictures/129.webp differ
diff --git a/files/assets/images/defaultpictures/130.webp b/files/assets/images/defaultpictures/130.webp
index 2bff3099d..e8855f691 100644
Binary files a/files/assets/images/defaultpictures/130.webp and b/files/assets/images/defaultpictures/130.webp differ
diff --git a/files/assets/images/defaultpictures/131.webp b/files/assets/images/defaultpictures/131.webp
index 6bcfa788d..8a3a42423 100644
Binary files a/files/assets/images/defaultpictures/131.webp and b/files/assets/images/defaultpictures/131.webp differ
diff --git a/files/assets/images/defaultpictures/132.webp b/files/assets/images/defaultpictures/132.webp
index 945c75217..03f27ae69 100644
Binary files a/files/assets/images/defaultpictures/132.webp and b/files/assets/images/defaultpictures/132.webp differ
diff --git a/files/assets/images/defaultpictures/133.webp b/files/assets/images/defaultpictures/133.webp
index b10d2fff0..fd95a221c 100644
Binary files a/files/assets/images/defaultpictures/133.webp and b/files/assets/images/defaultpictures/133.webp differ
diff --git a/files/assets/images/defaultpictures/134.webp b/files/assets/images/defaultpictures/134.webp
index a295f476a..60c1ecfe2 100644
Binary files a/files/assets/images/defaultpictures/134.webp and b/files/assets/images/defaultpictures/134.webp differ
diff --git a/files/assets/images/defaultpictures/135.webp b/files/assets/images/defaultpictures/135.webp
index 9421d8a43..2ec803381 100644
Binary files a/files/assets/images/defaultpictures/135.webp and b/files/assets/images/defaultpictures/135.webp differ
diff --git a/files/assets/images/defaultpictures/136.webp b/files/assets/images/defaultpictures/136.webp
index 53d62da2a..f485b70cd 100644
Binary files a/files/assets/images/defaultpictures/136.webp and b/files/assets/images/defaultpictures/136.webp differ
diff --git a/files/assets/images/defaultpictures/137.webp b/files/assets/images/defaultpictures/137.webp
index 856812918..e33f95fc1 100644
Binary files a/files/assets/images/defaultpictures/137.webp and b/files/assets/images/defaultpictures/137.webp differ
diff --git a/files/assets/images/defaultpictures/138.webp b/files/assets/images/defaultpictures/138.webp
index a8886335c..d1304c2c2 100644
Binary files a/files/assets/images/defaultpictures/138.webp and b/files/assets/images/defaultpictures/138.webp differ
diff --git a/files/assets/images/defaultpictures/139.webp b/files/assets/images/defaultpictures/139.webp
index b04da7154..b93f38842 100644
Binary files a/files/assets/images/defaultpictures/139.webp and b/files/assets/images/defaultpictures/139.webp differ
diff --git a/files/assets/images/defaultpictures/140.webp b/files/assets/images/defaultpictures/140.webp
index 5f7406da1..4ea4f74d0 100644
Binary files a/files/assets/images/defaultpictures/140.webp and b/files/assets/images/defaultpictures/140.webp differ
diff --git a/files/assets/images/defaultpictures/141.webp b/files/assets/images/defaultpictures/141.webp
index def4c229a..630b5e34c 100644
Binary files a/files/assets/images/defaultpictures/141.webp and b/files/assets/images/defaultpictures/141.webp differ
diff --git a/files/assets/images/defaultpictures/142.webp b/files/assets/images/defaultpictures/142.webp
index bee6907c9..8b6728e2b 100644
Binary files a/files/assets/images/defaultpictures/142.webp and b/files/assets/images/defaultpictures/142.webp differ
diff --git a/files/assets/images/defaultpictures/143.webp b/files/assets/images/defaultpictures/143.webp
index 2a82322e9..a569a8223 100644
Binary files a/files/assets/images/defaultpictures/143.webp and b/files/assets/images/defaultpictures/143.webp differ
diff --git a/files/assets/images/defaultpictures/144.webp b/files/assets/images/defaultpictures/144.webp
index 9ed477813..fcc616272 100644
Binary files a/files/assets/images/defaultpictures/144.webp and b/files/assets/images/defaultpictures/144.webp differ
diff --git a/files/assets/images/defaultpictures/145.webp b/files/assets/images/defaultpictures/145.webp
index ec501d255..6111b9155 100644
Binary files a/files/assets/images/defaultpictures/145.webp and b/files/assets/images/defaultpictures/145.webp differ
diff --git a/files/assets/images/defaultpictures/146.webp b/files/assets/images/defaultpictures/146.webp
index 43d853095..b192ecdfc 100644
Binary files a/files/assets/images/defaultpictures/146.webp and b/files/assets/images/defaultpictures/146.webp differ
diff --git a/files/assets/images/defaultpictures/147.webp b/files/assets/images/defaultpictures/147.webp
index 604d09e10..357061abb 100644
Binary files a/files/assets/images/defaultpictures/147.webp and b/files/assets/images/defaultpictures/147.webp differ
diff --git a/files/assets/images/defaultpictures/148.webp b/files/assets/images/defaultpictures/148.webp
index 57aeb2b0b..4663f0c2a 100644
Binary files a/files/assets/images/defaultpictures/148.webp and b/files/assets/images/defaultpictures/148.webp differ
diff --git a/files/assets/images/defaultpictures/149.webp b/files/assets/images/defaultpictures/149.webp
index 48d5ab696..a3246aba8 100644
Binary files a/files/assets/images/defaultpictures/149.webp and b/files/assets/images/defaultpictures/149.webp differ
diff --git a/files/assets/images/defaultpictures/150.webp b/files/assets/images/defaultpictures/150.webp
index 9ec6c0306..100731d43 100644
Binary files a/files/assets/images/defaultpictures/150.webp and b/files/assets/images/defaultpictures/150.webp differ
diff --git a/files/assets/images/defaultpictures/51.webp b/files/assets/images/defaultpictures/51.webp
index 068f38658..71b4f687f 100644
Binary files a/files/assets/images/defaultpictures/51.webp and b/files/assets/images/defaultpictures/51.webp differ
diff --git a/files/assets/images/defaultpictures/52.webp b/files/assets/images/defaultpictures/52.webp
index 8351eb533..1fecb23a6 100644
Binary files a/files/assets/images/defaultpictures/52.webp and b/files/assets/images/defaultpictures/52.webp differ
diff --git a/files/assets/images/defaultpictures/53.webp b/files/assets/images/defaultpictures/53.webp
index f1788fed0..e3b4604bf 100644
Binary files a/files/assets/images/defaultpictures/53.webp and b/files/assets/images/defaultpictures/53.webp differ
diff --git a/files/assets/images/defaultpictures/54.webp b/files/assets/images/defaultpictures/54.webp
index c867c07c7..c4aafa614 100644
Binary files a/files/assets/images/defaultpictures/54.webp and b/files/assets/images/defaultpictures/54.webp differ
diff --git a/files/assets/images/defaultpictures/55.webp b/files/assets/images/defaultpictures/55.webp
index 9769337e4..1d9effbad 100644
Binary files a/files/assets/images/defaultpictures/55.webp and b/files/assets/images/defaultpictures/55.webp differ
diff --git a/files/assets/images/defaultpictures/56.webp b/files/assets/images/defaultpictures/56.webp
index 6c1451863..07768e41a 100644
Binary files a/files/assets/images/defaultpictures/56.webp and b/files/assets/images/defaultpictures/56.webp differ
diff --git a/files/assets/images/defaultpictures/57.webp b/files/assets/images/defaultpictures/57.webp
index b4f9b40ee..687cccbcf 100644
Binary files a/files/assets/images/defaultpictures/57.webp and b/files/assets/images/defaultpictures/57.webp differ
diff --git a/files/assets/images/defaultpictures/58.webp b/files/assets/images/defaultpictures/58.webp
index fde741072..282e9bd2a 100644
Binary files a/files/assets/images/defaultpictures/58.webp and b/files/assets/images/defaultpictures/58.webp differ
diff --git a/files/assets/images/defaultpictures/59.webp b/files/assets/images/defaultpictures/59.webp
index 68af9f5b2..28c1e440a 100644
Binary files a/files/assets/images/defaultpictures/59.webp and b/files/assets/images/defaultpictures/59.webp differ
diff --git a/files/assets/images/defaultpictures/60.webp b/files/assets/images/defaultpictures/60.webp
index b6e0a57d1..6301752f8 100644
Binary files a/files/assets/images/defaultpictures/60.webp and b/files/assets/images/defaultpictures/60.webp differ
diff --git a/files/assets/images/defaultpictures/61.webp b/files/assets/images/defaultpictures/61.webp
index dd1224a28..5116da736 100644
Binary files a/files/assets/images/defaultpictures/61.webp and b/files/assets/images/defaultpictures/61.webp differ
diff --git a/files/assets/images/defaultpictures/62.webp b/files/assets/images/defaultpictures/62.webp
index 93b8cf3bf..42f8f309a 100644
Binary files a/files/assets/images/defaultpictures/62.webp and b/files/assets/images/defaultpictures/62.webp differ
diff --git a/files/assets/images/defaultpictures/63.webp b/files/assets/images/defaultpictures/63.webp
index f0e33dd4b..bad199a2f 100644
Binary files a/files/assets/images/defaultpictures/63.webp and b/files/assets/images/defaultpictures/63.webp differ
diff --git a/files/assets/images/defaultpictures/64.webp b/files/assets/images/defaultpictures/64.webp
index ead9913cf..fef87954d 100644
Binary files a/files/assets/images/defaultpictures/64.webp and b/files/assets/images/defaultpictures/64.webp differ
diff --git a/files/assets/images/defaultpictures/65.webp b/files/assets/images/defaultpictures/65.webp
index 494fa31c7..e6b97409e 100644
Binary files a/files/assets/images/defaultpictures/65.webp and b/files/assets/images/defaultpictures/65.webp differ
diff --git a/files/assets/images/defaultpictures/66.webp b/files/assets/images/defaultpictures/66.webp
index 640af64c7..25183f84a 100644
Binary files a/files/assets/images/defaultpictures/66.webp and b/files/assets/images/defaultpictures/66.webp differ
diff --git a/files/assets/images/defaultpictures/67.webp b/files/assets/images/defaultpictures/67.webp
index 5009aaab1..e70bd9bc7 100644
Binary files a/files/assets/images/defaultpictures/67.webp and b/files/assets/images/defaultpictures/67.webp differ
diff --git a/files/assets/images/defaultpictures/68.webp b/files/assets/images/defaultpictures/68.webp
index 0ea67cb6e..2505043a2 100644
Binary files a/files/assets/images/defaultpictures/68.webp and b/files/assets/images/defaultpictures/68.webp differ
diff --git a/files/assets/images/defaultpictures/69.webp b/files/assets/images/defaultpictures/69.webp
index e2c7b31e1..ad5553518 100644
Binary files a/files/assets/images/defaultpictures/69.webp and b/files/assets/images/defaultpictures/69.webp differ
diff --git a/files/assets/images/defaultpictures/70.webp b/files/assets/images/defaultpictures/70.webp
index 5feadf38d..09ccf3e90 100644
Binary files a/files/assets/images/defaultpictures/70.webp and b/files/assets/images/defaultpictures/70.webp differ
diff --git a/files/assets/images/defaultpictures/71.webp b/files/assets/images/defaultpictures/71.webp
index 18b8c6a4e..1e5c9537a 100644
Binary files a/files/assets/images/defaultpictures/71.webp and b/files/assets/images/defaultpictures/71.webp differ
diff --git a/files/assets/images/defaultpictures/72.webp b/files/assets/images/defaultpictures/72.webp
index aa4714daa..645d8a61f 100644
Binary files a/files/assets/images/defaultpictures/72.webp and b/files/assets/images/defaultpictures/72.webp differ
diff --git a/files/assets/images/defaultpictures/73.webp b/files/assets/images/defaultpictures/73.webp
index e79955890..6445ceb0a 100644
Binary files a/files/assets/images/defaultpictures/73.webp and b/files/assets/images/defaultpictures/73.webp differ
diff --git a/files/assets/images/defaultpictures/74.webp b/files/assets/images/defaultpictures/74.webp
index 238ac49c4..822000e9c 100644
Binary files a/files/assets/images/defaultpictures/74.webp and b/files/assets/images/defaultpictures/74.webp differ
diff --git a/files/assets/images/defaultpictures/75.webp b/files/assets/images/defaultpictures/75.webp
index f16654703..7065415b4 100644
Binary files a/files/assets/images/defaultpictures/75.webp and b/files/assets/images/defaultpictures/75.webp differ
diff --git a/files/assets/images/defaultpictures/76.webp b/files/assets/images/defaultpictures/76.webp
index 1c0744367..2a70b5d66 100644
Binary files a/files/assets/images/defaultpictures/76.webp and b/files/assets/images/defaultpictures/76.webp differ
diff --git a/files/assets/images/defaultpictures/77.webp b/files/assets/images/defaultpictures/77.webp
index 8b856cf58..d608aa37a 100644
Binary files a/files/assets/images/defaultpictures/77.webp and b/files/assets/images/defaultpictures/77.webp differ
diff --git a/files/assets/images/defaultpictures/78.webp b/files/assets/images/defaultpictures/78.webp
index 1fc8447c4..4c3dcaf8c 100644
Binary files a/files/assets/images/defaultpictures/78.webp and b/files/assets/images/defaultpictures/78.webp differ
diff --git a/files/assets/images/defaultpictures/79.webp b/files/assets/images/defaultpictures/79.webp
index d2ec6e792..80d2084af 100644
Binary files a/files/assets/images/defaultpictures/79.webp and b/files/assets/images/defaultpictures/79.webp differ
diff --git a/files/assets/images/defaultpictures/80.webp b/files/assets/images/defaultpictures/80.webp
index 1e8672eb2..812ea39ed 100644
Binary files a/files/assets/images/defaultpictures/80.webp and b/files/assets/images/defaultpictures/80.webp differ
diff --git a/files/assets/images/defaultpictures/81.webp b/files/assets/images/defaultpictures/81.webp
index 0a853b997..710cabe36 100644
Binary files a/files/assets/images/defaultpictures/81.webp and b/files/assets/images/defaultpictures/81.webp differ
diff --git a/files/assets/images/defaultpictures/82.webp b/files/assets/images/defaultpictures/82.webp
index 3aa49aa80..d68469a1b 100644
Binary files a/files/assets/images/defaultpictures/82.webp and b/files/assets/images/defaultpictures/82.webp differ
diff --git a/files/assets/images/defaultpictures/83.webp b/files/assets/images/defaultpictures/83.webp
index 767981388..d1115729f 100644
Binary files a/files/assets/images/defaultpictures/83.webp and b/files/assets/images/defaultpictures/83.webp differ
diff --git a/files/assets/images/defaultpictures/84.webp b/files/assets/images/defaultpictures/84.webp
index 095d5b87e..8bd2b3be0 100644
Binary files a/files/assets/images/defaultpictures/84.webp and b/files/assets/images/defaultpictures/84.webp differ
diff --git a/files/assets/images/defaultpictures/85.webp b/files/assets/images/defaultpictures/85.webp
index 287b7affd..a4a2f05c1 100644
Binary files a/files/assets/images/defaultpictures/85.webp and b/files/assets/images/defaultpictures/85.webp differ
diff --git a/files/assets/images/defaultpictures/86.webp b/files/assets/images/defaultpictures/86.webp
index facdd3b7d..54da58fd8 100644
Binary files a/files/assets/images/defaultpictures/86.webp and b/files/assets/images/defaultpictures/86.webp differ
diff --git a/files/assets/images/defaultpictures/87.webp b/files/assets/images/defaultpictures/87.webp
index 5351ce980..06062de06 100644
Binary files a/files/assets/images/defaultpictures/87.webp and b/files/assets/images/defaultpictures/87.webp differ
diff --git a/files/assets/images/defaultpictures/88.webp b/files/assets/images/defaultpictures/88.webp
index a4d1ccaa6..ebcef65ce 100644
Binary files a/files/assets/images/defaultpictures/88.webp and b/files/assets/images/defaultpictures/88.webp differ
diff --git a/files/assets/images/defaultpictures/89.webp b/files/assets/images/defaultpictures/89.webp
index abd01989d..bfcb1d62b 100644
Binary files a/files/assets/images/defaultpictures/89.webp and b/files/assets/images/defaultpictures/89.webp differ
diff --git a/files/assets/images/defaultpictures/90.webp b/files/assets/images/defaultpictures/90.webp
index 257a5f3d7..9d2d0cc3f 100644
Binary files a/files/assets/images/defaultpictures/90.webp and b/files/assets/images/defaultpictures/90.webp differ
diff --git a/files/assets/images/defaultpictures/91.webp b/files/assets/images/defaultpictures/91.webp
index 9205c65e1..c7068601b 100644
Binary files a/files/assets/images/defaultpictures/91.webp and b/files/assets/images/defaultpictures/91.webp differ
diff --git a/files/assets/images/defaultpictures/92.webp b/files/assets/images/defaultpictures/92.webp
index 68ec12fb6..e190778fd 100644
Binary files a/files/assets/images/defaultpictures/92.webp and b/files/assets/images/defaultpictures/92.webp differ
diff --git a/files/assets/images/defaultpictures/93.webp b/files/assets/images/defaultpictures/93.webp
index 1079c9116..4a0e1f7a0 100644
Binary files a/files/assets/images/defaultpictures/93.webp and b/files/assets/images/defaultpictures/93.webp differ
diff --git a/files/assets/images/defaultpictures/94.webp b/files/assets/images/defaultpictures/94.webp
index fd7b87a4b..743f92008 100644
Binary files a/files/assets/images/defaultpictures/94.webp and b/files/assets/images/defaultpictures/94.webp differ
diff --git a/files/assets/images/defaultpictures/95.webp b/files/assets/images/defaultpictures/95.webp
index 29df94969..fd1312bee 100644
Binary files a/files/assets/images/defaultpictures/95.webp and b/files/assets/images/defaultpictures/95.webp differ
diff --git a/files/assets/images/defaultpictures/96.webp b/files/assets/images/defaultpictures/96.webp
index 352414774..9ace7a390 100644
Binary files a/files/assets/images/defaultpictures/96.webp and b/files/assets/images/defaultpictures/96.webp differ
diff --git a/files/assets/images/defaultpictures/97.webp b/files/assets/images/defaultpictures/97.webp
index a7202a57e..980c55db9 100644
Binary files a/files/assets/images/defaultpictures/97.webp and b/files/assets/images/defaultpictures/97.webp differ
diff --git a/files/assets/images/defaultpictures/98.webp b/files/assets/images/defaultpictures/98.webp
index 32328e584..9e6824541 100644
Binary files a/files/assets/images/defaultpictures/98.webp and b/files/assets/images/defaultpictures/98.webp differ
diff --git a/files/assets/images/defaultpictures/99.webp b/files/assets/images/defaultpictures/99.webp
index 3b6f6f121..77d01e699 100644
Binary files a/files/assets/images/defaultpictures/99.webp and b/files/assets/images/defaultpictures/99.webp differ
diff --git a/files/assets/images/emojis/kazakhstan.webp b/files/assets/images/emojis/kazakhstan.webp
index 76ba38dc3..23423ad03 100644
Binary files a/files/assets/images/emojis/kazakhstan.webp and b/files/assets/images/emojis/kazakhstan.webp differ
diff --git a/files/assets/images/emojis/marseyfuckoffcarp.webp b/files/assets/images/emojis/marseyfuckoffcarp.webp
new file mode 100644
index 000000000..5299b0a43
Binary files /dev/null and b/files/assets/images/emojis/marseyfuckoffcarp.webp differ
diff --git a/files/assets/images/emojis/taylove.webp b/files/assets/images/emojis/taylove.webp
new file mode 100644
index 000000000..fd6dac889
Binary files /dev/null and b/files/assets/images/emojis/taylove.webp differ
diff --git a/files/assets/js/comments_v.js b/files/assets/js/comments_v.js
index 5bf0748c2..cac8a3217 100644
--- a/files/assets/js/comments_v.js
+++ b/files/assets/js/comments_v.js
@@ -141,6 +141,8 @@ post_reply=function(id){
myToast.hide();
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
+ try {document.getElementById('toast-post-error-text').innerText = JSON.parse(xhr.response)["error"];}
+ catch {}
}
}
xhr.send(form)
@@ -168,6 +170,8 @@ comment_edit=function(id){
myToast.hide();
var myToast = new bootstrap.Toast(document.getElementById('toast-post-error'));
myToast.show();
+ try {document.getElementById('toast-post-error-text').innerText = JSON.parse(xhr.response)["error"];}
+ catch {}
}
}
xhr.send(form)
diff --git a/files/assets/js/emoji_modal.js b/files/assets/js/emoji_modal.js
index 442a952f6..2251d798a 100644
--- a/files/assets/js/emoji_modal.js
+++ b/files/assets/js/emoji_modal.js
@@ -12,7 +12,7 @@ const EMOJIS_STRINGS = [
type:'marsey',
emojis: ['marseylaugh','marseyblowkiss','marseyshook','marseythumbsup','marseylove','marseyreading','marseywave','marseyjamming','marseyready','marseyscarf','marseymad','marseycry','marseyinabox','marseysad','marseyexcited','marseysleep','marseyangel','marseydead','marseyparty','marseyrain','marseyagree','marseydisagree','marseyjam','marseygasp','marseytwerking','marseysipping','marseyshrug','marseyglow','marseycope','marseyseethe','marseymerchant','marseyno','marseywalking','marseyhearts','marseybegging','marseytrans2','marseygigaretard','marseysneed','marseybaited','marseyeyeroll','marseydepressed','marseypat','marseyking','marseylong1','marseylong2','marseylong3',
- 'marseyairquotes','marseybyeceps','marseycarpcrying','marseycatgirljanny','marseydisabled','marseyegg_irl','marseyfrog','marseyhope','marseymao','marseymoose','marseypunisher','marseytoilet','thinbluefeline','marseycatgirl2','marseycatgirl3','marseycapywalking','marseyatsume','marseybeggar','marseyceiling','marseyclapping','marseydab','marseydealwithit','marseyduck','marseyduck2','marseyflareon','marseyflareonpat','marseyfox','marseyfreezepeach','marseyfrozen','marseyglaceon','marseyglaceonpat','marseygroomer2','marseyhacker2','marseyhillary','marseyinvisible','marseyjolteon','marseyjolteonpat','marseyleafeon','marseyleafeonpat','marseynoyou','marseypedobear','marseyplanecrash','marseypleading','marseypoor','marseyschrodinger','marseysulk','marseytheorist','marseyvaporeon','marseyvaporeonpat','marseywheredrama2','marseyspecialpat','marseyautism','marseybaphomet','marseybear','marseybrap','marseybrianna','marseybrianna2','marseyemo','marseyespeon','marseyespeonheadpat','marseyglow2','marseyhannibal','marseyhypno','marseykingcrown','marseyliondanc','marseyllama','marseyllama1','marseyllama2','marseyllama3','marseyniggawut','marseyorthodoxpat','marseypirate2','marseypumpkinglow','marseyrussiadolls','marseysnappypat','marseysylveon','marseysylveonpat','marseytime','marseytrickortreat','marseytrollolol','marseytwins','marseyumbreon','marseyumbreonpat','mersyapat','marchipmunklove','marseyban','marseycheerup','marseyfry','marseygroomer','marseymalding','marseyplush','marseysalutenavy','marseytunaktunak','marseyza','marsheep','marchipmunk','marseybased','marseydawnbreaker','marseyfurry','marseyhorseshoe','marseypop2','marseysheepdog','marseywallst','marsheen','marseyantiwork','marseycarppat','marseydrama','marseygiveup','marseykitty','marseymini','marseyteruteru','marseyyass','marsheepnpc','fuckoffcarp','marseyneet','marseyxoxo','marseychungus','marseypopcorntime','mersya2','marseycontemplate','marseysob','mersya','marseyderp','marseytinfoil2','marseylovedrama','marseytv','marseyloveyou','marseywheredrama','firecat','marseyannoyed','marseybye','marseycapypat','marseycheeky','marseydicklet','marseydisgust','marseydracula','marseydrone','marseygossip','marseykween','marseymugshot','marseymutt','marseyneon','marseynerd','marseyoceania','marseyohno','marseyramen','marseyrave','marseysadge','marseysalutearmy','marseysalutecop','marseyshy','marseysonofman','marseytroll2','marseyvibing','marseywendy','marseyhungry','marseyaoc','marseybrave','marseycoin','marseycopeseethedilate','marseyeldritch','marseyjiangshi','marseymayo','marseynintendo','marseyracist','marseysrdine2','marseywtf2','marseylongpost','marseylongpost2','marseyminimalism','marseyminimalism2','marseymonk','marseypharaoh','marseypharaoh2','marseything','marseydarwin','marseygodel','marseyjudge','marseykiwipat','marseynyan','marseypaint','marseyplaty','marseypostmodern','marseyprisma','marseyrussel','marseystinky','marseywagie','karlmarxey','marsey300','marsey666','marsey666black','marseycapitalistmanlet','marseychad','marseychucky','marseyclown3','marseycolossal','marseydream','marseyhappening','marseyhellraiser','marseyit','marseyjason','marseyjesus','marseyjourno','marseykiwi','marseykiwi2','marseyliondance','marseymati','marseyneat','marseynightmare','marseynosleep','marseypepe2','marseypumpking','marseysaint','marseysaw','marseysharingan','marseyshark','marseysigh','marseysmug3','marseytrad','marcerberus','marscientist','marseyamazon','marseybug2','marseycapy','marseyclown2','marseycrying','marseydio','marseydragon','marseyfans','marseyfine','marseygrilling2','marseyhead','marseyjeans','marseymancer','marseymexican','marseypikachu','marseypikachu2','marseysmug2','marseyspit','marseysweating','marseywoah','marseywolf','marseyyes','marseyzombie','mcmarsey','owlsey','marfield','marlion','marppy','marseyargentina','marseyascii2','marseyayy','marseybaby','marseybackstab','marseybigbrain','marseybiker','marseyblackface','marseybug','marseycarp2','marseycarp3','marseycreepy','marseydetective','marseyfellowkids','marseygandalf','marseygigachad','marseyhandsup','marseyhungry','marseyjapanese','marseykink','marseylowpoly','marseyminion','marseymodelo2','marseymorph','marseyonacid','marseypearlclutch','marseypearlclutch2','marseypenguin','marseypride','marseypunching','marseyseven','marseysexylibrarian','marseyshapiro','marseyshiftyeyes','marseyshooting','marseysjw','marseysmoothbrain','marseysniff','marseyspecial','marseysuper','marseythinkorino','marseythroatsinging','marseywarhol','marseyweeb','marseywinner','marseywtf','mlm','plarsy','marseyalice','marseyalien','marseyascii','marseybait','marseyballerina','marseyblueanime','marseybluehands','marseybowl','marseybruh','marseybuff','marseycountryclub','marseycool2','marseycrusader','marseycut','marseydaemon','marseydeuxfoid','marseydevil','marseyditzy','marseydoubt','marseyunpettable','marseyfeynman','marseyfocault','marseyfrozenpat','marseygarfield','marseygivecrown','marseygodzilla','marseygunned','marseyheathcliff','marseyheavymetal','marseyhoodwink','marseyjoint','marseymissing','marseymodelo','marseymonke','marseynooo','marseynpc2','marseyoctopus','marseypepe','marseypimp','marseypixel','marseypretty','marseypumpkin','marseypumpkin2','marseypumpkin3','marseypumpkin4','marseypumpkincloak','marseyquadmagyar','marseyrpgcharacter','marseysartre','marseyscared','marseyskater','marseyskeleton','marseyskeleton2','marseysmudge','marseysombrero','marseyspider2','marseyspirit','marseyspooky','marseyspookysmile','marseystars','marseystonetoss','marseythegrey','marseyvaporwave','marseywise','marseywitch','marseywords','marseywords2','marseywut','marseyyikes','marseywhirlyhat','marsey173','marseycthulhu','marseycuck','marseyemperor','marseyface','marseyjohnson','marseykneel','marseymummy','marseymummy2','marseypanda','marseypumpkin','marseyskeletor','marseystein','marseyvampire','marseyvengeance','marseywitch3','marseypop','marseyqueenlizard','marseybane','marseybog','marseybux','marseycommitted','marseydizzy','marseyfunko','marseyhealthy','marseykaiser','marseykyle','marseymask','marseymeds','marseykvlt','marseyn8','marseynietzsche','marseyobey','marseypatriot','marseypedo','marseypony','marseypuke','marseyqueen','marseyrage','marseysnek','marseytinfoil','marseywitch2','marseycenter','marseyauthleft','marseyauthright','marseylibleft','marseylibright','marseybinladen','marseycool','marseyjanny2','marseyjones','marseynapoleon','marseysanders','marseysnoo','marseysoypoint','marseybiting','marseyblush','marseybountyhunter','marseycoonass','marseyfinger','marseyglancing','marseyhappy','marseyluther','marseypizzashill','marseypokerface','marseypopcorn','marseyrasta','marseysad2','marseysmirk','marseysurprised','marseythomas','marseywitch','marseyyawn','marcusfootball','marje','marmsey','marsey1984','marsey420','marsey4chan','marsey69','marseyakshually','marseyandmarcus','marseyasian','marseybattered','marseybiden','marseybingus','marseyblm','marseybluecheck','marseybong','marseybooba','marseyboomer','marseybrainlet','marseybride','marseyburger','marseybush','marseycamus','marseycanned','marseycarp','marseycatgirl','marseychef','marseychonker','marseyclown','marseycomrade','marseyconfused','marseycoomer','marseycop','marseycorn','marseycowboy','marseycumjar1','marseycumjar2','marseycumjar3','marseycwc','marseydespair','marseydeux','marseydildo','marseydoomer','marseydrunk','marseydynamite','marseyfacepalm','marseyfamily','marseyfbi','marseyfeet','marseyfeminist','marseyflamethrower','marseyflamewar','marseyfloyd','marseyfug','marseyghost','marseygift','marseygigavaxxer','marseyglam','marseygodfather','marseygoodnight','marseygrass','marseygrilling','marseyhacker','marseyhmm','marseyhmmm','marseyilluminati','marseyira','marseyisis','marseyjanny','marseyjunkie','marseykkk','marseylawlz','marseylifting','marseylizard','marseylolcow','marseymanlet','marseymaoist','marseymcarthur','marseymermaid','marseymouse','marseymyeisha','marseyneckbeard','marseyniqab','marseynpc','marseynun','marseynut','marseyorthodox','marseyowow','marseypainter','marseypanties','marseypeacekeeper','marseypickle','marseypinochet','marseypipe','marseypirate','marseypoggers','marseypope','marseyproctologist','marseypsycho','marseyqoomer','marseyradioactive','marseyrat','marseyreich','marseyrentfree','marseyretard','marseyrick','marseyrope','marseyrowling','marseysadcat','marseysick','marseyschizo','marseyshisha','marseysmug','marseysociety','marseyspider','marseysrdine','marseystroke','marseysus','marseytaliban','marseytank','marseytankushanka','marseytea','marseythonk','marseytrain','marseytrans','marseytroll','marseytrump','marseyunabomber','marseyuwuw','marseyvan','marseyvaxmaxx','marseyworried','marseyxd','marseyyeezus','marseyzoomer','marseyzwei','marsoy','marsoyhype']
+ 'marseyairquotes','marseybyeceps','marseycarpcrying','marseycatgirljanny','marseydisabled','marseyegg_irl','marseyfrog','marseyhope','marseymao','marseymoose','marseypunisher','marseytoilet','thinbluefeline','marseycatgirl2','marseycatgirl3','marseycapywalking','marseyatsume','marseybeggar','marseyceiling','marseyclapping','marseydab','marseydealwithit','marseyduck','marseyduck2','marseyflareon','marseyflareonpat','marseyfox','marseyfreezepeach','marseyfrozen','marseyglaceon','marseyglaceonpat','marseygroomer2','marseyhacker2','marseyhillary','marseyinvisible','marseyjolteon','marseyjolteonpat','marseyleafeon','marseyleafeonpat','marseynoyou','marseypedobear','marseyplanecrash','marseypleading','marseypoor','marseyschrodinger','marseysulk','marseytheorist','marseyvaporeon','marseyvaporeonpat','marseywheredrama2','marseyspecialpat','marseyautism','marseybaphomet','marseybear','marseybrap','marseybrianna','marseybrianna2','marseyemo','marseyespeon','marseyespeonheadpat','marseyglow2','marseyhannibal','marseyhypno','marseykingcrown','marseyliondanc','marseyllama','marseyllama1','marseyllama2','marseyllama3','marseyniggawut','marseyorthodoxpat','marseypirate2','marseypumpkinglow','marseyrussiadolls','marseysnappypat','marseysylveon','marseysylveonpat','marseytime','marseytrickortreat','marseytrollolol','marseytwins','marseyumbreon','marseyumbreonpat','mersyapat','marchipmunklove','marseyban','marseycheerup','marseyfry','marseygroomer','marseymalding','marseyplush','marseysalutenavy','marseytunaktunak','marseyza','marsheep','marchipmunk','marseybased','marseydawnbreaker','marseyfurry','marseyhorseshoe','marseypop2','marseysheepdog','marseywallst','marsheen','marseyantiwork','marseycarppat','marseydrama','marseygiveup','marseykitty','marseymini','marseyteruteru','marseyyass','marsheepnpc','marseyfuckoffcarp','marseyneet','marseyxoxo','marseychungus','marseypopcorntime','mersya2','marseycontemplate','marseysob','mersya','marseyderp','marseytinfoil2','marseylovedrama','marseytv','marseyloveyou','marseywheredrama','firecat','marseyannoyed','marseybye','marseycapypat','marseycheeky','marseydicklet','marseydisgust','marseydracula','marseydrone','marseygossip','marseykween','marseymugshot','marseymutt','marseyneon','marseynerd','marseyoceania','marseyohno','marseyramen','marseyrave','marseysadge','marseysalutearmy','marseysalutecop','marseyshy','marseysonofman','marseytroll2','marseyvibing','marseywendy','marseyhungry','marseyaoc','marseybrave','marseycoin','marseycopeseethedilate','marseyeldritch','marseyjiangshi','marseymayo','marseynintendo','marseyracist','marseysrdine2','marseywtf2','marseylongpost','marseylongpost2','marseyminimalism','marseyminimalism2','marseymonk','marseypharaoh','marseypharaoh2','marseything','marseydarwin','marseygodel','marseyjudge','marseykiwipat','marseynyan','marseypaint','marseyplaty','marseypostmodern','marseyprisma','marseyrussel','marseystinky','marseywagie','karlmarxey','marsey300','marsey666','marsey666black','marseycapitalistmanlet','marseychad','marseychucky','marseyclown3','marseycolossal','marseydream','marseyhappening','marseyhellraiser','marseyit','marseyjason','marseyjesus','marseyjourno','marseykiwi','marseykiwi2','marseyliondance','marseymati','marseyneat','marseynightmare','marseynosleep','marseypepe2','marseypumpking','marseysaint','marseysaw','marseysharingan','marseyshark','marseysigh','marseysmug3','marseytrad','marcerberus','marscientist','marseyamazon','marseybug2','marseycapy','marseyclown2','marseycrying','marseydio','marseydragon','marseyfans','marseyfine','marseygrilling2','marseyhead','marseyjeans','marseymancer','marseymexican','marseypikachu','marseypikachu2','marseysmug2','marseyspit','marseysweating','marseywoah','marseywolf','marseyyes','marseyzombie','mcmarsey','owlsey','marfield','marlion','marppy','marseyargentina','marseyascii2','marseyayy','marseybaby','marseybackstab','marseybigbrain','marseybiker','marseyblackface','marseybug','marseycarp2','marseycarp3','marseycreepy','marseydetective','marseyfellowkids','marseygandalf','marseygigachad','marseyhandsup','marseyjapanese','marseykink','marseylowpoly','marseyminion','marseymodelo2','marseymorph','marseyonacid','marseypearlclutch','marseypearlclutch2','marseypenguin','marseypride','marseypunching','marseyseven','marseysexylibrarian','marseyshapiro','marseyshiftyeyes','marseyshooting','marseysjw','marseysmoothbrain','marseysniff','marseyspecial','marseysuper','marseythinkorino','marseythroatsinging','marseywarhol','marseyweeb','marseywinner','marseywtf','mlm','plarsy','marseyalice','marseyalien','marseyascii','marseybait','marseyballerina','marseyblueanime','marseybluehands','marseybowl','marseybruh','marseybuff','marseycountryclub','marseycool2','marseycrusader','marseycut','marseydaemon','marseydeuxfoid','marseydevil','marseyditzy','marseydoubt','marseyunpettable','marseyfeynman','marseyfocault','marseyfrozenpat','marseygarfield','marseygivecrown','marseygodzilla','marseygunned','marseyheathcliff','marseyheavymetal','marseyhoodwink','marseyjoint','marseymissing','marseymodelo','marseymonke','marseynooo','marseynpc2','marseyoctopus','marseypepe','marseypimp','marseypixel','marseypretty','marseypumpkin','marseypumpkin2','marseypumpkin3','marseypumpkin4','marseypumpkincloak','marseyquadmagyar','marseyrpgcharacter','marseysartre','marseyscared','marseyskater','marseyskeleton','marseyskeleton2','marseysmudge','marseysombrero','marseyspider2','marseyspirit','marseyspooky','marseyspookysmile','marseystars','marseystonetoss','marseythegrey','marseyvaporwave','marseywise','marseywitch','marseywords','marseywords2','marseywut','marseyyikes','marseywhirlyhat','marsey173','marseycthulhu','marseycuck','marseyemperor','marseyface','marseyjohnson','marseykneel','marseymummy','marseymummy2','marseypanda','marseypumpkin','marseyskeletor','marseystein','marseyvampire','marseyvengeance','marseywitch3','marseypop','marseyqueenlizard','marseybane','marseybog','marseybux','marseycommitted','marseydizzy','marseyfunko','marseyhealthy','marseykaiser','marseykyle','marseymask','marseymeds','marseykvlt','marseyn8','marseynietzsche','marseyobey','marseypatriot','marseypedo','marseypony','marseypuke','marseyqueen','marseyrage','marseysnek','marseytinfoil','marseywitch2','marseycenter','marseyauthleft','marseyauthright','marseylibleft','marseylibright','marseybinladen','marseycool','marseyjanny2','marseyjones','marseynapoleon','marseysanders','marseysnoo','marseysoypoint','marseybiting','marseyblush','marseybountyhunter','marseycoonass','marseyfinger','marseyglancing','marseyhappy','marseyluther','marseypizzashill','marseypokerface','marseypopcorn','marseyrasta','marseysad2','marseysmirk','marseysurprised','marseythomas','marseywitch','marseyyawn','marcusfootball','marje','marmsey','marsey1984','marsey420','marsey4chan','marsey69','marseyakshually','marseyandmarcus','marseyasian','marseybattered','marseybiden','marseybingus','marseyblm','marseybluecheck','marseybong','marseybooba','marseyboomer','marseybrainlet','marseybride','marseyburger','marseybush','marseycamus','marseycanned','marseycarp','marseycatgirl','marseychef','marseychonker','marseyclown','marseycomrade','marseyconfused','marseycoomer','marseycop','marseycorn','marseycowboy','marseycumjar1','marseycumjar2','marseycumjar3','marseycwc','marseydespair','marseydeux','marseydildo','marseydoomer','marseydrunk','marseydynamite','marseyfacepalm','marseyfamily','marseyfbi','marseyfeet','marseyfeminist','marseyflamethrower','marseyflamewar','marseyfloyd','marseyfug','marseyghost','marseygift','marseygigavaxxer','marseyglam','marseygodfather','marseygoodnight','marseygrass','marseygrilling','marseyhacker','marseyhmm','marseyhmmm','marseyilluminati','marseyira','marseyisis','marseyjanny','marseyjunkie','marseykkk','marseylawlz','marseylifting','marseylizard','marseylolcow','marseymanlet','marseymaoist','marseymcarthur','marseymermaid','marseymouse','marseymyeisha','marseyneckbeard','marseyniqab','marseynpc','marseynun','marseynut','marseyorthodox','marseyowow','marseypainter','marseypanties','marseypeacekeeper','marseypickle','marseypinochet','marseypipe','marseypirate','marseypoggers','marseypope','marseyproctologist','marseypsycho','marseyqoomer','marseyradioactive','marseyrat','marseyreich','marseyrentfree','marseyretard','marseyrick','marseyrope','marseyrowling','marseysadcat','marseysick','marseyschizo','marseyshisha','marseysmug','marseysociety','marseyspider','marseysrdine','marseystroke','marseysus','marseytaliban','marseytank','marseytankushanka','marseytea','marseythonk','marseytrain','marseytrans','marseytroll','marseytrump','marseyunabomber','marseyuwuw','marseyvan','marseyvaxmaxx','marseyworried','marseyxd','marseyyeezus','marseyzoomer','marseyzwei','marsoy','marsoyhype']
},
{
type:'platy',
@@ -20,7 +20,7 @@ const EMOJIS_STRINGS = [
},
{
type: 'tay',
- emojis: ['tayaaa', 'tayadmire', 'taycat', 'taycelebrate', 'taychefkiss', 'taychristmas', 'tayclap', 'taycold', 'taycrown', 'tayflex', 'tayflirt', 'taygrimacing', 'tayhappy', 'tayheart', 'tayhmm', 'tayhuh', 'tayhyperdab', 'tayjammin', 'taylaugh', 'taymindblown', 'tayno', 'taynod', 'taypeace', 'taypray', 'tayrun', 'tayscrunch', 'tayshake', 'tayshrug', 'taysilly', 'tayslide', 'taysmart', 'taystop', 'taytantrum', 'taytea', 'taythink', 'tayvibin', 'taywhat', 'taywine', 'taywine2', 'taywink', 'tayyes']
+ emojis: ['taylove','tayaaa', 'tayadmire', 'taycat', 'taycelebrate', 'taychefkiss', 'taychristmas', 'tayclap', 'taycold', 'taycrown', 'tayflex', 'tayflirt', 'taygrimacing', 'tayhappy', 'tayheart', 'tayhmm', 'tayhuh', 'tayhyperdab', 'tayjammin', 'taylaugh', 'taymindblown', 'tayno', 'taynod', 'taypeace', 'taypray', 'tayrun', 'tayscrunch', 'tayshake', 'tayshrug', 'taysilly', 'tayslide', 'taysmart', 'taystop', 'taytantrum', 'taytea', 'taythink', 'tayvibin', 'taywhat', 'taywine', 'taywine2', 'taywink', 'tayyes']
},
{
type: 'classic',
diff --git a/files/assets/js/userpage.js b/files/assets/js/userpage.js
index a7a673efe..2cc7d44e2 100644
--- a/files/assets/js/userpage.js
+++ b/files/assets/js/userpage.js
@@ -56,17 +56,6 @@ function post_toast_callback(url, data, callback) {
}
-const TRANSFER_TAX = 0.015;
-
-function updateTax(mobile=false) {
- let suf = mobile ? "-mobile" : "";
- let amount = parseInt(document.getElementById("coins-transfer-amount" + suf).value);
- if(isNaN(amount) || amount < 0) {
- amount = 0;
- }
- document.getElementById("coins-transfer-taxed" + suf).innerText = amount - Math.ceil(amount*TRANSFER_TAX);
-}
-
function toggleElement(group, id) {
for(let el of document.getElementsByClassName(group)) {
if(el.id != id) {
diff --git a/files/classes/comment.py b/files/classes/comment.py
index bc8a1bb6f..d0bdf5bfb 100644
--- a/files/classes/comment.py
+++ b/files/classes/comment.py
@@ -7,12 +7,14 @@ from sqlalchemy import *
from sqlalchemy.orm import relationship
from files.__main__ import Base
from files.classes.votes import CommentVote
-from files.helpers.const import AUTOPOLLER_ACCOUNT, censor_slurs
+from files.helpers.const import AUTOPOLLER_ID, censor_slurs
from files.helpers.lazy import lazy
from .flags import CommentFlag
from random import randint
site = environ.get("DOMAIN").strip()
+if site == 'pcmemes.net': cc = "splash mountain"
+else: cc = "country club"
class Comment(Base):
@@ -78,7 +80,7 @@ class Comment(Base):
@property
@lazy
def options(self):
- return [x for x in self.child_comments if x.author_id == AUTOPOLLER_ACCOUNT]
+ return [x for x in self.child_comments if x.author_id == AUTOPOLLER_ID]
def total_poll_voted(self, v):
if v:
@@ -183,7 +185,7 @@ class Comment(Base):
def replies(self):
r = self.__dict__.get("replies", None)
if r: r = [x for x in r if not x.author.shadowbanned]
- if not r and r != []: r = sorted([x for x in self.child_comments if not x.author.shadowbanned and x.author_id != AUTOPOLLER_ACCOUNT], key=lambda x: x.score, reverse=True)
+ if not r and r != []: r = sorted([x for x in self.child_comments if not x.author.shadowbanned and x.author_id != AUTOPOLLER_ID], key=lambda x: x.score, reverse=True)
return r
@replies.setter
@@ -201,21 +203,21 @@ class Comment(Base):
@property
def replies3(self):
r = self.__dict__.get("replies", None)
- if not r and r != []: r = sorted([x for x in self.child_comments if x.author_id != AUTOPOLLER_ACCOUNT], key=lambda x: x.score, reverse=True)
+ if not r and r != []: r = sorted([x for x in self.child_comments if x.author_id != AUTOPOLLER_ID], key=lambda x: x.score, reverse=True)
return r
@property
@lazy
def shortlink(self):
- return f"http://{site}/comment/{self.id}"
+ return f"http://{site}/comment/{self.id}#context"
@property
@lazy
def permalink(self):
- if self.post and self.post.club: return f"/comment/{self.id}/"
+ if self.post and self.post.club: return f"/comment/{self.id}?context=9#context"
- if self.post: return f"{self.post.permalink}/{self.id}/"
- else: return f"/comment/{self.id}/"
+ if self.post: return f"{self.post.permalink}/{self.id}?context=9#context"
+ else: return f"/comment/{self.id}?context=9#context"
@property
@lazy
@@ -302,7 +304,7 @@ class Comment(Base):
return data
def realbody(self, v):
- if self.post and self.post.club and not (v and v.paid_dues): return "
COUNTRY CLUB ONLY
"
+ if self.post and self.post.club and not (v and v.paid_dues): return f"
{cc} ONLY
"
body = self.body_html
@@ -335,7 +337,7 @@ class Comment(Base):
return body
def plainbody(self, v):
- if self.post and self.post.club and not (v and v.paid_dues): return "
COUNTRY CLUB ONLY
"
+ if self.post and self.post.club and not (v and v.paid_dues): return f"
{cc} ONLY
"
body = self.body
diff --git a/files/classes/mod_logs.py b/files/classes/mod_logs.py
index aa9f8af12..427faeb7c 100644
--- a/files/classes/mod_logs.py
+++ b/files/classes/mod_logs.py
@@ -3,6 +3,11 @@ from sqlalchemy.orm import relationship
from files.__main__ import Base
import time
from files.helpers.lazy import lazy
+from os import environ
+
+site = environ.get("DOMAIN").strip()
+if site == 'pcmemes.net': cc = "splash mountain"
+else: cc = "country club"
class ModAction(Base):
__tablename__ = "modactions"
@@ -77,7 +82,7 @@ class ModAction(Base):
@lazy
def string(self):
- output = ACTIONTYPES[self.kind]["str"].format(self=self)
+ output = ACTIONTYPES[self.kind]["str"].format(self=self, cc=cc)
if self.note: output += f" ({self.note})"
@@ -160,12 +165,12 @@ ACTIONTYPES={
"color": "bg-muted",
},
"club_allow":{
- "str":'allowed user {self.target_link} into the country club',
+ "str":'allowed user {self.target_link} into the {cc}',
"icon":"fa-user-slash",
"color": "bg-danger",
},
"club_ban":{
- "str":'disallowed user {self.target_link} from the country club',
+ "str":'disallowed user {self.target_link} from the {cc}',
"icon": "fa-user-slash",
"color": "bg-muted",
},
diff --git a/files/classes/submission.py b/files/classes/submission.py
index 3ae1d7a6c..9a9dc5a44 100644
--- a/files/classes/submission.py
+++ b/files/classes/submission.py
@@ -7,7 +7,7 @@ from flask import render_template
from sqlalchemy import *
from sqlalchemy.orm import relationship
from files.__main__ import Base
-from files.helpers.const import AUTOPOLLER_ACCOUNT, censor_slurs, TROLLTITLES
+from files.helpers.const import AUTOPOLLER_ID, censor_slurs, TROLLTITLES
from files.helpers.lazy import lazy
from .flags import Flag
from .comment import Comment
@@ -15,6 +15,8 @@ from flask import g
site = environ.get("DOMAIN").strip()
site_name = environ.get("SITE_NAME").strip()
+if site == 'pcmemes.net': cc = "SPLASH MOUNTAIN"
+else: cc = "COUNTRY CLUB"
class Submission(Base):
__tablename__ = "submissions"
@@ -78,7 +80,7 @@ class Submission(Base):
@property
@lazy
def options(self):
- return g.db.query(Comment).filter_by(parent_submission = self.id, author_id = AUTOPOLLER_ACCOUNT, level=1)
+ return g.db.query(Comment).filter_by(parent_submission = self.id, author_id = AUTOPOLLER_ID, level=1)
def total_poll_voted(self, v):
if v:
@@ -317,7 +319,7 @@ class Submission(Base):
else: return ""
def realbody(self, v):
- if self.club and not (v and v.paid_dues): return "
COUNTRY CLUB ONLY
"
+ if self.club and not (v and v.paid_dues): return f"
{cc} ONLY
"
body = self.body_html
body = censor_slurs(body, v)
@@ -335,7 +337,7 @@ class Submission(Base):
return body
def plainbody(self, v):
- if self.club and not (v and v.paid_dues): return "
COUNTRY CLUB ONLY
"
+ if self.club and not (v and v.paid_dues): return f"
{cc} ONLY
"
body = self.body
body = censor_slurs(body, v)
@@ -346,9 +348,9 @@ class Submission(Base):
@lazy
def realtitle(self, v):
- if self.club and not (v and v.paid_dues) and not (v and v.admin_level == 6):
+ if self.club and not (v and v.paid_dues) and not (v and v.admin_level > 1):
if v: return random.choice(TROLLTITLES).format(username=v.username)
- else: return 'COUNTRY CLUB MEMBERS ONLY'
+ else: return f'{cc} MEMBERS ONLY'
elif self.title_html: title = self.title_html
else: title = self.title
@@ -358,9 +360,9 @@ class Submission(Base):
@lazy
def plaintitle(self, v):
- if self.club and not (v and v.paid_dues) and not (v and v.admin_level == 6):
+ if self.club and not (v and v.paid_dues) and not (v and v.admin_level > 1):
if v: return random.choice(TROLLTITLES).format(username=v.username)
- else: return 'COUNTRY CLUB MEMBERS ONLY'
+ else: return f'{cc} MEMBERS ONLY'
else: title = self.title
title = censor_slurs(title, v)
diff --git a/files/classes/user.py b/files/classes/user.py
index 529377845..1cd03df48 100644
--- a/files/classes/user.py
+++ b/files/classes/user.py
@@ -50,6 +50,7 @@ class User(Base):
verified = Column(String)
verifiedcolor = Column(String)
marseyawarded = Column(Integer)
+ longpost = Column(Integer)
email = deferred(Column(String))
css = deferred(Column(String))
profilecss = deferred(Column(String))
@@ -81,12 +82,15 @@ class User(Base):
nitter = Column(Boolean)
mute = Column(Boolean)
unmutable = Column(Boolean)
+ eye = Column(Boolean)
+ alt = Column(Boolean)
frontsize = Column(Integer, default=25)
controversial = Column(Boolean, default=False)
bio = deferred(Column(String))
bio_html = Column(String)
sig = deferred(Column(String))
sig_html = Column(String)
+ fp = Column(String)
sigs_disabled = Column(Boolean)
friends = deferred(Column(String))
friends_html = deferred(Column(String))
@@ -166,7 +170,6 @@ class User(Base):
return return_value
@property
- @lazy
def referral_count(self):
return len(self.referrals)
@@ -178,7 +181,7 @@ class User(Base):
@property
@lazy
def paid_dues(self):
- return self.admin_level == 6 or self.club_allowed or (self.truecoins > int(environ.get("DUES").strip()) and not self.club_banned)
+ return self.admin_level > 1 or self.club_allowed or (self.truecoins > int(environ.get("DUES").strip()) and not self.club_banned)
def any_block_exists(self, other):
@@ -212,12 +215,12 @@ class User(Base):
@cache.memoize(timeout=86400)
def userpagelisting(self, v=None, page=1, sort="new", t="all"):
- if self.shadowbanned and not (v and (v.admin_level >= 3 or v.id == self.id)):
+ if self.shadowbanned and not (v and (v.admin_level > 1 or v.id == self.id)):
return []
posts = g.db.query(Submission.id).filter_by(author_id=self.id, is_pinned=False)
- if not (v and (v.admin_level >= 3 or v.id == self.id)):
+ if not (v and (v.admin_level > 1 or v.id == self.id)):
posts = posts.filter_by(deleted_utc=0, is_banned=False, private=False)
now = int(time.time())
@@ -356,7 +359,7 @@ class User(Base):
@property
@lazy
def post_notifications_count(self):
- return g.db.query(Notification.id).join(Comment).filter(Notification.user_id == self.id, Notification.read == False, Comment.author_id == AUTOJANNY_ACCOUNT).count()
+ return g.db.query(Notification.id).join(Comment).filter(Notification.user_id == self.id, Notification.read == False, Comment.author_id == AUTOJANNY_ID).count()
@property
@@ -400,13 +403,13 @@ class User(Base):
@lazy
def banner_url(self):
if self.bannerurl: return self.bannerurl
- else: return f"http://{site}/assets/images/{site_name}/preview.webp"
+ else: return f"http://{site}/assets/images/{site_name}/preview.webp?v=2"
@property
@lazy
def profile_url(self):
if self.profileurl: return self.profileurl
- elif "rama" in site: return f"http://{site}/assets/images/defaultpictures/{random.randint(1, 150)}.webp"
+ elif "rama" in site: return f"http://{site}/assets/images/defaultpictures/{random.randint(1, 150)}.webp?v=1"
else: return f"http://{site}/assets/images/default-profile-pic.webp"
@property
@@ -464,7 +467,7 @@ class User(Base):
self.profileurl = None
if self.discord_id: remove_user(self)
- self.is_banned = admin.id if admin else AUTOJANNY_ACCOUNT
+ self.is_banned = admin.id if admin else AUTOJANNY_ID
if reason: self.ban_reason = reason
g.db.add(self)
diff --git a/files/helpers/alerts.py b/files/helpers/alerts.py
index ef1335d9a..19e70350a 100644
--- a/files/helpers/alerts.py
+++ b/files/helpers/alerts.py
@@ -14,8 +14,8 @@ def send_notification(uid, text, autojanny=False):
text_html = sanitize(text_html)
- if autojanny: author_id = AUTOJANNY_ACCOUNT
- else: author_id = NOTIFICATIONS_ACCOUNT
+ if autojanny: author_id = AUTOJANNY_ID
+ else: author_id = NOTIFICATIONS_ID
new_comment = Comment(author_id=author_id,
parent_submission=None,
@@ -38,7 +38,7 @@ def send_follow_notif(vid, user, text):
text_html = CustomRenderer().render(mistletoe.Document(text))
text_html = sanitize(text_html)
- new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
+ new_comment = Comment(author_id=NOTIFICATIONS_ID,
parent_submission=None,
distinguish_level=6,
body=text,
@@ -57,7 +57,7 @@ def send_unfollow_notif(vid, user, text):
text_html = CustomRenderer().render(mistletoe.Document(text))
text_html = sanitize(text_html)
- new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
+ new_comment = Comment(author_id=NOTIFICATIONS_ID,
parent_submission=None,
distinguish_level=6,
body=text,
@@ -76,7 +76,7 @@ def send_block_notif(vid, user, text):
text_html = CustomRenderer().render(mistletoe.Document(text))
text_html = sanitize(text_html)
- new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
+ new_comment = Comment(author_id=NOTIFICATIONS_ID,
parent_submission=None,
distinguish_level=6,
body=text,
@@ -95,7 +95,7 @@ def send_unblock_notif(vid, user, text):
text_html = CustomRenderer().render(mistletoe.Document(text))
text_html = sanitize(text_html)
- new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
+ new_comment = Comment(author_id=NOTIFICATIONS_ID,
parent_submission=None,
distinguish_level=6,
body=text,
diff --git a/files/helpers/const.py b/files/helpers/const.py
index e249e1cde..63447a4f5 100644
--- a/files/helpers/const.py
+++ b/files/helpers/const.py
@@ -8,6 +8,8 @@ SLURS = {
"retarded": "r-slurred",
"retard": "r-slur",
"tard": "r-slur",
+ "newfag": "newstrag",
+ "oldfag": "oldstrag",
"faggot": "cute twink",
"faggot": "cute twink",
"fag": "cute twink",
@@ -93,45 +95,56 @@ Thank you."""
WELCOME_MSG = "Hi there! It's me, your soon-to-be favorite rDrama user @carpathianflorist here to give you a brief rundown on some of the sick features we have here. You'll probably want to start by following me, though. So go ahead and click my name and then smash that Follow button. This is actually really important, so go on. Hurry.\n\nThanks!\n\nNext up: If you're a member of the media, similarly just shoot me a DM and I'll set about verifying you and then we can take care of your sad journalism stuff.\n\n**FOR EVERYONE ELSE**\n\n Begin by navigating to [the settings page](https://rdrama.net/settings/profile) (we'll be prettying this up so it's less convoluted soon, don't worry) and getting some basic customization done.\n\n### Themes\n\nDefinitely change your theme right away, the default one (Midnight) is pretty enough, but why not use something *exotic* like Win98, or *flashy* like Tron? Even Coffee is super tasteful and way more fun than the default. More themes to come when we get around to it!\n\n### Avatar/pfp\n\nYou'll want to set this pretty soon; without uploading one, I put together a randomly-assigned selection of 180ish pictures of furries, ugly goths, mujahideen, anime girls, and My Little Ponys which are used by everyone who was too lazy to set a pfp. Set the banner too while you're at it. Your profile is important!\n\n### Flairs\n\nSince you're already on the settings page, you may as well set a flair, too. As with your username, you can - obviously - choose the color of this, either with a hex value or just from the preset colors. And also like your username, you can change this at any time. [Paypigs](https://marsey1.gumroad.com/l/tfcvri) can even further relive the glory days of 90s-00s internet and set obnoxious signatures.\n\n### PROFILE ANTHEMS\n\nSpeaking of profiles, hey, remember MySpace? Do you miss autoplaying music assaulting your ears every time you visited a friend's page? Yeah, we brought that back. Enter a YouTube URL, wait a few seconds for it to process, and then BAM! you've got a profile anthem which people cannot mute. Unless they spend 20,000 dramacoin in the shop for a mute button. Which you can then remove from your profile by spending 40,000 dramacoin on an unmuteable anthem. Get fucked poors!\n\n### Dramacoin?\n\nDramacoin is basically our take on the karma system. Except unlike the karma system, it's not gay and boring and stupid and useless. Dramacoin can be spent at [Marsey's Dramacoin Emporium](https://rdrama.net/shop) on upgrades to your user experience (many more coming than what's already listed there), and best of all on tremendously annoying awards to fuck with your fellow dramautists. We're always adding more, so check back regularly in case you happen to miss one of the announcement posts. Holiday-themed awards are currently unavailable while we resolve an internal dispute, but they **will** return, no matter what some other janitors insist.\n\nLike karma, dramacoin is obtained by getting upvotes on your threads and comments. *Unlike* karma, it's also obtained by getting downvotes on your threads and comments. Downvotes don't really do anything here - they pay the same amount of dramacoin and they increase thread/comment ranking just the same as an upvote. You just use them to express petty disapproval and hopefully start a fight. Because all votes are visible here. To hell with your anonymity.\n\nDramacoin can also be traded amongst users from their profiles. Note that there is a 1.5% transaction fee.\n\n**Dramacoin and shop items cannot be purchased with real money and this will not change.** Though we are notoriously susceptible to bribes, so definitely shoot your shot. It'll probably go well, honestly.\n\n### Badges\n\nRemember all those neat little metallic icons you saw on my profile when you were following me? If not, scroll back up and go have a look. And doublecheck to make sure you pressed the Follow button. Anyway, those are badges. You earn them by doing a variety of things. Some of them even offer benefits, like discounts at the shop. A [complete list of badges and their requirements can be found here](https://rdrama.net/badges), though I add more pretty regularly, so keep an eye on the changelog.\n\n### Other stuff\n\nWe're always adding new features, and we take a fun-first approach to development. If you have a suggestion for something that would be fun, funny, annoying - or best of all, some combination of all three - definitely make a thread about it. Or just DM me if you're shy. Weirdo. Anyway there's also the [leaderboards](https://rdrama.net/leaderboard), boring stuff like two-factor authentication you can toggle on somewhere in the settings page (psycho), the ability to save posts and comments, close to a thousand emojis already (several hundred of which are rDrama originals), and on and on and on and on. This is just the basics, mostly to help you get acquainted with some of the things you can do here to make it more easy on the eyes, customizable, and enjoyable. If you don't enjoy it, just go away! We're not changing things to suit you! Get out of here loser! And no, you can't delete your account :na:\n\nI love you. *xoxo Carp* 💋"
if SITE == 'rdrama.net':
- NOTIFICATIONS_ACCOUNT = 1046
- AUTOJANNY_ACCOUNT = 2360
- SNAPPY_ACCOUNT = 261
- LONGPOSTBOT_ACCOUNT = 1832
- ZOZBOT_ACCOUNT = 1833
- AUTOPOLLER_ACCOUNT = 6176
+ BASEDBOT_ID = 0
+ NOTIFICATIONS_ID = 1046
+ AUTOJANNY_ID = 2360
+ SNAPPY_ID = 261
+ LONGPOSTBOT_ID = 1832
+ ZOZBOT_ID = 1833
+ AUTOPOLLER_ID = 6176
TAX_RECEIVER_ID = 747
PIZZA_SHILL_ID = 2424
+ IDIO_ID = 30
CARP_ID = 995
RED_ID = 1577
LAWLZ_ID = 3833
LLM_ID = 253
+ DAD_ID = 2513
+ MOM_ID = 4588
elif SITE == "pcmemes.net":
- BASEDBOT_ACCOUNT = 800
- NOTIFICATIONS_ACCOUNT = 1046
- AUTOJANNY_ACCOUNT = 1050
- SNAPPY_ACCOUNT = 261
- LONGPOSTBOT_ACCOUNT = 1832
- ZOZBOT_ACCOUNT = 1833
- AUTOPOLLER_ACCOUNT = 3369
+ BASEDBOT_ID = 800
+ NOTIFICATIONS_ID = 1046
+ AUTOJANNY_ID = 1050
+ SNAPPY_ID = 261
+ LONGPOSTBOT_ID = 1832
+ ZOZBOT_ID = 1833
+ AUTOPOLLER_ID = 3369
TAX_RECEIVER_ID = 1577
PIZZA_SHILL_ID = 0
+ IDIO_ID = 0
CARP_ID = 0
RED_ID = 1577
LAWLZ_ID = 0
LLM_ID = 0
+ DAD_ID = 0
+ MOM_ID = 0
else:
- NOTIFICATIONS_ACCOUNT = 1
- AUTOJANNY_ACCOUNT = 2
- SNAPPY_ACCOUNT = 3
- LONGPOSTBOT_ACCOUNT = 4
- ZOZBOT_ACCOUNT = 5
- AUTOPOLLER_ACCOUNT = 6
+ BASEDBOT_ID = 0
+ NOTIFICATIONS_ID = 1
+ AUTOJANNY_ID = 2
+ SNAPPY_ID = 3
+ LONGPOSTBOT_ID = 4
+ ZOZBOT_ID = 5
+ AUTOPOLLER_ID = 6
TAX_RECEIVER_ID = 7
PIZZA_SHILL_ID = 0
+ IDIO_ID = 0
CARP_ID = 0
RED_ID = 0
LAWLZ_ID = 0
LLM_ID = 0
+ DAD_ID = 0
+ MOM_ID = 0
PUSHER_INSTANCE_ID = '02ddcc80-b8db-42be-9022-44c546b4dce6'
PUSHER_KEY = environ.get("PUSHER_KEY", "").strip()
@@ -187,6 +200,14 @@ AWARDS = {
"color": "text-black",
"price": 1000
},
+ "pizzashill": {
+ "kind": "pizzashill",
+ "title": "Pizzashill",
+ "description": "Forces the recipient to make all posts/comments > 280 characters for 24 hours.",
+ "icon": "fas fa-pizza-slice",
+ "color": "text-orange",
+ "price": 1000
+ },
"flairlock": {
"kind": "flairlock",
"title": "1-Day Flairlock",
@@ -307,6 +328,23 @@ AWARDS = {
"color": "text-orange",
"price": 1000
},
+ "eye": {
+ "kind": "eye",
+ "title": "All-Seeing Eye",
+ "description": "Gives the recipient the ability to view private profiles.",
+ "icon": "fas fa-eye",
+ "color": "text-silver",
+ "price": 10000
+ },
+ "alt": {
+ "kind": "alt",
+ "title": "Alt-Seeing Eye",
+ "description": "Gives the recipient the ability to view alts.",
+ "icon": "fas fa-eye",
+ "color": "text-gold",
+ "price": 50000
+ },
+
}
AWARDS2 = {
@@ -350,6 +388,14 @@ AWARDS2 = {
"color": "text-black",
"price": 1000
},
+ "pizzashill": {
+ "kind": "pizzashill",
+ "title": "Pizzashill",
+ "description": "Forces the recipient to make all posts/comments > 280 characters for 24 hours.",
+ "icon": "fas fa-pizza-slice",
+ "color": "text-orange",
+ "price": 1000
+ },
"flairlock": {
"kind": "flairlock",
"title": "1-Day Flairlock",
@@ -398,6 +444,14 @@ AWARDS2 = {
"color": "text-success",
"price": 10000
},
+ "eye": {
+ "kind": "eye",
+ "title": "All-Seeing Eye",
+ "description": "Gives the recipient the ability to view private profiles.",
+ "icon": "fas fa-eye",
+ "color": "text-silver",
+ "price": 10000
+ },
"pause": {
"kind": "pause",
"title": "Pause",
@@ -414,6 +468,14 @@ AWARDS2 = {
"color": "text-success",
"price": 40000
},
+ "alt": {
+ "kind": "alt",
+ "title": "Alt-Seeing Eye",
+ "description": "Gives the recipient the ability to view alts.",
+ "icon": "fas fa-eye",
+ "color": "text-gold",
+ "price": 50000
+ },
}
TROLLTITLES = [
diff --git a/files/helpers/get.py b/files/helpers/get.py
index a2dc660a8..a9f778f1b 100644
--- a/files/helpers/get.py
+++ b/files/helpers/get.py
@@ -209,7 +209,7 @@ def get_comments(cids, v=None, load_parent=False):
blocked.c.id,
).filter(Comment.id.in_(cids))
- if not (v and v.shadowbanned) and not (v and v.admin_level == 6):
+ if not (v and v.shadowbanned) and not (v and v.admin_level > 1):
comments = comments.join(User, User.id == Comment.author_id).filter(User.shadowbanned == None)
comments = comments.join(
diff --git a/files/helpers/wrappers.py b/files/helpers/wrappers.py
index a74c36bed..b3e683ee1 100644
--- a/files/helpers/wrappers.py
+++ b/files/helpers/wrappers.py
@@ -35,56 +35,12 @@ def get_logged_in_user():
return x[0]
-
def check_ban_evade(v):
-
- if not v or not v.ban_evade or v.admin_level > 0 or v.is_suspended: return
-
- if random.randint(0,30) < v.ban_evade:
- v.ban(reason="permaban evasion")
- send_notification(v.id, "Your account has been permanently suspended for the following reason:\n\n> permaban evasion")
-
- for post in g.db.query(Submission).filter_by(author_id=v.id).all():
- if post.is_banned:
- continue
-
- post.is_banned=True
- post.ban_reason="AutoJanny"
- g.db.add(post)
-
- ma=ModAction(
- kind="ban_post",
- user_id=AUTOJANNY_ACCOUNT,
- target_submission_id=post.id,
- _note="permaban evasion"
- )
- g.db.add(ma)
-
- for comment in g.db.query(Comment).filter_by(author_id=v.id).all():
- if comment.is_banned:
- continue
-
- comment.is_banned=True
- comment.ban_reason="AutoJanny"
- g.db.add(comment)
-
- try:
- ma=ModAction(
- kind="ban_comment",
- user_id=AUTOJANNY_ACCOUNT,
- target_comment_id=comment.id,
- _note="ban evasion"
- )
- g.db.add(ma)
- except: pass
-
- else:
- v.ban_evade +=1
+ if v and v.ban_evade and v.admin_level == 0 and not v.is_suspended:
+ if random.randint(0,30) < v.ban_evade: v.shadowbanned = "AutoJanny"
+ else: v.ban_evade +=1
g.db.add(v)
-
- g.db.commit()
-
-
+ g.db.commit()
def auth_desired(f):
def wrapper(*args, **kwargs):
@@ -128,8 +84,7 @@ def is_not_banned(f):
check_ban_evade(v)
- if v.is_suspended:
- abort(403)
+ if v.is_suspended: abort(403)
g.v = v
diff --git a/files/routes/admin.py b/files/routes/admin.py
index 412d240bc..47caf4368 100644
--- a/files/routes/admin.py
+++ b/files/routes/admin.py
@@ -18,10 +18,11 @@ from .front import frontlist
from files.helpers.discord import add_role
SITE_NAME = environ.get("SITE_NAME", "").strip()
-
+if SITE_NAME == 'PCM': cc = "splash mountain"
+else: cc = "country club"
@app.get("/name//")
-@admin_level_required(6)
+@admin_level_required(2)
def changename(v, id, name):
if request.host != 'pcmemes.net': abort(403)
user = g.db.query(User).filter_by(id=int(id)).first()
@@ -32,9 +33,8 @@ def changename(v, id, name):
return "Username changed!"
return "User not found!"
-
@app.get("/coins//")
-@admin_level_required(6)
+@admin_level_required(2)
def addcoins(v, id, coins):
if request.host != 'pcmemes.net': abort(403)
user = g.db.query(User).filter_by(id=int(id)).first()
@@ -46,7 +46,7 @@ def addcoins(v, id, coins):
return "User not found!"
@app.get("/truescore")
-@admin_level_required(6)
+@admin_level_required(2)
def truescore(v):
users = g.db.query(User).order_by(User.truecoins.desc()).limit(25).all()
return render_template("truescore.html", v=v, users=users)
@@ -54,9 +54,9 @@ def truescore(v):
@app.post("/@/revert_actions")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
def revert_actions(v, username):
- if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
+ if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
@@ -79,7 +79,7 @@ def revert_actions(v, username):
@app.post("/@/club_allow")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
def club_allow(v, username):
u = get_user(username, v=v)
@@ -106,11 +106,11 @@ def club_allow(v, username):
g.db.add(ma)
g.db.commit()
- return {"message": f"@{username} has been allowed into the country club!"}
+ return {"message": f"@{username} has been allowed into the {cc}!"}
@app.post("/@/club_ban")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
def club_ban(v, username):
u = get_user(username, v=v)
@@ -135,17 +135,17 @@ def club_ban(v, username):
g.db.add(ma)
g.db.commit()
- return {"message": f"@{username} has been kicked from the country club. Deserved."}
+ return {"message": f"@{username} has been kicked from the {cc}. Deserved."}
@app.post("/@/make_admin")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
def make_admin(v, username):
- if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
+ if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
- user.admin_level = 6
+ user.admin_level = 2
g.db.add(user)
g.db.commit()
return {"message": "User has been made admin!"}
@@ -153,9 +153,9 @@ def make_admin(v, username):
@app.post("/@/remove_admin")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
def remove_admin(v, username):
- if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
+ if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
user.admin_level = 0
@@ -166,9 +166,9 @@ def remove_admin(v, username):
@app.post("/@/make_fake_admin")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
def make_fake_admin(v, username):
- if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
+ if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
user.admin_level = 1
@@ -179,9 +179,9 @@ def make_fake_admin(v, username):
@app.post("/@/remove_fake_admin")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
def remove_fake_admin(v, username):
- if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
+ if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
user = get_user(username)
if not user: abort(404)
user.admin_level = 0
@@ -192,9 +192,9 @@ def remove_fake_admin(v, username):
@app.post("/admin/monthly")
@limiter.limit("1/day")
-@admin_level_required(6)
+@admin_level_required(2)
def monthly(v):
- if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.id in [1,28,30,995,2513,3333]) or ('rama' not in request.host and 'pcm' not in request.host):
+ if 'pcm' in request.host or (SITE_NAME == 'Drama' and v.admin_level > 2) or ('rama' not in request.host and 'pcm' not in request.host):
thing = g.db.query(AwardRelationship).order_by(AwardRelationship.id.desc()).first().id
for u in g.db.query(User).filter(User.patron > 0).all():
if u.patron == 1: procoins = 2000
@@ -212,7 +212,7 @@ def monthly(v):
@app.get('/admin/rules')
-@admin_level_required(6)
+@admin_level_required(2)
def get_rules(v):
try:
@@ -225,7 +225,7 @@ def get_rules(v):
@app.post('/admin/rules')
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def post_rules(v):
@@ -249,7 +249,7 @@ def post_rules(v):
@app.get("/admin/shadowbanned")
@auth_required
def shadowbanned(v):
- if not (v and v.admin_level == 6): abort(404)
+ if not (v and v.admin_level > 1): abort(404)
users = [x for x in g.db.query(User).filter(User.shadowbanned != None).all()]
return render_template("banned.html", v=v, users=users)
@@ -257,13 +257,13 @@ def shadowbanned(v):
@app.get("/admin/agendaposters")
@auth_required
def agendaposters(v):
- if not (v and v.admin_level == 6): abort(404)
+ if not (v and v.admin_level > 1): abort(404)
users = [x for x in g.db.query(User).filter_by(agendaposter = True).all()]
return render_template("banned.html", v=v, users=users)
@app.get("/admin/image_posts")
-@admin_level_required(3)
+@admin_level_required(2)
def image_posts_listing(v):
try: page = int(request.values.get('page', 1))
@@ -281,7 +281,7 @@ def image_posts_listing(v):
@app.get("/admin/reported/posts")
-@admin_level_required(3)
+@admin_level_required(2)
def reported_posts(v):
page = max(1, int(request.values.get("page", 1)))
@@ -302,7 +302,7 @@ def reported_posts(v):
@app.get("/admin/reported/comments")
-@admin_level_required(3)
+@admin_level_required(2)
def reported_comments(v):
page = max(1, int(request.values.get("page", 1)))
@@ -327,14 +327,14 @@ def reported_comments(v):
standalone=True)
@app.get("/admin")
-@admin_level_required(3)
+@admin_level_required(2)
def admin_home(v):
with open('./disablesignups', 'r') as f:
x = f.read()
return render_template("admin/admin_home.html", v=v, x=x)
@app.post("/admin/disablesignups")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def disablesignups(v):
with open('./disablesignups', 'r') as f: content = f.read()
@@ -348,7 +348,7 @@ def disablesignups(v):
return {"message": "Signups disabled!"}
@app.get("/admin/badge_grant")
-@admin_level_required(4)
+@admin_level_required(2)
def badge_grant_get(v):
badge_types = g.db.query(BadgeDef).all()
@@ -370,7 +370,7 @@ def badge_grant_get(v):
@app.post("/admin/badge_grant")
@limiter.limit("1/second")
-@admin_level_required(4)
+@admin_level_required(2)
@validate_formkey
def badge_grant_post(v):
@@ -431,7 +431,7 @@ def users_list(v):
)
@app.get("/admin/alt_votes")
-@admin_level_required(4)
+@admin_level_required(2)
def alt_votes_get(v):
if not request.values.get("u1") or not request.values.get("u2"):
@@ -541,7 +541,7 @@ def alt_votes_get(v):
@app.post("/admin/link_accounts")
@limiter.limit("1/second")
-@admin_level_required(4)
+@admin_level_required(2)
@validate_formkey
def admin_link_accounts(v):
@@ -561,7 +561,7 @@ def admin_link_accounts(v):
@app.get("/admin/removed")
-@admin_level_required(3)
+@admin_level_required(2)
def admin_removed(v):
page = int(request.values.get("page", 1))
@@ -586,7 +586,7 @@ def admin_removed(v):
@app.post("/agendaposter/")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def agendaposter(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@@ -639,7 +639,7 @@ def agendaposter(user_id, v):
@app.post("/shadowban/")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def shadowban(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@@ -665,7 +665,7 @@ def shadowban(user_id, v):
@app.post("/unshadowban/")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def unshadowban(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@@ -690,7 +690,7 @@ def unshadowban(user_id, v):
@app.post("/admin/verify/")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def verify(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@@ -709,7 +709,7 @@ def verify(user_id, v):
@app.post("/admin/unverify/")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def unverify(user_id, v):
user = g.db.query(User).filter_by(id=user_id).first()
@@ -729,7 +729,7 @@ def unverify(user_id, v):
@app.post("/admin/title_change/")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def admin_title_change(user_id, v):
@@ -763,7 +763,7 @@ def admin_title_change(user_id, v):
@app.post("/ban_user/")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def ban_user(user_id, v):
@@ -838,7 +838,7 @@ def ban_user(user_id, v):
@app.post("/unban_user/")
@limiter.limit("1/second")
-@admin_level_required(6)
+@admin_level_required(2)
@validate_formkey
def unban_user(user_id, v):
@@ -878,7 +878,7 @@ def unban_user(user_id, v):
@app.post("/ban_post/")
@limiter.limit("1/second")
-@admin_level_required(3)
+@admin_level_required(2)
@validate_formkey
def ban_post(post_id, v):
@@ -916,7 +916,7 @@ def ban_post(post_id, v):
@app.post("/unban_post/")
@limiter.limit("1/second")
-@admin_level_required(3)
+@admin_level_required(2)
@validate_formkey
def unban_post(post_id, v):
@@ -974,7 +974,7 @@ def api_distinguish_post(post_id, v):
@app.post("/sticky/")
-@admin_level_required(3)
+@admin_level_required(2)
def api_sticky_post(post_id, v):
post = g.db.query(Submission).filter_by(id=post_id).first()
@@ -994,9 +994,20 @@ def api_sticky_post(post_id, v):
cache.delete_memoized(frontlist)
- g.db.commit()
- if post.stickied: return {"message": "Post pinned!"}
- else: return {"message": "Post unpinned!"}
+ if post.stickied:
+ if v.id != post.author_id:
+ message = f"@{v.username} has pinned your [post](/post/{post_id})!"
+ existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message).first()
+ if not existing: send_notification(post.author_id, message)
+ g.db.commit()
+ return {"message": "Post pinned!"}
+ else:
+ if v.id != post.author_id:
+ message = f"@{v.username} has unpinned your [post](/post/{post_id})!"
+ existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message).first()
+ if not existing: send_notification(post.author_id, message)
+ g.db.commit()
+ return {"message": "Post unpinned!"}
@app.post("/ban_comment/")
@limiter.limit("1/second")
@@ -1075,14 +1086,14 @@ def admin_distinguish_comment(c_id, v):
return html
@app.get("/admin/dump_cache")
-@admin_level_required(6)
+@admin_level_required(2)
def admin_dump_cache(v):
cache.clear()
return {"message": "Internal cache cleared."}
@app.get("/admin/banned_domains/")
-@admin_level_required(4)
+@admin_level_required(2)
def admin_banned_domains(v):
banned_domains = g.db.query(BannedDomain).all()
@@ -1090,7 +1101,7 @@ def admin_banned_domains(v):
@app.post("/admin/banned_domains")
@limiter.limit("1/second")
-@admin_level_required(4)
+@admin_level_required(2)
@validate_formkey
def admin_toggle_ban_domain(v):
@@ -1126,7 +1137,7 @@ def admin_toggle_ban_domain(v):
@app.post("/admin/nuke_user")
@limiter.limit("1/second")
-@admin_level_required(4)
+@admin_level_required(2)
@validate_formkey
def admin_nuke_user(v):
@@ -1160,7 +1171,7 @@ def admin_nuke_user(v):
@app.post("/admin/unnuke_user")
@limiter.limit("1/second")
-@admin_level_required(4)
+@admin_level_required(2)
@validate_formkey
def admin_nunuke_user(v):
diff --git a/files/routes/awards.py b/files/routes/awards.py
index 3f4712555..0aafed5f7 100644
--- a/files/routes/awards.py
+++ b/files/routes/awards.py
@@ -16,7 +16,7 @@ discounts = {
73: 0.10,
}
-AWARDS2 = {
+AWARDS3 = {
"ban": {
"kind": "ban",
"title": "1-Day Ban",
@@ -55,7 +55,8 @@ def shop(v):
"icon": "fas fa-poop",
"color": "text-black-50",
"owned": 0,
- "price": 500
+ "price": 500,
+ "MB": True
},
"fireflies": {
"kind": "fireflies",
@@ -64,7 +65,8 @@ def shop(v):
"icon": "fas fa-sparkles",
"color": "text-warning",
"owned": 0,
- "price": 500
+ "price": 500,
+ "MB": True
},
"train": {
"kind": "train",
@@ -73,7 +75,8 @@ def shop(v):
"icon": "fas fa-train",
"color": "text-pink",
"owned": 0,
- "price": 500
+ "price": 500,
+ "MB": True
},
"pin": {
"kind": "pin",
@@ -82,7 +85,8 @@ def shop(v):
"icon": "fas fa-thumbtack fa-rotate--45",
"color": "text-warning",
"owned": 0,
- "price": 750
+ "price": 750,
+ "MB": True
},
"unpin": {
"kind": "unpin",
@@ -91,7 +95,18 @@ def shop(v):
"icon": "fas fa-thumbtack fa-rotate--45",
"color": "text-black",
"owned": 0,
- "price": 1000
+ "price": 1000,
+ "MB": True
+ },
+ "pizzashill": {
+ "kind": "pizzashill",
+ "title": "Pizzashill",
+ "description": "Forces the recipient to make all posts/comments > 280 characters for 24 hours.",
+ "icon": "fas fa-pizza-slice",
+ "color": "text-orange",
+ "owned": 0,
+ "price": 1000,
+ "MB": True
},
"flairlock": {
"kind": "flairlock",
@@ -100,7 +115,8 @@ def shop(v):
"icon": "fas fa-lock",
"color": "text-black",
"owned": 0,
- "price": 1250
+ "price": 1250,
+ "MB": True
},
"agendaposter": {
"kind": "agendaposter",
@@ -109,7 +125,8 @@ def shop(v):
"icon": "fas fa-snooze",
"color": "text-purple",
"owned": 0,
- "price": 2500
+ "price": 2500,
+ "MB": True
},
"marsey": {
"kind": "marsey",
@@ -118,7 +135,8 @@ def shop(v):
"icon": "fas fa-cat",
"color": "text-orange",
"owned": 0,
- "price": 3000
+ "price": 3000,
+ "MB": True
},
"ban": {
"kind": "ban",
@@ -127,7 +145,8 @@ def shop(v):
"icon": "fas fa-gavel",
"color": "text-danger",
"owned": 0,
- "price": 3000
+ "price": 3000,
+ "MB": True
},
"unban": {
"kind": "unban",
@@ -136,7 +155,8 @@ def shop(v):
"icon": "fas fa-gavel",
"color": "text-success",
"owned": 0,
- "price": 3500
+ "price": 3500,
+ "MB": True
},
"grass": {
"kind": "grass",
@@ -145,7 +165,18 @@ def shop(v):
"icon": "fas fa-seedling",
"color": "text-success",
"owned": 0,
- "price": 10000
+ "price": 10000,
+ "MB": False
+ },
+ "eye": {
+ "kind": "eye",
+ "title": "All-Seeing Eye",
+ "description": "Gives the recipient the ability to view private profiles.",
+ "icon": "fas fa-eye",
+ "color": "text-silver",
+ "owned": 0,
+ "price": 10000,
+ "MB": False
},
"pause": {
"kind": "pause",
@@ -154,7 +185,8 @@ def shop(v):
"icon": "fas fa-volume-mute",
"color": "text-danger",
"owned": 0,
- "price": 20000
+ "price": 20000,
+ "MB": False
},
"unpausable": {
"kind": "unpausable",
@@ -163,7 +195,18 @@ def shop(v):
"icon": "fas fa-volume",
"color": "text-success",
"owned": 0,
- "price": 40000
+ "price": 40000,
+ "MB": False
+ },
+ "alt": {
+ "kind": "alt",
+ "title": "Alt-Seeing Eye",
+ "description": "Gives the recipient the ability to view alts.",
+ "icon": "fas fa-eye",
+ "color": "text-gold",
+ "owned": 0,
+ "price": 50000,
+ "MB": False
},
}
@@ -231,6 +274,14 @@ def buy(v, award):
"color": "text-black",
"price": 1000
},
+ "pizzashill": {
+ "kind": "pizzashill",
+ "title": "Pizzashill",
+ "description": "Forces the recipient to make all posts/comments > 280 characters for 24 hours.",
+ "icon": "fas fa-pizza-slice",
+ "color": "text-orange",
+ "price": 1000,
+ },
"flairlock": {
"kind": "flairlock",
"title": "1-Day Flairlock",
@@ -279,6 +330,14 @@ def buy(v, award):
"color": "text-success",
"price": 10000
},
+ "eye": {
+ "kind": "eye",
+ "title": "All-Seeing Eye",
+ "description": "Gives the recipient the ability to view private profiles.",
+ "icon": "fas fa-eye",
+ "color": "text-silver",
+ "price": 10000
+ },
"pause": {
"kind": "pause",
"title": "Pause",
@@ -295,6 +354,14 @@ def buy(v, award):
"color": "text-success",
"price": 40000
},
+ "alt": {
+ "kind": "alt",
+ "title": "Alt-Seeing Eye",
+ "description": "Gives the recipient the ability to view alts.",
+ "icon": "fas fa-eye",
+ "color": "text-gold",
+ "price": 50000
+ },
}
if award not in AWARDS: abort(400)
@@ -362,7 +429,7 @@ def buy(v, award):
@auth_required
def award_post(pid, v):
- if v.is_suspended and v.unban_utc == 0: return {"error": "forbidden."}, 403
+ if v.is_banned and not v.unban_utc: return {"error": "forbidden."}, 403
kind = request.values.get("kind", "").strip()
@@ -426,7 +493,7 @@ def award_post(pid, v):
author.ban_evade = 0
send_notification(author.id, f"You have been unbanned!")
elif kind == "grass":
- author.is_banned = AUTOJANNY_ACCOUNT
+ author.is_banned = AUTOJANNY_ID
author.ban_reason = f"grass award used by @{v.username} on /post/{post.id}"
link = f"[this post]({post.permalink})"
send_notification(author.id, f"Your account has been suspended permanently for {link}. You must [provide the admins](/contact) a timestamped picture of you touching grass to get unbanned!")
@@ -460,16 +527,31 @@ def award_post(pid, v):
author.flairchanged = time.time() + 86400
elif kind == "pause":
author.mute = True
- send_notification(995, f"@{v.username} bought {kind} award!")
+ send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=68, user_id=author.id)
g.db.add(new_badge)
elif kind == "unpausable":
author.unmutable = True
- send_notification(995, f"@{v.username} bought {kind} award!")
+ send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=67, user_id=author.id)
g.db.add(new_badge)
elif kind == "marsey":
- author.marseyawarded = time.time() + 86400
+ if author.marseyawarded: author.marseyawarded += 86400
+ else: author.marseyawarded = time.time() + 86400
+ elif kind == "pizzashill":
+ if author.longpost: author.longpost += 86400
+ else: author.longpost = time.time() + 86400
+ send_notification(IDIO_ID, f"@{v.username} used {kind} award on {post.shortlink}")
+ elif kind == "eye":
+ author.eye = True
+ send_notification(CARP_ID, f"@{v.username} used {kind} award!")
+ new_badge = Badge(badge_id=83, user_id=author.id)
+ g.db.add(new_badge)
+ elif kind == "alt":
+ author.alt = True
+ send_notification(CARP_ID, f"@{v.username} used {kind} award!")
+ new_badge = Badge(badge_id=84, user_id=author.id)
+ g.db.add(new_badge)
post.author.received_award_count += 1
g.db.add(post.author)
@@ -548,7 +630,7 @@ def award_comment(cid, v):
author.ban_evade = 0
send_notification(author.id, f"You have been unbanned!")
elif kind == "grass":
- author.is_banned = AUTOJANNY_ACCOUNT
+ author.is_banned = AUTOJANNY_ID
author.ban_reason = f"grass award used by @{v.username} on /comment/{c.id}"
link = f"[this comment]({c.permalink})"
send_notification(author.id, f"Your account has been suspended permanently for {link}. You must [provide the admins](/contact) a timestamped picture of you touching grass to get unbanned!")
@@ -579,16 +661,31 @@ def award_comment(cid, v):
author.flairchanged = time.time() + 86400
elif kind == "pause":
author.mute = True
- send_notification(995, f"@{v.username} bought {kind} award!")
+ send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=68, user_id=author.id)
g.db.add(new_badge)
elif kind == "unpausable":
author.unmutable = True
- send_notification(995, f"@{v.username} bought {kind} award!")
+ send_notification(CARP_ID, f"@{v.username} used {kind} award!")
new_badge = Badge(badge_id=67, user_id=author.id)
g.db.add(new_badge)
elif kind == "marsey":
- author.marseyawarded = time.time() + 86400
+ if author.marseyawarded: author.marseyawarded += 86400
+ else: author.marseyawarded = time.time() + 86400
+ elif kind == "pizzashill":
+ if author.longpost: author.longpost += 86400
+ else: author.longpost = time.time() + 86400
+ send_notification(IDIO_ID, f"@{v.username} used {kind} award on {c.shortlink}")
+ elif kind == "eye":
+ author.eye = True
+ send_notification(CARP_ID, f"@{v.username} used {kind} award!")
+ new_badge = Badge(badge_id=83, user_id=author.id)
+ g.db.add(new_badge)
+ elif kind == "alt":
+ author.alt = True
+ send_notification(CARP_ID, f"@{v.username} used {kind} award!")
+ new_badge = Badge(badge_id=84, user_id=author.id)
+ g.db.add(new_badge)
c.author.received_award_count += 1
g.db.add(c.author)
@@ -598,20 +695,18 @@ def award_comment(cid, v):
else: return redirect("/")
@app.get("/admin/awards")
-@admin_level_required(6)
+@admin_level_required(2)
def admin_userawards_get(v):
- if request.host == 'rdrama.net' and v.id not in [1,28,30,995,2513,3333]: render_template("admin/awards.html", awards=list(AWARDS2.values()), v=v)
+ if request.host == 'rdrama.net' and v.admin_level != 3: return render_template("admin/awards.html", awards=list(AWARDS3.values()), v=v)
return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)
@app.post("/admin/awards")
@limiter.limit("1/second")
-@auth_required
+@admin_level_required(2)
@validate_formkey
def admin_userawards_post(v):
- if v.admin_level < 6: abort(403)
-
try: u = request.values.get("username").strip()
except: abort(404)
@@ -650,145 +745,5 @@ def admin_userawards_post(v):
g.db.commit()
- if request.host == 'rdrama.net' and v.id not in [1,28,30,995,2513,3333]: render_template("admin/awards.html", awards=list(AWARDS2.values()), v=v)
- return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)
-
-
-@app.get("/api/shop/items")
-@auth_required
-def items(v):
- AWARDS = {
- "shit": {
- "kind": "shit",
- "title": "Shit",
- "description": "Makes flies swarm the post.",
- "icon": "fas fa-poop",
- "color": "text-black-50",
- "owned": 0,
- "price": 500
- },
- "fireflies": {
- "kind": "fireflies",
- "title": "Fireflies",
- "description": "Makes fireflies swarm the post.",
- "icon": "fas fa-sparkles",
- "color": "text-warning",
- "owned": 0,
- "price": 500
- },
- "train": {
- "kind": "train",
- "title": "Train",
- "description": "Summons a train on the post.",
- "icon": "fas fa-train",
- "color": "text-pink",
- "owned": 0,
- "price": 500
- },
- "pin": {
- "kind": "pin",
- "title": "1-Hour Pin",
- "description": "Pins the post/comment.",
- "icon": "fas fa-thumbtack fa-rotate--45",
- "color": "text-warning",
- "owned": 0,
- "price": 750
- },
- "unpin": {
- "kind": "unpin",
- "title": "1-Hour Unpin",
- "description": "Removes 1 hour from the pin duration of the post/comment.",
- "icon": "fas fa-thumbtack fa-rotate--45",
- "color": "text-black",
- "owned": 0,
- "price": 1000
- },
- "flairlock": {
- "kind": "flairlock",
- "title": "1-Day Flairlock",
- "description": "Sets a flair for the recipient and locks it or 24 hours.",
- "icon": "fas fa-lock",
- "color": "text-black",
- "owned": 0,
- "price": 1250
- },
- "agendaposter": {
- "kind": "agendaposter",
- "title": "Agendaposter",
- "description": "Forces the agendaposter theme on the recipient for 24 hours.",
- "icon": "fas fa-snooze",
- "color": "text-purple",
- "owned": 0,
- "price": 2500
- },
- "marsey": {
- "kind": "marsey",
- "title": "Marsey",
- "description": "Makes the recipient unable to post/comment anything but marsey emojis for 24 hours.",
- "icon": "fas fa-cat",
- "color": "text-orange",
- "owned": 0,
- "price": 3000
- },
- "ban": {
- "kind": "ban",
- "title": "1-Day Ban",
- "description": "Bans the recipient for a day.",
- "icon": "fas fa-gavel",
- "color": "text-danger",
- "owned": 0,
- "price": 3000
- },
- "unban": {
- "kind": "unban",
- "title": "1-Day Unban",
- "description": "Removes 1 day from the ban duration of the recipient.",
- "icon": "fas fa-gavel",
- "color": "text-success",
- "owned": 0,
- "price": 3500
- },
- "grass": {
- "kind": "grass",
- "title": "Grass",
- "description": "Ban the recipient permanently (must provide a timestamped picture of them touching grass to the admins to get unbanned)",
- "icon": "fas fa-seedling",
- "color": "text-success",
- "owned": 0,
- "price": 10000
- },
- "pause": {
- "kind": "pause",
- "title": "Pause",
- "description": "Gives the recipient the ability to pause profile anthems.",
- "icon": "fas fa-volume-mute",
- "color": "text-danger",
- "owned": 0,
- "price": 20000
- },
- "unpausable": {
- "kind": "unpausable",
- "title": "Unpausable",
- "description": "Makes the profile anthem of the recipient unpausable.",
- "icon": "fas fa-volume",
- "color": "text-success",
- "owned": 0,
- "price": 40000
- },
- }
-
- for useraward in g.db.query(AwardRelationship).filter(AwardRelationship.user_id == v.id, AwardRelationship.submission_id == None, AwardRelationship.comment_id == None).all(): AWARDS[useraward.kind]["owned"] += 1
-
- if v.patron == 1: discount = 0.10
- elif v.patron == 2: discount = 0.15
- elif v.patron == 3: discount = 0.20
- elif v.patron == 4: discount = 0.25
- elif v.patron == 5: discount = 0.30
- else: discount = 0
-
- for badge in [69,70,71,72,73]:
- if v.has_badge(badge): discount += discounts[badge]
-
- for val in AWARDS.values(): val["discount"] = discount
-
- return AWARDS
\ No newline at end of file
+ if request.host == 'rdrama.net' and v.admin_level != 3: return render_template("admin/awards.html", awards=list(AWARDS3.values()), v=v)
+ return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)
\ No newline at end of file
diff --git a/files/routes/comments.py b/files/routes/comments.py
index caa80709c..7dab9975e 100644
--- a/files/routes/comments.py
+++ b/files/routes/comments.py
@@ -11,8 +11,9 @@ from flask import *
from files.__main__ import app, limiter
from files.helpers.sanitize import filter_title
-
site = environ.get("DOMAIN").strip()
+if site == 'pcmemes.net': cc = "SPLASH MOUNTAIN"
+else: cc = "COUNTRY CLUB"
beams_client = PushNotifications(
instance_id=PUSHER_INSTANCE_ID,
@@ -46,7 +47,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None):
if comment.post and comment.post.club and not (v and v.paid_dues): abort(403)
- if not comment.parent_submission and not (v and (comment.author.id == v.id or comment.sentto == v.id)) and not (v and v.admin_level == 6) : abort(403)
+ if not comment.parent_submission and not (v and (comment.author.id == v.id or comment.sentto == v.id)) and not (v and v.admin_level > 1) : abort(403)
if not pid:
if comment.parent_submission: pid = comment.parent_submission
@@ -90,12 +91,12 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None):
blocked.c.id,
)
- if not (v and v.shadowbanned) and not (v and v.admin_level == 6):
+ if not (v and v.shadowbanned) and not (v and v.admin_level > 1):
comments = comments.join(User, User.id == Comment.author_id).filter(User.shadowbanned == None)
comments=comments.filter(
Comment.parent_submission == post.id,
- Comment.author_id != AUTOPOLLER_ACCOUNT
+ Comment.author_id != AUTOPOLLER_ID
).join(
votes,
votes.c.comment_id == Comment.id,
@@ -122,7 +123,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None):
if request.headers.get("Authorization"): return top_comment.json
else:
- if post.is_banned and not (v and (v.admin_level >= 3 or post.author_id == v.id)): template = "submission_banned.html"
+ if post.is_banned and not (v and (v.admin_level > 1 or post.author_id == v.id)): template = "submission_banned.html"
else: template = "submission.html"
return render_template(template, v=v, p=post, sort=sort, linked_comment=comment, comment_info=comment_info, render_replies=True)
@@ -163,6 +164,12 @@ def api_comment(v):
marregex = list(re.finditer("^(:!?m\w+:\s*)+$", body))
if len(marregex) == 0: return {"error":"You can only type marseys!"}, 403
+ if v.longpost:
+ if time.time() > v.longpost:
+ v.longpost = None
+ g.db.add(v)
+ elif len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
if not body and not request.files.get('file'): return {"error":"You need to actually write something!"}, 400
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|webp|PNG|JPG|JPEG|GIF|WEBP|9999))', body, re.MULTILINE):
@@ -187,6 +194,8 @@ def api_comment(v):
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', body_html))) > 0: return {"error":"You can only type marseys!"}, 403
+ if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
bans = filter_comment_html(body_html)
if bans:
@@ -203,7 +212,7 @@ def api_comment(v):
).first()
if existing: return {"error": f"You already made that comment: /comment/{existing.id}"}, 409
- if parent.author.any_block_exists(v) and not v.admin_level>=3: return {"error": "You can't reply to users who have blocked you, or users you have blocked."}, 403
+ if parent.author.any_block_exists(v) and v.admin_level < 2: return {"error": "You can't reply to users who have blocked you, or users you have blocked."}, 403
is_bot = request.headers.get("Authorization")
@@ -240,7 +249,7 @@ def api_comment(v):
comment.ban_reason = "AutoJanny"
g.db.add(comment)
ma=ModAction(
- user_id=AUTOJANNY_ACCOUNT,
+ user_id=AUTOJANNY_ID,
target_comment_id=comment.id,
kind="ban_comment",
_note="spam"
@@ -255,7 +264,7 @@ def api_comment(v):
parent_submission=parent_submission,
parent_comment_id=parent_comment_id,
level=level,
- over_18=parent_post.over_18 or request.values.get("over_18","")=="true",
+ over_18=request.host == 'pcmemes.net' and v.id == 1578 or parent_post.over_18 or request.values.get("over_18","")=="true",
is_bot=is_bot,
app_id=v.client.application.id if v.client else None,
body_html=body_html,
@@ -267,7 +276,7 @@ def api_comment(v):
g.db.flush()
for option in options:
- c_option = Comment(author_id=AUTOPOLLER_ACCOUNT,
+ c_option = Comment(author_id=AUTOPOLLER_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
@@ -296,7 +305,7 @@ def api_comment(v):
body_based_html = sanitize(body_md)
- c_based = Comment(author_id=BASEDBOT_ACCOUNT,
+ c_based = Comment(author_id=BASEDBOT_ID,
parent_submission=parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@@ -327,7 +336,7 @@ def api_comment(v):
- c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
+ c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@@ -360,7 +369,7 @@ def api_comment(v):
- c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
+ c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@@ -395,7 +404,7 @@ def api_comment(v):
- c2 = Comment(author_id=LONGPOSTBOT_ACCOUNT,
+ c2 = Comment(author_id=LONGPOSTBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
@@ -405,7 +414,7 @@ def api_comment(v):
g.db.add(c2)
- longpostbot = g.db.query(User).filter_by(id = LONGPOSTBOT_ACCOUNT).first()
+ longpostbot = g.db.query(User).filter_by(id = LONGPOSTBOT_ID).first()
longpostbot.comment_count += 1
longpostbot.coins += 1
g.db.add(longpostbot)
@@ -432,7 +441,7 @@ def api_comment(v):
- c2 = Comment(author_id=ZOZBOT_ACCOUNT,
+ c2 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c.id,
level=level+1,
@@ -458,7 +467,7 @@ def api_comment(v):
- c3 = Comment(author_id=ZOZBOT_ACCOUNT,
+ c3 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c2.id,
level=level+2,
@@ -480,7 +489,7 @@ def api_comment(v):
body_html2 = sanitize(body_md)
- c4 = Comment(author_id=ZOZBOT_ACCOUNT,
+ c4 = Comment(author_id=ZOZBOT_ID,
parent_submission=parent_submission,
parent_comment_id=c3.id,
level=level+3,
@@ -490,7 +499,7 @@ def api_comment(v):
g.db.add(c4)
- zozbot = g.db.query(User).filter_by(id = ZOZBOT_ACCOUNT).first()
+ zozbot = g.db.query(User).filter_by(id = ZOZBOT_ID).first()
zozbot.comment_count += 3
zozbot.coins += 3
g.db.add(zozbot)
@@ -511,7 +520,7 @@ def api_comment(v):
for x in g.db.query(Subscription.user_id).filter_by(submission_id=c.parent_submission).all(): notify_users.add(x[0])
- if parent.author.id != v.id: notify_users.add(parent.author.id)
+ if parent.author.id not in [v.id, BASEDBOT_ID, AUTOJANNY_ID, SNAPPY_ID, LONGPOSTBOT_ID, ZOZBOT_ID, AUTOPOLLER_ID]: notify_users.add(parent.author.id)
soup = BeautifulSoup(body_html, features="html.parser")
mentions = soup.find_all("a", href=re.compile("^/@(\w+)"))
@@ -526,9 +535,11 @@ def api_comment(v):
if user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net':
- if 'aevann' in body_html.lower() and 1 not in notify_users: notify_users.add(1)
- if 'joan' in body_html.lower() and 28 not in notify_users: notify_users.add(28)
- if 'carp' in body_html.lower() and 995 not in notify_users: notify_users.add(995)
+ if ('aevan' in body_html.lower() or 'avean' in body_html.lower()) and 1 not in notify_users: notify_users.add(1)
+ if ('joan' in body_html.lower() or 'pewkie' in body_html.lower()) and 28 not in notify_users: notify_users.add(28)
+ if 'carp' in body_html.lower() and 995 not in notify_users:
+ notify_users.add(995)
+ notify_users.add(541)
if ('idio3' in body_html.lower() or 'idio ' in body_html.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users:
@@ -545,7 +556,7 @@ def api_comment(v):
'notification': {
'title': f'New reply by @{v.username}',
'body': c.body,
- 'deep_link': f'http://{site}{c.permalink}?context=10&read=true#context',
+ 'deep_link': f'http://{site}/comment/{c.id}?context=9&read=true#context',
},
},
},
@@ -606,6 +617,12 @@ def edit_comment(cid, v):
marregex = list(re.finditer("^(:!?m\w+:\s*)+$", body))
if len(marregex) == 0: return {"error":"You can only type marseys!"}, 403
+ if v.longpost:
+ if time.time() > v.longpost:
+ v.longpost = None
+ g.db.add(v)
+ elif len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|webp|PNG|JPG|JPEG|GIF|WEBP|9999))', body, re.MULTILINE):
if "wikipedia" not in i.group(1): body = body.replace(i.group(1), f'})')
body_md = CustomRenderer().render(mistletoe.Document(body))
@@ -613,6 +630,8 @@ def edit_comment(cid, v):
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', body_html))) > 0: return {"error":"You can only type marseys!"}, 403
+ if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
bans = filter_comment_html(body_html)
if bans:
@@ -695,7 +714,7 @@ def edit_comment(cid, v):
- c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
+ c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=c.parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@@ -729,7 +748,7 @@ def edit_comment(cid, v):
- c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
+ c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=c.parent_submission,
distinguish_level=6,
parent_comment_id=c.id,
@@ -767,9 +786,11 @@ def edit_comment(cid, v):
if user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net':
- if 'aevann' in body_html.lower() and 1 not in notify_users: notify_users.add(1)
- if 'joan' in body_html.lower() and 28 not in notify_users: notify_users.add(28)
- if 'carp' in body_html.lower() and 995 not in notify_users: notify_users.add(995)
+ if ('aevan' in body_html.lower() or 'avean' in body_html.lower()) and 1 not in notify_users: notify_users.add(1)
+ if ('joan' in body_html.lower() or 'pewkie' in body_html.lower()) and 28 not in notify_users: notify_users.add(28)
+ if 'carp' in body_html.lower() and 995 not in notify_users:
+ notify_users.add(995)
+ notify_users.add(541)
if ('idio3' in body_html.lower() or 'idio ' in body_html.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users:
@@ -842,16 +863,16 @@ def toggle_pin_comment(cid, v):
if comment.is_pinned:
if comment.is_pinned.startswith("t:"): abort(403)
else:
- if v.admin_level == 6 or comment.is_pinned.endswith(" (OP)"): comment.is_pinned = None
+ if v.admin_level > 1 or comment.is_pinned.endswith(" (OP)"): comment.is_pinned = None
else: abort(403)
else:
- if v.admin_level == 6: comment.is_pinned = v.username
+ if v.admin_level > 1: comment.is_pinned = v.username
else: comment.is_pinned = v.username + " (OP)"
g.db.add(comment)
g.db.flush()
- if v.admin_level == 6:
+ if v.admin_level > 1:
ma=ModAction(
kind="pin_comment" if comment.is_pinned else "unpin_comment",
user_id=v.id,
@@ -861,8 +882,20 @@ def toggle_pin_comment(cid, v):
g.db.commit()
- if comment.is_pinned: return {"message": "Comment pinned!"}
- else: return {"message": "Comment unpinned!"}
+ if comment.is_pinned:
+ if v.id != comment.author_id:
+ message = f"@{v.username} has pinned your [comment]({comment.permalink})!"
+ existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message).first()
+ if not existing: send_notification(comment.author_id, message)
+ g.db.commit()
+ return {"message": "Comment pinned!"}
+ else:
+ if v.id != comment.author_id:
+ message = f"@{v.username} has unpinned your [comment]({comment.permalink})!"
+ existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message).first()
+ if not existing: send_notification(comment.author_id, message)
+ g.db.commit()
+ return {"message": "Comment unpinned!"}
@app.post("/save_comment/")
@@ -878,6 +911,7 @@ def save_comment(cid, v):
if not save:
new_save=SaveRelationship(user_id=v.id, comment_id=comment.id, type=2)
g.db.add(new_save)
+
try: g.db.commit()
except: g.db.rollback()
diff --git a/files/routes/discord.py b/files/routes/discord.py
index 93641efc2..4ffc60f3d 100644
--- a/files/routes/discord.py
+++ b/files/routes/discord.py
@@ -116,7 +116,7 @@ def discord_redirect(v):
if x.status_code in [201, 204]:
- if v.id in [1,7]:
+ if v.admin_level > 2:
add_role(v, "owner")
time.sleep(0.1)
diff --git a/files/routes/front.py b/files/routes/front.py
index e47a8157a..a4107d422 100644
--- a/files/routes/front.py
+++ b/files/routes/front.py
@@ -28,7 +28,7 @@ def notifications(v):
messages = request.values.get('messages', False)
modmail = request.values.get('modmail', False)
posts = request.values.get('posts', False)
- if modmail and v.admin_level == 6:
+ if modmail and v.admin_level > 1:
comments = g.db.query(Comment).filter(Comment.sentto==0).order_by(Comment.created_utc.desc()).offset(25*(page-1)).limit(26).all()
next_exists = (len(comments) > 25)
comments = comments[:25]
@@ -37,7 +37,7 @@ def notifications(v):
next_exists = (len(comments) > 25)
comments = comments[:25]
elif posts:
- notifications = v.notifications.join(Notification.comment).filter(Comment.author_id == AUTOJANNY_ACCOUNT).order_by(Notification.id.desc()).offset(25 * (page - 1)).limit(101).all()
+ notifications = v.notifications.join(Notification.comment).filter(Comment.author_id == AUTOJANNY_ID).order_by(Notification.id.desc()).offset(25 * (page - 1)).limit(101).all()
listing = []
@@ -58,7 +58,7 @@ def notifications(v):
notifications = v.notifications.join(Notification.comment).filter(
Comment.is_banned == False,
Comment.deleted_utc == 0,
- Comment.author_id != AUTOJANNY_ACCOUNT,
+ Comment.author_id != AUTOJANNY_ID,
).order_by(Notification.id.desc()).offset(25 * (page - 1)).limit(26).all()
next_exists = (len(notifications) > 25)
@@ -299,7 +299,7 @@ def changeloglist(v=None, sort="new", page=1 ,t="all"):
Submission.author_id.notin_(blocked)
)
- admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level == 6).all()]
+ admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level > 1).all()]
posts = posts.filter(Submission.title.ilike('_changelog%'), Submission.author_id.in_(admins))
if t != 'all':
@@ -364,13 +364,10 @@ def comment_idlist(page=1, v=None, nsfw=False, sort="new", t="all"):
UserBlock.user_id).filter_by(
target_id=v.id).all()]
- comments = comments.filter(
- Comment.author_id.notin_(blocking),
- Comment.author_id.notin_(blocked)
- )
+ comments = comments.filter(Comment.author_id.notin_(blocking), Comment.author_id.notin_(blocked))
- if not v or not v.admin_level >= 3:
- comments = comments.filter_by(is_banned=False).filter(Comment.deleted_utc == 0)
+ if not v or not v.admin_level > 1:
+ comments = comments.filter(Comment.is_banned==False, Comment.deleted_utc == 0)
now = int(time.time())
if t == 'hour':
diff --git a/files/routes/login.py b/files/routes/login.py
index 151484f1a..09de77f32 100644
--- a/files/routes/login.py
+++ b/files/routes/login.py
@@ -27,9 +27,9 @@ def check_for_alts(current_id):
session["history"] = list(past_accs)
for past_id in session["history"]:
-
- if past_id == current_id:
- continue
+
+ if past_id == MOM_ID or current_id == MOM_ID: break
+ if past_id == current_id: continue
check1 = g.db.query(Alt).filter_by(
user1=current_id, user2=past_id).first()
@@ -72,8 +72,6 @@ def check_for_alts(current_id):
g.db.add(new_alt)
g.db.flush()
-# login post procedure
-
@app.post("/login")
@limiter.limit("1/second")
@@ -320,8 +318,8 @@ def sign_up_post(v):
g.db.add(ref_user)
id_1 = g.db.query(User.id).filter_by(id=7).count()
- users_count = g.db.query(User.id).count() #paranoid
- if id_1 == 0 and users_count < 7: admin_level=6
+ users_count = g.db.query(User.id).count()
+ if id_1 == 0 and users_count < 7: admin_level=3
else: admin_level=0
new_user = User(
@@ -332,7 +330,7 @@ def sign_up_post(v):
email=email,
created_utc=int(time.time()),
referred_by=ref_id or None,
- ban_evade = int(any([x.is_banned and not x.unban_utc for x in g.db.query(User).filter(User.id.in_(tuple(session.get("history", [])))).all() if x])),
+ ban_evade = int(any([(x.is_banned or x.shadowbanned) and not x.unban_utc for x in g.db.query(User).filter(User.id.in_(tuple(session.get("history", [])))).all() if x])),
agendaposter = any([x.agendaposter for x in g.db.query(User).filter(User.id.in_(tuple(session.get("history", [])))).all() if x]),
club_banned=any([x.club_banned for x in g.db.query(User).filter(User.id.in_(tuple(session.get("history", [])))).all() if x])
)
diff --git a/files/routes/oauth.py b/files/routes/oauth.py
index d9c8a393e..58fe568d6 100644
--- a/files/routes/oauth.py
+++ b/files/routes/oauth.py
@@ -49,7 +49,7 @@ def request_api_keys(v):
g.db.add(new_app)
- send_admin(NOTIFICATIONS_ACCOUNT, f"{v.username} has requested API keys for `{request.values.get('name')}`. You can approve or deny the request [here](/admin/apps).")
+ send_admin(NOTIFICATIONS_ID, f"{v.username} has requested API keys for `{request.values.get('name')}`. You can approve or deny the request [here](/admin/apps).")
g.db.commit()
@@ -101,7 +101,7 @@ def edit_oauth_app(v, aid):
@app.post("/admin/app/approve/")
@limiter.limit("1/second")
-@admin_level_required(3)
+@admin_level_required(2)
@validate_formkey
def admin_app_approve(v, aid):
@@ -136,7 +136,7 @@ def admin_app_approve(v, aid):
@app.post("/admin/app/revoke/")
@limiter.limit("1/second")
-@admin_level_required(3)
+@admin_level_required(2)
@validate_formkey
def admin_app_revoke(v, aid):
@@ -162,7 +162,7 @@ def admin_app_revoke(v, aid):
@app.post("/admin/app/reject/")
@limiter.limit("1/second")
-@admin_level_required(3)
+@admin_level_required(2)
@validate_formkey
def admin_app_reject(v, aid):
@@ -187,7 +187,7 @@ def admin_app_reject(v, aid):
@app.get("/admin/app/")
-@admin_level_required(3)
+@admin_level_required(2)
def admin_app_id(v, aid):
aid=aid
@@ -213,7 +213,7 @@ def admin_app_id(v, aid):
)
@app.get("/admin/app//comments")
-@admin_level_required(3)
+@admin_level_required(2)
def admin_app_id_comments(v, aid):
aid=aid
@@ -242,7 +242,7 @@ def admin_app_id_comments(v, aid):
@app.get("/admin/apps")
-@admin_level_required(3)
+@admin_level_required(2)
def admin_apps_list(v):
apps = g.db.query(OauthApp).all()
diff --git a/files/routes/posts.py b/files/routes/posts.py
index 8bc8fcb4a..9e4cb06fa 100644
--- a/files/routes/posts.py
+++ b/files/routes/posts.py
@@ -68,9 +68,11 @@ def publish(pid, v):
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net':
- if 'aevann' in f'{post.body_html}{post.title}'.lower() and 1 not in notify_users: notify_users.add(1)
- if 'joan' in f'{post.body_html}{post.title}'.lower() and 28 not in notify_users: notify_users.add(28)
- if 'carp' in f'{post.body_html}{post.title}'.lower() and 995 not in notify_users: notify_users.add(995)
+ if ('aevan' in f'{post.body_html}{post.title}'.lower() or 'avean' in f'{post.body_html}{post.title}'.lower()) and 1 not in notify_users: notify_users.add(1)
+ if ('joan' in f'{post.body_html}{post.title}'.lower() or 'pewkie' in f'{post.body_html}{post.title}'.lower()) and 28 not in notify_users: notify_users.add(28)
+ if 'carp' in f'{post.body_html}{post.title}'.lower() and 995 not in notify_users:
+ notify_users.add(995)
+ notify_users.add(541)
if ('idio3' in f'{post.body_html}{post.title}'.lower() or 'idio ' in f'{post.body_html}{post.title}'.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users: send_notification(x, f"@{v.username} has mentioned you: http://{site}{post.permalink}")
@@ -118,7 +120,7 @@ def post_id(pid, anything=None, v=None):
post = get_post(pid, v=v)
- if post.club and not (v and v.paid_dues) or post.private and not (v and (v.id == post.author_id or v.admin_level == 6)): abort(403)
+ if post.club and not (v and v.paid_dues) or post.private and not (v and (v.id == post.author_id or v.admin_level > 1)): abort(403)
if v:
votes = g.db.query(CommentVote).filter_by(user_id=v.id).subquery()
@@ -134,12 +136,12 @@ def post_id(pid, anything=None, v=None):
blocked.c.id,
)
- if not (v and v.shadowbanned) and not (v and v.admin_level == 6):
+ if not (v and v.shadowbanned) and not (v and v.admin_level > 1):
comments = comments.join(User, User.id == Comment.author_id).filter(User.shadowbanned == None)
comments=comments.filter(
Comment.parent_submission == post.id,
- Comment.author_id != AUTOPOLLER_ACCOUNT,
+ Comment.author_id != AUTOPOLLER_ID,
).join(
votes,
votes.c.comment_id == Comment.id,
@@ -176,7 +178,7 @@ def post_id(pid, anything=None, v=None):
post.replies = [x for x in output if x.is_pinned] + [x for x in output if x.level == 1 and not x.is_pinned]
else:
- comments = g.db.query(Comment).join(User, User.id == Comment.author_id).filter(User.shadowbanned == None, Comment.parent_submission == post.id, Comment.author_id != AUTOPOLLER_ACCOUNT)
+ comments = g.db.query(Comment).join(User, User.id == Comment.author_id).filter(User.shadowbanned == None, Comment.parent_submission == post.id, Comment.author_id != AUTOPOLLER_ID)
if sort == "new":
comments = comments.order_by(Comment.created_utc.desc())
@@ -201,7 +203,7 @@ def post_id(pid, anything=None, v=None):
g.db.commit()
if request.headers.get("Authorization"): return post.json
else:
- if post.is_banned and not (v and (v.admin_level >= 3 or post.author_id == v.id)): template = "submission_banned.html"
+ if post.is_banned and not (v and (v.admin_level > 1 or post.author_id == v.id)): template = "submission_banned.html"
else: template = "submission.html"
return render_template(template, v=v, p=post, sort=sort, render_replies=True)
@@ -214,7 +216,7 @@ def edit_post(pid, v):
p = get_post(pid)
- if p.author_id != v.id and not (v.admin_level == 6 and v.id in [1,28,30,995,2513,3333]): abort(403)
+ if p.author_id != v.id and not (v.admin_level > 1 and v.admin_level > 2): abort(403)
title = request.values.get("title", "").strip()
body = request.values.get("body", "").strip()
@@ -232,6 +234,12 @@ def edit_post(pid, v):
marregex = list(re.finditer("^(:!?m\w+:\s*)+$", body))
if len(marregex) == 0: return {"error":"You can only type marseys!"}, 403
+ if v.longpost:
+ if time.time() > v.longpost:
+ v.longpost = None
+ g.db.add(v)
+ elif len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
if title != p.title:
title_html = filter_title(title)
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', title_html))) > 0: return {"error":"You can only type marseys!"}, 403
@@ -255,6 +263,9 @@ def edit_post(pid, v):
p.body = body
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', body_html))) > 0: return {"error":"You can only type marseys!"}, 40
+
+ if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
p.body_html = body_html
if "rama" in request.host and "ivermectin" in body_html.lower():
@@ -271,7 +282,7 @@ def edit_post(pid, v):
body_jannied_html = sanitize(body_md)
- c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
+ c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=p.id,
level=1,
over_18=False,
@@ -303,7 +314,7 @@ def edit_post(pid, v):
body_jannied_html = sanitize(body_md)
- c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
+ c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=p.id,
level=1,
over_18=False,
@@ -332,13 +343,15 @@ def edit_post(pid, v):
message = f"@{v.username} has mentioned you: http://{site}{p.permalink}"
if request.host == 'rdrama.net':
- if 'aevann' in f'{body_html}{title}'.lower() and 1 not in notify_users: notify_users.add(1)
- if 'joan' in f'{body_html}{title}'.lower() and 28 not in notify_users: notify_users.add(28)
- if 'carp' in f'{body_html}{title}'.lower() and 995 not in notify_users: notify_users.add(995)
+ if ('aevan' in f'{body_html}{title}'.lower() or 'avean' in f'{body_html}{title}'.lower()) and 1 not in notify_users: notify_users.add(1)
+ if ('joan' in f'{body_html}{title}'.lower() or 'pewkie' in f'{body_html}{title}'.lower()) and 28 not in notify_users: notify_users.add(28)
+ if 'carp' in f'{body_html}{title}'.lower() and 995 not in notify_users:
+ notify_users.add(995)
+ notify_users.add(541)
if ('idio3' in f'{body_html}{title}'.lower() or 'idio ' in f'{body_html}{title}'.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users:
- existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ACCOUNT, Comment.body == message, Comment.notifiedto == x).first()
+ existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message, Comment.notifiedto == x).first()
if not existing: send_notification(x, message)
@@ -514,8 +527,12 @@ def submit_post(v):
title = request.values.get("title", "").strip()
url = request.values.get("url", "").strip()
title_html = filter_title(title)
+ body = request.values.get("body", "").strip()
+
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', title_html))) > 0: return {"error":"You can only type marseys!"}, 40
+ if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
if url:
if "/i.imgur.com/" in url: url = url.replace(".png", ".webp").replace(".jpg", ".webp").replace(".jpeg", ".webp")
elif "/media.giphy.com/" in url or "/c.tenor.com/" in url: url = url.replace(".gif", ".webp")
@@ -560,13 +577,12 @@ def submit_post(v):
try: embed = requests.get("https://publish.twitter.com/oembed", timeout=5, params={"url":url, "omit_script":"t"}).json()["html"]
except: embed = None
elif "youtu" in domain:
- try:
- yt_id = re.match(re.compile("^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|shorts\/|\&v=)([^#\&\?]*).*"), url).group(2)
- params = parse_qs(urlparse(url).query)
- t = params.get('t', params.get('start', [0]))[0].replace('s','')
- if t: embed = f"https://youtube.com/embed/{yt_id}?start={t}"
- else: embed = f"https://youtube.com/embed/{yt_id}"
- except: embed = None
+ yt_id = re.match(re.compile("^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|shorts\/|\&v=)([^#\&\?]*).*"), url).group(2)
+ params = parse_qs(urlparse(url).query)
+ t = params.get('t', params.get('start', [0]))[0]
+ if isinstance(t, str): t = t.replace('s','')
+ if t: embed = f"https://youtube.com/embed/{yt_id}?start={t}"
+ else: embed = f"https://youtube.com/embed/{yt_id}"
elif app.config['SERVER_NAME'] in domain and "/post/" in url and "context" not in url:
id = url.split("/post/")[1]
if "/" in id: id = id.split("/")[0]
@@ -586,8 +602,6 @@ def submit_post(v):
elif len(title) > 500:
if request.headers.get("Authorization"): return {"error": "500 character limit for titles"}, 400
else: render_template("submit.html", v=v, error="500 character limit for titles.", title=title[:500], url=url, body=request.values.get("body", "")), 400
-
- body = request.values.get("body", "").strip()
if v.marseyawarded:
if time.time() > v.marseyawarded:
@@ -600,6 +614,12 @@ def submit_post(v):
marregex = list(re.finditer("^(:!?m\w+:\s*)+$", body))
if len(marregex) == 0: return {"error":"You can only type marseys!"}, 403
+ if v.longpost:
+ if time.time() > v.longpost:
+ v.longpost = None
+ g.db.add(v)
+ elif len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
dup = g.db.query(Submission).filter(
Submission.author_id == v.id,
Submission.deleted_utc == 0,
@@ -650,7 +670,7 @@ def submit_post(v):
post.ban_reason = "AutoJanny"
g.db.add(post)
ma=ModAction(
- user_id=AUTOJANNY_ACCOUNT,
+ user_id=AUTOJANNY_ID,
target_submission_id=post.id,
kind="ban_post",
_note="spam"
@@ -681,6 +701,8 @@ def submit_post(v):
if v.marseyawarded and len(list(re.finditer('>[^<\s+]|[^>\s+]<', body_html))) > 0: return {"error":"You can only type marseys!"}, 400
+ if v.longpost and len(body) < 280: return {"error":"You have to type more than 280 characters!"}, 403
+
if len(body_html) > 20000: return {"error":"Submission body too long!"}, 400
bans = filter_comment_html(body_html)
@@ -698,7 +720,7 @@ def submit_post(v):
private=bool(request.values.get("private","")),
club=club,
author_id=v.id,
- over_18=bool(request.values.get("over_18","")),
+ over_18=request.host == 'pcmemes.net' and v.id == 1578 or bool(request.values.get("over_18","")),
app_id=v.client.application.id if v.client else None,
is_bot = request.headers.get("Authorization"),
url=url,
@@ -713,7 +735,7 @@ def submit_post(v):
g.db.flush()
for option in options:
- c = Comment(author_id=AUTOPOLLER_ACCOUNT,
+ c = Comment(author_id=AUTOPOLLER_ID,
parent_submission=new_post.id,
level=1,
body_html=filter_title(option),
@@ -781,9 +803,11 @@ def submit_post(v):
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
if request.host == 'rdrama.net':
- if 'aevann' in f'{body_html}{title}'.lower() and 1 not in notify_users: notify_users.add(1)
- if 'joan' in f'{body_html}{title}'.lower() and 28 not in notify_users: notify_users.add(28)
- if 'carp' in f'{body_html}{title}'.lower() and 995 not in notify_users: notify_users.add(995)
+ if ('aevan' in f'{body_html}{title}'.lower() or 'avean' in f'{body_html}{title}'.lower()) and 1 not in notify_users: notify_users.add(1)
+ if ('joan' in f'{body_html}{title}'.lower() or 'pewkie' in f'{body_html}{title}'.lower()) and 28 not in notify_users: notify_users.add(28)
+ if 'carp' in f'{body_html}{title}'.lower() and 995 not in notify_users:
+ notify_users.add(995)
+ notify_users.add(541)
if ('idio3' in f'{body_html}{title}'.lower() or 'idio ' in f'{body_html}{title}'.lower()) and 30 not in notify_users: notify_users.add(30)
for x in notify_users: send_notification(x, f"@{v.username} has mentioned you: http://{site}{new_post.permalink}")
@@ -812,7 +836,7 @@ def submit_post(v):
body_jannied_html = sanitize(body_md)
- c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
+ c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=new_post.id,
level=1,
over_18=False,
@@ -846,7 +870,7 @@ def submit_post(v):
- c_jannied = Comment(author_id=AUTOJANNY_ACCOUNT,
+ c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_submission=new_post.id,
level=1,
over_18=False,
@@ -884,7 +908,7 @@ def submit_post(v):
if new_post.url:
if new_post.url.startswith('https://old.reddit.com/r/'):
rev = new_post.url.replace('https://old.reddit.com/', '')
- rev = "* [reveddit.com](https://reveddit.com/{rev})\n"
+ rev = f"* [reveddit.com](https://reveddit.com/{rev})\n"
else: rev = ''
body += f"Snapshots:\n\n{rev}* [archive.org](https://web.archive.org/{new_post.url})\n* [archive.ph](https://archive.ph/?url={quote(new_post.url)}&run=1) (click to archive)\n\n"
gevent.spawn(archiveorg, new_post.url)
@@ -898,7 +922,7 @@ def submit_post(v):
if "Snapshots:\n\n" not in body: body += "Snapshots:\n\n"
body += f'**[{title}]({href})**:\n\n'
- body += f'* [reveddit.com](https://reveddit.com/{href})\n'
+ body += f'* [reveddit.com](https://reveddit.com/{href.replace("https://old.reddit.com/", "")})\n'
body += f'* [archive.org](https://web.archive.org/{href})\n'
body += f'* [archive.ph](https://archive.ph/?url={quote(href)}&run=1) (click to archive)\n\n'
gevent.spawn(archiveorg, href)
@@ -907,7 +931,7 @@ def submit_post(v):
body_html = sanitize(body_md)
if len(body_html) < 20000:
- c = Comment(author_id=SNAPPY_ACCOUNT,
+ c = Comment(author_id=SNAPPY_ID,
distinguish_level=6,
parent_submission=new_post.id,
level=1,
@@ -919,7 +943,7 @@ def submit_post(v):
g.db.add(c)
- snappy = g.db.query(User).filter_by(id = SNAPPY_ACCOUNT).first()
+ snappy = g.db.query(User).filter_by(id = SNAPPY_ID).first()
snappy.comment_count += 1
snappy.coins += 1
g.db.add(snappy)
@@ -936,7 +960,7 @@ def submit_post(v):
cache.delete_memoized(frontlist)
cache.delete_memoized(User.userpagelisting)
- if v.admin_level == 6 and "[changelog]" in new_post.title or "(changelog)" in new_post.title:
+ if v.admin_level > 1 and ("[changelog]" in new_post.title or "(changelog)" in new_post.title):
send_message(f"http://{site}{new_post.permalink}")
cache.delete_memoized(changeloglist)
@@ -991,7 +1015,7 @@ def undelete_post_pid(pid, v):
def toggle_comment_nsfw(cid, v):
comment = g.db.query(Comment).filter_by(id=cid).first()
- if not comment.author_id == v.id and not v.admin_level >= 3: abort(403)
+ if not comment.author_id == v.id and not v.admin_level > 1: abort(403)
comment.over_18 = not comment.over_18
g.db.add(comment)
g.db.flush()
@@ -1008,7 +1032,7 @@ def toggle_post_nsfw(pid, v):
post = get_post(pid)
- if not post.author_id == v.id and not v.admin_level >= 3:
+ if not post.author_id == v.id and not v.admin_level > 1:
abort(403)
post.over_18 = not post.over_18
diff --git a/files/routes/reporting.py b/files/routes/reporting.py
index 12fcc6ee7..d7c9be5af 100644
--- a/files/routes/reporting.py
+++ b/files/routes/reporting.py
@@ -69,13 +69,10 @@ def api_flag_comment(cid, v):
@app.post('/del_report/')
@limiter.limit("1/second")
-@auth_required
+@admin_level_required(2)
@validate_formkey
def remove_report(report_fn, v):
- if v.admin_level < 6:
- return {"error": "go outside"}, 403
-
if report_fn.startswith('c'):
report = g.db.query(CommentFlag).filter_by(id=int(report_fn.lstrip('c'))).first()
elif report_fn.startswith('p'):
diff --git a/files/routes/search.py b/files/routes/search.py
index 44a59ef76..9608b12e4 100644
--- a/files/routes/search.py
+++ b/files/routes/search.py
@@ -59,7 +59,9 @@ def searchposts(v):
posts = g.db.query(Submission.id)
- if not (v and v.admin_level == 6): posts = posts.filter(Submission.private == False)
+ if not (v and v.paid_dues): posts = posts.filter(Submission.club == False)
+
+ if not (v and v.admin_level > 1): posts = posts.filter(Submission.private == False)
if 'q' in criteria:
words=criteria['q'].split()
@@ -90,14 +92,11 @@ def searchposts(v):
)
)
- if not(v and v.admin_level >= 3):
- posts = posts.filter(
- Submission.deleted_utc == 0,
- Submission.is_banned == False,
- )
+ if not (v and v.admin_level > 1):
+ posts.filter(Submission.deleted_utc == 0, Submission.is_banned == False)
+ if not (v and v.eye): posts = posts.join(User, User.id==Submission.author_id).filter(User.is_private == False)
- if v and v.admin_level >= 4:
- pass
+ if v and v.admin_level > 1: pass
elif v:
blocking = [x[0] for x in g.db.query(
UserBlock.target_id).filter_by(
@@ -193,8 +192,6 @@ def searchcomments(v):
-
-
comments = g.db.query(Comment.id).filter(Comment.parent_submission != None)
if 'q' in criteria:
@@ -207,10 +204,8 @@ def searchcomments(v):
if 'author' in criteria: comments = comments.filter(Comment.author_id == get_user(criteria['author']).id)
- if not(v and v.admin_level >= 3):
- comments = comments.filter(
- Comment.deleted_utc == 0,
- Comment.is_banned == False)
+ if not(v and v.admin_level > 1):
+ comments = comments.join(User, User.id==Comment.author_id).filter(User.is_private == False, Comment.deleted_utc == 0, Comment.is_banned == False)
if t:
now = int(time.time())
diff --git a/files/routes/settings.py b/files/routes/settings.py
index d1a0183db..e808b9f7a 100644
--- a/files/routes/settings.py
+++ b/files/routes/settings.py
@@ -236,11 +236,11 @@ def settings_profile_post(v):
user = g.db.query(User).filter_by(username=username).first()
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
- if request.host == 'rdrama.net' and 'aevann' in friends_html.lower() and 1 not in notify_users: notify_users.add(1)
+ if request.host == 'rdrama.net' and ('aevan' in friends_html.lower() or 'avean' in friends_html.lower()) and 1 not in notify_users: notify_users.add(1)
for x in notify_users:
message = f"@{v.username} has added you to their friends list!"
- existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ACCOUNT, Comment.body == message, Comment.notifiedto == x).first()
+ existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message, Comment.notifiedto == x).first()
if not existing: send_notification(x, message)
v.friends = friends[:500]
@@ -281,11 +281,11 @@ def settings_profile_post(v):
user = g.db.query(User).filter_by(username=username).first()
if user and not v.any_block_exists(user) and user.id != v.id: notify_users.add(user.id)
- if request.host == 'rdrama.net' and 'aevann' in enemies_html.lower() and 1 not in notify_users: notify_users.add(1)
+ if request.host == 'rdrama.net' and ('aevan' in enemies_html.lower() or 'avean' in enemies_html.lower()) and 1 not in notify_users: notify_users.add(1)
for x in notify_users:
message = f"@{v.username} has added you to their enemies list!"
- existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ACCOUNT, Comment.body == message, Comment.notifiedto == x).first()
+ existing = g.db.query(Comment.id).filter(Comment.author_id == NOTIFICATIONS_ID, Comment.body == message, Comment.notifiedto == x).first()
if not existing: send_notification(x, message)
v.enemies = enemies[:500]
@@ -793,7 +793,7 @@ def settings_css(v):
@auth_required
def settings_profilecss_get(v):
- if v.truecoins < 1000 and not v.patron and v.admin_level < 6: return f"You must have +1000 {COINS_NAME} or be a patron to set profile css."
+ if v.truecoins < 1000 and not v.patron and v.admin_level == 0 : return f"You must have +1000 {COINS_NAME} or be a patron to set profile css."
return render_template("settings_profilecss.html", v=v)
@app.post("/settings/profilecss")
@@ -825,7 +825,7 @@ def settings_block_user(v):
if v.has_block(user):
return {"error": f"You have already blocked @{user.username}."}, 409
- if user.id == NOTIFICATIONS_ACCOUNT:
+ if user.id == NOTIFICATIONS_ID:
return {"error": "You can't block this user."}, 409
new_block = UserBlock(user_id=v.id,
@@ -908,6 +908,8 @@ def settings_content_get(v):
@validate_formkey
def settings_name_change(v):
+ if v.is_banned and not v.unban_utc: return {"error": "forbidden."}, 403
+
new_name=request.values.get("name").strip()
if new_name==v.username:
diff --git a/files/routes/static.py b/files/routes/static.py
index ce4618e2a..0073bd398 100644
--- a/files/routes/static.py
+++ b/files/routes/static.py
@@ -15,7 +15,7 @@ site_name = environ.get("SITE_NAME").strip()
def static_rules(v):
if not path.exists(f'./{site_name} rules.html'):
- if v and v.admin_level == 6:
+ if v and v.admin_level > 1:
return render_template('norules.html', v=v)
else:
abort(404)
@@ -87,12 +87,12 @@ def cached_chart():
)
today_cutoff = calendar.timegm(midnight_this_morning)
- day = 3600 * 24
+ day = 3600 * 200
day_cutoffs = [today_cutoff - day * i for i in range(days)]
day_cutoffs.insert(0, calendar.timegm(now))
- daily_times = [time.strftime("%d", time.gmtime(day_cutoffs[i + 1])) for i in range(len(day_cutoffs) - 1)][2:][::-1]
+ daily_times = [time.strftime("%d/%m", time.gmtime(day_cutoffs[i + 1])) for i in range(len(day_cutoffs) - 1)][2:][::-1]
daily_signups = [g.db.query(User.id).filter(User.created_utc < day_cutoffs[i], User.created_utc > day_cutoffs[i + 1]).count() for i in range(len(day_cutoffs) - 1)][2:][::-1]
@@ -100,6 +100,8 @@ def cached_chart():
comment_stats = [g.db.query(Comment.id).filter(Comment.created_utc < day_cutoffs[i], Comment.created_utc > day_cutoffs[i + 1],Comment.is_banned == False, Comment.author_id != 1).count() for i in range(len(day_cutoffs) - 1)][2:][::-1]
+ plt.rcParams["figure.figsize"] = (20,20)
+
signup_chart = plt.subplot2grid((20, 4), (0, 0), rowspan=5, colspan=4)
posts_chart = plt.subplot2grid((20, 4), (7, 0), rowspan=5, colspan=4)
comments_chart = plt.subplot2grid((20, 4), (14, 0), rowspan=5, colspan=4)
@@ -163,7 +165,7 @@ def patrons(v):
@app.get("/badmins")
@auth_desired
def admins(v):
- admins = g.db.query(User).filter_by(admin_level=6).order_by(User.coins.desc()).all()
+ admins = g.db.query(User).filter(User.admin_level>1).order_by(User.coins.desc()).all()
return render_template("admins.html", v=v, admins=admins)
@@ -174,7 +176,7 @@ def log(v):
page=int(request.args.get("page",1))
- if v and v.admin_level == 6: actions = g.db.query(ModAction).order_by(ModAction.id.desc()).offset(25 * (page - 1)).limit(26).all()
+ if v and v.admin_level > 1: actions = g.db.query(ModAction).order_by(ModAction.id.desc()).offset(25 * (page - 1)).limit(26).all()
else: actions=g.db.query(ModAction).filter(ModAction.kind!="shadowban", ModAction.kind!="unshadowban", ModAction.kind!="club", ModAction.kind!="unclub", ModAction.kind!="check").order_by(ModAction.id.desc()).offset(25*(page-1)).limit(26).all()
next_exists=len(actions)>25
diff --git a/files/routes/users.py b/files/routes/users.py
index 2f07adada..45a3a6617 100644
--- a/files/routes/users.py
+++ b/files/routes/users.py
@@ -11,13 +11,87 @@ from files.mail import *
from flask import *
from files.__main__ import app, limiter
from pusher_push_notifications import PushNotifications
+from collections import Counter
site = environ.get("DOMAIN").strip()
-beams_client = PushNotifications(
- instance_id=PUSHER_INSTANCE_ID,
- secret_key=PUSHER_KEY,
-)
+beams_client = PushNotifications(instance_id=PUSHER_INSTANCE_ID, secret_key=PUSHER_KEY)
+
+@app.get("/@/upvoters")
+@auth_desired
+def upvoters(v, username):
+ id = get_user(username).id
+
+ votes = g.db.query(Vote.user_id, func.count(Vote.user_id)).join(Submission, Vote.submission_id==Submission.id).filter(Vote.vote_type==1, Submission.author_id==id).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).limit(25).all()
+
+ votes2 = g.db.query(CommentVote.user_id, func.count(CommentVote.user_id)).join(Comment, CommentVote.comment_id==Comment.id).filter(CommentVote.vote_type==1, Comment.author_id==id).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).limit(25).all()
+
+ votes = Counter(dict(votes)) + Counter(dict(votes2))
+
+ users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
+ users2 = []
+ for user in users: users2.append((user, votes[user.id]))
+
+ users = sorted(users2, key=lambda x: x[1], reverse=True)[:25]
+
+ return render_template("voters.html", v=v, users=users, name='Up', name2=f'@{username} biggest simps')
+
+@app.get("/@/downvoters")
+@auth_desired
+def downvoters(v, username):
+ id = get_user(username).id
+
+ votes = g.db.query(Vote.user_id, func.count(Vote.user_id)).join(Submission, Vote.submission_id==Submission.id).filter(Vote.vote_type==-1, Submission.author_id==id).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).limit(25).all()
+
+ votes2 = g.db.query(CommentVote.user_id, func.count(CommentVote.user_id)).join(Comment, CommentVote.comment_id==Comment.id).filter(CommentVote.vote_type==-1, Comment.author_id==id).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).limit(25).all()
+
+ votes = Counter(dict(votes)) + Counter(dict(votes2))
+
+ users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
+ users2 = []
+ for user in users: users2.append((user, votes[user.id]))
+
+ users = sorted(users2, key=lambda x: x[1], reverse=True)[:25]
+
+ return render_template("voters.html", v=v, users=users, name='Down', name2=f'@{username} biggest haters')
+
+@app.get("/@/upvoting")
+@auth_desired
+def upvoting(v, username):
+ id = get_user(username).id
+
+ votes = g.db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote, Vote.submission_id==Submission.id).filter(Vote.vote_type==1, Vote.user_id==id).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).limit(25).all()
+
+ votes2 = g.db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote, CommentVote.comment_id==Comment.id).filter(CommentVote.vote_type==1, CommentVote.user_id==id).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).limit(25).all()
+
+ votes = Counter(dict(votes)) + Counter(dict(votes2))
+
+ users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
+ users2 = []
+ for user in users: users2.append((user, votes[user.id]))
+
+ users = sorted(users2, key=lambda x: x[1], reverse=True)[:25]
+
+ return render_template("voters.html", v=v, users=users, name='Up', name2=f'Who @{username} simps for')
+
+@app.get("/@/downvoting")
+@auth_desired
+def downvoting(v, username):
+ id = get_user(username).id
+
+ votes = g.db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote, Vote.submission_id==Submission.id).filter(Vote.vote_type==-1, Vote.user_id==id).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).limit(25).all()
+
+ votes2 = g.db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote, CommentVote.comment_id==Comment.id).filter(CommentVote.vote_type==-1, CommentVote.user_id==id).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).limit(25).all()
+
+ votes = Counter(dict(votes)) + Counter(dict(votes2))
+
+ users = g.db.query(User).filter(User.id.in_(votes.keys())).all()
+ users2 = []
+ for user in users: users2.append((user, votes[user.id]))
+
+ users = sorted(users2, key=lambda x: x[1], reverse=True)[:25]
+
+ return render_template("voters.html", v=v, users=users, name='Down', name2=f'Who @{username} hates')
@app.post("/pay_rent")
@limiter.limit("1/second")
@@ -128,12 +202,29 @@ def transfer_coins(v, username):
if v.coins < amount: return {"error": f"You don't have enough {app.config['COINS_NAME']}"}, 400
if amount < 100: return {"error": f"You have to gift at least 100 {app.config['COINS_NAME']}."}, 400
- tax = math.ceil(amount*0.015)
- tax_receiver = g.db.query(User).filter_by(id=TAX_RECEIVER_ID).first()
- tax_receiver.coins += tax
- log_message = f"[@{v.username}]({v.url}) has transferred {amount} {app.config['COINS_NAME']} to [@{receiver.username}]({receiver.url})"
- send_notification(TAX_RECEIVER_ID, log_message)
- g.db.add(tax_receiver)
+ if not v.patron and not receiver.patron:
+ tax = math.ceil(amount*0.03)
+ tax_receiver = g.db.query(User).filter_by(id=TAX_RECEIVER_ID).first()
+ if request.host == 'rdrama.net': tax_receiver.coins += tax/3
+ else: tax_receiver.coins += tax
+ log_message = f"[@{v.username}]({v.url}) has transferred {amount} {app.config['COINS_NAME']} to [@{receiver.username}]({receiver.url})"
+ send_notification(TAX_RECEIVER_ID, log_message)
+ g.db.add(tax_receiver)
+
+ if request.host == 'rdrama.net':
+ carp = g.db.query(User).filter_by(id=CARP_ID).first()
+ carp.coins += tax/3
+ log_message = f"[@{v.username}]({v.url}) has transferred {amount} {app.config['COINS_NAME']} to [@{receiver.username}]({receiver.url})"
+ send_notification(CARP_ID, log_message)
+ g.db.add(carp)
+
+ dad = g.db.query(User).filter_by(id=DAD_ID).first()
+ dad.coins += tax/3
+ log_message = f"[@{v.username}]({v.url}) has transferred {amount} {app.config['COINS_NAME']} to [@{receiver.username}]({receiver.url})"
+ send_notification(DAD_ID, log_message)
+ g.db.add(dad)
+ else: tax = 0
+
receiver.coins += amount-tax
v.coins -= amount
send_notification(receiver.id, f"🤑 [@{v.username}]({v.url}) has gifted you {amount-tax} {app.config['COINS_NAME']}!")
@@ -422,7 +513,7 @@ def u_username(username, v=None):
g.db.commit()
- if u.is_private and (not v or (v.id != u.id and v.admin_level < 3)):
+ if u.is_private and (not v or (v.id != u.id and v.admin_level < 2 and not v.eye)):
if v and u.id == LLM_ID:
if int(time.time()) - v.rent_utc > 600:
@@ -433,12 +524,12 @@ def u_username(username, v=None):
else: return render_template("userpage_private.html", time=int(time.time()), u=u, v=v)
- if hasattr(u, 'is_blocking') and u.is_blocking and (not v or v.admin_level < 3):
+ if hasattr(u, 'is_blocking') and u.is_blocking and (not v or v.admin_level < 2):
if request.headers.get("Authorization"): return {"error": f"You are blocking @{u.username}."}
else: return render_template("userpage_blocking.html", u=u, v=v)
- if hasattr(u, 'is_blocked') and u.is_blocked and (not v or v.admin_level < 3):
+ if hasattr(u, 'is_blocked') and u.is_blocked and (not v or v.admin_level < 2):
if request.headers.get("Authorization"): return {"error": "This person is blocking you."}
else: return render_template("userpage_blocked.html", u=u, v=v)
@@ -515,7 +606,7 @@ def u_username_comments(username, v=None):
v=v)
- if u.is_private and (not v or (v.id != u.id and v.admin_level < 3)):
+ if u.is_private and (not v or (v.id != u.id and v.admin_level < 2 and not v.eye)):
if v and u.id == LLM_ID:
if int(time.time()) - v.rent_utc > 600:
if request.headers.get("Authorization"): return {"error": "That userpage is private"}
@@ -524,13 +615,13 @@ def u_username_comments(username, v=None):
if request.headers.get("Authorization"): return {"error": "That userpage is private"}
else: return render_template("userpage_private.html", time=int(time.time()), u=u, v=v)
- if hasattr(u, 'is_blocking') and u.is_blocking and (not v or v.admin_level < 3):
+ if hasattr(u, 'is_blocking') and u.is_blocking and (not v or v.admin_level < 2):
if request.headers.get("Authorization"): return {"error": f"You are blocking @{u.username}."}
else: return render_template("userpage_blocking.html",
u=u,
v=v)
- if hasattr(u, 'is_blocked') and u.is_blocked and (not v or v.admin_level < 3):
+ if hasattr(u, 'is_blocked') and u.is_blocked and (not v or v.admin_level < 2):
if request.headers.get("Authorization"): return {"error": "This person is blocking you."}
else: return render_template("userpage_blocked.html",
u=u,
@@ -738,3 +829,22 @@ def saved_comments(v, username):
page=page,
next_exists=next_exists,
standalone=True)
+
+
+@app.post("/fp/")
+@auth_required
+def fp(v, fp):
+ if v.username != fp:
+ v.fp = fp
+ users = g.db.query(User).filter(User.fp == fp, User.id != v.id).all()
+ for u in users:
+ li = [v.id, u.id]
+ existing = g.db.query(Alt).filter(Alt.user1.in_(li), Alt.user2.in_(li)).first()
+ if existing: continue
+ new_alt = Alt(user1=v.id, user2=u.id)
+ g.db.add(new_alt)
+ g.db.flush()
+ print(v.username + ' + ' + u.username)
+ g.db.add(v)
+ g.db.commit()
+ return ''
\ No newline at end of file
diff --git a/files/routes/votes.py b/files/routes/votes.py
index dcb4a4680..bc3f59e3c 100644
--- a/files/routes/votes.py
+++ b/files/routes/votes.py
@@ -22,6 +22,8 @@ def admin_vote_info_get(v):
else: abort(400)
except: abort(400)
+ if thing.author.shadowbanned and not (v and v.admin_level): return render_template('errors/500.html', v=v), 500
+
if isinstance(thing, Submission):
ups = g.db.query(Vote
@@ -61,6 +63,8 @@ def admin_vote_info_get(v):
@validate_formkey
def api_vote_post(post_id, new, v):
+ if v.is_banned and not v.unban_utc: return {"error": "forbidden."}, 403
+
if new not in ["-1", "0", "1"]: abort(400)
if request.headers.get("Authorization"): abort(403)
@@ -118,6 +122,8 @@ def api_vote_post(post_id, new, v):
@validate_formkey
def api_vote_comment(comment_id, new, v):
+ if v.is_banned and not v.unban_utc: return {"error": "forbidden."}, 403
+
if new not in ["-1", "0", "1"]: abort(400)
if request.headers.get("Authorization"): abort(403)
diff --git a/files/templates/admin/awards.html b/files/templates/admin/awards.html
index ae28df17c..a7c7e159d 100644
--- a/files/templates/admin/awards.html
+++ b/files/templates/admin/awards.html
@@ -63,7 +63,7 @@
- {% if 'rdrama.net' not in request.host or v.id in [1,995,2513] %}
+ {% if 'rdrama.net' not in request.host or v.admin_level > 2 %}
-
@@ -77,7 +72,7 @@
@media (min-width: 767.98px) {
.award-columns {
- column-count: 7 !important;
+ column-count: 8 !important;
}
}
\ No newline at end of file
diff --git a/files/templates/comments.html b/files/templates/comments.html
index 7619c83f7..d580b8d26 100644
--- a/files/templates/comments.html
+++ b/files/templates/comments.html
@@ -27,13 +27,13 @@
{% if v %}
{% include "award_modal.html" %}
-
+
{% endif %}
-{% if v and v.admin_level == 6 %}
+{% if v and v.admin_level > 1 %}
{% endif %}
@@ -173,7 +173,7 @@
{% set downs=c.downvotes %}
{% set score=ups-downs %}
-{% if v and (v.shadowbanned or v.admin_level == 6) %}
+{% if v and (v.shadowbanned or v.admin_level > 1) %}
{% set replies=c.replies3 %}
{% else %}
{% set replies=c.replies %}
@@ -215,11 +215,11 @@
{% endfor %}
{% endif %}
{% endif %}
@@ -255,7 +255,7 @@
{% else %}
{{c.post.realtitle(v) | safe}}
{% endif %}
- {% elif c.author_id==NOTIFICATIONS_ACCOUNT or c.author_id==AUTOJANNY_ACCOUNT %}
+ {% elif c.author_id==NOTIFICATIONS_ID or c.author_id==AUTOJANNY_ID %}
{{'SITE_NAME' | app_config}} Notification
{% else %}
{% if c.sentto == 0 %}
@@ -291,7 +291,7 @@
{% endif %}
{% if c.active_flags %}{{c.active_flags}} Reports{% endif %}
{% if c.over_18 %}+18{% endif %}
- {% if v and v.admin_level==6 and c.author.shadowbanned %}{% endif %}
+ {% if v and v.admin_level > 1 and c.author.shadowbanned %}{% endif %}
{% if c.is_pinned %}{% endif %}
{% if c.distinguish_level %}{% endif %}
{% if c.is_op %}{% endif %}
@@ -303,7 +303,7 @@
{% endif %}
{{c.author.username}}
- {% if c.author.customtitle %} {% if c.author.quadrant %}{% endif %}{{c.author.customtitle | safe}}{% endif %}
+ {% if c.author.customtitle %} {% if c.author.quadrant %}{% endif %}{{c.author.customtitle | safe}}{% endif %}
{% if c.parent_comment_id and not standalone and level<=7 %}{{ c.parent_comment.author.username }}{% endif %}
@@ -319,7 +319,7 @@
{% for f in c.ordered_flags %}
-
{{f.user.username}}{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v.admin_level==6 %}[remove]{% endif %}
+
{{f.user.username}}{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v and v.admin_level > 1 %}[remove]{% endif %}
{% endfor %}
@@ -347,7 +347,7 @@
{% endif %}
- {% if not c.parent_submission and c.author_id!=NOTIFICATIONS_ACCOUNT and c.author_id!=AUTOJANNY_ACCOUNT and c.author_id!=v.id %}
+ {% if not c.parent_submission and c.author_id!=NOTIFICATIONS_ID and c.author_id!=AUTOJANNY_ID and c.author_id!=v.id %}
Reply
@@ -443,8 +443,8 @@
Reply
{% endif %}
- Context
- Copy link
+ Context
+ Copy link
{% if v %}
Report
{% endif %}
@@ -461,7 +461,7 @@
{% endif %}
{% endif %}
- {% if v and v.admin_level==6 and v.id==c.author_id %}
+ {% if v and v.admin_level > 1 and v.id==c.author_id %}
UndistinguishDistinguish
{% endif %}
@@ -474,14 +474,14 @@
Block user
{% endif %}
- {% if v and c.post and (v.admin_level >= 1 or v.id == c.post.author_id) and c.level == 1 %}
+ {% if v and c.post and (v.admin_level > 1 or v.id == c.post.author_id) and c.level == 1 %}
UnpinPin
{% endif %}
- {% if v and v.admin_level>=3 %}
+ {% if v and v.admin_level > 1 %}
{% if "/reported/" in request.path %}
ApproveRemove
@@ -496,12 +496,12 @@
Mark +18
{% endif %}
- {% if v and v.admin_level==6 and v.id != c.author_id %}
+ {% if v and v.admin_level > 1 and v.id != c.author_id %}
Unban userBan user
{% endif %}
- {% if v and v.admin_level >=4 and c.oauth_app %}
+ {% if v and v.admin_level > 1 and c.oauth_app %}
API App
{% endif %}
@@ -575,11 +575,11 @@
{% endfor %}
diff --git a/files/templates/submission.html b/files/templates/submission.html
index 81855311c..7f88da0b5 100644
--- a/files/templates/submission.html
+++ b/files/templates/submission.html
@@ -87,26 +87,26 @@
}
-
+
{% endif %}
{% if p.award_count("train") > 1 %}
-
+
{% endif %}
{% if p.award_count("train") > 2 %}
-
+
{% endif %}
{% if p.award_count("train") > 3 %}
-
+
{% endif %}
-{% if v and (v.id == p.author_id or v.admin_level == 6 and v.id in [1,28,30,995,2513,3333]) %}
+{% if v and (v.id == p.author_id or v.admin_level > 1 and v.admin_level > 2) %}
{% if v %}
-
+
{% include "award_modal.html" %}
{% include "emoji_modal.html" %}
{% include "gif_modal.html" %}
- {% if v.admin_level == 6 %}
+ {% if v.admin_level > 1 %}
{% include "ban_modal.html" %}
{% endif %}
{% endif %}
@@ -316,7 +316,7 @@
- {% if v and (v.id==p.author_id or v.admin_level==6 and v.id in [1,28,30,995,2513,3333]) %}
+ {% if v and (v.id==p.author_id or v.admin_level > 1 and v.admin_level > 2) %}
{% endif %}
@@ -351,12 +351,12 @@
- {% if v.admin_level >=3 or v.id == p.author.id and v.paid_dues %}
+ {% if v.admin_level > 1 or v.id == p.author.id and v.paid_dues %}
{% endif %}
- {% if v.admin_level >=3 %}
+ {% if v.admin_level > 1 %}
{% if v==p.author %}
@@ -373,7 +373,7 @@
{% endif %}
{% endif %}
- {% if v.admin_level >=4 and p.oauth_app %}
+ {% if v.admin_level > 1 and p.oauth_app %}
{% endif %}
@@ -387,7 +387,7 @@
{% endif %}
- {% if v and (v.id==p.author_id or v.admin_level>=3) %}
+ {% if v and (v.id==p.author_id or v.admin_level > 1) %}
{% endif %}
@@ -397,7 +397,7 @@
{% endif %}
- {% if v and v.admin_level == 6 and v.id!=p.author_id %}
+ {% if v and v.admin_level > 1 and v.id!=p.author_id %}
{% endif %}
@@ -410,6 +410,11 @@
{% block content %}
+{% if request.host == 'pcmemes.net' %}
+ {% set cc='SPLASH MOUNTAIN' %}
+{% else %}
+ {% set cc='COUNTRY CLUB' %}
+{% endif %}
@@ -436,7 +441,7 @@
{% endfor %}
{% endif %}
- {% if v and v.admin_level==6 and p.author.shadowbanned %}{% endif %}
+ {% if v and v.admin_level > 1 and p.author.shadowbanned %}{% endif %}
{% if p.stickied %}{% endif %}
{% if p.is_pinned %}{% endif %}
{% if p.distinguish_level %} {% endif %}
@@ -446,7 +451,7 @@
{% if p.active_flags %}{{p.active_flags}} Reports{% endif %}
{% if p.author.verified %}
{% endif %}
- {{p.author.username}}{% if p.author.customtitle %} {% if p.author.quadrant %}{% endif %}{{p.author.customtitle | safe}}{% endif %}
+ {{p.author.username}}{% if p.author.customtitle %} {% if p.author.quadrant %}{% endif %}{{p.author.customtitle | safe}}{% endif %}
{{p.age_string}}
({% if p.realurl(v) %}{{p.domain}}{% else %}text post{% endif %})
@@ -459,19 +464,19 @@
{% for f in p.ordered_flags %}
-
{{f.user.username}}{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v.admin_level==6 %}[remove]{% endif %}
+
{{f.user.username}}{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v and v.admin_level > 1 %}[remove]{% endif %}
- {% if p.club %}COUNTRY CLUB{% endif %}
+ {% if p.club %}{{cc}}{% endif %}
{{p.realtitle(v) | safe}}
{% endif %}
@@ -555,7 +560,7 @@
- {% if v and (v.id==p.author_id or v.admin_level==6 and v.id in [1,28,30,995,2513,3333]) and not v.is_suspended %}
+ {% if v and (v.id==p.author_id or v.admin_level > 1 and v.admin_level > 2) and not v.is_suspended %}
@@ -600,7 +605,7 @@
- {% if v and (v.id==p.author_id or v.admin_level==6 and v.id in [1,28,30,995,2513,3333]) %}
+ {% if v and (v.id==p.author_id or v.admin_level > 1 and v.admin_level > 2) %}
Edit
{% endif %}
@@ -639,7 +644,7 @@
Delete
{% endif %}
{% endif %}
- {% if v and v.admin_level>=3 %}
+ {% if v and v.admin_level > 1 %}
PinUnpin
{% if v==p.author %}
@@ -649,12 +654,12 @@
{% endif %}
{% if v %}
- {% if v.admin_level >=3 or v.id == p.author.id and v.paid_dues %}
+ {% if v.admin_level > 1 or v.id == p.author.id and v.paid_dues %}
Mark clubUnmark club
{% endif %}
- {% if v.admin_level >=3 %}
+ {% if v.admin_level > 1 %}
{% if "/reported/" in request.path %}
{% if v.id != p.author.id %}Remove{% endif %}
Approve
@@ -664,12 +669,12 @@
{% endif %}
{% endif %}
- {% if v.id == p.author_id or v.admin_level >= 3 %}
+ {% if v.id == p.author_id or v.admin_level > 1 %}
Mark +18Unmark +18
{% endif %}
- {% if v.admin_level >= 4 and p.oauth_app %}
+ {% if v.admin_level > 1 and p.oauth_app %}
API App
{% endif %}
@@ -686,7 +691,7 @@
Unban user
{% endif %}
- {% if v.admin_level >=3 and v.id!=p.author_id %}
+ {% if v.admin_level > 1 and v.id!=p.author_id %}
Ban userUnban user
{% endif %}
diff --git a/files/templates/submission_banned.html b/files/templates/submission_banned.html
index 3d7145f40..7f591e9e4 100644
--- a/files/templates/submission_banned.html
+++ b/files/templates/submission_banned.html
@@ -19,19 +19,19 @@
{% endblock %}
{% block adminpanel %}
-{% if v.admin_level >=3 %}
+{% if v.admin_level > 1 %}
{% endif %}
-{% if v.admin_level >=3 and v.id==p.author_id %}
+{% if v.admin_level > 1 and v.id==p.author_id %}
{% endif %}
-{% if v.admin_level >=1 and v.admin_level > p.author.admin_level %}
+{% if v.admin_level > 1 and v.admin_level > p.author.admin_level %}
{% if p.is_banned %}
@@ -72,7 +72,7 @@
- {% if v and v.admin_level >=3 and p.body_html %}
+ {% if v and v.admin_level > 1 and p.body_html %}
{{p.body_html | safe}}
diff --git a/files/templates/submission_listing.html b/files/templates/submission_listing.html
index f975c3dc6..dcd4da6ae 100644
--- a/files/templates/submission_listing.html
+++ b/files/templates/submission_listing.html
@@ -32,6 +32,12 @@
})
+{% if request.host == 'pcmemes.net' %}
+ {% set cc='SPLASH MOUNTAIN' %}
+{% else %}
+ {% set cc='COUNTRY CLUB' %}
+{% endif %}
+
{% for p in listing %}
@@ -119,7 +125,7 @@
{% for f in p.ordered_flags %}
-
{{f.user.username}}{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v.admin_level==6 %}[remove]{% endif %}
+
{{f.user.username}}{% if f.reason %}: {{f.reason | safe}}{% endif %} {% if v and v.admin_level > 1 %}[remove]{% endif %}
{% endfor %}
@@ -204,7 +210,7 @@
{% endfor %}
{% endif %}
- {% if v and v.admin_level==6 and p.author.shadowbanned %}{% endif %}
+ {% if v and v.admin_level > 1 and p.author.shadowbanned %}{% endif %}
{% if p.stickied %}{% endif %}
{% if p.distinguish_level %}{% endif %}
{% if p.is_pinned and request.path.startswith('/@') %}{% endif %}
@@ -216,7 +222,7 @@
{% if p.active_flags %}{{p.active_flags}} Reports{% endif %}
{% if p.author.verified %}
{% endif %}
- {{p.author.username}}{% if p.author.customtitle %} {% if p.author.quadrant %}{% endif %}{{p.author.customtitle | safe}}{% endif %}
+ {{p.author.username}}{% if p.author.customtitle %} {% if p.author.quadrant %}{% endif %}{{p.author.customtitle | safe}}{% endif %}
{{p.age_string}}
({% if p.realurl(v) %}{{p.domain}}{% else %}text post{% endif %})
@@ -225,7 +231,7 @@
{{u.coins}}
-
+
{% if u.procoins %}
{{u.procoins}}
-
+
{% endif %}
{% if u.stored_subscriber_count >=1 and not u.is_nofollow %}{{u.stored_subscriber_count}} follower{{'s' if u.stored_subscriber_count != 1 else ''}} {% endif %}
@@ -500,28 +537,28 @@
Get them helpGift {{'COINS_NAME' | app_config}}
- {% if 'pcm' in request.host and v.admin_level == 6 %}
+ {% if 'pcm' in request.host and v.admin_level > 1 %}
{% if u.admin_level == 0 %}
Make admin
- {% elif v.id in [10,1551,1552,1577,1592] %}
+ {% elif v.admin_level > 2 %}
Remove adminRevert admin actions
{% endif %}
{% endif %}
- {% if 'rama' in request.host and v.id in [1,28,30,995,2513,3333] %}
+ {% if 'rama' in request.host and v.admin_level > 2 %}
Make adminRemove adminMake fake adminRemove fake admin
- {% if u.admin_level == 6 %}
+ {% if u.admin_level > 1 %}
Revert admin actions
{% endif %}
{% endif %}
- {% if 'rama' not in request.host and 'pcm' not in request.host and v.admin_level == 6 %}
+ {% if 'rama' not in request.host and 'pcm' not in request.host and v.admin_level > 1 %}
Make adminRemove admin
@@ -642,23 +679,24 @@
{% endif %}
User ID: {{u.id}}
+
Coins spent: {{u.coins_spent}}
{% if v and v.admin_level > 1 %}
+
True score: {{u.truecoins}}
{% if u.is_private %}
User has private mode enabled.
{% endif %}
+ {% endif %}
+ {% if v and (v.admin_level > 1 or v.alt) %}
Alts:
+
+{% endblock %}
\ No newline at end of file
diff --git a/snappy.txt b/snappy.txt
index d1fa6de8a..13925f9e7 100644
--- a/snappy.txt
+++ b/snappy.txt
@@ -2646,11 +2646,6 @@ This has nothing to do with SRD, consider posting your inane, unfunny "meme" pos
Anyone else feel that this guy keeps overstepping his bounds?
{[para]}
-There is more to it than just that at play here. You'll notice fascists (and Nazis) are being placed in the **authoritarian left quadrant**.
-This is a part of the right wing misinformation campaign where they distance themselves from the Nazis by arguing that fascists' and Nazis are actually on the left! Three Arrows did a pretty good video on it a while ago (https://www.youtube.com/watch?v=hUFvG4RpwJI).
-That this particular misinformation campaign would show up on PCM where out Nazis freely self identify with Auth Right... it doesn't make much sense. The whole idea of the misinformation campaign is to placate "moderate conservatives," by assuring them that the "bad people" were "left wing" all along, and it only works if you want to believe it, because the evidence is overwhelming that the Nazis were extreme right, and Nazis and Nazi sympathizers support right wing candidates without fail.
-That said... when your entire identity is "owning the libs"... you'll believe just about anything.
-{[para]}
So I got anal herpes from my wife a little bit ago and it was giving me some great difficulties plugging my good old meth. Luckily my butt hole is sore free at the moment after getting some good old Valtrex from the doctor. Imp it was kinda kinky plugging meth with herpes sores. It was painful but something really turns me on about shoving some shard up the shoot with an active disease.
{[para]}
Maybe AHS needs a new flair for these sort of subs. At their core lies destructive nihilism. We cannot be entirely sure what exactly their ideology is. Everything is hidden behind many layers of irony and postmodernist obscurantism. We can safely assume they're fascists but they will never spell it out. Their main goal isn't to spread a message anyway. Their main goal is to destroy meaningful debate.