Commit Graph

11629 Commits

Author SHA1 Message Date
evazion
e5ba6d4afc MediaFile: fix thumbnail dimension calculation.
Calculate the dimensions of thumbnails ourselves instead of letting
libvips calculate them for us. This way we know the exact size of
thumbnails, so we can set the right width and height for <img> tags. If
we let libvips calculate thumbnail sizes for us, then we can't predict
the exact size of thumbnails, because sometimes libvips rounds numbers
differently than us.
2021-12-01 04:45:26 -06:00
evazion
c2e6202da6 Fix #4920: Wrong color for certain samples.
The problem was that we were stripping color profiles from thumbnails,
but we weren't setting `export_profile: "srgb"` to convert images to
sRGB first. This resulted in wrong colors for images with non-sRGB color
profiles, such as Adobe RGB.

The fix is to convert images to sRGB when possible, while leaving CMYK
and greyscale images alone. We leave CMYK images alone because we can't
convert CMYK to sRGB without losing color. We leave greyscale images
alone if they don't have a color profile, that way they stay as
one-channel greyscale (or two-channel greyscale, in case of alpha)
instead of being converted to three-channel sRGB. However, if a
greyscale image has a color profile, then we have to convert to sRGB,
otherwise the colors would be wrong when we strip the profile.

We also have to set the import profile, otherwise images with broken
embedded color profiles won't have a fallback profile and may get
incorrect colors. In this case we also have to be careful, because we
can't specify an sRGB fallback for greyscale or CMYK images.
2021-12-01 04:45:26 -06:00
evazion
c1a37d9577 docker: set MALLOC_ARENA_MAX=2.
Setting MALLOC_ARENA_MAX=2 is claimed to reduce memory bloat caused by
fragmentation. Jemalloc 3.x is also claimed to reduce memory bloat, but
modern distros only ship Jemalloc 5.x, and supposedly only 3.x works.

https://devcenter.heroku.com/articles/tuning-glibc-memory-behavior
https://bugs.ruby-lang.org/issues/14718
https://www.speedshop.co/2017/12/04/malloc-doubles-ruby-memory.html
https://www.joyfulbikeshedding.com/blog/2019-03-14-what-causes-ruby-memory-bloat.html
2021-11-28 22:45:50 -06:00
evazion
9ec93e4dc7 docker: replace libjpeg-turbo with mozjpeg.
Build vips with mozjpeg instead of libjpeg-turbo. Mozjpeg is slower but
has better compression.

https://github.com/mozilla/mozjpeg
https://libjpeg-turbo.org/About/Mozjpeg
https://siipo.la/blog/is-webp-really-better-than-jpeg
https://www.ctrl.blog/entry/webp-avif-comparison.html
http://web.archive.org/web/20151204210024/http://people.mozilla.org/~josh/lossy_compressed_image_study_july_2014/
2021-11-28 17:58:43 -06:00
evazion
2c63fcf081 docker: upgrade Ruby to 3.0.3.
Upgrade bootsnap to 1.9.3 too because Ruby 3.0.3 has a bug that causes
Rails to fail to boot when bootsnap is enabled. Bootsnap 1.9.3 works
around this bug.

Also add libgmp to build with bignum support.
2021-11-28 17:58:43 -06:00
evazion
1e6f57a9ef docker: upgrade libvips to 8.12.1; add .avif support. 2021-11-28 05:20:29 -06:00
evazion
59f8320d91 votes: fix bug with tag scripting in show score mode.
Fix a bug where scores would disappear when applying tag scripts in show
scores mode.
2021-11-28 01:26:09 -06:00
evazion
9591fa1302 votes: fix bug with removing votes multiple times.
Fix an issue where if you tried to remove the same vote multiple times,
nothing would happen.

Specifically, if you upvoted a post in one tab, then opened it in a
second tab, then removed your vote in the first tab, then upvoted it
again in the first tab, then tried to remove your vote again in the
second tab, nothing would happen when removing it in the second tab.

This was because we were removing votes by vote ID, which meant that if
a vote had already been removed, removing it again would do nothing
since it was already deleted.
2021-11-25 23:49:18 -06:00
evazion
8e32f656fa votes: fix division by zero in upvote ratio.
Fix a division by zero when calculating the upvote ratio in the votes tooltip.

This could happen if the post had votes according to the post_votes
table, but didn't have any votes according to the up_score and
down_score. This should never happen, yet it did happen for post 2248039
and post 2959269.
2021-11-25 23:35:09 -06:00
evazion
0baca68a37 search: make order:random truly random; add random:N metatag.
Make the `order:random` metatag truly randomize the search. Add a
`random:N` metatag that returns up to N random posts, like what
`order:random` did before.

`order:random` now returns the entire search in random order. Before it
just returned a pageful of pseudorandom posts. This will be more
accurate for small searches, but slower for large searches. If
`order:random` times out, try `random:N` instead.

The `random:N` metatag returns up to N pseudorandom posts. This is
faster than `order:random` for large searches, but for small searches,
it may return less than N posts, and the randomness may be biased. Some
posts may be more likely than others to appear. N must be between 0 and
200.

Also, `/posts?tags=touhou&random=1` now redirects to `/posts?tags=touhou+random:N`.
Before the `random=1` param acted like a free `order:random` tag; now it
redirects to a `random:N` search, so it counts against your tag limit.
2021-11-25 18:14:34 -06:00
evazion
5dc67613e6 search: optimize username metatags.
Optimize metatag searches involving usernames, including user:,
approver:, appealer:, commenter:, upvoter:, etc.

Do `User.find_by_name` instead of `User.name_matches` because this
fetches the user upfront instead of doing it inside a subquery. Using a
subquery makes the SQL more complicated and leads to worse query plans.
This especially helps searches involving multiple username metatags.
2021-11-25 00:40:53 -06:00
evazion
5ba6014a4e votes: fix username tooltips not appearing inside other tooltips.
Fix a bug where, when hovering over a username inside a tooltip, the
username tooltip wouldn't appear.

May break 0bf5ac73?
2021-11-25 00:02:25 -06:00
evazion
a45e6b5cfe Fix #4931: Add popup voter list for comments.
Show the comment's upvote and downvote count when you hover over a
comment's score. For mods, show the list of voters as well.
2021-11-24 22:18:48 -06:00
evazion
594b46a85d tests: fix broken tests. 2021-11-23 23:18:54 -06:00
evazion
810f0b5d6b favorites: fix empty favorites tooltip.
Fix the favorites tooltip being empty when a post has no favorites.
2021-11-23 23:18:54 -06:00
evazion
353e708538 votes: allow admins to remove post votes.
Allow admins to remove votes on posts. This is for fixing vote abuse.

Votes can be removed by going to the vote list on the /post_votes page,
or by clicking on a post's score, then using the "Remove" option in the
"..." dropdown menu next to the vote.

Votes are soft-deleted - they're marked as deleted in the database, but
not fully deleted. Removed votes are only visible to admins, not to
regular users. When a vote is removed by an admin, it leaves a mod
action.

Technically it's possible to undelete votes, but there's no UI for it.
2021-11-23 23:18:54 -06:00
evazion
692f2848f2 Merge pull request #4929 from nonamethanks/fix-autoban-duration
SpamDetector: raise autoban duration to 100 years.
2021-11-22 20:38:55 -06:00
nonamethanks
524eacf4b9 SpamDetector: raise autoban duration to 100 years.
This is to match the max duration usable by mods in the site.
The previous value of 999_999 seconds only amounted to 11 days.
2021-11-22 18:29:46 +01:00
evazion
f151e93615 votes: fix upvote ratio calculation.
Old posts don't have vote records, so we can't use vote records to
calculate the ratio.
2021-11-21 18:06:41 -06:00
evazion
00befc96f0 /comments: add vote buttons beneath thumbnails on /comments page.
Also fix an N+1 queries problem.
2021-11-21 18:04:52 -06:00
evazion
be5173c8dd votes: add is_deleted flag to post_votes table.
Add an is_deleted flag to post_votes so they can be soft-deleted in the future.
2021-11-21 02:36:30 -06:00
evazion
35c97d0836 mode menu: remove upvote/downvote mode.
Remove the upvote and downvote modes from the post mode menu. These are
unnecessary now since you can use the vote buttons beneath the thumbnails.
2021-11-21 02:36:22 -06:00
evazion
6b9e1181e5 search: optimize ?search[user_name]=... searches.
Optimize searches using the `search[user_name]=...` URL parameter. If
we're not doing a wildcard search, then do a regular user lookup, which
generates better SQL.
2021-11-20 03:19:04 -06:00
evazion
c98af3c85a Merge pull request #4923 from danbooru/feat-member-voting
Allow Members to vote
2021-11-20 02:44:16 -06:00
evazion
eda23c719a votes: fixup various minor issues.
* Add a gap between thumbnails on mobile.
* Adjust CSS for scores and vote buttons.
* Include "Private favorites" as an incentive on the user upgrade page.
* Fix vote buttons not being visible beneath thumbnails on mobile.
* Fix the "Show scores" link not preserving the current page number.
* Fix vote buttons being unintentionally enabled for all thumbnails by default.
* Fix banned and restricted users being able to favorite posts by
  tagging them with `fav:self`.
* Fix search engines being able to crawl /posts?view=score pages.
* Fix broken tests.
2021-11-20 02:40:18 -06:00
evazion
3ae62d08eb favorites: show favlist when hovering over favcount.
Changes:

* Make it so you can click or hover over a post's favorite count to see
  the list of public favorites.
* Remove the "Show »" button next to the favorite count.
* Make the favorites list visible to all users. Before favorites were
  only visible to Gold users.
* Make the /favorites page show the list of all public favorites,
  instead of redirecting to the current user's favorites.
* Add /posts/:id/favorites endpoint.
* Add /users/:id/favorites endpoint.

This is for several reasons:

* To make viewing favorites work the same way as viewing upvotes.
* To make posts load faster for Gold users. Before, we loaded all the
  favorites when viewing a post, even when the user didn't look at them.
  This made pageloads slower for posts that had hundreds or thousands of
  favorites. Now we only load the favlist if the user hovers over the favcount.
* To make the favorite list visible to all users. Before, it wasn't
  visible to non-Gold users, because of the performance issue listed above.
* To make it more obvious that favorites are public by default. Before,
  since regular users could only see the favcount, they may have
  mistakenly believed other users couldn't see their favorites.
2021-11-20 02:40:18 -06:00
evazion
c4ad50bbba Fix #4924: Moderator dashboard shouldn't show a "Promote" link that's unusable by non-moderators
Remove these links entirely.
2021-11-20 02:40:18 -06:00
Lily
4a20014e5c mod dashboard: minor cleanup
* only show the [+] and [-] feedback buttons to gold users
* only show the [promote] button to moderators, and only when targetting users
  builder or below
* don't show either button if the target is the current user
2021-11-20 02:40:18 -06:00
evazion
330a412714 Fix #4924: Moderator dashboard shouldn't show a "Promote" link that's unusable by non-moderators
Remove these links entirely.
2021-11-19 17:38:46 -06:00
evazion
5d55b722a8 Merge pull request #4925 from nottalulah/fix-dashboard
mod dashboard: minor cleanup
2021-11-19 17:34:17 -06:00
Lily
a82bee1b0d mod dashboard: minor cleanup
* only show the [+] and [-] feedback buttons to gold users
* only show the [promote] button to moderators, and only when targetting users
  builder or below
* don't show either button if the target is the current user
2021-11-19 00:30:11 -04:00
evazion
e28da733d7 votes: show vote buttons to logged-out users.
Show upvote and downvote buttons to logged-out users. Clicking them
sends you to the login page.
2021-11-18 04:15:20 -06:00
evazion
bd8672681f votes: add vote buttons beneath thumbnails.
Add upvote and downvote buttons beneath thumbnails on the post index page.

This is disabled by default. To enable it, click the "..." menu in the top
right of the page, then click "Show scores".

This is currently a per-search setting, not an account setting. If you
enable it in one tab, it won't be enabled in other tabs.
2021-11-18 04:15:20 -06:00
evazion
5585d1f7d6 votes: show votes when hovering over post score.
Make it so you can hover over a post's score to see the list of public
upvotes. Also show the upvote count, the downvote count, and the upvote
ratio.
2021-11-18 04:15:20 -06:00
evazion
a9997d0d2b favgroups: make private favgroups a Gold-only option.
Make private favgroups a Gold-only option. This is for consistency with
private favorites and upvotes being Gold-only options.

Existing Members with private favgroups are allowed to keep them, as
long as they don't disable privacy. If they disable it, then they can't
re-enable it again without upgrading to Gold first.
2021-11-18 04:15:20 -06:00
evazion
bc96eb864b votes: make private favorites and upvotes a Gold-only option.
Make private favorites and upvotes a Gold-only account option.

Existing Members with private favorites enabled are allowed to keep it
enabled, as long as they don't disable it. If they disable it, then they
can't re-enable it again without upgrading to Gold first.

This is a Gold-only option to prevent uploaders from creating multiple
accounts to upvote their own posts. If private upvotes were allowed for
Members, then it would be too easy to use fake accounts and private
upvotes to upvote your own posts.
2021-11-18 04:11:51 -06:00
evazion
055e5939b4 votes: allow Members to vote.
* Allow Member-level users to vote.
* Don't allow Banned or Restricted users to create favorites any more.

Banned and Restricted users aren't allowed to upvote or favorite any
more to prevent sockpuppet accounts from upvoting even after they're
banned.
2021-11-16 17:18:47 -06:00
evazion
1a27b1d5eb votes: make upvotes visible to everyone by default.
Make upvotes public the same way favorites are public:

* Rename the "Private favorites" account setting to "Private favorites and upvotes".
* Make upvotes public, unless the user has private upvotes enabled. Note
  that private upvotes are still visible to admins. Downvotes are still
  hidden to everyone except for admins.
* Make https://danbooru.donmai.us/post_votes visible to all users. This
  page shows all public upvotes. Private upvotes and downvotes are only
  visible on the page to admins and to the voter themselves.
* Make votes searchable with the `upvote:username` and `downvote:username`
  metatags. These already existed before, but they were only usable by
  admins and by people searching for their own votes.

Upvotes are public to discourage users from upvoting with multiple
accounts. Upvote abuse is obvious to everyone when upvotes are public.
The other reason is to make upvotes consistent with favorites, which are
already public.
2021-11-16 05:23:54 -06:00
evazion
43c2870664 Fix #4917: Add down_score/up_score orders and metasearches.
Add `upvotes:N`, `downvotes:N`, `order:upvotes`, `order:downvotes`,
`order:upvotes_asc`, `order:downvotes_asc` metatags.

In the API, the field is called up_score / down_score. Here it's called
`upvotes` and `downvotes` because this should be easier to understand
for end users.

Note that internally, `down_score` is negative. A post that matches
`downvotes:>5` will have down_score < -5 internally.
2021-11-16 03:52:38 -06:00
evazion
b561ca49f2 foundation: fix mojibake in artist commentaries.
Fix certain artist commentaries for foundation.app containing scrambled
characters. Apparently caused by the Nokogiri HTML5 parser not handling
UTF-8 input correctly when the encoding isn't explicitly set to UTF-8.
2021-11-15 04:55:48 -06:00
evazion
76ecf6d30b Merge pull request #4921 from nonamethanks/fix-foundation-iqdb
Fix foundation urls not working with iqdb
2021-11-15 03:14:07 -06:00
nonamethanks
41f9fde2e0 Fix foundation urls not working with iqdb 2021-11-15 10:10:49 +01:00
evazion
ab6d9bd0e8 post votes: fix exception when voting on posts using API.
Fix an `undefined method post_vote_url` exception when doing
`POST https://danbooru.donmai.us/posts/1/votes.json`.

Also add the following API endpoints:

* https://danbooru.donmai.us/post_votes/:id.json
* https://danbooru.donmai.us/comment_votes/:id.json
* https://danbooru.donmai.us/forum_post_votes/:id.json

where `:id` is the vote ID, not the post ID.
2021-11-14 20:11:38 -06:00
evazion
afae7aed07 sandbox: fix filesystems not being mounted read-only.
* Fix /proc not being mounted read-only.
* Fix other read-only directories not actually being mounted read-only.
  This was because the mount(2) system call ignores mount flags when
  creating a bind mount. The solution is to bind mount the directory
  first, then remount it as read-only second.

Known bug: submounts still don't get mounted as read-only. That is, if
we're mounting /usr as read-only, and /usr has a submount of /usr/local,
then /usr/local won't get mounted as read-only.
2021-11-14 02:07:34 -06:00
evazion
70d17d4d5d posts: fix incorrect duration shown for certain videos.
Fix thumbnails incorrectly showing a duration of "0:00" when a video had
a duration between 59.5 seconds and 60.0 seconds. This happened because
of incorrect rounding - the seconds value was rounded up, but the
minutes value wasn't.

Examples: https://danbooru.donmai.us/posts?tags=duration:59.5...60.0+status:any
2021-11-13 23:53:04 -06:00
evazion
8cf00cd1a6 Add sandbox for running untrusted code.
Add a Sandbox class for running untrusted external programs like ffmpeg
or exiftool inside a sandbox. This uses Linux namespaces to run the
process in an isolated container, much like a Docker container. Unlike a
Docker container, we can use it to sandbox programs when Danbooru itself
is already running inside a Docker container.

This is also more restrictive than Docker in several ways:

* It has a system call filter that is more restrictive and more
  customizable than Docker's filter by default. Even if the process
  breaks out of the container, the syscall filter will limit what it can
  do, even if it escalates to root.
* It blocks the use of setuid binaries, so the process can't use things
  like sudo to escalate to root inside the sandbox.
* It blocks all network access inside the sandbox by default.
* All files in the container are read-only by default. The sandboxed
  process can only communicate by writing to stdout.

See app/logical/sandbox.rb for more details.

This isn't actually enabled yet. It will be rolled out progressively to
ensure it doesn't break things.
2021-11-13 05:25:10 -06:00
evazion
91587aeb6b robots.txt: block Googlebot from crawling certain useless URLs.
Block Googlebot from crawling certain slow useless URLs. Sometimes
Googlebot tries to crawl old source:<url>, approver:<name>, and
ordfav:<name> searches in bulk, which tends to slow down the site because
things like source:<url> are inherently slow, and because Google spends
hours at a time crawling them in parallel. This is despite the fact that
these links are already marked as nofollow and noindex, and source:<url>
links were removed from posts a long time ago to try to stop Google from
crawling them.
2021-11-12 16:55:37 -06:00
evazion
c68043bf26 docker: add missing libseccomp-dev package.
Fix app/logical/seccomp.rb failing to load because libseccomp.so wasn't
available.
2021-11-12 16:39:45 -06:00
evazion
908df7921f Add Ruby wrapper around libseccomp.
Add a Ruby wrapper library around the libseccomp library. Seccomp is
used to restrict the syscalls a program can make. See comments in
app/logical/seccomp.rb for further details.

This is not used for anything yet. It's simply adding part of the
sandboxing infrastructure for later use.
2021-11-11 09:20:57 -06:00
evazion
3f9a85a828 Rails: send logs to stderr by default, not stdout.
Send all logs to stderr by default instead of stdout. Fixes a problem
where parsing the output of sandboxed commands could fail, because they
could contain Rails log messages in their stdout.

When we run a command in a sandbox, we call fork+exec to run the command
in the background so we can capture its output. If Rails prints
anything to stdout between the fork and exec calls, then it will be
inadvertently captured along with the command's output. This will break
parsing of the command's output. This can happen if warning messages are
printed by Rails while setting up the sandbox between the fork and exec
calls.

Writing to stderr is also more correct, since stdout is buffered by
default, which means logs could potentially be lost if the process dies
unexpectedly before the buffers are flushed. Stderr is unbuffered by
default, which means logs will always be output immediately.
2021-11-11 09:20:57 -06:00