Commit Graph

2583 Commits

Author SHA1 Message Date
evazion
51ba56e8a3 Fix #5001: Media assets not searchable through upload records.
Fix this:

  https://danbooru.donmai.us/uploads.json?search[media_assets][md5]=b83daa7f1ae7e4127b1befd32f71ba10

failing with an ActiveRecord::StatementInvalid error.

The bug was that for a `has_many through: ...` association, like
`has_many :media_assets, through: :upload_media_assets`, we weren't
joining on the associated table properly so we ended up generating
invalid SQL.
2022-02-08 19:18:11 -06:00
evazion
21c0d55aa4 Fix #5002: "Urls url has already been taken" when submitting duplicate urls with different capitalization
Fix URLs being normalized after checking for duplicates rather than
before, which meant that URLs that differed in capitalization weren't
detected as duplicates.
2022-02-08 19:15:55 -06:00
evazion
572878fb0d uploads: allow uploading .m4v format videos.
Fix not being able to upload .m4v format videos as reported here:

* https://danbooru.donmai.us/forum_posts/205248
* https://github.com/danbooru/danbooru/issues/3615#issuecomment-1030950924

From https://en.wikipedia.org/wiki/M4V:

  The M4V file format is a video container format developed by Apple and
  is very similar to the MP4 format. The primary difference is that M4V
  files may optionally be protected by DRM copy protection.

This could be a problem if it allows uploading videos that are
unplayable because of DRM.
2022-02-06 21:41:35 -06:00
evazion
7bed81812d Don't show error messages that could contain private information.
Fix a potential exploit where private information could be leaked if
it was contained in the error message of an unexpected exception.

For example, NoMethodError contains a raw dump of the object in the
error message, which could leak private user data if you could force a
User object to raise a NoMethodError.

Fix the error page to only show known-safe error messages from expected
exceptions, not unknown error messages from unexpected exceptions.

API changes:

* JSON errors now have a `message` param. The message will be blank for unknown exceptions.
* XML errors have a new format. This is a breaking change. They now look like this:

    <result>
      <success type="boolean">false</success>
      <error>PaginationExtension::PaginationError</error>
      <message>You cannot go beyond page 5000.</message>
      <backtrace type="array">
        <backtrace>app/logical/pagination_extension.rb:54:in `paginate'</backtrace>
        <backtrace>app/models/application_record.rb:17:in `paginate'</backtrace>
        <backtrace>app/logical/post_query_builder.rb:529:in `paginated_posts'</backtrace>
        <backtrace>app/logical/post_sets/post.rb:95:in `posts'</backtrace>
        <backtrace>app/controllers/posts_controller.rb:22:in `index'</backtrace>
      </backtrace>
    </result>

  instead of like this:

    <result success="false">You cannot go beyond page 5000.</result>
2022-02-06 18:09:54 -06:00
nonamethanks
1c9014a5bb Fix lofter not working with iqdb 2022-02-05 09:43:17 +01:00
evazion
e7744cb6e3 uploads: generate thumbnails in parallel.
Make uploads faster by generating and saving thumbnails in parallel.

We generate each thumbnail in parallel, then send each thumbnail to the
backend image servers in parallel.

Most images have 5 variants: 'preview' (150x150), 180x180, 360x360,
720x720, and 'sample' (850px width). Plus the original file, that's 6
files we have to save. In production we have 2 image servers, so we have
to save each file twice, to 2 remote servers. Doing all this in parallel
should make uploads significantly faster.
2022-02-04 16:20:50 -06:00
evazion
c4852b3486 rails: fix deprecated #to_s(:format) method.
Fix this deprecation:

    Deprecate passing a format to #to_s in favor of #to_formatted_s in
    Array, Range, Date, DateTime, Time, BigDecimal, Float and, Integer.

https://guides.rubyonrails.org/7_0_release_notes.html#active-support-deprecations
2022-02-01 13:19:50 -06:00
evazion
8cdc11a3e1 Fix #4983: Weird result for status:DELETED. 2022-02-01 01:59:09 -06:00
evazion
7435f2e516 Fix #4969: Tag changes made by replacements wipe out edits done at the same time.
Lock the post during replacement to ensure we have the latest version of
the tags and to ensure nobody else can modify the post until after the
replacement is finished.
2022-02-01 01:16:00 -06:00
evazion
60a13fd2d5 Fix #4913: Invalid replacements created if an error is raised during replacement
Perform the replacement in a before_create callback so that it runs in a
transaction and if it fails, the transaction will rollback and the
replacement record won't be created.

Doing the replacement in a transaction isn't great because, for one
thing, it could hold the transaction open a long time, which isn't good
for the database. And two, if the transaction rolls back, the database
changes will be undone, but if the replacement file has already been saved
to disk, then it won't be undone, which could result in a dangling file.
2022-02-01 01:14:41 -06:00
evazion
2bb5ad78fb tests: fix broken tests.
* Fix a bug where creating posts failed if IQDB wasn't configured.
* Fix broken Skeb test caused by changed URL.
* Fix broken IP geolocation tests caused by API returning different data.
* Fix broken post regeneration tests.
2022-01-31 14:17:14 -06:00
evazion
65b7c08e33 post replacements: refactor and fix tests.
* Move replacement tests from test/unit/upload_service_test.rb to
  test/functional/post_replacement_controller_test.rb
* Move UploadService::Replacer to PostReplacementProcessor.
* Fix a minor bug where if you used the API to replace a post with a file,
  the replacement would fail unless you passed an empty string for the
  replacement_url.
2022-01-31 14:17:14 -06:00
evazion
21dcf53dcb uploads: show similar images for disk uploads.
Fix the upload page so that it shows similar images (IQDB matches) for
files uploaded from your computer. Before this only worked for files
uploaded from a source.
2022-01-28 21:07:06 -06:00
evazion
c0730630af uploads: fixup issues causing Rails to fail to boot.
* Fix `UploadService is not a class` error.
* Update list of available job classes (remove UploadPreprocessorDelayedStartJob,
  UploadServiceDelayedStartJob, add ProcessUploadJob).
2022-01-28 04:32:20 -06:00
evazion
abdab7a0a8 uploads: rework upload process.
Rework the upload process so that files are saved to Danbooru first
before the user starts tagging the upload.

The main user-visible change is that you have to select the file first
before you can start tagging it. Saving the file first lets us fix a
number of problems:

* We can check for dupes before the user tags the upload.
* We can perform dupe checks and show preview images for users not using the bookmarklet.
* We can show preview images without having to proxy images through Danbooru.
* We can show previews of videos and ugoira files.
* We can reliably show the filesize and resolution of the image.
* We can let the user save files to upload later.
* We can get rid of a lot of spaghetti code related to preprocessing
  uploads. This was the cause of most weird "md5 confirmation doesn't
  match md5" errors.

(Not all of these are implemented yet.)

Internally, uploading is now a two-step process: first we create an upload
object, then we create a post from the upload. This is how it works:

* The user goes to /uploads/new and chooses a file or pastes an URL into
  the file upload component.
* The file upload component calls `POST /uploads` to create an upload.
* `POST /uploads` immediately returns a new upload object in the `pending` state.
* Danbooru starts processing the upload in a background job (downloading,
  resizing, and transferring the image to the image servers).
* The file upload component polls `/uploads/$id.json`, checking the
  upload `status` until it returns `completed` or `error`.
* When the upload status is `completed`, the user is redirected to /uploads/$id.
* On the /uploads/$id page, the user can tag the upload and submit it.
* The upload form calls `POST /posts` to create a new post from the upload.
* The user is redirected to the new post.

This is the data model:

* An upload represents a set of files uploaded to Danbooru by a user.
  Uploaded files don't have to belong to a post. An upload has an
  uploader, a status (pending, processing, completed, or error), a
  source (unless uploading from a file), and a list of media assets
  (image or video files).

* There is a has-and-belongs-to-many relationship between uploads and
  media assets. An upload can have many media assets, and a media asset
  can belong to multiple uploads. Uploads are joined to media assets
  through a upload_media_assets table.

  An upload could potentially have multiple media assets if it's a Pixiv
  or Twitter gallery. This is not yet implemented (at the moment all
  uploads have one media asset).

  A media asset can belong to multiple uploads if multiple people try
  to upload the same file, or if the same user tries to upload the same
  file more than once.

New features:

* On the upload page, you can press Ctrl+V to paste an URL and immediately upload it.
* You can save files for upload later. Your saved files are at /uploads.

Fixes:

* Improved error messages when uploading invalid files, bad URLs, and
  when forgetting the rating.
2022-01-28 04:13:22 -06:00
evazion
f11c46b4f8 uploads: stop pruning uploads. 2022-01-28 04:13:22 -06:00
GiantFrog
d69256cf75 Fix bug where env variables need to be ints 2022-01-21 16:55:08 -07:00
GiantFrog
b1b706aaff Add configurable upload limits 2022-01-17 13:28:24 -07:00
evazion
acf565be7b Fix #4678: Validate custom CSS.
* Make it an error to add invalid custom CSS to your account.
* Add a fix script to remove custom CSS from all accounts with invalid CSS.
2022-01-15 23:20:49 -06:00
evazion
5bec0aa147 Fix #4629: Tag renames/aliases should also modify pool descriptions. 2022-01-15 20:34:08 -06:00
evazion
33103f6dc4 pools: add ability to search for pools linking to given tag.
Add ability to search for pools linking to a given tag in the pool
description. Example:

    https://danbooru.donmai.us/pools?search[linked_to]=touhou

(This isn't actually exposed in the UI to avoid cluttering the pool
search form with rarely used options.)

Pools with broken links can be found here:

    https://danbooru.donmai.us/dtext_links?search[has_linked_tag]=No&search[has_linked_wiki]=No&search[model_type]=Pool

Lays the groundwork for fixing #4629.
2022-01-15 20:26:30 -06:00
evazion
adc5bbf906 posts: fix paginator not appearing when all posts are hidden.
Fix the paginator not appearing when all posts on the page are hidden,
because of deleted posts, banned artists, censored tags, or non-safe
posts in safe mode. This prevented navigating to the next or previous
page.
2022-01-14 22:07:38 -06:00
evazion
00ebd2e13c Merge pull request #4956 from nonamethanks/fix-skeb
Skeb: fix several issues with the strategy
2022-01-14 22:04:44 -06:00
nonamethanks
33db1a2761 Skeb: fix several issues with the strategy
* Fix fetching of videos
* Fix fetching of original commentary
* Fix images being returned out of order in bookmarklet
2022-01-14 21:24:48 +01:00
evazion
fe18e37566 Fix #4954: BigQuery exports not updating.
Fix BigQuery export jobs failing with:

    Google::Cloud::InvalidArgumentError: required: Bucket is requester pays
    bucket but no user project provided.

Caused by changing the storage bucket to requester pays. The
`user_project` param must be set to true on requester pays buckets to
bill usage to the current project.
2022-01-14 00:12:20 -06:00
evazion
df09bb239b Fix #4906: Trying to replace a sourceless post that matches md5 returns error and doesn't fix source.
Allow replacing a post with itself. Skip uploading the file and just
update the post's source with the given source.
2022-01-11 16:09:14 -06:00
evazion
17fb34922b nijie: fix failure to fetch source data due to change in login system.
Nijie changed their login system so that now there are two cookies that
need to be remembered: NIJIEIJIEID, and nijie_tok.
2022-01-11 15:14:54 -06:00
evazion
1518c3c4be posts: fix search queries not being logged to NewRelic in some cases (#4900)
Fix the /posts index controller not logging the normalized search query
to NewRelic when the search failed, either because of a tag limit error,
a search timeout, or a RSS feed rate limit error.

Also don't log the number of search results when it's an API request or
failed search. This is to avoid doing a potentially slow full post count
when it's not otherwise needed.
2022-01-11 13:39:30 -06:00
evazion
f8768fd6b7 BURs: move the is_banned flag when aliasing artists.
When a banned artist tag is aliased into a nonbanned artist tag, move
the is_banned flag from the old artist entry to the new artist_entry.

Related to #4940. Fixes a case where a banned artist could lose the
banned status when it was moved.
2022-01-11 12:17:56 -06:00
evazion
40d6351249 Fix #4940: DanbooruBot retiring banned_artist implications. 2022-01-11 11:53:35 -06:00
evazion
aedc09f301 bigquery: exclude GoodJob::Job from BigQuery. 2022-01-10 00:12:31 -06:00
evazion
cae6599631 pagination: fix paginator regression caused by Rails 7.
Fix the paginator not detecting the first or last page correctly during
sequential pagination.

Caused by the fact that we fetch one more record than needed to detect
whether we're on the last page, then throw that record away by
overriding Rails' internal `records` method. An upstream refactoring
meant that the `size` method now counts the number of records *after*
the extra record is thrown away, where before it counted *before* the
extra record was thrown away.
2022-01-07 14:24:57 -06:00
evazion
72ea78e697 searchable: replace find_ordered with in_order_of.
Rails 7 added an `in_order_of` method that does what our `find_ordered`
method did before.
2022-01-07 14:24:57 -06:00
evazion
72d5291a27 bigquery: exclude more GoodJobs classes from BigQuery. 2022-01-06 11:13:55 -06:00
evazion
123edc63a1 bigquery: don't dump good_jobs table to bigquery. 2022-01-06 00:41:26 -06:00
evazion
090125e239 Revert "Temp disable dumping favorites table to BigQuery."
This reverts commit 788dcbd87b.
2022-01-04 18:08:54 -06:00
evazion
9000facaf7 Revert "bigquery: temp disable dumping the posts table."
This reverts commit f02b437085.
2022-01-04 18:08:47 -06:00
evazion
82211ba935 jobs: add ability to search jobs on /jobs page.
Add ability to search jobs on the /jobs page by job type or by status.

Fixes #2577 (Search filters for delayed jobs). This wasn't possible
before with DelayedJobs because it stored the job data in a YAML string,
which made it difficult to search jobs by type. GoodJobs stores job data
in a JSON object, which is easier to search in Postgres.
2022-01-04 17:18:36 -06:00
evazion
f4953549ae jobs: switch from DelayedJob to GoodJob.
Switch the ActiveJob backend from DelayedJob to GoodJob. Differences:

* The job worker is run with `bin/good_job start` instead of `bin/delayed_job`.
* Jobs have an 8 hour timeout instead of a 4 hour timeout.
* Jobs don't automatically retry on failure.
* Finishing jobs are preserved and pruned after 7 days.
2022-01-04 13:52:08 -06:00
evazion
751835745b emails: fix email validation regex.
Fix the email validation regex allowing certain invalid emails like `foo@gmail..com`.
2022-01-02 16:08:35 -06:00
evazion
6d7a139ef1 Fix #4946: Don't Add Comments to Posts When Doing Post Replacements. 2021-12-28 11:16:15 -06:00
evazion
0ba6dc9ee5 Fix #4945: Search for an artist by URL throws an exception. 2021-12-18 01:55:29 -06:00
evazion
1c5786d20f posts: remove cropped thumbnails. 2021-12-16 15:58:29 -06:00
evazion
a62ae69740 dtext: fix frozen string error. 2021-12-16 00:56:46 -06:00
evazion
a7dc05ce63 Enable frozen string literals.
Make all string literals immutable by default.
2021-12-14 21:33:27 -06:00
evazion
e04892fb38 posts: use 180x180 thumbnails in place of 150x150 thumbnails.
For small thumbnails, use 180x180 thumbnails scaled down to 150x150.
This is so we can get rid of 150x150 images and just use 180x180 for
both small and medium size thumbnails.

Also fix RSS feeds, XML sitemaps, and Discord embeds to use 360x360
thumbnails instead of 150x150 thumbnails.
2021-12-13 05:23:38 -06:00
evazion
2e9f4dc2f4 controllers: refactor rate limits.
Refactor controllers so that endpoint rate limits are declared locally,
with the endpoint, instead of globally, in a single method in ApplicationController.

This way an endpoint's rate limit is declared in the same file as the
endpoint itself.

This is so we can add fine-grained rate limits for certain GET requests.
Before rate limits were only for non-GET requests.
2021-12-10 01:46:01 -06:00
evazion
52013eac1f posts: use low quality thumbnails when Save-Data header is set.
When the Save-Data HTTP header is present, disable high quality (2x
pixel density) thumbnails. This is normally set when "Data Saver mode"
is enabled on Android, or "Lite mode" is enabled in Chrome.

This setting can also be set using the `save_data` URL param or HTTP
cookie. This is mainly for testing.

The <body> tag has a `current-user-save-data` data attribute that
indicates whether save data mode is on.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Save-Data
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/save-data/#the_save-data_request_header
https://source.android.com/devices/tech/connect/data-saver
2021-12-09 20:08:27 -06:00
evazion
7dbde7bc14 Fix #4933: Don't allow mass update requests if both the antecedent and consequent are single tags 2021-12-09 18:05:14 -06:00
evazion
7976d12cd0 Fix #4930: "Show scores" setting should be preserved
Make "show scores" setting persistent.

The setting is stored in a `post_preview_show_votes` cookie. This means
it's remembered on a per-device basis, but not on a per-account basis.
This is so users without an account can use the setting, and so you can
use different settings on desktop and mobile.

The `view=score` URL param has been replaced by `show_votes=true`. The
`show_votes` URL param overrides the `post_preview_show_votes` cookie.
2021-12-09 15:47:10 -06:00