diff --git a/.erb-lint.yml b/.erb-lint.yml index 3a52bb710a6..8489128a7a7 100644 --- a/.erb-lint.yml +++ b/.erb-lint.yml @@ -15,8 +15,6 @@ linters: rubocop_config: inherit_from: - .rubocop.yml - # Uncomment the following line to ignore known issues - # - .rubocop_todo_erb.yml Layout/ArgumentAlignment: EnforcedStyle: with_fixed_indentation Layout/InitialIndentation: diff --git a/.gitattributes b/.gitattributes index 4cab1f4d267..e838c59ef59 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,6 @@ # Set the default behavior, in case people don't have core.autocrlf set. * text=auto +# Bash scripts needs to have LF line endings, even on Windows +*.sh text eol=lf +# /usr/local/bin/ruby: warning: shebang line ending with \r may cause problems +/bin/* text eol=lf diff --git a/.github/workflows/automated-tests.yml b/.github/workflows/automated-tests.yml index 494718290b4..f53bb9e01f7 100644 --- a/.github/workflows/automated-tests.yml +++ b/.github/workflows/automated-tests.yml @@ -34,7 +34,7 @@ jobs: - 3306:3306 elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:7.17.5 + image: docker.elastic.co/elasticsearch/elasticsearch:7.17.26 ports: - 9200:9200 options: >- @@ -58,12 +58,15 @@ jobs: arguments: spec/models - command: rspec arguments: --exclude-pattern 'spec/{controllers,models}/**/*.rb' + libvips: true - command: cucumber arguments: features/admins + libvips: true - command: cucumber arguments: features/bookmarks - command: cucumber arguments: features/collections + libvips: true - command: cucumber arguments: features/comments_and_kudos - command: cucumber @@ -73,8 +76,10 @@ jobs: vcr: true - command: cucumber arguments: features/other_a + libvips: true - command: cucumber arguments: features/other_b + libvips: true - command: cucumber arguments: features/prompt_memes_a - command: cucumber @@ -129,6 +134,10 @@ jobs: restore-keys: | cassette-library-${{ hashFiles(matrix.tests.arguments) }}- + - name: Install libvips for image processing + if: ${{ matrix.tests.libvips }} + run: sudo apt-get install -y libvips-dev + - name: Set up Ruby and run bundle install uses: ruby/setup-ruby@v1 with: @@ -150,7 +159,7 @@ jobs: run: bundle exec ${{ matrix.tests.command }} ${{ matrix.tests.arguments }} - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: # Optional for public repos. However, individual forks can set this # secret to reduce the chance of being rate-limited by GitHub. diff --git a/.github/workflows/phrase-export-checks.yml b/.github/workflows/phrase-export-checks.yml new file mode 100644 index 00000000000..98944c93150 --- /dev/null +++ b/.github/workflows/phrase-export-checks.yml @@ -0,0 +1,84 @@ +name: Check Phrase exports +on: + pull_request: + branches: + - master + - main + workflow_dispatch: + +jobs: + en-keys-to-remove: + if: github.head_ref == 'phrase-translations' + runs-on: ubuntu-latest + name: Check for outdated English keys in Phrase + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Ruby and run bundle install + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Run i18n-tasks missing (diff mode) + run: bundle exec i18n-tasks missing -t diff -f keys en | bundle exec i18n-tasks tree-mv -f keys "en.{*}" "\1" > en-keys-to-remove.txt + + - name: Check that all keys exported from Phrase exist in English + run: "! test -s en-keys-to-remove.txt" + + - name: Upload list of English keys that should be removed from Phrase + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: en-keys-to-remove + path: en-keys-to-remove.txt + + unused-keys: + if: github.head_ref == 'phrase-translations' + runs-on: ubuntu-latest + needs: en-keys-to-remove + name: Check unused keys for all locales + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Ruby and run bundle install + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Run i18n-tasks unused + run: bundle exec i18n-tasks unused -f keys > unused-keys.txt + + - name: Upload list of unused locale keys + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: unused-keys + path: unused-keys.txt + + inconsistent-interpolations: + if: github.head_ref == 'phrase-translations' + runs-on: ubuntu-latest + name: Check consistent interpolations for all locales + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Ruby and run bundle install + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Run i18n-tasks check-consistent-interpolations + run: bundle exec i18n-tasks check-consistent-interpolations -f yaml > inconsistent-interpolations.yml + continue-on-error: true + + - name: Upload yaml of inconsistent interpolations + uses: actions/upload-artifact@v4 + with: + name: inconsistent-interpolations + path: inconsistent-interpolations.yml diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml index f6d3176be1d..cdd3f0a9e7a 100644 --- a/.github/workflows/reviewdog.yml +++ b/.github/workflows/reviewdog.yml @@ -23,11 +23,12 @@ jobs: bundler-cache: true - name: rubocop - uses: reviewdog/action-rubocop@708a61f1f3bc4127205f5ec59f4f8617478ebdda + uses: reviewdog/action-rubocop@cd8c2943f425b54f97095777109ae9f1f2d79a61 with: use_bundler: true reporter: github-pr-check skip_install: true + fail_level: any erb-lint: name: ERB Lint runner @@ -44,7 +45,8 @@ jobs: bundler-cache: true - name: erb-lint - uses: tk0miya/action-erblint@667687e73b44e7b7a710a1204b180f49f80ebb5e + uses: tk0miya/action-erblint@b6e537f4616e4fa7a9eef209ca34ca944e1440dd with: use_bundler: true - reporter: github-pr-check # default + reporter: github-pr-check + fail_on_error: true diff --git a/.gitignore b/.gitignore index 53da1b09dbc..df5aa242f87 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,9 @@ public/system/test # /tmp/ /tmp/* +# ActiveRecord storage path +storage/ + # /vendor/ /vendor/gems diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 00000000000..75267cd8fda --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,17 @@ +tasks: + - init: ./script/docker/init.sh + command: docker compose up -d web + +ports: + - port: 3000 + onOpen: open-browser + - port: 3306 + onOpen: ignore + - port: 6379 + onOpen: ignore + - port: 9200 + onOpen: ignore + - port: 9300 + onOpen: ignore + - port: 9400 + onOpen: ignore diff --git a/.phrase.yml b/.phrase.yml index c4cd012f7ed..cc7e9347e5b 100644 --- a/.phrase.yml +++ b/.phrase.yml @@ -134,15 +134,15 @@ phrase: - file: ./config/locales/phrase-exports/ru.yml params: locale_id: ru + - file: ./config/locales/phrase-exports/scr.yml + params: + locale_id: scr - file: ./config/locales/phrase-exports/sk.yml params: locale_id: sk - file: ./config/locales/phrase-exports/sl.yml params: locale_id: sl - - file: ./config/locales/phrase-exports/sr.yml - params: - locale_id: sr - file: ./config/locales/phrase-exports/sv.yml params: locale_id: sv diff --git a/.rubocop.yml b/.rubocop.yml index 6ca41445023..3e0d86588b2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,3 @@ -# Uncomment the following line to ignore known issues -# inherit_from: .rubocop_todo.yml - # Options available at https://github.com/bbatsov/rubocop/blob/master/config/default.yml require: @@ -14,7 +11,7 @@ inherit_mode: AllCops: NewCops: enable - TargetRubyVersion: 3.0 + TargetRubyVersion: 3.1 Bundler/OrderedGems: Enabled: false @@ -53,6 +50,12 @@ Lint/AmbiguousBlockAssociation: Lint/AmbiguousRegexpLiteral: Enabled: false +Lint/RedundantSafeNavigation: + Exclude: + # Take a better safe than sorry approach to safe navigation in admin + # policies. + - 'app/policies/*.rb' + Metrics/AbcSize: Enabled: false @@ -119,6 +122,11 @@ Migration/LargeTableSchemaUpdate: - users - works +Naming/VariableNumber: + AllowedIdentifiers: + - age_over_13 + - no_age_over_13 + Rails/DefaultScope: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml deleted file mode 100644 index 7423de01eda..00000000000 --- a/.rubocop_todo.yml +++ /dev/null @@ -1,4994 +0,0 @@ -# This configuration was generated by -# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 100000000000000` -# on 2023-05-28 17:16:12 UTC using RuboCop version 1.22.1. -# The point is for the user to remove these configuration records -# one by one as the offenses are removed from the code base. -# Note that changes in the inspected code, or installation of new -# versions of RuboCop, may require this file to be generated again. - -# Offense count: 8 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: outdent, indent -Layout/AccessModifierIndentation: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/downloads_controller.rb' - - 'app/models/potential_match.rb' - -# Offense count: 133 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: with_first_argument, with_fixed_indentation -Layout/ArgumentAlignment: - Exclude: - - 'app/controllers/admin/admin_invitations_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/feedbacks_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/models/abuse_report.rb' - - 'app/models/admin_post.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_profile.rb' - - 'app/models/comment.rb' - - 'app/models/external_author_name.rb' - - 'app/models/gift.rb' - - 'app/models/known_issue.rb' - - 'app/models/prompt.rb' - - 'app/models/pseud.rb' - - 'app/models/question.rb' - - 'app/models/series.rb' - - 'app/models/skin_parent.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/work.rb' - - 'features/step_definitions/bookmark_steps.rb' - - 'features/step_definitions/work_search_steps.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/autocomplete_source.rb' - - 'lib/creation_notifier.rb' - - 'spec/controllers/tags_controller_spec.rb' - - 'spec/models/search/work_search_form_spec.rb' - -# Offense count: 23 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: with_first_element, with_fixed_indentation -Layout/ArrayAlignment: - Exclude: - - 'app/controllers/challenge/prompt_meme_controller.rb' - - 'app/models/collection_participant.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/subscription.rb' - - 'spec/lib/html_cleaner_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: IndentationWidth. -Layout/AssignmentIndentation: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleAlignWith, Severity. -# SupportedStylesAlignWith: start_of_line, begin -Layout/BeginEndAlignment: - Exclude: - - 'app/controllers/tags_controller.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleAlignWith. -# SupportedStylesAlignWith: either, start_of_block, start_of_line -Layout/BlockAlignment: - Exclude: - - 'app/controllers/readings_controller.rb' - - 'app/models/admin_post.rb' - - 'app/models/challenge_signup.rb' - -# Offense count: 13 -# Cop supports --auto-correct. -Layout/BlockEndNewline: - Exclude: - - 'app/models/challenge_signup.rb' - - 'app/models/gift.rb' - - 'app/models/skin.rb' - - 'app/models/work.rb' - - 'spec/controllers/admin_posts_controller_spec.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - - 'spec/models/favorite_tag_spec.rb' - -# Offense count: 17 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentOneStep, IndentationWidth. -# SupportedStyles: case, end -Layout/CaseIndentation: - Exclude: - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/models/inbox_comment.rb' - -# Offense count: 7 -# Cop supports --auto-correct. -Layout/ClosingParenthesisIndentation: - Exclude: - - 'app/controllers/collection_participants_controller.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/collection.rb' - - 'app/models/search/query_result.rb' - - 'app/models/work.rb' - -# Offense count: 9 -# Cop supports --auto-correct. -Layout/CommentIndentation: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/chapter.rb' - - 'app/models/story_parser.rb' - - 'app/models/user.rb' - - 'config/initializers/devise.rb' - - 'spec/models/external_work_spec.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleAlignWith, Severity. -# SupportedStylesAlignWith: start_of_line, def -Layout/DefEndAlignment: - Exclude: - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/models/user.rb' - -# Offense count: 241 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: leading, trailing -Layout/DotPosition: - Exclude: - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/challenge_requests_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/creatorships_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/decorators/homepage.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/collection_participant.rb' - - 'app/models/concerns/creatable.rb' - - 'app/models/fandom.rb' - - 'app/models/gift.rb' - - 'app/models/inbox_comment.rb' - - 'app/models/potential_match.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/question.rb' - - 'app/models/related_work.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search_range.rb' - - 'app/models/series.rb' - - 'app/models/spam_report.rb' - - 'app/models/subscription.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'features/step_definitions/work_import_steps.rb' - - 'lib/html_cleaner.rb' - - 'lib/otw_sanitize/user_class_sanitizer.rb' - - 'lib/tasks/creatorships.rake' - - 'spec/controllers/api/api_helper.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - - 'spec/controllers/tags_controller_spec.rb' - - 'spec/helpers/tag_sets_helper_spec.rb' - - 'spec/models/feedback_reporters/feedback_reporter_spec.rb' - - 'spec/models/filter_count_spec.rb' - - 'spec/models/search/async_indexer_spec.rb' - - 'spec/models/story_parser_spec.rb' - - 'spec/models/work_spec.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Layout/ElseAlignment: - Exclude: - - 'app/helpers/external_authors_helper.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: AllowBorderComment, AllowMarginComment. -Layout/EmptyComment: - Exclude: - - 'app/models/tagset_models/tag_set.rb' - -# Offense count: 189 -# Cop supports --auto-correct. -Layout/EmptyLineAfterGuardClause: - Exclude: - - 'app/controllers/admin/skins_controller.rb' - - 'app/controllers/admin/user_creations_controller.rb' - - 'app/controllers/admin_posts_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/downloads_controller.rb' - - 'app/controllers/external_authors_controller.rb' - - 'app/controllers/people_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/controllers/series_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/decorators/bookmarkable_decorator.rb' - - 'app/decorators/homepage.rb' - - 'app/decorators/pseud_decorator.rb' - - 'app/helpers/date_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/abuse_report.rb' - - 'app/models/admin_post_tag.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/challenge_signup_summary.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/common_tagging.rb' - - 'app/models/concerns/creatable.rb' - - 'app/models/download.rb' - - 'app/models/download_writer.rb' - - 'app/models/feedback.rb' - - 'app/models/indexing/cache_master.rb' - - 'app/models/indexing/index_queue.rb' - - 'app/models/invitation.rb' - - 'app/models/invite_request.rb' - - 'app/models/moderated_work.rb' - - 'app/models/potential_match_builder.rb' - - 'app/models/potential_matcher/potential_matcher_progress.rb' - - 'app/models/preference.rb' - - 'app/models/profile.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/bookmarkable_query.rb' - - 'app/models/search/index_sweeper.rb' - - 'app/models/search/pseud_search_form.rb' - - 'app/models/search/query.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/search/query_result.rb' - - 'app/models/search/tag_indexer.rb' - - 'app/models/search/tag_query.rb' - - 'app/models/search/taggable_query.rb' - - 'app/models/search/work_query.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/serial_work.rb' - - 'app/models/series.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'app/models/work_link.rb' - - 'app/models/work_skin.rb' - - 'app/validators/url_active_validator.rb' - - 'app/validators/url_format_validator.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'features/step_definitions/comment_steps.rb' - - 'features/step_definitions/potential_match_steps.rb' - - 'lib/backwards_compatible_password_decryptor.rb' - - 'lib/bookmarkable.rb' - - 'lib/collectible.rb' - - 'lib/creation_notifier.rb' - - 'lib/css_cleaner.rb' - - 'lib/html_cleaner.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - - 'lib/otw_sanitize/media_sanitizer.rb' - - 'lib/otw_sanitize/user_class_sanitizer.rb' - - 'lib/redis_test_setup.rb' - - 'lib/responder.rb' - - 'lib/tasks/load_autocomplete_data.rake' - - 'lib/tasks/resque.rake' - - 'script/gift_exchange/generate_from_spec.rb' - - 'script/gift_exchange/load_json_challenge.rb' - -# Offense count: 21 -# Cop supports --auto-correct. -Layout/EmptyLineAfterMagicComment: - Exclude: - - 'app/helpers/exports_helper.rb' - - 'factories/api_key.rb' - - 'factories/prompt.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'spec/controllers/admin/api_controller_spec.rb' - - 'spec/controllers/api/v2/api_works_search_spec.rb' - - 'spec/controllers/api/v2/api_works_spec.rb' - - 'spec/controllers/challenge_claims_controller_spec.rb' - - 'spec/controllers/collection_participants_controller_spec.rb' - - 'spec/controllers/external_authors_controller_spec.rb' - - 'spec/controllers/owned_tag_sets_controller_spec.rb' - - 'spec/controllers/works/default_rails_actions_spec.rb' - - 'spec/controllers/works/drafts_spec.rb' - - 'spec/controllers/works/importing_spec.rb' - - 'spec/controllers/works/multiple_actions_spec.rb' - - 'spec/helpers/exports_helper_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/models/filter_count_spec.rb' - - 'spec/models/stat_counter_spec.rb' - - 'spec/models/tag_spec.rb' - -# Offense count: 56 -# Cop supports --auto-correct. -# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. -Layout/EmptyLineBetweenDefs: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/locales_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/user_invite_requests_controller.rb' - - 'app/helpers/external_authors_helper.rb' - - 'app/models/admin_post.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/character.rb' - - 'app/models/collection.rb' - - 'app/models/collection_participant.rb' - - 'app/models/fandom.rb' - - 'app/models/freeform.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/relationship.rb' - - 'app/models/search_range.rb' - - 'app/models/series.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/user.rb' - - 'config/initializers/monkeypatches/translate_string.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/collectible.rb' - - 'lib/css_cleaner.rb' - -# Offense count: 82 -# Cop supports --auto-correct. -Layout/EmptyLines: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/locales_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/potential_matches_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/helpers/external_authors_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/fandom.rb' - - 'app/models/pseud.rb' - - 'app/models/search/bookmarkable_query.rb' - - 'app/models/search_range.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/fandom_nomination.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'config/deploy/production.rb' - - 'config/initializers/monkeypatches/override_default_form_field_sizes.rb' - - 'config/initializers/monkeypatches/translate_string.rb' - - 'features/step_definitions/challege_gift_exchange_steps.rb' - - 'features/step_definitions/challenge_steps.rb' - - 'features/step_definitions/generic_steps.rb' - - 'features/step_definitions/profile_steps.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/collectible.rb' - - 'lib/css_cleaner.rb' - - 'lib/html_cleaner.rb' - - 'lib/tasks/cucumber.rake' - - 'script/get_user_data.rb' - - 'spec/models/external_work_spec.rb' - - 'spec/models/invitation_spec.rb' - - 'spec/models/skin_spec.rb' - -# Offense count: 17 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: around, only_before -Layout/EmptyLinesAroundAccessModifier: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/languages_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/models/potential_match.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/user.rb' - - 'app/sweepers/collection_sweeper.rb' - - 'lib/collectible.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Layout/EmptyLinesAroundArguments: - Exclude: - - 'app/controllers/works_controller.rb' - - 'spec/models/story_parser_spec.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Layout/EmptyLinesAroundBeginBody: - Exclude: - - 'app/controllers/api/v2/bookmarks_controller.rb' - -# Offense count: 87 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty_lines, no_empty_lines -Layout/EmptyLinesAroundBlockBody: - Exclude: - - 'app/models/tagset_models/tag_set.rb' - - 'config/routes.rb' - - 'factories/subscriptions.rb' - - 'factories/user_invite_requests.rb' - - 'factories/works.rb' - - 'factories/wrangling_guideline.rb' - - 'lib/collectible.rb' - - 'lib/tasks/admin_tasks.rake' - - 'lib/tasks/deploy_tasks.rake' - - 'lib/tasks/memcached.rake' - - 'lib/tasks/resque.rake' - - 'lib/tasks/skin_tasks.rake' - - 'lib/tasks/spam_report.rake' - - 'spec/controllers/api/v2/api_base_controller_spec.rb' - - 'spec/controllers/bookmarks_controller_spec.rb' - - 'spec/controllers/invite_requests_controller_spec.rb' - - 'spec/controllers/works/default_rails_actions_spec.rb' - - 'spec/helpers/exports_helper_spec.rb' - - 'spec/helpers/home_helper_spec.rb' - - 'spec/helpers/inbox_helper_spec.rb' - - 'spec/helpers/user_invite_requests_helper_spec.rb' - - 'spec/lib/collectible_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/lib/string_cleaner_spec.rb' - - 'spec/lib/url_formatter_spec.rb' - - 'spec/lib/works_owner_spec.rb' - - 'spec/models/admin_blacklisted_email_spec.rb' - - 'spec/models/challenge_assignment_spec.rb' - - 'spec/models/challenge_claim_spec.rb' - - 'spec/models/collection_spec.rb' - - 'spec/models/comment_spec.rb' - - 'spec/models/external_author_spec.rb' - - 'spec/models/external_work_spec.rb' - - 'spec/models/gift_exchange_spec.rb' - - 'spec/models/gift_spec.rb' - - 'spec/models/invitation_spec.rb' - - 'spec/models/potential_match_spec.rb' - - 'spec/models/search/bookmark_query_spec.rb' - - 'spec/models/search/index_sweeper_spec.rb' - - 'spec/models/search/work_query_spec.rb' - - 'spec/models/search/work_search_form_exclusion_filters_spec.rb' - - 'spec/models/skin_parent_spec.rb' - - 'spec/models/stat_counter_spec.rb' - - 'spec/models/story_parser_spec.rb' - - 'spec/models/tag_set_nomination_spec.rb' - - 'spec/models/unsorted_tag_spec.rb' - -# Offense count: 129 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only -Layout/EmptyLinesAroundClassBody: - Exclude: - - 'app/controllers/admin/admin_invitations_controller.rb' - - 'app/controllers/admin/banners_controller.rb' - - 'app/controllers/admin/blacklisted_emails_controller.rb' - - 'app/controllers/admin/skins_controller.rb' - - 'app/controllers/admin/spam_controller.rb' - - 'app/controllers/admin_posts_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge/gift_exchange_controller.rb' - - 'app/controllers/challenge/prompt_meme_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/challenge_requests_controller.rb' - - 'app/controllers/challenges_controller.rb' - - 'app/controllers/collection_profile_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/downloads_controller.rb' - - 'app/controllers/feedbacks_controller.rb' - - 'app/controllers/gifts_controller.rb' - - 'app/controllers/home_controller.rb' - - 'app/controllers/known_issues_controller.rb' - - 'app/controllers/languages_controller.rb' - - 'app/controllers/locales_controller.rb' - - 'app/controllers/menu_controller.rb' - - 'app/controllers/opendoors/external_authors_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/people_controller.rb' - - 'app/controllers/potential_matches_controller.rb' - - 'app/controllers/profile_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/controllers/readings_controller.rb' - - 'app/controllers/redirect_controller.rb' - - 'app/controllers/related_works_controller.rb' - - 'app/controllers/serial_works_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/subscriptions_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/unsorted_tags_controller.rb' - - 'app/controllers/users/sessions_controller.rb' - - 'app/controllers/work_links_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/controllers/wrangling_guidelines_controller.rb' - - 'app/decorators/homepage.rb' - - 'app/decorators/pseud_decorator.rb' - - 'app/mailers/comment_mailer.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/admin_post_tag.rb' - - 'app/models/banned.rb' - - 'app/models/category.rb' - - 'app/models/challenge_signup_summary.rb' - - 'app/models/character.rb' - - 'app/models/collection_profile.rb' - - 'app/models/external_author_name.rb' - - 'app/models/external_creatorship.rb' - - 'app/models/fandom.rb' - - 'app/models/freeform.rb' - - 'app/models/gift.rb' - - 'app/models/indexing/cache_master.rb' - - 'app/models/indexing/index_queue.rb' - - 'app/models/indexing/scheduled_reindex_job.rb' - - 'app/models/log_item.rb' - - 'app/models/potential_match.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/rating.rb' - - 'app/models/redis_mail_queue.rb' - - 'app/models/relationship.rb' - - 'app/models/search/async_indexer.rb' - - 'app/models/search/bookmark_indexer.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/bookmarkable_indexer.rb' - - 'app/models/search/index_sweeper.rb' - - 'app/models/search/indexer.rb' - - 'app/models/search/pseud_indexer.rb' - - 'app/models/search/pseud_query.rb' - - 'app/models/search/pseud_search_form.rb' - - 'app/models/search/query.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/search/query_result.rb' - - 'app/models/search/tag_indexer.rb' - - 'app/models/search/tag_query.rb' - - 'app/models/search/tag_search_form.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/search_range.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/fandom_nomination.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/work_link.rb' - - 'app/sweepers/feed_sweeper.rb' - - 'app/sweepers/pseud_sweeper.rb' - - 'app/sweepers/tag_set_sweeper.rb' - - 'app/validators/url_active_validator.rb' - - 'app/validators/url_format_validator.rb' - - 'config/initializers/gem-plugin_config/permit_yo_config.rb' - - 'config/initializers/rack_attack.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'lib/word_counter.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -Layout/EmptyLinesAroundMethodBody: - Exclude: - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/models/skin.rb' - - 'app/models/skin_parent.rb' - -# Offense count: 38 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines -Layout/EmptyLinesAroundModuleBody: - Exclude: - - 'app/helpers/advanced_search_helper.rb' - - 'app/helpers/date_helper.rb' - - 'app/helpers/exports_helper.rb' - - 'app/helpers/external_authors_helper.rb' - - 'app/helpers/inbox_helper.rb' - - 'app/helpers/invitations_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'app/helpers/search_helper.rb' - - 'app/helpers/series_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tag_type_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/helpers/user_invite_requests_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/models/search/taggable_query.rb' - - 'config/initializers/gem-plugin_config/permit_yo_config.rb' - - 'config/initializers/monkeypatches/accept_header.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/acts_as_commentable/commentable_entity.rb' - - 'lib/bookmarkable.rb' - - 'lib/challenge_core.rb' - - 'lib/collectible.rb' - - 'lib/css_cleaner.rb' - - 'lib/redis_test_setup.rb' - - 'lib/searchable.rb' - - 'lib/string_cleaner.rb' - - 'lib/works_owner.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleAlignWith, Severity. -# SupportedStylesAlignWith: keyword, variable, start_of_line -Layout/EndAlignment: - Exclude: - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/user_invite_requests_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/external_authors_helper.rb' - - 'app/models/inbox_comment.rb' - -# Offense count: 34 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: native, lf, crlf -Layout/EndOfLine: - Exclude: - - 'app/controllers/abuse_reports_controller.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'app/jobs/hit_count_update_job.rb' - - 'app/jobs/readings_job.rb' - - 'app/jobs/redis_hash_job.rb' - - 'app/jobs/redis_job_spawner.rb' - - 'app/jobs/redis_set_job.rb' - - 'app/jobs/tag_count_update_job.rb' - - 'app/jobs/tag_method_job.rb' - - 'app/mailers/kudo_mailer.rb' - - 'app/models/admin_setting.rb' - - 'app/models/redis_hit_counter.rb' - - 'app/policies/tag_wrangler_policy.rb' - - 'config/environments/test.rb' - - 'config/routes.rb' - - 'db/migrate/20230106203903_drop_open_id_tables.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/reading_steps.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - - 'lib/redis_scanning.rb' - - 'spec/controllers/api/v2/api_works_spec.rb' - - 'spec/controllers/collection_items_controller_spec.rb' - - 'spec/jobs/hit_count_update_job_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/lib/i18n/i18n_tasks_spec.rb' - - 'spec/mailers/user_mailer_spec.rb' - - 'spec/models/admin_setting_spec.rb' - - 'spec/models/pseud_spec.rb' - - 'spec/models/redis_hit_counter_spec.rb' - - 'spec/models/tag_spec.rb' - - 'spec/spec_helper.rb' - - 'spec/support/i18n_newlines_tasks.rb' - -# Offense count: 27 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. -Layout/ExtraSpacing: - Exclude: - - 'Gemfile' - - 'app/controllers/application_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'config.ru' - - 'config/deploy.rb' - - 'config/schedule.rb' - - 'features/support/paths.rb' - - 'lib/tasks/memcached.rake' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/models/story_parser_spec.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses -Layout/FirstArgumentIndentation: - Exclude: - - 'app/helpers/comments_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/tag.rb' - - 'features/step_definitions/user_steps.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_brackets -Layout/FirstArrayElementIndentation: - Exclude: - - 'app/models/collection.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/skin.rb' - -# Offense count: 19 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_braces -Layout/FirstHashElementIndentation: - Exclude: - - 'app/controllers/comments_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/story_parser.rb' - - 'app/models/work.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - - 'spec/models/story_parser_spec.rb' - -# Offense count: 106 -# Cop supports --auto-correct. -# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. -# SupportedHashRocketStyles: key, separator, table -# SupportedColonStyles: key, separator, table -# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit -Layout/HashAlignment: - Exclude: - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/admin_post.rb' - - 'app/models/admin_setting.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/collection_participant.rb' - - 'app/models/download_writer.rb' - - 'app/models/feedback.rb' - - 'app/models/known_issue.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/preference.rb' - - 'app/models/profile.rb' - - 'app/models/pseud.rb' - - 'app/models/question.rb' - - 'app/models/search/pseud_query.rb' - - 'app/models/skin.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'lib/creation_notifier.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - - 'lib/otw_sanitize/media_sanitizer.rb' - - 'spec/controllers/api/v2/api_bookmarks_spec.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - - 'spec/models/search/pseud_decorator_spec.rb' - - 'spec/models/skin_spec.rb' - -# Offense count: 285 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: normal, indented_internal_methods -Layout/IndentationConsistency: - Exclude: - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/models/comment.rb' - - 'app/models/skin_parent.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/user.rb' - - 'config/initializers/gem-plugin_config/resque.rb' - - 'features/step_definitions/banner_steps.rb' - - 'features/step_definitions/challege_gift_exchange_steps.rb' - - 'features/step_definitions/challenge_promptmeme_steps.rb' - - 'features/step_definitions/challenge_steps.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/skin_steps.rb' - - 'features/step_definitions/tag_steps.rb' - - 'features/step_definitions/work_related_steps.rb' - - 'features/step_definitions/work_search_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'lib/tasks/opendoors.rake' - -# Offense count: 10 -# Cop supports --auto-correct. -# Configuration parameters: IndentationWidth, EnforcedStyle. -# SupportedStyles: spaces, tabs -Layout/IndentationStyle: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - -# Offense count: 62 -# Cop supports --auto-correct. -# Configuration parameters: Width, IgnoredPatterns. -Layout/IndentationWidth: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/external_works_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/external_authors_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/models/admin_post.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/collection.rb' - - 'app/models/comment.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/preference.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/skin_parent.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'features/step_definitions/tag_steps.rb' - - 'features/step_definitions/work_related_steps.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'lib/tasks/cucumber.rake' - - 'lib/tasks/memcached.rake' - - 'lib/tasks/resque.rake' - - 'spec/controllers/works/importing_spec.rb' - -# Offense count: 52 -# Cop supports --auto-correct. -# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment. -Layout/LeadingCommentSpace: - Exclude: - - 'Gemfile' - - 'app/controllers/profile_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/admin_setting.rb' - - 'app/models/comment.rb' - - 'app/models/external_work.rb' - - 'app/models/invitation.rb' - - 'app/models/invite_request.rb' - - 'app/models/tagset_models/freeform_nomination.rb' - - 'app/models/user.rb' - - 'app/models/user_invite_request.rb' - - 'app/models/work.rb' - - 'config/deploy.rb' - - 'config/deploy/production.rb' - - 'config/deploy/staging.rb' - - 'config/initializers/devise.rb' - - 'config/initializers/gem-plugin_config/escape_utils_config.rb' - - 'config/initializers/monkeypatches/translate_string.rb' - - 'db/migrate/20171031204025_create_moderated_works.rb' - - 'features/step_definitions/challenge_promptmeme_steps.rb' - - 'features/step_definitions/icon_steps.rb' - - 'features/step_definitions/pickle_steps.rb' - - 'lib/tasks/tag_tasks.rake' - - 'spec/models/search/work_query_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Layout/LeadingEmptyLines: - Exclude: - - 'features/step_definitions/challenge_promptmeme_steps.rb' - - 'features/step_definitions/challenge_yuletide_steps.rb' - -# Offense count: 23 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: aligned, indented -Layout/LineEndStringConcatenationIndentation: - Exclude: - - 'spec/controllers/prompts_controller_spec.rb' - - 'spec/controllers/tag_set_associations_controller_spec.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineArrayBraceLayout: - Exclude: - - 'app/controllers/challenge/prompt_meme_controller.rb' - - 'app/models/series.rb' - -# Offense count: 13 -# Cop supports --auto-correct. -Layout/MultilineBlockLayout: - Exclude: - - 'app/models/challenge_signup.rb' - - 'app/models/gift.rb' - - 'app/models/skin.rb' - - 'app/models/work.rb' - - 'spec/controllers/admin_posts_controller_spec.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - - 'spec/models/favorite_tag_spec.rb' - -# Offense count: 15 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineHashBraceLayout: - Exclude: - - 'app/controllers/api/v2/works_controller.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/favorite_tag.rb' - - 'spec/controllers/api/v2/api_bookmarks_spec.rb' - - 'spec/controllers/api/v2/api_works_spec.rb' - -# Offense count: 13 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineMethodCallBraceLayout: - Exclude: - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/questions_controller.rb' - - 'app/helpers/comments_helper.rb' - - 'app/models/collection.rb' - - 'app/models/pseud.rb' - - 'app/models/search/query_result.rb' - - 'app/models/work.rb' - - 'features/step_definitions/user_steps.rb' - - 'spec/models/collection_item_spec.rb' - -# Offense count: 127 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: aligned, indented, indented_relative_to_receiver -Layout/MultilineMethodCallIndentation: - Exclude: - - 'app/controllers/api/v2/bookmarks_controller.rb' - - 'app/controllers/creatorships_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/decorators/homepage.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/collection_participant.rb' - - 'app/models/fandom.rb' - - 'app/models/gift.rb' - - 'app/models/potential_match.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/related_work.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search_range.rb' - - 'app/models/series.rb' - - 'app/models/spam_report.rb' - - 'app/models/subscription.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'lib/html_cleaner.rb' - - 'lib/otw_sanitize/user_class_sanitizer.rb' - - 'spec/models/search/index_sweeper_spec.rb' - -# Offense count: 21 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: aligned, indented -Layout/MultilineOperationIndentation: - Exclude: - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/potential_matches_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/external_authors_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection_item.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'features/support/paths.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Layout/RescueEnsureAlignment: - Exclude: - - 'app/controllers/tags_controller.rb' - -# Offense count: 294 -# Cop supports --auto-correct. -Layout/SingleLineBlockChain: - Exclude: - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/exports_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'app/helpers/mute_helper.rb' - - 'app/helpers/pseuds_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/mailers/admin_mailer.rb' - - 'app/models/admin_post.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_signup_summary.rb' - - 'app/models/character.rb' - - 'app/models/collection.rb' - - 'app/models/concerns/filterable.rb' - - 'app/models/external_author.rb' - - 'app/models/freeform.rb' - - 'app/models/potential_match.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/relationship.rb' - - 'app/models/search/index_sweeper.rb' - - 'app/models/series.rb' - - 'app/models/skin.rb' - - 'app/models/spam_report.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/work.rb' - - 'lib/acts_as_commentable/commentable_entity.rb' - - 'lib/autocomplete_source.rb' - - 'lib/collectible.rb' - - 'lib/searchable.rb' - - 'lib/word_counter.rb' - - 'script/create_admin.rb' - - 'script/gift_exchange/load_json_challenge.rb' - - 'spec/controllers/admin/admin_users_controller_spec.rb' - - 'spec/controllers/admin/banners_controller_spec.rb' - - 'spec/controllers/admin/blacklisted_emails_controller_spec.rb' - - 'spec/controllers/admin/skins_controller_spec.rb' - - 'spec/controllers/admin/user_creations_controller_spec.rb' - - 'spec/controllers/admin_posts_controller_spec.rb' - - 'spec/controllers/archive_faqs_controller_spec.rb' - - 'spec/controllers/bookmarks_controller_spec.rb' - - 'spec/controllers/challenge_assignments_controller_spec.rb' - - 'spec/controllers/chapters_controller_spec.rb' - - 'spec/controllers/collection_items_controller_spec.rb' - - 'spec/controllers/comments_controller_blocking_spec.rb' - - 'spec/controllers/comments_controller_spec.rb' - - 'spec/controllers/creatorships_controller_spec.rb' - - 'spec/controllers/invite_requests_controller_spec.rb' - - 'spec/controllers/skins_controller_spec.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - - 'spec/controllers/works/default_rails_actions_spec.rb' - - 'spec/controllers/works/importing_spec.rb' - - 'spec/controllers/works/multiple_actions_spec.rb' - - 'spec/lib/i18n/i18n_tasks_spec.rb' - - 'spec/lib/tasks/admin_tasks.rake_spec.rb' - - 'spec/lib/tasks/after_tasks.rake_spec.rb' - - 'spec/lib/tasks/creatorships.rake_spec.rb' - - 'spec/lib/tasks/opendoors.rake_spec.rb' - - 'spec/lib/tasks/resanitize.rake_spec.rb' - - 'spec/lib/tasks/skin_tasks.rake_spec.rb' - - 'spec/lib/tasks/tag_tasks.rake_spec.rb' - - 'spec/lib/tasks/work_tasks.rake_spec.rb' - - 'spec/models/admin_spec.rb' - - 'spec/models/comment_spec.rb' - - 'spec/models/creatorship_spec.rb' - - 'spec/models/search/bookmark_indexer_spec.rb' - - 'spec/models/search/index_sweeper_spec.rb' - - 'spec/models/search/pseud_indexer_spec.rb' - - 'spec/models/search/stat_counter_indexer_spec.rb' - - 'spec/models/search/work_indexer_spec.rb' - - 'spec/models/serial_work_spec.rb' - - 'spec/models/story_parser_spec.rb' - - 'spec/models/subscription_spec.rb' - - 'spec/models/work_spec.rb' - - 'spec/support/shared_examples/mailer_shared_examples.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -Layout/SpaceAfterColon: - Exclude: - - 'app/helpers/validation_helper.rb' - - 'app/models/search/pseud_query.rb' - - 'spec/controllers/admin_posts_controller_spec.rb' - - 'spec/models/search/bookmark_query_spec.rb' - -# Offense count: 33 -# Cop supports --auto-correct. -Layout/SpaceAfterComma: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/subscriptions_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/models/admin_blacklisted_email.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/skin.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/validators/email_blacklist_validator.rb' - - 'app/validators/email_veracity_validator.rb' - - 'app/validators/url_active_validator.rb' - - 'app/validators/url_format_validator.rb' - - 'features/step_definitions/web_steps.rb' - - 'lib/html_cleaner.rb' - - 'lib/tasks/resque.rake' - - 'lib/url_formatter.rb' - - 'spec/models/collection_spec.rb' - - 'spec/models/moderated_work_spec.rb' - - 'spec/models/search/index_sweeper_spec.rb' - - 'spec/models/work_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Layout/SpaceAfterMethodName: - Exclude: - - 'app/controllers/application_controller.rb' - - 'lib/url_formatter.rb' - -# Offense count: 68 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: space, no_space -Layout/SpaceAroundEqualsInParameterDefault: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/search_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/admin_activity.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/creatorship.rb' - - 'app/models/external_work.rb' - - 'app/models/invitation.rb' - - 'app/models/invite_request.rb' - - 'app/models/locale.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/search/pseud_search_form.rb' - - 'app/models/search/query.rb' - - 'app/models/search/query_result.rb' - - 'app/models/search/tag_search_form.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/skin.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/work.rb' - - 'app/models/work_link.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'lib/works_owner.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Layout/SpaceAroundMethodCallOperator: - Exclude: - - 'spec/controllers/collection_participants_controller_spec.rb' - -# Offense count: 68 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator. -# SupportedStylesForExponentOperator: space, no_space -Layout/SpaceAroundOperators: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/opendoors/external_authors_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/chapter.rb' - - 'app/models/invite_request.rb' - - 'app/models/skin.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'features/step_definitions/generic_steps.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'features/support/vcr.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/autocomplete_source.rb' - - 'lib/sortable_list.rb' - - 'lib/tasks/memcached.rake' - - 'lib/tasks/resque.rake' - - 'spec/lib/word_counter_spec.rb' - - 'spec/models/search/pseud_decorator_spec.rb' - -# Offense count: 35 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. -# SupportedStyles: space, no_space -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceBeforeBlockBraces: - Exclude: - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/admin_post.rb' - - 'app/models/chapter.rb' - - 'app/models/indexing/scheduled_reindex_job.rb' - - 'app/models/pseud.rb' - - 'app/models/relationship.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/series.rb' - - 'app/models/tag.rb' - - 'features/step_definitions/web_steps.rb' - - 'lib/collectible.rb' - - 'spec/models/work_spec.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Layout/SpaceBeforeComma: - Exclude: - - 'app/helpers/tags_helper.rb' - - 'app/models/external_creatorship.rb' - - 'app/models/work.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment. -Layout/SpaceBeforeFirstArg: - Exclude: - - 'spec/models/story_parser_spec.rb' - -# Offense count: 22 -# Cop supports --auto-correct. -Layout/SpaceBeforeSemicolon: - Exclude: - - 'app/models/collection.rb' - - 'app/models/collection_participant.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: require_no_space, require_space -Layout/SpaceInLambdaLiteral: - Exclude: - - 'app/models/pseud.rb' - - 'app/models/user.rb' - -# Offense count: 53 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets. -# SupportedStyles: space, no_space, compact -# SupportedStylesForEmptyBrackets: space, no_space -Layout/SpaceInsideArrayLiteralBrackets: - Exclude: - - 'app/controllers/challenge/prompt_meme_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/series_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/models/collection.rb' - - 'app/models/collection_participant.rb' - - 'app/models/pseud.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'spec/controllers/api/v2/api_bookmarks_spec.rb' - -# Offense count: 386 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. -# SupportedStyles: space, no_space -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceInsideBlockBraces: - Exclude: - - 'app/controllers/admin/skins_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/unsorted_tags_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/pseuds_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/character.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/collection_participant.rb' - - 'app/models/external_author.rb' - - 'app/models/external_work.rb' - - 'app/models/fandom.rb' - - 'app/models/freeform.rb' - - 'app/models/gift.rb' - - 'app/models/potential_match.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/relationship.rb' - - 'app/models/series.rb' - - 'app/models/skin.rb' - - 'app/models/subscription.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/fandom_nomination.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/work.rb' - - 'app/models/work_skin.rb' - - 'app/sweepers/tag_set_sweeper.rb' - - 'app/validators/url_active_validator.rb' - - 'features/step_definitions/challege_gift_exchange_steps.rb' - - 'features/step_definitions/generic_steps.rb' - - 'features/step_definitions/web_steps.rb' - - 'lib/acts_as_commentable/commentable_entity.rb' - - 'lib/autocomplete_source.rb' - - 'lib/collectible.rb' - - 'lib/css_cleaner.rb' - - 'lib/sortable_list.rb' - - 'lib/tasks/cucumber.rake' - - 'lib/tasks/resque.rake' - - 'lib/tasks/skin_tasks.rake' - - 'spec/lib/works_owner_spec.rb' - - 'spec/models/abuse_report_spec.rb' - - 'spec/models/admin_blacklisted_email_spec.rb' - - 'spec/models/external_work_spec.rb' - - 'spec/models/invitation_spec.rb' - -# Offense count: 195 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. -# SupportedStyles: space, no_space, compact -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceInsideHashLiteralBraces: - Exclude: - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/media_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/comment.rb' - - 'app/models/gift.rb' - - 'app/models/language.rb' - - 'app/models/locale.rb' - - 'app/models/prompt.rb' - - 'app/models/redis_mail_queue.rb' - - 'app/models/skin.rb' - - 'app/models/skin_parent.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/user_invite_request.rb' - - 'app/models/work.rb' - - 'app/models/work_skin.rb' - - 'config/deploy.rb' - - 'config/deploy/production.rb' - - 'config/initializers/gem-plugin_config/permit_yo_config.rb' - - 'config/initializers/monkeypatches/override_default_form_field_sizes.rb' - - 'lib/autocomplete_source.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'lib/sortable_list.rb' - - 'lib/tasks/cucumber.rake' - - 'spec/controllers/series_controller_spec.rb' - - 'spec/controllers/works/default_rails_actions_spec.rb' - - 'spec/models/search/bookmark_query_spec.rb' - - 'spec/models/search/work_query_spec.rb' - -# Offense count: 30 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: space, compact, no_space -Layout/SpaceInsideParens: - Exclude: - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/kudo.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'features/step_definitions/tag_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: space, no_space -Layout/SpaceInsideStringInterpolation: - Exclude: - - 'app/models/redis_mail_queue.rb' - - 'config/initializers/active_record_log_subscriber.rb' - -# Offense count: 22 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: final_newline, final_blank_line -Layout/TrailingEmptyLines: - Exclude: - - 'Capfile' - - 'app/controllers/menu_controller.rb' - - 'app/models/category.rb' - - 'app/models/indexing/scheduled_reindex_job.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/character_nomination.rb' - - 'app/models/tagset_models/freeform_nomination.rb' - - 'app/models/tagset_models/relationship_nomination.rb' - - 'app/views/admin_posts/index.rss.builder' - - 'config/initializers/gem-plugin_config/escape_utils_config.rb' - - 'config/initializers/gem-plugin_config/newrelic.rb' - - 'features/step_definitions/banner_steps.rb' - - 'features/step_definitions/challenge_yuletide_steps.rb' - - 'features/support/env.rb' - - 'lib/responder.rb' - - 'lib/sortable_list.rb' - - 'lib/string_cleaner.rb' - - 'lib/tasks/notifications.rake' - - 'public/dispatch.rb' - - 'spec/models/challenge_claim_spec.rb' - - 'spec/models/gift_spec.rb' - - 'spec/models/skin_spec.rb' - -# Offense count: 1 -# Configuration parameters: IgnoredMethods. -Lint/AmbiguousBlockAssociation: - Exclude: - - 'app/controllers/autocomplete_controller.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Lint/AmbiguousOperator: - Exclude: - - 'app/models/admin_setting.rb' - -# Offense count: 34 -# Cop supports --auto-correct. -Lint/AmbiguousOperatorPrecedence: - Exclude: - - 'app/controllers/api/v2/bookmarks_controller.rb' - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/invitations_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/potential_matcher/potential_matcher_constrained.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/skin.rb' - - 'app/models/tag.rb' - - 'app/models/work.rb' - - 'app/policies/skin_policy.rb' - - 'config/initializers/gem-plugin_config/redis.rb' - - 'config/initializers/gem-plugin_config/resque.rb' - - 'lib/autocomplete_source.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'spec/models/tag_spec.rb' - -# Offense count: 9 -# Configuration parameters: AllowSafeAssignment. -Lint/AssignmentInCondition: - Exclude: - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/search_range.rb' - - 'app/models/tag.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - -# Offense count: 11 -# Cop supports --auto-correct. -Lint/BooleanSymbol: - Exclude: - - 'app/models/bookmark.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/tagset_models/owned_set_tagging.rb' - -# Offense count: 10 -# Configuration parameters: AllowedMethods. -# AllowedMethods: enums -Lint/ConstantDefinitionInBlock: - Exclude: - - 'lib/tasks/load_autocomplete_data.rake' - - 'lib/tasks/opendoors.rake' - - 'lib/tasks/search.rake' - - 'spec/models/story_parser_spec.rb' - - 'spec/spec_helper.rb' - -# Offense count: 2 -# Configuration parameters: DebuggerReceivers, DebuggerMethods. -Lint/Debugger: - Exclude: - - 'features/step_definitions/generic_steps.rb' - - 'features/step_definitions/web_steps.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Lint/DeprecatedClassMethods: - Exclude: - - 'app/helpers/application_helper.rb' - - 'lib/tasks/skin_tasks.rake' - -# Offense count: 20 -# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches. -Lint/DuplicateBranch: - Exclude: - - 'app/controllers/comments_controller.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/skin.rb' - - 'features/step_definitions/autocomplete_steps.rb' - - 'features/support/paths.rb' - - 'script/get_user_data.rb' - -# Offense count: 2 -Lint/DuplicateMethods: - Exclude: - - 'app/models/feedback_reporters/feedback_reporter.rb' - -# Offense count: 5 -# Configuration parameters: AllowComments, AllowEmptyLambdas. -Lint/EmptyBlock: - Exclude: - - 'factories/challenge_claims.rb' - - 'factories/prompt_restriction.rb' - - 'features/step_definitions/comment_steps.rb' - - 'lib/tasks/cucumber.rake' - - 'lib/tasks/search.rake' - -# Offense count: 2 -# Configuration parameters: AllowComments. -Lint/EmptyConditionalBody: - Exclude: - - 'db/migrate/20200115232918_add_user_id_to_kudos.rb' - -# Offense count: 6 -Lint/ImplicitStringConcatenation: - Exclude: - - 'spec/lib/html_cleaner_spec.rb' - -# Offense count: 6 -Lint/IneffectiveAccessModifier: - Exclude: - - 'app/models/potential_match.rb' - - 'app/models/user.rb' - - 'app/sweepers/collection_sweeper.rb' - -# Offense count: 2 -Lint/MissingSuper: - Exclude: - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/bookmarkable_query.rb' - -# Offense count: 1 -Lint/MixedRegexpCaptureTypes: - Exclude: - - 'app/models/story_parser.rb' - -# Offense count: 8 -Lint/NonLocalExitFromIterator: - Exclude: - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/models/prompt_restriction.rb' - - 'lib/collectible.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Lint/OrderedMagicComments: - Exclude: - - 'spec/helpers/exports_helper_spec.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -Lint/ParenthesesAsGroupedExpression: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/related_works_controller.rb' - - 'config/deploy.rb' - - 'features/step_definitions/admin_steps.rb' - - 'features/step_definitions/email_steps.rb' - - 'features/step_definitions/profile_steps.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: AllowedImplicitNamespaces. -# AllowedImplicitNamespaces: Gem -Lint/RaiseException: - Exclude: - - 'app/models/series.rb' - - 'app/models/work.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Lint/RedundantDirGlobSort: - Exclude: - - 'spec/spec_helper.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: AllowedMethods. -# AllowedMethods: instance_of?, kind_of?, is_a?, eql?, respond_to?, equal? -Lint/RedundantSafeNavigation: - Exclude: - - 'app/helpers/application_helper.rb' - - 'app/policies/application_policy.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -Lint/RedundantStringCoercion: - Exclude: - - 'app/helpers/application_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'features/step_definitions/work_steps.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Lint/RedundantWithIndex: - Exclude: - - 'app/models/tagset_models/owned_tag_set.rb' - -# Offense count: 4 -Lint/RescueException: - Exclude: - - 'app/controllers/series_controller.rb' - - 'app/models/invitation.rb' - - 'app/validators/email_veracity_validator.rb' - - 'lib/tasks/resque.rake' - -# Offense count: 2 -# Cop supports --auto-correct. -Lint/ScriptPermission: - Exclude: - - 'public/dispatch.fcgi' - - 'public/dispatch.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Lint/SendWithMixinArgument: - Exclude: - - 'config/initializers/active_record_log_subscriber.rb' - -# Offense count: 2 -# Configuration parameters: IgnoreImplicitReferences. -Lint/ShadowedArgument: - Exclude: - - 'features/step_definitions/web_steps.rb' - -# Offense count: 3 -Lint/ShadowingOuterLocalVariable: - Exclude: - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/works_controller.rb' - -# Offense count: 2 -Lint/StructNewOverride: - Exclude: - - 'app/models/search/query_facet.rb' - - 'script/gift_exchange/generate_from_spec.rb' - -# Offense count: 3 -# Configuration parameters: AllowComments, AllowNil. -Lint/SuppressedException: - Exclude: - - 'app/controllers/opendoors/tools_controller.rb' - - 'app/models/redis_mail_queue.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Lint/TripleQuotes: - Exclude: - - 'spec/lib/html_cleaner_spec.rb' - -# Offense count: 2 -# Configuration parameters: Methods. -Lint/UnexpectedBlockArity: - Exclude: - - 'app/models/tagset_models/owned_tag_set.rb' - - 'spec/requests/comments_n_plus_one_spec.rb' - -# Offense count: 25 -# Cop supports --auto-correct. -# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. -Lint/UnusedBlockArgument: - Exclude: - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/unsorted_tags_controller.rb' - - 'app/helpers/validation_helper.rb' - - 'app/mailers/kudo_mailer.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/indexing/index_queue.rb' - - 'app/models/search/query.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'config.ru' - - 'factories/collections.rb' - - 'factories/wrangling_guideline.rb' - - 'features/step_definitions/archivist_steps.rb' - - 'features/step_definitions/challege_gift_exchange_steps.rb' - - 'features/step_definitions/challenge_promptmeme_steps.rb' - - 'features/step_definitions/skin_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/url_formatter.rb' - -# Offense count: 17 -# Cop supports --auto-correct. -# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods. -Lint/UnusedMethodArgument: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_models/prompt_meme.rb' - - 'app/models/external_author.rb' - - 'app/models/fandom.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/work.rb' - - 'features/step_definitions/invite_steps.rb' - - 'lib/challenge_core.rb' - - 'lib/collectible.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Lint/UriRegexp: - Exclude: - - 'app/models/collection.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. -Lint/UselessAccessModifier: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/potential_match.rb' - - 'app/models/work.rb' - -# Offense count: 38 -Lint/UselessAssignment: - Exclude: - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/date_helper.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/pseuds_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/comment.rb' - - 'app/models/external_author.rb' - - 'app/models/feedback.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/redis_mail_queue.rb' - - 'app/models/skin.rb' - - 'app/models/subscription.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/validators/email_veracity_validator.rb' - - 'features/step_definitions/profile_steps.rb' - - 'features/step_definitions/tag_steps.rb' - - 'features/step_definitions/user_steps.rb' - - 'features/support/paths.rb' - - 'lib/tasks/skin_tasks.rake' - - 'lib/tasks/work_tasks.rake' - -# Offense count: 1 -# Cop supports --auto-correct. -Lint/UselessTimes: - Exclude: - - 'app/controllers/archive_faqs_controller.rb' - -# Offense count: 30 -# Configuration parameters: CountBlocks, Max. -Metrics/BlockNesting: - Exclude: - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/comment.rb' - - 'app/models/creatorship.rb' - - 'app/models/skin.rb' - - 'app/models/work.rb' - - 'lib/autocomplete_source.rb' - - 'lib/css_cleaner.rb' - -# Offense count: 6 -# Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters. -Metrics/ParameterLists: - Exclude: - - 'app/models/potential_match.rb' - - 'app/models/reading.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/work_steps.rb' - -# Offense count: 40 -Naming/AccessorMethodName: - Exclude: - - 'app/controllers/admin/user_creations_controller.rb' - - 'app/controllers/external_authors_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/related_works_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/helpers/date_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/collection.rb' - - 'app/models/concerns/creatable.rb' - - 'app/models/download.rb' - - 'app/models/download_writer.rb' - - 'app/models/indexing/cache_master.rb' - - 'app/models/locale.rb' - - 'app/models/potential_match.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/skin.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/work.rb' - - 'lib/collectible.rb' - - 'lib/responder.rb' - - 'lib/tasks/skin_tasks.rake' - -# Offense count: 2 -# Cop supports --auto-correct. -Naming/BinaryOperatorParameterName: - Exclude: - - 'app/models/tag.rb' - - 'app/models/work.rb' - -# Offense count: 3 -# Configuration parameters: ForbiddenDelimiters. -# ForbiddenDelimiters: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$)) -Naming/HeredocDelimiterNaming: - Exclude: - - 'spec/helpers/validation_helper_spec.rb' - -# Offense count: 1 -# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: at, by, db, id, in, io, ip, of, on, os, pp, to -Naming/MethodParameterName: - Exclude: - - 'config/initializers/gem-plugin_config/escape_utils_config.rb' - -# Offense count: 34 -# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros. -# NamePrefix: is_, has_, have_ -# ForbiddenPrefixes: is_, has_, have_ -# AllowedMethods: is_a? -# MethodDefinitionMacros: define_method, define_singleton_method -Naming/PredicateName: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/helpers/users_helper.rb' - - 'app/models/admin_blacklisted_email.rb' - - 'app/models/chapter.rb' - - 'app/models/collection_participant.rb' - - 'app/models/comment.rb' - - 'app/models/gift.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'config/initializers/gem-plugin_config/permit_yo_config.rb' - - 'lib/acts_as_commentable/commentable.rb' - - 'lib/autocomplete_source.rb' - - 'lib/css_cleaner.rb' - -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: PreferredName. -Naming/RescuedExceptionsVariableName: - Exclude: - - 'app/controllers/api/v2/bookmarks_controller.rb' - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/series_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/models/invitation.rb' - - 'app/models/story_parser.rb' - -# Offense count: 52 -# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers. -# SupportedStyles: snake_case, normalcase, non_integer -# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339 -Naming/VariableNumber: - Exclude: - - 'app/controllers/users/registrations_controller.rb' - - 'app/models/user.rb' - - 'spec/controllers/inbox_controller_spec.rb' - - 'spec/controllers/invite_requests_controller_spec.rb' - - 'spec/controllers/tag_set_associations_controller_spec.rb' - - 'spec/controllers/users/registrations_controller_spec.rb' - - 'spec/controllers/works/default_rails_actions_spec.rb' - - 'spec/controllers/wrangling_guidelines_controller_spec.rb' - - 'spec/models/search/pseud_query_spec.rb' - - 'spec/models/search/pseud_search_form_spec.rb' - - 'spec/models/search/work_search_form_spec.rb' - - 'spec/models/user_spec.rb' - -# Offense count: 4 -# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly. -# Include: **/*_spec*rb*, **/spec/**/* -RSpec/FilePath: - Exclude: - - 'spec/controllers/api/v2/api_base_controller_spec.rb' - - 'spec/controllers/gift_exchange_controller_spec.rb' - - 'spec/controllers/prompt_meme_controller_spec.rb' - - 'spec/lib/string_cleaner_spec.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: numeric, symbolic -RSpec/Rails/HttpStatus: - Exclude: - - 'spec/controllers/prompts_controller_spec.rb' - - 'spec/controllers/works/drafts_spec.rb' - -# Offense count: 40 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/ActiveRecordCallbacksOrder: - Exclude: - - 'app/models/admin_banner.rb' - - 'app/models/admin_post.rb' - - 'app/models/bookmark.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/comment.rb' - - 'app/models/fandom.rb' - - 'app/models/favorite_tag.rb' - - 'app/models/kudo.rb' - - 'app/models/reading.rb' - - 'app/models/serial_work.rb' - - 'app/models/series.rb' - - 'app/models/skin.rb' - - 'app/models/tag.rb' - - 'app/models/tagging.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Rails/ApplicationRecord: - Exclude: - - 'app/models/related_work.rb' - -# Offense count: 36 -# Cop supports --auto-correct. -# Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent. -Rails/Blank: - Exclude: - - 'app/controllers/api/v2/base_controller.rb' - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/people_controller.rb' - - 'app/controllers/questions_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/decorators/pseud_decorator.rb' - - 'app/models/moderated_work.rb' - - 'app/models/potential_matcher/prompt_tag_type_info.rb' - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/index_sweeper.rb' - - 'app/models/search/pseud_search_form.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/search/work_query.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/skin.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/work.rb' - - 'app/sweepers/feed_sweeper.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'lib/responder.rb' - - 'lib/word_counter.rb' - - 'script/gift_exchange/generate_from_spec.rb' - -# Offense count: 22 -# Configuration parameters: Database, Include. -# SupportedDatabases: mysql, postgresql -# Include: db/migrate/*.rb -Rails/BulkChangeTable: - Exclude: - - 'db/migrate/20170322092920_rename_taggings_count_to_taggings_count_cache.rb' - - 'db/migrate/20170919143944_add_indexes_to_nominations.rb' - - 'db/migrate/20180811160316_add_sortable_name_to_languages.rb' - - 'db/migrate/20180822202259_add_disable_support_form_to_admin_settings.rb' - - 'db/migrate/20181017032400_moves_users_to_devise.rb' - - 'db/migrate/20181113063726_rename_columns_that_do_not_allow_css.rb' - - 'db/migrate/20181222042042_add_unique_index_to_user_confirmation_tokens.rb' - - 'db/migrate/20181224173813_add_unique_index_to_user_emails.rb' - - 'db/migrate/20190213230717_rename_warnings_on_prompt_restrictions.rb' - - 'db/migrate/20190214054439_rename_warnings_on_potential_match_settings.rb' - - 'db/migrate/20190611212339_add_unique_index_to_meta_taggings.rb' - - 'db/migrate/20200707213354_add_unique_indices_to_admin_login_email.rb' - - 'db/migrate/20201210140123_add_organizational_fields_to_collections.rb' - - 'db/migrate/20210902040827_index_tag_set_nominations.rb' - - 'db/migrate/20221218033319_add_recoverable_lockable_to_admins.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Rails/ContentTag: - Exclude: - - 'lib/pagination_list_link_renderer.rb' - -# Offense count: 2 -# Configuration parameters: Include. -# Include: db/migrate/*.rb -Rails/CreateTableWithTimestamps: - Exclude: - - 'db/migrate/20141127004302_create_fannish_next_of_kins.rb' - - 'db/migrate/20150725141326_install_audited.rb' - -# Offense count: 3 -# Configuration parameters: EnforcedStyle, AllowToTime. -# SupportedStyles: strict, flexible -Rails/Date: - Exclude: - - 'app/models/admin_setting.rb' - - 'app/models/invite_request.rb' - -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: EnforceForPrefixed. -Rails/Delegate: - Exclude: - - 'app/models/challenge_signup.rb' - - 'app/models/search/query_result.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - -# Offense count: 23 -# Cop supports --auto-correct. -# Configuration parameters: Whitelist, AllowedMethods, AllowedReceivers. -# Whitelist: find_by_sql -# AllowedMethods: find_by_sql -# AllowedReceivers: Gem::Specification -Rails/DynamicFindBy: - Exclude: - - 'app/controllers/opendoors/tools_controller.rb' - - 'app/controllers/questions_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/models/external_author.rb' - - 'features/step_definitions/admin_steps.rb' - - 'features/step_definitions/external_work_steps.rb' - - 'features/step_definitions/work_download_steps.rb' - - 'features/step_definitions/work_related_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/tasks/skin_tasks.rake' - - 'spec/controllers/wrangling_guidelines_controller_spec.rb' - -# Offense count: 11 -# Cop supports --auto-correct. -Rails/EagerEvaluationLogMessage: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/models/pseud.rb' - - 'app/models/user.rb' - - 'app/sweepers/collection_sweeper.rb' - - 'lib/autocomplete_source.rb' - - 'lib/html_cleaner.rb' - -# Offense count: 1 -# Configuration parameters: Include, AllowReads, AllowWrites. -# Include: app/**/*.rb, lib/**/*.rb -Rails/EnvironmentVariableAccess: - Exclude: - - 'app/controllers/hit_count_controller.rb' - -# Offense count: 1 -# Configuration parameters: Include. -# Include: app/**/*.rb, config/**/*.rb, lib/**/*.rb -Rails/Exit: - Exclude: - - 'config/boot.rb' - -# Offense count: 11 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: slashes, arguments -Rails/FilePath: - Exclude: - - 'app/models/collection.rb' - - 'app/models/pseud.rb' - - 'app/models/skin.rb' - - 'config/initializers/active_record_log_subscriber.rb' - - 'features/step_definitions/fixtures_steps.rb' - - 'lib/tasks/cucumber.rake' - - 'lib/tasks/resque.rake' - -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: Include, IgnoredMethods. -# Include: app/models/**/*.rb -# IgnoredMethods: order, limit, select, lock -Rails/FindEach: - Exclude: - - 'app/models/filter_count.rb' - - 'app/models/inherited_meta_tag_updater.rb' - - 'app/models/moderated_work.rb' - - 'app/models/pseud.rb' - - 'app/models/scheduled_tag_job.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/user.rb' - -# Offense count: 57 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/HasManyOrHasOneDependent: - Exclude: - - 'app/models/admin.rb' - - 'app/models/admin_post.rb' - - 'app/models/admin_post_tag.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_models/prompt_meme.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/comment.rb' - - 'app/models/concerns/creatable.rb' - - 'app/models/concerns/filterable.rb' - - 'app/models/external_author.rb' - - 'app/models/external_author_name.rb' - - 'app/models/external_work.rb' - - 'app/models/fandom.rb' - - 'app/models/language.rb' - - 'app/models/media.rb' - - 'app/models/pseud.rb' - - 'app/models/role.rb' - - 'app/models/skin.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'app/models/work_skin.rb' - -# Offense count: 44 -# Configuration parameters: Include. -# Include: app/helpers/**/*.rb -Rails/HelperInstanceVariable: - Exclude: - - 'app/helpers/advanced_search_helper.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/pseuds_helper.rb' - - 'app/helpers/search_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/users_helper.rb' - - 'app/helpers/works_helper.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: numeric, symbolic -Rails/HttpStatus: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/locales_controller.rb' - -# Offense count: 6 -# Configuration parameters: Include. -# Include: spec/**/*.rb, test/**/*.rb -Rails/I18nLocaleAssignment: - Exclude: - - 'spec/mailers/user_mailer_spec.rb' - - 'spec/models/archive_faq_spec.rb' - - 'spec/spec_helper.rb' - -# Offense count: 29 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/InverseOf: - Exclude: - - 'app/models/admin_post.rb' - - 'app/models/admin_setting.rb' - - 'app/models/archive_faq.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/comment.rb' - - 'app/models/concerns/filterable.rb' - - 'app/models/external_creatorship.rb' - - 'app/models/pseud.rb' - - 'app/models/tag.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - -# Offense count: 8 -# Configuration parameters: Include. -# Include: app/controllers/**/*.rb -Rails/LexicallyScopedActionFilter: - Exclude: - - 'app/controllers/admin/sessions_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/external_authors_controller.rb' - - 'app/controllers/opendoors/external_authors_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/questions_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Rails/LinkToBlank: - Exclude: - - 'app/helpers/challenge_helper.rb' - -# Offense count: 17 -# Cop supports --auto-correct. -Rails/NegateInclude: - Exclude: - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/admin_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/creatorship.rb' - - 'app/models/search/index_sweeper.rb' - - 'app/models/skin.rb' - - 'app/models/skin_parent.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'config/initializers/active_record_log_subscriber.rb' - - 'config/locales/rails-i18n/pluralization/hr.rb' - - 'features/step_definitions/autocomplete_steps.rb' - - 'lib/collectible.rb' - - 'lib/css_cleaner.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb -Rails/Output: - Exclude: - - 'app/models/search/indexer.rb' - - 'config/deploy.rb' - - 'config/initializers/monkeypatches/fix_phraseapp.rb' - - 'config/initializers/monkeypatches/mail_disable_starttls.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Rails/Pick: - Exclude: - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/models/series.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Rails/Pluck: - Exclude: - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/skins_controller.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Rails/PluralizationGrammar: - Exclude: - - 'config/schedule.rb' - -# Offense count: 24 -# Cop supports --auto-correct. -Rails/Presence: - Exclude: - - 'app/controllers/api/v2/bookmarks_controller.rb' - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/helpers/admin_post_helper.rb' - - 'app/models/chapter.rb' - - 'app/models/pseud.rb' - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/work_query.rb' - - 'app/models/story_parser.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/validators/url_active_validator.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/work_steps.rb' - -# Offense count: 117 -# Cop supports --auto-correct. -# Configuration parameters: NotNilAndNotEmpty, NotBlank, UnlessBlank. -Rails/Present: - Exclude: - - 'app/controllers/admin/admin_invitations_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/invitations_controller.rb' - - 'app/controllers/opendoors/tools_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/unsorted_tags_controller.rb' - - 'app/controllers/user_invite_requests_controller.rb' - - 'app/controllers/users/registrations_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/admin_post_tag.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/gift.rb' - - 'app/models/indexing/index_queue.rb' - - 'app/models/invitation.rb' - - 'app/models/search/query_result.rb' - - 'app/models/search/work_query.rb' - - 'app/models/serial_work.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'features/step_definitions/banner_steps.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/icon_steps.rb' - - 'features/step_definitions/work_import_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/css_cleaner.rb' - - 'lib/tasks/tag_tasks.rake' - - 'script/get_user_data.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/ReadWriteAttribute: - Exclude: - - 'app/models/collection.rb' - - 'app/models/external_work.rb' - - 'app/models/series.rb' - - 'app/models/work.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/RedundantAllowNil: - Exclude: - - 'app/models/skin.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Rails/RedundantForeignKey: - Exclude: - - 'app/models/external_creatorship.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: AutoCorrect. -Rails/RelativeDateConstant: - Exclude: - - 'app/models/search_range.rb' - -# Offense count: 3 -# Configuration parameters: Include. -# Include: db/migrate/*.rb -Rails/ReversibleMigrationMethodDefinition: - Exclude: - - 'db/migrate/20150725141326_install_audited.rb' - - 'db/migrate/20160706031054_move_admins_to_devise.rb' - - 'db/migrate/20170414154143_add_request_uuid_to_audits.rb' - -# Offense count: 43 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: strict, flexible -Rails/TimeZone: - Exclude: - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/helpers/translation_helper.rb' - - 'app/models/admin_setting.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_signup_summary.rb' - - 'app/models/collection.rb' - - 'app/models/invitation.rb' - - 'app/models/invite_request.rb' - - 'app/models/pseud.rb' - - 'app/models/reading.rb' - - 'app/models/story_parser.rb' - - 'app/models/work.rb' - - 'factories/challenges.rb' - - 'features/step_definitions/admin_steps.rb' - - 'features/step_definitions/challenge_promptmeme_steps.rb' - - 'features/step_definitions/invite_steps.rb' - - 'features/support/elapsed_time.rb' - - 'features/support/formatter.rb' - - 'spec/controllers/api/v2/api_works_spec.rb' - - 'spec/controllers/inbox_controller_spec.rb' - - 'spec/models/collection_spec.rb' - -# Offense count: 13 -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/UniqueValidationWithoutIndex: - Exclude: - - 'app/models/admin_post_tag.rb' - - 'app/models/collection.rb' - - 'app/models/comment.rb' - - 'app/models/external_author.rb' - - 'app/models/external_author_name.rb' - - 'app/models/invite_request.rb' - - 'app/models/language.rb' - - 'app/models/locale.rb' - - 'app/models/moderated_work.rb' - - 'app/models/pseud.rb' - - 'app/models/skin.rb' - - 'app/models/skin_parent.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - -# Offense count: 174 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/Validation: - Exclude: - - 'app/models/abuse_report.rb' - - 'app/models/admin.rb' - - 'app/models/admin_activity.rb' - - 'app/models/admin_banner.rb' - - 'app/models/admin_post.rb' - - 'app/models/admin_post_tag.rb' - - 'app/models/admin_setting.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_models/prompt_meme.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/collection_participant.rb' - - 'app/models/collection_profile.rb' - - 'app/models/comment.rb' - - 'app/models/common_tagging.rb' - - 'app/models/creatorship.rb' - - 'app/models/external_author_name.rb' - - 'app/models/external_work.rb' - - 'app/models/feedback.rb' - - 'app/models/filter_count.rb' - - 'app/models/filter_tagging.rb' - - 'app/models/gift.rb' - - 'app/models/inbox_comment.rb' - - 'app/models/known_issue.rb' - - 'app/models/language.rb' - - 'app/models/locale.rb' - - 'app/models/log_item.rb' - - 'app/models/meta_tagging.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/preference.rb' - - 'app/models/profile.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/question.rb' - - 'app/models/serial_work.rb' - - 'app/models/series.rb' - - 'app/models/skin.rb' - - 'app/models/skin_parent.rb' - - 'app/models/subscription.rb' - - 'app/models/tag.rb' - - 'app/models/tagging.rb' - - 'app/models/tagset_models/owned_set_tagging.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/set_tagging.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'app/models/user_invite_request.rb' - - 'app/models/work.rb' - - 'app/models/wrangling_assignment.rb' - - 'app/models/wrangling_guideline.rb' - -# Offense count: 100 -# Cop supports --auto-correct. -Rails/WhereEquals: - Exclude: - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/models/admin_post.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/collection_participant.rb' - - 'app/models/gift.rb' - - 'app/models/kudo.rb' - - 'app/models/moderated_work.rb' - - 'app/models/potential_match.rb' - - 'app/models/prompt.rb' - - 'app/models/pseud.rb' - - 'app/models/series.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'lib/tasks/tag_tasks.rake' - -# Offense count: 20 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: exists, where -Rails/WhereExists: - Exclude: - - 'app/controllers/challenge_requests_controller.rb' - - 'app/helpers/works_helper.rb' - - 'app/models/admin_blacklisted_email.rb' - - 'app/models/gift.rb' - - 'app/models/invite_request.rb' - - 'app/models/meta_tagging.rb' - - 'app/models/prompt.rb' - - 'app/models/pseud.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/work.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/series_steps.rb' - - 'features/step_definitions/work_steps.rb' - -# Offense count: 20 -# Cop supports --auto-correct. -Rails/WhereNot: - Exclude: - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/invitation.rb' - - 'app/models/kudo.rb' - - 'app/models/pseud.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'lib/tasks/skin_tasks.rake' - -# Offense count: 21 -Security/Eval: - Exclude: - - 'app/helpers/application_helper.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/story_parser.rb' - - 'features/step_definitions/pickle_steps.rb' - - 'lib/challenge_core.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: AutoCorrect. -Security/JSONLoad: - Exclude: - - 'script/gift_exchange/generate_from_spec.rb' - - 'script/gift_exchange/json_tag_frequency.rb' - - 'script/gift_exchange/load_json_challenge.rb' - -# Offense count: 1 -Security/Open: - Exclude: - - 'app/models/story_parser.rb' - -# Offense count: 10 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: separated, grouped -Style/AccessorGrouping: - Exclude: - - 'app/models/potential_matcher/potential_matcher_constrained.rb' - - 'app/models/potential_matcher/potential_matcher_progress.rb' - - 'app/models/potential_matcher/prompt_batch.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - -# Offense count: 17 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: prefer_alias, prefer_alias_method -Style/Alias: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/collection.rb' - - 'app/models/comment.rb' - - 'app/models/external_work.rb' - - 'app/models/pseud.rb' - - 'app/models/search/query_result.rb' - - 'app/models/series.rb' - - 'config/initializers/monkeypatches/override_default_form_field_sizes.rb' - - 'config/initializers/monkeypatches/translate_string.rb' - - 'lib/backwards_compatible_password_decryptor.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: always, conditionals -Style/AndOr: - Exclude: - - 'app/controllers/collections_controller.rb' - - 'app/controllers/pseuds_controller.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: percent_q, bare_percent -Style/BarePercentLiterals: - Exclude: - - 'features/step_definitions/invite_steps.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/BlockComments: - Exclude: - - 'db/migrate/20200115232918_add_user_id_to_kudos.rb' - -# Offense count: 60 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods, AllowBracesOnProceduralOneLiners, BracesRequiredMethods. -# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces -# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object -# FunctionalMethods: let, let!, subject, watch -# IgnoredMethods: lambda, proc, it -Style/BlockDelimiters: - Exclude: - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/subscriptions_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/admin_post.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/work.rb' - - 'app/validators/url_active_validator.rb' - - 'features/step_definitions/web_steps.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'spec/controllers/admin_posts_controller_spec.rb' - - 'spec/controllers/languages_controller_spec.rb' - - 'spec/controllers/related_works_controller_spec.rb' - - 'spec/controllers/tag_set_associations_controller_spec.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - - 'spec/controllers/works/default_rails_actions_spec.rb' - - 'spec/controllers/works/multiple_actions_spec.rb' - - 'spec/models/favorite_tag_spec.rb' - - 'spec/models/search/index_sweeper_spec.rb' - - 'spec/models/story_parser_spec.rb' - - 'spec/models/work_spec.rb' - -# Offense count: 43 -# Cop supports --auto-correct. -Style/CaseLikeIf: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/external_authors_controller.rb' - - 'app/controllers/troubleshooting_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/inbox_helper.rb' - - 'app/helpers/invitations_helper.rb' - - 'app/helpers/orphans_helper.rb' - - 'app/models/abuse_report.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/creatorship.rb' - - 'app/models/prompt.rb' - - 'app/models/pseud.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'features/step_definitions/banner_steps.rb' - - 'features/step_definitions/bookmark_steps.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/user_steps.rb' - - 'features/step_definitions/work_search_steps.rb' - - 'lib/html_cleaner.rb' - - 'script/get_user_data.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: is_a?, kind_of? -Style/ClassCheck: - Exclude: - - 'app/models/comment.rb' - - 'app/models/external_work.rb' - - 'app/models/tagset_models/tag_set.rb' - -# Offense count: 17 -# Cop supports --auto-correct. -# Configuration parameters: IgnoredMethods. -# IgnoredMethods: ==, equal?, eql? -Style/ClassEqualityComparison: - Exclude: - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/meta_tagging.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'lib/url_formatter.rb' - - 'spec/lib/works_owner_spec.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/CollectionCompact: - Exclude: - - 'app/helpers/validation_helper.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -Style/ColonMethodCall: - Exclude: - - 'app/models/collection.rb' - - 'app/models/story_parser.rb' - - 'app/validators/url_active_validator.rb' - - 'features/step_definitions/bookmark_steps.rb' - - 'features/step_definitions/generic_steps.rb' - - 'lib/url_formatter.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, AllowInnerBackticks. -# SupportedStyles: backticks, percent_x, mixed -Style/CommandLiteral: - Exclude: - - 'lib/tasks/deploy_tasks.rake' - -# Offense count: 13 -# Cop supports --auto-correct. -# Configuration parameters: Keywords, RequireColon. -# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW, NOTE -Style/CommentAnnotation: - Exclude: - - 'app/controllers/challenge/gift_exchange_controller.rb' - - 'app/models/feedback.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/skin.rb' - - 'app/models/tag.rb' - - 'app/models/work.rb' - - 'config/initializers/monkeypatches/translate_string.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/collectible.rb' - - 'spec/controllers/tags_controller_spec.rb' - - 'spec/controllers/works/importing_spec.rb' - - 'spec/models/challenge_assignment_spec.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -Style/CommentedKeyword: - Exclude: - - 'app/helpers/application_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'lib/creation_notifier.rb' - - 'spec/models/collection_spec.rb' - -# Offense count: 66 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. -# SupportedStyles: assign_to_condition, assign_inside_condition -Style/ConditionalAssignment: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/gifts_controller.rb' - - 'app/controllers/media_controller.rb' - - 'app/controllers/potential_matches_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/series_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/decorators/homepage.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/users_helper.rb' - - 'app/mailers/collection_mailer.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/comment.rb' - - 'app/models/pseud.rb' - - 'app/models/search/bookmarkable_query.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/series.rb' - - 'app/models/spam_report.rb' - - 'app/models/story_parser.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/work.rb' - - 'app/validators/email_format_validator.rb' - - 'config/initializers/phraseapp_in_context_editor.rb' - - 'lib/autocomplete_source.rb' - - 'lib/css_cleaner.rb' - - 'lib/html_cleaner.rb' - - 'lib/works_owner.rb' - -# Offense count: 20 -Style/DocumentDynamicEvalDefinition: - Exclude: - - 'app/helpers/application_helper.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/story_parser.rb' - - 'lib/challenge_core.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: allowed_in_returns, forbidden -Style/DoubleNegation: - Exclude: - - 'app/controllers/works_controller.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/EachWithObject: - Exclude: - - 'app/models/rating.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -Style/EmptyCaseCondition: - Exclude: - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/models/skin.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty, nil, both -Style/EmptyElse: - Exclude: - - 'app/models/admin_setting.rb' - - 'app/models/skin.rb' - - 'app/sweepers/tag_set_sweeper.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/EmptyLiteral: - Exclude: - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set_association.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: compact, expanded -Style/EmptyMethod: - Exclude: - - 'spec/lib/tasks/resque.rake_spec.rb' - -# Offense count: 9 -# Cop supports --auto-correct. -Style/Encoding: - Exclude: - - 'features/step_definitions/banner_steps.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'spec/helpers/exports_helper_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/lib/string_cleaner_spec.rb' - - 'spec/lib/word_counter_spec.rb' - - 'spec/models/stat_counter_spec.rb' - - 'spec/models/tag_spec.rb' - -# Offense count: 20 -# Cop supports --auto-correct. -Style/EvalWithLocation: - Exclude: - - 'app/helpers/application_helper.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/story_parser.rb' - - 'lib/challenge_core.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/ExpandPathArguments: - Exclude: - - 'Rakefile' - - 'config.ru' - - 'config/boot.rb' - - 'config/environment.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/ExplicitBlockArgument: - Exclude: - - 'app/controllers/archive_faqs_controller.rb' - - 'features/step_definitions/web_steps.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: left_coerce, right_coerce, single_coerce, fdiv -Style/FloatDivision: - Exclude: - - 'app/models/invite_request.rb' - -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: each, for -Style/For: - Exclude: - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/helpers/series_helper.rb' - - 'app/models/collection.rb' - - 'app/models/creatorship.rb' - - 'app/models/pseud.rb' - - 'app/models/work.rb' - - 'app/views/admin_posts/index.rss.builder' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: format, sprintf, percent -Style/FormatString: - Exclude: - - 'app/helpers/validation_helper.rb' - -# Offense count: 37 -# Cop supports --auto-correct. -Style/GlobalStdStream: - Exclude: - - 'config/boot.rb' - - 'lib/tasks/after_tasks.rake' - - 'lib/tasks/cucumber.rake' - - 'lib/tasks/opendoors.rake' - - 'lib/tasks/skin_tasks.rake' - - 'lib/tasks/tag_tasks.rake' - - 'lib/tasks/work_tasks.rake' - -# Offense count: 243 -# Configuration parameters: MinBodyLength. -Style/GuardClause: - Exclude: - - 'app/controllers/admin/admin_invitations_controller.rb' - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/controllers/admin/api_controller.rb' - - 'app/controllers/admin/user_creations_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/challenge_requests_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/invitations_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/controllers/questions_controller.rb' - - 'app/controllers/readings_controller.rb' - - 'app/controllers/redirect_controller.rb' - - 'app/controllers/related_works_controller.rb' - - 'app/controllers/series_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/unsorted_tags_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/invitations_helper.rb' - - 'app/helpers/series_helper.rb' - - 'app/helpers/skins_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/admin_banner.rb' - - 'app/models/admin_post.rb' - - 'app/models/admin_post_tag.rb' - - 'app/models/admin_setting.rb' - - 'app/models/archive_faq.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_models/prompt_meme.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/challenge_signup_summary.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/collection_preference.rb' - - 'app/models/comment.rb' - - 'app/models/common_tagging.rb' - - 'app/models/concerns/creatable.rb' - - 'app/models/creatorship.rb' - - 'app/models/external_author.rb' - - 'app/models/fandom.rb' - - 'app/models/favorite_tag.rb' - - 'app/models/filter_tagging.rb' - - 'app/models/gift.rb' - - 'app/models/invitation.rb' - - 'app/models/invite_request.rb' - - 'app/models/meta_tagging.rb' - - 'app/models/potential_match.rb' - - 'app/models/profile.rb' - - 'app/models/prompt.rb' - - 'app/models/pseud.rb' - - 'app/models/reading.rb' - - 'app/models/related_work.rb' - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/bookmarkable_query.rb' - - 'app/models/search/index_sweeper.rb' - - 'app/models/search/indexer.rb' - - 'app/models/search/pseud_query.rb' - - 'app/models/search/work_query.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/serial_work.rb' - - 'app/models/series.rb' - - 'app/models/skin.rb' - - 'app/models/skin_parent.rb' - - 'app/models/spam_report.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'app/models/user_invite_request.rb' - - 'app/models/work.rb' - - 'app/sweepers/collection_sweeper.rb' - - 'app/sweepers/feed_sweeper.rb' - - 'app/sweepers/pseud_sweeper.rb' - - 'app/sweepers/tag_set_sweeper.rb' - - 'app/validators/email_blacklist_validator.rb' - - 'app/validators/email_format_validator.rb' - - 'app/validators/email_veracity_validator.rb' - - 'app/validators/url_format_validator.rb' - - 'config/initializers/active_record_log_subscriber.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/challenge_core.rb' - - 'lib/collectible.rb' - - 'lib/creation_notifier.rb' - - 'lib/css_cleaner.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - - 'lib/url_formatter.rb' - -# Offense count: 13 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: braces, no_braces -Style/HashAsLastArrayItem: - Exclude: - - 'app/controllers/challenge/gift_exchange_controller.rb' - - 'app/controllers/challenge/prompt_meme_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/series_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/models/user.rb' - - 'app/policies/user_policy.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: AllowSplatArgument. -Style/HashConversion: - Exclude: - - 'app/models/search/work_search_form.rb' - - 'app/models/spam_report.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: AllowedReceivers. -Style/HashEachMethods: - Exclude: - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/works_controller.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/html_cleaner.rb' - -# Offense count: 1 -# Configuration parameters: MinBranchesCount. -Style/HashLikeCase: - Exclude: - - 'features/step_definitions/autocomplete_steps.rb' - -# Offense count: 37 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. -# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys -Style/HashSyntax: - Exclude: - - 'app/models/admin_setting.rb' - - 'app/views/admin_posts/index.rss.builder' - - 'app/views/tags/feed.atom.builder' - - 'db/migrate/20150725141326_install_audited.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'lib/tasks/admin_tasks.rake' - - 'lib/tasks/deploy_tasks.rake' - - 'lib/tasks/memcached.rake' - - 'lib/tasks/notifications.rake' - - 'lib/tasks/resque.rake' - - 'lib/tasks/skin_tasks.rake' - - 'lib/tasks/spam_report.rake' - - 'lib/tasks/work_tasks.rake' - -# Offense count: 16 -# Cop supports --auto-correct. -Style/IdenticalConditionalBranches: - Exclude: - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/related_works_controller.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'features/step_definitions/series_steps.rb' - - 'features/step_definitions/work_steps.rb' - -# Offense count: 14 -# Cop supports --auto-correct. -# Configuration parameters: AllowIfModifier. -Style/IfInsideElse: - Exclude: - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/gifts_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/users/registrations_controller.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/models/bookmark.rb' - - 'app/models/collection.rb' - - 'app/sweepers/pseud_sweeper.rb' - -# Offense count: 347 -# Cop supports --auto-correct. -Style/IfUnlessModifier: - Exclude: - - 'app/controllers/admin/admin_invitations_controller.rb' - - 'app/controllers/admin/api_controller.rb' - - 'app/controllers/admin_posts_controller.rb' - - 'app/controllers/api/v2/bookmarks_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/home_controller.rb' - - 'app/controllers/invitations_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/controllers/redirect_controller.rb' - - 'app/controllers/series_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/subscriptions_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/users/sessions_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/invitations_helper.rb' - - 'app/helpers/language_helper.rb' - - 'app/helpers/skins_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/abuse_report.rb' - - 'app/models/admin_banner.rb' - - 'app/models/admin_post.rb' - - 'app/models/admin_setting.rb' - - 'app/models/application_record.rb' - - 'app/models/archive_faq.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_models/prompt_meme.rb' - - 'app/models/challenge_signup_summary.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/collection_preference.rb' - - 'app/models/comment.rb' - - 'app/models/common_tagging.rb' - - 'app/models/concerns/creatable.rb' - - 'app/models/creatorship.rb' - - 'app/models/download_writer.rb' - - 'app/models/fandom.rb' - - 'app/models/favorite_tag.rb' - - 'app/models/gift.rb' - - 'app/models/invitation.rb' - - 'app/models/invite_request.rb' - - 'app/models/kudo.rb' - - 'app/models/meta_tagging.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/reading.rb' - - 'app/models/related_work.rb' - - 'app/models/relationship.rb' - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/bookmarkable_query.rb' - - 'app/models/search/index_sweeper.rb' - - 'app/models/search/indexer.rb' - - 'app/models/search/query.rb' - - 'app/models/search/query_result.rb' - - 'app/models/search/tag_query.rb' - - 'app/models/search/work_query.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/serial_work.rb' - - 'app/models/skin.rb' - - 'app/models/skin_parent.rb' - - 'app/models/spam_report.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'app/models/user_invite_request.rb' - - 'app/models/work.rb' - - 'app/sweepers/feed_sweeper.rb' - - 'app/validators/url_format_validator.rb' - - 'config/initializers/active_record_log_subscriber.rb' - - 'config/initializers/monkeypatches/mail_disable_starttls.rb' - - 'features/step_definitions/challenge_steps.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/invite_steps.rb' - - 'features/step_definitions/series_steps.rb' - - 'features/step_definitions/work_import_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/autocomplete_source.rb' - - 'lib/challenge_core.rb' - - 'lib/collectible.rb' - - 'lib/css_cleaner.rb' - - 'lib/html_cleaner.rb' - - 'lib/sortable_list.rb' - - 'lib/tasks/skin_tasks.rake' - - 'lib/tasks/tag_tasks.rake' - - 'lib/tasks/work_tasks.rake' - - 'script/get_user_data.rb' - - 'script/gift_exchange/export_settings_json.rb' - - 'script/gift_exchange/generate_from_spec.rb' - - 'script/gift_exchange/requests_summary_to_json.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: AllowedMethods. -# AllowedMethods: nonzero? -Style/IfWithBooleanLiteralBranches: - Exclude: - - 'app/models/challenge_signup.rb' - - 'app/models/prompt.rb' - -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: InverseMethods, InverseBlocks. -Style/InverseMethods: - Exclude: - - 'app/controllers/pseuds_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/potential_match.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/search/index_sweeper.rb' - - 'app/models/series.rb' - - 'app/models/tagset_models/tag_set.rb' - -# Offense count: 51 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: line_count_dependent, lambda, literal -Style/Lambda: - Exclude: - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/external_work.rb' - - 'app/models/fandom.rb' - - 'app/models/gift.rb' - - 'app/models/inbox_comment.rb' - - 'app/models/prompt.rb' - - 'app/models/pseud.rb' - - 'app/models/related_work.rb' - - 'app/models/series.rb' - - 'app/models/skin.rb' - - 'app/models/tag.rb' - - 'app/models/work.rb' - -# Offense count: 21 -# Cop supports --auto-correct. -Style/LineEndConcatenation: - Exclude: - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'features/support/paths.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline -Style/MethodDefParentheses: - Exclude: - - 'app/helpers/application_helper.rb' - -# Offense count: 5 -Style/MixinUsage: - Exclude: - - 'Rakefile' - - 'config/initializers/gem-plugin_config/redis.rb' - - 'spec/controllers/api/v2/api_base_controller_spec.rb' - - 'spec/controllers/api/v2/api_works_search_spec.rb' - - 'spec/controllers/api/v2/api_works_spec.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/MultilineIfModifier: - Exclude: - - 'app/controllers/users/registrations_controller.rb' - - 'app/models/search/pseud_query.rb' - - 'app/models/search/work_query.rb' - - 'config/boot.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/MultilineIfThen: - Exclude: - - 'config/initializers/phraseapp_in_context_editor.rb' - -# Offense count: 31 -# Cop supports --auto-correct. -Style/MultilineTernaryOperator: - Exclude: - - 'app/controllers/admin/user_creations_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/media_controller.rb' - - 'app/controllers/related_works_controller.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/models/download_writer.rb' - - 'app/models/invite_request.rb' - - 'app/models/kudo.rb' - - 'app/models/prompt.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/autocomplete_source.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -Style/MultilineWhenThen: - Exclude: - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/comments_helper.rb' - -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: AllowMethodComparison. -Style/MultipleComparison: - Exclude: - - 'app/models/collection_participant.rb' - - 'app/models/preference.rb' - - 'app/models/search/query_cleaner.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'lib/tasks/load_autocomplete_data.rake' - -# Offense count: 68 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: literals, strict -Style/MutableConstant: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_models/prompt_meme.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/collection_participant.rb' - - 'app/models/indexing/cache_master.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/pseud_search_form.rb' - - 'app/models/search/tag_search_form.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/unsorted_tag.rb' - - 'features/step_definitions/external_work_steps.rb' - - 'features/step_definitions/skin_steps.rb' - - 'features/step_definitions/user_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/css_cleaner.rb' - -# Offense count: 18 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: both, prefix, postfix -Style/NegatedIf: - Exclude: - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/models/bookmark.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/work.rb' - - 'features/step_definitions/bookmark_steps.rb' - - 'lib/css_cleaner.rb' - -# Offense count: 16 -# Cop supports --auto-correct. -Style/NegatedIfElseCondition: - Exclude: - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/invitations_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/users/registrations_controller.rb' - - 'app/helpers/series_helper.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/collection.rb' - - 'features/step_definitions/admin_steps.rb' - - 'lib/challenge_core.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: both, prefix, postfix -Style/NegatedUnless: - Exclude: - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/potential_matches_controller.rb' - - 'app/helpers/series_helper.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/NegatedWhile: - Exclude: - - 'app/helpers/home_helper.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: AllowedMethods. -# AllowedMethods: be, be_a, be_an, be_between, be_falsey, be_kind_of, be_instance_of, be_truthy, be_within, eq, eql, end_with, include, match, raise_error, respond_to, start_with -Style/NestedParenthesizedCalls: - Exclude: - - 'spec/controllers/tags_controller_spec.rb' - -# Offense count: 24 -# Cop supports --auto-correct. -Style/NestedTernaryOperator: - Exclude: - - 'app/controllers/series_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/helpers/users_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/collection.rb' - - 'app/models/kudo.rb' - - 'app/models/potential_match.rb' - - 'app/models/pseud.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'lib/autocomplete_source.rb' - -# Offense count: 24 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, MinBodyLength. -# SupportedStyles: skip_modifier_ifs, always -Style/Next: - Exclude: - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/user_invite_requests_controller.rb' - - 'app/helpers/series_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/comment.rb' - - 'app/models/external_author.rb' - - 'app/models/prompt.rb' - - 'app/models/search/tag_indexer.rb' - - 'app/models/skin.rb' - - 'app/models/spam_report.rb' - - 'app/models/story_parser.rb' - - 'app/views/tags/feed.atom.builder' - - 'lib/autocomplete_source.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: predicate, comparison -Style/NilComparison: - Exclude: - - 'app/models/pseud.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/Not: - Exclude: - - 'app/controllers/collections_controller.rb' - - 'app/controllers/pseuds_controller.rb' - -# Offense count: 12 -# Cop supports --auto-correct. -# Configuration parameters: MinDigits, Strict. -Style/NumericLiterals: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/models/work.rb' - - 'lib/devise_failure_message_options.rb' - - 'spec/controllers/owned_tag_sets_controller_spec.rb' - - 'spec/lib/tasks/opendoors.rake_spec.rb' - -# Offense count: 83 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IgnoredMethods. -# SupportedStyles: predicate, comparison -Style/NumericPredicate: - Exclude: - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/invitations_controller.rb' - - 'app/controllers/opendoors/tools_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/potential_matches_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/decorators/pseud_decorator.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/series_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/helpers/user_invite_requests_helper.rb' - - 'app/helpers/users_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/models/admin_setting.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/challenge_signup_summary.rb' - - 'app/models/invitation.rb' - - 'app/models/potential_match.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/series.rb' - - 'app/models/spam_report.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user_invite_request.rb' - - 'features/step_definitions/admin_steps.rb' - - 'features/step_definitions/email_custom_steps.rb' - - 'features/step_definitions/potential_match_steps.rb' - - 'features/step_definitions/series_steps.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/css_cleaner.rb' - - 'lib/html_cleaner.rb' - - 'lib/tasks/tag_tasks.rake' - - 'lib/url_helpers.rb' - - 'script/gift_exchange/export_settings_json.rb' - - 'script/gift_exchange/generate_from_spec.rb' - - 'script/gift_exchange/load_json_challenge.rb' - -# Offense count: 1 -Style/OptionalArguments: - Exclude: - - 'app/helpers/prompt_restrictions_helper.rb' - -# Offense count: 24 -# Configuration parameters: AllowedMethods. -# AllowedMethods: respond_to_missing? -Style/OptionalBooleanParameter: - Exclude: - - 'app/controllers/autocomplete_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/collection.rb' - - 'app/models/creatorship.rb' - - 'app/models/potential_matcher/potential_matcher_progress.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/work.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/OrAssignment: - Exclude: - - 'app/controllers/opendoors/external_authors_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'lib/autocomplete_source.rb' - - 'lib/tasks/work_tasks.rake' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/ParallelAssignment: - Exclude: - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/helpers/tags_helper.rb' - -# Offense count: 21 -# Cop supports --auto-correct. -# Configuration parameters: AllowSafeAssignment, AllowInMultilineConditions. -Style/ParenthesesAroundCondition: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge/gift_exchange_controller.rb' - - 'app/controllers/challenge/prompt_meme_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/comment.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/skin.rb' - - 'app/models/tagset_models/cast_nomination.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/work.rb' - - 'app/validators/url_format_validator.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/css_cleaner.rb' - -# Offense count: 121 -# Cop supports --auto-correct. -# Configuration parameters: PreferredDelimiters. -Style/PercentLiteralDelimiters: - Exclude: - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/controllers/admin/skins_controller.rb' - - 'app/controllers/admin/user_creations_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/invitations_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/unsorted_tags_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/models/abuse_report.rb' - - 'app/models/challenge_models/gift_exchange.rb' - - 'app/models/challenge_models/prompt_meme.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/collection.rb' - - 'app/models/download_writer.rb' - - 'app/models/feedback.rb' - - 'app/models/indexing/cache_master.rb' - - 'app/models/indexing/scheduled_reindex_job.rb' - - 'app/models/potential_match.rb' - - 'app/models/potential_match_settings.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/bookmarkable_query.rb' - - 'app/models/search/query.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/search/tag_indexer.rb' - - 'app/models/search/taggable_query.rb' - - 'app/models/search/work_query.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/skin.rb' - - 'app/models/skin_parent.rb' - - 'app/models/subscription.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/work.rb' - - 'config/deploy.rb' - - 'lib/challenge_core.rb' - - 'lib/css_cleaner.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - - 'lib/tasks/cucumber.rake' - - 'lib/tasks/deploy_tasks.rake' - - 'script/gift_exchange/export_settings_json.rb' - - 'script/gift_exchange/generate_from_spec.rb' - - 'script/gift_exchange/json_tag_frequency.rb' - - 'spec/controllers/admin/api_controller_spec.rb' - - 'spec/controllers/api/v2/api_authorization_spec.rb' - - 'spec/controllers/api/v2/api_works_search_spec.rb' - - 'spec/controllers/works/default_rails_actions_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/models/search/work_search_form_spec.rb' - - 'spec/models/story_parser_spec.rb' - - 'spec/models/unsorted_tag_spec.rb' - -# Offense count: 101 -# Cop supports --auto-correct. -Style/PerlBackrefs: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/opendoors/tools_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/models/search/query.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'features/step_definitions/challege_gift_exchange_steps.rb' - - 'features/support/email.rb' - - 'features/support/paths.rb' - - 'lib/css_cleaner.rb' - - 'lib/tasks/skin_tasks.rake' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: short, verbose -Style/PreferredHashMethods: - Exclude: - - 'app/helpers/application_helper.rb' - - 'lib/html_cleaner.rb' - - 'lib/sortable_list.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/Proc: - Exclude: - - 'app/helpers/validation_helper.rb' - - 'app/models/chapter.rb' - - 'app/models/tagset_models/fandom_nomination.rb' - - 'app/models/tagset_models/tag_nomination.rb' - -# Offense count: 34 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: same_as_string_literals, single_quotes, double_quotes -Style/QuotedSymbols: - Exclude: - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, AllowedCompactTypes. -# SupportedStyles: compact, exploded -Style/RaiseArgs: - Exclude: - - 'app/models/series.rb' - - 'app/models/work.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: Methods. -Style/RedundantArgument: - Exclude: - - 'app/helpers/pseuds_helper.rb' - - 'app/models/search/query.rb' - - 'lib/otw_sanitize/user_class_sanitizer.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/RedundantAssignment: - Exclude: - - 'app/models/download.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_association.rb' - -# Offense count: 15 -# Cop supports --auto-correct. -Style/RedundantBegin: - Exclude: - - 'app/controllers/readings_controller.rb' - - 'app/models/admin_post.rb' - - 'app/models/search/query.rb' - - 'app/models/story_parser.rb' - - 'config/initializers/monkeypatches/translate_string.rb' - - 'lib/acts_as_commentable/commentable_entity.rb' - - 'lib/backwards_compatible_password_decryptor.rb' - - 'lib/tasks/opendoors.rake' - - 'lib/tasks/work_tasks.rake' - -# Offense count: 5 -# Cop supports --auto-correct. -Style/RedundantCondition: - Exclude: - - 'app/models/abuse_report.rb' - - 'app/models/tag.rb' - - 'app/models/work.rb' - - 'features/step_definitions/invite_steps.rb' - - 'lib/collectible.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/RedundantConditional: - Exclude: - - 'app/models/challenge_signup.rb' - -# Offense count: 40 -# Cop supports --auto-correct. -Style/RedundantInterpolation: - Exclude: - - 'app/controllers/admin/skins_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/collection.rb' - - 'app/models/potential_match.rb' - - 'app/models/potential_match_settings.rb' - - 'features/step_definitions/challege_gift_exchange_steps.rb' - - 'features/step_definitions/challenge_steps.rb' - - 'features/step_definitions/generic_steps.rb' - - 'features/step_definitions/invite_steps.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/challenge_core.rb' - - 'lib/works_owner.rb' - - 'spec/controllers/tags_controller_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/models/potential_match_spec.rb' - - 'spec/models/search/pseud_decorator_spec.rb' - -# Offense count: 19 -# Cop supports --auto-correct. -Style/RedundantParentheses: - Exclude: - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge/gift_exchange_controller.rb' - - 'app/controllers/challenge/prompt_meme_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/invite_requests_controller.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/models/comment.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -Style/RedundantPercentQ: - Exclude: - - 'features/step_definitions/invite_steps.rb' - -# Offense count: 15 -# Cop supports --auto-correct. -Style/RedundantRegexpCharacterClass: - Exclude: - - 'app/models/skin.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'features/step_definitions/bookmark_steps.rb' - - 'features/step_definitions/tag_steps.rb' - - 'features/step_definitions/work_search_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'features/support/paths.rb' - -# Offense count: 357 -# Cop supports --auto-correct. -Style/RedundantRegexpEscape: - Exclude: - - 'app/models/abuse_report.rb' - - 'app/models/admin_blacklisted_email.rb' - - 'app/models/collection.rb' - - 'app/models/download.rb' - - 'app/models/external_author_name.rb' - - 'app/models/preference.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/work.rb' - - 'features/step_definitions/admin_steps.rb' - - 'features/step_definitions/archivist_steps.rb' - - 'features/step_definitions/autocomplete_steps.rb' - - 'features/step_definitions/banner_steps.rb' - - 'features/step_definitions/bookmark_steps.rb' - - 'features/step_definitions/challege_gift_exchange_steps.rb' - - 'features/step_definitions/challenge_promptmeme_steps.rb' - - 'features/step_definitions/challenge_steps.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/comment_steps.rb' - - 'features/step_definitions/email_custom_steps.rb' - - 'features/step_definitions/external_work_steps.rb' - - 'features/step_definitions/fixtures_steps.rb' - - 'features/step_definitions/generic_steps.rb' - - 'features/step_definitions/invite_steps.rb' - - 'features/step_definitions/kudos_steps.rb' - - 'features/step_definitions/potential_match_steps.rb' - - 'features/step_definitions/pseud_steps.rb' - - 'features/step_definitions/request_header_steps.rb' - - 'features/step_definitions/series_steps.rb' - - 'features/step_definitions/skin_steps.rb' - - 'features/step_definitions/subscription_steps.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'features/step_definitions/tag_steps.rb' - - 'features/step_definitions/user_steps.rb' - - 'features/step_definitions/web_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/autocomplete_source.rb' - - 'lib/css_cleaner.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - - 'spec/lib/tasks/after_tasks.rake_spec.rb' - -# Offense count: 72 -# Cop supports --auto-correct. -# Configuration parameters: AllowMultipleReturnValues. -Style/RedundantReturn: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/decorators/homepage.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/home_helper.rb' - - 'app/helpers/series_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/models/admin_blacklisted_email.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/collection.rb' - - 'app/models/comment.rb' - - 'app/models/potential_match.rb' - - 'app/models/preference.rb' - - 'app/models/prompt.rb' - - 'app/models/pseud.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'app/validators/email_blacklist_validator.rb' - - 'lib/acts_as_commentable/comment_methods.rb' - - 'lib/backwards_compatible_password_decryptor.rb' - - 'lib/collectible.rb' - - 'lib/css_cleaner.rb' - - 'lib/html_cleaner.rb' - - 'lib/url_formatter.rb' - - 'lib/works_owner.rb' - - 'script/gift_exchange/generate_from_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/RedundantSort: - Exclude: - - 'app/models/series.rb' - -# Offense count: 52 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, AllowInnerSlashes. -# SupportedStyles: slashes, percent_r, mixed -Style/RegexpLiteral: - Exclude: - - 'app/controllers/opendoors/tools_controller.rb' - - 'app/helpers/home_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'app/models/abuse_report.rb' - - 'app/models/collection.rb' - - 'app/models/search/query.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/work.rb' - - 'app/validators/url_format_validator.rb' - - 'config/deploy.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'features/step_definitions/web_steps.rb' - - 'features/step_definitions/work_search_steps.rb' - - 'lib/autocomplete_source.rb' - - 'lib/html_cleaner.rb' - - 'lib/tasks/skin_tasks.rake' - - 'lib/url_formatter.rb' - - 'spec/lib/html_cleaner_spec.rb' - -# Offense count: 28 -# Cop supports --auto-correct. -Style/RescueModifier: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/challenges_controller.rb' - - 'app/controllers/potential_matches_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/models/search/query_result.rb' - - 'app/models/story_parser.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - - 'spec/controllers/works/importing_spec.rb' - -# Offense count: 24 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: implicit, explicit -Style/RescueStandardError: - Exclude: - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/inbox_controller.rb' - - 'app/controllers/opendoors/tools_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/readings_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/date_helper.rb' - - 'app/models/admin_post.rb' - - 'app/models/redis_mail_queue.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/work_link.rb' - - 'app/validators/url_active_validator.rb' - - 'config/initializers/archive_config/locale.rb' - - 'features/step_definitions/challenge_steps.rb' - - 'lib/acts_as_commentable/commentable_entity.rb' - -# Offense count: 63 -# Cop supports --auto-correct. -# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods. -# AllowedMethods: present?, blank?, presence, try, try! -Style/SafeNavigation: - Exclude: - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/external_authors_controller.rb' - - 'app/controllers/opendoors/tools_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/invitations_helper.rb' - - 'app/helpers/pseuds_helper.rb' - - 'app/helpers/skins_helper.rb' - - 'app/helpers/users_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/comment.rb' - - 'app/models/favorite_tag.rb' - - 'app/models/potential_match.rb' - - 'app/models/potential_matcher/potential_matcher_constrained.rb' - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/pseud_query.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'features/step_definitions/potential_match_steps.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'features/step_definitions/work_related_steps.rb' - - 'lib/challenge_core.rb' - - 'lib/tasks/tag_tasks.rake' - - 'script/gift_exchange/json_tag_frequency.rb' - - 'spec/lib/works_owner_spec.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Style/SelfAssignment: - Exclude: - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/models/chapter.rb' - - 'features/step_definitions/challenge_promptmeme_steps.rb' - -# Offense count: 21 -# Cop supports --auto-correct. -# Configuration parameters: AllowAsExpressionSeparator. -Style/Semicolon: - Exclude: - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/helpers/external_authors_helper.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/fandom_nomination.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'app/models/work.rb' - - 'lib/tasks/tag_tasks.rake' - - 'spec/lib/works_owner_spec.rb' - - 'spec/models/skin_parent_spec.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Style/SingleArgumentDig: - Exclude: - - 'app/models/search/query.rb' - - 'spec/controllers/admin/blacklisted_emails_controller_spec.rb' - -# Offense count: 26 -# Cop supports --auto-correct. -# Configuration parameters: AllowIfMethodIsEmpty. -Style/SingleLineMethods: - Exclude: - - 'app/controllers/autocomplete_controller.rb' - - 'app/models/collection.rb' - - 'app/models/collection_participant.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'lib/collectible.rb' - - 'spec/lib/tasks/resque.rake_spec.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/SlicingWithRange: - Exclude: - - 'app/models/search/work_search_form.rb' - -# Offense count: 17 -# Cop supports --auto-correct. -# Configuration parameters: AllowModifier. -Style/SoleNestedConditional: - Exclude: - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/helpers/tags_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/admin_setting.rb' - - 'app/models/bookmark.rb' - - 'app/models/collection_item.rb' - - 'app/models/comment.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'config/initializers/gem-plugin_config/redis.rb' - - 'config/initializers/monkeypatches/mail_disable_starttls.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'lib/autocomplete_source.rb' - - 'lib/collectible.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: RequireEnglish, EnforcedStyle. -# SupportedStyles: use_perl_names, use_english_names -Style/SpecialGlobalVars: - Exclude: - - 'public/dispatch.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Style/StderrPuts: - Exclude: - - 'config/boot.rb' - - 'lib/tasks/cucumber.rake' - -# Offense count: 182 -# Cop supports --auto-correct. -# Configuration parameters: Mode. -Style/StringConcatenation: - Exclude: - - 'app/controllers/admin/api_controller.rb' - - 'app/controllers/admin/blacklisted_emails_controller.rb' - - 'app/controllers/admin/user_creations_controller.rb' - - 'app/controllers/api/v2/bookmarks_controller.rb' - - 'app/controllers/api/v2/works_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge_requests_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/inbox_controller.rb' - - 'app/controllers/opendoors/external_authors_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/decorators/pseud_decorator.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'app/helpers/prompt_restrictions_helper.rb' - - 'app/helpers/pseuds_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/users_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/mailers/application_mailer.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/admin_blacklisted_email.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/download_writer.rb' - - 'app/models/external_author_name.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/query.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/search_range.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/tag_set_association.rb' - - 'config/initializers/gem-plugin_config/redis.rb' - - 'config/initializers/gem-plugin_config/resque.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'features/step_definitions/generic_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'lib/autocomplete_source.rb' - - 'lib/css_cleaner.rb' - - 'lib/html_cleaner.rb' - - 'lib/otw_sanitize/media_sanitizer.rb' - - 'lib/tasks/cucumber.rake' - - 'lib/tasks/skin_tasks.rake' - - 'lib/url_formatter.rb' - - 'lib/url_helpers.rb' - - 'public/dispatch.fcgi' - - 'public/dispatch.rb' - - 'script/gift_exchange/benchmark_assignments.rb' - - 'script/gift_exchange/benchmark_match.rb' - - 'script/gift_exchange/benchmark_regenerate.rb' - - 'script/gift_exchange/generate_from_spec.rb' - - 'script/gift_exchange/load_json_challenge.rb' - - 'spec/controllers/api/v2/api_works_spec.rb' - - 'spec/controllers/inbox_controller_spec.rb' - - 'spec/controllers/prompts_controller_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/models/story_parser_spec.rb' - - 'spec/models/work_spec.rb' - -# Offense count: 2633 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiterals: - Exclude: - - 'Capfile' - - 'Gemfile' - - 'Rakefile' - - 'app/controllers/admin/admin_invitations_controller.rb' - - 'app/controllers/admin/banners_controller.rb' - - 'app/controllers/admin/blacklisted_emails_controller.rb' - - 'app/controllers/admin/skins_controller.rb' - - 'app/controllers/admin_posts_controller.rb' - - 'app/controllers/api/v2/bookmarks_controller.rb' - - 'app/controllers/application_controller.rb' - - 'app/controllers/archive_faqs_controller.rb' - - 'app/controllers/autocomplete_controller.rb' - - 'app/controllers/bookmarks_controller.rb' - - 'app/controllers/challenge/gift_exchange_controller.rb' - - 'app/controllers/challenge/prompt_meme_controller.rb' - - 'app/controllers/challenge_assignments_controller.rb' - - 'app/controllers/challenge_claims_controller.rb' - - 'app/controllers/challenge_requests_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/challenges_controller.rb' - - 'app/controllers/chapters_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/collection_participants_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/comments_controller.rb' - - 'app/controllers/downloads_controller.rb' - - 'app/controllers/external_authors_controller.rb' - - 'app/controllers/external_works_controller.rb' - - 'app/controllers/fandoms_controller.rb' - - 'app/controllers/favorite_tags_controller.rb' - - 'app/controllers/gifts_controller.rb' - - 'app/controllers/home_controller.rb' - - 'app/controllers/inbox_controller.rb' - - 'app/controllers/invitations_controller.rb' - - 'app/controllers/known_issues_controller.rb' - - 'app/controllers/languages_controller.rb' - - 'app/controllers/locales_controller.rb' - - 'app/controllers/media_controller.rb' - - 'app/controllers/opendoors/external_authors_controller.rb' - - 'app/controllers/owned_tag_sets_controller.rb' - - 'app/controllers/potential_matches_controller.rb' - - 'app/controllers/preferences_controller.rb' - - 'app/controllers/profile_controller.rb' - - 'app/controllers/prompts_controller.rb' - - 'app/controllers/pseuds_controller.rb' - - 'app/controllers/questions_controller.rb' - - 'app/controllers/readings_controller.rb' - - 'app/controllers/related_works_controller.rb' - - 'app/controllers/series_controller.rb' - - 'app/controllers/skins_controller.rb' - - 'app/controllers/stats_controller.rb' - - 'app/controllers/tag_set_associations_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/controllers/tag_wranglings_controller.rb' - - 'app/controllers/tags_controller.rb' - - 'app/controllers/user_invite_requests_controller.rb' - - 'app/controllers/users/registrations_controller.rb' - - 'app/controllers/users_controller.rb' - - 'app/controllers/works_controller.rb' - - 'app/controllers/wrangling_guidelines_controller.rb' - - 'app/decorators/pseud_decorator.rb' - - 'app/helpers/application_helper.rb' - - 'app/helpers/bookmarks_helper.rb' - - 'app/helpers/challenge_helper.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/comments_helper.rb' - - 'app/helpers/external_authors_helper.rb' - - 'app/helpers/mailer_helper.rb' - - 'app/helpers/orphans_helper.rb' - - 'app/helpers/series_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/helpers/translation_helper.rb' - - 'app/helpers/users_helper.rb' - - 'app/helpers/validation_helper.rb' - - 'app/helpers/works_helper.rb' - - 'app/mailers/user_mailer.rb' - - 'app/models/abuse_report.rb' - - 'app/models/admin.rb' - - 'app/models/admin_blacklisted_email.rb' - - 'app/models/admin_setting.rb' - - 'app/models/archive_faq.rb' - - 'app/models/bookmark.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_claim.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/chapter.rb' - - 'app/models/character.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/collection_participant.rb' - - 'app/models/comment.rb' - - 'app/models/common_tagging.rb' - - 'app/models/download.rb' - - 'app/models/download_writer.rb' - - 'app/models/external_author.rb' - - 'app/models/external_author_name.rb' - - 'app/models/external_creatorship.rb' - - 'app/models/fandom.rb' - - 'app/models/filter_count.rb' - - 'app/models/freeform.rb' - - 'app/models/inbox_comment.rb' - - 'app/models/indexing/cache_master.rb' - - 'app/models/indexing/index_queue.rb' - - 'app/models/indexing/scheduled_reindex_job.rb' - - 'app/models/invitation.rb' - - 'app/models/invite_request.rb' - - 'app/models/language.rb' - - 'app/models/media.rb' - - 'app/models/meta_tagging.rb' - - 'app/models/opendoors.rb' - - 'app/models/preference.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/question.rb' - - 'app/models/redis_mail_queue.rb' - - 'app/models/relationship.rb' - - 'app/models/scheduled_tag_job.rb' - - 'app/models/search/async_indexer.rb' - - 'app/models/search/bookmark_query.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/bookmarkable_indexer.rb' - - 'app/models/search/bookmarkable_query.rb' - - 'app/models/search/indexer.rb' - - 'app/models/search/pseud_query.rb' - - 'app/models/search/pseud_search_form.rb' - - 'app/models/search/query.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/search/query_result.rb' - - 'app/models/search/tag_query.rb' - - 'app/models/search/work_query.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/series.rb' - - 'app/models/skin.rb' - - 'app/models/story_parser.rb' - - 'app/models/tag.rb' - - 'app/models/tagging.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_nomination.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/user.rb' - - 'app/models/work.rb' - - 'app/models/work_link.rb' - - 'app/models/work_skin.rb' - - 'app/models/wrangling_guideline.rb' - - 'app/sweepers/feed_sweeper.rb' - - 'app/validators/email_format_validator.rb' - - 'app/validators/email_veracity_validator.rb' - - 'app/validators/url_active_validator.rb' - - 'app/views/tags/feed.atom.builder' - - 'config.ru' - - 'config/boot.rb' - - 'config/deploy.rb' - - 'config/deploy/production.rb' - - 'config/deploy/staging.rb' - - 'config/environment.rb' - - 'config/initializers/active_record_log_subscriber.rb' - - 'config/initializers/archive_config/locale.rb' - - 'config/initializers/assets.rb' - - 'config/initializers/devise.rb' - - 'config/initializers/gem-plugin_config/redis.rb' - - 'config/initializers/gem-plugin_config/resque.rb' - - 'config/initializers/gem-plugin_config/will_paginate_config.rb' - - 'config/initializers/mime_types.rb' - - 'config/initializers/monkeypatches/accept_header.rb' - - 'config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb' - - 'config/initializers/phraseapp_in_context_editor.rb' - - 'config/initializers/rack_attack.rb' - - 'config/initializers/session_store.rb' - - 'config/routes.rb' - - 'config/schedule.rb' - - 'config/schedule_production.rb' - - 'db/migrate/20150725141326_install_audited.rb' - - 'db/migrate/20171030201300_add_simplified_email_to_invite_requests.rb' - - 'factories/abuse_reports.rb' - - 'factories/admin.rb' - - 'factories/admin_blacklisted_email.rb' - - 'factories/admin_post.rb' - - 'factories/api_key.rb' - - 'factories/bookmarks.rb' - - 'factories/challenge_claims.rb' - - 'factories/challenges.rb' - - 'factories/chapters.rb' - - 'factories/comments.rb' - - 'factories/feedback.rb' - - 'factories/prompt.rb' - - 'factories/prompt_restriction.rb' - - 'factories/pseuds.rb' - - 'factories/related_works.rb' - - 'factories/serial_work.rb' - - 'factories/skins.rb' - - 'factories/subscriptions.rb' - - 'factories/tags.rb' - - 'factories/user_invite_requests.rb' - - 'factories/works.rb' - - 'factories/wrangling_guideline.rb' - - 'features/step_definitions/challege_gift_exchange_steps.rb' - - 'features/step_definitions/collection_steps.rb' - - 'features/step_definitions/comment_steps.rb' - - 'features/step_definitions/fixtures_steps.rb' - - 'features/step_definitions/generic_steps.rb' - - 'features/step_definitions/gift_steps.rb' - - 'features/step_definitions/pickle_steps.rb' - - 'features/step_definitions/rake_steps.rb' - - 'features/step_definitions/request_header_steps.rb' - - 'features/step_definitions/tag_set_steps.rb' - - 'features/step_definitions/user_steps.rb' - - 'features/step_definitions/web_steps.rb' - - 'features/step_definitions/work_download_steps.rb' - - 'features/step_definitions/work_import_steps.rb' - - 'features/step_definitions/work_search_steps.rb' - - 'features/step_definitions/work_steps.rb' - - 'features/support/capybara.rb' - - 'features/support/env.rb' - - 'features/support/paths.rb' - - 'features/support/pickle.rb' - - 'features/support/vcr.rb' - - 'features/support/wait_for_ajax.rb' - - 'lib/acts_as_commentable/commentable_entity.rb' - - 'lib/autocomplete_source.rb' - - 'lib/challenge_core.rb' - - 'lib/collectible.rb' - - 'lib/css_cleaner.rb' - - 'lib/html_cleaner.rb' - - 'lib/otw_sanitize/embed_sanitizer.rb' - - 'lib/otw_sanitize/media_sanitizer.rb' - - 'lib/otw_sanitize/user_class_sanitizer.rb' - - 'lib/pagination_list_link_renderer.rb' - - 'lib/redis_test_setup.rb' - - 'lib/responder.rb' - - 'lib/searchable.rb' - - 'lib/string_cleaner.rb' - - 'lib/tasks/cucumber.rake' - - 'lib/tasks/load_autocomplete_data.rake' - - 'lib/tasks/memcached.rake' - - 'lib/tasks/resque.rake' - - 'lib/tasks/skin_tasks.rake' - - 'lib/tasks/work_tasks.rake' - - 'lib/url_formatter.rb' - - 'lib/url_helpers.rb' - - 'lib/word_counter.rb' - - 'lib/works_owner.rb' - - 'public/dispatch.fcgi' - - 'script/gift_exchange/benchmark_assignments.rb' - - 'script/gift_exchange/benchmark_match.rb' - - 'script/gift_exchange/benchmark_regenerate.rb' - - 'script/gift_exchange/export_settings_json.rb' - - 'script/gift_exchange/generate_from_spec.rb' - - 'script/gift_exchange/json_tag_frequency.rb' - - 'script/gift_exchange/load_json_challenge.rb' - - 'script/gift_exchange/requests_summary_to_json.rb' - - 'spec/controllers/api/v2/api_works_spec.rb' - - 'spec/controllers/challenge_claims_controller_spec.rb' - - 'spec/controllers/challenge_signups_controller_spec.rb' - - 'spec/controllers/challenges_controller_spec.rb' - - 'spec/controllers/chapters_controller_spec.rb' - - 'spec/controllers/collection_items_controller_spec.rb' - - 'spec/controllers/collection_profile_controller_spec.rb' - - 'spec/controllers/creatorships_controller_spec.rb' - - 'spec/controllers/external_authors_controller_spec.rb' - - 'spec/controllers/gift_exchange_controller_spec.rb' - - 'spec/controllers/inbox_controller_spec.rb' - - 'spec/controllers/owned_tag_sets_controller_spec.rb' - - 'spec/controllers/profile_controller_spec.rb' - - 'spec/controllers/prompt_meme_controller_spec.rb' - - 'spec/controllers/related_works_controller_spec.rb' - - 'spec/controllers/serial_works_controller_spec.rb' - - 'spec/controllers/series_controller_spec.rb' - - 'spec/controllers/tag_set_nominations_controller_spec.rb' - - 'spec/controllers/tags_controller_spec.rb' - - 'spec/controllers/users/registrations_controller_spec.rb' - - 'spec/controllers/works/multiple_actions_spec.rb' - - 'spec/controllers/wrangling_guidelines_controller_spec.rb' - - 'spec/helpers/admin_post_helper_spec.rb' - - 'spec/helpers/exports_helper_spec.rb' - - 'spec/helpers/home_helper_spec.rb' - - 'spec/helpers/inbox_helper_spec.rb' - - 'spec/helpers/tag_sets_helper_spec.rb' - - 'spec/helpers/user_invite_requests_helper_spec.rb' - - 'spec/helpers/validation_helper_spec.rb' - - 'spec/helpers/works_helper_spec.rb' - - 'spec/lib/collectible_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/lib/string_cleaner_spec.rb' - - 'spec/lib/tasks/opendoors.rake_spec.rb' - - 'spec/lib/tasks/resque.rake_spec.rb' - - 'spec/lib/tasks/work_tasks.rake_spec.rb' - - 'spec/lib/url_formatter_spec.rb' - - 'spec/lib/word_counter_spec.rb' - - 'spec/lib/works_owner_spec.rb' - - 'spec/models/abuse_report_spec.rb' - - 'spec/models/admin_blacklisted_email_spec.rb' - - 'spec/models/admin_spec.rb' - - 'spec/models/challenge_assignment_spec.rb' - - 'spec/models/challenge_claim_spec.rb' - - 'spec/models/chapter_spec.rb' - - 'spec/models/collection_item_spec.rb' - - 'spec/models/collection_spec.rb' - - 'spec/models/concerns/filterable_spec.rb' - - 'spec/models/external_author_spec.rb' - - 'spec/models/external_work_spec.rb' - - 'spec/models/favorite_tag_spec.rb' - - 'spec/models/feedback_spec.rb' - - 'spec/models/filter_count_spec.rb' - - 'spec/models/gift_exchange_spec.rb' - - 'spec/models/gift_spec.rb' - - 'spec/models/indexing/cache_master_spec.rb' - - 'spec/models/indexing/index_queue_spec.rb' - - 'spec/models/invitation_spec.rb' - - 'spec/models/invite_request_spec.rb' - - 'spec/models/language_spec.rb' - - 'spec/models/potential_match_spec.rb' - - 'spec/models/pseud_spec.rb' - - 'spec/models/search/async_indexer_spec.rb' - - 'spec/models/search/bookmark_query_spec.rb' - - 'spec/models/search/bookmarkable_query_spec.rb' - - 'spec/models/search/index_sweeper_spec.rb' - - 'spec/models/search/pseud_decorator_spec.rb' - - 'spec/models/search/pseud_query_spec.rb' - - 'spec/models/search/query_cleaner_spec.rb' - - 'spec/models/search/query_spec.rb' - - 'spec/models/search/stat_counter_indexer_spec.rb' - - 'spec/models/search/work_query_spec.rb' - - 'spec/models/search/work_search_form_spec.rb' - - 'spec/models/series_spec.rb' - - 'spec/models/skin_parent_spec.rb' - - 'spec/models/skin_spec.rb' - - 'spec/models/stat_counter_spec.rb' - - 'spec/models/story_parser_spec.rb' - - 'spec/models/subscription_spec.rb' - - 'spec/models/tag_set_nomination_spec.rb' - - 'spec/models/tag_spec.rb' - - 'spec/models/tag_wrangling_spec.rb' - - 'spec/models/unsorted_tag_spec.rb' - - 'spec/models/work_spec.rb' - - 'spec/spec_helper.rb' - - 'spec/support/matchers/add_to_reindex_queue.rb' - -# Offense count: 10 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiteralsInInterpolation: - Exclude: - - 'app/controllers/admin/admin_users_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/helpers/share_helper.rb' - - 'app/helpers/tag_sets_helper.rb' - - 'app/models/chapter.rb' - - 'app/models/search/async_indexer.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/story_parser.rb' - - 'lib/tasks/opendoors.rake' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/StructInheritance: - Exclude: - - 'app/models/challenge_signup_summary.rb' - - 'app/models/search/query_facet.rb' - -# Offense count: 65 -# Cop supports --auto-correct. -# Configuration parameters: AllowMethodsWithArguments, IgnoredMethods. -# IgnoredMethods: respond_to, define_method -Style/SymbolProc: - Exclude: - - 'app/controllers/admin/skins_controller.rb' - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collection_items_controller.rb' - - 'app/controllers/inbox_controller.rb' - - 'app/models/admin_post.rb' - - 'app/models/challenge_assignment.rb' - - 'app/models/challenge_signup.rb' - - 'app/models/chapter.rb' - - 'app/models/collection.rb' - - 'app/models/collection_item.rb' - - 'app/models/moderated_work.rb' - - 'app/models/potential_match.rb' - - 'app/models/prompt.rb' - - 'app/models/prompt_restriction.rb' - - 'app/models/pseud.rb' - - 'app/models/relationship.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/series.rb' - - 'app/models/spam_report.rb' - - 'app/models/tag.rb' - - 'app/models/tagset_models/owned_tag_set.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'app/models/tagset_models/tag_set_nomination.rb' - - 'app/models/work.rb' - - 'config/initializers/rack_attack.rb' - - 'factories/admin.rb' - - 'features/step_definitions/comment_steps.rb' - - 'lib/acts_as_commentable/commentable_entity.rb' - - 'lib/collectible.rb' - - 'lib/tasks/load_autocomplete_data.rake' - - 'lib/tasks/skin_tasks.rake' - - 'lib/tasks/tag_tasks.rake' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArguments: - Exclude: - - 'app/controllers/bookmarks_controller.rb' - - 'lib/creation_notifier.rb' - -# Offense count: 13 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArrayLiteral: - Exclude: - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/models/collection.rb' - - 'app/models/search/bookmark_search_form.rb' - - 'app/models/search/work_indexer.rb' - - 'app/models/skin.rb' - - 'spec/controllers/works/default_rails_actions_spec.rb' - -# Offense count: 12 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInHashLiteral: - Exclude: - - 'app/helpers/validation_helper.rb' - - 'app/models/search/indexer.rb' - - 'spec/controllers/tag_set_associations_controller_spec.rb' - - 'spec/models/skin_spec.rb' - - 'spec/models/story_parser_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, AllowedMethods. -# AllowedMethods: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym -Style/TrivialAccessors: - Exclude: - - 'app/models/search/query.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -Style/UnlessElse: - Exclude: - - 'app/controllers/challenge_signups_controller.rb' - - 'app/controllers/collections_controller.rb' - - 'app/controllers/opendoors/external_authors_controller.rb' - - 'app/controllers/tag_set_nominations_controller.rb' - - 'app/helpers/application_helper.rb' - - 'app/models/potential_match.rb' - - 'app/models/tagset_models/tag_set.rb' - - 'lib/pagination_list_link_renderer.rb' - -# Offense count: 50 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, MinSize, WordRegex. -# SupportedStyles: percent, brackets -Style/WordArray: - Exclude: - - 'app/controllers/tag_wranglers_controller.rb' - - 'app/helpers/collections_helper.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/character.rb' - - 'app/models/collection_participant.rb' - - 'app/models/fandom.rb' - - 'app/models/freeform.rb' - - 'app/models/relationship.rb' - - 'app/models/search/query_cleaner.rb' - - 'app/models/search/work_search_form.rb' - - 'app/models/tag.rb' - - 'app/models/work.rb' - - 'lib/tasks/cucumber.rake' - - 'spec/controllers/tag_wranglers_controller_spec.rb' - - 'spec/helpers/validation_helper_spec.rb' - - 'spec/lib/html_cleaner_spec.rb' - - 'spec/models/collection_spec.rb' - - 'spec/models/indexing/cache_master_spec.rb' - - 'spec/models/indexing/index_queue_spec.rb' - - 'spec/models/search/bookmark_search_form_spec.rb' - - 'spec/models/search/work_query_spec.rb' - - 'spec/models/search/work_search_form_spec.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -Style/ZeroLengthPredicate: - Exclude: - - 'app/controllers/autocomplete_controller.rb' - - 'app/helpers/tags_helper.rb' - - 'app/models/spam_report.rb' - - 'app/models/tag.rb' - - 'lib/url_helpers.rb' diff --git a/.rubocop_todo_erb.yml b/.rubocop_todo_erb.yml deleted file mode 100644 index 86023c719f5..00000000000 --- a/.rubocop_todo_erb.yml +++ /dev/null @@ -1,1495 +0,0 @@ -# This file is similar to .rubocop_todo.yml, but specifically for ERB files. -# Since erb_lint does not have an option to make this file automatically, -# it was semi-manually generated. The point is also similar to the regular todo file. -Layout/ArgumentAlignment: - Exclude: - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/orphans/_orphan_series.html.erb' - - 'app/views/skins/_form.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/tags/_search_form.html.erb' - - 'app/views/collections/_sidebar.html.erb' - - 'app/views/tags/edit.html.erb' - - 'app/views/works/_collection_filters.html.erb' - - 'app/views/potential_matches/_no_potential_recipients.html.erb' - - 'app/views/works/edit_multiple.html.erb' - - 'app/views/challenge_assignments/confirm_purge.html.erb' - - 'app/views/works/_work_form_tags.html.erb' - - 'app/views/favorite_tags/_form.html.erb' - - 'app/views/known_issues/_known_issues_form.html.erb' - - 'app/views/comment_mailer/_comment_notification_footer_for_other.html.erb' - - 'app/views/potential_matches/show.html.erb' - - 'app/views/owned_tag_sets/_internal_tag_set_fields.html.erb' - - 'app/views/challenge_assignments/_maintainer_index.html.erb' - - 'app/views/chapters/manage.html.erb' - - 'app/views/external_authors/index.html.erb' - - 'app/views/users/sessions/_passwd_small.html.erb' - - 'app/views/admin_posts/show.html.erb' - - 'app/views/comments/_comment_form.html.erb' - - 'app/views/invite_requests/manage.html.erb' - - 'app/views/admin/passwords/edit.html.erb' - - 'app/views/prompts/_prompt_controls.html.erb' - - 'app/views/chapters/edit.html.erb' - - 'app/views/admin/admin_users/confirm_delete_user_creations.html.erb' - - 'app/views/series/show.html.erb' - - 'app/views/works/_standard_form.html.erb' - - 'app/views/challenge/shared/_challenge_form_delete.html.erb' - - 'app/views/challenge/shared/_challenge_form_confirm_delete.html.erb' - - 'app/views/collection_participants/_participant_form.html.erb' - - 'app/views/external_works/edit.html.erb' - - 'app/views/works/_work_form_associations_language.html.erb' - - 'app/views/admin/_admin_options.html.erb' - - 'app/views/prompts/_prompt_navigation.html.erb' - - 'app/views/home/first_login_help.html.erb' - - 'app/views/abuse_reports/new.html.erb' - - 'app/views/challenge_signups/_signup_controls.html.erb' - - 'app/views/bookmarks/_bookmark_blurb.html.erb' - - 'app/views/bookmarks/_filters.html.erb' - - 'app/views/tag_wranglers/index.html.erb' - - 'app/views/home/_intro_module.html.erb' - - 'app/views/comment_mailer/_comment_notification_footer_for_tag.html.erb' - - 'app/views/external_authors/_external_author_blurb.html.erb' - - 'app/views/owned_tag_sets/_navigation.html.erb' - - 'app/views/potential_matches/_assignment_with_request.html.erb' - - 'app/views/collections/_collection_blurb.html.erb' - - 'app/views/works/_filters.html.erb' - - 'app/views/users/edit.html.erb' - - 'app/views/users/change_password.html.erb' - - 'app/views/challenge_assignments/show.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/bookmarks/_bookmarkable_blurb.html.erb' - - 'app/views/challenge_assignments/_assignment_blurb.html.erb' - - 'app/views/collections/_filters.html.erb' - - 'app/views/series/_series_module.html.erb' - - 'app/views/home/_news_module.html.erb' - - 'app/views/admin_posts/_admin_post_form.html.erb' - - 'app/views/invite_requests/_index_closed.html.erb' - - 'app/views/skins/_skin_actions.html.erb' - - 'app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb' - - 'app/views/users/passwords/edit.html.erb' - - 'app/views/admin/_admin_nav.html.erb' - - 'app/views/challenge_signups/summary.html.erb' - - 'app/views/user_mailer/abuse_report.html.erb' - - 'app/views/comments/_comment_actions.html.erb' - - 'app/views/user_mailer/signup_notification.html.erb' - - 'app/views/tag_set_nominations/show.html.erb' - - 'app/views/bookmarks/_external_work_fields.html.erb' - - 'app/views/users/change_username.html.erb' - - 'app/views/archive_faqs/_question_answer_fields.html.erb' - - 'app/views/invitations/manage.html.erb' - - 'app/views/users/registrations/_passwd.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/fandoms/unassigned.html.erb' - - 'app/views/admin/blacklisted_emails/index.html.erb' - - 'app/views/subscriptions/_form.html.erb' - - 'app/views/subscriptions/index.html.erb' - - 'app/views/admin/api/_api_key_form.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/collections/_collection_form_delete.html.erb' - - 'app/views/chapters/preview.html.erb' - - 'app/views/owned_tag_sets/show_options.html.erb' - - 'app/views/collections/_header.html.erb' - - 'app/views/challenge/shared/_challenge_navigation_user.html.erb' - - 'app/views/potential_matches/_match_navigation.html.erb' - - 'app/views/comments/_single_comment.html.erb' - - 'app/views/bookmarks/_search_form.html.erb' - - 'app/views/potential_matches/_no_potential_givers.html.erb' - - 'app/views/invite_requests/_index_open.html.erb' - - 'app/views/user_mailer/delete_work_notification.html.erb' - - 'app/views/works/_search_form.html.erb' - - 'app/views/admin_posts/index.html.erb' - - 'app/views/works/new.html.erb' - - 'app/views/works/new_import.html.erb' - -Layout/BlockEndNewline: - Exclude: - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/downloads/_download_afterword.html.erb' - - 'app/views/potential_matches/_list_recipients_for_pseud.html.erb' - -Layout/ClosingParenthesisIndentation: - Exclude: - - 'app/views/users/edit.html.erb' - - 'app/views/home/_intro_module.html.erb' - - 'app/views/invite_requests/_index_open.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/users/show.html.erb' - - 'app/views/users/change_username.html.erb' - - 'app/views/invite_requests/_index_closed.html.erb' - - 'app/views/home/first_login_help.html.erb' - - 'app/views/users/delete_preview.html.erb' - -Layout/CommentIndentation: - Exclude: - - 'app/views/challenge_requests/index.html.erb' - - 'app/views/skins/_skin_style_block.html.erb' - - 'app/views/challenge_claims/_unposted_claim_blurb.html.erb' - - 'app/views/skins/_skin_module.html.erb' - - 'app/views/inbox/_delete_form.html.erb' - - 'app/views/gifts/_gift_blurb.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/challenge_claims/_maintainer_index.html.erb' - - 'app/views/pseuds/_byline.html.erb' - - 'app/views/skins/_form.html.erb' - - 'app/views/inbox/_inbox_comment_contents.html.erb' - - 'app/views/layouts/application.html.erb' - - 'app/views/downloads/show.html.erb' - - 'app/views/works/_collection_filters.html.erb' - - 'app/views/tag_set_nominations/_review_individual_nom.html.erb' - - 'app/views/archive_faqs/_archive_faq_form.html.erb' - - 'app/views/bookmarks/index.html.erb' - - 'app/views/related_works/index.html.erb' - - 'app/views/favorite_tags/_form.html.erb' - - 'app/views/challenge/shared/_challenge_signups.html.erb' - - 'app/views/external_authors/_external_author_description.html.erb' - - 'app/views/owned_tag_sets/_show_tags_alpha_listbox.html.erb' - - 'app/views/admin/admin_users/_user_form.html.erb' - - 'app/views/owned_tag_sets/_internal_tag_set_fields.html.erb' - - 'app/views/users/sessions/_passwd_small.html.erb' - - 'app/views/collectibles/_collectible_form.html.erb' - - 'app/views/bookmarks/_bookmarks.html.erb' - - 'app/views/comments/_comment_form.html.erb' - - 'app/views/inbox/show.html.erb' - - 'app/views/prompts/_prompt_form.html.erb' - - 'app/views/admin_posts/_admin_post.html.erb' - - 'app/views/challenge_assignments/_maintainer_index_unfulfilled.html.erb' - - 'app/views/collection_items/_collection_item_form.html.erb' - - 'app/views/owned_tag_sets/_tag_set_associations_remove.html.erb' - - 'app/views/prompts/index.html.erb' - - 'app/views/prompts/_prompt_controls.html.erb' - - 'app/views/potential_matches/_list_recipients_for_pseud.html.erb' - - 'app/views/bookmarks/_bookmark_item_module.html.erb' - - 'app/views/inbox/_approve_button.html.erb' - - 'app/views/skins/_revert_skin_form.html.erb' - - 'app/views/prompts/show.html.erb' - - 'app/views/works/_work_abbreviated_list.html.erb' - - 'app/views/stats/index.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb' - - 'app/views/works/_work_form_associations_language.html.erb' - - 'app/views/home/first_login_help.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_tags.html.erb' - - 'app/views/challenge_signups/_signup_controls.html.erb' - - 'app/views/bookmarks/_bookmark_blurb.html.erb' - - 'app/views/bookmarks/_filters.html.erb' - - 'app/views/collection_items/_item_fields.html.erb' - - 'app/views/external_authors/_external_author_blurb.html.erb' - - 'app/views/kudos/_kudos.html.erb' - - 'app/views/potential_matches/_assignment_with_request.html.erb' - - 'app/views/skins/_header.html.erb' - - 'app/views/challenge_signups/show.html.erb' - - 'app/views/inbox/_read_form.html.erb' - - 'app/views/tag_set_nominations/_review_fandoms.html.erb' - - 'app/views/skins/_skin_navigation.html.erb' - - 'app/views/collections/_collection_blurb.html.erb' - - 'app/views/works/_filters.html.erb' - - 'app/views/home/_tos.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form.html.erb' - - 'app/views/challenge_assignments/show.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/user_mailer/_work_info.html.erb' - - 'app/views/home/_inbox_module.html.erb' - - 'app/views/potential_matches/_assignments.html.erb' - - 'app/views/bookmarks/_bookmarkable_blurb.html.erb' - - 'app/views/works/_work_form_pseuds.html.erb' - - 'app/views/works/_work_module.html.erb' - - 'app/views/users/confirmation.html.erb' - - 'app/views/share/_share.html.erb' - - 'app/views/inbox/_reply_button.html.erb' - - 'app/views/invite_requests/index.html.erb' - - 'app/views/challenge_assignments/_assignment_blurb.html.erb' - - 'app/views/collections/_filters.html.erb' - - 'app/views/skins/_update_skin_form.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form_management.html.erb' - - 'app/views/bookmarks/_bookmark_blurb_short.html.erb' - - 'app/views/challenge/shared/_challenge_requests.html.erb' - - 'app/views/series/_series_module.html.erb' - - 'app/views/home/_news_module.html.erb' - - 'app/views/skins/_skin_actions.html.erb' - - 'app/views/challenge_signups/index.html.erb' - - 'app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb' - - 'app/views/challenge_assignments/_maintainer_index_fulfilled.html.erb' - - 'app/views/challenge_signups/summary.html.erb' - - 'app/views/user_mailer/abuse_report.html.erb' - - 'app/views/comments/_comment_abbreviated_list.html.erb' - - 'app/views/comments/_comment_actions.html.erb' - - 'app/views/tag_set_nominations/show.html.erb' - - 'app/views/owned_tag_sets/_show_tags_in_single_list.html.erb' - - 'app/views/tag_set_associations/index.html.erb' - - 'app/views/archive_faqs/_question_answer_fields.html.erb' - - 'app/views/prompts/_prompt_blurb.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/admin/banners/_banner.html.erb' - - 'app/views/owned_tag_sets/_show_fandoms_by_media.html.erb' - - 'app/views/fandoms/unassigned.html.erb' - - 'app/views/challenge/prompt_meme/_challenge_sidebar.html.erb' - - 'app/views/subscriptions/_form.html.erb' - - 'app/views/collections/show.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/readings/_reading_blurb.html.erb' - - 'app/views/external_works/_work_module.html.erb' - - 'app/views/layouts/_includes.html.erb' - - 'app/views/bookmarks/_bookmark_user_module.html.erb' - - 'app/views/works/index.html.erb' - - 'app/views/owned_tag_sets/show_options.html.erb' - - 'app/views/layouts/_banner.html.erb' - - 'app/views/tag_set_nominations/_nomination_form.html.erb' - - 'app/views/challenge/shared/_challenge_navigation_user.html.erb' - - 'app/views/archive_faqs/show.html.erb' - - 'app/views/comments/_single_comment.html.erb' - - 'app/views/potential_matches/index.html.erb' - - 'app/views/layouts/_javascripts.html.erb' - - 'app/views/users/_header_navigation.html.erb' - - 'app/views/owned_tag_sets/_show_tags_by_alpha.html.erb' - - 'app/views/works/collected.html.erb' - - 'app/views/user_invite_requests/index.html.erb' - - 'app/views/layouts/_tos_prompt.html.erb' - - 'app/views/layouts/_proxy_notice.html.erb' - - 'app/views/owned_tag_sets/wrangle.html.erb' - - 'app/views/works/_work_blurb.html.erb' - - 'app/views/tag_set_nominations/_review_cast.html.erb' - - 'app/views/bookmarks/_bookmark_owner_navigation.html.erb' - - 'app/views/challenge_assignments/_maintainer_index_defaulted.html.erb' - -Layout/DotPosition: - Exclude: - - 'app/views/series/_series_module.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_associations.html.erb' - -Layout/EmptyComment: - Exclude: - - 'app/views/challenge/shared/_challenge_signups.html.erb' - -Layout/ExtraSpacing: - Exclude: - - 'app/views/potential_matches/_no_potential_recipients.html.erb' - - 'app/views/potential_matches/_no_potential_givers.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/comment_mailer/_comment_notification_footer_for_other.html.erb' - - 'app/views/works/_work_module.html.erb' - - 'app/views/admin/admin_invitations/index.html.erb' - - 'app/views/users/registrations/_legal.html.erb' - - 'app/views/prompt_restrictions/_prompt_restriction_form.html.erb' - - 'app/views/works/show_multiple.html.erb' - -Layout/FirstHashElementIndentation: - Exclude: - - 'app/views/comments/new.html.erb' - - 'app/views/admin/_admin_options.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb' - -Layout/HashAlignment: - Exclude: - - 'app/views/home/first_login_help.html.erb' - -Layout/LeadingCommentSpace: - Exclude: - - 'app/views/potential_matches/_list_recipients_for_pseud.html.erb' - - 'app/views/archive_faqs/show.html.erb' - -Layout/LeadingEmptyLines: - Exclude: - - 'app/views/owned_tag_sets/_tag_set_form.html.erb' - - 'app/views/collection_items/_collection_item_form.html.erb' - - 'app/views/tags/wrangle.html.erb' - - 'app/views/owned_tag_sets/wrangle.html.erb' - - 'app/views/prompts/index.html.erb' - - 'app/views/kudo_mailer/batch_kudo_notification.html.erb' - - 'app/views/pseuds/_byline.html.erb' - - 'app/views/admin_posts/_admin_post_form.html.erb' - - 'app/views/challenge/shared/_challenge_signups.html.erb' - - 'app/views/owned_tag_sets/_show_tags_alpha_listbox.html.erb' - - 'app/views/admin/skins/index_approved.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/works/_standard_form.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_tags.html.erb' - - 'app/views/owned_tag_sets/_show_fandoms_by_media.html.erb' - - 'app/views/works/edit_multiple.html.erb' - -Layout/MultilineBlockLayout: - Exclude: - - 'app/views/downloads/_download_preface.html.erb' - -Layout/MultilineHashBraceLayout: - Exclude: - - 'app/views/collections/_filters.html.erb' - -Layout/MultilineMethodCallBraceLayout: - Exclude: - - 'app/views/users/edit.html.erb' - - 'app/views/layouts/_tos_prompt.html.erb' - - 'app/views/bookmarks/_filters.html.erb' - - 'app/views/home/_intro_module.html.erb' - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/invite_requests/_index_open.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/users/show.html.erb' - - 'app/views/users/change_username.html.erb' - - 'app/views/invite_requests/_index_closed.html.erb' - - 'app/views/comment_mailer/_comment_notification_footer_for_other.html.erb' - - 'app/views/home/first_login_help.html.erb' - - 'app/views/users/delete_preview.html.erb' - - 'app/views/works/_filters.html.erb' - -Layout/MultilineMethodCallIndentation: - Exclude: - - 'app/views/series/_series_module.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_associations.html.erb' - -Layout/MultilineOperationIndentation: - Exclude: - - 'app/views/bookmarks/_filters.html.erb' - -Layout/SpaceAfterColon: - Exclude: - - 'app/views/home/first_login_help.html.erb' - -Layout/SpaceAfterComma: - Exclude: - - 'app/views/potential_match_settings/_potential_match_settings_form.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_tags.html.erb' - - 'app/views/home/site_pages.html.erb' - -Layout/SpaceAroundOperators: - Exclude: - - 'app/views/layouts/home.html.erb' - - 'app/views/comments/_comment_thread.html.erb' - - 'app/views/works/_work_module.html.erb' - - 'app/views/challenge/shared/_challenge_meta.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/admin_posts/_admin_post_form.html.erb' - - 'app/views/layouts/application.html.erb' - - 'app/views/admin/admin_invitations/find.html.erb' - - 'app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb' - - 'app/views/users/_sidebar.html.erb' - - 'app/views/owned_tag_sets/_tag_set_association_fields.html.erb' - - 'app/views/home/site_map.html.erb' - - 'app/views/comment_mailer/_comment_notification_footer_for_other.html.erb' - - 'app/views/layouts/session.html.erb' - - 'app/views/archive_faqs/_question_answer_fields.html.erb' - - 'app/views/invitations/manage.html.erb' - - 'app/views/prompts/_prompt_blurb.html.erb' - - 'app/views/prompts/_prompt_form.html.erb' - - 'app/views/owned_tag_sets/_show_fandoms_by_media.html.erb' - -Layout/SpaceBeforeBlockBraces: - Exclude: - - 'app/views/fandoms/unassigned.html.erb' - - 'app/views/fandoms/index.html.erb' - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/series/_series_module.html.erb' - - 'app/views/downloads/_download_afterword.html.erb' - - 'app/views/user_mailer/batch_subscription_notification.html.erb' - - 'app/views/collection_mailer/item_added_notification.html.erb' - - 'app/views/user_mailer/prompter_notification.html.erb' - - 'app/views/user_mailer/related_work_notification.html.erb' - - 'app/views/prompts/_prompt_blurb.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/external_works/_work_module.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/external_works/_blurb.html.erb' - - 'app/views/preferences/index.html.erb' - - 'app/views/works/_work_module.html.erb' - -Layout/SpaceBeforeComma: - Exclude: - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/challenge/shared/_challenge_form_schedule.html.erb' - - 'app/views/prompts/_prompt_form.html.erb' - - 'app/views/home/tos_faq.html.erb' - - -Layout/SpaceBeforeFirstArg: - Exclude: - - 'app/views/admin/admin_invitations/index.html.erb' - -Layout/SpaceInsideArrayLiteralBrackets: - Exclude: - - 'app/views/locales/_locale_form.html.erb' - -Layout/SpaceInsideBlockBraces: - Exclude: - - 'app/views/fandoms/unassigned.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/downloads/_download_afterword.html.erb' - - 'app/views/user_mailer/batch_subscription_notification.html.erb' - - 'app/views/collection_mailer/item_added_notification.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/works/_work_module.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/tag_set_nominations/_nomination_form.html.erb' - - 'app/views/home/site_pages.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/works/_work_abbreviated_list.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_associations.html.erb' - - 'app/views/fandoms/index.html.erb' - - 'app/views/owned_tag_sets/_show_tags_alpha_listbox.html.erb' - - 'app/views/user_mailer/related_work_notification.html.erb' - - 'app/views/preferences/index.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_tags.html.erb' - - 'app/views/invitations/_user_invitations.html.erb' - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/potential_match_settings/_potential_match_settings_form.html.erb' - - 'app/views/user_mailer/prompter_notification.html.erb' - - 'app/views/owned_tag_sets/_show_fandoms_by_media.html.erb' - - 'app/views/prompts/_prompt_blurb.html.erb' - - 'app/views/owned_tag_sets/_tag_set_blurb.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/collections/_collection_blurb.html.erb' - - 'app/views/owned_tag_sets/show.html.erb' - -Layout/SpaceInsideHashLiteralBraces: - Exclude: - - 'app/views/challenge_claims/_unposted_claim_blurb.html.erb' - - 'app/views/archive_faqs/_admin_index.html.erb' - - 'app/views/comment_mailer/comment_sent_notification.html.erb' - - 'app/views/orphans/index.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/tags/edit.html.erb' - - 'app/views/archive_faqs/_archive_faq_form.html.erb' - - 'app/views/potential_matches/_no_potential_recipients.html.erb' - - 'app/views/comments/edit.html.erb' - - 'app/views/collections/_challenge_collections.html.erb' - - 'app/views/invitations/_user_invitations.html.erb' - - 'app/views/admin/banners/index.html.erb' - - 'app/views/potential_matches/show.html.erb' - - 'app/views/chapters/manage.html.erb' - - 'app/views/comment_mailer/edited_comment_notification.html.erb' - - 'app/views/comments/_comment_form.html.erb' - - 'app/views/prompts/new.html.erb' - - 'app/views/users/registrations/new.html.erb' - - 'app/views/collection_items/_collection_item_form.html.erb' - - 'app/views/series/index.html.erb' - - 'app/views/collections/_form.html.erb' - - 'app/views/admin/skins/index_rejected.html.erb' - - 'app/views/collections/confirm_delete.html.erb' - - 'app/views/admin/skins/index_approved.html.erb' - - 'app/views/pseuds/index.html.erb' - - 'app/views/challenge/prompt_meme/_prompt_meme_form.html.erb' - - 'app/views/chapters/edit.html.erb' - - 'app/views/series/_series_navigation.html.erb' - - 'app/views/admin/skins/index.html.erb' - - 'app/views/stats/index.html.erb' - - 'app/views/users/_contents.html.erb' - - 'app/views/challenge_signups/confirm_delete.html.erb' - - 'app/views/archive_faqs/confirm_delete.html.erb' - - 'app/views/people/search.html.erb' - - 'app/views/bookmarks/confirm_delete.html.erb' - - 'app/views/prompts/_prompt_navigation.html.erb' - - 'app/views/admin_mailer/edited_comment_notification.html.erb' - - 'app/views/challenge_signups/_signup_controls.html.erb' - - 'app/views/challenge/gift_exchange/_gift_exchange_form.html.erb' - - 'app/views/pseuds/_pseud_blurb.html.erb' - - 'app/views/tag_wranglers/index.html.erb' - - 'app/views/owned_tag_sets/_navigation.html.erb' - - 'app/views/tags/show.html.erb' - - 'app/views/comment_mailer/comment_reply_notification.html.erb' - - 'app/views/collections/_collection_blurb.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form.html.erb' - - 'app/views/comment_mailer/comment_notification.html.erb' - - 'app/views/challenge_assignments/show.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/chapters/confirm_delete.html.erb' - - 'app/views/profile/show.html.erb' - - 'app/views/tag_set_nominations/confirm_destroy_multiple.html.erb' - - 'app/views/tag_wranglings/index.html.erb' - - 'app/views/challenge_assignments/_assignment_blurb.html.erb' - - 'app/views/bookmarks/_bookmark_blurb_short.html.erb' - - 'app/views/admin/admin_invitations/find.html.erb' - - 'app/views/challenge_signups/summary.html.erb' - - 'app/views/tag_set_nominations/confirm_delete.html.erb' - - 'app/views/tag_set_nominations/show.html.erb' - - 'app/views/owned_tag_sets/confirm_delete.html.erb' - - 'app/views/external_authors/_external_author_form.html.erb' - - 'app/views/admin_mailer/comment_notification.html.erb' - - 'app/views/invitations/show.html.erb' - - 'app/views/invitations/manage.html.erb' - - 'app/views/admin/banners/_navigation.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/fandoms/unassigned.html.erb' - - 'app/views/known_issues/_admin_index.html.erb' - - 'app/views/subscriptions/index.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/collections/_collection_form_delete.html.erb' - - 'app/views/feedbacks/new.html.erb' - - 'app/views/locales/index.html.erb' - - 'app/views/tag_set_nominations/_nomination_form.html.erb' - - 'app/views/pseuds/delete_preview.html.erb' - - 'app/views/challenge/shared/_challenge_navigation_user.html.erb' - - 'app/views/prompts/edit.html.erb' - - 'app/views/readings/index.html.erb' - - 'app/views/potential_matches/_match_navigation.html.erb' - - 'app/views/admin/banners/confirm_delete.html.erb' - - 'app/views/admin_posts/_admin_index.html.erb' - - 'app/views/potential_matches/_no_potential_givers.html.erb' - - 'app/views/tags/wrangle.html.erb' - - 'app/views/home/site_map.html.erb' - - 'app/views/user_invite_requests/index.html.erb' - - 'app/views/works/_search_box.html.erb' - - 'app/views/series/confirm_delete.html.erb' - - 'app/views/comment_mailer/edited_comment_reply_notification.html.erb' - - 'app/views/works/_work_blurb.html.erb' - - 'app/views/owned_tag_sets/batch_load.html.erb' - - 'app/views/bookmarks/_bookmark_owner_navigation.html.erb' - - 'app/views/languages/show.html.erb' - - 'app/views/works/confirm_delete.html.erb' - - 'app/views/works/edit.html.erb' - - 'app/views/works/edit_multiple.html.erb' - - 'app/views/works/new.html.erb' - - 'app/views/works/search_results.html.erb' - - 'app/views/wrangling_guidelines/_admin_index.html.erb' - -Layout/SpaceInsideParens: - Exclude: - - 'app/views/layouts/_header.html.erb' - - 'app/views/admin/sessions/new.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/skins/_form.html.erb' - - 'app/views/external_authors/index.html.erb' - - 'app/views/tags/edit.html.erb' - - 'app/views/works/new.html.erb' - - 'app/views/works/new_import.html.erb' - -Layout/SpaceInsideStringInterpolation: - Exclude: - - 'app/views/works/new_import.html.erb' - -Layout/SingleLineBlockChain: - Exclude: - - 'app/views/user_mailer/batch_subscription_notification.html.erb' - - 'app/views/collection_mailer/item_added_notification.html.erb' - - 'app/views/kudo_mailer/batch_kudo_notification.html.erb' - - 'app/views/external_works/_work_module.html.erb' - - 'app/views/works/_work_module.html.erb' - - 'app/views/home/site_pages.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/works/_work_abbreviated_list.html.erb' - - 'app/views/external_works/_blurb.html.erb' - - 'app/views/share/_embed_meta.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_associations.html.erb' - - 'app/views/share/_embed_link_header.html.erb' - - 'app/views/user_mailer/challenge_assignment_notification.html.erb' - - 'app/views/owned_tag_sets/_show_tags_alpha_listbox.html.erb' - - 'app/views/kudos/index.html.erb' - - 'app/views/user_mailer/related_work_notification.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_tags.html.erb' - - 'app/views/invitations/_user_invitations.html.erb' - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/potential_match_settings/_potential_match_settings_form.html.erb' - - 'app/views/user_mailer/prompter_notification.html.erb' - - 'app/views/owned_tag_sets/_show_fandoms_by_media.html.erb' - - 'app/views/prompts/_prompt_blurb.html.erb' - - 'app/views/owned_tag_sets/_tag_set_blurb.html.erb' - - 'app/views/collections/_collection_blurb.html.erb' - - 'app/views/owned_tag_sets/show.html.erb' - -Lint/AmbiguousBlockAssociation: - Exclude: - - 'app/views/tag_set_nominations/_nomination_form.html.erb' - - 'app/views/preferences/index.html.erb' - -Lint/ParenthesesAsGroupedExpression: - Exclude: - - 'app/views/home/dmca.html.erb' - - 'app/views/downloads/_download_chapter.html.erb' - - 'app/views/works/confirm_delete.html.erb' - -Lint/RedundantStringCoercion: - Exclude: - - 'app/views/prompts/_prompt_blurb.html.erb' - -Lint/TopLevelReturnWithArgument: - Exclude: - - 'app/views/user_mailer/challenge_assignment_notification.html.erb' - -Lint/UnusedBlockArgument: - Exclude: - - 'app/views/potential_match_settings/_potential_match_settings_form.html.erb' - -Naming/VariableNumber: - Exclude: - - 'app/views/users/registrations/_legal.html.erb' - -Rails/Blank: - Exclude: - - 'app/views/user_mailer/challenge_assignment_notification.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - -Rails/LinkToBlank: - Exclude: - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/users/registrations/_legal.html.erb' - -Rails/NegateInclude: - Exclude: - - 'app/views/inbox/show.html.erb' - -Rails/Presence: - Exclude: - - 'app/views/comments/_single_comment.html.erb' - - 'app/views/prompts/_prompt_blurb.html.erb' - - 'app/views/prompts/_prompt_form.html.erb' - - 'app/views/invite_requests/manage.html.erb' - -Rails/Present: - Exclude: - - 'app/views/profile/show.html.erb' - - 'app/views/works/_notes_form.html.erb' - -Rails/TimeZone: - Exclude: - - 'app/views/user_mailer/collection_notification.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/user_mailer/challenge_assignment_notification.html.erb' - - 'app/views/user_mailer/abuse_report.html.erb' - - 'app/views/user_mailer/potential_match_generation_notification.html.erb' - - 'app/views/user_mailer/feedback.html.erb' - - 'app/views/user_mailer/invalid_signup_notification.html.erb' - -Style/BlockDelimiters: - Exclude: - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/downloads/_download_afterword.html.erb' - - 'app/views/potential_matches/_list_recipients_for_pseud.html.erb' - -Style/ClassEqualityComparison: - Exclude: - - 'app/views/tags/edit.html.erb' - -Style/CommentAnnotation: - Exclude: - - 'app/views/prompts/_prompt_form.html.erb' - -Style/ConditionalAssignment: - Exclude: - - 'app/views/archive_faqs/_faq_index.html.erb' - - 'app/views/stats/index.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - -Style/HashAsLastArrayItem: - Exclude: - - 'app/views/works/_work_header_navigation.html.erb' - -Style/HashExcept: - Exclude: - - 'app/views/potential_match_settings/_potential_match_settings_form.html.erb' - -Style/HashSyntax: - Exclude: - - 'app/views/user_mailer/invitation_to_claim.html.erb' - - 'app/views/bookmarks/show.html.erb' - - 'app/views/challenge/shared/_challenge_form_schedule.html.erb' - - 'app/views/challenge_claims/_unposted_claim_blurb.html.erb' - - 'app/views/archive_faqs/_filters.html.erb' - - 'app/views/downloads/_download_afterword.html.erb' - - 'app/views/challenge_assignments/_user_index.html.erb' - - 'app/views/archive_faqs/_admin_index.html.erb' - - 'app/views/external_authors/_external_author_navigation.html.erb' - - 'app/views/comment_mailer/comment_sent_notification.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/archive_faqs/manage.html.erb' - - 'app/views/challenge_claims/_maintainer_index.html.erb' - - 'app/views/orphans/_orphan_series.html.erb' - - 'app/views/orphans/index.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/layouts/application.html.erb' - - 'app/views/skins/_form.html.erb' - - 'app/views/downloads/show.html.erb' - - 'app/views/challenge/gift_exchange/new.html.erb' - - 'app/views/collections/_sidebar.html.erb' - - 'app/views/collections/list_pm_challenges.html.erb' - - 'app/views/tag_set_nominations/_review_individual_nom.html.erb' - - 'app/views/archive_faqs/_archive_faq_form.html.erb' - - 'app/views/bookmarks/index.html.erb' - - 'app/views/potential_matches/_no_potential_recipients.html.erb' - - 'app/views/comments/edit.html.erb' - - 'app/views/related_works/index.html.erb' - - 'app/views/challenge_signups/edit.html.erb' - - 'app/views/collections/_challenge_collections.html.erb' - - 'app/views/works/_work_form_tags.html.erb' - - 'app/views/known_issues/_known_issues_form.html.erb' - - 'app/views/invitations/index.html.erb' - - 'app/views/archive_faqs/_faq_index.html.erb' - - 'app/views/challenge/shared/_challenge_signups.html.erb' - - 'app/views/comment_mailer/_comment_notification_footer_for_other.html.erb' - - 'app/views/locales/new.html.erb' - - 'app/views/invitations/_user_invitations.html.erb' - - 'app/views/collections/_works_module.html.erb' - - 'app/views/user_invite_requests/new.html.erb' - - 'app/views/potential_matches/show.html.erb' - - 'app/views/owned_tag_sets/_internal_tag_set_fields.html.erb' - - 'app/views/pseuds/show.html.erb' - - 'app/views/opendoors/external_authors/index.html.erb' - - 'app/views/chapters/manage.html.erb' - - 'app/views/comment_mailer/edited_comment_notification.html.erb' - - 'app/views/collectibles/_collectible_form.html.erb' - - 'app/views/external_authors/index.html.erb' - - 'app/views/gifts/_gift_search.html.erb' - - 'app/views/related_works/show.html.erb' - - 'app/views/works/_work_approved_children.html.erb' - - 'app/views/bookmarks/_bookmarks.html.erb' - - 'app/views/comments/_comment_form.html.erb' - - 'app/views/prompts/_prompt_form.html.erb' - - 'app/views/prompts/new.html.erb' - - 'app/views/series/_series_blurb.html.erb' - - 'app/views/series/edit.html.erb' - - 'app/views/users/registrations/new.html.erb' - - 'app/views/pseuds/edit.html.erb' - - 'app/views/challenge_assignments/_maintainer_index_unfulfilled.html.erb' - - 'app/views/collection_items/_collection_item_form.html.erb' - - 'app/views/collections/_form.html.erb' - - 'app/views/series/index.html.erb' - - 'app/views/admin/skins/index_rejected.html.erb' - - 'app/views/owned_tag_sets/_tag_set_associations_remove.html.erb' - - 'app/views/admin_posts/_filters.html.erb' - - 'app/views/challenge_signups/_signup_form_general_information.html.erb' - - 'app/views/external_works/new.html.erb' - - 'app/views/prompts/_prompt_controls.html.erb' - - 'app/views/collections/confirm_delete.html.erb' - - 'app/views/admin_posts/edit.html.erb' - - 'app/views/admin/skins/index_approved.html.erb' - - 'app/views/bookmarks/edit.html.erb' - - 'app/views/fandoms/show.html.erb' - - 'app/views/home/tos_faq.html.erb' - - 'app/views/users/registrations/_legal.html.erb' - - 'app/views/prompts/show.html.erb' - - 'app/views/locales/_navigation.html.erb' - - 'app/views/pseuds/index.html.erb' - - 'app/views/challenge/prompt_meme/_prompt_meme_form.html.erb' - - 'app/views/chapters/new.html.erb' - - 'app/views/admin/admin_users/confirm_delete_user_creations.html.erb' - - 'app/views/admin/skins/index.html.erb' - - 'app/views/layouts/_footer.html.erb' - - 'app/views/series/_series_navigation.html.erb' - - 'app/views/stats/index.html.erb' - - 'app/views/users/_contents.html.erb' - - 'app/views/challenge_signups/confirm_delete.html.erb' - - 'app/views/archive_faqs/confirm_delete.html.erb' - - 'app/views/works/_standard_form.html.erb' - - 'app/views/tags/search.html.erb' - - 'app/views/users/_sidebar.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb' - - 'app/views/challenge/shared/_challenge_form_confirm_delete.html.erb' - - 'app/views/people/search.html.erb' - - 'app/views/bookmarks/confirm_delete.html.erb' - - 'app/views/prompts/_prompt_navigation.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_tags.html.erb' - - 'app/views/admin_mailer/edited_comment_notification.html.erb' - - 'app/views/pseuds/_pseud_blurb.html.erb' - - 'app/views/challenge/gift_exchange/_gift_exchange_form.html.erb' - - 'app/views/collections/_bookmarks_module.html.erb' - - 'app/views/invitations/_invitation.html.erb' - - 'app/views/opendoors/external_authors/show.html.erb' - - 'app/views/tag_wranglers/index.html.erb' - - 'app/views/tags/index.html.erb' - - 'app/views/external_authors/_external_author_blurb.html.erb' - - 'app/views/owned_tag_sets/_navigation.html.erb' - - 'app/views/potential_match_settings/_potential_match_settings_form.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_navigation_user.html.erb' - - 'app/views/tags/show.html.erb' - - 'app/views/challenge_signups/show.html.erb' - - 'app/views/comment_mailer/comment_reply_notification.html.erb' - - 'app/views/tag_set_nominations/_review_fandoms.html.erb' - - 'app/views/collections/_collection_blurb.html.erb' - - 'app/views/owned_tag_sets/show.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form.html.erb' - - 'app/views/comment_mailer/comment_notification.html.erb' - - 'app/views/admin/skins/_navigation.html.erb' - - 'app/views/archive_faqs/edit.html.erb' - - 'app/views/orphans/_orphan_work.html.erb' - - 'app/views/challenge_assignments/show.html.erb' - - 'app/views/challenge/shared/_challenge_form_instructions.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/chapters/confirm_delete.html.erb' - - 'app/views/locales/edit.html.erb' - - 'app/views/pseuds/new.html.erb' - - 'app/views/potential_matches/_assignments.html.erb' - - 'app/views/known_issues/index.html.erb' - - 'app/views/profile/show.html.erb' - - 'app/views/tag_set_nominations/confirm_destroy_multiple.html.erb' - - 'app/views/admin/admin_invitations/index.html.erb' - - 'app/views/challenge/prompt_meme/_challenge_navigation_user.html.erb' - - 'app/views/comments/unreviewed.html.erb' - - 'app/views/known_issues/new.html.erb' - - 'app/views/tag_set_nominations/index.html.erb' - - 'app/views/works/_work_module.html.erb' - - 'app/views/owned_tag_sets/index.html.erb' - - 'app/views/challenge_assignments/_assignment_blurb.html.erb' - - 'app/views/collections/new.html.erb' - - 'app/views/challenge/shared/_challenge_meta.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form_management.html.erb' - - 'app/views/bookmarks/_bookmark_blurb_short.html.erb' - - 'app/views/challenge/shared/_challenge_requests.html.erb' - - 'app/views/works/drafts.html.erb' - - 'app/views/bookmarks/new.html.erb' - - 'app/views/home/_news_module.html.erb' - - 'app/views/admin_posts/_admin_post_form.html.erb' - - 'app/views/chapters/_hidden_fields.html.erb' - - 'app/views/challenge_signups/index.html.erb' - - 'app/views/admin/admin_invitations/find.html.erb' - - 'app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb' - - 'app/views/challenge_assignments/_maintainer_index_fulfilled.html.erb' - - 'app/views/challenge_claims/_user_index.html.erb' - - 'app/views/opendoors/tools/_tools_navigation.html.erb' - - 'app/views/challenge_signups/_show_requests.html.erb' - - 'app/views/challenge_signups/summary.html.erb' - - 'app/views/collections/list_ge_challenges.html.erb' - - 'app/views/tag_set_nominations/confirm_delete.html.erb' - - 'app/views/comments/_comment_actions.html.erb' - - 'app/views/people/index.html.erb' - - 'app/views/tag_set_nominations/_show_by_tag_type.html.erb' - - 'app/views/tag_set_nominations/show.html.erb' - - 'app/views/owned_tag_sets/confirm_delete.html.erb' - - 'app/views/unsorted_tags/index.html.erb' - - 'app/views/layouts/_header.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_sidebar.html.erb' - - 'app/views/external_authors/_external_author_form.html.erb' - - 'app/views/admin_mailer/comment_notification.html.erb' - - 'app/views/invitations/show.html.erb' - - 'app/views/tag_set_associations/index.html.erb' - - 'app/views/prompts/_prompt_blurb.html.erb' - - 'app/views/invitations/manage.html.erb' - - 'app/views/series/manage.html.erb' - - 'app/views/admin/admin_invitations/new.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/comments/_confirm_delete.html.erb' - - 'app/views/owned_tag_sets/_show_fandoms_by_media.html.erb' - - 'app/views/prompt_restrictions/_prompt_restriction_form.html.erb' - - 'app/views/fandoms/unassigned.html.erb' - - 'app/views/known_issues/_admin_index.html.erb' - - 'app/views/challenge/prompt_meme/_challenge_sidebar.html.erb' - - 'app/views/collection_items/new.html.erb' - - 'app/views/redirect/show.html.erb' - - 'app/views/archive_faqs/_archive_faq_order.html.erb' - - 'app/views/works/_hidden_fields.html.erb' - - 'app/views/opendoors/tools/index.html.erb' - - 'app/views/collections/show.html.erb' - - 'app/views/subscriptions/index.html.erb' - - 'app/views/admin/api/_api_key_form.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/external_authors/_external_author_name.html.erb' - - 'app/views/works/confirm_delete.html.erb' - - 'app/views/comments/new.html.erb' - - 'app/views/feedbacks/new.html.erb' - - 'app/views/bookmarks/_bookmark_user_module.html.erb' - - 'app/views/locales/index.html.erb' - - 'app/views/tag_set_nominations/_review.html.erb' - - 'app/views/works/_notes_form.html.erb' - - 'app/views/series/_series_order.html.erb' - - 'app/views/archive_faqs/_archive_faq_questions_order.html.erb' - - 'app/views/tag_set_nominations/_nomination_form.html.erb' - - 'app/views/collections/edit.html.erb' - - 'app/views/home/about.html.erb' - - 'app/views/layouts/_banner.html.erb' - - 'app/views/challenge/shared/_challenge_navigation_user.html.erb' - - 'app/views/prompts/edit.html.erb' - - 'app/views/challenge_signups/new.html.erb' - - 'app/views/pseuds/delete_preview.html.erb' - - 'app/views/readings/index.html.erb' - - 'app/views/admin_posts/new.html.erb' - - 'app/views/owned_tag_sets/edit.html.erb' - - 'app/views/users/sessions/_greeting.html.erb' - - 'app/views/archive_faqs/show.html.erb' - - 'app/views/comments/_single_comment.html.erb' - - 'app/views/media/index.html.erb' - - 'app/views/potential_matches/index.html.erb' - - 'app/views/challenge/prompt_meme/edit.html.erb' - - 'app/views/external_authors/edit.html.erb' - - 'app/views/admin_posts/_admin_index.html.erb' - - 'app/views/owned_tag_sets/_tag_set_association_fields.html.erb' - - 'app/views/languages/new.html.erb' - - 'app/views/potential_matches/_no_potential_givers.html.erb' - - 'app/views/archive_faqs/new.html.erb' - - 'app/views/home/site_map.html.erb' - - 'app/views/users/_header_navigation.html.erb' - - 'app/views/owned_tag_sets/_show_tags_by_alpha.html.erb' - - 'app/views/known_issues/edit.html.erb' - - 'app/views/challenge/prompt_meme/new.html.erb' - - 'app/views/skins/_skin_parent_fields.html.erb' - - 'app/views/comments/show.html.erb' - - 'app/views/collections/list_challenges.html.erb' - - 'app/views/works/collected.html.erb' - - 'app/views/potential_matches/_no_match_required.html.erb' - - 'app/views/challenge_signups/_show_offers.html.erb' - - 'app/views/challenge/prompt_meme/_challenge_signups.html.erb' - - 'app/views/works/_search_form.html.erb' - - 'app/views/preferences/index.html.erb' - - 'app/views/user_invite_requests/index.html.erb' - - 'app/views/bookmarks/search_results.html.erb' - - 'app/views/works/_search_box.html.erb' - - 'app/views/series/confirm_delete.html.erb' - - 'app/views/comment_mailer/edited_comment_reply_notification.html.erb' - - 'app/views/works/_work_blurb.html.erb' - - 'app/views/home/dmca.html.erb' - - 'app/views/owned_tag_sets/batch_load.html.erb' - - 'app/views/challenge/gift_exchange/edit.html.erb' - - 'app/views/tag_set_nominations/_review_cast.html.erb' - - 'app/views/challenge_assignments/_maintainer_index_defaulted.html.erb' - - 'app/views/languages/show.html.erb' - - 'app/views/languages/edit.html.erb' - - 'app/views/locales/_locale_form.html.erb' - - 'app/views/works/confirm_delete_multiple.html.erb' - - 'app/views/works/edit.html.erb' - - 'app/views/works/edit_multiple.html.erb' - - 'app/views/works/index.html.erb' - - 'app/views/works/new.html.erb' - - 'app/views/works/new_import.html.erb' - - 'app/views/works/search_results.html.erb' - - 'app/views/works/show_multiple.html.erb' - - 'app/views/wrangling_guidelines/_admin_index.html.erb' - - 'app/views/wrangling_guidelines/_wrangling_guideline_form.html.erb' - - 'app/views/wrangling_guidelines/_wrangling_guideline_order.html.erb' - -Style/IfUnlessModifier: - Exclude: - - 'app/views/pseuds/_byline.html.erb' - -Style/InverseMethods: - Exclude: - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/potential_match_settings/_potential_match_settings_form.html.erb' - -Style/LineEndConcatenation: - Exclude: - - 'app/views/admin/admin_users/bulk_search.html.erb' - -Style/MultilineTernaryOperator: - Exclude: - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/works/_work_form_tags.html.erb' - - 'app/views/user_mailer/batch_subscription_notification.html.erb' - - 'app/views/comment_mailer/edited_comment_reply_notification.html.erb' - - 'app/views/subscriptions/index.html.erb' - - 'app/views/user_mailer/delete_work_notification.html.erb' - - 'app/views/potential_matches/_list_recipients_for_pseud.html.erb' - - 'app/views/admin_posts/index.html.erb' - - 'app/views/comment_mailer/comment_reply_notification.html.erb' - - 'app/views/home/first_login_help.html.erb' - -Style/NegatedUnless: - Exclude: - - 'app/views/challenge_signups/_signup_form.html.erb' - -Style/NestedParenthesizedCalls: - Exclude: - - 'app/views/user_mailer/collection_notification.html.erb' - - 'app/views/comment_mailer/comment_notification.html.erb' - - 'app/views/user_mailer/invitation_to_claim.html.erb' - - 'app/views/comment_mailer/comment_sent_notification.html.erb' - - 'app/views/layouts/_javascripts.html.erb' - - 'app/views/admin_mailer/comment_notification.html.erb' - - 'app/views/user_mailer/admin_hidden_work_notification.html.erb' - - 'app/views/user_mailer/abuse_report.html.erb' - - 'app/views/user_mailer/batch_subscription_notification.html.erb' - - 'app/views/user_mailer/prompter_notification.html.erb' - - 'app/views/comment_mailer/edited_comment_notification.html.erb' - - 'app/views/comment_mailer/edited_comment_reply_notification.html.erb' - - 'app/views/user_mailer/_work_info.html.erb' - - 'app/views/user_mailer/delete_work_notification.html.erb' - - 'app/views/user_mailer/signup_notification.html.erb' - - 'app/views/comment_mailer/comment_reply_notification.html.erb' - - 'app/views/user_mailer/admin_deleted_work_notification.html.erb' - - 'app/views/admin_mailer/edited_comment_notification.html.erb' - -Style/NestedTernaryOperator: - Exclude: - - 'app/views/layouts/_header.html.erb' - - 'app/views/user_mailer/challenge_assignment_notification.html.erb' - - 'app/views/comment_mailer/edited_comment_reply_notification.html.erb' - - 'app/views/collection_mailer/item_added_notification.html.erb' - - 'app/views/potential_matches/_list_recipients_for_pseud.html.erb' - - 'app/views/comment_mailer/comment_reply_notification.html.erb' - - 'app/views/tags/edit.html.erb' - -Style/NumericLiterals: - Exclude: - - 'app/views/archive_faqs/show.html.erb' - -Style/NumericPredicate: - Exclude: - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb' - - 'app/views/collection_mailer/item_added_notification.html.erb' - -Style/ParenthesesAroundCondition: - Exclude: - - 'app/views/collectibles/_collectible_form.html.erb' - -Style/PercentLiteralDelimiters: - Exclude: - - 'app/views/bookmarks/_filters.html.erb' - - 'app/views/tags/index.html.erb' - - 'app/views/owned_tag_sets/_internal_tag_set_fields.html.erb' - - 'app/views/tag_set_nominations/_nomination_form.html.erb' - - 'app/views/tags/show.html.erb' - - 'app/views/works/_filters.html.erb' - - 'app/views/owned_tag_sets/_tag_set_blurb.html.erb' - - 'app/views/admin/skins/index_approved.html.erb' - - 'app/views/inbox/show.html.erb' - - 'app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb' - - 'app/views/tags/edit.html.erb' - - 'app/views/tag_set_nominations/_review.html.erb' - -Style/RedundantCondition: - Exclude: - - 'app/views/layouts/_header.html.erb' - - 'app/views/series/index.html.erb' - - 'app/views/admin/admin_users/_user_history.html.erb' - -Style/RedundantInterpolation: - Exclude: - - 'app/views/works/_hidden_fields.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/potential_matches/_list_recipients_for_pseud.html.erb' - - 'app/views/tag_wranglings/index.html.erb' - - 'app/views/challenge/shared/_challenge_meta.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/archive_faqs/show.html.erb' - - 'app/views/chapters/_hidden_fields.html.erb' - - 'app/views/tags/edit.html.erb' - - 'app/views/bookmarks/index.html.erb' - - 'app/views/tags/wrangle.html.erb' - - 'app/views/user_mailer/challenge_assignment_notification.html.erb' - - 'app/views/menu/_menu_fandoms.html.erb' - - 'app/views/layouts/_header.html.erb' - - 'app/views/bookmarks/_bookmark_blurb.html.erb' - - 'app/views/owned_tag_sets/_internal_tag_set_fields.html.erb' - - 'app/views/works/_search_box.html.erb' - - 'app/views/bookmarks/_bookmark_owner_navigation.html.erb' - - 'app/views/comments/_comment_form.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/works/preview_tags.html.erb' - -Style/RedundantParentheses: - Exclude: - - 'app/views/users/_sidebar.html.erb' - - 'app/views/gifts/index.html.erb' - - 'app/views/collection_items/_collection_item_form.html.erb' - - 'app/views/archive_faqs/_question_answer_fields.html.erb' - - 'app/views/inbox/show.html.erb' - - 'app/views/prompts/_prompt_form.html.erb' - - 'app/views/tags/edit.html.erb' - -Style/RedundantSort: - Exclude: - - 'app/views/owned_tag_sets/show_options.html.erb' - -Style/SafeNavigation: - Exclude: - - 'app/views/admin/admin_users/_user_history.html.erb' - -Style/Semicolon: - Exclude: - - 'app/views/owned_tag_sets/_show_fandoms_by_media.html.erb' - -Style/StringConcatenation: - Exclude: - - 'app/views/user_mailer/invitation_to_claim.html.erb' - - 'app/views/collections/_form.html.erb' - - 'app/views/admin_posts/_filters.html.erb' - - 'app/views/archive_faqs/_filters.html.erb' - - 'app/views/collection_mailer/item_added_notification.html.erb' - - 'app/views/admin/api/_api_key_form.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/home/tos_faq.html.erb' - - 'app/views/user_mailer/feedback.html.erb' - - 'app/views/chapters/_chapter_form.html.erb' - - 'app/views/skins/_form.html.erb' - - 'app/views/external_works/_blurb.html.erb' - - 'app/views/works/_standard_form.html.erb' - - 'app/views/admin/banners/_banner_form.html.erb' - - 'app/views/tags/edit.html.erb' - - 'app/views/archive_faqs/_archive_faq_form.html.erb' - - 'app/views/related_works/index.html.erb' - - 'app/views/questions/manage.html.erb' - - 'app/views/collection_participants/_participant_form.html.erb' - - 'app/views/languages/_form.html.erb' - - 'app/views/external_works/edit.html.erb' - - 'app/views/known_issues/_known_issues_form.html.erb' - - 'app/views/invitations/index.html.erb' - - 'app/views/works/_work_form_associations_language.html.erb' - - 'app/views/comment_mailer/_comment_notification_footer_for_other.html.erb' - - 'app/views/user_mailer/invalid_signup_notification.html.erb' - - 'app/views/home/first_login_help.html.erb' - - 'app/views/layouts/_header.html.erb' - - 'app/views/tag_wranglers/index.html.erb' - - 'app/views/user_invite_requests/new.html.erb' - - 'app/views/comment_mailer/_comment_notification_footer_for_tag.html.erb' - - 'app/views/chapters/manage.html.erb' - - 'app/views/bookmarks/_external_work_fields.html.erb' - - 'app/views/archive_faqs/_question_answer_fields.html.erb' - - 'app/views/invitations/manage.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/locales/_locale_form.html.erb' - - 'app/views/prompts/_prompt_form.html.erb' - - 'app/views/layouts/session.html.erb' - - 'app/views/prompt_restrictions/_prompt_restriction_form.html.erb' - - 'app/views/works/new_import.html.erb' - - 'app/views/wrangling_guidelines/_wrangling_guideline_form.html.erb' - -Style/StringLiterals: - Exclude: - - 'app/views/user_mailer/invitation_to_claim.html.erb' - - 'app/views/layouts/home.html.erb' - - 'app/views/bookmarks/show.html.erb' - - 'app/views/challenge/shared/_challenge_form_schedule.html.erb' - - 'app/views/challenge_claims/_unposted_claim_blurb.html.erb' - - 'app/views/archive_faqs/_filters.html.erb' - - 'app/views/downloads/_download_afterword.html.erb' - - 'app/views/comments/_comment_thread.html.erb' - - 'app/views/skins/_skin_module.html.erb' - - 'app/views/challenge_assignments/_user_index.html.erb' - - 'app/views/users/delete_confirmation.html.erb' - - 'app/views/archive_faqs/_admin_index.html.erb' - - 'app/views/menu/search.html.erb' - - 'app/views/inbox/_delete_form.html.erb' - - 'app/views/comment_mailer/comment_sent_notification.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/archive_faqs/manage.html.erb' - - 'app/views/orphans/_orphan_series.html.erb' - - 'app/views/orphans/index.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/inbox/_inbox_comment_contents.html.erb' - - 'app/views/layouts/application.html.erb' - - 'app/views/skins/_form.html.erb' - - 'app/views/downloads/_download_chapter.html.erb' - - 'app/views/downloads/show.html.erb' - - 'app/views/home/donate.html.erb' - - 'app/views/collections/_sidebar.html.erb' - - 'app/views/tags/edit.html.erb' - - 'app/views/works/_collection_filters.html.erb' - - 'app/views/tag_set_nominations/_review_individual_nom.html.erb' - - 'app/views/bookmarks/index.html.erb' - - 'app/views/potential_matches/_no_potential_recipients.html.erb' - - 'app/views/works/edit_multiple.html.erb' - - 'app/views/comments/edit.html.erb' - - 'app/views/menu/_menu_about.html.erb' - - 'app/views/questions/manage.html.erb' - - 'app/views/related_works/index.html.erb' - - 'app/views/works/_work_form_tags.html.erb' - - 'app/views/favorite_tags/_form.html.erb' - - 'app/views/known_issues/_known_issues_form.html.erb' - - 'app/views/invitations/index.html.erb' - - 'app/views/archive_faqs/_faq_index.html.erb' - - 'app/views/works/_work_series_links.html.erb' - - 'app/views/locales/new.html.erb' - - 'app/views/user_mailer/admin_deleted_work_notification.html.erb' - - 'app/views/invitations/_user_invitations.html.erb' - - 'app/views/admin/banners/index.html.erb' - - 'app/views/admin/banners/edit.html.erb' - - 'app/views/collections/_works_module.html.erb' - - 'app/views/user_invite_requests/new.html.erb' - - 'app/views/tag_set_nominations/new.html.erb' - - 'app/views/pseuds/show.html.erb' - - 'app/views/related_works/_approve.html.erb' - - 'app/views/tag_set_nominations/edit.html.erb' - - 'app/views/chapters/manage.html.erb' - - 'app/views/downloads/_download_preface.html.erb' - - 'app/views/comment_mailer/edited_comment_notification.html.erb' - - 'app/views/external_authors/index.html.erb' - - 'app/views/gifts/_gift_search.html.erb' - - 'app/views/related_works/show.html.erb' - - 'app/views/skins/_skin_type_navigation.html.erb' - - 'app/views/related_works/_remove.html.erb' - - 'app/views/bookmarks/_bookmarks.html.erb' - - 'app/views/comments/_comment_form.html.erb' - - 'app/views/works/_adult.html.erb' - - 'app/views/works/_work_approved_children.html.erb' - - 'app/views/inbox/show.html.erb' - - 'app/views/prompts/_prompt_form.html.erb' - - 'app/views/series/_series_blurb.html.erb' - - 'app/views/users/registrations/new.html.erb' - - 'app/views/series/edit.html.erb' - - 'app/views/pseuds/edit.html.erb' - - 'app/views/menu/browse.html.erb' - - 'app/views/collection_items/_collection_item_form.html.erb' - - 'app/views/series/index.html.erb' - - 'app/views/collections/_form.html.erb' - - 'app/views/admin/skins/index_rejected.html.erb' - - 'app/views/owned_tag_sets/_tag_set_associations_remove.html.erb' - - 'app/views/admin_posts/_filters.html.erb' - - 'app/views/external_works/new.html.erb' - - 'app/views/home/index.html.erb' - - 'app/views/bookmarks/_bookmark_item_module.html.erb' - - 'app/views/admin_posts/edit.html.erb' - - 'app/views/admin/skins/index_approved.html.erb' - - 'app/views/bookmarks/edit.html.erb' - - 'app/views/fandoms/show.html.erb' - - 'app/views/inbox/_approve_button.html.erb' - - 'app/views/users/registrations/_legal.html.erb' - - 'app/views/locales/_navigation.html.erb' - - 'app/views/bookmarks/share.html.erb' - - 'app/views/pseuds/index.html.erb' - - 'app/views/series/_series_navigation.html.erb' - - 'app/views/chapters/new.html.erb' - - 'app/views/admin/admin_users/confirm_delete_user_creations.html.erb' - - 'app/views/admin/skins/index.html.erb' - - 'app/views/chapters/edit.html.erb' - - 'app/views/admin/banners/show.html.erb' - - 'app/views/layouts/_footer.html.erb' - - 'app/views/works/_work_abbreviated_list.html.erb' - - 'app/views/stats/index.html.erb' - - 'app/views/users/_contents.html.erb' - - 'app/views/menu/_menu_browse.html.erb' - - 'app/views/admin/banners/_banner_form.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_associations.html.erb' - - 'app/views/tags/search.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb' - - 'app/views/people/search.html.erb' - - 'app/views/bookmarks/confirm_delete.html.erb' - - 'app/views/menu/about.html.erb' - - 'app/views/collection_participants/_participant_form.html.erb' - - 'app/views/external_works/edit.html.erb' - - 'app/views/menu/_menu_fandoms.html.erb' - - 'app/views/admin/activities/show.html.erb' - - 'app/views/prompts/_prompt_navigation.html.erb' - - 'app/views/home/first_login_help.html.erb' - - 'app/views/owned_tag_sets/_show_tag_set_tags.html.erb' - - 'app/views/admin_mailer/edited_comment_notification.html.erb' - - 'app/views/challenge_signups/_signup_controls.html.erb' - - 'app/views/challenge/gift_exchange/_gift_exchange_form.html.erb' - - 'app/views/collections/_bookmarks_module.html.erb' - - 'app/views/pseuds/_pseud_blurb.html.erb' - - 'app/views/tag_wranglers/index.html.erb' - - 'app/views/home/lost_cookie.html.erb' - - 'app/views/tags/index.html.erb' - - 'app/views/collection_items/_item_fields.html.erb' - - 'app/views/external_authors/_external_author_blurb.html.erb' - - 'app/views/owned_tag_sets/_navigation.html.erb' - - 'app/views/tags/show.html.erb' - - 'app/views/skins/_header.html.erb' - - 'app/views/users/change_email.html.erb' - - 'app/views/owned_tag_sets/_tag_set_blurb.html.erb' - - 'app/views/comment_mailer/comment_reply_notification.html.erb' - - 'app/views/inbox/_read_form.html.erb' - - 'app/views/skins/new_wizard.html.erb' - - 'app/views/orphans/new.html.erb' - - 'app/views/skins/_skin_navigation.html.erb' - - 'app/views/collections/_collection_blurb.html.erb' - - 'app/views/external_works/show.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form.html.erb' - - 'app/views/comment_mailer/comment_notification.html.erb' - - 'app/views/gifts/index.html.erb' - - 'app/views/users/change_password.html.erb' - - 'app/views/users/edit.html.erb' - - 'app/views/archive_faqs/edit.html.erb' - - 'app/views/orphans/_orphan_work.html.erb' - - 'app/views/challenge_signups/_signup_form.html.erb' - - 'app/views/locales/edit.html.erb' - - 'app/views/pseuds/new.html.erb' - - 'app/views/home/_inbox_module.html.erb' - - 'app/views/orphans/_choose_pseud.html.erb' - - 'app/views/profile/show.html.erb' - - 'app/views/admin/admin_invitations/index.html.erb' - - 'app/views/layouts/mailer.html.erb' - - 'app/views/comments/unreviewed.html.erb' - - 'app/views/known_issues/new.html.erb' - - 'app/views/tag_wranglings/index.html.erb' - - 'app/views/users/confirmation.html.erb' - - 'app/views/admin/spam/index.html.erb' - - 'app/views/inbox/_reply_button.html.erb' - - 'app/views/owned_tag_sets/index.html.erb' - - 'app/views/share/_share.html.erb' - - 'app/views/works/_work_module.html.erb' - - 'app/views/collections/new.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form_management.html.erb' - - 'app/views/bookmarks/_bookmark_blurb_short.html.erb' - - 'app/views/series/_series_module.html.erb' - - 'app/views/works/drafts.html.erb' - - 'app/views/bookmarks/new.html.erb' - - 'app/views/home/_news_module.html.erb' - - 'app/views/admin_posts/_admin_post_form.html.erb' - - 'app/views/skins/_skin_actions.html.erb' - - 'app/views/admin/admin_invitations/find.html.erb' - - 'app/views/challenge_claims/_user_index.html.erb' - - 'app/views/tag_wranglings/_wrangler_dashboard.html.erb' - - 'app/views/challenge_signups/summary.html.erb' - - 'app/views/languages/_form.html.erb' - - 'app/views/menu/fandoms.html.erb' - - 'app/views/comments/_comment_abbreviated_list.html.erb' - - 'app/views/comments/_comment_actions.html.erb' - - 'app/views/user_mailer/signup_notification.html.erb' - - 'app/views/people/index.html.erb' - - 'app/views/tag_set_nominations/show.html.erb' - - 'app/views/skins/new.html.erb' - - 'app/views/layouts/_header.html.erb' - - 'app/views/external_authors/_external_author_form.html.erb' - - 'app/views/user_mailer/change_email.html.erb' - - 'app/views/admin_mailer/comment_notification.html.erb' - - 'app/views/invitations/show.html.erb' - - 'app/views/tag_set_associations/index.html.erb' - - 'app/views/errors/500.html.erb' - - 'app/views/archive_faqs/_question_answer_fields.html.erb' - - 'app/views/invitations/manage.html.erb' - - 'app/views/prompts/_prompt_blurb.html.erb' - - 'app/views/series/manage.html.erb' - - 'app/views/users/registrations/_passwd.html.erb' - - 'app/views/admin/banners/_navigation.html.erb' - - 'app/views/admin/admin_invitations/new.html.erb' - - 'app/views/bookmarks/_bookmark_form.html.erb' - - 'app/views/comments/_confirm_delete.html.erb' - - 'app/views/series/new.html.erb' - - 'app/views/layouts/session.html.erb' - - 'app/views/prompt_restrictions/_prompt_restriction_form.html.erb' - - 'app/views/fandoms/unassigned.html.erb' - - 'app/views/known_issues/_admin_index.html.erb' - - 'app/views/redirect/show.html.erb' - - 'app/views/collection_items/new.html.erb' - - 'app/views/archive_faqs/_archive_faq_order.html.erb' - - 'app/views/skins/edit.html.erb' - - 'app/views/opendoors/tools/index.html.erb' - - 'app/views/subscriptions/_form.html.erb' - - 'app/views/collections/show.html.erb' - - 'app/views/menu/_menu_search.html.erb' - - 'app/views/subscriptions/index.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/collections/_collection_form_delete.html.erb' - - 'app/views/external_authors/_external_author_name.html.erb' - - 'app/views/readings/_reading_blurb.html.erb' - - 'app/views/comments/new.html.erb' - - 'app/views/layouts/_includes.html.erb' - - 'app/views/bookmarks/_bookmark_user_module.html.erb' - - 'app/views/locales/index.html.erb' - - 'app/views/tag_set_nominations/_review.html.erb' - - 'app/views/works/_notes_form.html.erb' - - 'app/views/series/_series_order.html.erb' - - 'app/views/archive_faqs/_archive_faq_questions_order.html.erb' - - 'app/views/skins/index.html.erb' - - 'app/views/tag_set_nominations/_nomination_form.html.erb' - - 'app/views/collections/_header.html.erb' - - 'app/views/collections/edit.html.erb' - - 'app/views/home/about.html.erb' - - 'app/views/challenge/shared/_challenge_navigation_user.html.erb' - - 'app/views/layouts/_banner.html.erb' - - 'app/views/pseuds/delete_preview.html.erb' - - 'app/views/readings/index.html.erb' - - 'app/views/skins/show.html.erb' - - 'app/views/admin_posts/new.html.erb' - - 'app/views/users/sessions/_greeting.html.erb' - - 'app/views/admin_mailer/send_spam_alert.html.erb' - - 'app/views/admin_sessions/new.html.erb' - - 'app/views/archive_faqs/show.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_signups.html.erb' - - 'app/views/comments/_single_comment.html.erb' - - 'app/views/admin/banners/confirm_delete.html.erb' - - 'app/views/external_works/_blurb.html.erb' - - 'app/views/media/index.html.erb' - - 'app/views/potential_matches/index.html.erb' - - 'app/views/external_authors/edit.html.erb' - - 'app/views/pseuds/_pseuds_form.html.erb' - - 'app/views/admin_posts/_admin_index.html.erb' - - 'app/views/owned_tag_sets/_tag_set_association_fields.html.erb' - - 'app/views/admin/banners/new.html.erb' - - 'app/views/languages/new.html.erb' - - 'app/views/potential_matches/_no_potential_givers.html.erb' - - 'app/views/archive_faqs/new.html.erb' - - 'app/views/tags/wrangle.html.erb' - - 'app/views/home/site_map.html.erb' - - 'app/views/users/_header_navigation.html.erb' - - 'app/views/known_issues/edit.html.erb' - - 'app/views/skins/_skin_parent_fields.html.erb' - - 'app/views/tags/new.html.erb' - - 'app/views/comments/show.html.erb' - - 'app/views/user_mailer/delete_work_notification.html.erb' - - 'app/views/works/collected.html.erb' - - 'app/views/potential_matches/_no_match_required.html.erb' - - 'app/views/languages/index.html.erb' - - 'app/views/preferences/index.html.erb' - - 'app/views/user_invite_requests/index.html.erb' - - 'app/views/tag_set_nominations/_tag_nominations.html.erb' - - 'app/views/user_mailer/claim_notification.html.erb' - - 'app/views/bookmarks/search.html.erb' - - 'app/views/bookmarks/search_results.html.erb' - - 'app/views/works/_search_box.html.erb' - - 'app/views/comment_mailer/edited_comment_reply_notification.html.erb' - - 'app/views/works/_work_blurb.html.erb' - - 'app/views/home/dmca.html.erb' - - 'app/views/admin_posts/index.html.erb' - - 'app/views/owned_tag_sets/batch_load.html.erb' - - 'app/views/bookmarks/_bookmark_owner_navigation.html.erb' - - 'app/views/challenge_assignments/_maintainer_index_defaulted.html.erb' - - 'app/views/languages/show.html.erb' - - 'app/views/languages/edit.html.erb' - - 'app/views/locales/_locale_form.html.erb' - - 'app/views/works/edit.html.erb' - - 'app/views/works/edit_tags.html.erb' - - 'app/views/works/index.html.erb' - - 'app/views/works/new.html.erb' - - 'app/views/works/new_import.html.erb' - - 'app/views/works/preview_tags.html.erb' - - 'app/views/works/search.html.erb' - - 'app/views/works/search_results.html.erb' - - 'app/views/works/share.html.erb' - - 'app/views/works/show_multiple.html.erb' - - 'app/views/wrangling_guidelines/_admin_index.html.erb' - - 'app/views/wrangling_guidelines/_wrangling_guideline_form.html.erb' - - 'app/views/wrangling_guidelines/_wrangling_guideline_order.html.erb' - - 'app/views/wrangling_guidelines/edit.html.erb' - - 'app/views/wrangling_guidelines/index.html.erb' - - 'app/views/wrangling_guidelines/manage.html.erb' - - 'app/views/wrangling_guidelines/new.html.erb' - - 'app/views/wrangling_guidelines/show.html.erb' - -Style/StringLiteralsInInterpolation: - Exclude: - - 'app/views/owned_tag_sets/_internal_tag_set_fields.html.erb' - - 'app/views/invitations/_user_invitations.html.erb' - - 'app/views/challenge/shared/_challenge_requests.html.erb' - - 'app/views/user_mailer/challenge_assignment_notification.html.erb' - - 'app/views/admin/admin_users/bulk_search.html.erb' - - 'app/views/pseuds/_pseud_blurb.html.erb' - - 'app/views/works/new_import.html.erb' - -Style/SymbolProc: - Exclude: - - 'app/views/fandoms/unassigned.html.erb' - - 'app/views/owned_tag_sets/_tag_set_form.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/fandoms/index.html.erb' - - 'app/views/potential_match_settings/_potential_match_settings_form.html.erb' - -Style/TernaryParentheses: - Exclude: - - 'app/views/challenge_assignments/_maintainer_index_unfulfilled.html.erb' - - 'app/views/layouts/home.html.erb' - - 'app/views/admin/skins/index_rejected.html.erb' - - 'app/views/collection_mailer/item_added_notification.html.erb' - - 'app/views/works/_work_header_navigation.html.erb' - - 'app/views/admin/skins/index_approved.html.erb' - - 'app/views/tag_set_nominations/_review.html.erb' - - 'app/views/works/_notes_form.html.erb' - - 'app/views/works/_work_module.html.erb' - - 'app/views/challenge_assignments/_assignment_blurb.html.erb' - - 'app/views/challenge/shared/_challenge_meta.html.erb' - - 'app/views/prompts/_prompt_form_tag_options.html.erb' - - 'app/views/admin/skins/index.html.erb' - - 'app/views/skins/_form.html.erb' - - 'app/views/collection_profile/show.html.erb' - - 'app/views/layouts/application.html.erb' - - 'app/views/stats/index.html.erb' - - 'app/views/tags/edit.html.erb' - - 'app/views/users/_sidebar.html.erb' - - 'app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb' - - 'app/views/works/_filters.html.erb' - - 'app/views/bookmarks/_filters.html.erb' - - 'app/views/admin_posts/index.html.erb' - - 'app/views/skins/_skin_navigation.html.erb' - - 'app/views/layouts/session.html.erb' - - 'app/views/prompt_restrictions/_prompt_restriction_form.html.erb' - -Style/TrailingCommaInArguments: - Exclude: - - 'app/views/home/first_login_help.html.erb' - -Style/WordArray: - Exclude: - - 'app/views/works/_search_form.html.erb' - - 'app/views/tags/_search_form.html.erb' - -Style/ZeroLengthPredicate: - Exclude: - - 'app/views/collection_mailer/item_added_notification.html.erb' diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md index 941dbf1965e..128480ddacf 100644 --- a/ACKNOWLEDGMENTS.md +++ b/ACKNOWLEDGMENTS.md @@ -12,7 +12,7 @@ Acknowledgments

Galera Cluster for clustered MySQL.

GitHub for collaborative programming.

HAProxy for load balancing.

-

Hound for style guidance.

+

Hound and reviewdog logo reviewdog for style guidance.

Jira for our issue tracking.

NGINX for our front end.

Memcached for caching.

@@ -23,5 +23,5 @@ Acknowledgments

RSpec for unit tests.

Ruby as our language.

RubyMine for our integrated development environment.

+

Sentry for APM/application monitoring.

Slack for communications.

-

Vagrant for our development environment.

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4f9fecea70f..a9a71a4b64d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ and a [list of Known Issues](https://archiveofourown.org/known_issues) for publicly editable. If you need help using the site, or want to report an issue you have found, -please [contact the AO3 Support team](https://archiveofourown.org/support). +please [contact the AO3 Support team](https://archiveofourown.org/support). Our Support team is staffed by volunteers, so please wait for a response before submitting another ticket. Duplicate submissions will not make things happen faster. ## Reporting security issues @@ -25,14 +25,15 @@ official OTW volunteers, please feel free to make changes! ## Suggesting new features -Please [contact the AO3 Support team](https://archiveofourown.org/support). +Please [contact the AO3 Support team](https://archiveofourown.org/support). Our Support team is staffed by volunteers, so please wait for a response before submitting another ticket. Duplicate submissions will not make things happen faster. ## Contributing code **We only accept pull requests for issues we have already added to [Jira](https://otwarchive.atlassian.net)**, with the exception of spelling corrections and documentation improvements -(e.g. any Markdown files). +(e.g. any Markdown files). We also do not accept code generated by AI tools; for more information, +please refer to [our commit policy](https://github.com/otwcode/otwarchive/wiki/Commit-Policy#scary-legal-stuff). If you'd like the ability to comment on, assign, and transition issues, you're welcome to create a Jira account! (It makes things a bit easier for us diff --git a/Gemfile b/Gemfile index d12d130f256..72596c99adb 100644 --- a/Gemfile +++ b/Gemfile @@ -56,7 +56,6 @@ gem "aws-sdk-s3" gem 'css_parser' gem "terrapin" -gem "kt-paperclip", ">= 5.2.0" # for looking up image dimensions quickly gem 'fastimage' @@ -80,14 +79,6 @@ gem 'escape_utils', '1.2.1' gem 'timeliness' -# TODO: rpm_contrib is deprecated and needs to be replaced -# Here is a list of possible alternatives: -# https://github.com/newrelic/extends_newrelic_rpm -# -# The last working version is not compatible with Rails 5 -# -# gem 'rpm_contrib', '2.2.0' - # for generating graphs gem 'google_visualr', git: 'https://github.com/winston/google_visualr' @@ -123,7 +114,7 @@ gem "departure", "~> 6.5" gem "mail", ">= 2.8" group :test do - gem "rspec-rails", "~> 4.0.1" + gem "rspec-rails", "~> 6.0" gem 'pickle' gem 'shoulda' gem "capybara" @@ -163,7 +154,7 @@ end group :linters do gem "erb_lint", "0.4.0" - gem "rubocop", "1.22.1" + gem "rubocop", "1.22.3" gem "rubocop-rails", "2.12.4" gem "rubocop-rspec", "2.6.0" end @@ -180,11 +171,16 @@ gem 'rvm-capistrano' # Use unicorn as the web server gem 'unicorn', '~> 5.5', require: false +# Install puma so we can migrate to it +gem "puma", "~> 6.5.0" # Use god as the monitor gem 'god', '~> 0.13.7' group :staging, :production do - # Place the New Relic gem as low in the list as possible, allowing the - # frameworks above it to be instrumented when the gem initializes. - gem "newrelic_rpm" + gem "stackprof" + gem "sentry-ruby" + gem "sentry-rails" + gem "sentry-resque" end + +gem "image_processing", "~> 1.12" diff --git a/Gemfile.lock b/Gemfile.lock index 9bd481f3879..a4e628b9c13 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,75 +24,75 @@ GEM remote: https://rubygems.org/ specs: aaronh-chronic (0.3.9) - actioncable (7.0.8.1) - actionpack (= 7.0.8.1) - activesupport (= 7.0.8.1) + actioncable (7.0.8.5) + actionpack (= 7.0.8.5) + activesupport (= 7.0.8.5) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.8.1) - actionpack (= 7.0.8.1) - activejob (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + actionmailbox (7.0.8.5) + actionpack (= 7.0.8.5) + activejob (= 7.0.8.5) + activerecord (= 7.0.8.5) + activestorage (= 7.0.8.5) + activesupport (= 7.0.8.5) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.8.1) - actionpack (= 7.0.8.1) - actionview (= 7.0.8.1) - activejob (= 7.0.8.1) - activesupport (= 7.0.8.1) + actionmailer (7.0.8.5) + actionpack (= 7.0.8.5) + actionview (= 7.0.8.5) + activejob (= 7.0.8.5) + activesupport (= 7.0.8.5) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.8.1) - actionview (= 7.0.8.1) - activesupport (= 7.0.8.1) + actionpack (7.0.8.5) + actionview (= 7.0.8.5) + activesupport (= 7.0.8.5) rack (~> 2.0, >= 2.2.4) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) actionpack-page_caching (1.2.4) actionpack (>= 4.0.0) - actiontext (7.0.8.1) - actionpack (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + actiontext (7.0.8.5) + actionpack (= 7.0.8.5) + activerecord (= 7.0.8.5) + activestorage (= 7.0.8.5) + activesupport (= 7.0.8.5) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.8.1) - activesupport (= 7.0.8.1) + actionview (7.0.8.5) + activesupport (= 7.0.8.5) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) active_record_query_trace (1.8.2) activerecord (>= 6.0.0) - activejob (7.0.8.1) - activesupport (= 7.0.8.1) + activejob (7.0.8.5) + activesupport (= 7.0.8.5) globalid (>= 0.3.6) - activemodel (7.0.8.1) - activesupport (= 7.0.8.1) + activemodel (7.0.8.5) + activesupport (= 7.0.8.5) activemodel-serializers-xml (1.0.2) activemodel (> 5.x) activesupport (> 5.x) builder (~> 3.1) - activerecord (7.0.8.1) - activemodel (= 7.0.8.1) - activesupport (= 7.0.8.1) - activestorage (7.0.8.1) - actionpack (= 7.0.8.1) - activejob (= 7.0.8.1) - activerecord (= 7.0.8.1) - activesupport (= 7.0.8.1) + activerecord (7.0.8.5) + activemodel (= 7.0.8.5) + activesupport (= 7.0.8.5) + activestorage (7.0.8.5) + actionpack (= 7.0.8.5) + activejob (= 7.0.8.5) + activerecord (= 7.0.8.5) + activesupport (= 7.0.8.5) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.8.1) + activesupport (7.0.8.5) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -139,7 +139,7 @@ GEM bigdecimal (3.1.6) brakeman (6.1.2) racc - builder (3.2.4) + builder (3.3.0) bullet (7.1.6) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) @@ -173,7 +173,7 @@ GEM chronic (0.10.2) climate_control (1.2.0) coderay (1.1.3) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) crack (1.0.0) bigdecimal @@ -257,9 +257,9 @@ GEM rainbow rubocop smart_properties - erubi (1.12.0) + erubi (1.13.0) escape_utils (1.2.1) - et-orbi (1.2.7) + et-orbi (1.2.11) tzinfo factory_bot (6.4.6) activesupport (>= 5.0.0) @@ -293,8 +293,8 @@ GEM faraday-retry (1.0.3) fastimage (2.3.0) ffi (1.16.3) - fugit (1.10.1) - et-orbi (~> 1, >= 1.2.7) + fugit (1.11.1) + et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) globalid (1.2.1) activesupport (>= 6.1) @@ -308,12 +308,11 @@ GEM httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - i18n (1.14.1) + i18n (1.14.6) concurrent-ruby (~> 1.0) - i18n-tasks (1.0.13) + i18n-tasks (1.0.14) activesupport (>= 4.0.2) ast (>= 2.1.0) - better_html (>= 1.0, < 3.0) erubi highline (>= 2.0.0) i18n @@ -321,15 +320,12 @@ GEM rails-i18n rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) + image_processing (1.12.2) + mini_magick (>= 4.9.5, < 5) + ruby-vips (>= 2.0.17, < 3) jmespath (1.6.2) json (2.7.1) kgio (2.10.0) - kt-paperclip (7.2.2) - activemodel (>= 4.2.0) - activesupport (>= 4.2.0) - marcel (~> 1.0.1) - mime-types - terrapin (>= 0.6.0, < 2.0) launchy (2.5.2) addressable (~> 2.8) lograge (0.14.0) @@ -337,7 +333,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.22.0) + loofah (2.23.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -347,12 +343,12 @@ GEM net-smtp marcel (1.0.2) matrix (0.4.2) - mechanize (2.10.0) + mechanize (2.12.2) addressable (~> 2.8) base64 domain_name (~> 0.5, >= 0.5.20190701) http-cookie (~> 1.0, >= 1.0.3) - mime-types (~> 3.0) + mime-types (~> 3.3) net-http-digest_auth (~> 1.4, >= 1.4.1) net-http-persistent (>= 2.5.2, < 5.0.dev) nkf @@ -360,13 +356,14 @@ GEM rubyntlm (~> 0.6, >= 0.6.3) webrick (~> 1.7) webrobots (~> 0.1.2) - method_source (1.0.0) + method_source (1.1.0) mime-types (3.5.2) mime-types-data (~> 3.2015) mime-types-data (3.2024.0206) + mini_magick (4.12.0) mini_mime (1.1.2) - mini_portile2 (2.8.5) - minitest (5.22.2) + mini_portile2 (2.8.8) + minitest (5.25.1) mono_logger (1.1.2) multi_json (1.15.0) multi_test (1.1.0) @@ -396,14 +393,13 @@ GEM net-ssh-gateway (2.0.0) net-ssh (>= 4.0.0) netrc (0.11.0) - newrelic_rpm (9.7.1) nio4r (2.7.0) nkf (0.2.0) - nokogiri (1.16.3) + nokogiri (1.16.8) mini_portile2 (~> 2.8.2) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.24.0) + parallel (1.25.1) parser (3.3.0.5) ast (~> 2.4.1) racc @@ -425,11 +421,13 @@ GEM byebug (~> 11.0) pry (>= 0.13, < 0.15) public_suffix (5.0.4) + puma (6.5.0) + nio4r (~> 2.0) pundit (2.3.1) activesupport (>= 3.0.0) raabro (1.4.0) - racc (1.7.3) - rack (2.2.8.1) + racc (1.8.1) + rack (2.2.9) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-dev-mark (0.8.0) @@ -439,20 +437,20 @@ GEM rack (~> 2.2, >= 2.2.4) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.8.1) - actioncable (= 7.0.8.1) - actionmailbox (= 7.0.8.1) - actionmailer (= 7.0.8.1) - actionpack (= 7.0.8.1) - actiontext (= 7.0.8.1) - actionview (= 7.0.8.1) - activejob (= 7.0.8.1) - activemodel (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + rails (7.0.8.5) + actioncable (= 7.0.8.5) + actionmailbox (= 7.0.8.5) + actionmailer (= 7.0.8.5) + actionpack (= 7.0.8.5) + actiontext (= 7.0.8.5) + actionview (= 7.0.8.5) + activejob (= 7.0.8.5) + activemodel (= 7.0.8.5) + activerecord (= 7.0.8.5) + activestorage (= 7.0.8.5) + activesupport (= 7.0.8.5) bundler (>= 1.15.0) - railties (= 7.0.8.1) + railties (= 7.0.8.5) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -461,22 +459,22 @@ GEM activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.0) + rails-html-sanitizer (1.6.1) loofah (~> 2.21) - nokogiri (~> 1.14) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) rails-i18n (7.0.8) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.0.8.1) - actionpack (= 7.0.8.1) - activesupport (= 7.0.8.1) + railties (7.0.8.5) + actionpack (= 7.0.8.5) + activesupport (= 7.0.8.5) method_source rake (>= 12.2) thor (~> 1.0) zeitwerk (~> 2.5) rainbow (3.1.1) raindrops (0.20.1) - rake (13.1.0) + rake (13.2.1) redis (3.3.5) redis-namespace (1.8.2) redis (>= 3.0.4) @@ -501,26 +499,26 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rexml (3.2.6) + rexml (3.3.9) rollout (2.4.3) rspec-core (3.13.0) rspec-support (~> 3.13.0) - rspec-expectations (3.13.0) + rspec-expectations (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-mocks (3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (4.0.2) - actionpack (>= 4.2) - activesupport (>= 4.2) - railties (>= 4.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) + rspec-rails (6.1.5) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) rspec-support (3.13.1) - rubocop (1.22.1) + rubocop (1.22.3) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) @@ -529,7 +527,7 @@ GEM rubocop-ast (>= 1.12.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.31.1) + rubocop-ast (1.31.2) parser (>= 3.3.0.4) rubocop-rails (2.12.4) activesupport (>= 4.2.0) @@ -538,6 +536,8 @@ GEM rubocop-rspec (2.6.0) rubocop (~> 1.19) ruby-progressbar (1.13.0) + ruby-vips (2.2.1) + ffi (~> 1.12) ruby2_keywords (0.0.5) rubyntlm (0.6.3) rubyzip (2.3.2) @@ -553,6 +553,15 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) + sentry-rails (5.18.0) + railties (>= 5.0) + sentry-ruby (~> 5.18.0) + sentry-resque (5.18.0) + resque (>= 1.24) + sentry-ruby (~> 5.18.0) + sentry-ruby (5.18.0) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) shoulda (4.0.0) shoulda-context (~> 2.0) shoulda-matchers (~> 4.0) @@ -577,6 +586,7 @@ GEM sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) + stackprof (0.2.26) stringex (2.8.6) sys-uname (1.2.3) ffi (~> 1.1) @@ -586,7 +596,7 @@ GEM climate_control test-unit (3.6.2) power_assert - thor (1.3.1) + thor (1.3.2) tilt (2.3.0) timecop (0.9.8) timeliness (0.4.5) @@ -608,7 +618,7 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.8.1) + webrick (1.8.2) webrobots (0.1.2) websocket (1.2.10) websocket-driver (0.7.6) @@ -623,7 +633,7 @@ GEM will_paginate (4.0.0) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.13) + zeitwerk (2.6.18) PLATFORMS ruby @@ -673,8 +683,8 @@ DEPENDENCIES htmlentities httparty i18n-tasks + image_processing (~> 1.12) kgio (= 2.10.0) - kt-paperclip (>= 5.2.0) launchy lograge mail (>= 2.8) @@ -683,12 +693,12 @@ DEPENDENCIES minitest mysql2 n_plus_one_control - newrelic_rpm nokogiri (>= 1.8.5) permit_yo phraseapp-in-context-editor-ruby (>= 1.0.6) pickle pry-byebug + puma (~> 6.5.0) pundit rack (~> 2.2) rack-attack @@ -703,17 +713,21 @@ DEPENDENCIES resque-scheduler rest-client (~> 2.1.0) rollout - rspec-rails (~> 4.0.1) - rubocop (= 1.22.1) + rspec-rails (~> 6.0) + rubocop (= 1.22.3) rubocop-rails (= 2.12.4) rubocop-rspec (= 2.6.0) rvm-capistrano sanitize (>= 4.6.5) selenium-webdriver + sentry-rails + sentry-resque + sentry-ruby shoulda simplecov simplecov-cobertura sprockets (< 4) + stackprof terrapin test-unit (~> 3.2) timecop diff --git a/README.md b/README.md index b91d3e67c3f..b7234cdb7a2 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ We welcome pull requests for bugs described in our issue tracker. Please see our * [Developer Documentation](https://github.com/otwcode/otwarchive/wiki) * [Commit Policy](https://github.com/otwcode/otwarchive/wiki/Commit-policy) +We do not have a public chat, but you are welcome to contact us at otw-coders@transformativeworks.org if you have any questions. + API ---------- There is currently no API for the OTW-Archive software. While it is something we're considering for the future, we ask that contributors instead focus on issues already in our [Jira issue tracker](https://otwarchive.atlassian.net/). @@ -36,6 +38,7 @@ We benefit from software and services that are free to use for Open Source proje * [Codeship](https://codeship.com/) * [Hound](https://houndci.com/) by [thoughtbot](https://thoughtbot.com/) * [BrowserStack](https://www.browserstack.com) +* [Sentry](https://sentry.io) * [Full list of acknowledgments](ACKNOWLEDGMENTS.md) Thank you kindly! diff --git a/SECURITY.md b/SECURITY.md index 63258de0691..1a646472cdc 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -5,7 +5,7 @@ with details and reproduction steps. We will get back to you as soon as possible and we may ask for additional information or guidance. Please avoid testing for security issues on the Archive of Our Own itself, -as you risk disrupting other users and violating the [Terms of Service](https://archiveofourown.org/tos#IV.C.). +as you risk disrupting other users and violating the [Terms of Service](https://archiveofourown.org/content#II.K.1). Please give us a reasonable amount of time to address the issue before any disclosure to the public or a third-party. diff --git a/app/controllers/admin/admin_users_controller.rb b/app/controllers/admin/admin_users_controller.rb index 94a7e96e298..260b230c25c 100644 --- a/app/controllers/admin/admin_users_controller.rb +++ b/app/controllers/admin/admin_users_controller.rb @@ -1,6 +1,31 @@ class Admin::AdminUsersController < Admin::BaseController include ExportsHelper + before_action :set_roles, only: [:index, :bulk_search] + before_action :load_user, only: [:show, :update, :confirm_delete_user_creations, :destroy_user_creations, :troubleshoot, :activate, :creations] + before_action :user_is_banned, only: [:confirm_delete_user_creations, :destroy_user_creations] + before_action :load_user_creations, only: [:confirm_delete_user_creations, :creations] + + def set_roles + @roles = Role.assignable.distinct + end + + def load_user + @user = User.find_by!(login: params[:id]) + end + + def user_is_banned + return if @user&.banned? + + flash[:error] = ts("That user is not banned!") + redirect_to admin_users_path + end + + def load_user_creations + @works = @user.works.paginate(page: params[:works_page]) + @comments = @user.comments.paginate(page: params[:comments_page]) + end + def index authorize User @role_values = @roles.map{ |role| [role.name.humanize.titlecase, role.name] } @@ -37,22 +62,16 @@ def bulk_search end end - before_action :set_roles, only: [:index, :bulk_search] - def set_roles - @roles = Role.assignable.distinct - end - # GET admin/users/1 def show - @user = authorize User.find_by!(login: params[:id]) - @hide_dashboard = true + authorize @user @page_subtitle = t(".page_title", login: @user.login) log_items end # POST admin/users/update def update - @user = authorize User.find_by(login: params[:id]) + authorize @user attributes = permitted_attributes(@user) @user.email = attributes[:email] if attributes[:email].present? @@ -119,19 +138,8 @@ def update_status end end - before_action :user_is_banned, only: [:confirm_delete_user_creations, :destroy_user_creations] - def user_is_banned - @user = User.find_by(login: params[:id]) - unless @user && @user.banned? - flash[:error] = ts("That user is not banned!") - redirect_to admin_users_path and return - end - end - def confirm_delete_user_creations authorize @user - @works = @user.works.paginate(page: params[:works_page]) - @comments = @user.comments.paginate(page: params[:comments_page]) @bookmarks = @user.bookmarks @collections = @user.sole_owned_collections @series = @user.series @@ -139,18 +147,26 @@ def confirm_delete_user_creations def destroy_user_creations authorize @user - creations = @user.works + @user.bookmarks + @user.sole_owned_collections + @user.comments + + creations = @user.works + @user.bookmarks + @user.sole_owned_collections creations.each do |creation| AdminActivity.log_action(current_admin, creation, action: "destroy spam", summary: creation.inspect) creation.mark_as_spam! if creation.respond_to?(:mark_as_spam!) creation.destroy end - flash[:notice] = ts("All creations by user %{login} have been deleted.", login: @user.login) + + # comments are special and needs to be handled separately + @user.comments.each do |comment| + AdminActivity.log_action(current_admin, comment, action: "destroy spam", summary: comment.inspect) + # Akismet spam procedures are skipped, since logged-in comments aren't spam-checked anyways + comment.destroy_or_mark_deleted # comments with replies cannot be destroyed, mark deleted instead + end + + flash[:notice] = t(".success", login: @user.login) redirect_to(admin_users_path) end def troubleshoot - @user = User.find_by(login: params[:id]) authorize @user @user.fix_user_subscriptions @@ -163,7 +179,6 @@ def troubleshoot end def activate - @user = User.find_by(login: params[:id]) authorize @user @user.activate @@ -177,6 +192,11 @@ def activate end end + def creations + authorize @user + @page_subtitle = t(".page_title", login: @user.login) + end + def log_items @log_items ||= @user.log_items.sort_by(&:created_at).reverse end diff --git a/app/controllers/admin/api_controller.rb b/app/controllers/admin/api_controller.rb index fa24a7b09c3..e6efb99333a 100644 --- a/app/controllers/admin/api_controller.rb +++ b/app/controllers/admin/api_controller.rb @@ -2,12 +2,14 @@ class Admin::ApiController < Admin::BaseController before_action :check_for_cancel, only: [:create, :update] def index + @page_subtitle = t(".page_title") @api_keys = if params[:query] sql_query = "%" + params[:query] + "%" ApiKey.where("name LIKE ?", sql_query).order("name").paginate(page: params[:page]) else ApiKey.order("name").paginate(page: params[:page]) end + authorize @api_keys end def show @@ -15,10 +17,12 @@ def show end def new - @api_key = ApiKey.new + @page_subtitle = t(".page_title") + @api_key = authorize ApiKey.new end def create + authorize ApiKey # Use provided api key params if available otherwise fallback to empty # ApiKey object @api_key = params[:api_key].nil? ? ApiKey.new : ApiKey.new(api_key_params) @@ -31,11 +35,12 @@ def create end def edit - @api_key = ApiKey.find(params[:id]) + @page_subtitle = t(".page_title") + @api_key = authorize ApiKey.find(params[:id]) end def update - @api_key = ApiKey.find(params[:id]) + @api_key = authorize ApiKey.find(params[:id]) if @api_key.update(api_key_params) flash[:notice] = ts("Access token was successfully updated") redirect_to action: "index" @@ -45,7 +50,7 @@ def update end def destroy - @api_key = ApiKey.find(params[:id]) + @api_key = authorize ApiKey.find(params[:id]) @api_key.destroy redirect_to(admin_api_path) end diff --git a/app/controllers/admin_posts_controller.rb b/app/controllers/admin_posts_controller.rb index 92637ca4657..426c71b3d3e 100644 --- a/app/controllers/admin_posts_controller.rb +++ b/app/controllers/admin_posts_controller.rb @@ -94,7 +94,8 @@ def load_languages def admin_post_params params.require(:admin_post).permit( - :admin_id, :title, :content, :translated_post_id, :language_id, :tag_list, :comment_permissions + :admin_id, :title, :content, :translated_post_id, :language_id, :tag_list, + :comment_permissions, :moderated_commenting_enabled ) end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5cf4afd6843..89a98aa6b0c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,5 @@ class ApplicationController < ActionController::Base + include ActiveStorage::SetCurrent include Pundit::Authorization protect_from_forgery with: :exception, prepend: true rescue_from ActionController::InvalidAuthenticityToken, with: :display_auth_error @@ -176,7 +177,7 @@ def load_admin_banner before_action :load_tos_popup def load_tos_popup # Integers only, YYYY-MM-DD format of date Board approved TOS - @current_tos_version = 20180523 + @current_tos_version = 2024_11_19 # rubocop:disable Style/NumericLiterals end # store previous page in session to make redirecting back possible @@ -269,13 +270,17 @@ def access_denied(options ={}) def admin_only_access_denied respond_to do |format| format.html do - flash[:error] = ts("Sorry, only an authorized admin can access the page you were trying to reach.") + flash[:error] = t("admin.access.page_access_denied") redirect_to root_path end format.json do - errors = [ts("Sorry, only an authorized admin can do that.")] + errors = [t("admin.access.action_access_denied")] render json: { errors: errors }, status: :forbidden end + format.js do + flash[:error] = t("admin.access.page_access_denied") + render js: "window.location.href = '#{root_path}';" + end end end @@ -390,9 +395,18 @@ def use_caching? def check_user_status if current_user.is_a?(User) && (current_user.suspended? || current_user.banned?) if current_user.suspended? - flash[:error] = t("suspension_notice", default: "Your account has been suspended until %{suspended_until}. You may not add or edit content until your suspension has been resolved. Please contact Abuse for more information.", suspended_until: localize(current_user.suspended_until)).html_safe + suspension_end = current_user.suspended_until + + # Unban threshold is 6:51pm, 12 hours after the unsuspend_users rake task located in schedule.rb is run at 6:51am + unban_theshold = DateTime.new(suspension_end.year, suspension_end.month, suspension_end.day, 18, 51, 0, "+00:00") + + # If the stated suspension end date is after the unban threshold we need to advance a day + suspension_end = suspension_end.next_day(1) if suspension_end > unban_theshold + localized_suspension_end = view_context.date_in_zone(suspension_end) + flash[:error] = t("users.status.suspension_notice_html", suspended_until: localized_suspension_end, contact_abuse_link: view_context.link_to(t("users.contact_abuse"), new_abuse_report_path)) + else - flash[:error] = t("ban_notice", default: "Your account has been banned. You are not permitted to add or edit archive content. Please contact Abuse for more information.").html_safe + flash[:error] = t("users.status.ban_notice_html", contact_abuse_link: view_context.link_to(t("users.contact_abuse"), new_abuse_report_path)) end redirect_to current_user end @@ -401,8 +415,18 @@ def check_user_status # Prevents temporarily suspended users from deleting content def check_user_not_suspended return unless current_user.is_a?(User) && current_user.suspended? + + suspension_end = current_user.suspended_until + + # Unban threshold is 6:51pm, 12 hours after the unsuspend_users rake task located in schedule.rb is run at 6:51am + unban_theshold = DateTime.new(suspension_end.year, suspension_end.month, suspension_end.day, 18, 51, 0, "+00:00") + + # If the stated suspension end date is after the unban threshold we need to advance a day + suspension_end = suspension_end.next_day(1) if suspension_end > unban_theshold + localized_suspension_end = view_context.date_in_zone(suspension_end) - flash[:error] = t("suspension_notice", default: "Your account has been suspended until %{suspended_until}. You may not add or edit content until your suspension has been resolved. Please contact Abuse for more information.", suspended_until: localize(current_user.suspended_until)).html_safe + flash[:error] = t("users.status.suspension_notice_html", suspended_until: localized_suspension_end, contact_abuse_link: view_context.link_to(t("users.contact_abuse"), new_abuse_report_path)) + redirect_to current_user end diff --git a/app/controllers/archive_faqs_controller.rb b/app/controllers/archive_faqs_controller.rb index b97130558f8..8a8a8817ba2 100644 --- a/app/controllers/archive_faqs_controller.rb +++ b/app/controllers/archive_faqs_controller.rb @@ -1,14 +1,14 @@ class ArchiveFaqsController < ApplicationController - before_action :admin_only, except: [:index, :show] before_action :set_locale before_action :validate_locale, if: :logged_in_as_admin? before_action :require_language_id + before_action :default_locale_only, only: [:new, :create, :manage, :update_positions, :confirm_delete, :destroy] around_action :with_locale # GET /archive_faqs def index - @archive_faqs = ArchiveFaq.order('position ASC') + @archive_faqs = ArchiveFaq.order("position ASC") unless logged_in_as_admin? @archive_faqs = @archive_faqs.with_translations(I18n.locale) end @@ -40,6 +40,7 @@ def show end protected + def build_questions notice = "" num_to_build = params["num_questions"] ? params["num_questions"].to_i : @archive_faq.questions.count @@ -59,9 +60,10 @@ def build_questions end public + # GET /archive_faqs/new def new - @archive_faq = ArchiveFaq.new + @archive_faq = authorize ArchiveFaq.new 1.times { @archive_faq.questions.build(attributes: { question: "This is a temporary question", content: "This is temporary content", anchor: "ThisIsATemporaryAnchor"})} respond_to do |format| format.html # new.html.erb @@ -70,32 +72,34 @@ def new # GET /archive_faqs/1/edit def edit - @archive_faq = ArchiveFaq.find_by(slug: params[:id]) + @archive_faq = authorize ArchiveFaq.find_by(slug: params[:id]) + authorize :archive_faq, :full_access? if default_locale? build_questions end # GET /archive_faqs/manage def manage - @archive_faqs = ArchiveFaq.order('position ASC') + @archive_faqs = authorize ArchiveFaq.order("position ASC") end # POST /archive_faqs def create - @archive_faq = ArchiveFaq.new(archive_faq_params) - if @archive_faq.save - flash[:notice] = 'ArchiveFaq was successfully created.' - redirect_to(@archive_faq) - else - render action: "new" - end + @archive_faq = authorize ArchiveFaq.new(archive_faq_params) + if @archive_faq.save + flash[:notice] = t(".success") + redirect_to(@archive_faq) + else + render action: "new" + end end # PUT /archive_faqs/1 def update - @archive_faq = ArchiveFaq.find_by(slug: params[:id]) + @archive_faq = authorize ArchiveFaq.find_by(slug: params[:id]) + authorize :archive_faq, :full_access? if default_locale? if @archive_faq.update(archive_faq_params) - flash[:notice] = 'ArchiveFaq was successfully updated.' + flash[:notice] = t(".success") redirect_to(@archive_faq) else render action: "edit" @@ -104,9 +108,10 @@ def update # reorder FAQs def update_positions + authorize :archive_faq if params[:archive_faqs] @archive_faqs = ArchiveFaq.reorder_list(params[:archive_faqs]) - flash[:notice] = ts("Archive FAQs order was successfully updated.") + flash[:notice] = t(".success") elsif params[:archive_faq] params[:archive_faq].each_with_index do |id, position| ArchiveFaq.update(id, position: position + 1) @@ -149,6 +154,13 @@ def require_language_id redirect_to url_for(request.query_parameters.merge(language_id: @i18n_locale.to_s)) end + def default_locale_only + return if default_locale? + + flash[:error] = t("archive_faqs.default_locale_only") + redirect_to archive_faqs_path + end + # Setting I18n.locale directly is not thread safe def with_locale I18n.with_locale(@i18n_locale) { yield } @@ -156,18 +168,22 @@ def with_locale # GET /archive_faqs/1/confirm_delete def confirm_delete - @archive_faq = ArchiveFaq.find_by(slug: params[:id]) + @archive_faq = authorize ArchiveFaq.find_by(slug: params[:id]) end # DELETE /archive_faqs/1 def destroy - @archive_faq = ArchiveFaq.find_by(slug: params[:id]) + @archive_faq = authorize ArchiveFaq.find_by(slug: params[:id]) @archive_faq.destroy redirect_to(archive_faqs_path) end private + def default_locale? + @i18n_locale.to_s == I18n.default_locale.to_s + end + def archive_faq_params params.require(:archive_faq).permit( :title, diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index e4b0b590037..a7ba9f7d38a 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -92,7 +92,7 @@ def noncanonical_tag raise "Redshirt: Attempted to constantize invalid class initialize noncanonical_tag #{params[:type].classify}" unless Tag::TYPES.include?(params[:type].classify) tag_class = params[:type].classify.constantize - one_tag = tag_class.find_by(canonical: false, name: params[:term]) + one_tag = tag_class.find_by(canonical: false, name: params[:term]) if params[:term].present? # If there is an exact match in the database, ensure it is the first thing suggested. match = if one_tag [one_tag.name] diff --git a/app/controllers/blocked/users_controller.rb b/app/controllers/blocked/users_controller.rb index 9c2c232a099..bf93a58ac1a 100644 --- a/app/controllers/blocked/users_controller.rb +++ b/app/controllers/blocked/users_controller.rb @@ -12,7 +12,8 @@ class UsersController < ApplicationController # GET /users/:user_id/blocked/users def index @blocks = @user.blocks_as_blocker - .joins(:blocked).includes(blocked: :default_pseud) + .joins(:blocked) + .includes(blocked: [:pseuds, { default_pseud: { icon_attachment: :blob } }]) .order(created_at: :desc).order(id: :desc).page(params[:page]) @pseuds = @blocks.map { |b| b.blocked.default_pseud } diff --git a/app/controllers/bookmarks_controller.rb b/app/controllers/bookmarks_controller.rb index ee48b66edbd..32658a750d1 100644 --- a/app/controllers/bookmarks_controller.rb +++ b/app/controllers/bookmarks_controller.rb @@ -1,10 +1,10 @@ class BookmarksController < ApplicationController before_action :load_collection before_action :load_owner, only: [:index] - before_action :load_bookmarkable, only: [:index, :new, :create, :fetch_recent, :hide_recent] + before_action :load_bookmarkable, only: [:index, :new, :create] before_action :users_only, only: [:new, :create, :edit, :update] before_action :check_user_status, only: [:new, :create, :edit, :update] - before_action :load_bookmark, only: [:show, :edit, :update, :destroy, :fetch_recent, :hide_recent, :confirm_delete, :share] + before_action :load_bookmark, only: [:show, :edit, :update, :destroy, :confirm_delete, :share] before_action :check_visibility, only: [:show, :share] before_action :check_ownership, only: [:edit, :update, :destroy, :confirm_delete, :share] @@ -279,26 +279,6 @@ def destroy redirect_to user_bookmarks_path(current_user) end - # Used on index page to show 4 most recent bookmarks (after bookmark being currently viewed) via RJS - # Only main bookmarks page or tag bookmarks page - # non-JS fallback should be to the 'view all bookmarks' link which serves the same function - def fetch_recent - @bookmarkable = @bookmark.bookmarkable - respond_to do |format| - format.js { - @bookmarks = @bookmarkable.bookmarks.order_by_created_at.visible.offset(1).limit(4) - set_own_bookmarks - } - format.html do - id_symbol = (@bookmarkable.class.to_s.underscore + '_id').to_sym - redirect_to url_for({action: :index, id_symbol => @bookmarkable}) - end - end - end - def hide_recent - @bookmarkable = @bookmark.bookmarkable - end - protected def load_owner diff --git a/app/controllers/challenge_assignments_controller.rb b/app/controllers/challenge_assignments_controller.rb index 55555e4705e..1e90132adde 100644 --- a/app/controllers/challenge_assignments_controller.rb +++ b/app/controllers/challenge_assignments_controller.rb @@ -219,9 +219,11 @@ def default_all def default @challenge_assignment.defaulted_at = Time.now @challenge_assignment.save - @challenge_assignment.collection.notify_maintainers("Challenge default by #{@challenge_assignment.offer_byline}", - "Signed-up participant #{@challenge_assignment.offer_byline} has defaulted on their assignment for #{@challenge_assignment.request_byline}. " + - "You may want to assign a pinch hitter on the collection assignments page: #{collection_assignments_url(@challenge_assignment.collection)}") + + assignments_page_url = collection_assignments_url(@challenge_assignment.collection) + + @challenge_assignment.collection.notify_maintainers_challenge_default(@challenge_assignment, assignments_page_url) + flash[:notice] = "We have notified the collection maintainers that you had to default on your assignment." redirect_to user_assignments_path(current_user) end diff --git a/app/controllers/collection_items_controller.rb b/app/controllers/collection_items_controller.rb index f3cc41724c0..00156750a1b 100644 --- a/app/controllers/collection_items_controller.rb +++ b/app/controllers/collection_items_controller.rb @@ -23,7 +23,7 @@ def index @collection_items.unreviewed_by_collection end elsif params[:user_id] && (@user = User.find_by(login: params[:user_id])) && @user == current_user - @collection_items = CollectionItem.for_user(@user).includes(:collection) + @collection_items = CollectionItem.for_user(@user).includes(:collection).merge(Collection.with_attached_icon) @collection_items = case params[:status] when "approved" @collection_items.approved_by_both diff --git a/app/controllers/collections_controller.rb b/app/controllers/collections_controller.rb index 0a0c7861c0f..06074e58831 100644 --- a/app/controllers/collections_controller.rb +++ b/app/controllers/collections_controller.rb @@ -25,11 +25,20 @@ def load_collection_from_id def index if params[:work_id] && (@work = Work.find_by(id: params[:work_id])) - @collections = @work.approved_collections.by_title.includes(:parent, :moderators, :children, :collection_preference, owners: [:user]).paginate(page: params[:page]) + @collections = @work.approved_collections + .by_title + .for_blurb + .paginate(page: params[:page]) elsif params[:collection_id] && (@collection = Collection.find_by(name: params[:collection_id])) - @collections = @collection.children.by_title.includes(:parent, :moderators, :children, :collection_preference, owners: [:user]).paginate(page: params[:page]) + @collections = @collection.children + .by_title + .for_blurb + .paginate(page: params[:page]) elsif params[:user_id] && (@user = User.find_by(login: params[:user_id])) - @collections = @user.maintained_collections.by_title.includes(:parent, :moderators, :children, :collection_preference, owners: [:user]).paginate(page: params[:page]) + @collections = @user.maintained_collections + .by_title + .for_blurb + .paginate(page: params[:page]) @page_subtitle = ts("%{username} - Collections", username: @user.login) else if params[:user_id] diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index f4e96e3ca2c..6570e6e2013 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -30,6 +30,7 @@ class CommentsController < ApplicationController before_action :check_permission_to_moderate, only: [:approve, :reject] before_action :check_permission_to_modify_frozen_status, only: [:freeze, :unfreeze] before_action :check_permission_to_modify_hidden_status, only: [:hide, :unhide] + before_action :admin_logout_required, only: [:new, :create, :add_comment_reply] include BlockHelper @@ -342,36 +343,34 @@ def create # First, try saving the comment if @comment.save - if @comment.approved? - if @comment.unreviewed? - flash[:comment_notice] = ts("Your comment was received! It will appear publicly after the work creator has approved it.") - else - flash[:comment_notice] = ts("Comment created!") - end - respond_to do |format| - format.html do - if request.referer&.match(/inbox/) - redirect_to user_inbox_path(current_user, filters: filter_params[:filters], page: params[:page]) - elsif request.referer&.match(/new/) - # came here from the new comment page, probably via download link - # so go back to the comments page instead of reloading full work - redirect_to comment_path(@comment) - elsif request.referer == "#{root_url}" - # replying on the homepage - redirect_to root_path - elsif @comment.unreviewed? && current_user - redirect_to comment_path(@comment) - elsif @comment.unreviewed? - redirect_to_all_comments(@commentable) - else - redirect_to_comment(@comment, {view_full_work: (params[:view_full_work] == "true"), page: params[:page]}) - end + flash[:comment_notice] = if @comment.unreviewed? + # i18n-tasks-use t("comments.create.success.moderated.admin_post") + # i18n-tasks-use t("comments.create.success.moderated.work") + t("comments.create.success.moderated.#{@comment.ultimate_parent.model_name.i18n_key}") + else + t("comments.create.success.not_moderated") + end + respond_to do |format| + format.html do + if request.referer&.match(/inbox/) + redirect_to user_inbox_path(current_user, filters: filter_params[:filters], page: params[:page]) + elsif request.referer&.match(/new/) || (@comment.unreviewed? && current_user) + # If the referer is the new comment page, go to the comment's page + # instead of reloading the full work. + # If the comment is unreviewed and commenter is logged in, take + # them to the comment's page so they can access the edit and + # delete options for the comment, since unreviewed comments don't + # appear on the commentable. + redirect_to comment_path(@comment) + elsif request.referer == root_url + # replying on the homepage + redirect_to root_path + elsif @comment.unreviewed? + redirect_to_all_comments(@commentable) + else + redirect_to_comment(@comment, { view_full_work: (params[:view_full_work] == "true"), page: params[:page] }) end end - else - # this shouldn't come up any more - flash[:comment_notice] = ts("Sorry, but this comment looks like spam to us.") - redirect_back_or_default(root_path) end else flash[:error] = ts("Couldn't save comment!") @@ -425,10 +424,17 @@ def destroy end def review - return unless @comment && current_user_owns?(@comment.ultimate_parent) && @comment.unreviewed? + if logged_in_as_admin? + authorize @comment + else + return unless current_user_owns?(@comment.ultimate_parent) + end + + return unless @comment&.unreviewed? + @comment.toggle!(:unreviewed) # mark associated inbox comments as read - InboxComment.where(user_id: current_user.id, feedback_comment_id: @comment.id).update_all(read: true) + InboxComment.where(user_id: current_user.id, feedback_comment_id: @comment.id).update_all(read: true) unless logged_in_as_admin? flash[:notice] = ts("Comment approved.") respond_to do |format| format.html do @@ -436,6 +442,8 @@ def review redirect_to user_inbox_path(current_user, page: params[:page], filters: filter_params[:filters]) elsif params[:approved_from] == "home" redirect_to root_path + elsif @comment.ultimate_parent.is_a?(AdminPost) + redirect_to unreviewed_admin_post_comments_path(@comment.ultimate_parent) else redirect_to unreviewed_work_comments_path(@comment.ultimate_parent) end @@ -446,7 +454,8 @@ def review end def review_all - unless @commentable && current_user_owns?(@commentable) + authorize @commentable, policy_class: CommentPolicy if logged_in_as_admin? + unless (@commentable && current_user_owns?(@commentable)) || (@commentable && logged_in_as_admin? && @commentable.is_a?(AdminPost)) flash[:error] = ts("What did you want to review comments on?") redirect_back_or_default(root_path) return @@ -657,15 +666,13 @@ def redirect_to_all_comments(commentable, options = {}) if commentable.is_a?(Chapter) && (options[:view_full_work] || current_user.try(:preference).try(:view_full_works)) commentable = commentable.work end - redirect_to controller: commentable.class.to_s.underscore.pluralize, - action: :show, - id: commentable.id, - show_comments: options[:show_comments], - add_comment_reply_id: options[:add_comment_reply_id], - delete_comment_id: options[:delete_comment_id], - view_full_work: options[:view_full_work], - anchor: options[:anchor], - page: options[:page] + redirect_to polymorphic_path(commentable, + options.slice(:show_comments, + :add_comment_reply_id, + :delete_comment_id, + :view_full_work, + :anchor, + :page)) end end diff --git a/app/controllers/feedbacks_controller.rb b/app/controllers/feedbacks_controller.rb index 7dfdeb7f087..9f3acab63aa 100644 --- a/app/controllers/feedbacks_controller.rb +++ b/app/controllers/feedbacks_controller.rb @@ -3,8 +3,9 @@ class FeedbacksController < ApplicationController before_action :load_support_languages def new - @feedback = Feedback.new @admin_setting = AdminSetting.current + @feedback = Feedback.new + @feedback.referer = request.referer if logged_in_as_admin? @feedback.email = current_admin.email elsif is_registered_user? @@ -19,6 +20,8 @@ def create @feedback.rollout = @feedback.rollout_string @feedback.user_agent = request.env["HTTP_USER_AGENT"] @feedback.ip_address = request.remote_ip + @feedback.referer = nil unless @feedback.referer && ArchiveConfig.PERMITTED_HOSTS.include?(URI(@feedback.referer).host) + @feedback.site_skin = helpers.current_skin if @feedback.save @feedback.email_and_send flash[:notice] = t("successfully_sent", @@ -39,8 +42,7 @@ def load_support_languages def feedback_params params.require(:feedback).permit( - :comment, :email, :summary, :username, :language + :comment, :email, :summary, :username, :language, :referer ) end - end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 98402e86240..edff4637cab 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -7,13 +7,25 @@ class HomeController < ApplicationController def unicorn_test end + def content + @page_title = t(".page_title") + render action: "content", layout: "application" + end + + def privacy + @page_title = t(".page_title") + render action: "privacy", layout: "application" + end + # terms of service def tos + @page_title = t(".page_title") render action: "tos", layout: "application" end # terms of service faq def tos_faq + @page_title = t(".page_title") render action: "tos_faq", layout: "application" end @@ -52,6 +64,7 @@ def donate # about def about + @page_subtitle = t(".page_title") render action: "about", layout: "application" end diff --git a/app/controllers/inbox_controller.rb b/app/controllers/inbox_controller.rb index fb7a710f7e6..4191691060a 100644 --- a/app/controllers/inbox_controller.rb +++ b/app/controllers/inbox_controller.rb @@ -2,7 +2,7 @@ class InboxController < ApplicationController include BlockHelper before_action :load_user - before_action :check_ownership + before_action :check_ownership_or_admin before_action :load_commentable, only: :reply before_action :check_blocked, only: :reply @@ -13,6 +13,7 @@ def load_user end def show + authorize InboxComment if logged_in_as_admin? @inbox_total = @user.inbox_comments.with_bad_comments_removed.count @unread = @user.inbox_comments.with_bad_comments_removed.count_unread @filters = filter_params[:filters] || {} @@ -30,6 +31,7 @@ def reply end def update + authorize InboxComment if logged_in_as_admin? begin @inbox_comments = InboxComment.find(params[:inbox_comments]) if params[:read] diff --git a/app/controllers/invite_requests_controller.rb b/app/controllers/invite_requests_controller.rb index ba1c69166f3..e58c027059f 100644 --- a/app/controllers/invite_requests_controller.rb +++ b/app/controllers/invite_requests_controller.rb @@ -2,8 +2,10 @@ class InviteRequestsController < ApplicationController before_action :admin_only, only: [:manage, :destroy] # GET /invite_requests + # Set browser page title to Invitation Requests def index @invite_request = InviteRequest.new + @page_subtitle = t(".page_title") end # GET /invite_requests/1 diff --git a/app/controllers/known_issues_controller.rb b/app/controllers/known_issues_controller.rb index 4f6bbe6cd30..793daff088e 100644 --- a/app/controllers/known_issues_controller.rb +++ b/app/controllers/known_issues_controller.rb @@ -1,5 +1,4 @@ class KnownIssuesController < ApplicationController - before_action :admin_only, except: [:index] # GET /known_issues @@ -9,25 +8,24 @@ def index # GET /known_issues/1 def show - @known_issue = KnownIssue.find(params[:id]) + @known_issue = authorize KnownIssue.find(params[:id]) end # GET /known_issues/new def new - @known_issue = KnownIssue.new + @known_issue = authorize KnownIssue.new end # GET /known_issues/1/edit def edit - @known_issue = KnownIssue.find(params[:id]) + @known_issue = authorize KnownIssue.find(params[:id]) end # POST /known_issues def create - @known_issue = KnownIssue.new(known_issue_params) - + @known_issue = authorize KnownIssue.new(known_issue_params) if @known_issue.save - flash[:notice] = 'Known issue was successfully created.' + flash[:notice] = "Known issue was successfully created." redirect_to(@known_issue) else render action: "new" @@ -36,10 +34,9 @@ def create # PUT /known_issues/1 def update - @known_issue = KnownIssue.find(params[:id]) - + @known_issue = authorize KnownIssue.find(params[:id]) if @known_issue.update(known_issue_params) - flash[:notice] = 'Known issue was successfully updated.' + flash[:notice] = "Known issue was successfully updated." redirect_to(@known_issue) else render action: "edit" @@ -48,7 +45,7 @@ def update # DELETE /known_issues/1 def destroy - @known_issue = KnownIssue.find(params[:id]) + @known_issue = authorize KnownIssue.find(params[:id]) @known_issue.destroy redirect_to(known_issues_path) end diff --git a/app/controllers/kudos_controller.rb b/app/controllers/kudos_controller.rb index d575bdc65fe..bedb0a8342a 100644 --- a/app/controllers/kudos_controller.rb +++ b/app/controllers/kudos_controller.rb @@ -1,5 +1,6 @@ class KudosController < ApplicationController skip_before_action :store_location + before_action :admin_logout_required, only: [:create] def index @work = Work.find(params[:work_id]) diff --git a/app/controllers/languages_controller.rb b/app/controllers/languages_controller.rb index 96892070d76..ecaa6209b9a 100644 --- a/app/controllers/languages_controller.rb +++ b/app/controllers/languages_controller.rb @@ -1,5 +1,4 @@ class LanguagesController < ApplicationController - def index @languages = Language.default_order @works_counts = Rails.cache.fetch("/v1/languages/work_counts/#{current_user.present?}", expires_in: 1.day) do @@ -16,7 +15,7 @@ def create @language = Language.new(language_params) authorize @language if @language.save - flash[:notice] = t('successfully_added', default: 'Language was successfully added.') + flash[:notice] = t("languages.successfully_added") redirect_to languages_path else render action: "new" @@ -31,8 +30,9 @@ def edit def update @language = Language.find_by(short: params[:id]) authorize @language - if @language.update(language_params) - flash[:notice] = t('successfully_updated', default: 'Language was successfully updated.') + + if @language.update(permitted_attributes(@language)) + flash[:notice] = t("languages.successfully_updated") redirect_to languages_path else render action: "new" @@ -40,6 +40,7 @@ def update end private + def language_params params.require(:language).permit( :name, :short, :support_available, :abuse_support_available, :sortable_name diff --git a/app/controllers/muted/users_controller.rb b/app/controllers/muted/users_controller.rb index 209fbc8b21b..ad29263d71f 100644 --- a/app/controllers/muted/users_controller.rb +++ b/app/controllers/muted/users_controller.rb @@ -12,7 +12,8 @@ class UsersController < ApplicationController # GET /users/:user_id/muted/users def index @mutes = @user.mutes_as_muter - .joins(:muted).includes(muted: :default_pseud) + .joins(:muted) + .includes(muted: [:pseuds, { default_pseud: { icon_attachment: :blob } }]) .order(created_at: :desc).order(id: :desc).page(params[:page]) @pseuds = @mutes.map { |b| b.muted.default_pseud } diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 34a641a7fdf..96e3833cd68 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -8,14 +8,14 @@ def search else options = people_search_params.merge(page: params[:page]) @search = PseudSearchForm.new(options) - @people = @search.search_results + @people = @search.search_results.scope(:for_search) flash_search_warnings(@people) end end def index if @collection.present? - @people = @collection.participants.order(:name).page(params[:page]) + @people = @collection.participants.with_attached_icon.includes(:user).order(:name).page(params[:page]) @rec_counts = Pseud.rec_counts_for_pseuds(@people) @work_counts = Pseud.work_counts_for_pseuds(@people) else diff --git a/app/controllers/pseuds_controller.rb b/app/controllers/pseuds_controller.rb index 77265c9cca7..331600fe3f1 100644 --- a/app/controllers/pseuds_controller.rb +++ b/app/controllers/pseuds_controller.rb @@ -15,7 +15,7 @@ def load_user # GET /pseuds.xml def index if @user - @pseuds = @user.pseuds.alphabetical.paginate(page: params[:page]) + @pseuds = @user.pseuds.with_attached_icon.alphabetical.paginate(page: params[:page]) @rec_counts = Pseud.rec_counts_for_pseuds(@pseuds) @work_counts = Pseud.work_counts_for_pseuds(@pseuds) @page_subtitle = @user.login @@ -91,7 +91,7 @@ def create # if setting this one as default, unset the attribute of the current default pseud old_default.update_attribute(:is_default, false) end - redirect_to([@user, @pseud]) + redirect_to polymorphic_path([@user, @pseud]) else render action: "new" end diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb index a00ef266972..4c82934805f 100644 --- a/app/controllers/questions_controller.rb +++ b/app/controllers/questions_controller.rb @@ -1,33 +1,34 @@ class QuestionsController < ApplicationController - before_action :load_archive_faq, except: [:index, :update_positions] + before_action :load_archive_faq, except: :update_positions # GET /archive_faq/:archive_faq_id/questions/manage def manage - @questions = @archive_faq.questions.order('position') + authorize :archive_faq, :full_access? + @questions = @archive_faq.questions.order("position") end # fetch archive_faq these questions belong to from db def load_archive_faq - @archive_faq = ArchiveFaq.find_by_slug(params[:archive_faq_id]) + @archive_faq = ArchiveFaq.find_by(slug: params[:archive_faq_id]) unless @archive_faq.present? - flash[:error] = ts("Sorry, we couldn't find the FAQ you were looking for." - ) + flash[:error] = t("questions.not_found") redirect_to root_path and return end end # Update the position number of questions within a archive_faq def update_positions + authorize :archive_faq, :full_access? if params[:questions] - @archive_faq = ArchiveFaq.find_by_slug(params[:archive_faq_id]) + @archive_faq = ArchiveFaq.find_by(slug: params[:archive_faq_id]) @archive_faq.reorder_list(params[:questions]) - flash[:notice] = ts("Question order has been successfully updated.") + flash[:notice] = t(".success") elsif params[:question] params[:question].each_with_index do |id, position| Question.update(id, position: position + 1) (@questions ||= []) << Question.find(id) end - flash[:notice] = ts("Question order has been successfully updated.") + flash[:notice] = t(".success") end respond_to do |format| format.html { redirect_to(@archive_faq) and return } diff --git a/app/controllers/readings_controller.rb b/app/controllers/readings_controller.rb index 6ae84d496a0..12e1676bdcb 100644 --- a/app/controllers/readings_controller.rb +++ b/app/controllers/readings_controller.rb @@ -10,7 +10,7 @@ def load_user end def index - @readings = @user.readings + @readings = @user.readings.visible @page_subtitle = ts("History") if params[:show] == 'to-read' @readings = @readings.where(toread: true) diff --git a/app/controllers/skins_controller.rb b/app/controllers/skins_controller.rb index 8b9cb610f40..848cb21d941 100644 --- a/app/controllers/skins_controller.rb +++ b/app/controllers/skins_controller.rb @@ -1,5 +1,4 @@ class SkinsController < ApplicationController - before_action :users_only, only: [:new, :create, :destroy] before_action :load_skin, except: [:index, :new, :create, :unset] before_action :check_ownership_or_admin, only: [:edit, :update] @@ -22,22 +21,22 @@ def index redirect_to skins_path and return end if is_work_skin - @skins = @user.work_skins.sort_by_recent + @skins = @user.work_skins.sort_by_recent.includes(:author).with_attached_icon @title = ts('My Work Skins') else - @skins = @user.skins.site_skins.sort_by_recent + @skins = @user.skins.site_skins.sort_by_recent.includes(:author).with_attached_icon @title = ts('My Site Skins') end else if is_work_skin - @skins = WorkSkin.approved_skins.sort_by_recent_featured + @skins = WorkSkin.approved_skins.sort_by_recent_featured.includes(:author).with_attached_icon @title = ts('Public Work Skins') else - if logged_in? - @skins = Skin.approved_skins.usable.site_skins.sort_by_recent_featured - else - @skins = Skin.approved_skins.usable.site_skins.cached.sort_by_recent_featured - end + @skins = if logged_in? + Skin.approved_skins.usable.site_skins.sort_by_recent_featured.with_attached_icon + else + Skin.approved_skins.usable.site_skins.cached.sort_by_recent_featured.with_attached_icon + end @title = ts('Public Site Skins') end end diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 0e4ddc2253a..6729df1328f 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -15,9 +15,12 @@ def load_user # GET /subscriptions.xml def index @subscriptions = @user.subscriptions.includes(:subscribable) - if params[:type].present? - @subscriptions = @subscriptions.where(subscribable_type: params[:type].classify) + + if params[:type] && Subscription::VALID_SUBSCRIBABLES.include?(params[:type].singularize.titleize) + @subscribable_type = params[:type] + @subscriptions = @subscriptions.where(subscribable_type: @subscribable_type.classify) end + @subscriptions = @subscriptions.to_a.sort { |a,b| a.name.downcase <=> b.name.downcase } @subscriptions = @subscriptions.paginate page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE end diff --git a/app/controllers/tag_set_nominations_controller.rb b/app/controllers/tag_set_nominations_controller.rb index 8b554768d54..02e8e060e45 100644 --- a/app/controllers/tag_set_nominations_controller.rb +++ b/app/controllers/tag_set_nominations_controller.rb @@ -139,6 +139,10 @@ def base_nom_query(tag_type) # set up various variables for reviewing nominations def setup_for_review set_limit + + # Only this amount of tag nominations is shown on the review page. + # If there are more (more_noms == true), moderators have to approve/reject from the shown noms to see more noms. + # TODO: AO3-3764 Show all tag set nominations @nom_limit = 30 @nominations = HashWithIndifferentAccess.new @nominations_count = HashWithIndifferentAccess.new @@ -147,7 +151,8 @@ def setup_for_review if @tag_set.includes_fandoms? # all char and rel tags happen under fandom noms @nominations_count[:fandom] = @tag_set.fandom_nominations.unreviewed.count - more_noms = true if @nominations_count[:fandom] > @nom_limit + more_noms = true if @nominations_count[:fandom] > @nom_limit + # Show a random selection of nominations if there are more noms than can be shown at once @nominations[:fandom] = more_noms ? base_nom_query("fandom").random_order : base_nom_query("fandom").order(:tagname) if (@limit[:character] > 0 || @limit[:relationship] > 0) @nominations[:cast] = base_nom_query(%w(character relationship)). @@ -162,7 +167,7 @@ def setup_for_review more_noms = true if (@tag_set.character_nominations.unreviewed.count > @nom_limit || @tag_set.relationship_nominations.unreviewed.count > @nom_limit) @nominations[:character] = base_nom_query("character") if @limit[:character] > 0 @nominations[:relationship] = base_nom_query("relationship") if @limit[:relationship] > 0 - if more_noms + if more_noms # Show a random selection of nominations if there are more noms than can be shown at once parent_tagnames = TagNomination.for_tag_set(@tag_set).unreviewed.random_order.limit(100).pluck(:parent_tagname).uniq.first(30) @nominations[:character] = @nominations[:character].where(parent_tagname: parent_tagnames) if @limit[:character] > 0 @nominations[:relationship] = @nominations[:relationship].where(parent_tagname: parent_tagnames) if @limit[:relationship] > 0 @@ -172,6 +177,7 @@ def setup_for_review end @nominations_count[:freeform] = @tag_set.freeform_nominations.unreviewed.count more_noms = true if @nominations_count[:freeform] > @nom_limit + # Show a random selection of nominations if there are more noms than can be shown at once @nominations[:freeform] = (more_noms ? base_nom_query("freeform").random_order : base_nom_query("freeform").order(:tagname)) unless @limit[:freeform].zero? if more_noms diff --git a/app/controllers/tag_wranglers_controller.rb b/app/controllers/tag_wranglers_controller.rb index 8419905245d..9722cbb3c87 100644 --- a/app/controllers/tag_wranglers_controller.rb +++ b/app/controllers/tag_wranglers_controller.rb @@ -6,6 +6,8 @@ class TagWranglersController < ApplicationController before_action :check_permission_to_wrangle, except: [:report_csv] def index + authorize :wrangling, :full_access? if logged_in_as_admin? + @wranglers = Role.find_by(name: "tag_wrangler").users.alphabetical conditions = ["canonical = 1"] joins = "LEFT JOIN wrangling_assignments ON (wrangling_assignments.fandom_id = tags.id) @@ -39,6 +41,8 @@ def index end def show + authorize :wrangling if logged_in_as_admin? + @wrangler = User.find_by!(login: params[:id]) @page_subtitle = @wrangler.login @fandoms = @wrangler.fandoms.by_name @@ -46,7 +50,7 @@ def show end def report_csv - authorize :tag_wrangler, :report_csv? + authorize :wrangling wrangler = User.find_by!(login: params[:id]) wrangled_tags = Tag @@ -64,6 +68,8 @@ def report_csv end def create + authorize :wrangling if logged_in_as_admin? + unless params[:tag_fandom_string].blank? names = params[:tag_fandom_string].gsub(/$/, ',').split(',').map(&:strip) fandoms = Fandom.where('name IN (?)', names) @@ -95,6 +101,8 @@ def create end def destroy + authorize :wrangling if logged_in_as_admin? + wrangler = User.find_by(login: params[:id]) assignment = WranglingAssignment.where(user_id: wrangler.id, fandom_id: params[:fandom_id]).first assignment.destroy diff --git a/app/controllers/tag_wranglings_controller.rb b/app/controllers/tag_wranglings_controller.rb index 8bbd2dd6830..c3068d93a3e 100644 --- a/app/controllers/tag_wranglings_controller.rb +++ b/app/controllers/tag_wranglings_controller.rb @@ -8,32 +8,36 @@ class TagWranglingsController < ApplicationController def index @counts = tag_counts_per_category - unless params[:show].blank? - raise "Redshirt: Attempted to constantize invalid class initialize tag_wranglings_controller_index #{params[:show].classify}" unless Tag::USER_DEFINED.include?(params[:show].classify) + authorize :wrangling, :read_access? if logged_in_as_admin? + return if params[:show].blank? - params[:sort_column] = 'created_at' if !valid_sort_column(params[:sort_column], 'tag') - params[:sort_direction] = 'ASC' if !valid_sort_direction(params[:sort_direction]) + raise "Redshirt: Attempted to constantize invalid class initialize tag_wranglings_controller_index #{params[:show].classify}" unless Tag::USER_DEFINED.include?(params[:show].classify) - if params[:show] == "fandoms" - @media_names = Media.by_name.pluck(:name) - @page_subtitle = ts("fandoms") - end + params[:sort_column] = "created_at" unless valid_sort_column(params[:sort_column], "tag") + params[:sort_direction] = "ASC" unless valid_sort_direction(params[:sort_direction]) - type = params[:show].singularize.capitalize - @tags = TagQuery.new({ - type: type, - in_use: true, - unwrangleable: false, - unwrangled: true, - sort_column: params[:sort_column], - sort_direction: params[:sort_direction], - page: params[:page], - per_page: ArchiveConfig.ITEMS_PER_PAGE - }).search_results + if params[:show] == "fandoms" + @media_names = Media.by_name.pluck(:name) + @page_subtitle = t(".page_subtitle") end + + type = params[:show].singularize.capitalize + @tags = TagQuery.new({ + type: type, + in_use: true, + unwrangleable: false, + unwrangled: true, + has_posted_works: true, + sort_column: params[:sort_column], + sort_direction: params[:sort_direction], + page: params[:page], + per_page: ArchiveConfig.ITEMS_PER_PAGE + }).search_results end def wrangle + authorize :wrangling, :full_access? if logged_in_as_admin? + params[:page] = '1' if params[:page].blank? params[:sort_column] = 'name' if !valid_sort_column(params[:sort_column], 'tag') params[:sort_direction] = 'ASC' if !valid_sort_direction(params[:sort_direction]) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index f7ae2d2b6e9..cdc5932ba12 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -56,12 +56,14 @@ def search flash_search_warnings(@tags) end - # if user is Admin or Tag Wrangler, show them details about the tag + # if user is admin with view access or Tag Wrangler, show them details about the tag # if user is not logged in or a regular user, show them # 1. the works, if the tag had been wrangled and we can redirect them to works using it or its canonical merger # 2. the tag, the works and the bookmarks using it, if the tag is unwrangled (because we can't redirect them # to the works controller) def show + authorize :wrangling, :read_access? if logged_in_as_admin? + @page_subtitle = @tag.name if @tag.is_a?(Banned) && !logged_in_as_admin? flash[:error] = ts('Please log in as admin') @@ -166,6 +168,8 @@ def show_hidden # GET /tags/new def new + authorize :wrangling if logged_in_as_admin? + @tag = Tag.new respond_to do |format| @@ -209,6 +213,8 @@ def create end def edit + authorize :wrangling, :read_access? if logged_in_as_admin? + @page_subtitle = ts('%{tag_name} - Edit', tag_name: @tag.name) if @tag.is_a?(Banned) && !logged_in_as_admin? @@ -241,6 +247,8 @@ def edit end def update + authorize :wrangling if logged_in_as_admin? + # update everything except for the synonym, # so that the associations are there to move when the synonym is created syn_string = params[:tag].delete(:syn_string) @@ -272,6 +280,8 @@ def update end def wrangle + authorize :wrangling, :read_access? if logged_in_as_admin? + @page_subtitle = ts('%{tag_name} - Wrangle', tag_name: @tag.name) @counts = {} @tag.child_types.map { |t| t.underscore.pluralize.to_sym }.each do |tag_type| @@ -303,6 +313,8 @@ def wrangle end def mass_update + authorize :wrangling if logged_in_as_admin? + params[:page] = '1' if params[:page].blank? params[:sort_column] = 'name' unless valid_sort_column(params[:sort_column], 'tag') params[:sort_direction] = 'ASC' unless valid_sort_direction(params[:sort_direction]) diff --git a/app/controllers/unsorted_tags_controller.rb b/app/controllers/unsorted_tags_controller.rb index fc6c8fd6c68..eef8ef17277 100644 --- a/app/controllers/unsorted_tags_controller.rb +++ b/app/controllers/unsorted_tags_controller.rb @@ -5,13 +5,17 @@ class UnsortedTagsController < ApplicationController before_action :check_permission_to_wrangle def index + authorize :wrangling, :read_access? if logged_in_as_admin? + @tags = UnsortedTag.page(params[:page]) @counts = tag_counts_per_category end def mass_update - unless params[:tags].blank? - params[:tags].delete_if {|tag_id, tag_type| tag_type.blank? } + authorize :wrangling if logged_in_as_admin? + + if params[:tags].present? + params[:tags].delete_if { |_, tag_type| tag_type.blank? } tags = UnsortedTag.where(id: params[:tags].keys) tags.each do |tag| new_type = params[:tags][tag.id.to_s] diff --git a/app/controllers/user_invite_requests_controller.rb b/app/controllers/user_invite_requests_controller.rb index daad6c7c58d..48bc411f4ee 100644 --- a/app/controllers/user_invite_requests_controller.rb +++ b/app/controllers/user_invite_requests_controller.rb @@ -55,10 +55,13 @@ def update params[:requests].each_pair do |id, quantity| unless quantity.blank? request = UserInviteRequest.find(id) + user = User.find(request.user_id) requested_total = request.quantity.to_i request.quantity = 0 request.save! - UserMailer.invite_request_declined(request.user_id, requested_total, request.reason).deliver_later + I18n.with_locale(user.preference.locale.iso) do + UserMailer.invite_request_declined(request.user_id, requested_total, request.reason).deliver_later + end end end flash[:notice] = 'All Requests were declined.' diff --git a/app/controllers/users/passwords_controller.rb b/app/controllers/users/passwords_controller.rb index a96166674d6..98eb170146a 100644 --- a/app/controllers/users/passwords_controller.rb +++ b/app/controllers/users/passwords_controller.rb @@ -14,14 +14,14 @@ def create end if user.prevent_password_resets? - flash[:error] = t(".reset_blocked", contact_abuse_link: view_context.link_to(t(".contact_abuse"), new_abuse_report_path)).html_safe + flash[:error] = t(".reset_blocked_html", contact_abuse_link: view_context.link_to(t(".contact_abuse"), new_abuse_report_path)) redirect_to root_path and return elsif user.password_resets_limit_reached? available_time = ApplicationController.helpers.time_in_zone( user.password_resets_available_time, nil, user ) - flash[:error] = t(".reset_cooldown", reset_available_time: available_time).html_safe + flash[:error] = t(".reset_cooldown_html", reset_available_time: available_time) redirect_to root_path and return end diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 5f11db3c066..590392f2fe5 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -50,7 +50,7 @@ def configure_permitted_parameters devise_parameter_sanitizer.permit( :sign_up, keys: [ - :password_confirmation, :email, :age_over_13, :terms_of_service, :accepted_tos_version + :password_confirmation, :email, :age_over_13, :data_processing, :terms_of_service, :accepted_tos_version ] ) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b4429d20adf..b99c8581c55 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,7 +1,7 @@ class UsersController < ApplicationController cache_sweeper :pseud_sweeper - before_action :check_user_status, only: [:edit, :update] + before_action :check_user_status, only: [:edit, :update, :change_username, :changed_username] before_action :load_user, except: [:activate, :delete_confirmation, :index] before_action :check_ownership, except: [:activate, :delete_confirmation, :edit, :index, :show, :update] before_action :check_ownership_or_admin, only: [:edit, :update] @@ -39,6 +39,18 @@ def edit authorize @user.profile if logged_in_as_admin? end + def change_email + @page_subtitle = t(".browser_title") + end + + def change_password + @page_subtitle = t(".browser_title") + end + + def change_username + @page_subtitle = t(".browser_title") + end + def changed_password unless params[:password] && reauthenticate render(:change_password) && return @@ -162,7 +174,9 @@ def changed_email if @user.save flash.now[:notice] = ts("Your email has been successfully updated") - UserMailer.change_email(@user.id, old_email, new_email).deliver_later + I18n.with_locale(@user.preference.locale.iso) do + UserMailer.change_email(@user.id, old_email, new_email).deliver_later + end else # Make sure that on failure, the form still shows the old email as the "current" one. @user.email = old_email @@ -315,7 +329,7 @@ def destroy_author use_default = params[:use_default] == 'true' || params[:sole_author] == 'orphan_pseud' Creatorship.orphan(pseuds, works, use_default) - Collection.orphan(pseuds, @sole_owned_collections, use_default) + Collection.orphan(pseuds, @sole_owned_collections, default: use_default) elsif params[:sole_author] == 'delete' # Deletes works where user is sole author @sole_authored_works.each(&:destroy) diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index 1f7f70832cf..d87f5fb0596 100755 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -13,7 +13,7 @@ class WorksController < ApplicationController # admins should have the ability to edit tags (:edit_tags, :update_tags) as per our ToS before_action :check_ownership_or_admin, only: [:edit_tags, :update_tags] before_action :log_admin_activity, only: [:update_tags] - before_action :check_visibility, only: [:show, :navigate, :share] + before_action :check_visibility, only: [:show, :navigate, :share, :mark_for_later, :mark_as_read] before_action :load_first_chapter, only: [:show, :edit, :update, :preview] @@ -56,12 +56,11 @@ def index options = params[:work_search].present? ? clean_work_search_params : {} - if params[:fandom_id] || (@collection.present? && @tag.present?) - if params[:fandom_id].present? - @fandom = Fandom.find_by(id: params[:fandom_id]) - end + if params[:fandom_id].present? || (@collection.present? && @tag.present?) + @fandom = Fandom.find(params[:fandom_id]) if params[:fandom_id] tag = @fandom || @tag + options[:filter_ids] ||= [] options[:filter_ids] << tag.id end @@ -160,6 +159,8 @@ def drafts redirect_to logged_in? ? user_path(current_user) : new_user_session_path return end + + @page_subtitle = t(".page_title", username: @user.login) if params[:pseud_id] @pseud = @user.pseuds.find_by(name: params[:pseud_id]) diff --git a/app/controllers/wrangling_guidelines_controller.rb b/app/controllers/wrangling_guidelines_controller.rb index 230de7034eb..f015a185d68 100644 --- a/app/controllers/wrangling_guidelines_controller.rb +++ b/app/controllers/wrangling_guidelines_controller.rb @@ -3,7 +3,7 @@ class WranglingGuidelinesController < ApplicationController # GET /wrangling_guidelines def index - @wrangling_guidelines = WranglingGuideline.order('position ASC') + @wrangling_guidelines = WranglingGuideline.order("position ASC") end # GET /wrangling_guidelines/1 @@ -13,57 +13,64 @@ def show # GET /wrangling_guidelines/new def new + authorize :wrangling @wrangling_guideline = WranglingGuideline.new end # GET /wrangling_guidelines/1/edit def edit + authorize :wrangling @wrangling_guideline = WranglingGuideline.find(params[:id]) end # GET /wrangling_guidelines/manage def manage - @wrangling_guidelines = WranglingGuideline.order('position ASC') + authorize :wrangling + @wrangling_guidelines = WranglingGuideline.order("position ASC") end # POST /wrangling_guidelines def create + authorize :wrangling @wrangling_guideline = WranglingGuideline.new(wrangling_guideline_params) if @wrangling_guideline.save - flash[:notice] = ts('Wrangling Guideline was successfully created.') + flash[:notice] = t("wrangling_guidelines.create") redirect_to(@wrangling_guideline) else - render action: 'new' + render action: "new" end end # PUT /wrangling_guidelines/1 def update + authorize :wrangling @wrangling_guideline = WranglingGuideline.find(params[:id]) if @wrangling_guideline.update(wrangling_guideline_params) - flash[:notice] = ts('Wrangling Guideline was successfully updated.') + flash[:notice] = t("wrangling_guidelines.update") redirect_to(@wrangling_guideline) else - render action: 'edit' + render action: "edit" end end # reorder FAQs def update_positions + authorize :wrangling if params[:wrangling_guidelines] @wrangling_guidelines = WranglingGuideline.reorder_list(params[:wrangling_guidelines]) - flash[:notice] = ts('Wrangling Guidelines order was successfully updated.') + flash[:notice] = t("wrangling_guidelines.reorder") end redirect_to(wrangling_guidelines_path) end # DELETE /wrangling_guidelines/1 def destroy + authorize :wrangling @wrangling_guideline = WranglingGuideline.find(params[:id]) @wrangling_guideline.destroy - flash[:notice] = ts('Wrangling Guideline was successfully deleted.') + flash[:notice] = t("wrangling_guidelines.delete") redirect_to(wrangling_guidelines_path) end @@ -72,5 +79,4 @@ def destroy def wrangling_guideline_params params.require(:wrangling_guideline).permit(:title, :content) end - end diff --git a/app/decorators/homepage.rb b/app/decorators/homepage.rb index c986c30bb9a..312ebfd17aa 100644 --- a/app/decorators/homepage.rb +++ b/app/decorators/homepage.rb @@ -15,7 +15,7 @@ def rounded_counts @fandom_count = Rails.cache.fetch("/v1/home/counts/fandom", expires_in: 40.minutes) do estimate_number(Fandom.canonical.count) end - return @user_count, @work_count, @fandom_count + [@user_count, @work_count, @fandom_count] end def logged_in? @@ -23,45 +23,48 @@ def logged_in? end def admin_posts - if Rails.env.development? - @admin_posts = AdminPost.non_translated.for_homepage.all - else - @admin_posts = Rails.cache.fetch("home/index/home_admin_posts", expires_in: 20.minutes) do - AdminPost.non_translated.for_homepage.to_a - end - end + @admin_posts = if Rails.env.development? + AdminPost.non_translated.for_homepage.all + else + Rails.cache.fetch("home/index/home_admin_posts", expires_in: 20.minutes) do + AdminPost.non_translated.for_homepage.to_a + end + end end def favorite_tags return unless logged_in? - if Rails.env.development? - @favorite_tags ||= @user.favorite_tags.to_a.sort_by { |favorite_tag| favorite_tag.tag.sortable_name.downcase } - else - @favorite_tags ||= Rails.cache.fetch("home/index/#{@user.id}/home_favorite_tags") do - @user.favorite_tags.to_a.sort_by { |favorite_tag| favorite_tag.tag.sortable_name.downcase } - end - end + + @favorite_tags ||= if Rails.env.development? + @user.favorite_tags.to_a.sort_by { |favorite_tag| favorite_tag.tag.sortable_name.downcase } + else + Rails.cache.fetch("home/index/#{@user.id}/home_favorite_tags") do + @user.favorite_tags.to_a.sort_by { |favorite_tag| favorite_tag.tag.sortable_name.downcase } + end + end end def readings return unless logged_in? && @user.preference.try(:history_enabled?) - if Rails.env.development? - @readings ||= @user.readings.random_order. - limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE). - where(toread: true). - all - else - @readings ||= Rails.cache.fetch("home/index/#{@user.id}/home_marked_for_later") do - @user.readings.random_order. - limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE). - where(toread: true). - to_a - end - end + + @readings ||= if Rails.env.development? + @user.readings.visible.random_order + .limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) + .where(toread: true) + .all + else + Rails.cache.fetch("home/index/#{@user.id}/home_marked_for_later") do + @user.readings.visible.random_order + .limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) + .where(toread: true) + .to_a + end + end end def inbox_comments return unless logged_in? + @inbox_comments ||= @user.inbox_comments.with_bad_comments_removed.for_homepage end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 01cfe944a73..2a2cf4b6f0f 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -22,24 +22,23 @@ def classes_for_main show_sidebar = ((@user || @admin_posts || @collection || show_wrangling_dashboard) && !@hide_dashboard) class_names += " dashboard" if show_sidebar - if page_has_filters? - class_names += " filtered" - end - - if %w(abuse_reports feedbacks known_issues).include?(controller.controller_name) - class_names = "system support " + controller.controller_name + ' ' + controller.action_name - end - if controller.controller_name == "archive_faqs" - class_names = "system docs support faq " + controller.action_name - end - if controller.controller_name == "wrangling_guidelines" - class_names = "system docs guideline " + controller.action_name - end - if controller.controller_name == "home" - class_names = "system docs " + controller.action_name - end - if controller.controller_name == "errors" - class_names = "system " + controller.controller_name + " error-" + controller.action_name + class_names += " filtered" if page_has_filters? + + case controller.controller_name + when "abuse_reports", "feedbacks", "known_issues" + class_names = "system support #{controller.controller_name} #{controller.action_name}" + when "archive_faqs" + class_names = "system docs support faq #{controller.action_name}" + when "wrangling_guidelines" + class_names = "system docs guideline #{controller.action_name}" + when "home" + class_names = if %w(content privacy).include?(controller.action_name) + "system docs tos tos-#{controller.action_name}" + else + "system docs #{controller.action_name}" + end + when "errors" + class_names = "system #{controller.controller_name} error-#{controller.action_name}" end class_names @@ -631,4 +630,17 @@ def disallow_robots?(item) item.users.all? { |u| u&.preference&.minimize_search_engines? } end end -end # end of ApplicationHelper + + # Determines if the page (controller and action combination) does not need + # to show the ToS (Terms of Service) popup. + def tos_exempt_page? + case params[:controller] + when "home" + %w[index content dmca privacy tos tos_faq].include?(params[:action]) + when "abuse_reports", "feedbacks", "users/sessions" + %w[new create].include?(params[:action]) + when "archive_faqs" + %w[index show].include?(params[:action]) + end + end +end diff --git a/app/helpers/bookmarks_helper.rb b/app/helpers/bookmarks_helper.rb index b1d7be1e0f5..c16587a105b 100644 --- a/app/helpers/bookmarks_helper.rb +++ b/app/helpers/bookmarks_helper.rb @@ -24,14 +24,9 @@ def get_new_bookmark_path(bookmarkable) end end - # tag_bookmarks_path was behaving badly for tags with slashes - def link_to_tag_bookmarks(tag) - {controller: 'bookmarks', action: 'index', tag_id: tag} - end - def link_to_bookmarkable_bookmarks(bookmarkable, link_text='') if link_text.blank? - link_text = Bookmark.count_visible_bookmarks(bookmarkable, current_user) + link_text = number_with_delimiter(Bookmark.count_visible_bookmarks(bookmarkable, current_user)) end path = case bookmarkable.class.name when "Work" diff --git a/app/helpers/collections_helper.rb b/app/helpers/collections_helper.rb index 59fcc53ef66..d1c8af19837 100644 --- a/app/helpers/collections_helper.rb +++ b/app/helpers/collections_helper.rb @@ -123,4 +123,16 @@ def collection_item_approval_options(actor:, item_type:) [t("#{key}.rejected"), :rejected] ] end + + # Fetches the icon URL for the given collection, using the standard (100x100) variant. + def standard_icon_url(collection) + return "/images/skins/iconsets/default/icon_collection.png" unless collection.icon.attached? + + rails_blob_url(collection.icon.variant(:standard)) + end + + # Wraps the collection's standard_icon_url in an image tag + def collection_icon_display(collection) + image_tag(standard_icon_url(collection), size: "100x100", alt: collection.icon_alt_text, class: "icon", skip_pipeline: true) + end end diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb index 95f5ce1b72c..fd87f3e7946 100644 --- a/app/helpers/comments_helper.rb +++ b/app/helpers/comments_helper.rb @@ -32,6 +32,24 @@ def link_to_comment_ultimate_parent(comment) end end + def comment_link_with_commentable_name(comment) + ultimate_parent = comment.ultimate_parent + commentable_name = ultimate_parent&.commentable_name + text = case ultimate_parent.class.to_s + when "Work" + t("comments_helper.comment_link_with_commentable_name.on_work_html", title: commentable_name) + when "AdminPost" + t("comments_helper.comment_link_with_commentable_name.on_admin_post_html", title: commentable_name) + else + if ultimate_parent.is_a?(Tag) + t("comments_helper.comment_link_with_commentable_name.on_tag_html", name: commentable_name) + else + t("comments_helper.comment_link_with_commentable_name.on_unknown") + end + end + link_to(text, comment_path(comment)) + end + # return pseudname or name for comment def get_commenter_pseud_or_name(comment) if comment.pseud_id @@ -112,6 +130,7 @@ def can_reply_to_comment?(comment) return false if comment_parent_hidden?(comment) return false if blocked_by_comment?(comment) return false if blocked_by?(comment.ultimate_parent) + return false if logged_in_as_admin? return true unless guest? @@ -185,16 +204,14 @@ def parent_disallows_comments?(comment) parent.disable_anon_comments? && !logged_in? end - #### HELPERS FOR REPLYING TO COMMENTS ##### + def can_review_comment?(comment) + return false unless comment.unreviewed? - def add_cancel_comment_reply_link(comment) - if params[:add_comment_reply_id] && params[:add_comment_reply_id] == comment.id.to_s - cancel_comment_reply_link(comment) - else - add_comment_reply_link(comment) - end + is_author_of?(comment.ultimate_parent) || policy(comment).can_review_comment? end + #### HELPERS FOR REPLYING TO COMMENTS ##### + # return link to add new reply to a comment def add_comment_reply_link(comment) commentable_id = comment.ultimate_parent.is_a?(Tag) ? @@ -225,14 +242,17 @@ def cancel_comment_reply_link(comment) comment.parent.id link_to( ts("Cancel"), - url_for(controller: :comments, - action: :cancel_comment_reply, - id: comment.id, - comment_id: params[:comment_id], - commentable_id => commentable_value, - view_full_work: params[:view_full_work], - page: params[:page]), - remote: true) + url_for( + controller: :comments, + action: :cancel_comment_reply, + id: comment.id, + comment_id: params[:comment_id], + commentable_id => commentable_value, + view_full_work: params[:view_full_work], + page: params[:page] + ), + remote: true + ) end # canceling an edit @@ -369,4 +389,8 @@ def comments_are_moderated(commentable) parent = find_parent(commentable) parent.respond_to?(:moderated_commenting_enabled) && parent.moderated_commenting_enabled? end + + def focused_on_comment(commentable) + params[:add_comment_reply_id] && params[:add_comment_reply_id] == commentable.id.to_s + end end diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb index 0fe46c4376d..55e91cdb8cc 100644 --- a/app/helpers/home_helper.rb +++ b/app/helpers/home_helper.rb @@ -9,4 +9,106 @@ def html_to_text(string) end return string end + + # A TOC section has an h4 header, p with intro link, and ol of subsections. + def tos_table_of_contents_section(action) + return unless %w[content privacy tos].include?(action) + + content = tos_section_header(action) + tos_section_intro_link(action) + tos_subsection_list(action) + # If we're on /tos, /content, or /privacy, use the details tag to make + # sections expandable and collapsable. + if controller.controller_name == "home" + # Use the open attribute to make the page's corresponding section expanded + # by default. + content_tag(:details, content, open: controller.action_name == action) + else + content + end + end + + private + + def tos_section_header(action) + # If we're on /tos, /content, or /privacy, the corresponding section header + # gets extra text indicating it is the current section. + text = if controller.controller_name == "home" && controller.action_name == action + t("home.tos_toc.#{action}.header_current") + else + t("home.tos_toc.#{action}.header") + end + heading = content_tag(:h4, text, class: "heading") + # If we're on /tos, /content, or /privacy, use a summary tag around the h4 + # so it serves as the toggle to expand or collapse its section. + if controller.controller_name == "home" + content_tag(:summary, heading) + else + heading + end + end + + def tos_section_intro_link(action) + content_tag(:p, link_to(t("home.tos_toc.#{action}.intro"), tos_anchor_url(action, action))) + end + + def tos_subsection_list(action) + items = case action + when "content" + content_policy_subsection_items + when "privacy" + privacy_policy_subsection_items + when "tos" + tos_subsection_items + end + content_tag(:ol, items.html_safe, style: "list-style-type: upper-alpha;") + end + + # When we are on the /signup page, the entire TOS is displayed. This lets us + # make sure that page only uses plain anchors in its TOC while the /tos, + # /content, nad /privacy pages (found in the home controller) sometimes + # point to other pages. + def tos_anchor_url(action, anchor) + if controller.controller_name == "home" + url_for(only_path: true, action: action, anchor: anchor) + else + "##{anchor}" + end + end + + def content_policy_subsection_items + content_tag(:li, link_to(t("home.tos_toc.content.offensive_content"), tos_anchor_url("content", "II.A"))) + + content_tag(:li, link_to(t("home.tos_toc.content.fanworks"), tos_anchor_url("content", "II.B"))) + + content_tag(:li, link_to(t("home.tos_toc.content.commercial_promotion"), tos_anchor_url("content", "II.C"))) + + content_tag(:li, link_to(t("home.tos_toc.content.copyright_infringement"), tos_anchor_url("content", "II.D"))) + + content_tag(:li, link_to(t("home.tos_toc.content.plagiarism"), tos_anchor_url("content", "II.E"))) + + content_tag(:li, link_to(t("home.tos_toc.content.personal_information_and_fannish_identities"), tos_anchor_url("content", "II.F"))) + + content_tag(:li, link_to(t("home.tos_toc.content.impersonation"), tos_anchor_url("content", "II.G"))) + + content_tag(:li, link_to(t("home.tos_toc.content.harassment"), tos_anchor_url("content", "II.H"))) + + content_tag(:li, link_to(t("home.tos_toc.content.user_icons"), tos_anchor_url("content", "II.I"))) + + content_tag(:li, link_to(t("home.tos_toc.content.mandatory_tags"), tos_anchor_url("content", "II.J"))) + + content_tag(:li, link_to(t("home.tos_toc.content.illegal_and_inappropriate_content"), tos_anchor_url("content", "II.K"))) + end + + def privacy_policy_subsection_items + content_tag(:li, link_to(t("home.tos_toc.privacy.applicability"), tos_anchor_url("privacy", "III.A"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.scope_of_personal_information_we_process"), tos_anchor_url("privacy", "III.B"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.types_of_personal_information_we_collect_and_process"), tos_anchor_url("privacy", "III.C"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.aggregate_and_anonymous_information"), tos_anchor_url("privacy", "III.D"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.your_rights_under_applicable_data_privacy_laws"), tos_anchor_url("privacy", "III.E"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.information_shared_with_third_parties"), tos_anchor_url("privacy", "III.F"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.termination_of_account"), tos_anchor_url("privacy", "III.G"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.retention_of_personal_information"), tos_anchor_url("privacy", "III.H"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.contact_us"), tos_anchor_url("privacy", "III.I"))) + end + + def tos_subsection_items + content_tag(:li, link_to(t("home.tos_toc.tos.general_terms"), tos_anchor_url("tos", "I.A"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.updates_to_the_tos"), tos_anchor_url("tos", "I.B"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.potential_problems"), tos_anchor_url("tos", "I.C"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.content_you_access"), tos_anchor_url("tos", "I.D"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.what_we_do_with_content"), tos_anchor_url("tos", "I.E"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.what_you_cant_do"), tos_anchor_url("tos", "I.F"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.registration_and_email_addresses"), tos_anchor_url("tos", "I.G"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.age_policy"), tos_anchor_url("tos", "I.H"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.abuse_policy"), tos_anchor_url("tos", "I.I"))) + end end diff --git a/app/helpers/mailer_helper.rb b/app/helpers/mailer_helper.rb index c83af00bf0f..67af73b77ec 100644 --- a/app/helpers/mailer_helper.rb +++ b/app/helpers/mailer_helper.rb @@ -181,22 +181,25 @@ def style_work_tag_metadata(tags) end def commenter_pseud_or_name_link(comment) + return style_bold(t("roles.anonymous_creator")) if comment.by_anonymous_creator? + if comment.comment_owner.nil? - t("roles.guest_commenter_name_html", name: style_bold(comment.comment_owner_name), role: style_role(t("roles.guest_with_parens"))) - elsif comment.by_anonymous_creator? - style_bold(t("roles.anonymous_creator")) + t("roles.commenter_name.html", name: style_bold(comment.comment_owner_name), role_with_parens: style_role(t("roles.guest_with_parens"))) else - style_pseud_link(comment.pseud) + role = comment.user.official ? t("roles.official_with_parens") : t("roles.registered_with_parens") + pseud_link = style_link(comment.pseud.byline, user_pseud_url(comment.user, comment.pseud)) + t("roles.commenter_name.html", name: tag.strong(pseud_link), role_with_parens: style_role(role)) end end def commenter_pseud_or_name_text(comment) + return t("roles.anonymous_creator") if comment.by_anonymous_creator? + if comment.comment_owner.nil? - t("roles.guest_commenter_name_text", name: comment.comment_owner_name, role: t("roles.guest_with_parens")) - elsif comment.by_anonymous_creator? - t("roles.anonymous_creator") + t("roles.commenter_name.text", name: comment.comment_owner_name, role_with_parens: t("roles.guest_with_parens")) else - text_pseud(comment.pseud) + role = comment.user.official ? t("roles.official_with_parens") : t("roles.registered_with_parens") + t("roles.commenter_name.text", name: text_pseud(comment.pseud), role_with_parens: role) end end diff --git a/app/helpers/skins_helper.rb b/app/helpers/skins_helper.rb index e0768992e7f..73bd2af9876 100644 --- a/app/helpers/skins_helper.rb +++ b/app/helpers/skins_helper.rb @@ -9,37 +9,38 @@ def skin_author_link(skin) # we only actually display an image if there's a file def skin_preview_display(skin) - if skin && skin.icon_file_name - link_to image_tag(skin.icon.url(:standard), alt: skin.icon_alt_text, class: "icon", skip_pipeline: true), skin.icon.url(:original) - end - end - - def skin_tag - skin = nil - - if params[:site_skin] - skin ||= Skin.approved_or_owned_by.usable.find_by(id: params[:site_skin]) - end + return unless skin&.icon&.attached? - if (logged_in? || logged_in_as_admin?) && session[:site_skin] - skin ||= Skin.approved_or_owned_by.usable.find_by(id: session[:site_skin]) - end - - skin_id = if skin.nil? - current_user&.preference&.skin_id || AdminSetting.default_skin_id - else - skin.id - end + link_to image_tag(rails_blob_url(skin.icon.variant(:standard)), + alt: skin.icon_alt_text, + class: "icon", + skip_pipeline: true), + rails_blob_url(skin.icon) + end - return "" if skin_id.nil? + # Fetches the current skin. This is determined by the following + # 1. Skin ID set by request parameter + # 2. Skin ID set in the current session (if someone, a user or admin, is logged in) + # 3. Current user's skin preference + # 4. The default skin (as set by the active AdminSetting) + def current_skin + skin = Skin.approved_or_owned_by.usable.find_by(id: params[:site_skin]) if params[:site_skin] + skin ||= Skin.approved_or_owned_by.usable.find_by(id: session[:site_skin]) if (logged_in? || logged_in_as_admin?) && session[:site_skin] + skin ||= current_user&.preference&.skin + skin || AdminSetting.default_skin + end + def skin_tag roles = if logged_in_as_admin? Skin::DEFAULT_ROLES_TO_INCLUDE + ["admin"] else Skin::DEFAULT_ROLES_TO_INCLUDE end - # We include the version information for both the skin_id and the + skin = current_skin + return "" unless skin + + # We include the version information for both the skin's id and the # AdminSetting.default_skin_id because the default skin is used in skins of # type "user", so we need to regenerate the cache block when it's modified. # @@ -47,12 +48,11 @@ def skin_tag # regenerate the cache block when an admin updates the current default # skin. Rails.cache.fetch( - [:v1, :site_skin, skin_id, logged_in_as_admin?], - version: [skin_cache_version(skin_id), + [:v1, :site_skin, skin.id, logged_in_as_admin?], + version: [skin_cache_version(skin.id), AdminSetting.default_skin_id, skin_cache_version(AdminSetting.default_skin_id)] ) do - skin ||= Skin.find(skin_id) skin.get_style(roles) end end diff --git a/app/helpers/tag_sets_helper.rb b/app/helpers/tag_sets_helper.rb index 83772895e25..35e83290edf 100644 --- a/app/helpers/tag_sets_helper.rb +++ b/app/helpers/tag_sets_helper.rb @@ -64,7 +64,7 @@ def nomination_status(nomination=nil) end def nomination_tag_information(nominated_tag) - tag_object = nominated_tag.type.gsub(/Nomination/, '').constantize.find_by_name(nominated_tag.tagname) + tag_object = Tag.find_by(name: nominated_tag.tagname) status = "nonexistent" tooltip = ts("This tag has never been used before. Check the spelling!") title = ts("nonexistent tag") diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 938044a272f..f51e9e0aa2e 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -21,21 +21,17 @@ def print_pseuds(user) end # Determine which icon to show on user pages - def standard_icon(user = nil, pseud = nil) - if pseud && pseud.icon - pseud.icon.url(:standard).gsub(/^http:/, "https:") - elsif user && user.default_pseud && user.default_pseud.icon - user.default_pseud.icon.url(:standard).gsub(/^http:/, "https:") - else - '/images/skins/iconsets/default/icon_user.png' - end + def standard_icon(pseud = nil) + return "/images/skins/iconsets/default/icon_user.png" unless pseud&.icon&.attached? + + rails_blob_url(pseud.icon.variant(:standard)) end # no alt text if there isn't specific alt text def icon_display(user = nil, pseud = nil) path = user ? (pseud ? user_pseud_path(pseud.user, pseud) : user_path(user)) : nil pseud ||= user.default_pseud if user - icon = standard_icon(user, pseud) + icon = standard_icon(pseud) alt_text = pseud.try(:icon_alt_text) || nil if path diff --git a/app/helpers/wrangling_helper.rb b/app/helpers/wrangling_helper.rb index 8ef592ed4b9..6b69f6beb88 100644 --- a/app/helpers/wrangling_helper.rb +++ b/app/helpers/wrangling_helper.rb @@ -3,7 +3,7 @@ def tag_counts_per_category counts = {} [Fandom, Character, Relationship, Freeform].each do |klass| counts[klass.to_s.downcase.pluralize.to_sym] = Rails.cache.fetch("/wrangler/counts/sidebar/#{klass}", race_condition_ttl: 10, expires_in: 1.hour) do - TagQuery.new(type: klass.to_s, in_use: true, unwrangleable: false, unwrangled: true).count + TagQuery.new(type: klass.to_s, in_use: true, unwrangleable: false, unwrangled: true, has_posted_works: true).count end end counts[:UnsortedTag] = Rails.cache.fetch("/wrangler/counts/sidebar/UnsortedTag", race_condition_ttl: 10, expires_in: 1.hour) do diff --git a/app/jobs/report_attachment_job.rb b/app/jobs/report_attachment_job.rb new file mode 100644 index 00000000000..2e3fbad24d1 --- /dev/null +++ b/app/jobs/report_attachment_job.rb @@ -0,0 +1,7 @@ +class ReportAttachmentJob < ApplicationJob + def perform(ticket_id, work) + download = Download.new(work, mime_type: "text/html") + html = DownloadWriter.new(download).generate_html + FeedbackReporter.new.send_attachment!(ticket_id, "#{download.file_name}.html", html) + end +end diff --git a/app/mailers/archive_devise_mailer.rb b/app/mailers/archive_devise_mailer.rb index 91e874e8e27..20006499c09 100644 --- a/app/mailers/archive_devise_mailer.rb +++ b/app/mailers/archive_devise_mailer.rb @@ -11,18 +11,14 @@ class ArchiveDeviseMailer < Devise::Mailer def reset_password_instructions(record, token, options = {}) @user = record @token = token - if @user.is_a?(Admin) - subject = t("admin.mailer.reset_password_instructions.subject", + subject = if @user.is_a?(Admin) + t("admin.mailer.reset_password_instructions.subject", app_name: ArchiveConfig.APP_SHORT_NAME) - devise_mail(record, :reset_password_instructions, - options.merge(subject: subject)) - else - I18n.with_locale(@user.preference.locale.iso) do - subject = t("users.mailer.reset_password_instructions.subject", - app_name: ArchiveConfig.APP_SHORT_NAME) - devise_mail(record, :reset_password_instructions, - options.merge(subject: subject)) - end - end + else + t("users.mailer.reset_password_instructions.subject", + app_name: ArchiveConfig.APP_SHORT_NAME) + end + devise_mail(record, :reset_password_instructions, + options.merge(subject: subject)) end end diff --git a/app/mailers/kudo_mailer.rb b/app/mailers/kudo_mailer.rb index 5ac847a3304..6c210c32027 100644 --- a/app/mailers/kudo_mailer.rb +++ b/app/mailers/kudo_mailer.rb @@ -10,21 +10,18 @@ def batch_kudo_notification(user_id, user_kudos) user = User.find(user_id) kudos_hash = JSON.parse(user_kudos) - I18n.with_locale(user.preference.locale.iso) do - kudos_hash.each_pair do |commentable_info, kudo_givers_hash| - # Parse the key to extract the type and id of the commentable so we can - # weed out any commentables that no longer exist. - commentable_type, commentable_id = commentable_info.split("_") - commentable = commentable_type.constantize.find_by(id: commentable_id) - next unless commentable + kudos_hash.each_pair do |commentable_info, _kudo_givers_hash| + # Parse the key to extract the type and id of the commentable so we can + # weed out any commentables that no longer exist. + commentable_type, commentable_id = commentable_info.split("_") + commentable = commentable_type.constantize.find_by(id: commentable_id) + next unless commentable - @commentables << commentable - end - mail( - to: user.email, - # i18n-tasks-use t('kudo_mailer.batch_kudo_notification.subject') - subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) - ) + @commentables << commentable end + mail( + to: user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) end end diff --git a/app/mailers/tag_wrangling_supervisor_mailer.rb b/app/mailers/tag_wrangling_supervisor_mailer.rb new file mode 100644 index 00000000000..a9c287ca86e --- /dev/null +++ b/app/mailers/tag_wrangling_supervisor_mailer.rb @@ -0,0 +1,12 @@ +class TagWranglingSupervisorMailer < ApplicationMailer + default to: ArchiveConfig.TAG_WRANGLER_SUPERVISORS_ADDRESS + + # Send an email to tag wrangling supervisors when a tag wrangler changes their username + def wrangler_username_change_notification(old_name, new_name) + @old_username = old_name + @new_username = new_name + mail( + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end +end diff --git a/app/mailers/tos_update_mailer.rb b/app/mailers/tos_update_mailer.rb new file mode 100644 index 00000000000..2c694c9822b --- /dev/null +++ b/app/mailers/tos_update_mailer.rb @@ -0,0 +1,11 @@ +class TosUpdateMailer < ApplicationMailer + # Sent by notifications:send_tos_update + def tos_update_notification(user, admin_post_id) + @username = user.login + @admin_post = admin_post_id + mail( + to: user.email, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}] Updates to #{ArchiveConfig.APP_SHORT_NAME}'s Terms of Service" + ) + end +end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 0e0f9890482..ebe3070ebf9 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -30,9 +30,9 @@ def invited_to_collection_notification(user_id, work_id, collection_id) @work = Work.find(work_id) @collection = Collection.find(collection_id) mail( - to: @user.email, - subject: "[#{ArchiveConfig.APP_SHORT_NAME}]#{'[' + @collection.title + ']'} Request to include work in a collection" - ) + to: @user.email, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}]#{'[' + @collection.title + ']'} Request to include work in a collection" + ) end # We use an options hash here, instead of keyword arguments, to avoid @@ -72,7 +72,7 @@ def anonymous_or_unrevealed_notification(user_id, work_id, collection_id, option # TODO refactor to make it asynchronous def invitation(invitation_id) @invitation = Invitation.find(invitation_id) - @user_name = (@invitation.creator.is_a?(User) ? @invitation.creator.login : '') + @user_name = (@invitation.creator.is_a?(User) ? @invitation.creator.login : "") mail( to: @invitation.invitee_email, subject: t("user_mailer.invitation.subject", app_name: ArchiveConfig.APP_SHORT_NAME) @@ -92,22 +92,14 @@ def invitation_to_claim(invitation_id, archivist_login) end # Notifies a writer that their imported works have been claimed - def claim_notification(creator_id, claimed_work_ids, is_user=false) - if is_user - creator = User.find(creator_id) - locale = creator.preference.locale.iso - else - creator = ExternalAuthor.find(creator_id) - locale = I18n.default_locale - end + def claim_notification(creator_id, claimed_work_ids) + creator = User.find(creator_id) @external_email = creator.email @claimed_works = Work.where(id: claimed_work_ids) - I18n.with_locale(locale) do - mail( - to: creator.email, - subject: t("user_mailer.claim_notification.subject", app_name: ArchiveConfig.APP_SHORT_NAME) - ) - end + mail( + to: creator.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) end # Sends a batched subscription notification @@ -116,6 +108,7 @@ def batch_subscription_notification(subscription_id, entries) # then the resque job does not error and we just silently fail. @subscription = Subscription.find_by(id: subscription_id) return if @subscription.nil? + creation_entries = JSON.parse(entries) @creations = [] # look up all the creations that have generated updates for this subscription @@ -123,13 +116,14 @@ def batch_subscription_notification(subscription_id, entries) creation_type, creation_id = creation_info.split("_") creation = creation_type.constantize.where(id: creation_id).first next unless creation && creation.try(:posted) - next if (creation.is_a?(Chapter) && !creation.work.try(:posted)) - next if creation.pseuds.any? {|p| p.user == User.orphan_account} # no notifications for orphan works + next if creation.is_a?(Chapter) && !creation.work.try(:posted) + next if creation.pseuds.any? { |p| p.user == User.orphan_account } # no notifications for orphan works + # TODO: allow subscriptions to orphan_account to receive notifications # If the subscription notification is for a user subscription, we don't # want to send updates about works that have recently become anonymous. - if @subscription.subscribable_type == 'User' + if @subscription.subscribable_type == "User" next if Subscription.anonymous_creation?(creation) end @@ -142,9 +136,7 @@ def batch_subscription_notification(subscription_id, entries) @creations.uniq! subject = @subscription.subject_text(@creations.first) - if @creations.count > 1 - subject += " and #{@creations.count - 1} more" - end + subject += " and #{@creations.count - 1} more" if @creations.count > 1 I18n.with_locale(@subscription.user.preference.locale.iso) do mail( to: @subscription.user.email, @@ -160,7 +152,7 @@ def invite_increase_notification(user_id, total) I18n.with_locale(@user.preference.locale.iso) do mail( to: @user.email, - subject: "#{t 'user_mailer.invite_increase_notification.subject', app_name: ArchiveConfig.APP_SHORT_NAME}" + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) ) end end @@ -170,40 +162,36 @@ def invite_request_declined(user_id, total, reason) @user = User.find(user_id) @total = total @reason = reason - I18n.with_locale(@user.preference.locale.iso) do - mail( - to: @user.email, - subject: t('user_mailer.invite_request_declined.subject', app_name: ArchiveConfig.APP_SHORT_NAME) - ) - end + mail( + to: @user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) end - # TODO: This may be sent to multiple users simultaneously. We need to ensure - # each user gets the email for their preferred locale. - def collection_notification(collection_id, subject, message) + def collection_notification(collection_id, subject, message, email) @message = message @collection = Collection.find(collection_id) mail( - to: @collection.get_maintainers_email, + to: email, subject: "[#{ArchiveConfig.APP_SHORT_NAME}][#{@collection.title}] #{subject}" ) end - def invalid_signup_notification(collection_id, invalid_signup_ids) + def invalid_signup_notification(collection_id, invalid_signup_ids, email) @collection = Collection.find(collection_id) @invalid_signups = invalid_signup_ids mail( - to: @collection.get_maintainers_email, + to: email, subject: "[#{ArchiveConfig.APP_SHORT_NAME}][#{@collection.title}] Invalid sign-ups found" ) end # This is sent at the end of matching, i.e., after assignments are generated. # It is also sent when assignments are regenerated. - def potential_match_generation_notification(collection_id) + def potential_match_generation_notification(collection_id, email) @collection = Collection.find(collection_id) mail( - to: @collection.get_maintainers_email, + to: email, subject: "[#{ArchiveConfig.APP_SHORT_NAME}][#{@collection.title}] Potential assignment generation complete" ) end @@ -216,7 +204,6 @@ def challenge_assignment_notification(collection_id, assigned_user_id, assignmen I18n.with_locale(@assigned_user.preference.locale.iso) do mail( to: @assigned_user.email, - # i18n-tasks-use t('user_mailer.challenge_assignment_notification.subject') subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title) ) end @@ -228,7 +215,7 @@ def signup_notification(user_id) I18n.with_locale(@user.preference.locale.iso) do mail( to: @user.email, - subject: t('user_mailer.signup_notification.subject', app_name: ArchiveConfig.APP_SHORT_NAME) + subject: t("user_mailer.signup_notification.subject", app_name: ArchiveConfig.APP_SHORT_NAME) ) end end @@ -238,12 +225,10 @@ def change_email(user_id, old_email, new_email) @user = User.find(user_id) @old_email = old_email @new_email = new_email - I18n.with_locale(@user.preference.locale.iso) do - mail( - to: @old_email, - subject: t('user_mailer.change_email.subject', app_name: ArchiveConfig.APP_SHORT_NAME) - ) - end + mail( + to: @old_email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) end ### WORKS NOTIFICATIONS ### @@ -323,7 +308,7 @@ def recipient_notification(user_id, work_id, collection_id = nil) end # Emails a prompter to say that a response has been posted to their prompt - def prompter_notification(work_id, collection_id=nil) + def prompter_notification(work_id, collection_id = nil) @work = Work.find(work_id) @collection = Collection.find(collection_id) if collection_id @work.challenge_claims.each do |claim| @@ -352,7 +337,7 @@ def delete_work_notification(user, work) I18n.with_locale(@user.preference.locale.iso) do mail( to: user.email, - subject: t('user_mailer.delete_work_notification.subject', app_name: ArchiveConfig.APP_SHORT_NAME) + subject: t("user_mailer.delete_work_notification.subject", app_name: ArchiveConfig.APP_SHORT_NAME) ) end end @@ -372,7 +357,7 @@ def admin_deleted_work_notification(user, work) I18n.with_locale(@user.preference.locale.iso) do mail( to: user.email, - subject: t('user_mailer.admin_deleted_work_notification.subject', app_name: ArchiveConfig.APP_SHORT_NAME) + subject: t("user_mailer.admin_deleted_work_notification.subject", app_name: ArchiveConfig.APP_SHORT_NAME) ) end end @@ -385,7 +370,6 @@ def admin_hidden_work_notification(creation_id, user_id) I18n.with_locale(@user.preference.locale.iso) do mail( to: @user.email, - # i18n-tasks-use t('user_mailer.admin_hidden_work_notification.subject') subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) ) end @@ -396,8 +380,8 @@ def admin_spam_work_notification(creation_id, user_id) @work = Work.find_by(id: creation_id) mail( - to: @user.email, - subject: "[#{ArchiveConfig.APP_SHORT_NAME}] Your work was hidden as spam" + to: @user.email, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}] Your work was hidden as spam" ) end @@ -407,13 +391,14 @@ def admin_spam_work_notification(creation_id, user_id) def feedback(feedback_id) feedback = Feedback.find(feedback_id) return unless feedback.email + @summary = feedback.summary @comment = feedback.comment @username = feedback.username if feedback.username.present? @language = feedback.language mail( to: feedback.email, - subject: "[#{ArchiveConfig.APP_SHORT_NAME}] Support - #{strip_html_breaks_simple(feedback.summary)}" + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, summary: strip_html_breaks_simple(feedback.summary)) ) end @@ -430,6 +415,4 @@ def abuse_report(abuse_report_id) ) end - protected - end diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb index 9a8d55d923c..7583d66ad4a 100644 --- a/app/models/abuse_report.rb +++ b/app/models/abuse_report.rb @@ -85,7 +85,7 @@ def add_work_id_to_url(url) work_id = Chapter.find_by(id: chapter_id).try(:work_id) return url if work_id.nil? - + uri = Addressable::URI.parse(url) uri.path = "/works/#{work_id}" + uri.path @@ -116,7 +116,20 @@ def send_report ip_address: ip_address, url: url ) - reporter.send_report! + response = reporter.send_report! + ticket_id = response["id"] + return if ticket_id.blank? + + attach_work_download(ticket_id) + end + + def attach_work_download(ticket_id) + is_not_comments = url[%r{/comments/}, 0].nil? + work_id = url[%r{/works/(\d+)}, 1] + return unless work_id && is_not_comments + + work = Work.find_by(id: work_id) + ReportAttachmentJob.perform_later(ticket_id, work) if work end # if the URL clearly belongs to a work (i.e. contains "/works/123") diff --git a/app/models/admin.rb b/app/models/admin.rb index e57d07fb6b6..9806ff6cac1 100644 --- a/app/models/admin.rb +++ b/app/models/admin.rb @@ -1,5 +1,5 @@ class Admin < ApplicationRecord - VALID_ROLES = %w[superadmin board board_assistants_team communications development_and_membership docs elections translation tag_wrangling support policy_and_abuse open_doors].freeze + VALID_ROLES = %w[superadmin board board_assistants_team communications development_and_membership docs elections legal translation tag_wrangling support policy_and_abuse open_doors].freeze serialize :roles, Array diff --git a/app/models/challenge_assignment.rb b/app/models/challenge_assignment.rb index 93986f1eb15..80b37738451 100755 --- a/app/models/challenge_assignment.rb +++ b/app/models/challenge_assignment.rb @@ -14,29 +14,29 @@ class ChallengeAssignment < ApplicationRecord validate :signups_match, on: :update def signups_match if self.sent_at.nil? && - self.request_signup.present? && - self.offer_signup.present? && - !self.request_signup.request_potential_matches.pluck(:offer_signup_id).include?(self.offer_signup_id) + self.request_signup.present? && + self.offer_signup.present? && + !self.request_signup.request_potential_matches.pluck(:offer_signup_id).include?(self.offer_signup_id) errors.add(:base, ts("does not match. Did you mean to write-in a giver?")) end end - scope :for_request_signup, lambda {|signup| where('request_signup_id = ?', signup.id)} + scope :for_request_signup, ->(signup) { where("request_signup_id = ?", signup.id) } - scope :for_offer_signup, lambda {|signup| where('offer_signup_id = ?', signup.id)} + scope :for_offer_signup, ->(signup) { where("offer_signup_id = ?", signup.id) } - scope :in_collection, lambda {|collection| where('challenge_assignments.collection_id = ?', collection.id) } + scope :in_collection, ->(collection) { where("challenge_assignments.collection_id = ?", collection.id) } - scope :defaulted, -> { where("defaulted_at IS NOT NULL") } + scope :defaulted, -> { where.not(defaulted_at: nil) } scope :undefaulted, -> { where("defaulted_at IS NULL") } scope :uncovered, -> { where("covered_at IS NULL") } - scope :covered, -> { where("covered_at IS NOT NULL") } - scope :sent, -> { where("sent_at IS NOT NULL") } + scope :covered, -> { where.not(covered_at: nil) } + scope :sent, -> { where.not(sent_at: nil) } - scope :with_pinch_hitter, -> { where("pinch_hitter_id IS NOT NULL") } + scope :with_pinch_hitter, -> { where.not(pinch_hitter_id: nil) } scope :with_offer, -> { where("offer_signup_id IS NOT NULL OR pinch_hitter_id IS NOT NULL") } - scope :with_request, -> { where("request_signup_id IS NOT NULL") } + scope :with_request, -> { where.not(request_signup_id: nil) } scope :with_no_request, -> { where("request_signup_id IS NULL") } scope :with_no_offer, -> { where("offer_signup_id IS NULL AND pinch_hitter_id IS NULL") } @@ -53,13 +53,12 @@ def signups_match scope :order_by_offering_pseud, -> { joins(OFFERING_PSEUD_JOIN).order("pseuds.name") } - # Get all of a user's assignments - scope :by_offering_user, lambda {|user| - select("DISTINCT challenge_assignments.*"). - joins(OFFERING_PSEUD_JOIN). - joins("INNER JOIN users ON pseuds.user_id = users.id"). - where('users.id = ?', user.id) + scope :by_offering_user, lambda { |user| + select("DISTINCT challenge_assignments.*") + .joins(OFFERING_PSEUD_JOIN) + .joins("INNER JOIN users ON pseuds.user_id = users.id") + .where("users.id = ?", user.id) } # sorting by fulfilled/posted status @@ -67,26 +66,25 @@ def signups_match collection_items.item_id = challenge_assignments.creation_id AND collection_items.item_type = challenge_assignments.creation_type)" - COLLECTION_ITEMS_LEFT_JOIN = "LEFT JOIN collection_items ON (collection_items.collection_id = challenge_assignments.collection_id AND + COLLECTION_ITEMS_LEFT_JOIN = "LEFT JOIN collection_items ON (collection_items.collection_id = challenge_assignments.collection_id AND collection_items.item_id = challenge_assignments.creation_id AND collection_items.item_type = challenge_assignments.creation_type)" WORKS_JOIN = "INNER JOIN works ON works.id = challenge_assignments.creation_id AND challenge_assignments.creation_type = 'Work'" WORKS_LEFT_JOIN = "LEFT JOIN works ON works.id = challenge_assignments.creation_id AND challenge_assignments.creation_type = 'Work'" - scope :fulfilled, -> { + scope :fulfilled, lambda { joins(COLLECTION_ITEMS_JOIN).joins(WORKS_JOIN) .where("challenge_assignments.creation_id IS NOT NULL AND collection_items.user_approval_status = ? AND collection_items.collection_approval_status = ? AND works.posted = 1", CollectionItem.user_approval_statuses[:approved], CollectionItem.collection_approval_statuses[:approved]) } - scope :posted, -> { joins(WORKS_JOIN).where("challenge_assignments.creation_id IS NOT NULL AND works.posted = 1") } # should be faster than unfulfilled scope because no giant left joins def self.unfulfilled_in_collection(collection) fulfilled_ids = ChallengeAssignment.in_collection(collection).fulfilled.pluck(:id) - fulfilled_ids.empty? ? in_collection(collection) : in_collection(collection).where("challenge_assignments.id NOT IN (?)", fulfilled_ids) + fulfilled_ids.empty? ? in_collection(collection) : in_collection(collection).where.not(challenge_assignments: { id: fulfilled_ids }) end # faster than unposted scope because no left join! @@ -106,7 +104,7 @@ def self.duplicate_recipients(collection) end # has to be a left join to get assignments that don't have a collection item - scope :unfulfilled, -> { + scope :unfulfilled, lambda { joins(COLLECTION_ITEMS_LEFT_JOIN).joins(WORKS_LEFT_JOIN) .where("challenge_assignments.creation_id IS NULL OR collection_items.user_approval_status != ? OR collection_items.collection_approval_status != ? OR works.posted = 0", CollectionItem.user_approval_statuses[:approved], CollectionItem.collection_approval_statuses[:approved]) @@ -117,7 +115,6 @@ def self.duplicate_recipients(collection) scope :unstarted, -> { where("challenge_assignments.creation_id IS NULL") } - before_destroy :clear_assignment def clear_assignment if offer_signup @@ -137,6 +134,7 @@ def request def get_collection_item return nil unless self.creation + CollectionItem.where("collection_id = ? AND item_id = ? AND item_type = ?", self.collection_id, self.creation_id, self.creation_type).first end @@ -153,17 +151,13 @@ def posted? end def defaulted=(value) - if value == "1" - self.defaulted_at = Time.now - else - self.defaulted_at = nil - end + self.defaulted_at = (Time.now if value == "1") end def defaulted !self.defaulted_at.nil? end - alias_method :defaulted?, :defaulted + alias defaulted? defaulted def offer_signup_pseud=(pseud_byline) if pseud_byline.blank? @@ -209,16 +203,27 @@ def offering_pseud end def requesting_pseud - request_signup ? request_signup.pseud : (pinch_request_signup ? pinch_request_signup.pseud : nil) + if request_signup + request_signup.pseud + else + (pinch_request_signup ? pinch_request_signup.pseud : nil) + end end - def offer_byline - offer_signup && offer_signup.pseud ? offer_signup.pseud.byline : (pinch_hitter ? (pinch_hitter.byline + "* (pinch hitter)") : "- none -") + if offer_signup && offer_signup.pseud + offer_signup.pseud.byline + else + (pinch_hitter ? I18n.t("challenge_assignment.offer_byline.pinch_hitter", pinch_hitter_byline: pinch_hitter.byline) : I18n.t("challenge_assignment.offer_byline.none")) + end end def request_byline - request_signup && request_signup.pseud ? request_signup.pseud.byline : (pinch_request_signup ? (pinch_request_byline + "* (pinch recipient)") : "- None -") + if request_signup && request_signup.pseud + request_signup.pseud.byline + else + (pinch_request_signup ? I18n.t("challenge_assignment.request_byline.pinch_recipient", pinch_request_byline: pinch_request_byline) : I18n.t("challenge_assignment.request_byline.none")) + end end def pinch_hitter_byline @@ -260,7 +265,11 @@ def send_out unless self.sent_at self.sent_at = Time.now save - assigned_to = self.offer_signup ? self.offer_signup.pseud.user : (self.pinch_hitter ? self.pinch_hitter.user : nil) + assigned_to = if self.offer_signup + self.offer_signup.pseud.user + else + (self.pinch_hitter ? self.pinch_hitter.user : nil) + end request = self.request_signup || self.pinch_request_signup UserMailer.challenge_assignment_notification(collection.id, assigned_to.id, self.id).deliver_later if assigned_to && request end @@ -289,9 +298,7 @@ def self.delayed_send_out(collection_id) collection.assignments.each do |assignment| assignment.send_out end - subject = I18n.t("user_mailer.collection_notification.assignments_sent.subject") - message = I18n.t("user_mailer.collection_notification.assignments_sent.complete") - collection.notify_maintainers(subject, message) + collection.notify_maintainers_assignments_sent # purge the potential matches! we don't want bazillions of them in our db PotentialMatch.clear!(collection) @@ -332,13 +339,14 @@ def self.delayed_generate(collection_id) @offer_match_buckets = {} @max_match_count = 0 if settings.nil? || settings.no_match_required? - # stuff everyone into the same bucket - @max_match_count = 1 - @request_match_buckets[1] = collection.signups - @offer_match_buckets[1] = collection.signups + # stuff everyone into the same bucket + @max_match_count = 1 + @request_match_buckets[1] = collection.signups + @offer_match_buckets[1] = collection.signups else collection.signups.find_each do |signup| next if signup.nil? + request_match_count = signup.request_potential_matches.count @request_match_buckets[request_match_count] ||= [] @request_match_buckets[request_match_count] << signup @@ -357,24 +365,37 @@ def self.delayed_generate(collection_id) # matches.) 0.upto(@max_match_count) do |count| if @request_match_buckets[count] - @request_match_buckets[count].sort_by {rand}.each do |request_signup| + @request_match_buckets[count].sort_by { rand } + .each do |request_signup| # go through the potential matches in order from best to worst and try and assign request_signup.reload next if request_signup.assigned_as_request + ChallengeAssignment.assign_request!(collection, request_signup) end end - if @offer_match_buckets[count] - @offer_match_buckets[count].sort_by {rand}.each do |offer_signup| - offer_signup.reload - next if offer_signup.assigned_as_offer - ChallengeAssignment.assign_offer!(collection, offer_signup) - end + next unless @offer_match_buckets[count] + + @offer_match_buckets[count].sort_by { rand } + .each do |offer_signup| + offer_signup.reload + next if offer_signup.assigned_as_offer + + ChallengeAssignment.assign_offer!(collection, offer_signup) end end REDIS_GENERAL.del(progress_key(collection)) - UserMailer.potential_match_generation_notification(collection.id).deliver_later + + if collection.collection_email.present? + UserMailer.potential_match_generation_notification(collection.id, collection.collection_email).deliver_later + else + collection.maintainers_list.each do |user| + I18n.with_locale(user.preference.locale.iso) do + UserMailer.potential_match_generation_notification(collection.id, user.email).deliver_later + end + end + end end # go through the request's potential matches in order from best to worst and try and assign @@ -388,7 +409,7 @@ def self.assign_request!(collection, request_signup) # if there's a circular match let's save it as our last choice if potential_match.offer_signup.assigned_as_request && !last_choice && - collection.assignments.for_request_signup(potential_match.offer_signup).first.offer_signup == request_signup + collection.assignments.for_request_signup(potential_match.offer_signup).first.offer_signup == request_signup last_choice = potential_match next end @@ -398,9 +419,7 @@ def self.assign_request!(collection, request_signup) break end - if !assigned && last_choice - ChallengeAssignment.do_assign_request!(assignment, last_choice) - end + ChallengeAssignment.do_assign_request!(assignment, last_choice) if !assigned && last_choice request_signup.assigned_as_request = true request_signup.save! @@ -420,7 +439,7 @@ def self.assign_offer!(collection, offer_signup) # if there's a circular match let's save it as our last choice if potential_match.request_signup.assigned_as_offer && !last_choice && - collection.assignments.for_offer_signup(potential_match.request_signup).first.request_signup == offer_signup + collection.assignments.for_offer_signup(potential_match.request_signup).first.request_signup == offer_signup last_choice = potential_match next end @@ -430,9 +449,7 @@ def self.assign_offer!(collection, offer_signup) break end - if !assigned && last_choice - ChallengeAssignment.do_assign_offer!(assignment, last_choice) - end + ChallengeAssignment.do_assign_offer!(assignment, last_choice) if !assigned && last_choice offer_signup.assigned_as_offer = true offer_signup.save! diff --git a/app/models/collection.rb b/app/models/collection.rb index d1d71b2466f..84c92a4fd99 100755 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -2,16 +2,16 @@ class Collection < ApplicationRecord include Filterable include WorksOwner - has_attached_file :icon, - styles: { standard: "100x100>" }, - url: "/system/:class/:attachment/:id/:style/:basename.:extension", - path: %w(staging production).include?(Rails.env) ? ":class/:attachment/:id/:style.:extension" : ":rails_root/public:url", - storage: %w(staging production).include?(Rails.env) ? :s3 : :filesystem, - s3_protocol: "https", - default_url: "/images/skins/iconsets/default/icon_collection.png" + has_one_attached :icon do |attachable| + attachable.variant(:standard, resize_to_limit: [100, 100]) + end - validates_attachment_content_type :icon, content_type: /image\/\S+/, allow_nil: true - validates_attachment_size :icon, less_than: 500.kilobytes, allow_nil: true + # i18n-tasks-use t("errors.attributes.icon.invalid_format") + # i18n-tasks-use t("errors.attributes.icon.too_large") + validates :icon, attachment: { + allowed_formats: %r{image/\S+}, + maximum_size: ArchiveConfig.ICON_SIZE_KB_MAX.kilobytes + } belongs_to :parent, class_name: "Collection", inverse_of: :children has_many :children, class_name: "Collection", foreign_key: "parent_id", inverse_of: :parent @@ -22,13 +22,14 @@ class Collection < ApplicationRecord has_one :collection_preference, dependent: :destroy accepts_nested_attributes_for :collection_preference + before_validation :clear_icon + before_validation :cleanup_url before_create :ensure_associated def ensure_associated - self.collection_preference = CollectionPreference.new unless self.collection_preference - self.collection_profile = CollectionProfile.new unless self.collection_profile + self.collection_preference = CollectionPreference.new unless self.collection_preference + self.collection_profile = CollectionProfile.new unless self.collection_profile end - belongs_to :challenge, dependent: :destroy, polymorphic: true has_many :prompts, dependent: :destroy @@ -52,10 +53,10 @@ def clean_up_challenge accepts_nested_attributes_for :collection_items, allow_destroy: true has_many :approved_collection_items, -> { approved_by_both }, class_name: "CollectionItem" - has_many :works, through: :collection_items, source: :item, source_type: 'Work' + has_many :works, through: :collection_items, source: :item, source_type: "Work" has_many :approved_works, -> { posted }, through: :approved_collection_items, source: :item, source_type: "Work" - has_many :bookmarks, through: :collection_items, source: :item, source_type: 'Bookmark' + has_many :bookmarks, through: :collection_items, source: :item, source_type: "Bookmark" has_many :approved_bookmarks, through: :approved_collection_items, source: :item, source_type: "Bookmark" has_many :collection_participants, dependent: :destroy @@ -63,41 +64,34 @@ def clean_up_challenge has_many :participants, through: :collection_participants, source: :pseud has_many :users, through: :participants, source: :user - has_many :invited, -> { where('collection_participants.participant_role = ?', CollectionParticipant::INVITED) }, through: :collection_participants, source: :pseud - has_many :owners, -> { where('collection_participants.participant_role = ?', CollectionParticipant::OWNER) }, through: :collection_participants, source: :pseud - has_many :moderators, -> { where('collection_participants.participant_role = ?', CollectionParticipant::MODERATOR) }, through: :collection_participants, source: :pseud - has_many :members, -> { where('collection_participants.participant_role = ?', CollectionParticipant::MEMBER) }, through: :collection_participants, source: :pseud - has_many :posting_participants, -> { where('collection_participants.participant_role in (?)', [CollectionParticipant::MEMBER,CollectionParticipant::MODERATOR, CollectionParticipant::OWNER ] ) }, through: :collection_participants, source: :pseud - - + has_many :invited, -> { where(collection_participants: { participant_role: CollectionParticipant::INVITED }) }, through: :collection_participants, source: :pseud + has_many :owners, -> { where(collection_participants: { participant_role: CollectionParticipant::OWNER }) }, through: :collection_participants, source: :pseud + has_many :moderators, -> { where(collection_participants: { participant_role: CollectionParticipant::MODERATOR }) }, through: :collection_participants, source: :pseud + has_many :members, -> { where(collection_participants: { participant_role: CollectionParticipant::MEMBER }) }, through: :collection_participants, source: :pseud + has_many :posting_participants, -> { where(collection_participants: { participant_role: [CollectionParticipant::MEMBER, CollectionParticipant::MODERATOR, CollectionParticipant::OWNER] }) }, through: :collection_participants, source: :pseud CHALLENGE_TYPE_OPTIONS = [ - ["", ""], - [ts("Gift Exchange"), "GiftExchange"], - [ts("Prompt Meme"), "PromptMeme"], - ] - - before_validation :clear_icon + ["", ""], + [ts("Gift Exchange"), "GiftExchange"], + [ts("Prompt Meme"), "PromptMeme"] + ].freeze validate :must_have_owners def must_have_owners # we have to use collection participants because the association may not exist until after # the collection is saved - errors.add(:base, ts("Collection has no valid owners.")) if (self.collection_participants + (self.parent ? self.parent.collection_participants : [])).select {|p| p.is_owner?}.empty? + errors.add(:base, ts("Collection has no valid owners.")) if (self.collection_participants + (self.parent ? self.parent.collection_participants : [])).select(&:is_owner?) + .empty? end validate :collection_depth def collection_depth - if (self.parent && self.parent.parent) || (self.parent && !self.children.empty?) || (!self.children.empty? && !self.children.collect(&:children).flatten.empty?) - errors.add(:base, ts("Sorry, but %{name} is a subcollection, so it can't also be a parent collection.", name: parent.name)) - end + errors.add(:base, ts("Sorry, but %{name} is a subcollection, so it can't also be a parent collection.", name: parent.name)) if self.parent&.parent || (self.parent && !self.children.empty?) || (!self.children.empty? && !self.children.collect(&:children).flatten.empty?) end validate :parent_exists def parent_exists - unless parent_name.blank? || Collection.find_by(name: parent_name) - errors.add(:base, ts("We couldn't find a collection with name %{name}.", name: parent_name)) - end + errors.add(:base, ts("We couldn't find a collection with name %{name}.", name: parent_name)) unless parent_name.blank? || Collection.find_by(name: parent_name) end validate :parent_is_allowed @@ -111,111 +105,112 @@ def parent_is_allowed end end - validates_presence_of :name, message: ts("Please enter a name for your collection.") + validates :name, presence: { message: ts("Please enter a name for your collection.") } validates :name, uniqueness: { message: ts("Sorry, that name is already taken. Try again, please!") } - validates_length_of :name, - minimum: ArchiveConfig.TITLE_MIN, - too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) - validates_length_of :name, - maximum: ArchiveConfig.TITLE_MAX, - too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) - validates_format_of :name, - message: ts('must begin and end with a letter or number; it may also contain underscores. It may not contain any other characters, including spaces.'), - with: /\A[A-Za-z0-9]\w*[A-Za-z0-9]\Z/ - validates_length_of :icon_alt_text, allow_blank: true, maximum: ArchiveConfig.ICON_ALT_MAX, - too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_ALT_MAX) - validates_length_of :icon_comment_text, allow_blank: true, maximum: ArchiveConfig.ICON_COMMENT_MAX, - too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_COMMENT_MAX) + validates :name, + length: { minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) } + validates :name, + length: { maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) } + validates :name, + format: { message: ts("must begin and end with a letter or number; it may also contain underscores. It may not contain any other characters, including spaces."), + with: /\A[A-Za-z0-9]\w*[A-Za-z0-9]\Z/ } + validates :icon_alt_text, length: { allow_blank: true, maximum: ArchiveConfig.ICON_ALT_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_ALT_MAX) } + validates :icon_comment_text, length: { allow_blank: true, maximum: ArchiveConfig.ICON_COMMENT_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_COMMENT_MAX) } validates :email, email_format: { allow_blank: true } - validates_presence_of :title, message: ts("Please enter a title to be displayed for your collection.") - validates_length_of :title, - minimum: ArchiveConfig.TITLE_MIN, - too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) - validates_length_of :title, - maximum: ArchiveConfig.TITLE_MAX, - too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) + validates :title, presence: { message: ts("Please enter a title to be displayed for your collection.") } + validates :title, + length: { minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) } + validates :title, + length: { maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) } validate :no_reserved_strings def no_reserved_strings errors.add(:title, ts("^Sorry, the ',' character cannot be in a collection Display Title.")) if - title.match(/\,/) + title.match(/,/) end # return title.html_safe to overcome escaping done by sanitiser def title - read_attribute(:title).try(:html_safe) + self[:title].try(:html_safe) end - validates_length_of :description, - allow_blank: true, - maximum: ArchiveConfig.SUMMARY_MAX, - too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.SUMMARY_MAX) + validates :description, + length: { allow_blank: true, + maximum: ArchiveConfig.SUMMARY_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.SUMMARY_MAX) } - validates_format_of :header_image_url, allow_blank: true, with: URI::regexp(%w(http https)), message: ts("is not a valid URL.") - validates_format_of :header_image_url, allow_blank: true, with: /\.(png|gif|jpg)$/, message: ts("can only point to a gif, jpg, or png file."), multiline: true + validates :header_image_url, format: { allow_blank: true, with: URI::DEFAULT_PARSER.make_regexp(%w[http https]), message: ts("is not a valid URL.") } + validates :header_image_url, format: { allow_blank: true, with: /\A\S+\.(png|gif|jpg)\z/, message: ts("can only point to a gif, jpg, or png file.") } validates :tags_after_saving, length: { maximum: ArchiveConfig.COLLECTION_TAGS_MAX, message: "^Sorry, a collection can only have %{count} tags." } scope :top_level, -> { where(parent_id: nil) } - scope :closed, -> { joins(:collection_preference).where("collection_preferences.closed = ?", true) } - scope :not_closed, -> { joins(:collection_preference).where("collection_preferences.closed = ?", false) } - scope :moderated, -> { joins(:collection_preference).where("collection_preferences.moderated = ?", true) } - scope :unmoderated, -> { joins(:collection_preference).where("collection_preferences.moderated = ?", false) } - scope :unrevealed, -> { joins(:collection_preference).where("collection_preferences.unrevealed = ?", true) } - scope :anonymous, -> { joins(:collection_preference).where("collection_preferences.anonymous = ?", true) } + scope :closed, -> { joins(:collection_preference).where(collection_preferences: { closed: true }) } + scope :not_closed, -> { joins(:collection_preference).where(collection_preferences: { closed: false }) } + scope :moderated, -> { joins(:collection_preference).where(collection_preferences: { moderated: true }) } + scope :unmoderated, -> { joins(:collection_preference).where(collection_preferences: { moderated: false }) } + scope :unrevealed, -> { joins(:collection_preference).where(collection_preferences: { unrevealed: true }) } + scope :anonymous, -> { joins(:collection_preference).where(collection_preferences: { anonymous: true }) } scope :no_challenge, -> { where(challenge_type: nil) } - scope :gift_exchange, -> { where(challenge_type: 'GiftExchange') } - scope :prompt_meme, -> { where(challenge_type: 'PromptMeme') } + scope :gift_exchange, -> { where(challenge_type: "GiftExchange") } + scope :prompt_meme, -> { where(challenge_type: "PromptMeme") } scope :name_only, -> { select("collections.name") } scope :by_title, -> { order(:title) } + scope :for_blurb, -> { includes(:parent, :moderators, :children, :collection_preference, owners: [:user]).with_attached_icon } - before_validation :cleanup_url def cleanup_url self.header_image_url = Addressable::URI.heuristic_parse(self.header_image_url) if self.header_image_url end # Get only collections with running challenges def self.signup_open(challenge_type) - if challenge_type == "PromptMeme" - not_closed.where(challenge_type: challenge_type). - joins("INNER JOIN prompt_memes on prompt_memes.id = challenge_id").where("prompt_memes.signup_open = 1"). - where("prompt_memes.signups_close_at > ?", Time.now).order("prompt_memes.signups_close_at DESC") - elsif challenge_type == "GiftExchange" - not_closed.where(challenge_type: challenge_type). - joins("INNER JOIN gift_exchanges on gift_exchanges.id = challenge_id").where("gift_exchanges.signup_open = 1"). - where("gift_exchanges.signups_close_at > ?", Time.now).order("gift_exchanges.signups_close_at DESC") + case challenge_type + when "PromptMeme" + not_closed.where(challenge_type: challenge_type) + .joins("INNER JOIN prompt_memes on prompt_memes.id = challenge_id").where("prompt_memes.signup_open = 1") + .where("prompt_memes.signups_close_at > ?", Time.zone.now).order("prompt_memes.signups_close_at DESC") + when "GiftExchange" + not_closed.where(challenge_type: challenge_type) + .joins("INNER JOIN gift_exchanges on gift_exchanges.id = challenge_id").where("gift_exchanges.signup_open = 1") + .where("gift_exchanges.signups_close_at > ?", Time.zone.now).order("gift_exchanges.signups_close_at DESC") end end - scope :with_name_like, lambda {|name| - where("collections.name LIKE ?", '%' + name + '%'). - limit(10) + scope :with_name_like, lambda { |name| + where("collections.name LIKE ?", "%#{name}%") + .limit(10) } - scope :with_title_like, lambda {|title| - where("collections.title LIKE ?", '%' + title + '%') + scope :with_title_like, lambda { |title| + where("collections.title LIKE ?", "%#{title}%") } - scope :with_item_count, -> { - select("collections.*, count(distinct collection_items.id) as item_count"). - joins("left join collections child_collections on child_collections.parent_id = collections.id + scope :with_item_count, lambda { + select("collections.*, count(distinct collection_items.id) as item_count") + .joins("left join collections child_collections on child_collections.parent_id = collections.id left join collection_items on ( (collection_items.collection_id = child_collections.id OR collection_items.collection_id = collections.id) AND collection_items.user_approval_status = 1 - AND collection_items.collection_approval_status = 1)"). - group("collections.id") + AND collection_items.collection_approval_status = 1)") + .group("collections.id") } def to_param - name_was + name_was end # Change membership of collection(s) from a particular pseud to the orphan account - def self.orphan(pseuds, collections, default=true) - for pseud in pseuds - for collection in collections + def self.orphan(pseuds, collections, default: true) + pseuds.each do |pseud| + collections.each do |collection| if pseud && collection && collection.owners.include?(pseud) orphan_pseud = default ? User.orphan_account.default_pseud : User.orphan_account.pseuds.find_or_create_by(name: pseud.name) pseud.change_membership(collection, orphan_pseud) @@ -237,8 +232,8 @@ def autocomplete_search_string_before_last_save end def autocomplete_prefixes - [ "autocomplete_collection_all", - "autocomplete_collection_#{closed? ? 'closed' : 'open'}" ] + ["autocomplete_collection_all", + "autocomplete_collection_#{closed? ? 'closed' : 'open'}"] end def autocomplete_score @@ -246,7 +241,6 @@ def autocomplete_score end ## END AUTOCOMPLETE - def parent_name=(name) @parent_name = name self.parent = Collection.find_by(name: name) @@ -285,31 +279,32 @@ def maintainers end def user_is_owner?(user) - user && user != :false && !(user.pseuds & self.all_owners).empty? + user && user != false && !(user.pseuds & self.all_owners).empty? end def user_is_moderator?(user) - user && user != :false && !(user.pseuds & self.all_moderators).empty? + user && user != false && !(user.pseuds & self.all_moderators).empty? end def user_is_maintainer?(user) - user && user != :false && !(user.pseuds & (self.all_moderators + self.all_owners)).empty? + user && user != false && !(user.pseuds & (self.all_moderators + self.all_owners)).empty? end def user_is_participant?(user) - user && user != :false && !get_participating_pseuds_for_user(user).empty? + user && user != false && !get_participating_pseuds_for_user(user).empty? end def user_is_posting_participant?(user) - user && user != :false && !(user.pseuds & self.all_posting_participants).empty? + user && user != false && !(user.pseuds & self.all_posting_participants).empty? end def get_participating_pseuds_for_user(user) - (user && user != :false) ? user.pseuds & self.all_participants : [] + (user && user != false) ? user.pseuds & self.all_participants : [] end def get_participants_for_user(user) return [] unless user + CollectionParticipant.in_collection(self).for_user(user) end @@ -321,28 +316,65 @@ def gift_notification self.collection_profile.gift_notification || (parent ? parent.collection_profile.gift_notification : "") end - def moderated? ; self.collection_preference.moderated ; end - def closed? ; self.collection_preference.closed ; end - def unrevealed? ; self.collection_preference.unrevealed ; end - def anonymous? ; self.collection_preference.anonymous ; end - def challenge? ; !self.challenge.nil? ; end + def moderated?() = self.collection_preference.moderated + + def closed?() = self.collection_preference.closed + + def unrevealed?() = self.collection_preference.unrevealed + + def anonymous?() = self.collection_preference.anonymous + + def challenge?() = !self.challenge.nil? def gift_exchange? - return self.challenge_type == "GiftExchange" + self.challenge_type == "GiftExchange" end + def prompt_meme? - return self.challenge_type == "PromptMeme" + self.challenge_type == "PromptMeme" end - def get_maintainers_email - return self.email if !self.email.blank? - return parent.email if parent && !parent.email.blank? - "#{self.maintainers.collect(&:user).flatten.uniq.collect(&:email).join(',')}" + def maintainers_list + self.maintainers.collect(&:user).flatten.uniq end - def notify_maintainers(subject, message) - # send maintainers a notice via email - UserMailer.collection_notification(self.id, subject, message).deliver_later + def collection_email + return self.email if self.email.present? + return parent.email if parent && parent.email.present? + end + + def notify_maintainers_assignments_sent + subject = I18n.t("user_mailer.collection_notification.assignments_sent.subject") + message = I18n.t("user_mailer.collection_notification.assignments_sent.complete") + if self.collection_email.present? + UserMailer.collection_notification(self.id, subject, message, self.collection_email).deliver_later + else + # if collection email is not set and collection parent email is not set, loop through maintainers and send each a notice via email + self.maintainers_list.each do |user| + I18n.with_locale(user.preference.locale.iso) do + translated_subject = I18n.t("user_mailer.collection_notification.assignments_sent.subject") + translated_message = I18n.t("user_mailer.collection_notification.assignments_sent.complete") + UserMailer.collection_notification(self.id, translated_subject, translated_message, user.email).deliver_later + end + end + end + end + + def notify_maintainers_challenge_default(challenge_assignment, assignments_page_url) + if self.collection_email.present? + subject = I18n.t("user_mailer.collection_notification.challenge_default.subject", offer_byline: challenge_assignment.offer_byline) + message = I18n.t("user_mailer.collection_notification.challenge_default.complete", offer_byline: challenge_assignment.offer_byline, request_byline: challenge_assignment.request_byline, assignments_page_url: assignments_page_url) + UserMailer.collection_notification(self.id, subject, message, self.collection_email).deliver_later + else + # if collection email is not set and collection parent email is not set, loop through maintainers and send each a notice via email + self.maintainers_list.each do |user| + I18n.with_locale(user.preference.locale.iso) do + translated_subject = I18n.t("user_mailer.collection_notification.challenge_default.subject", offer_byline: challenge_assignment.offer_byline) + translated_message = I18n.t("user_mailer.collection_notification.challenge_default.complete", offer_byline: challenge_assignment.offer_byline, request_byline: challenge_assignment.request_byline, assignments_page_url: assignments_page_url) + UserMailer.collection_notification(self.id, translated_subject, translated_message, user.email).deliver_later + end + end + end end include AsyncWithResque @@ -366,45 +398,49 @@ def reveal_collection_item_authors end def send_reveal_notifications - approved_collection_items.each {|collection_item| collection_item.notify_of_reveal} + approved_collection_items.each(&:notify_of_reveal) end def self.sorted_and_filtered(sort, filters, page) - pagination_args = {page: page} + pagination_args = { page: page } # build up the query with scopes based on the options the user specifies query = Collection.top_level - if !filters[:title].blank? + if filters[:title].present? # we get the matching collections out of autocomplete and use their ids ids = Collection.autocomplete_lookup(search_param: filters[:title], - autocomplete_prefix: (filters[:closed].blank? ? "autocomplete_collection_all" : (filters[:closed] ? "autocomplete_collection_closed" : "autocomplete_collection_open")) - ).map {|result| Collection.id_from_autocomplete(result)} - query = query.where("collections.id in (?)", ids) - else - query = (filters[:closed] == "true" ? query.closed : query.not_closed) if !filters[:closed].blank? + autocomplete_prefix: (if filters[:closed].blank? + "autocomplete_collection_all" + else + (filters[:closed] ? "autocomplete_collection_closed" : "autocomplete_collection_open") + end)).map { |result| Collection.id_from_autocomplete(result) } + query = query.where(collections: { id: ids }) + elsif filters[:closed].present? + query = (filters[:closed] == "true" ? query.closed : query.not_closed) end - query = (filters[:moderated] == "true" ? query.moderated : query.unmoderated) if !filters[:moderated].blank? + query = (filters[:moderated] == "true" ? query.moderated : query.unmoderated) if filters[:moderated].present? if filters[:challenge_type].present? - if filters[:challenge_type] == "gift_exchange" + case filters[:challenge_type] + when "gift_exchange" query = query.gift_exchange - elsif filters[:challenge_type] == "prompt_meme" + when "prompt_meme" query = query.prompt_meme - elsif filters[:challenge_type] == "no_challenge" + when "no_challenge" query = query.no_challenge end end - query = query.order(sort) + query = query.order(sort).for_blurb - if !filters[:fandom].blank? + if filters[:fandom].blank? + query.paginate(pagination_args) + else fandom = Fandom.find_by_name(filters[:fandom]) if fandom (fandom.approved_collections & query).paginate(pagination_args) else [] end - else - query.paginate(pagination_args) end end @@ -416,9 +452,13 @@ def delete_icon=(value) def delete_icon !!@delete_icon end - alias_method :delete_icon?, :delete_icon + alias delete_icon? delete_icon def clear_icon - self.icon = nil if delete_icon? && !icon.dirty? + return unless delete_icon? + + self.icon.purge + self.icon_alt_text = nil + self.icon_comment_text = nil end end diff --git a/app/models/comment.rb b/app/models/comment.rb index 40d30a3aa8d..4e56da9feef 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -85,7 +85,7 @@ def check_for_spam includes( pseud: { user: [:roles, :block_of_current_user, :block_by_current_user, :preference] }, parent: { work: [:pseuds, :users] } - ) + ).merge(Pseud.with_attached_icon) } # Gets methods and associations from acts_as_commentable plugin diff --git a/app/models/external_author.rb b/app/models/external_author.rb index 9e10c901c92..e70005a00a9 100644 --- a/app/models/external_author.rb +++ b/app/models/external_author.rb @@ -131,7 +131,9 @@ def block_import def notify_user_of_claim(claimed_work_ids) # send announcement to user of the stories they have been given - UserMailer.claim_notification(self.id, claimed_work_ids).deliver_later + I18n.with_locale(self.user.preference.locale.iso) do + UserMailer.claim_notification(self.user_id, claimed_work_ids).deliver_later + end end def find_or_invite(archivist = nil) diff --git a/app/models/feedback.rb b/app/models/feedback.rb index 66916140c9f..f13582d1d5d 100644 --- a/app/models/feedback.rb +++ b/app/models/feedback.rb @@ -1,8 +1,8 @@ # Class which holds feedback sent to the archive administrators about the archive as a whole class Feedback < ApplicationRecord - attr_accessor :ip_address + attr_accessor :ip_address, :referer, :site_skin - # note -- this has NOTHING to do with the Comment class! + # NOTE: this has NOTHING to do with the Comment class! # This is just the name of the text field in the Feedback # class which holds the user's comments. validates_presence_of :comment @@ -60,7 +60,8 @@ def rollout_string end def send_report - return unless %w(staging production).include?(Rails.env) + return unless zoho_enabled? + reporter = SupportReporter.new( title: summary, description: comment, @@ -69,8 +70,17 @@ def send_report username: username, user_agent: user_agent, site_revision: ArchiveConfig.REVISION.to_s, - rollout: rollout + rollout: rollout, + ip_address: ip_address, + referer: referer, + site_skin: site_skin ) reporter.send_report! end + + private + + def zoho_enabled? + %w[staging production].include?(Rails.env) + end end diff --git a/app/models/feedback_reporters/abuse_reporter.rb b/app/models/feedback_reporters/abuse_reporter.rb index 63196890b06..5a03b7e1bbe 100644 --- a/app/models/feedback_reporters/abuse_reporter.rb +++ b/app/models/feedback_reporters/abuse_reporter.rb @@ -1,6 +1,4 @@ class AbuseReporter < FeedbackReporter - attr_accessor :ip_address - def report_attributes super.deep_merge( "departmentId" => department_id, diff --git a/app/models/feedback_reporters/feedback_reporter.rb b/app/models/feedback_reporters/feedback_reporter.rb index fc1682061d0..c0cce2e20e1 100644 --- a/app/models/feedback_reporters/feedback_reporter.rb +++ b/app/models/feedback_reporters/feedback_reporter.rb @@ -13,7 +13,8 @@ class FeedbackReporter :language, :category, :username, - :url + :url, + :ip_address def initialize(attrs = {}) attrs.each_pair do |key, val| @@ -33,6 +34,13 @@ def send_report! zoho_resource_client.create_ticket(ticket_attributes: report_attributes) end + def send_attachment!(id, filename, download) + zoho_resource_client.create_ticket_attachment( + ticket_id: id, + attachment_attributes: attachment_attributes(filename, download) + ) + end + def report_attributes { "email" => email, @@ -44,6 +52,14 @@ def report_attributes } end + def attachment_attributes(filename, download) + attachment = StringIO.new(download) + # Workaround for HTTParty not recognizing StringIO as a file-like object: + # https://github.com/jnunemaker/httparty/issues/675#issuecomment-590757288 + attachment.define_singleton_method(:path) { filename } + { file: attachment } + end + private def zoho_contact_id diff --git a/app/models/feedback_reporters/support_reporter.rb b/app/models/feedback_reporters/support_reporter.rb index 572b2170c60..3c50eacf163 100644 --- a/app/models/feedback_reporters/support_reporter.rb +++ b/app/models/feedback_reporters/support_reporter.rb @@ -1,5 +1,5 @@ class SupportReporter < FeedbackReporter - attr_accessor :user_agent, :site_revision, :rollout + attr_accessor :user_agent, :referer, :rollout, :site_revision, :site_skin def report_attributes super.deep_merge( @@ -13,10 +13,17 @@ def report_attributes private def custom_zoho_fields + # To avoid issues where Zoho ticket creation silently fails, only grab the first + # 255 characters of the referer URL. That may miss some complex search queries, + # but still keep enough to be useful most of the time. + truncated_referer = referer.present? ? referer[0..254] : "Unknown URL" { "cf_archive_version" => site_revision.presence || "Unknown site revision", "cf_rollout" => rollout.presence || "Unknown", - "cf_user_agent" => user_agent.presence || "Unknown user agent" + "cf_user_agent" => user_agent.presence || "Unknown user agent", + "cf_ip" => ip_address.presence || "Unknown IP", + "cf_url" => truncated_referer, + "cf_site_skin" => site_skin&.public ? site_skin.title : "Custom skin" } end diff --git a/app/models/potential_match.rb b/app/models/potential_match.rb index 251e2da1503..0927aeb660c 100644 --- a/app/models/potential_match.rb +++ b/app/models/potential_match.rb @@ -1,5 +1,4 @@ class PotentialMatch < ApplicationRecord - # We use "-1" to represent all the requested items matching ALL = -1 @@ -12,26 +11,23 @@ class PotentialMatch < ApplicationRecord belongs_to :offer_signup, class_name: "ChallengeSignup" belongs_to :request_signup, class_name: "ChallengeSignup" -protected - + def self.progress_key(collection) - CACHE_PROGRESS_KEY + "#{collection.id}" + CACHE_PROGRESS_KEY + collection.id.to_s end def self.signup_key(collection) - CACHE_SIGNUP_KEY + "#{collection.id}" + CACHE_SIGNUP_KEY + collection.id.to_s end def self.interrupt_key(collection) - CACHE_INTERRUPT_KEY + "#{collection.id}" + CACHE_INTERRUPT_KEY + collection.id.to_s end def self.invalid_signup_key(collection) - CACHE_INVALID_SIGNUP_KEY + "#{collection.id}" + CACHE_INVALID_SIGNUP_KEY + collection.id.to_s end -public - def self.clear!(collection) # rapidly delete all potential prompt matches and potential matches # WITHOUT CALLBACKS @@ -89,10 +85,20 @@ def self.generate_in_background(collection_id) # check for invalid signups PotentialMatch.clear_invalid_signups(collection) - invalid_signup_ids = collection.signups.select {|s| !s.valid?}.collect(&:id) - unless invalid_signup_ids.empty? - invalid_signup_ids.each {|sid| REDIS_GENERAL.sadd invalid_signup_key(collection), sid} - UserMailer.invalid_signup_notification(collection.id, invalid_signup_ids).deliver_later + invalid_signup_ids = collection.signups.reject(&:valid?) + .collect(&:id) + if invalid_signup_ids.present? + invalid_signup_ids.each { |sid| REDIS_GENERAL.sadd invalid_signup_key(collection), sid } + + if collection.collection_email.present? + UserMailer.invalid_signup_notification(collection.id, invalid_signup_ids, collection.collection_email).deliver_later + else + collection.maintainers_list.each do |user| + I18n.with_locale(user.preference.locale.iso) do + UserMailer.invalid_signup_notification(collection.id, invalid_signup_ids, user.email).deliver_later + end + end + end PotentialMatch.cancel_generation(collection) else @@ -133,7 +139,7 @@ def self.generate_for_signup(collection, signup, settings, collection_tag_sets, potential_match = other_signup.match(signup, settings) end - potential_match.save if potential_match && potential_match.valid? + potential_match.save if potential_match&.valid? end end @@ -150,7 +156,7 @@ def self.matching_signup_ids(collection, signup, collection_tag_sets, required_t signup_tagsets = signup.send(prompt_type.pluralize).pluck(:tag_set_id, :optional_tag_set_id).flatten.compact # get the ids of all the tags of the required types in the signup's tagsets - signup_tags = SetTagging.where(tag_set_id: signup_tagsets).joins(:tag).where("tags.type IN (?)", required_types).pluck(:tag_id) + signup_tags = SetTagging.where(tag_set_id: signup_tagsets).joins(:tag).where(tags: { type: required_types }).pluck(:tag_id) if signup_tags.empty? # a match is required by the settings but the user hasn't put any of the required tags in, meaning they are open to anything @@ -162,9 +168,9 @@ def self.matching_signup_ids(collection, signup, collection_tag_sets, required_t # and now we look up any signups that have one of those tagsets in the opposite position -- ie, # if this signup is a request, we are looking for offers with the same tag; if it's an offer, we're # looking for requests with the same tag. - matching_signup_ids = (prompt_type == "request" ? Offer : Request). - where("tag_set_id IN (?) OR optional_tag_set_id IN (?)", match_tagsets, match_tagsets). - pluck(:challenge_signup_id).compact + matching_signup_ids = (prompt_type == "request" ? Offer : Request) + .where("tag_set_id IN (?) OR optional_tag_set_id IN (?)", match_tagsets, match_tagsets) + .pluck(:challenge_signup_id).compact # now add on "any" matches for the required types condition = case required_types.first.underscore @@ -204,14 +210,14 @@ def self.regenerate_for_signup_in_background(signup_id) # Get all the data settings = collection.challenge.potential_match_settings collection_tag_sets = Prompt.where(collection_id: collection.id).pluck(:tag_set_id, :optional_tag_set_id).flatten.compact - required_types = settings.required_types.map {|t| t.classify} + required_types = settings.required_types.map(&:classify) # clear the existing potential matches for this signup in each direction signup.offer_potential_matches.destroy_all signup.request_potential_matches.destroy_all # We check the signup in both directions -- as a request signup and as an offer signup - %w(request offer).each do |prompt_type| + %w[request offer].each do |prompt_type| PotentialMatch.generate_for_signup(collection, signup, settings, collection_tag_sets, required_types, prompt_type) end end @@ -254,21 +260,25 @@ def <=>(other) # start with seeing how many offers/requests match cmp = compare_all(self.num_prompts_matched, other.num_prompts_matched) - return cmp unless cmp == 0 + return cmp unless cmp.zero? # compare the "quality" of the best prompt match # (i.e. the number of matching tags between the most closely-matching # request prompt/offer prompt pair) cmp = compare_all(max_tags_matched, other.max_tags_matched) - return cmp unless cmp == 0 + return cmp unless cmp.zero? # if we're a match down to here just match on id - return self.id <=> other.id + self.id <=> other.id end -protected + protected + def compare_all(self_value, other_value) - self_value == ALL ? (other_value == ALL ? 0 : 1) : (other_value == ALL ? -1 : self_value <=> other_value) + if self_value == ALL + other_value == ALL ? 0 : 1 + else + (other_value == ALL ? -1 : self_value <=> other_value) + end end - end diff --git a/app/models/pseud.rb b/app/models/pseud.rb index ac298bc5fee..6dca5d7641b 100644 --- a/app/models/pseud.rb +++ b/app/models/pseud.rb @@ -3,24 +3,16 @@ class Pseud < ApplicationRecord include WorksOwner include Justifiable - has_attached_file :icon, - styles: { standard: "100x100>" }, - path: if Rails.env.production? - ":attachment/:id/:style.:extension" - elsif Rails.env.staging? - ":rails_env/:attachment/:id/:style.:extension" - else - ":rails_root/public/system/:rails_env/:class/:attachment/:id_partition/:style/:filename" - end, - storage: %w(staging production).include?(Rails.env) ? :s3 : :filesystem, - s3_protocol: "https", - default_url: "/images/skins/iconsets/default/icon_user.png" - - validates_attachment_content_type :icon, - content_type: %w[image/gif image/jpeg image/png], - allow_nil: true + has_one_attached :icon do |attachable| + attachable.variant(:standard, resize_to_limit: [100, 100]) + end - validates_attachment_size :icon, less_than: 500.kilobytes, allow_nil: true + # i18n-tasks-use t("errors.attributes.icon.invalid_format") + # i18n-tasks-use t("errors.attributes.icon.too_large") + validates :icon, attachment: { + allowed_formats: %w[image/gif image/jpeg image/png], + maximum_size: ArchiveConfig.ICON_SIZE_KB_MAX.kilobytes + } NAME_LENGTH_MIN = 1 NAME_LENGTH_MAX = 40 @@ -88,6 +80,7 @@ class Pseud < ApplicationRecord scope :alphabetical, -> { order(:name) } scope :default_alphabetical, -> { order(is_default: :desc).alphabetical } scope :abbreviated_list, -> { default_alphabetical.limit(ArchiveConfig.ITEMS_PER_PAGE) } + scope :for_search, -> { includes(:user).with_attached_icon } def self.not_orphaned where("user_id != ?", User.orphan_account) @@ -419,9 +412,10 @@ def delete_icon def clear_icon return unless delete_icon? - - self.icon = nil unless icon.dirty? + + self.icon.purge self.icon_alt_text = nil + self.icon_comment_text = nil end ################################# diff --git a/app/models/reading.rb b/app/models/reading.rb index 06366108d3c..08d1dca1886 100644 --- a/app/models/reading.rb +++ b/app/models/reading.rb @@ -5,6 +5,8 @@ class Reading < ApplicationRecord after_save :expire_cached_home_marked_for_later, if: :saved_change_to_toread? after_destroy :expire_cached_home_marked_for_later, if: :toread? + scope :visible, -> { left_joins(:work).merge(Work.visible_to_registered_user.or(Work.where(id: nil))) } + # called from show in work controller def self.update_or_create(work, user) if user && user.preference.try(:history_enabled) && !user.is_author_of?(work) diff --git a/app/models/redis_mail_queue.rb b/app/models/redis_mail_queue.rb index cd4d0958325..63a23045480 100644 --- a/app/models/redis_mail_queue.rb +++ b/app/models/redis_mail_queue.rb @@ -37,7 +37,9 @@ def self.deliver_kudos # queue the notification for delivery begin # don't die if we hit one deleted user - KudoMailer.batch_kudo_notification(author_id, user_kudos.to_json).deliver_later + I18n.with_locale(User.find(author_id).preference.locale.iso) do + KudoMailer.batch_kudo_notification(author_id, user_kudos.to_json).deliver_later + end rescue end end diff --git a/app/models/search/bookmark_indexer.rb b/app/models/search/bookmark_indexer.rb index cd4559fd6f9..996ebc36b61 100644 --- a/app/models/search/bookmark_indexer.rb +++ b/app/models/search/bookmark_indexer.rb @@ -11,7 +11,7 @@ def self.index_all(options = {}) unless options[:skip_delete] options[:skip_delete] = true BookmarkableIndexer.delete_index - BookmarkableIndexer.create_index(shards: 18) + BookmarkableIndexer.create_index(shards: ArchiveConfig.BOOKMARKABLE_SHARDS) create_mapping end BookmarkedExternalWorkIndexer.index_all(skip_delete: true) @@ -35,7 +35,7 @@ def self.mapping }, creators: { type: "text", - analyzer: "simple" + analyzer: "standard" }, work_types: { type: "keyword" @@ -45,7 +45,7 @@ def self.mapping }, bookmarker: { type: "text", - analyzer: "simple" + analyzer: "standard" }, tag: { type: "text", diff --git a/app/models/search/work_indexer.rb b/app/models/search/work_indexer.rb index 36978eef04c..c3b65eb135f 100644 --- a/app/models/search/work_indexer.rb +++ b/app/models/search/work_indexer.rb @@ -13,9 +13,9 @@ def self.klass_with_includes :stat_counter, :tags, :users, + :relationships, fandoms: { meta_tags: :meta_tags, merger: { meta_tags: :meta_tags } }, pseuds: :user, - relationships: :merger, serial_works: :series ) end @@ -23,7 +23,7 @@ def self.klass_with_includes def self.index_all(options = {}) unless options[:skip_delete] delete_index - create_index(shards: 12) + create_index(shards: ArchiveConfig.WORKS_SHARDS) end options[:skip_delete] = true super(options) @@ -38,7 +38,7 @@ def self.mapping }, title: { type: "text", - analyzer: "simple" + analyzer: "standard" }, creators: { type: "text" diff --git a/app/models/skin.rb b/app/models/skin.rb index 08e8576ae77..4f1355cbbb7 100755 --- a/app/models/skin.rb +++ b/app/models/skin.rb @@ -48,13 +48,16 @@ class Skin < ApplicationRecord accepts_nested_attributes_for :skin_parents, allow_destroy: true, reject_if: proc { |attrs| attrs[:position].blank? || (attrs[:parent_skin_title].blank? && attrs[:parent_skin_id].blank?) } - has_attached_file :icon, - styles: { standard: "100x100>" }, - url: "/system/:class/:attachment/:id/:style/:basename.:extension", - path: %w(staging production).include?(Rails.env) ? ":class/:attachment/:id/:style.:extension" : ":rails_root/public:url", - storage: %w(staging production).include?(Rails.env) ? :s3 : :filesystem, - s3_protocol: "https", - default_url: "/images/skins/iconsets/default/icon_skins.png" + has_one_attached :icon do |attachable| + attachable.variant(:standard, resize_to_limit: [100, 100]) + end + + # i18n-tasks-use t("errors.attributes.icon.invalid_format") + # i18n-tasks-use t("errors.attributes.icon.too_large") + validates :icon, attachment: { + allowed_formats: %r{image/\S+}, + maximum_size: ArchiveConfig.ICON_SIZE_KB_MAX.kilobytes + } after_save :skin_invalidate_cache def skin_invalidate_cache @@ -70,8 +73,6 @@ def skin_invalidate_cache end end - validates_attachment_content_type :icon, content_type: /image\/\S+/, allow_nil: true - validates_attachment_size :icon, less_than: 500.kilobytes, allow_nil: true validates_length_of :icon_alt_text, allow_blank: true, maximum: ArchiveConfig.ICON_ALT_MAX, too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_ALT_MAX) @@ -106,7 +107,7 @@ def valid_media validate :valid_public_preview def valid_public_preview - return true if (self.official? || !self.public? || self.icon_file_name) + return true if self.official? || !self.public? || self.icon.attached? errors.add(:base, :no_public_preview) end @@ -493,7 +494,7 @@ def self.load_site_css skin.ie_condition = skin_ie skin.unusable = true skin.official = true - File.open(version_dir + 'preview.png', 'rb') {|preview_file| skin.icon = preview_file} + skin.icon.attach(io: File.open("#{version_dir}preview.png", "rb"), content_type: "image/png", filename: "preview.png") skin.save!(validate: false) skins << skin end @@ -507,7 +508,7 @@ def self.load_site_css top_skin = Skin.new(title: "Archive #{version}", css: "", description: "Version #{version} of the default Archive style.", public: true, role: "site", media: ["screen"]) end - File.open(version_dir + 'preview.png', 'rb') {|preview_file| top_skin.icon = preview_file} + top_skin.icon.attach(io: File.open("#{version_dir}preview.png", "rb"), content_type: "image/png", filename: "preview.png") top_skin.official = true top_skin.save!(validate: false) skins.each_with_index do |skin, index| @@ -596,8 +597,6 @@ def set_thumbnail_from_current_version self.class.site_skins_dir + "preview.png" end - File.open(icon_path) do |icon_file| - self.icon = icon_file - end + self.icon.attach(io: File.open(icon_path), content_type: "image/png", filename: "preview.png") end end diff --git a/app/models/subscription.rb b/app/models/subscription.rb index c3b077cffbc..8ad19d7ff2d 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -11,7 +11,7 @@ class Subscription < ApplicationRecord # if there's an invalid subscribable type validates :subscribable, presence: true, if: proc { |s| VALID_SUBSCRIBABLES.include?(s.subscribable_type) } - + # Get the subscriptions associated with this work # currently: users subscribed to work, users subscribed to creator of work scope :for_work, lambda {|work| @@ -32,6 +32,8 @@ def name subscribable.name elsif subscribable.respond_to?(:title) subscribable.title + else + I18n.t("subscriptions.deleted") end end diff --git a/app/models/tag.rb b/app/models/tag.rb index ebbf35987a9..b8b694a5438 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -227,6 +227,21 @@ def flush_work_cache end end + # queue_flush_work_cache will update the cached work (bookmarkable) info for + # bookmarks, but we still need to expire the portion of bookmark blurbs that + # contains the bookmarker's tags. + after_update :queue_flush_bookmark_cache + def queue_flush_bookmark_cache + async_after_commit(:flush_bookmark_cache) if saved_change_to_name? + end + + def flush_bookmark_cache + self.bookmarks.each do |bookmark| + ActionController::Base.new.expire_fragment("bookmark-owner-blurb-#{bookmark.cache_key}-v2") + ActionController::Base.new.expire_fragment("bookmark-blurb-#{bookmark.cache_key}-v2") + end + end + before_save :set_last_wrangler def set_last_wrangler unless User.current_user.nil? @@ -1050,14 +1065,15 @@ def unwrangled? ################################# def unwrangled_query(tag_type, options = {}) - self_type = %w(Character Fandom Media).include?(self.type) ? self.type.downcase : "fandom" + self_type = %w[Character Fandom Media].include?(self.type) ? self.type.downcase : "fandom" TagQuery.new(options.merge( - type: tag_type, - unwrangleable: false, - wrangled: false, - "pre_#{self_type}_ids": [self.id], - per_page: Tag.per_page - )) + type: tag_type, + unwrangleable: false, + wrangled: false, + has_posted_works: true, + "pre_#{self_type}_ids": [self.id], + per_page: Tag.per_page + )) end def unwrangled_tags(tag_type, options = {}) @@ -1188,6 +1204,16 @@ def update_tag_nominations parent_names << "" if parent_names.present? TagNomination.where(tagname: name, parent_tagname: parent_names).update_all(parented: true) + + return unless saved_change_to_name? && name_before_last_save.present? + + # Act as if the tag with the previous name was deleted and mirror clear_tag_nominations + TagNomination.where(tagname: name_before_last_save).update_all( + canonical: false, + exists: false, + parented: false, + synonym: nil + ) end before_destroy :clear_tag_nominations diff --git a/app/models/tagset_models/cast_nomination.rb b/app/models/tagset_models/cast_nomination.rb index c06bd2f6dd8..4600934050a 100644 --- a/app/models/tagset_models/cast_nomination.rb +++ b/app/models/tagset_models/cast_nomination.rb @@ -3,7 +3,7 @@ class CastNomination < TagNomination has_one :owned_tag_set, through: :tag_set_nomination belongs_to :fandom_nomination - validate :known_fandom + validate :known_fandom, unless: :blank_tagname? def known_fandom return true if (!parent_tagname.blank? || self.fandom_nomination || from_fandom_nomination) return true if (tag = Tag.find_by_name(self.tagname)) && tag.parents.any? {|p| p.is_a?(Fandom)} diff --git a/app/models/tagset_models/tag_nomination.rb b/app/models/tagset_models/tag_nomination.rb index b0d14d29dc7..f6bcaaf69ba 100644 --- a/app/models/tagset_models/tag_nomination.rb +++ b/app/models/tagset_models/tag_nomination.rb @@ -13,11 +13,11 @@ class TagNomination < ApplicationRecord with: /\A[^,*<>^{}=`\\%]+\z/, message: ts("^Tag nominations cannot include the following restricted characters: , ^ * < > { } = ` \\ %") - validate :type_validity + validate :type_validity, unless: :blank_tagname? def type_validity - if !tagname.blank? && (tag = Tag.find_by_name(tagname)) && "#{tag.type}Nomination" != self.type - errors.add(:base, ts("^The tag %{tagname} is already in the archive as a #{tag.type} tag. (All tags have to be unique.) Try being more specific, for instance tacking on the medium or the fandom.", tagname: self.tagname)) - end + return unless (tag = Tag.find_by_name(tagname)) && "#{tag.type}Nomination" != self.type + + errors.add(:base, ts("^The tag %{tagname} is already in the archive as a #{tag.type} tag. (All tags have to be unique.) Try being more specific, for instance tacking on the medium or the fandom.", tagname: self.tagname)) end validate :not_already_reviewed, on: :update @@ -32,7 +32,7 @@ def not_already_reviewed end # This makes sure no tagnames are nominated for different parents in this tag set - validate :require_unique_tagname_with_parent + validate :require_unique_tagname_with_parent, unless: :blank_tagname? def require_unique_tagname_with_parent query = TagNomination.for_tag_set(get_owned_tag_set).where(tagname: self.tagname).where("parent_tagname != ?", (self.get_parent_tagname || '')) # let people change their own! @@ -43,18 +43,15 @@ def require_unique_tagname_with_parent end end - after_save :destroy_if_blank - def destroy_if_blank - if tagname.blank? - self.destroy - end - end - def get_owned_tag_set @tag_set || self.tag_set_nomination.owned_tag_set end - before_save :set_tag_status + def blank_tagname? + tagname.blank? + end + + before_save :set_tag_status, unless: :blank_tagname? def set_tag_status if (tag = Tag.find_by_name(tagname)) self.exists = true @@ -69,7 +66,7 @@ def set_tag_status true end - before_save :set_parented + before_save :set_parented, unless: :blank_tagname? def set_parented if type == "FreeformNomination" # skip freeforms @@ -88,7 +85,7 @@ def set_parented # sneaky bit: if the tag set moderator has already rejected or approved this tag, don't # show it to them again. - before_save :set_approval_status + before_save :set_approval_status, unless: :blank_tagname? def set_approval_status set_noms = tag_set_nomination set_noms = fandom_nomination.tag_set_nomination if !set_noms && from_fandom_nomination @@ -105,6 +102,11 @@ def set_approval_status true end + after_save :destroy_if_blank + def destroy_if_blank + self.destroy if blank_tagname? + end + def self.for_tag_set(tag_set) joins(tag_set_nomination: :owned_tag_set). where("owned_tag_sets.id = ?", tag_set.id) diff --git a/app/models/user.rb b/app/models/user.rb index 3d4e2dd89bb..47c6c6b3d04 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -89,6 +89,7 @@ class User < ApplicationRecord before_update :add_renamed_at, if: :will_save_change_to_login? after_update :update_pseud_name + after_update :send_wrangler_username_change_notification, if: :is_tag_wrangler? after_update :log_change_if_login_was_edited after_update :log_email_change, if: :saved_change_to_email? @@ -209,20 +210,12 @@ def unread_inbox_comments_count validates :email, email_format: true, uniqueness: true - # Virtual attribute for age check and terms of service - attr_accessor :age_over_13 - attr_accessor :terms_of_service - # attr_accessible :age_over_13, :terms_of_service + # Virtual attribute for age check, data processing agreement, and terms of service + attr_accessor :age_over_13, :data_processing, :terms_of_service - validates_acceptance_of :terms_of_service, - allow_nil: false, - message: ts("^Sorry, you need to accept the Terms of Service in order to sign up."), - if: :first_save? - - validates_acceptance_of :age_over_13, - allow_nil: false, - message: ts("^Sorry, you have to be over 13!"), - if: :first_save? + validates :data_processing, acceptance: { allow_nil: false, if: :first_save? } + validates :age_over_13, acceptance: { allow_nil: false, if: :first_save? } + validates :terms_of_service, acceptance: { allow_nil: false, if: :first_save? } def to_param login @@ -328,9 +321,18 @@ def prevent_password_resets? end protected - def first_save? - self.new_record? + + def first_save? + self.new_record? + end + + # Override of Devise method for email sending to set I18n.locale + # Based on https://github.com/heartcombo/devise/blob/v4.9.3/lib/devise/models/authenticatable.rb#L200 + def send_devise_notification(notification, *args) + I18n.with_locale(preference.locale.iso) do + devise_mailer.send(notification, self, *args).deliver_now end + end public @@ -569,6 +571,12 @@ def log_change_if_login_was_edited create_log_item(action: ArchiveConfig.ACTION_RENAME, note: "Old Username: #{login_before_last_save}; New Username: #{login}") if saved_change_to_login? end + def send_wrangler_username_change_notification + return unless saved_change_to_login? && login_before_last_save.present? + + TagWranglingSupervisorMailer.wrangler_username_change_notification(login_before_last_save, login).deliver_now + end + def log_email_change current_admin = User.current_user if User.current_user.is_a?(Admin) options = { diff --git a/app/models/work.rb b/app/models/work.rb index 06fe678cc48..0881823f956 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -1248,7 +1248,8 @@ def crossover def otp return true if relationships.size == 1 - all_without_syns = relationships.map { |r| r.merger ? r.merger : r }.uniq.compact + all_without_syns = relationships.map { |r| r.merger_id || r.id } + .uniq all_without_syns.count == 1 end diff --git a/app/models/work_skin.rb b/app/models/work_skin.rb index cb9dc0b3f4c..ff4e56b3a00 100644 --- a/app/models/work_skin.rb +++ b/app/models/work_skin.rb @@ -30,7 +30,11 @@ def self.basic_formatting def self.import_basic_formatting css = File.read(File.join(Rails.public_path, "/stylesheets/work_skins/basic_formatting.css")) skin = WorkSkin.find_or_create_by(title: "Basic Formatting", css: css, role: "user", public: true, official: true) - File.open(File.join(Rails.public_path, '/images/skins/previews/basic_formatting.png'), 'rb') {|preview_file| skin.icon = preview_file} + skin.icon.attach( + io: File.open(File.join(Rails.public_path, "/images/skins/previews/basic_formatting.png"), "rb"), + filename: "basic_formatting.png", + content_type: "image/png" + ) skin.official = true skin.save! skin diff --git a/app/policies/api_key_policy.rb b/app/policies/api_key_policy.rb new file mode 100644 index 00000000000..52640c39719 --- /dev/null +++ b/app/policies/api_key_policy.rb @@ -0,0 +1,14 @@ +class ApiKeyPolicy < ApplicationPolicy + PERMITTED_ROLES = %w[superadmin].freeze + + def index? + user_has_roles?(PERMITTED_ROLES) + end + + alias show? index? + alias new? index? + alias edit? index? + alias create? index? + alias update? index? + alias destroy? index? +end diff --git a/app/policies/archive_faq_policy.rb b/app/policies/archive_faq_policy.rb new file mode 100644 index 00000000000..87c8a7e9e3d --- /dev/null +++ b/app/policies/archive_faq_policy.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class ArchiveFaqPolicy < ApplicationPolicy + TRANSLATION_ACCESS_ROLES = %w[superadmin docs support translation].freeze + # a subset of TRANSLATION_ACCESS_ROLES + FULL_ACCESS_ROLES = %w[superadmin docs support].freeze + + def translation_access? + user_has_roles?(TRANSLATION_ACCESS_ROLES) + end + + def full_access? + user_has_roles?(FULL_ACCESS_ROLES) + end + + alias edit? translation_access? + alias update? translation_access? + alias new? full_access? + alias create? full_access? + alias manage? full_access? + alias update_positions? full_access? + alias confirm_delete? full_access? + alias destroy? full_access? +end diff --git a/app/policies/comment_policy.rb b/app/policies/comment_policy.rb index 52745bc7ccc..857219cee02 100644 --- a/app/policies/comment_policy.rb +++ b/app/policies/comment_policy.rb @@ -1,10 +1,10 @@ class CommentPolicy < ApplicationPolicy - DESTROY_COMMENT_ROLES = %w[superadmin board policy_and_abuse support].freeze - DESTROY_ADMIN_POST_COMMENT_ROLES = %w[superadmin board board_assistants_team communications elections policy_and_abuse support].freeze + DESTROY_COMMENT_ROLES = %w[superadmin board legal policy_and_abuse support].freeze + DESTROY_ADMIN_POST_COMMENT_ROLES = %w[superadmin board board_assistants_team communications elections legal policy_and_abuse support].freeze FREEZE_TAG_COMMENT_ROLES = %w[superadmin tag_wrangling].freeze FREEZE_WORK_COMMENT_ROLES = %w[superadmin policy_and_abuse].freeze - HIDE_TAG_COMMENT_ROLES = %w[superadmin tag_wrangling].freeze - HIDE_WORK_COMMENT_ROLES = %w[superadmin policy_and_abuse].freeze + HIDE_TAG_COMMENT_ROLES = %w[superadmin legal tag_wrangling].freeze + HIDE_WORK_COMMENT_ROLES = %w[superadmin legal policy_and_abuse].freeze SPAM_ADMIN_POST_COMMENT_ROLES = %w[superadmin board board_assistants_team communications elections policy_and_abuse support].freeze SPAM_COMMENT_ROLES = %w[superadmin board policy_and_abuse support].freeze @@ -48,11 +48,21 @@ def can_mark_comment_spam? end end + def can_review_comment? + record.ultimate_parent.is_a?(AdminPost) && user&.is_a?(Admin) + end + + def can_review_all? + record.is_a?(AdminPost) && user&.is_a?(Admin) + end + alias destroy? can_destroy_comment? alias approve? can_mark_comment_spam? alias reject? can_mark_comment_spam? + alias review? can_review_comment? + alias review_all? can_review_all? def show_email? - user_has_roles?(%w[policy_and_abuse support superadmin]) + user_has_roles?(%w[legal policy_and_abuse support superadmin]) end end diff --git a/app/policies/inbox_comment_policy.rb b/app/policies/inbox_comment_policy.rb new file mode 100644 index 00000000000..8ec7d755b38 --- /dev/null +++ b/app/policies/inbox_comment_policy.rb @@ -0,0 +1,7 @@ +class InboxCommentPolicy < ApplicationPolicy + VIEW_INBOX_ROLES = %w[superadmin policy_and_abuse].freeze + + def show? + user_has_roles?(VIEW_INBOX_ROLES) + end +end diff --git a/app/policies/known_issue_policy.rb b/app/policies/known_issue_policy.rb new file mode 100644 index 00000000000..a74de07e65b --- /dev/null +++ b/app/policies/known_issue_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class KnownIssuePolicy < ApplicationPolicy + MANAGE_ROLES = %w[superadmin support].freeze + + def admin_index? + user_has_roles?(MANAGE_ROLES) + end + + alias destroy? admin_index? + alias edit? admin_index? + alias create? admin_index? + alias new? admin_index? + alias show? admin_index? + alias update? admin_index? +end diff --git a/app/policies/language_policy.rb b/app/policies/language_policy.rb index a7e73ba94e0..37810ec1863 100644 --- a/app/policies/language_policy.rb +++ b/app/policies/language_policy.rb @@ -1,11 +1,35 @@ class LanguagePolicy < ApplicationPolicy - MANAGE_LANGUAGES = %w[superadmin translation].freeze + LANGUAGE_EDIT_ACCESS = %w[superadmin translation support policy_and_abuse].freeze + LANGUAGE_CREATE_ACCESS = %w[superadmin translation].freeze def new? - user_has_roles?(MANAGE_LANGUAGES) + user_has_roles?(LANGUAGE_CREATE_ACCESS) + end + + def edit? + user_has_roles?(LANGUAGE_EDIT_ACCESS) + end + + # Define which roles can update which attributes + ALLOWED_ATTRIBUTES_BY_ROLES = { + "superadmin" => %i[name short support_available abuse_support_available sortable_name], + "translation" => %i[name short support_available abuse_support_available sortable_name], + "support" => %i[name short support_available sortable_name], + "policy_and_abuse" => %i[abuse_support_available] + }.freeze + + def permitted_attributes + ALLOWED_ATTRIBUTES_BY_ROLES.values_at(*user.roles).compact.flatten + end + + def can_edit_abuse_fields? + user_has_roles?(%w[superadmin translation policy_and_abuse]) + end + + def can_edit_non_abuse_fields? + user_has_roles?(%w[superadmin translation support]) end alias create? new? - alias edit? new? - alias update? new? + alias update? edit? end diff --git a/app/policies/tag_wrangler_policy.rb b/app/policies/tag_wrangler_policy.rb deleted file mode 100644 index f71e9ac1839..00000000000 --- a/app/policies/tag_wrangler_policy.rb +++ /dev/null @@ -1,7 +0,0 @@ -class TagWranglerPolicy < ApplicationPolicy - WRANGLING_REPORT = %w[superadmin tag_wrangling].freeze - - def report_csv? - user_has_roles?(WRANGLING_REPORT) - end -end diff --git a/app/policies/user_creation_policy.rb b/app/policies/user_creation_policy.rb index 98746464c02..3eb5f8b247c 100644 --- a/app/policies/user_creation_policy.rb +++ b/app/policies/user_creation_policy.rb @@ -1,21 +1,23 @@ class UserCreationPolicy < ApplicationPolicy + FULL_ACCESS_ROLES = %w[superadmin legal policy_and_abuse].freeze + def show_admin_options? destroy? || hide? || edit? end def destroy? - user_has_roles?(%w[superadmin policy_and_abuse]) + user_has_roles?(FULL_ACCESS_ROLES) end def hide? - user_has_roles?(%w[superadmin policy_and_abuse]) + user_has_roles?(FULL_ACCESS_ROLES) end def show_ip_address? - user_has_roles?(%w[superadmin policy_and_abuse]) + user_has_roles?(FULL_ACCESS_ROLES) end def show_original_creators? - user_has_roles?(%w[superadmin policy_and_abuse]) + user_has_roles?(FULL_ACCESS_ROLES) end end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 9e8a9fa945b..614196a67fb 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -4,7 +4,7 @@ class UserPolicy < ApplicationPolicy # - managing a user's invitations # - updating a user's email and roles (e.g. wranglers, archivists, not admin roles) # This is further restricted using ALLOWED_ATTRIBUTES_BY_ROLES. - MANAGE_ROLES = %w[superadmin policy_and_abuse open_doors support tag_wrangling].freeze + MANAGE_ROLES = %w[superadmin legal policy_and_abuse open_doors support tag_wrangling].freeze # Roles that allow updating the Fannish Next Of Kin of a user. MANAGE_NEXT_OF_KIN_ROLES = %w[superadmin policy_and_abuse support].freeze @@ -12,6 +12,9 @@ class UserPolicy < ApplicationPolicy # Roles that allow deleting all of a spammer's creations. SPAM_CLEANUP_ROLES = %w[superadmin policy_and_abuse].freeze + # Roles that allow accessing a summary of a user's works and comments. + REVIEW_CREATIONS_ROLES = %w[superadmin policy_and_abuse].freeze + # Define which roles can update which attributes. ALLOWED_ATTRIBUTES_BY_ROLES = { "open_doors" => [roles: []], @@ -41,6 +44,10 @@ def can_destroy_spam_creations? user_has_roles?(SPAM_CLEANUP_ROLES) end + def can_access_creation_summary? + user_has_roles?(REVIEW_CREATIONS_ROLES) + end + def permitted_attributes ALLOWED_ATTRIBUTES_BY_ROLES.values_at(*user.roles).compact.flatten end @@ -59,6 +66,8 @@ def can_edit_user_role?(role) alias confirm_delete_user_creations? can_destroy_spam_creations? alias destroy_user_creations? can_destroy_spam_creations? + alias creations? can_access_creation_summary? + alias troubleshoot? can_manage_users? alias activate? can_manage_users? end diff --git a/app/policies/wrangling_policy.rb b/app/policies/wrangling_policy.rb new file mode 100644 index 00000000000..ba17ced729c --- /dev/null +++ b/app/policies/wrangling_policy.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class WranglingPolicy < ApplicationPolicy + FULL_ACCESS_ROLES = %w[superadmin tag_wrangling].freeze + READ_ACCESS_ROLES = (FULL_ACCESS_ROLES + %w[policy_and_abuse]).freeze + + def full_access? + user_has_roles?(FULL_ACCESS_ROLES) + end + + def read_access? + user_has_roles?(READ_ACCESS_ROLES) + end + + alias create? full_access? + alias destroy? full_access? + alias mass_update? full_access? + alias show? full_access? + alias report_csv? full_access? + alias new? full_access? + alias edit? full_access? + alias manage? full_access? + alias update? full_access? + alias update_positions? full_access? +end diff --git a/app/validators/attachment_validator.rb b/app/validators/attachment_validator.rb new file mode 100644 index 00000000000..79fa02601d5 --- /dev/null +++ b/app/validators/attachment_validator.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Custom validator to ensure that a field using ActiveStorage +# * matches the given formats, specified with regex or by a list (leave empty to allow any) +# * is less than the given maximum (if none is given, the default is 500kb) +class AttachmentValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + return unless value&.attached? + + allowed_formats = options[:allowed_formats] + maximum_size = options[:maximum_size] || 500.kilobytes + + case allowed_formats + when Regexp + record.errors.add(attribute, :invalid_format) unless allowed_formats.match?(value.content_type) + when Array + record.errors.add(attribute, :invalid_format) unless allowed_formats.include?(value.content_type) + end + + record.errors.add(attribute, :too_large, maximum_size: maximum_size.to_fs(:human_size)) unless value.blob.byte_size < maximum_size + + value.purge if record.errors[attribute].any? + end +end diff --git a/app/views/admin/_admin_nav.html.erb b/app/views/admin/_admin_nav.html.erb index 8ee535467a1..e705ea49bb8 100644 --- a/app/views/admin/_admin_nav.html.erb +++ b/app/views/admin/_admin_nav.html.erb @@ -1,15 +1,16 @@ -

<%= ts("Admin Navigation") %>

+

<%= t(".landmark") %>

diff --git a/app/views/admin/_header.html.erb b/app/views/admin/_header.html.erb index e2e16dca705..9c7ae29136f 100644 --- a/app/views/admin/_header.html.erb +++ b/app/views/admin/_header.html.erb @@ -27,15 +27,21 @@ <% if policy(AdminPost).can_post? %>
  • <%= link_to t(".nav.posts.post_news"), new_admin_post_path %>
  • <% end %> -
  • <%= link_to t(".nav.posts.faqs"), archive_faqs_path %>
  • -
  • <%= link_to t(".nav.posts.known_issues"), known_issues_path %>
  • -
  • <%= link_to t(".nav.posts.wrangling_guidelines"), wrangling_guidelines_path %>
  • + <% if policy(ArchiveFaq).translation_access? %> +
  • <%= link_to t(".nav.posts.faqs"), archive_faqs_path %>
  • + <% end %> + <% if policy(KnownIssue).admin_index? %> +
  • <%= link_to t(".nav.posts.known_issues"), known_issues_path %>
  • + <% end %> + <% if policy(:wrangling).new? %> +
  • <%= link_to t(".nav.posts.wrangling_guidelines"), wrangling_guidelines_path %>
  • + <% end %> <% if policy(AdminBlacklistedEmail).index? %>
  • <%= link_to t(".nav.banned_emails"), admin_blacklisted_emails_path %>
  • <% end %> - + <% if policy(ModeratedWork).index? %>
  • <%= link_to t(".nav.spam"), admin_spam_index_path %>
  • <% end %> @@ -58,8 +64,9 @@ <% end %> -
  • <%= link_to t(".nav.wrangling"), tag_wranglings_path %>
  • - + <% if policy(:wrangling).full_access? %> +
  • <%= link_to t(".nav.wrangling"), tag_wranglings_path %>
  • + <% end %> <% if policy(Locale).index? %>
  • <%= link_to t(".nav.locales"), locales_path %>
  • <% end %> @@ -68,6 +75,8 @@
  • <%= link_to t(".nav.activities"), admin_activities_path %>
  • <% end %> -
  • <%= link_to t(".nav.api_tokens"), admin_api_index_path %>
  • + <% if policy(ApiKey).index? %> +
  • <%= link_to t(".nav.api_tokens"), admin_api_index_path %>
  • + <% end %> diff --git a/app/views/admin/admin_users/_user_creations_summary.html.erb b/app/views/admin/admin_users/_user_creations_summary.html.erb new file mode 100644 index 00000000000..a69164a098e --- /dev/null +++ b/app/views/admin/admin_users/_user_creations_summary.html.erb @@ -0,0 +1,21 @@ +<% unless @user.works.empty? %> + <%# Checking @user.items.empty? rather than @items.empty? allows us to display +# an empty listbox with pagination if the admin manually enters the wrong URL. +# This is consistent with pagination on other site pages. %> +
    +

    <%= search_header(@works, nil, "Work") %>

    + <%= render "works/work_abbreviated_list", works: works %> + <%= will_paginate(works, param_name: "works_page", params: { anchor: "works-summary" }) %> +
    +<% end %> + +<% unless @user.comments.empty? %> + <%# We use comments rather than comment as the class because .comment:after +# create a clear that causes wonky styling when there are only a few +# comments. %> +
    +

    <%= search_header(@comments, nil, "Comment") %>

    + <%= render "comments/comment_abbreviated_list", comments: comments %> + <%= will_paginate(comments, param_name: "comments_page", params: { anchor: "comments-summary" }) %> +
    +<% end %> diff --git a/app/views/admin/admin_users/confirm_delete_user_creations.html.erb b/app/views/admin/admin_users/confirm_delete_user_creations.html.erb index e9eef3a5d05..9a40a8150e9 100644 --- a/app/views/admin/admin_users/confirm_delete_user_creations.html.erb +++ b/app/views/admin/admin_users/confirm_delete_user_creations.html.erb @@ -1,35 +1,17 @@ - -

    <%= ts("Delete Spammer Creations") %>

    +

    <%= t(".page_heading") %>

    <%= form_tag destroy_user_creations_admin_user_path(@user), method: :post, class: "simple destroy" do %>

    - <%= ts("Are you sure you want to delete all the works and comments created by this user, - along with their %{bookmarks} bookmarks, %{series} series, and %{collections} collections? This cannot be undone.", - bookmarks: @bookmarks.size, series: @series.size, collections: @collections.size).html_safe %> + <%= t(".caution_html", bookmarks: @bookmarks.size, series: @series.size, collections: @collections.size) %>

    - <% unless @works.size.zero? %> -
    -

    <%= ts("Works")%> (<%= @works.size %>)

    - <%= render "works/work_abbreviated_list", works: @works %> - <%= will_paginate(@works, param_name: 'works_page') %> -
    - <% end %> - - <% unless @comments.size.zero? %> -
    -

    <%= ts("Comments")%> (<%= @comments.size %>)

    - <%= render "comments/comment_abbreviated_list", comments: @comments %> - <%= will_paginate(@comments, :param_name => 'comments_page') %> -
    - <% end %> + <%= render "user_creations_summary", works: @works, comments: @comments %>

    - <%= submit_tag ts("Yes, Delete All Spammer Creations"), - data: { confirm: ts("Are you sure? Remember this will destroy ALL these objects!") } %> + <%= submit_tag t(".submit"), data: { confirm: t(".confirm") } %>

    <% end %> diff --git a/app/views/admin/admin_users/creations.html.erb b/app/views/admin/admin_users/creations.html.erb new file mode 100644 index 00000000000..9ac8030f7ae --- /dev/null +++ b/app/views/admin/admin_users/creations.html.erb @@ -0,0 +1,24 @@ +
    + +

    <%= t(".page_heading", user: @user.login) %>

    + + + + + + + + <% if @user.works.empty? && @user.comments.empty? %> +

    <%= t(".no_creations") %>

    + <% else %> + <%= render "user_creations_summary", works: @works, comments: @comments %> + <% end %> + +
    diff --git a/app/views/admin/admin_users/show.html.erb b/app/views/admin/admin_users/show.html.erb index c7295c244a9..6ca6c957f47 100644 --- a/app/views/admin/admin_users/show.html.erb +++ b/app/views/admin/admin_users/show.html.erb @@ -4,7 +4,7 @@ -