Fixes#321. Due to the extremely large quantity of comments on a
typical Motte post, 'hot' sorting logic underflowed an intermediate
value. Roughly:
|(-1 000 000) * (103 [votes] + 1 + 2723 [comments] / 1)| > 2^31
We resolve this by reducing the coefficient from 1e6 to 1e5, which
reduces precision of intermediate calculations somewhat, and by
dividing #comments by 10 rather than 1, which better matches Motte
user behavior regardless: Users comment much more often than vote.
This buys us two orders of magnitude more headroom before out-of-
bounds. Shouldn't be an issue until the CW thread reaches ~200k
comments.
Moves behavior in api_comment that updates stateful counters and
generates notifications into a function which can also be called
if a filtered comment is approved. Fixes#272.
Incidentally, also fixes#278 by adding another filter to the post
subscribers query during general clean-up/refactoring.
Originally was going to move this function into the Comments model,
since assurances about state (even with side effects) should probably
be made there, but I couldn't find a sane way to untangle the imports.
Resolves root problem of non-admin users seeing comments they shouldn't
by JOINing on the appropriate fields and including them in the WHERE
clause of the query.
In the process, was also able to remove some unperformant queries
that used (potentially extremely long) lists passed to WHERE clauses in
lieu of proper JOINs.
The Slur Replacer feature from rDrama has already been removed, but
the toggle for it in settings remained. A user in Discord pointed out
it was confusing and potentially disconcerting to have a default-on
toggle to 'enable slurs'.
Explicitly exempts admin action routes from rate limiting because
the limits were being hit during normal user behavior.
While verbose, alternatives like grouping admin routes into e.g. a
Flask blueprint to modify their behavior as a collective would have
been a larger refactor than seemed wise at the moment.
Also, some routes that were limited at 1/second were originally set
as such as a makeshift debounce for people double-clicking buttons.
This was discussed and deemed an acceptable risk compared to making
the mod queue more frustrating to go through.
The last places coins were visible to non-admins were in user popovers
and, potentially, via direct access of /@<username>/coins. These have
been removed.
Additionally, there are a number of routes which, despite being removed
from the UI, were still operative and usable. These are disabled
pending possible(?) future uses of coins.
Due to use of Submission.{choices, options, bet_options} in realbody,
generating submission_listings resulted in extremely high volume of
SELECT queries.
In local testing with 6 posts, one of which had a poll with 2 options,
the removal of these calls reduced quantity of queries on the homepage
from 84 to 22.
Given that it was previously decided to remove the polls feature after
a regression while adding comment filtering, the remaining dead code
paths for polls were also removed.
Ports in lightly modified logic from the upstream which tracks active
sessions to provide counters and listings to understand site traffic
in the admin panel.
Given that coins are not visible in many contexts, the conspicuous
appearance of treasure chests (random coin rewards on 1% of comments)
seems out of place. This removes the logic which rewards treasure,
the visible display of treasure, and drops the column containing
treasure information which has already been awarded to at least one
comment on prod.
Using the new assetcache module, we replace (almost) all instances
of `?v=` cachebusting query parameters in Python and in Jinja templates.
The primary exceptions were: user site backgrounds, and some
infrequently changed graphics referenced literally from .js files.
Fixes#221. Provides custom message behavior for the user DM route
and slightly refactors the `@is_not_permabanned` wrapper to not be
deliberately misleading to users.
Recently, unrelated changes led to enabling logging for flask-limiter
accidentally, at which point it was discovered that it wasn't actually
limiting requests due to Limiter.key_func = get_CF not being proper
for either prod (not behind Cloudflare) or localhost (likewise).
We instead use the remote_addr attached directly to the request using
the existing flask-limiter function to do so.
Detailed troubleshooting at:
https://github.com/themotte/rDrama/issues/222#issuecomment-1229489062
In four contexts, Comment.replies(.) was not updated to reflect the
interface changes with comment filtering. This directly caused #170
and #172 (which was a stack trace from the former).
- Updating notifications for DMs (routes/users.py L690)
- Updating notifications for modmail (routes/users.py L729)
- morecomments for logged out users (routes/posts.py L421)
- JSON for API access (classes/comment.py L347)
All four contexts seem to behave correctly after the change. However,
strictly speaking the JSON generation will not include a user's own
filtered or removed comments, though this is hard to remedy without
passing the user object `v` to json_core. Propagating that through the
codebase seems a worse option than leaving it as is.
This change disables multimedia embedding:
- In comments and comments replies.
- In new submissions.
- In comment & submission preview
And it's all toggle-able via an envvar, except for the JS bits,
but I linked those to the github issue, so should be easy to find
in the future.
The way it works is:
- removes markdown image/video syntax,
eg. `` into ``
- changes link text into anchors, eg.
`https://example.org/someimage.jpg` into
`[https://example.org/someimage.jpg](https://example.org/someimage.jpg)`
- removes html img/video/audio tags, eg.
`<img href="https://example.org/someimage.jpg" />` into ``
- when embedding gifs via the giphy modal in "new submission", it will
insert only an anchor to the gif
- when attaching an image, it will upload the image, then add only an
anchor to the post/comment body
I tested this manually, but not sure if I got all the test cases. What I
checked was:
- create comment w/ image/video/audio media using markdown -> success
- create comment reply w/ image/video/audio media using markdown ->
success
- create comment w/ link to img/imgur/youtube/audio -> success
- create comment w/ attachment -> success
- create comment reply w/ attachment -> success
- create comment w/ img/video tag -> success
- create comment reply w/ image/video tag -> success
- create post submission w/ image/video/media using markdown -> success
- create post submission w/ link to img/imgur/youtube/audio -> success
- create post submission w/ attachment -> success
- create post submission w/ giphy gif -> success
Also, updated the formatting page.
Co-authored-by: Ben Rog-Wilhelm <zorba-github@pavlovian.net>
I tried reproducing the issues from #110 but without luck. The
workflow looks a little like this:
- User changes their avatar.
- This triggers a POST request to the profile endpoint.
- User clicks "Log out" from the dropdown menu"
- This triggers the post_toast function in js that makes a POST to
/logout, which clears the user's session. Then, on receipt of the
response, the js calls `location.reload`, which replays the
browser's last action, which in our case is the earlier POST
request to the profile endpoint. This is why the browser asks
whether it's OK to resubmit the data _again_. Agreeing resubmits
the first POST request.
- After `location.reload`, since the user is no longer logged in,
they either get a 405 (from the profile edit page) or a 500 (from
the profile overview page).
This PR then changes the `/logout` endpoint from POST to GET, then
updates the header template to change the "Log out" anchor to simply
link to "/logout" instead of calling any js.
Reasoning behind it:
- logout doesn't modify server-side resources, so it's safe to make it a
GET request.
- Making it a GET prevents the browser from ever displaying the "data
resubmit" warning window.
- The "/logout" endpoint can now simply redirect to the homepage.
It is intentional that the links show up on admin level 2 but aren't usable until admin level 3; I don't know what I want right now and I want to encourage admins to pester me about it.