Commit Graph

12089 Commits

Author SHA1 Message Date
evazion
cb35bad237 media assets: fix incorrect frame counts for certain .webm files.
Fix calculating incorrect frame counts for certain .webm files. An
example is https://danbooru.donmai.us/media_assets/5968481.

Caused by ffmpeg printing multiple `frame= NNN` lines, and us taking the
first one instead of the last one:

    frame=    1 fps=0.0 q=-0.0 size=N/A time=00:00:00.08 bitrate=N/A speed=2.07x    
[null @ 0x56046ff4e440] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 321 >= 321
    [null @ 0x56046ff4e440] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 321 >= 321
    frame=  395 fps=0.0 q=-0.0 size=N/A time=00:00:06.66 bitrate=N/A speed=12.3x    
frame=  791 fps=759 q=-0.0 size=N/A time=00:00:13.26 bitrate=N/A speed=12.7x    
frame= 1193 fps=772 q=-0.0 size=N/A time=00:00:19.94 bitrate=N/A speed=12.9x    
frame= 1374 fps=780 q=-0.0 Lsize=N/A time=00:00:22.86 bitrate=N/A speed=  13x
    video:719kB audio:4288kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
2022-11-03 22:01:51 -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
c21146f94d media file: fix error when calculating dimensions of corrupt gif.
Fix exception when `MediaFile::Image#dimensions` calls `metadata.width`.
Caused by the `ExifTool::Metadata#merge` method returning a Hash instead
of a new `ExifTool::Metadata` instance.
2022-11-03 04:08:26 -05:00
evazion
523d7afdd1 media assets: save more metadata for videos.
Include the following metadata tags for videos:

* FFmpeg:MajorBrand (e.g. mp42)
* FFmpeg:PixFmt (e.g. yuv420p. Indicates bit depth and color subsampling mode)
* FFmpeg:FrameCount (e.g. total number of frames in the video)
* FFmpeg:VideoCodec (e.g. h264)
* FFmpeg:VideoProfile (e.g. Main)
* FFmpeg:AudioCodec (e.g. AAC)
* FFmpeg:AudioProfile (e.g. LC)
* FFmpeg:AudioLayout (e.g. stereo)
* FFmpeg:AudioBitRate (e.g. 128kb/s)
2022-11-02 21:57:19 -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
NamelessContributor
79a4fcd08a post counts: add search field. 2022-11-02 13:46:46 +01: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
0317ced63a media assets: fix unsafe redirect error in /media_assets/:id/:variant
Fix error when redirecting to image hosted on separate domain.
2022-11-01 18:03:58 -05:00
evazion
69d88568a6 media assets: allow assets to be regenerated.
Add a `MediaAsset#regenerate!` method that regenerates everything about
the asset, including the metadata, thumbnails, IQDB, cached Cloudflare
URLs, and AI tags.

Fixes it so that a) it's possible to regenerate media assets that aren't
attached to posts and b) regenerating a post regenerates everything. Before
it didn't regenerate the metadata, AI tags, or all of the cached URLs.
2022-11-01 17:32:40 -05:00
evazion
d2c520035b media assets: fix regenerating AI tags for flash files.
Fix it so that trying to regenerate AI tags for a Flash file doesn't
fail because Flash files have no image preview.

Also let `MediaFile.open` take a block argument.
2022-11-01 16:30:50 -05:00
evazion
29b3b83c9a github: update github actions versions. 2022-11-01 15:37:58 -05:00
evazion
2d74bc60db github: temp disable ARM build. 2022-11-01 14:53:14 -05:00
evazion
124af2808a docker: upgrade libvips to 8.13.3.
Followup to f9b7811f8. Better fix for #5323. libvips-8.13.3 has been
released so we can use that instead of compiling from HEAD.
2022-11-01 11:26:05 -05:00
evazion
f9b7811f8c Fix #5323: New samples and thumbnails have wrong colors
Caused by a bug in libvips-8.13.2 that was fixed in libvips issue 3027.
See libvips issue 3129 for details.

The fix is to build libvips from master until 8.13.3 is released.
2022-11-01 01:47:22 -05:00
evazion
ad998a8127 media assets: add image redirect routes.
Add URLs that redirect from a media asset to the image:

* https://danbooru.donmai.us/media_assets/6961761/original -> https://cdn.donmai.us/original/2c/4f/2c4ff193b0fc7106e59b2f6696a68a02.jpg
* https://danbooru.donmai.us/media_assets/6961761/sample   -> https://cdn.donmai.us/sample/2c/4f/sample-2c4ff193b0fc7106e59b2f6696a68a02.jpg
* https://danbooru.donmai.us/media_assets/6961761/720x720  -> https://cdn.donmai.us/180x180/2c/4f/2c4ff193b0fc7106e59b2f6696a68a02.webp
* https://danbooru.donmai.us/media_assets/6961761/360x360  -> https://cdn.donmai.us/180x180/2c/4f/2c4ff193b0fc7106e59b2f6696a68a02.jpg
* https://danbooru.donmai.us/media_assets/6961761/180x180  -> https://cdn.donmai.us/180x180/2c/4f/2c4ff193b0fc7106e59b2f6696a68a02.jpg

This is useful if you have a media asset ID and want to get to the image
without looking up the image URL in the API.

This endpoint is rate-limited to 5 requests per second. It's not meant
to be used for things like thumbnail galleries or bulk scraping images.
2022-11-01 01:47:18 -05:00
evazion
b41b67af6c media assets: add dynamically-generated thumbnails (owner-only).
Add ability to dynamically generate thumbnails with:

* https://danbooru.donmai.us/media_assets/6961761.jpg?width=180&height=180

This is currently restricted to the Owner-level user because it's slow.
2022-11-01 01:36:38 -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
2341d8341d posts: fix flagged posts not having red thumbnail borders for approvers. 2022-10-31 02:39:45 -05:00
evazion
27e4ae3d33 script/fixes/123_refresh_media_metadata.rb: don't wrap in transaction.
Don't wrap the metadata refresh script in a transaction because it could
be a very long running operation and it's not good to leave a transaction
open that long.
2022-10-31 02:29:07 -05: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
214a877c3c users: fix typo in contributor/approver migration script.
Fixup for #5306.
2022-10-30 21:19:05 -05:00
evazion
3846584540 mastodon: fix exception when fetching data for deleted posts.
Fix a `OAuth2::Error: Record not found` exception when trying to fetch
source data for a deleted Pawoo or Baraag post.
2022-10-30 17:26:43 -05:00
evazion
c76e0bd4c1 gelbooru: fix normalization of old image URLs. 2022-10-30 17:26:43 -05:00
evazion
30b286a030 Fix #5241: Source extractors not using 60s timeout.
Raise the default HTTP timeout from 10 seconds to 20 seconds.
2022-10-30 17:26:42 -05:00
evazion
042863b2a6 tests: fix broken tests. 2022-10-30 17:26:42 -05:00
evazion
eff82c43d2 emails: fix validation of undeliverable email addresses.
* Fix bug where bogus domains weren't found because we checked for `nil?` instead of `blank?`.
* Fix bug where bogus names weren't found because we used a nonexistent variable in the
  RCPT TO check (`to_address` instead of `address`).
2022-10-30 14:49:12 -05:00
evazion
d65a35d4ae media assets: add fix script to refresh metadata.
Add a script to go through every media asset and check the metadata
(width, height, duration, filesize, md5, EXIF metadata) and update it
if it's changed. This is necessary after upgrading ExifTool because the
metadata it returns may have changed.
2022-10-30 14:49:12 -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
af7c40d98e Merge pull request #5316 from nottalulah/patch-2
uploads: link to the media asset from the upload page
2022-10-28 23:44:07 -05:00
evazion
d9c982fdaa Merge pull request #5315 from nottalulah/patch-1
user actions: fix password change causing empty entry
2022-10-28 23:43:49 -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
Lily
15d749d4c0 uploads: link to the media asset from the upload page
Similar to how there's a link on the post page. For convenience of checking metadata.
2022-10-27 16:50:42 -03:00
Lily
e553381405 user actions: fix password change causing empty entry 2022-10-27 11:44:47 -03:00
Ikko Ashimine
df88a92fc4 tests: fix typo in application_controller_test.rb
overriden -> overridden
2022-10-27 20:39:26 +09:00
evazion
57316dc622 css: fix autoprefixer warning about flex-end. 2022-10-27 04:17:45 -05:00
evazion
36b82f2b35 Fix #5118: has_large in posts API responses is sometimes nil 2022-10-27 04:06:47 -05:00
evazion
7953c2f091 irb: really disable autocomplete.
Fixup for c0afce18b.
2022-10-27 02:56:44 -05:00
evazion
e09f990a60 uploads: raise default max upload limit to 100MB.
The previous upload limit was 50MB, to discourage uploading excessively
large images. But for videos this can be too low, especially for long
videos at high resolutions.

The upload limit really should be around 200MB to allow for a ~10Mbps
bitrate at the maximum upload length of 2:20. However, the maximum
upload limit under Cloudflare is 100MB, so if we raised the upload limit
beyond this, it would only work when uploading a file from a source URL,
not from your computer. To get around this, we would have to put the
upload endpoint outside of Cloudflare, or allow uploading files in
chunks.
2022-10-27 02:33:21 -05: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
33e9e5b3f0 db: apply good_jobs migrations
Apply a couple of migrations from `bin/rails generate good_job:update`.
2022-10-26 04:15:37 -05:00
evazion
f90db34323 Update Ruby gems. 2022-10-26 04:15:37 -05:00
evazion
c0afce18b8 irb: disable autocomplete. 2022-10-26 04:15:37 -05:00