Commit Graph
100 Commits
Author SHA1 Message Date
evazion 4cb01d5813 docker: set MALLOC_CONF in docker image.
Set the MALLOC_CONF environment variable in the Docker image to tune the
Jemalloc configuration. Configuring Jemalloc to use two memory arenas
reduces memory fragmentation, and using background threads and low decay
times allows freed memory to be returned to the OS sooner.

Previously we set this environment variable at runtime in Kubernetes,
but baking it into the image is simpler.
2022-01-12 17:39:49 -06:00
evazion 5ba71f2a79 Fix #4840: Forum post interface is not updated correctly after deletion.
Re-render and replace the whole forum post with AJAX when a forum post
is deleted or undeleted. This is easier now that forum posts are
componentized.
2022-01-12 12:59:06 -06:00
evazion 7ad24ef231 Fix #4953: Add is_deleted attribute to forum posts.
* Add data-is-deleted, data-updater-id, data-topic-id, and
  data-topic-is-deleted data attributes to forum posts.
* Change data-forum-post-id to data-id.
* Dim deleted forum posts like comments.
2022-01-12 12:48:54 -06:00
evazion c1a1741d20 posts: add z=N URL param to searches and tag lists.
Add a `z=N` param to the URL when doing a search from the search box, or
when clicking a link in the tag list. This is to gather data on how
often the links in the tag list are used, and whether it's more common
to click tags in the tag list or to perform searches manually.

This is temporary and will be removed when enough data is collected.
2022-01-12 10:36:14 -06:00
evazion 7c32b8b503 Fix #4466: Replacing a post does not correctly set the best source.
Don't default the "Final source" field to the current source. This way
the default will be to set the source to the normalized replacement URL.
The "final source" field can be set to override this.
2022-01-11 19:48:20 -06:00
evazion 8bb923cf9b Fix #4807: Change creator to creator_id on forum post attributes. 2022-01-11 18:55:11 -06:00
evazion dc724ee912 BURs: add test for aliasing together two tags with an implication (#4871).
Add a test for when A and B imply the same tag, and A is aliased to B.
2022-01-11 16:38:40 -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 698d732667 Fix #4878: Disapproval messages appear out of order.
Display disapproval messages in oldest-to-newest order.
2022-01-11 12:27:56 -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 422dbbc72e Fix #4942: Missing Blacklist Controls. 2022-01-11 10:16:23 -06:00
evazion 33828ec8a4 posts: remove set_tag_string method. 2022-01-11 10:06:46 -06:00
evazion 2e1c7ce6d3 Fix #4951: chartags:0 returning posts with chartags.
* Add fix script to fix posts with incorrect tag_count_* fields.
* Simplify the code for updating tag_count_* fields (no functional change).
2022-01-10 13:33:56 -06:00
evazion bd7018a3ae rails: update cache format version to 7.0. 2022-01-10 11:39:09 -06:00
evazion fd2db2ff23 Update Ruby gems and Yarn packages. 2022-01-10 11:32:59 -06:00
evazion 104234126f robots.txt: add more static pages.
Let Google index a few more static pages.
2022-01-10 11:00:13 -06:00
evazion aedc09f301 bigquery: exclude GoodJob::Job from BigQuery. 2022-01-10 00:12:31 -06:00
evazion 323882dbc4 upgrades: fix unsafe redirect errors in receipt/payment actions. 2022-01-10 00:11:10 -06:00
evazion 85e1ae3c9b favorites: fix posts with incorrect fav_count fields.
There were about 4000 posts with an incorrect fav_count.
2022-01-09 19:31:45 -06:00
evazion ab4214dc00 emails: mark all invalid emails as undeliverable. 2022-01-09 13:24:53 -06:00
evazion c09cd9e9fd users: fix incorrect count columns on users table.
Fix incorrect post_upload_count, note_update_count, and
unread_dmail_count columns on the users table.
2022-01-09 12:51:10 -06:00
evazion 5623b139aa db: add foreign key constraints on all tables.
Add foreign key constraints on all foreign keys on all tables.

These constraints are deferrable so that they're checked at the end of
the transaction, rather at the end of the statement. This is to reduce
lock duration and to allow for cyclic relationships.

Constraints are added in one migration then validated in another so that
the entire table isn't locked against reads and writes while the foreign
key constraints are being validated.

A few tables had invalid foreign keys. Add a fix script to fix these tables:

* A couple artist versions belonged to deleted artists.
* One dmail belonged to a deleted user.
* One forum topic visit belonged to that same deleted user.
* A few dozen note versions belonged to nonexistent posts. This came
  from RaisingK moving notes to different posts years ago, back when it
  was possible for users to set a note's post ID in the API.
* Some uploads had their parent ID set to 0.
2022-01-09 11:01:00 -06:00
evazion 3814aa21b3 favorites: delete favorites for expunged posts.
Delete favorites that have an invalid post_id because they belong to an
expunged post.

This bug of not deleting favorites after a post is expunged was fixed
long ago, but old favorites were never cleaned up.

Fixes #4711: Some users have incorrect fav count.
2022-01-08 20:55:55 -06:00
evazion 04d3a04836 favorites: fix users with incorrect favorite counts.
Fix users that have a non-zero favorite count, but no favorites.
Follow-up to 69facb22b.
2022-01-08 14:18:29 -06:00
evazion 69facb22b1 Fix #4265: Negative favorite counts.
There were 2176 users with incorrect favorite counts, and it stopped
after user id 522393, so this must have been an old bug.
2022-01-08 13:42:49 -06:00
evazion d900e15dcc css: fix stylelint complaints. 2022-01-08 12:30:21 -06:00
evazion 3bf65d1378 css: update browserslist requirement.
Update the minimum browser requirement from browsers released since
2012, to browsers released in the last 5 years.

This means PostCSS won't prefix CSS properties like `flex` or other
properties supported by browsers since 2017. Babel also won't transpile
Javascript syntax that has been supported by browsers since 2017.
2022-01-08 12:09:25 -06:00
evazion bb60a59001 css: remove postcss-flexbugs-fixes plugin.
Remove a PostCSS plugin used to workaround bugs in the `flex` CSS
property. Most of these bugs are no longer relevant and only affected
ancient browsers like IE 10 or 11.

https://github.com/philipwalton/flexbugs
2022-01-08 11:54:45 -06:00
evazion 52311ad914 css: don't include fallbacks for CSS variables.
Don't include fallback CSS properties for CSS variables. Before we
generated CSS like this:

  a.tag-type-1 {
    color: #c00004;
    color: var(--artist-tag-color);
  }

Now we generate CSS like this:

  a.tag-type-1 {
    color: var(--artist-tag-color);
  }

This means that support for CSS variables is now required for colors to
work properly. All major browsers have supported CSS variables since
2016-2017.
2022-01-08 11:50:02 -06:00
evazion 349f8e098f posts: prevent dragging of thumbnails.
Disable the ability to click and drag thumbnails. This usually happened
by accident when you clicked on a thumbnail and accidentally dragged it,
especially during tag scripting.
2022-01-07 21:33:26 -06:00
evazion 37f2d5925f sessions: fix open redirect in login page.
Fix an open redirect exploit where if you went to <https://danbooru.donmai.us/login?url=//fakebooru.com>,
then after you logged in you would be redirected to https://fakebooru.com.

This was actually fixed by the upgrade to Rails 7.0. `redirect_to` now
raises an `UnsafeRedirectError` on redirect to an offsite URL. Before we
tried to prevent offsite redirects by checking that the URL started with
a slash, but this was insufficient - it allowed protocol-relative URLs
like `//fakebooru.com`.

Add a test case for protocol-relative URLs and return a 403 error on an
offsite redirect.
2022-01-07 21:11:04 -06:00
evazion 841990709d rails: enable Server-Timing HTTP header in production.
This returns a Server-Timing header on all HTTP responses, which
includes details on how long it took the server to render the response.
Browsers can show this timing information in the devtools. In Chrome, go
to the Network panel, then click a HTTP request, then click the Timing tab.
2022-01-07 21:11:04 -06:00
evazion 87dfc66073 rails: update framework files and settings to 7.0.
* Update framework files with `bin/rails app:update`.
* Update to use new Rails 7.0 default settings, except for a couple
  things regarding new cookie and cache formats that would prevent us
  from rolling back to Rails 6.1 if necessary.
2022-01-07 21:10:55 -06:00
evazion 346aeca791 rails: remove sprockets references.
Remove a dummy Sprockets config file needed to get `bin/derailed` to
run. This is no longer necessary since Rails 7.0 no longer depends on
Sprockets.
2022-01-07 14:49:14 -06:00
evazion 450594b803 tests: fix broken tests. 2022-01-07 14:44:24 -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 a26ed9d389 rails: fix #to_s(:human_size) deprecation warnings.
Fix this deprecation warning:

  DEPRECATION WARNING: Integer#to_s(:human_size) is deprecated. Please use Integer#to_formatted_s(:human_size) instead.
2022-01-07 14:24:54 -06:00
evazion 3f25ad6dce rails: upgrade to Rails 7.0.1. 2022-01-07 14:24:45 -06:00
evazion 41a095abfe gems: temp disable meta_request gem.
It's not yet compatible with Rails 7.0.
2022-01-07 12:43:39 -06:00
evazion ea069c7b0d models: remove hack to ignore tsvector columns.
Previously we overrode `ActiveRecord::Base#columns` to make it ignore
tsvector columns so they wouldn't show up in API responses. These
columns have been removed, so this is no longer necessary.
2022-01-07 11:23:53 -06:00
evazion 53527b9b29 posts: remove pool_string, fav_string from ignored columns.
These columns have been removed from the database.
2022-01-07 11:22:10 -06:00
evazion dbf4e1e98e db: remove unused tsvector triggers.
This was forgotten in 080dbf5a8.
2022-01-06 20:03:50 -06:00
evazion 0f3fc0d697 Fix Twitter widget overlapping Discord widget on Downbooru page. 2022-01-06 12:43:37 -06:00
evazion e8c52432a4 db: remove unused columns on posts table.
is_note_locked, is_rating_locked, and is_status_locked have been unused
since 126046cb6.

tag_index has been unused since 37a8dc5db.

fav_string has been unused since 165339236.

pool_string has been unused since 7d503f088.
2022-01-06 11:39:18 -06:00
evazion 080dbf5a8c db: remove unused tsvector columns.
These columns have been unused since e3b836b50.
2022-01-06 11:25:51 -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 edd0656b73 tests: fix broken tests. 2022-01-06 00:41:18 -06:00
evazion b254d6d9d9 jobs: fix searching by name not finding certain jobs.
Fix a bug where /jobs?search[name]=Prune+Posts didn't find jobs named PrunePostsJob.
`"Prune Posts".tr(" ", "_").classify` was wrong because it returned `"PrunePost"`.
2022-01-05 11:14:56 -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 7ce81ceccb emails: fix exception when user signs up without an email.
Fix an `ActionView::Template::Error: undefined method 'verification_key'
for nil` error in the welcome_user mailer when a user signs up without
an email address.

Caused by the fact that we now render mail templates regardless of
whether the user has an email address, and then skip sending the email
only after the mail template is rendered.
2022-01-04 17:57:16 -06:00
evazion 1ccc74adca jobs: add ability to order jobs in /jobs listing. 2022-01-04 17:53:35 -06:00
evazion dc159ed135 jobs: show retried jobs in /jobs listing.
Fix the /jobs listing to show retried jobs. GoodJob::ActiveJobJob has a
default scope that filters out retried jobs; remove it in the index
controller so we can see retried jobs.

Also fix mail delivery jobs not showing up in the dropdown in the /jobs
search form.
2022-01-04 17:46:54 -06:00
evazion f38910f0a2 jobs: hide job arguments and errors from non-admins.
These can sometimes contain sensitive information, such as IP addresses
or what files a user is trying to upload.
2022-01-04 17:20:43 -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 12601e49fd users: fix exception in can_receive_email?. 2022-01-04 16:04:41 -06:00
evazion 3841fba78e jobs: remove DelayedJobs.
Remove the DelayedJobs gem and database table. Completes the transition
to GoodJob started in c06bfa64f and f4953549a.

Downstream users can upgrade as follows:

* Stop the Rails server.
* Stop the DelayedJobs worker (normally running as `bin/delayed_job` or `bin/rails jobs:work`).
* Run `bin/rails jobs:work` to finish any pending delayed jobs.
* Run `bin/rails db:migrate` to create the good_jobs table and drop the delayed_jobs table.
* Start the Rails server again.
* Start the GoodJobs worker with `bin/good_job start`.
2022-01-04 15:58:12 -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 21a9bb2c63 jobs: rename /delayed_jobs to /jobs.
Rename the /delayed_jobs endpoint to just /jobs since it's no longer
based on DelayedJob.
2022-01-02 21:21:16 -06:00
evazion f7784d2340 jobs: update jobs dashboard to work with GoodJob.
Update the jobs dashboard at /delayed_jobs to work with GoodJob instead
of DelayedJob.
2022-01-02 21:21:04 -06:00
evazion c06bfa64f5 Add GoodJob gem.
This is the first step towards replacing DelayedJob with GoodJob. Compared to
DelayedJob:

* GoodJob supports Rails 7 (DelayedJob is currently a blocker for Rails 7
  because it has a version bound on ActiveRecord <6.2).
* GoodJob has a builtin admin dashboard.
* GoodJob supports threaded job workers.
* GoodJob supports scheduled cronjobs.
* GoodJob supports healthchecks for workers.
* GoodJob uses Postgres notifications instead of polling to pick up new
  jobs. This allows jobs to be picked up faster and scales better with
  large numbers of workers.

https://github.com/bensheldon/good_job
2022-01-02 17:13:41 -06:00
evazion 370ed32426 emails: fix exception when disabling dmail notifications.
Fix an `undefined method 'find' for Maintenance::User:Module` exception
when disabling email notifications using the "Disable notifications"
link in dmails.
2022-01-02 17:10:27 -06:00
evazion e40218d1c8 Fix #4515: Set List-Unsubscribe header on notification emails. 2022-01-02 17:10:27 -06:00
evazion 27ed41437c emails: fix invalid RCPT TO errors.
Fix `501 invalid RCPT TO address provided` errors caused by usernames
containing invalid characters. Example: `To: Foo,Bar <foobar@gmail.com>`.
2022-01-02 16:08:35 -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 d903f45935 emails: add script to fix invalid emails.
Add a fix script to fix email addresses that are invalid or that contain
common typos. If the email can't be fixed, usually because the fixed
address is already in use by another account, then the email address is
marked undeliverable.
2022-01-02 16:08:35 -06:00
evazion 32613f9bb1 emails: fix sending emails to invalid addresses.
Fix mailers to not attempt deliveries to invalid or nonexistent email
addresses. This usually happened when someone changed their email, and
we tried to send a confirmation email to a nonexistent address.
2022-01-02 16:07:57 -06:00
evazion 9ffc269e43 winter sale: update banner interval.
Reset cookie and set the hide banner interval to 1 hour for the final
three hours of the sale.
2021-12-31 15:12:47 -06:00
evazion 18c08688df Merge pull request #4947 from nonamethanks/fix-duration-twitter
Fix duration check for uploads from twitter
2021-12-29 22:33:59 -06:00
evazion f2b5c9f54d winter sale: fix error with promotion codes.
Fix an exception when checking out on Stripe caused by using the
`allow_promotion_codes` and `discounts` parameters at the same time.

   Stripe::InvalidRequestError - You may only specify one of these parameters: allow_promotion_codes, discounts
2021-12-28 16:05:45 -06:00
evazion b8356c97c1 Add Danbooru Winter Sale. 2021-12-28 14:41:37 -06:00
evazion 572b1b74f7 posts: add hidden 720x720 thumbnail option (#4944).
Allow 720x720 thumbnails with https://danbooru.donmai.us/posts?size=720.
2021-12-28 11:36:14 -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 0e778f0972 Update Ruby gems and Yarn packages. 2021-12-28 09:47:34 -06:00
evazion 4d9028f1fd docker: switch Ruby memory allocator to Jemalloc.
Switch the Ruby memory allocator from Glibc malloc to Jemalloc. Jemalloc
supposedly uses less memory than Glibc malloc because it's better at
handling memory fragmentation. It also has detailed internal statistics
to help monitor allocator behavior.

We use the LD_PRELOAD method of loading Jemalloc instead of building it
into Ruby so that we can switch allocators at runtime.
2021-12-19 03:44:59 -06:00
evazion 0ba6dc9ee5 Fix #4945: Search for an artist by URL throws an exception. 2021-12-18 01:55:29 -06:00
evazion b5b54f2c78 gems: add rbtrace 2021-12-17 22:23:59 -06:00
evazion 993965b654 posts: reduce string allocations during thumbnail generation.
Further micro-optimize thumbnails to reduce string allocations.

`Post#levelblocked?` gets called once per thumbnail. Before it split the
tag string, which meant one string allocation for each tag on each post.
This added up to thousands of string allocations per pageload.
2021-12-16 17:17:06 -06:00
evazion 1c5786d20f posts: remove cropped thumbnails. 2021-12-16 15:58:29 -06:00
evazion 379775d10d Remove HTML data attributes from thumbnails #4943
Remove most data attributes from thumbnails, except the ones used by our
own Javascript.
2021-12-16 15:48:07 -06:00
evazion c3f61a5888 tests: fix broken tests. 2021-12-16 01:38:06 -06:00
evazion a62ae69740 dtext: fix frozen string error. 2021-12-16 00:56:46 -06:00
evazion 163ba8e7da posts: micro-optimize allocations during thumbnail generation.
Do a few micro-optimizations to reduce the number of memory allocations
during thumbnail generation.

This commit, combined with freezing string literals in a7dc05 and
67b961, reduces the number of allocations on the front page from 180,000
to 150,000, and the number of retained objects from 8,000 to 4,000.
2021-12-16 00:53:48 -06:00
evazion 3fcecd59a8 Add derailed_benchmarks gem. 2021-12-16 00:53:48 -06:00
evazion 51a4daef47 Update Rails from 6.1.4.3 to 6.1.4.4.
Fixes this bug:

    There was a bug in the previous release such that requests in
    development with a port number wouldn’t be considered “authorized”
    requests. Requests to “127.0.0.1:3000” and custom hosts should work
    in this new version.

https://weblog.rubyonrails.org/2021/12/15/Rails-6-0-4-4-and-6-1-4-4-have-been-released/
2021-12-15 21:40:24 -06:00
evazion a7dc05ce63 Enable frozen string literals.
Make all string literals immutable by default.
2021-12-14 21:33:27 -06:00
evazion 67b96135dd Make Symbol#to_s return frozen string.
Monkey-patch Symbol#to_s to return a frozen (immutable) string instead
of a mutable string.

This should reduce string allocations, and thereby reduce memory usage
and garbage collector pressure, but it may be incompatible with
libraries that expect Symbol#to_s to return a mutable string.

https://bugs.ruby-lang.org/issues/16150
https://github.com/Shopify/symbol-fstring
2021-12-14 21:33:27 -06:00
evazion 4e730a145d Update Ruby gems and Yarn packages. 2021-12-14 21:33:27 -06:00
evazion fbcf98db96 seo: prevent crawling comment, show_seq links.
* Mark /comments/:id links in comment timestamps as nofollow to prevent
  Googlebot from crawling these links.
* Mark /posts/:id/show_seq links as disallowed in robots.txt to prevent
  Googlebot from crawling forward/back links on posts.
2021-12-13 05:24:07 -06:00
evazion c0610cb809 posts: reduce sidebar width on laptops/tablets.
This allows fitting one more medium-size thumbnail per row on
laptop and tablet size screens.
2021-12-13 05:24:05 -06:00
evazion 0997f5595e posts: increase default thumbnail size.
* Increase the default thumbnail size from small (150x150) to medium (180x180).
* Change the mobile layout to use three posts per row instead of two for small thumbnails.

Parent/child posts are still 150x150 to avoid taking up even more space above posts.
2021-12-13 05:23:38 -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 9eed21ef14 posts: bottom align thumbnails; prevent thumbnail reflow.
* Bottom-align thumbnails on desktop. This is so that vote buttons line
  up beneath thumbnails. Also so that pool titles line up on the pool
  gallery page. This is desktop only because it tends to leave large
  gaps above thumbnails on mobile.

* Make thumbnails fixed-height so that the layout doesn't shift as
  thumbnails are loaded.
2021-12-13 05:23:00 -06:00
evazion 487b51efe4 related tags: fix related tag section being hidden.
Fix the related tags section being completely hidden when it was
collapsed. The `.hidden` CSS class that was used by related tags
conflicted with the `.hidden` utility class added in 8841de68ac.
2021-12-10 06:02:46 -06:00
evazion bf022e858a seo: prevent crawlers from crawling /posts/:id/favorites. 2021-12-10 01:46:01 -06:00