Commit Graph

2709 Commits

Author SHA1 Message Date
evazion
ec87cffe02 Add Rule34.xxx support. 2022-11-10 00:39:52 -06:00
evazion
0bad53e6ac Add TBIB.org support. 2022-11-09 16:49:20 -06:00
evazion
5b4856273f Add safebooru.org support.
Refactor the Gelbooru source extractor to support Safebooru.org as well.
2022-11-09 15:44:04 -06:00
nonamethanks
35bfcbc3bd Newgrounds: support video uploads 2022-11-09 15:01:28 +01:00
nonamethanks
d7d35cb16f Fanbox: add support for embedded videos
Fixes #5339.
2022-11-09 14:02:48 +01:00
evazion
53d4052387 Merge pull request #5329 from nonamethanks/feat-bilibili
Add bilibili support
2022-11-09 01:17:18 -06:00
evazion
153d5f3e67 moebooru: support md5-based post URLs.
Support URLs like these:

* https://yande.re/post/show?md5=2c95b8975b73744da2bcbed9619c1d59
* https://konachan.com/post/show?md5=955aa45f3b452b415509b47dcc9475ac

This makes scraping images from these sites by md5 easier.
2022-11-08 21:40:16 -06:00
evazion
03a4f1a46e gelbooru: fix exception when fetching data for deleted post.
Fix exceptions when fetching deleted or nonexistent posts from Gelbooru. The Gelbooru API doesn't
return any data for deleted posts.
2022-11-08 15:34:44 -06:00
evazion
174c8e0067 Fix #5335: Queries with "ordfav:<username>" and geometry attributes (e.g. "ratio:", "height:") crashes the api/site.
Fix `Relation passed to #and must be structurally compatible. Incompatible values: [:joins] (ArgumentError)`
exception in `ordfav:evazion ratio:4:3` search. Broken by e849d8f1c.

We were effectively doing this:

    q1 = Post.joins(:favorites, :media_asset).where("favorites.user_id = ?", 52664).order("favorites.id DESC")
    q2 = Post.joins(:media_asset, :favorites).where("ROUND(media_assets.image_width::numeric / media_assets.image_height::numeric, 2) = 1.33")
    q3 = q1.and(q2)

This failed because Rails didn't like the fact that the joins were in a different order when the
queries were `and`-ed together.
2022-11-06 21:13:48 -06:00
evazion
c133866cb7 users: don't allow users to choose reserved names.
Don't allow users to choose names that conflict with search syntax, like `any` or `none`, or names
that impersonate user levels, like `Admin`, `Moderator`, `Anonymous`, etc.
2022-11-06 16:00:07 -06:00
evazion
8bd60e41a1 Fix #4555: Invalidate sessions for deleted users
Fix three exploits that allowed one to keep using their account after it was deleted:

* It was possible to use session cookies from another computer to login after you deleted your account.
* It was possible to use API keys to make API requests after you deleted your account.
* It was possible to request a password reset, delete your account, then use the password reset link
  to change your password and login to your deleted account.
2022-11-06 14:58:08 -06:00
evazion
6f08e1427b users: set is_deleted flag when account is deleted.
* Set the `is_deleted` flag when the user is deleted.
* Return the `is_deleted` flag in the /users.json API.
2022-11-06 13:18:49 -06:00
nonamethanks
0a78a6188d Reddit: support user galleries and embedded images 2022-11-06 15:04:05 +01:00
evazion
b43a913ad7 users: delete more data when user deactivates their account.
* Don't delete the user's favorites unless private favorites are enabled. The general rule is that
  public account activity is kept and private account activity is deleted.
* Delete the user's API keys, forum topics visits, private favgroups, downvotes, and upvotes (if
  privacy is enabled).
* Reset all of the user's account settings to default. This means custom CSS is deleted, where it
  wasn't before.
* Delete everything but the user's name and password asynchronously.
* Don't log the current user out if it's the owner deleting another user's account.
* Fix #5067 (Mod actions sometimes not created for user deletions) by wrapping the deletion process
  in a transaction.
2022-11-06 00:05:18 -05:00
evazion
3ffde5b23d users: move account deletion endpoint to /users/:id/deactivate.
Move the account deletion endpoint from /maintenance/users/deletion to either:

* https://danbooru.donmai.us/users/deactivate
* https://danbooru.donmai.us/users/:id/deactivate

This incidentally allows the Owner-level user to deactivate accounts belonging to other users. This
is meant for things like deactivating inactive accounts with invalid or abusive names. This is
limited to accounts below Gold level for security.
2022-11-05 19:09:56 -05:00
evazion
af9e570419 skeb: parse www.skeb.jp URLs. 2022-11-05 19:09:56 -05:00
evazion
ab08ad24e6 baraag: parse https://baraag.net/web/@{name} URLs. 2022-11-05 19:09:56 -05:00
evazion
fcb68048e3 fanbox: parse https://pixiv.net/fanbox URLs. 2022-11-05 19:09:56 -05:00
evazion
f5b003fc94 furaffinity: parse https://www.furaffinity.net/stats/{name} URLs. 2022-11-05 19:09:56 -05:00
nonamethanks
9f3f302328 Lofter: support another theme
Fixes #5334.
2022-11-06 00:03:15 +01:00
evazion
c1623f3fcc posts: don't remove sound tag from Flash posts.
Fix a bug in 28237e2e0 where editing a Flash post would automatically remove the `sound` tag.
2022-11-05 02:26:11 -05:00
evazion
28237e2e09 posts: automatically tag videos with sound.
Automatically add the `sound` tag if the post has sound. Remove the tag if the post doesn't have sound.

A video is considered to have sound if its peak loudness is greater than -70 dB. The current quietest post
on Danbooru has a peak loudness of -62 dB (post #3470668), but it's possible to have audible sound at
-80 dB or possibly even lower. It's hard to draw a clear line between "silent" and "barely audible".
2022-11-05 01:02:29 -05:00
evazion
4a241ac6b5 media assets: don't round volume levels.
At first we rounded loudness values to 4 decimal places to make them
easier to compare. This meant the lowest level was 0.0001, or -80 dB,
but it's possible for volume levels to go even lower than that.
2022-11-05 00:29:44 -05:00
evazion
e005520ad8 media assets: save audio volume levels in media metadata.
For videos with sound, save information about audio volume levels in the
media asset's metadata. These values are stored:

* FFmpeg:AudioPeakLoudness       The peak loudness of the audio track, from 0.0 (silent) to 1.0 (max volume)
* FFmpeg:AudioAverageLoudness    The average loudness of the audio track, from 0.0 (silent) to 1.0 (max volume).
* FFmpeg:AudioLoudnessRange      The difference between the quietest and loudest sounds in the audio track (in decibels).
* FFmpeg:AudioSilencePercentage  The percentage of the video that is silent (1.0 is completely silent, 0.5 is 50% silence, 0.0 is no silence).

These values are calculated based on the EBU R 128 standard, using the ffmpeg command below:

  ffmpeg -i file.mp4 -af silencedetect=duration=0.05:noise=0.0001,ebur128=metadata=1:peak=true:dualmono=true -f null /dev/null

See the links below for details:

* https://en.wikipedia.org/wiki/EBU_R_128
* https://www.ffmpeg.org/ffmpeg-filters.html#ebur128-1
* https://tech.ebu.ch/loudness
* https://tech.ebu.ch/docs/tech/tech3341.pdf
2022-11-04 18:06:30 -05:00
nonamethanks
fc4d620002 Add bilibili support 2022-11-04 12:11:08 +01:00
evazion
a244ec5a3b Merge pull request #5325 from nonamethanks/feat-reddit
Add reddit support
2022-11-04 02:28:29 -05:00
evazion
5f8fefccaa media assets: fix .webm files not including video/audio bit rates in metadata.
Fix .webm files not including the `FFmpeg:VideoBitRate` and `FFmpeg:AudioBitRate`
fields in the media_metadata table. This was because the .webm format
doesn't include the video or audio bit rates in the metadata, and
ffprobe doesn't calculate them either, so we have to calculate them
ourselves by hand.

Fixup for 523d7afdd.
2022-11-03 21:06:08 -05:00
evazion
3172031caa media assets: track corrupted files in media metadata.
If a media asset is corrupt, include the error message from libvips or
ffmpeg in the "Vips:Error" or "FFmpeg:Error" fields in the media
metadata table.

Corrupt files can't be uploaded nowadays, but they could be in the past,
so we have some old corrupted files that we can't generate thumbnails
for. This lets us mark these files in the metadata so they're findable
with the tag search `exif:Vips:Error`.

Known bug: Vips has a single global error buffer that is shared between
threads and that isn't cleared between operations. So we can't reliably
get the actual error message because it may pick up errors from other
threads, or from previous operations in the same thread.
2022-11-02 20:48:15 -05:00
evazion
19c091d81c dmcas: add rate limit and email validation to DMCA form. 2022-11-02 20:47:22 -05:00
evazion
e849d8f1c2 posts: optimize filetype: searches.
When searching posts by width, height, file size, or file extension, use the
values from the media_assets table rather than the posts table.

This makes filetype: searches faster because the file_ext is indexed on
the media assets table, but not on the posts table.

This paves the way for getting rid of the width, height, file_size, and
file_ext indexes on the posts table in the future. It's wasteful to
index these columns on both the posts table and the media assets table.
2022-11-02 02:03:14 -05:00
evazion
3ecc389995 Fix #5313: Exception in -duration:>0. 2022-11-02 00:03:31 -05:00
evazion
acc511ab7d media assets: fix dimensions of flash files.
Use ExifTool to get the dimensions of Flash files instead of calculating
it ourselves. Avoids copying third-party code.

Fixes a bug where Flash files with fractional dimensions (e.g. 607.6 x 756.6)
had their dimensions rounded down instead of rounded up.

Fixes another bug where Flash files could return negative dimensions.
This happened for two files:

* https://danbooru.donmai.us/media_assets/228662 (-179.2 x -339.2)
* https://danbooru.donmai.us/media_assets/228664 (-179.2 x -339.2)

Now we round these up to 1x1. This is still wrong, but it's less wrong than before.
2022-10-31 17:30:40 -05:00
evazion
2f2c73eebb media assets: fix dimensions of corrupt GIFs.
Fix certain corrupt GIFs returning dimensions of 0x0. This happened
when the GIF was too corrupt for libvips to read. Fixed by using
ExifTool to read the dimensions instead.

Also add validations to ensure that it's not possible to have media
assets with a width or height of 0.
2022-10-31 15:18:02 -05:00
evazion
e6ebc54b6c media assets: include image width, height, and file type in EXIF metadata.
Previously the width, height, and file type fields returned by ExifTool
weren't saved in the media metadata because they were already saved in
the media asset. However, in some cases, it can be useful to compare
ExifTool's version of these fields with our own. This can be useful when
an image is corrupt and libvips can't get the width or height, or when
it's a video and we want to make sure we detected the correct type of video.

script/files/123_refresh_media_metatadata.rb needs to be run after this
to update the metadata.
2022-10-31 15:17:35 -05:00
nonamethanks
e294e1193e Add reddit support 2022-10-31 15:10:27 +01:00
evazion
dfd19f3ad4 media file: fix exception when getting frame count of corrupted gif.
Fix a `gifload: no frames in GIF` error from libvips when trying to read
the frame count for https://danbooru.donmai.us/media_assets/1141668.
2022-10-31 02:27:26 -05:00
evazion
c76e0bd4c1 gelbooru: fix normalization of old image URLs. 2022-10-30 17:26:43 -05:00
evazion
042863b2a6 tests: fix broken tests. 2022-10-30 17:26:42 -05:00
evazion
5456a2ea29 Merge pull request #5306 from nonamethanks/new-roles
Users: add Contributor and Approver user levels
2022-10-30 03:27:18 -05:00
evazion
dab239929a Merge pull request #5314 from eltociear/patch-2
tests: fix typo in application_controller_test.rb
2022-10-28 23:43:36 -05:00
evazion
83ba91425f uploads: fix .mp4 filetype detection.
Fix a bug where MP4 files with major brand "iso4" weren't detected as
MP4, so they couldn't be uploaded.

This switches our MP4 detection code to something very similar to Firefox's
MP4 sniffing algorithm. Ours is slightly wrong because a) we only check
the major_brand, not the minor_brands, and b) we falsely detect certain 3GP
videos as MP4. 3GP is a very similar format to MP4, close enough that it
can be played by Chrome (but not Firefox), but it's technically not MP4
and should not have a .mp4 file extension. We leave it alone because we
have two existing 3GP media assets that were falsely detected as MP4.

https://danbooru.donmai.us/forum_topics/22356
https://github.com/mozilla/gecko-dev/blob/master/toolkit/components/mediasniffer/nsMediaSniffer.cpp#L78
https://mimesniff.spec.whatwg.org/#signature-for-mp4
2022-10-28 03:51:46 -05:00
evazion
6e685cdd42 uploads: disallow more video formats not supported by all browsers.
Disallow uploading videos with 10-bit color or 4:4:4 chroma subsampling.
Neither of these features are supported by Firefox.

Only 8 such videos have been uploaded to Danbooru:

* https://danbooru.donmai.us/media_assets/3070695 (4:4:4)
* https://danbooru.donmai.us/media_assets/3070697 (4:4:4)
* https://danbooru.donmai.us/media_assets/3292518 (4:4:4)
* https://danbooru.donmai.us/media_assets/3358659 (10-bit)
* https://danbooru.donmai.us/media_assets/3358660 (10-bit)
* https://danbooru.donmai.us/media_assets/3730866 (10-bit)
* https://danbooru.donmai.us/media_assets/5056665 (10-bit)
* https://danbooru.donmai.us/media_assets/5479605 (4:4:4)

Note that Exiftool doesn't output this information, so it's not in the
EXIF metadata. We have to reply on ffprobe at upload time instead.

Followup to #3615.
2022-10-28 01:21:34 -05:00
Ikko Ashimine
df88a92fc4 tests: fix typo in application_controller_test.rb
overriden -> overridden
2022-10-27 20:39:26 +09:00
evazion
a9d586e93a Fix #3615: Unsupported video codecs.
Don't allow uploading videos with unsupported video codecs.

The only video codecs we allow for MP4 files are H.264 and VP9. Other
codecs, including H.265 (aka HEVC), MPEG-4 part 2, and AV1, are
disallowed because they're not universally supported by browsers.
Firefox doesn't support H.265 or MPEG-4 part 2, and Safari doesn't
support AV1.

Additionally, don't allow videos with multiple video tracks, multiple
audio tracks, or no video tracks. Multiple video and audio tracks are
disallowed because they're rare and for moderation purposes, we don't
want people hiding content in extra tracks.

These restrictions really only apply to MP4 videos, since WebM files
don't support multiple video or audio tracks and only support a limited
number of codecs (VP8 and VP9 for videos, Vorbis and Opus for audio).

There are currently 22 posts with unsupported video codecs:

* https://danbooru.donmai.us/posts?tags=video+is:mp4+-exif:Track1:CompressorID=avc1+-exif:Track2:CompressorID=avc1+-exif:Track1:CompressorID=vp09+-exif:Track2:CompressorID=vp09 # AVC1 is H.264

There is one post that has multiple audio tracks:

* https://danbooru.donmai.us/posts/2382057
2022-10-27 01:43:33 -05:00
evazion
48ecb80d6b Fix #5230: video upload 500 error (StatementInvalid) & empty error panel on page
Fix StatementInvalid exception when uploading https://files.catbox.moe/vxoe2p.mp4.

This was a result of multiple bugs:

* First, generating thumbnails for the video failed. This was because
  the video uses the AV1 codec, which FFmpeg failed to decode. It failed
  because our version of FFmpeg was built without the `--enable-libdav1d`
  flag, so it uses the builtin AV1 decoder, which apparently can't
  handle this particular video (it spews a bunch of errors about "Failed
  to get pixel format" and "missing sequence header" and "failed to get
  reference frame").

* Because generating the thumbnails failed, an exception was raised. We
  tried to save the error message in the upload_media_assets.error
  field. However, this also failed because the error message was 77kb
  long (it contained the entire output of the ffmpeg command), but the
  `upload_media_assets` table had a btree index on the `error` column,
  which meant the maximum length of the error column was limited to
  ~2.7kb. This lead to a StatementInvalid exception being raised.

* Because the StatementInvalid exception was raised while we were trying
  to set the upload media asset's status to `failed`, the upload was
  left stuck in the `processing` state rather than being set to the
  `failed` state.

* Because the upload was stuck in the `processing` state, the upload
  page would hang forever waiting for the upload to complete.

The fixes are to:

* Build FFmpeg with `--enable-libdav1d` to use libdav1d for decoding AV1
  videos instead of the builtin AV1 decoder.

* Remove the index on the `upload_media_assets.error` column so that
  setting overly long error messages won't fail.

* Catch unexpected exceptions in ProcessUploadMediaAssetJob so we can
  mark uploads as failed, even if `process_upload!` itself fails because
  it raises an unexpected exception inside its own exception handler.

* Check that the video is playable with `MediaFile::Video#is_corrupt?` before
  allowing it to be uploaded. This way we can return a better error
  message if we can't generate thumbnails because the video isn't
  playable. This requires decoding the entire video, so it means uploads
  may take several seconds longer for long videos. It's also a security
  risk in case ffmpeg has any bugs.

* Define `MediaAsset#preview!` as raising an exception on error, so
  it's clear that generating thumbnails can fail. Define `MediaAsset#preview`
  as returning nil on error for when we don't care about the cause of
  the error.
2022-10-26 22:49:55 -05:00
evazion
9c811611c6 media assets: add full variant for .avif and .webp files.
Add a JPEG conversion for .avif and .webp files. The `full` variant is
the .avif or .webp file converted to JPEG format, with the same
resolution as the original file (full resolution).

Known bug: When converting an HDR .avif file to .jpeg, the resulting
image is too bright compared to the original image as rendered by
Firefox or Chrome.
2022-10-26 04:09:59 -05:00
evazion
9e2aff874f tests: fix strategy_should_work to not perform API calls outside of tests.
Fix strategy_should_work to not perform API calls outside of `should`
blocks. This could cause the whole test suite to crash if a source test
raised an unexpected exception.
2022-10-25 22:41:36 -05:00
evazion
acea0d5553 Fix #5065: .webp images upload support
Add ability to upload .webp images.

Animated WebP images aren't supported. This is because they aren't
supported by FFmpeg yet[1], so generating thumbnails and samples for
them would be more complicated than for other formats.

[1]: https://trac.ffmpeg.org/ticket/4907
2022-10-25 22:41:36 -05:00
evazion
df0e9bc4a7 uploads: fix it being possible to upload .mkv files as .webm.
Fix it being possible to upload arbitrary .mkv files and have them
be treated as .webm. This was possible because WebM uses the Matroska
container format, and we only checked for the Matroska header, not that
the file was actually a WebM.

There were only 6 such files in production:

* https://danbooru.donmai.us/posts?tags=exif:Matroska:DocType=matroska
* https://danbooru.donmai.us/posts/5522036
* https://danbooru.donmai.us/posts/4743498
* https://danbooru.donmai.us/posts/3925427
* https://danbooru.donmai.us/posts/3147897
* https://danbooru.donmai.us/posts/2965862
* https://danbooru.donmai.us/posts/2430436

These videos are playable in Chrome, but not in Firefox, since Firefox
doesn't support .mkv files (it supports some, depending on which codecs
are used, but not .mkv files in general).
2022-10-25 19:32:31 -05:00
evazion
6413b9abcd Fix #5312: StatementInvalid Error When Querying the media_assets Attribute of Uploads 2022-10-25 16:48:16 -05:00