Commit Graph

3215 Commits

Author SHA1 Message Date
evazion
a7dc05ce63 Enable frozen string literals.
Make all string literals immutable by default.
2021-12-14 21:33:27 -06:00
evazion
208b618918 tags: remove tag category locks.
Remove the ability to lock a tag's category. Before a moderator could
lock a tag such that only an admin could change the tag's category.

Nowadays the ability to change a tag's category is based on the tag's
size. Members can change tag categories for tags with up to 50 posts,
and Builders can change categories for tags with up to 1000 posts.
Manually locking tags is not necessary.

We only had a few dozen locked tags, mostly random *_(cosplay) tags or
company name tags. Most of these are holdovers from moderators randomly
locking tags like ten years ago.

The `is_locked` field is still in the database, so it is still returned
by the /tags.json API, even though it is unused.
2021-12-09 13:20:26 -06:00
evazion
c22f7b799b media assets: fix error when generating thumbnails for corrupt files.
Fix an error being raised when trying to generate thumbnails for corrupt
files. If the original image is corrupt, then ignore any errors and let
libvips try to generate a thumbnail as best it can. This will usually
result in an incomplete thumbnail.
2021-12-05 21:46:14 -06:00
evazion
ad49a10147 media assets: fix bug in thumbnail generation.
Fix thumbnail generation throwing a NoMatchingPatternError.
2021-12-05 19:04:17 -06:00
evazion
9cb70fa632 posts: add 720x720 thumbnail size.
This is used to provide higher resolution thumbnails for high pixel
density displays, such as phones or laptops. If your screen has a 2x
pixel density ratio, then 360x360 thumbnails will be rendered at 720x720
resolution.

We use WebP here because it's about 15% smaller than the equivalent
JPEG, and because if a device has a high enough pixel density to use
this, then it probably supports WebP.

720x720 thumbnails average about 36kb in size, compared to 20.35kb for
360x360 thumbnails and 7.55kb for 180x180 thumbnails.
2021-12-05 09:19:29 -06:00
evazion
17537084fe posts: generate 180x180px and 360x360px thumbnails (#4932).
Add two new thumbnail sizes. These new thumbnail sizes are generated on
upload, but not used yet.
2021-12-02 23:42:44 -06:00
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
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
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
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
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
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
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
8f36ebe2b8 Fix #4914: RuntimeError corrupting uploads
Bug: If a media asset got stuck in the 'processing' state during upload,
then it would stay stuck forever and the file couldn't be uploaded again
later.

Fix: Mark stuck assets as failed before raising the "Upload failed"
error. Once the asset is marked as failed, it can be uploaded again
later. Also, only wait for assets to finish processing if they were
uploaded less than 5 minutes ago. If a processing asset is more than 5
minutes old, consider it stuck and mark it as failed immediately.

Assets getting stuck in the processing state is a 'this should never
happen' error. Normally if any kind of exception is raised while
uploading the asset, the asset will be set to the 'failed' state. The
only way an asset can get stuck is if it fails and the exception handler
doesn't run, or the exception handler itself fails. This might happen if
the process is unexpectedly killed, or possibly if the HTTP request
times out and a TimeoutError is raised at an inopportune time. See below
for discussion of issues with Timeout.

[1]: https://vaneyckt.io/posts/the_disaster_that_is_rubys_timeout_method/
[2]: https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
[3]: https://adamhooper.medium.com/in-ruby-dont-use-timeout-77d9d4e5a001
[4]: https://ruby-doc.org/core-3.0.2/Thread.html#method-c-handle_interrupt-label-Guarding+from+Timeout-3A-3AError
2021-11-08 18:22:04 -06:00
evazion
a5f589f9e0 aliases/implications: change automatic retirement rules.
Change the rules for automatically retiring aliases and implications:

* Retire aliases to tags that are empty, or that are for a general or
  artist tag that hasn't received any new posts in the last two years.
* Retire implications from tags that are empty.
* Don't retire aliases or implications for character, copyright, or
  meta tags any more, unless the tags are empty.
2021-11-05 05:46:50 -05:00
evazion
9a9649bee8 BURs: change default order on index page to newest BURs first.
Change the /bulk_update_requests page to show the newest BURs first
instead of pending BURs first. This is more consistent with index pages
on the rest of the site, which normally default to newest first. Fixes
an issue where failed BURs would be shown first forever unless they were
manually approved or rejected.
2021-11-02 04:16:33 -05:00
nonamethanks
060223c9e2 Add Plurk support 2021-11-01 16:21:27 +01:00
evazion
5177a28f2c Merge pull request #4910 from nonamethanks/feat-foundation
Add Foundation support
2021-11-01 05:07:44 -05:00
nonamethanks
043f2fb124 Add Foundation support 2021-11-01 01:39:56 +01:00
evazion
4095d14f2a media assets: fix tagged filenames option.
Fix the `enable_seo_post_urls` config option not being respected. This
option controls whether filenames in image URLs contain the tags. This
option requires URLs rewrites in Nginx to work so it's disabled by
default.
2021-10-29 07:14:21 -05:00
evazion
a607cb1cb1 posts: fix IP leak in /posts.json includes.
This leaks the full post object in the error message, which includes the
uploader's IP:

* https://danbooru.donmai.us/posts/4871548.json?only=updater
2021-10-27 02:36:24 -05:00
evazion
082544ab03 StorageManager: remove Post-specific code.
Refactor StorageManager to remove all image URL generation code. Instead
the image URL generation code lives in MediaAsset.

Now StorageManager is only concerned with how to read and write files to
remote storage backends like S3 or SFTP, not with how image URLs should
be generated. This way the file storage code isn't tightly coupled to
posts, so it can be used to store any kind of file, not just images
belonging to posts.
2021-10-27 00:05:30 -05:00
evazion
afe5095ee6 posts: mark media asset as expunged when post is expunged.
Fix it so that when a post is expunged, the media asset is also marked
as expunged. This way the files will be deleted, but the media asset
will still remain as a record of what was expunged. The media asset will
have the md5, width, height, file ext, and file size of the deleted file.
2021-10-26 02:53:32 -05:00
evazion
f1b5c34b4d posts: show length of videos and animations in thumbnails.
Show the length of videos and animated posts in the thumbnail. The
length is shown the top left corner in MM:SS format. This replaces the
play button icon.

Show a speaker icon instead of a music note icon for posts with sound.

Doing this requires doing `.includes(:media_asset)` in a bunch of
places to avoid N+1 queries when we access the post's duration.
2021-10-25 02:56:55 -05:00
evazion
a9088d8a87 search: fix flag_count:N metatag being broken. 2021-10-24 17:02:38 -05:00
evazion
8d5e0a5b58 replacements: don't delete replaced files.
Don't delete replaced files after 30 days. There are only about 30k
replacements in total, so the cost of keeping replaced files is
negligible. It was also wrong because the media asset wasn't destroyed
too, so there were active media assets with missing files.
2021-10-24 04:35:13 -05:00
evazion
d258790199 uploads: don't delete files of abandoned uploads.
Just leave them. They don't take up that much space and they may be used
in the future if someone else tries to upload the same file.
2021-10-24 04:35:13 -05:00
evazion
f5e7d50dbb media assets: don't destroy ugoira data on destroy.
Don't destroy Pixiv Ugoira frame data when the media asset is destroyed.
This is wrong because when uploads were pruned, it could delete the
frame data of an active post.
2021-10-24 04:35:13 -05:00
evazion
5c7a0f225c media assets: prevent duplicate media assets.
Add a md5 uniqueness constraint on media assets to prevent duplicate
assets from being created. This way we can guarantee that there is one
active media asset per uploaded file.

Also make it so that if two people are uploading the same file at the
same time, the file is processed only once.
2021-10-24 04:35:06 -05:00
evazion
bc506ed1b8 uploads: refactor to simplify ugoira-handling and replacements:
* Make it so replacing a post doesn't generate a dummy upload as a side effect.
* Make it so you can't replace a post with itself (the post should be regenerated instead).
* Refactor uploads and replacements to save the ugoira frame data when
  the MediaAsset is created, not when the post is created. This way it's
  possible to view the ugoira before the post is created.
* Make `download_file!` in the Pixiv source strategy return a MediaFile
  with the ugoira frame data already attached to it, instead of returning it
  in the `data` field then passing it around separately in the `context`
  field of the upload.
2021-10-18 05:18:46 -05:00
evazion
1d034a3223 media assets: move more file-handling logic into MediaAsset.
Move more of the file-handling logic from UploadService and
StorageManager into MediaAsset. This is part of refactoring posts and
uploads to allow multiple images per post.
2021-10-18 00:10:29 -05:00
evazion
e3b836b506 Refactor full-text search to get rid of tsvector columns.
Refactor full-text search on several tables (comments, dmails,
forum_posts, forum_topics, notes, and wiki_pages) to use to_tsvector
expression indexes instead of dedicated tsvector columns. This way
full-text search works the same way across all tables.

API changes:

* Changed /wiki_pages.json?search[body_matches] to match against only
  the body. Before `body_matches` matched against both the title and the body.

* Added /wiki_pages.json?search[title_or_body_matches] to match against
  both the title and the body.

* Fixed /dmails.json?search[message_matches] to match against both the
  title and body when doing a wildcard search. Before a wildcard search
  only matched against the body.

* Added /dmails.json?search[body_matches] to match against only the dmail body.
2021-10-16 07:44:27 -05:00
evazion
300bc6941e newrelic: log with_timeout errors as expected.
Make it so that when a database call inside a `with_timeout` block times
out, the error logged to New Relic is marked as expected. This is so
that expected timeouts, such as timeouts when calculating search counts
or timeouts when generating related tags for the sidebar, don't count
against the error rate.
2021-10-14 23:39:21 -05:00
evazion
e72446463e Fix #4901: Duplicate disapprovals
* Add uniqueness constraint on post_disapprovals (user_id, post_id).
* Add fix script to remove existing duplicates.
2021-10-12 20:22:00 -05:00
evazion
341be51f95 posts: remove unused flag! and approve! methods.
These methods were unused outside of the test suite
2021-10-11 20:05:09 -05:00
evazion
f155023b77 posts: remove unused exception classes. 2021-10-11 18:58:15 -05:00
evazion
7976323f7a wiki pages: change tsvector update trigger to not use test_parser.
Change the wiki_pages tsvector_update_trigger to use
`pg_catalog.english` instead of `public.danbooru`. This changes how wiki
page text is parsed for full-text search to use the standard English
parser instead of test_parser. This is to prepare for dropping
test_parser. Using test_parser here was wrong anyway because it meant
that punctuation wasn't removed from words when indexing wiki pages for
full-text search.
2021-10-11 03:34:47 -05:00
evazion
37a8dc5dbd posts: use string_to_array index for tag searches.
Use the `string_to_array(tag_string, ' ')` index instead of the
`tag_index` for tag searches. The string_to_array index lets us treat
the tag_string as an array for searching purposes. This lets us get rid
of the tag_index column and the test_parser dependency in the future.
2021-10-10 22:00:10 -05:00
evazion
1653392361 posts: stop updating fav_string attribute.
Stop updating the fav_string attribute on posts. The column still exists
on the table, but is no longer used or updated.

Like the pool_string in 7d503f08, the fav_string was used in the past to
facilitate `fav:X` searches. Posts had a hidden fav_string column that
contained a list of every user who favorited the post. These were
treated like fake hidden tags on the post so that a search for `fav:X`
was treated like a tag search.

The fav_string attribute has been unused for search purposes for a while
now. It was only kept because of technicalities that required
departitioning the favorites table first (340e1008e) before it could be
removed. Basically, removing favorites with `@favorite.destroy` was
slow because Rails always deletes object by ID, but we didn't have an
index on favorites.id, and we couldn't easily add one until the
favorites table was departitioned.

Fixes #4652. See https://github.com/danbooru/danbooru/issues/4652#issuecomment-754993802
for more discussion of issues caused by the fav_string (in short: write
amplification, post table bloat, and favorite inconsistency problems).
2021-10-09 22:36:26 -05:00
evazion
c4a4e77ca5 favorites: order /favorites.json by id.
Order https://danbooru.donmai.us/favorites.json by favorite ID instead
of by post ID. This way you can get a feed of recently added favorites.
Previously this wasn't possible because we didn't have an index on
favorite ID.
2021-10-08 21:26:42 -05:00
evazion
340e1008e9 favorites: merge favorites subtables.
Merge the 100 favorite subtables into a single table.

Previously the favorites table was partitioned by user id into 100
subtables to try to make searching by user id faster. This wasn't really
necessary and probably slower than just making an index on
(favorites.user_id, favorites.id) to satisfy ordfav searches. BTree
indexes are logarithmic so dividing an index by 100 doesn't make it 100
times faster to search; instead it just removes a layer or two from the
tree.

This also adds a uniqueness index on (user_id, post_id) to prevent
duplicate favorites. Previously we had to check for duplicates at the
application layer, which required careful locking to do it correctly.

Finally, this adds an index on favorites.id, which was surprisingly
missing before. This made ordering and deleting favorites by id really
slow because it degraded to a sequential scan.
2021-10-08 21:26:42 -05:00
evazion
73acc16271 Merge pull request #4898 from nonamethanks/feat-meme-tag
Autotag the meme tag on posts with *_(meme) tags
2021-10-08 05:49:17 -05:00
evazion
7fa23c5fbf users: give all users unlimited favorites.
Let all users have unlimited favorites. Formerly the limit was 10k
favorites for regular members, 20k for Gold, and unlimited for Platinum.

Limiting favorites doesn't make sense since upvotes are unlimited.
2021-10-07 06:27:09 -05:00
evazion
7d503f088e posts: stop using pool_string attribute.
Stop using the pool_string attribute on posts:

* Stop updating it when adding or removing posts from pools.
* Stop returning pool_string in the /posts.json API.
* Stop including the `data-pools` attribute on thumbnails.

The pool_string attribute was used in the past to facilitate pool:X
searches. Posts had a hidden pool_string attribute that contained a list
of every pool the post belonged to. These pools were treated like fake
hidden tags on the post and a search for `pool:X` was treated like a tag
search.

The pool_string has no longer been used for this purpose for a long time
now, and was only maintained for API compatibility purposes. Getting rid
of it eliminates a bunch of legacy cruft relating to adding and removing
posts from pools.

If you need to see which pools a post belongs to, do this:

* https://danbooru.donmai.us/pools.json?search[post_ids_include_any]=318550

The `data-pools` attribute on thumbnails was used by some people to add
custom borders to pooled posts with custom CSS. This will no longer
work. This was already broken because it included things like collection
pools and deleted pools, which you probably didn't want. Use a
userscript to add this attribute back to thumbnails if you need it.
2021-10-07 05:55:43 -05:00
evazion
0731b07d27 posts: store duration of animations and videos.
Start storing the duration of animations and videos in the `duration`
field on the media_assets table. This had to wait until 3d30bfd69 was
deployed, which had to wait until Postgres was upgraded in order to add
the duration column to the media_assets table without downtime.

Also add a fix script to backfill the duration on existing posts. Usage:

    TAGS=animated ./script/fixes/079_fix_duration.rb
2021-10-07 03:21:08 -05:00
nonamethanks
d6daec8918 Autotag the meme tag on posts with *_(meme) tags 2021-10-06 18:06:46 +02:00
evazion
f6a6289c8d posts: autoremove tagme on posts with >30 tags.
If you're able to add 30 tags then you don't need to tag it tagme.
2021-10-06 08:08:52 -05:00
evazion
c99d0523bb /media_assets: add basic index and show pages.
* Add a basic index page at https://danbooru.donmai.us/media_assets.
* Add a basic show page at https://danbooru.donmai.us/media_assets/1.
* Add ability to search /media_assets.json by metadata. Example:
** https://danbooru.donmai.us/media_assets.json?search[metadata][File:ColorComponents]=3
* Add a "»" link next to the filesize on posts linking to the metadata page.

Known issues:

* Sometimes the MD5 links on the /media_assets page return "That record
  was not found" errors. These are unfinished uploads that haven't been
  made into posts yet.
* No good way to search for custom metadata fields in the search form.
* Design is ugly.
2021-09-29 07:46:11 -05:00