From db8d4c4773740eb989a01eaa2b901ab5cbe61a48 Mon Sep 17 00:00:00 2001 From: Kira Date: Sat, 24 Oct 2020 05:47:20 -0700 Subject: [PATCH] Normalize EOL style + newline at end of files. --- .../admin/exceptions_controller.rb | 26 +- app/controllers/blips_controller.rb | 232 ++--- app/controllers/edit_histories_controller.rb | 28 +- app/controllers/emails_controller.rb | 90 +- .../post_report_reasons_controller.rb | 104 +- .../tag_type_versions_controller.rb | 18 +- app/decorators/paginated_decorator.rb | 6 +- app/helpers/ticket_helper.rb | 24 +- app/javascript/src/javascripts/uploader.js | 24 +- .../src/javascripts/uploader_checkbox.vue | 48 +- .../src/javascripts/uploader_preview.vue | 140 +-- .../src/javascripts/uploader_related.vue | 178 ++-- .../src/styles/base/_functions.scss | 6 +- app/javascript/src/styles/common/voting.scss | 6 +- .../src/styles/specific/admin_dashboards.scss | 2 +- .../src/styles/specific/maintenance.scss | 2 +- .../src/styles/specific/meta_searches.scss | 2 +- .../src/styles/specific/user_deletions.scss | 2 +- app/jobs/iqdb_remove_job.rb | 18 +- app/jobs/iqdb_update_job.rb | 18 +- app/jobs/tag_alias_undo_job.rb | 16 +- app/jobs/transfer_favorites_job.rb | 36 +- app/logical/admin_route_constraint.rb | 14 +- app/logical/bulk_related_tag_query.rb | 100 +- app/logical/danbooru/has_bit_flags.rb | 2 +- app/logical/email_link_validator.rb | 44 +- app/logical/pbkdf2.rb | 160 ++-- app/logical/rate_limiter.rb | 48 +- app/logical/sources/alternates.rb | 26 +- app/logical/sources/alternates/furaffinity.rb | 46 +- app/logical/sources/alternates/null.rb | 14 +- app/logical/sources/strategies/pixiv_slim.rb | 140 +-- app/logical/tag_category.rb | 182 ++-- app/logical/tags_preview.rb | 82 +- app/logical/user_throttle.rb | 158 ++-- .../user/email_confirmation_mailer.rb | 28 +- app/models/edit_history.rb | 28 +- app/models/post_report_reason.rb | 2 +- app/models/post_set_maintainer.rb | 298 +++--- app/models/tag_type_version.rb | 58 +- app/models/user_status.rb | 14 +- app/views/admin/dashboards/_aliases.html.erb | 1 + app/views/admin/exceptions/index.html.erb | 60 +- app/views/admin/exceptions/show.html.erb | 32 +- app/views/admin/users/edit_blacklist.html.erb | 18 +- app/views/admin/users/password_reset.html.erb | 24 +- .../users/request_password_reset.html.erb | 42 +- app/views/blips/_form.html.erb | 22 +- app/views/blips/_quick_search.html.erb | 6 +- app/views/blips/partials/index/_list.html.erb | 20 +- app/views/edit_histories/index.html.erb | 74 +- app/views/edit_histories/show.html.erb | 52 +- app/views/email_blacklists/_search.html.erb | 12 +- app/views/iqdb_queries/show.html+xhr.erb | 2 +- .../moderator/ip_addrs/_ip_listing.json.erb | 2 +- app/views/moderator/ip_addrs/_search.html.erb | 20 +- .../moderator/ip_addrs/_user_listing.json.erb | 2 +- app/views/post_report_reasons/edit.html.erb | 32 +- app/views/post_sets/_add_dialog.html.erb | 24 +- .../partials/common/_anon_blacklist.html.erb | 14 +- app/views/static/_guest_warning.html.erb | 40 +- app/views/static/error.atom.erb | 1 + app/views/static/too_many_requests.html.erb | 2 +- app/views/tag_type_versions/index.html.erb | 80 +- app/views/tickets/_secondary_links.html.erb | 22 +- app/views/tickets/new.html.erb | 132 +-- app/views/tickets/new_types/_blip.html.erb | 24 +- app/views/tickets/new_types/_comment.html.erb | 26 +- app/views/tickets/new_types/_dmail.html.erb | 26 +- app/views/tickets/new_types/_forum.html.erb | 24 +- .../tickets/new_types/_namechange.html.erb | 36 +- app/views/tickets/new_types/_pool.html.erb | 28 +- app/views/tickets/new_types/_set.html.erb | 24 +- app/views/tickets/new_types/_user.html.erb | 16 +- app/views/tickets/new_types/_wiki.html.erb | 24 +- app/views/tickets/types/_blip.html.erb | 26 +- app/views/tickets/types/_comment.html.erb | 28 +- app/views/tickets/types/_dmail.html.erb | 26 +- app/views/tickets/types/_namechange.html.erb | 1 + app/views/tickets/types/_pool.html.erb | 12 +- app/views/tickets/types/_set.html.erb | 12 +- app/views/tickets/types/_user.html.erb | 16 +- app/views/upload_whitelists/_search.html.erb | 14 +- app/views/upload_whitelists/edit.html.erb | 44 +- app/views/users/upload_limit.html.erb | 88 +- config/deploy/production.rb | 2 +- config/docker/compose.yml | 2 +- config/docker/danbooru-base | 2 +- config/initializers/elasticsearch.rb | 2 +- config/initializers/mailgun.rb | 6 +- config/initializers/mechanize_patch.rb | 2 +- config/initializers/serialization_method.rb | 2 +- config/initializers/sidekiq.rb | 18 +- config/secrets.yml | 2 +- config/unicorn/staging.rb | 2 +- db/seeds.yml | 892 +++++++++--------- script/fixes/101_migrate_mod_actions.rb | 28 +- test/factories/upload_whitelist.rb | 8 +- .../user/deletions_controller_test.rb | 2 +- .../user/email_changes_controller_test.rb | 2 +- 100 files changed, 2338 insertions(+), 2335 deletions(-) diff --git a/app/controllers/admin/exceptions_controller.rb b/app/controllers/admin/exceptions_controller.rb index 106feaf70..48de5f0a4 100644 --- a/app/controllers/admin/exceptions_controller.rb +++ b/app/controllers/admin/exceptions_controller.rb @@ -1,13 +1,13 @@ -module Admin - class ExceptionsController < ApplicationController - before_action :admin_only - - def index - @exception_logs = ExceptionLog.order(id: :desc).paginate(params[:page], limit: 100) - end - - def show - @exception_log = ExceptionLog.find(params[:id]) - end - end -end +module Admin + class ExceptionsController < ApplicationController + before_action :admin_only + + def index + @exception_logs = ExceptionLog.order(id: :desc).paginate(params[:page], limit: 100) + end + + def show + @exception_log = ExceptionLog.find(params[:id]) + end + end +end diff --git a/app/controllers/blips_controller.rb b/app/controllers/blips_controller.rb index c9efb2f87..d8d599df4 100644 --- a/app/controllers/blips_controller.rb +++ b/app/controllers/blips_controller.rb @@ -1,116 +1,116 @@ -class BlipsController < ApplicationController - class BlipTooOld < Exception ; end - respond_to :html, :json - before_action :member_only, only: [:create, :new, :update, :edit, :hide] - before_action :moderator_only, only: [:unhide, :destroy] - - rescue_from BlipTooOld, with: :blip_too_old - - def index - @blips = Blip.visible.search(search_params).paginate(params[:page], limit: params[:limit]) - respond_with(@blips) - end - - def show - @blip = Blip.find(params[:id]) - check_privilege(@blip) - @parent = @blip.response_to - @children = Blip.visible.where('response_to = ?', @blip.id).paginate(params[:page]) - respond_with(@blip) - end - - def edit - @blip = Blip.find(params[:id]) - check_edit_privilege(@blip) - respond_with(@blip) - end - - def update - @blip = Blip.find(params[:id]) - check_edit_privilege(@blip) - Blip.transaction do - @blip.update(blip_params(:update)) - ModAction.log(:blip_update, {blip_id: @blip.id, user_id: @blip.creator_id}) - end - flash[:notice] = 'Blip updated' - respond_with(@blip) - end - - def hide - @blip = Blip.find(params[:id]) - check_hide_privilege(@blip) - - Blip.transaction do - @blip.update(is_hidden: true) - ModAction.log(:blip_hide, {blip_id: @blip.id, user_id: @blip.creator_id}) - end - respond_with(@blip) - end - - def unhide - @blip = Blip.find(params[:id]) - Blip.transaction do - @blip.update(is_hidden: false) - ModAction.log(:blip_unhide, {blip_id: @blip.id, user_id: @blip.creator_id}) - end - respond_with(@blip) - end - - def destroy - @blip = Blip.find(params[:id]) - - ModAction.log(:blip_delete, {blip_id: @blip.id, user_id: @blip.creator_id}) - @blip.destroy - flash[:notice] = 'Blip deleted' - respond_with(@blip) do |format| - format.html do - redirect_back(fallback_location: blip_path(id: @blip.response_to)) - end - end - end - - def new - @blip = Blip.new - end - - def create - @blip = Blip.create(blip_params(:create)) - - flash[:notice] = @blip.valid? ? "Blip posted" : @blip.errors.full_messages.join("; ") - respond_with(@blip) do |format| - format.html do - redirect_back(fallback_location: blips_path) - end - end - end - - private - - def search_params - params.fetch(:search, {}).permit! - end - - def blip_params(mode) - allowed = [:body] - allowed << :response_to if mode == :create - params.require(:blip).permit(allowed) - end - - def blip_too_old - redirect_back(fallback_location: blips_path, flash: {notice: 'You cannot edit blips more than 5 minutes old'}) - end - - def check_privilege(blip) - raise User::PrivilegeError unless blip.visible_to?(CurrentUser.user) - end - - def check_hide_privilege(blip) - raise User::PrivilegeError unless blip.can_hide?(CurrentUser.user) - end - - def check_edit_privilege(blip) - return if CurrentUser.is_moderator? - raise User::PrivilegeError if blip.creator_id != CurrentUser.id - raise BlipTooOld if blip.created_at < 5.minutes.ago - end -end +class BlipsController < ApplicationController + class BlipTooOld < Exception ; end + respond_to :html, :json + before_action :member_only, only: [:create, :new, :update, :edit, :hide] + before_action :moderator_only, only: [:unhide, :destroy] + + rescue_from BlipTooOld, with: :blip_too_old + + def index + @blips = Blip.visible.search(search_params).paginate(params[:page], limit: params[:limit]) + respond_with(@blips) + end + + def show + @blip = Blip.find(params[:id]) + check_privilege(@blip) + @parent = @blip.response_to + @children = Blip.visible.where('response_to = ?', @blip.id).paginate(params[:page]) + respond_with(@blip) + end + + def edit + @blip = Blip.find(params[:id]) + check_edit_privilege(@blip) + respond_with(@blip) + end + + def update + @blip = Blip.find(params[:id]) + check_edit_privilege(@blip) + Blip.transaction do + @blip.update(blip_params(:update)) + ModAction.log(:blip_update, {blip_id: @blip.id, user_id: @blip.creator_id}) + end + flash[:notice] = 'Blip updated' + respond_with(@blip) + end + + def hide + @blip = Blip.find(params[:id]) + check_hide_privilege(@blip) + + Blip.transaction do + @blip.update(is_hidden: true) + ModAction.log(:blip_hide, {blip_id: @blip.id, user_id: @blip.creator_id}) + end + respond_with(@blip) + end + + def unhide + @blip = Blip.find(params[:id]) + Blip.transaction do + @blip.update(is_hidden: false) + ModAction.log(:blip_unhide, {blip_id: @blip.id, user_id: @blip.creator_id}) + end + respond_with(@blip) + end + + def destroy + @blip = Blip.find(params[:id]) + + ModAction.log(:blip_delete, {blip_id: @blip.id, user_id: @blip.creator_id}) + @blip.destroy + flash[:notice] = 'Blip deleted' + respond_with(@blip) do |format| + format.html do + redirect_back(fallback_location: blip_path(id: @blip.response_to)) + end + end + end + + def new + @blip = Blip.new + end + + def create + @blip = Blip.create(blip_params(:create)) + + flash[:notice] = @blip.valid? ? "Blip posted" : @blip.errors.full_messages.join("; ") + respond_with(@blip) do |format| + format.html do + redirect_back(fallback_location: blips_path) + end + end + end + + private + + def search_params + params.fetch(:search, {}).permit! + end + + def blip_params(mode) + allowed = [:body] + allowed << :response_to if mode == :create + params.require(:blip).permit(allowed) + end + + def blip_too_old + redirect_back(fallback_location: blips_path, flash: {notice: 'You cannot edit blips more than 5 minutes old'}) + end + + def check_privilege(blip) + raise User::PrivilegeError unless blip.visible_to?(CurrentUser.user) + end + + def check_hide_privilege(blip) + raise User::PrivilegeError unless blip.can_hide?(CurrentUser.user) + end + + def check_edit_privilege(blip) + return if CurrentUser.is_moderator? + raise User::PrivilegeError if blip.creator_id != CurrentUser.id + raise BlipTooOld if blip.created_at < 5.minutes.ago + end +end diff --git a/app/controllers/edit_histories_controller.rb b/app/controllers/edit_histories_controller.rb index d96114178..0ca891666 100644 --- a/app/controllers/edit_histories_controller.rb +++ b/app/controllers/edit_histories_controller.rb @@ -1,14 +1,14 @@ -class EditHistoriesController < ApplicationController - respond_to :html - before_action :moderator_only - - def index - @edit_history = EditHistory.includes(:user).paginate(params[:page], limit: params[:limit]) - respond_with(@edit_history) - end - - def show - @edits = EditHistoryDecorator.decorate_collection(EditHistory.includes(:user).where('versionable_id = ? AND versionable_type = ?', params[:id], params[:type]).order(:id)) - respond_with(@edits) - end -end \ No newline at end of file +class EditHistoriesController < ApplicationController + respond_to :html + before_action :moderator_only + + def index + @edit_history = EditHistory.includes(:user).paginate(params[:page], limit: params[:limit]) + respond_with(@edit_history) + end + + def show + @edits = EditHistoryDecorator.decorate_collection(EditHistory.includes(:user).where('versionable_id = ? AND versionable_type = ?', params[:id], params[:type]).order(:id)) + respond_with(@edits) + end +end diff --git a/app/controllers/emails_controller.rb b/app/controllers/emails_controller.rb index fa552c062..6ec2d93da 100644 --- a/app/controllers/emails_controller.rb +++ b/app/controllers/emails_controller.rb @@ -1,45 +1,45 @@ -class EmailsController < ApplicationController - respond_to :html - - def resend_confirmation - if IpBan.is_banned? CurrentUser.ip_addr - redirect_to home_users_path, notice: "An error occurred trying to send an activation email" - return - end - - raise User::PrivilegeError.new("Must be logged in to resend verification email.") if CurrentUser.is_anonymous? - raise User::PrivilegeError.new("Account already active.") if CurrentUser.is_verified? - raise User::PrivilegeError.new('Cannot send confirmation because the email is not allowed.') if EmailBlacklist.is_banned?(CurrentUser.user.email) - if RateLimiter.check_limit("emailconfirm:#{CurrentUser.id}", 1, 12.hours) - raise User::PrivilegeError.new("Confirmation email sent too recently. Please wait at least 12 hours between sends.") - end - RateLimiter.hit("emailconfirm:#{CurrentUser.id}", 12.hours) - - - Maintenance::User::EmailConfirmationMailer.confirmation(CurrentUser.user).deliver_now - redirect_to home_users_path, notice: "Activation email resent" - end - - def activate_user - if IpBan.is_banned? CurrentUser.ip_addr - redirect_to home_users_path, notice: 'An error occurred trying to activate your account' - return - end - - user = verify_get_user(:activate) - raise User::PrivilegeError.new('Account cannot be activated because the email is not allowed.') if EmailBlacklist.is_banned?(user.email) - raise User::PrivilegeError.new('Account already activated.') if user.is_verified? - - user.mark_verified! - - redirect_to home_users_path, notice: "Account activated" - end - - private - - def verify_get_user(purpose) - message = EmailLinkValidator.validate(params[:sig], purpose) - raise User::PrivilegeError.new("Invalid activation link.") if message.blank? || !message - User.find(message.to_i) - end -end +class EmailsController < ApplicationController + respond_to :html + + def resend_confirmation + if IpBan.is_banned? CurrentUser.ip_addr + redirect_to home_users_path, notice: "An error occurred trying to send an activation email" + return + end + + raise User::PrivilegeError.new("Must be logged in to resend verification email.") if CurrentUser.is_anonymous? + raise User::PrivilegeError.new("Account already active.") if CurrentUser.is_verified? + raise User::PrivilegeError.new('Cannot send confirmation because the email is not allowed.') if EmailBlacklist.is_banned?(CurrentUser.user.email) + if RateLimiter.check_limit("emailconfirm:#{CurrentUser.id}", 1, 12.hours) + raise User::PrivilegeError.new("Confirmation email sent too recently. Please wait at least 12 hours between sends.") + end + RateLimiter.hit("emailconfirm:#{CurrentUser.id}", 12.hours) + + + Maintenance::User::EmailConfirmationMailer.confirmation(CurrentUser.user).deliver_now + redirect_to home_users_path, notice: "Activation email resent" + end + + def activate_user + if IpBan.is_banned? CurrentUser.ip_addr + redirect_to home_users_path, notice: 'An error occurred trying to activate your account' + return + end + + user = verify_get_user(:activate) + raise User::PrivilegeError.new('Account cannot be activated because the email is not allowed.') if EmailBlacklist.is_banned?(user.email) + raise User::PrivilegeError.new('Account already activated.') if user.is_verified? + + user.mark_verified! + + redirect_to home_users_path, notice: "Account activated" + end + + private + + def verify_get_user(purpose) + message = EmailLinkValidator.validate(params[:sig], purpose) + raise User::PrivilegeError.new("Invalid activation link.") if message.blank? || !message + User.find(message.to_i) + end +end diff --git a/app/controllers/post_report_reasons_controller.rb b/app/controllers/post_report_reasons_controller.rb index 09bda19e0..c5cf30d1e 100644 --- a/app/controllers/post_report_reasons_controller.rb +++ b/app/controllers/post_report_reasons_controller.rb @@ -1,52 +1,52 @@ -class PostReportReasonsController < ApplicationController - respond_to :html - before_action :admin_only - - - def index - @reasons = PostReportReason.order('id DESC') - respond_with(@reasons) - end - - def new - @reason = PostReportReason.new - end - - def destroy - @reason = PostReportReason.find(params[:id]) - PostReportReason.transaction do - @reason.destroy - ModAction.log(:report_reason_delete, {reason: @reason.reason, user_id: @reason.creator_id}) - end - respond_with(@reason) - end - - def create - PostReportReason.transaction do - @reason = PostReportReason.create(reason_params) - ModAction.log(:report_reason_create, {reason: @reason.reason}) - end - flash[:notice] = @reason.valid? ? "Post report reason created" : @reason.errors.full_messages.join("; ") - redirect_to post_report_reasons_path - end - - def edit - @reason = PostReportReason.find(params[:id]) - end - - def update - @reason = PostReportReason.find(params[:id]) - PostReportReason.transaction do - @reason.update(reason_params) - ModAction.log(:report_reason_update, {reason: @reason.reason, reason_was: @reason.reason_before_last_save}) if @reason.valid? - end - flash[:notice] = @reason.valid? ? 'Post report reason updated' : @reason.errors.full_messages.join('; ') - redirect_to post_report_reasons_path - end - - private - - def reason_params - params.require(:post_report_reason).permit(%i[reason description]) - end -end \ No newline at end of file +class PostReportReasonsController < ApplicationController + respond_to :html + before_action :admin_only + + + def index + @reasons = PostReportReason.order('id DESC') + respond_with(@reasons) + end + + def new + @reason = PostReportReason.new + end + + def destroy + @reason = PostReportReason.find(params[:id]) + PostReportReason.transaction do + @reason.destroy + ModAction.log(:report_reason_delete, {reason: @reason.reason, user_id: @reason.creator_id}) + end + respond_with(@reason) + end + + def create + PostReportReason.transaction do + @reason = PostReportReason.create(reason_params) + ModAction.log(:report_reason_create, {reason: @reason.reason}) + end + flash[:notice] = @reason.valid? ? "Post report reason created" : @reason.errors.full_messages.join("; ") + redirect_to post_report_reasons_path + end + + def edit + @reason = PostReportReason.find(params[:id]) + end + + def update + @reason = PostReportReason.find(params[:id]) + PostReportReason.transaction do + @reason.update(reason_params) + ModAction.log(:report_reason_update, {reason: @reason.reason, reason_was: @reason.reason_before_last_save}) if @reason.valid? + end + flash[:notice] = @reason.valid? ? 'Post report reason updated' : @reason.errors.full_messages.join('; ') + redirect_to post_report_reasons_path + end + + private + + def reason_params + params.require(:post_report_reason).permit(%i[reason description]) + end +end diff --git a/app/controllers/tag_type_versions_controller.rb b/app/controllers/tag_type_versions_controller.rb index 460bf18e9..13a1d2a43 100644 --- a/app/controllers/tag_type_versions_controller.rb +++ b/app/controllers/tag_type_versions_controller.rb @@ -1,9 +1,9 @@ -class TagTypeVersionsController < ApplicationController - respond_to :html, :jso - - def index - @tag_versions = TagTypeVersion.search(params[:search]).paginate(params[:page], limit: params[:limit]) - - respond_with(@tag_versions) - end -end +class TagTypeVersionsController < ApplicationController + respond_to :html, :jso + + def index + @tag_versions = TagTypeVersion.search(params[:search]).paginate(params[:page], limit: params[:limit]) + + respond_with(@tag_versions) + end +end diff --git a/app/decorators/paginated_decorator.rb b/app/decorators/paginated_decorator.rb index b43738639..c3f562531 100644 --- a/app/decorators/paginated_decorator.rb +++ b/app/decorators/paginated_decorator.rb @@ -1,3 +1,3 @@ -class PaginatedDecorator < Draper::CollectionDecorator - delegate :current_page, :total_pages, :is_first_page?, :is_last_page?, :sequential_paginator_mode, :records, :total_count -end \ No newline at end of file +class PaginatedDecorator < Draper::CollectionDecorator + delegate :current_page, :total_pages, :is_first_page?, :is_last_page?, :sequential_paginator_mode, :records, :total_count +end diff --git a/app/helpers/ticket_helper.rb b/app/helpers/ticket_helper.rb index 1be94c689..05fb440c3 100644 --- a/app/helpers/ticket_helper.rb +++ b/app/helpers/ticket_helper.rb @@ -1,12 +1,12 @@ -module TicketHelper - def pretty_ticket_status(ticket) - status = ticket.status - if status == "partial" - "Under Investigation" - elsif status == "approved" - "Investigated" - else - status.titleize - end - end -end \ No newline at end of file +module TicketHelper + def pretty_ticket_status(ticket) + status = ticket.status + if status == "partial" + "Under Investigation" + elsif status == "approved" + "Investigated" + else + status.titleize + end + end +end diff --git a/app/javascript/src/javascripts/uploader.js b/app/javascript/src/javascripts/uploader.js index 42fcb3cc9..58272b64e 100644 --- a/app/javascript/src/javascripts/uploader.js +++ b/app/javascript/src/javascripts/uploader.js @@ -1,12 +1,12 @@ -import Uploader from './uploader.vue'; -import Vue from 'vue'; - -export default { - init() { - const app = new Vue({ - render: (h) => h(Uploader) - }); - - app.$mount('#uploader'); - } -} +import Uploader from './uploader.vue'; +import Vue from 'vue'; + +export default { + init() { + const app = new Vue({ + render: (h) => h(Uploader) + }); + + app.$mount('#uploader'); + } +} diff --git a/app/javascript/src/javascripts/uploader_checkbox.vue b/app/javascript/src/javascripts/uploader_checkbox.vue index 4554a8022..890fede97 100644 --- a/app/javascript/src/javascripts/uploader_checkbox.vue +++ b/app/javascript/src/javascripts/uploader_checkbox.vue @@ -1,24 +1,24 @@ - - - + + + diff --git a/app/javascript/src/javascripts/uploader_preview.vue b/app/javascript/src/javascripts/uploader_preview.vue index 7a51b5bc7..2e890a0c8 100644 --- a/app/javascript/src/javascripts/uploader_preview.vue +++ b/app/javascript/src/javascripts/uploader_preview.vue @@ -1,70 +1,70 @@ - - - + + + diff --git a/app/javascript/src/javascripts/uploader_related.vue b/app/javascript/src/javascripts/uploader_related.vue index 687eda064..12888125c 100644 --- a/app/javascript/src/javascripts/uploader_related.vue +++ b/app/javascript/src/javascripts/uploader_related.vue @@ -1,89 +1,89 @@ - - - + + + diff --git a/app/javascript/src/styles/base/_functions.scss b/app/javascript/src/styles/base/_functions.scss index a362686de..40ff10a31 100644 --- a/app/javascript/src/styles/base/_functions.scss +++ b/app/javascript/src/styles/base/_functions.scss @@ -1,3 +1,3 @@ -@function border_color($color) { - @return darken($color, 25%); -} +@function border_color($color) { + @return darken($color, 25%); +} diff --git a/app/javascript/src/styles/common/voting.scss b/app/javascript/src/styles/common/voting.scss index 54fc05529..7863718e4 100644 --- a/app/javascript/src/styles/common/voting.scss +++ b/app/javascript/src/styles/common/voting.scss @@ -1,3 +1,3 @@ -.comment-vote-down-link, .comment-vote-up-link, .post-vote-up-link, .post-vote-down-link { - cursor: pointer; -} +.comment-vote-down-link, .comment-vote-up-link, .post-vote-up-link, .post-vote-down-link { + cursor: pointer; +} diff --git a/app/javascript/src/styles/specific/admin_dashboards.scss b/app/javascript/src/styles/specific/admin_dashboards.scss index aa59f308d..96325d482 100644 --- a/app/javascript/src/styles/specific/admin_dashboards.scss +++ b/app/javascript/src/styles/specific/admin_dashboards.scss @@ -2,4 +2,4 @@ .section { margin-bottom: 2em; } -} \ No newline at end of file +} diff --git a/app/javascript/src/styles/specific/maintenance.scss b/app/javascript/src/styles/specific/maintenance.scss index 196cbe2c7..300f58e97 100644 --- a/app/javascript/src/styles/specific/maintenance.scss +++ b/app/javascript/src/styles/specific/maintenance.scss @@ -2,4 +2,4 @@ div#c-maintenance-user-login-reminders { div#a-new { width: 50em; } -} \ No newline at end of file +} diff --git a/app/javascript/src/styles/specific/meta_searches.scss b/app/javascript/src/styles/specific/meta_searches.scss index 98133734d..5304ec234 100644 --- a/app/javascript/src/styles/specific/meta_searches.scss +++ b/app/javascript/src/styles/specific/meta_searches.scss @@ -2,4 +2,4 @@ section { margin-bottom: 2em; } -} \ No newline at end of file +} diff --git a/app/javascript/src/styles/specific/user_deletions.scss b/app/javascript/src/styles/specific/user_deletions.scss index b09d9c9ed..9455fcefb 100644 --- a/app/javascript/src/styles/specific/user_deletions.scss +++ b/app/javascript/src/styles/specific/user_deletions.scss @@ -7,4 +7,4 @@ div#c-maintenance-user-deletions { li { list-style-type: disc; } -} \ No newline at end of file +} diff --git a/app/jobs/iqdb_remove_job.rb b/app/jobs/iqdb_remove_job.rb index 874440366..e23cc9e50 100644 --- a/app/jobs/iqdb_remove_job.rb +++ b/app/jobs/iqdb_remove_job.rb @@ -1,9 +1,9 @@ -class IqdbRemoveJob - include Sidekiq::Worker - - sidekiq_options queue: 'iqdb' - - def perform(post_id) - # STUB: The implementation of this is performed by the iqdb component. - end -end +class IqdbRemoveJob + include Sidekiq::Worker + + sidekiq_options queue: 'iqdb' + + def perform(post_id) + # STUB: The implementation of this is performed by the iqdb component. + end +end diff --git a/app/jobs/iqdb_update_job.rb b/app/jobs/iqdb_update_job.rb index 954bab8e7..62688867a 100644 --- a/app/jobs/iqdb_update_job.rb +++ b/app/jobs/iqdb_update_job.rb @@ -1,9 +1,9 @@ -class IqdbUpdateJob - include Sidekiq::Worker - - sidekiq_options queue: 'iqdb' - - def perform(post_id, thumbnail_url) - # STUB: The implementation of this is performed by the iqdb component. - end -end +class IqdbUpdateJob + include Sidekiq::Worker + + sidekiq_options queue: 'iqdb' + + def perform(post_id, thumbnail_url) + # STUB: The implementation of this is performed by the iqdb component. + end +end diff --git a/app/jobs/tag_alias_undo_job.rb b/app/jobs/tag_alias_undo_job.rb index 0351d019e..bb1380dac 100644 --- a/app/jobs/tag_alias_undo_job.rb +++ b/app/jobs/tag_alias_undo_job.rb @@ -1,8 +1,8 @@ -class TagAliasUndoJob < ApplicationJob - queue_as :tags - - def perform(*args) - ta = TagAlias.find(args[0]) - ta.process_undo!(update_topic: args[1]) - end -end +class TagAliasUndoJob < ApplicationJob + queue_as :tags + + def perform(*args) + ta = TagAlias.find(args[0]) + ta.process_undo!(update_topic: args[1]) + end +end diff --git a/app/jobs/transfer_favorites_job.rb b/app/jobs/transfer_favorites_job.rb index 5b9bbaa10..99901f3bb 100644 --- a/app/jobs/transfer_favorites_job.rb +++ b/app/jobs/transfer_favorites_job.rb @@ -1,18 +1,18 @@ -class TransferFavoritesJob < ApplicationJob - queue_as :low_prio - - def perform(*args) - without_mod_action = args[2] - @post = Post.find_by(id: args[0]) - @user = User.find_by(id: args[1]) - unless @post && @user - # Something went wrong and there is nothing we can do inside the job. - return - end - - CurrentUser.as(@user) do - @post.give_favorites_to_parent!(without_mod_action: without_mod_action) - end - end - -end +class TransferFavoritesJob < ApplicationJob + queue_as :low_prio + + def perform(*args) + without_mod_action = args[2] + @post = Post.find_by(id: args[0]) + @user = User.find_by(id: args[1]) + unless @post && @user + # Something went wrong and there is nothing we can do inside the job. + return + end + + CurrentUser.as(@user) do + @post.give_favorites_to_parent!(without_mod_action: without_mod_action) + end + end + +end diff --git a/app/logical/admin_route_constraint.rb b/app/logical/admin_route_constraint.rb index 46c930b8d..c123212ff 100644 --- a/app/logical/admin_route_constraint.rb +++ b/app/logical/admin_route_constraint.rb @@ -1,7 +1,7 @@ -class AdminRouteConstraint - def matches?(request) - return false unless request.session[:user_id] - user = User.find(request.session[:user_id]) - user && user.is_admin? - end -end +class AdminRouteConstraint + def matches?(request) + return false unless request.session[:user_id] + user = User.find(request.session[:user_id]) + user && user.is_admin? + end +end diff --git a/app/logical/bulk_related_tag_query.rb b/app/logical/bulk_related_tag_query.rb index a774842e0..4d38ac321 100644 --- a/app/logical/bulk_related_tag_query.rb +++ b/app/logical/bulk_related_tag_query.rb @@ -1,50 +1,50 @@ -class BulkRelatedTagQuery - include ActiveModel::Serializers::JSON - include ActiveModel::Serializers::Xml - - attr_reader :query, :category, :user - - def initialize(query: nil, category: nil, user: nil) - @user = user - @query = Tag.normalize_query(query).split(' ').slice(0, 25) - @category = category - end - - def tags - if category.present? - related_tags_by_category - elsif query.present? - related_tags - else - {} - end - end - - def serializable_hash(**options) - tags - end - - protected - - def related_tags - @related_tags ||= Tag.where(name: @query).each_with_object({}) do |tag, hash| - related = tag.related_tag_array - categories = Tag.categories_for(related.map(&:first)) - - hash[tag.name] = related.map {|name, count| [name, count.to_i, categories.fetch(name, -1)]} - end - end - - def related_tags_by_category - @related_tags_by_category ||= begin - cat = Tag.categories.value_for(category) - - @query.each_with_object({}) do |tag, hash| - related = RelatedTagCalculator.calculate_from_sample_to_array(tag, cat) - categories = Tag.categories_for(related.map(&:first)) - - hash[tag] = related.map {|name, count| [name, count.to_i, categories.fetch(name, -1)]} - end - end - end -end +class BulkRelatedTagQuery + include ActiveModel::Serializers::JSON + include ActiveModel::Serializers::Xml + + attr_reader :query, :category, :user + + def initialize(query: nil, category: nil, user: nil) + @user = user + @query = Tag.normalize_query(query).split(' ').slice(0, 25) + @category = category + end + + def tags + if category.present? + related_tags_by_category + elsif query.present? + related_tags + else + {} + end + end + + def serializable_hash(**options) + tags + end + + protected + + def related_tags + @related_tags ||= Tag.where(name: @query).each_with_object({}) do |tag, hash| + related = tag.related_tag_array + categories = Tag.categories_for(related.map(&:first)) + + hash[tag.name] = related.map {|name, count| [name, count.to_i, categories.fetch(name, -1)]} + end + end + + def related_tags_by_category + @related_tags_by_category ||= begin + cat = Tag.categories.value_for(category) + + @query.each_with_object({}) do |tag, hash| + related = RelatedTagCalculator.calculate_from_sample_to_array(tag, cat) + categories = Tag.categories_for(related.map(&:first)) + + hash[tag] = related.map {|name, count| [name, count.to_i, categories.fetch(name, -1)]} + end + end + end +end diff --git a/app/logical/danbooru/has_bit_flags.rb b/app/logical/danbooru/has_bit_flags.rb index 66ec54008..6e7fa2ce7 100644 --- a/app/logical/danbooru/has_bit_flags.rb +++ b/app/logical/danbooru/has_bit_flags.rb @@ -36,4 +36,4 @@ module Danbooru end end end -end \ No newline at end of file +end diff --git a/app/logical/email_link_validator.rb b/app/logical/email_link_validator.rb index cb91eac22..25f461f3a 100644 --- a/app/logical/email_link_validator.rb +++ b/app/logical/email_link_validator.rb @@ -1,22 +1,22 @@ -class EmailLinkValidator - def self.generate(message, purpose, expires = nil) - - validator.generate(message, purpose: purpose, expires_in: expires) - end - - def self.validate(hash, purpose) - begin - message = validator.verify(hash, purpose: purpose) - return false if message.nil? - return message - rescue - return false - end - end - - private - - def self.validator - @validator ||= ActiveSupport::MessageVerifier.new(Danbooru.config.email_key, serializer: JSON, hash: "SHA256") - end -end +class EmailLinkValidator + def self.generate(message, purpose, expires = nil) + + validator.generate(message, purpose: purpose, expires_in: expires) + end + + def self.validate(hash, purpose) + begin + message = validator.verify(hash, purpose: purpose) + return false if message.nil? + return message + rescue + return false + end + end + + private + + def self.validator + @validator ||= ActiveSupport::MessageVerifier.new(Danbooru.config.email_key, serializer: JSON, hash: "SHA256") + end +end diff --git a/app/logical/pbkdf2.rb b/app/logical/pbkdf2.rb index f4ce4cae3..f5d7b903a 100644 --- a/app/logical/pbkdf2.rb +++ b/app/logical/pbkdf2.rb @@ -1,80 +1,80 @@ -# Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm). -# Copyright (c) 2013, Taylor Hornby -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -require 'securerandom' -require 'openssl' -require 'base64' - -module Pbkdf2 - - PBKDF2_ITERATIONS = 20000 - SALT_BYTE_SIZE = 24 - HASH_BYTE_SIZE = 24 - - HASH_SECTIONS = 4 - SECTION_DELIMITER = ':' - ITERATIONS_INDEX = 1 - SALT_INDEX = 2 - HASH_INDEX = 3 - - def self.create_hash( password ) - salt = SecureRandom.base64( SALT_BYTE_SIZE ) - pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac_sha1( - password, - salt, - PBKDF2_ITERATIONS, - HASH_BYTE_SIZE - ) - return ["sha1", PBKDF2_ITERATIONS, salt, Base64.encode64( pbkdf2 )].join( SECTION_DELIMITER ) - end - - def self.validate_password( password, correctHash ) - params = correctHash.split( SECTION_DELIMITER ) - return false if params.length != HASH_SECTIONS - - pbkdf2 = Base64.decode64( params[HASH_INDEX] ) - testHash = OpenSSL::PKCS5::pbkdf2_hmac_sha1( - password, - params[SALT_INDEX], - params[ITERATIONS_INDEX].to_i, - pbkdf2.length - ) - - return pbkdf2 == testHash - end - - def self.needs_upgrade( hash ) - params = hash.split( SECTION_DELIMITER ) - if params.length != HASH_SECTIONS - return true - end - if params[ITERATIONS_INDEX] != PBKDF2_ITERATIONS.to_s - return true - end - return false - end - -end +# Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm). +# Copyright (c) 2013, Taylor Hornby +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +require 'securerandom' +require 'openssl' +require 'base64' + +module Pbkdf2 + + PBKDF2_ITERATIONS = 20000 + SALT_BYTE_SIZE = 24 + HASH_BYTE_SIZE = 24 + + HASH_SECTIONS = 4 + SECTION_DELIMITER = ':' + ITERATIONS_INDEX = 1 + SALT_INDEX = 2 + HASH_INDEX = 3 + + def self.create_hash( password ) + salt = SecureRandom.base64( SALT_BYTE_SIZE ) + pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac_sha1( + password, + salt, + PBKDF2_ITERATIONS, + HASH_BYTE_SIZE + ) + return ["sha1", PBKDF2_ITERATIONS, salt, Base64.encode64( pbkdf2 )].join( SECTION_DELIMITER ) + end + + def self.validate_password( password, correctHash ) + params = correctHash.split( SECTION_DELIMITER ) + return false if params.length != HASH_SECTIONS + + pbkdf2 = Base64.decode64( params[HASH_INDEX] ) + testHash = OpenSSL::PKCS5::pbkdf2_hmac_sha1( + password, + params[SALT_INDEX], + params[ITERATIONS_INDEX].to_i, + pbkdf2.length + ) + + return pbkdf2 == testHash + end + + def self.needs_upgrade( hash ) + params = hash.split( SECTION_DELIMITER ) + if params.length != HASH_SECTIONS + return true + end + if params[ITERATIONS_INDEX] != PBKDF2_ITERATIONS.to_s + return true + end + return false + end + +end diff --git a/app/logical/rate_limiter.rb b/app/logical/rate_limiter.rb index 70bf9dd8c..0c1126137 100644 --- a/app/logical/rate_limiter.rb +++ b/app/logical/rate_limiter.rb @@ -1,24 +1,24 @@ -class RateLimiter - def self.check_limit(key, max_attempts, lockout_time = 1.minute) - return true if Cache.get("#{key}:lockout") - - attempts = Cache.get(key) || 0 - if attempts >= max_attempts - Cache.put("#{key}:lockout", true, lockout_time) - reset_limit(key) - return true - end - false - end - - def self.hit(key, time_period = 1.minute) - value = Cache.get(key) || 0 - Cache.put(key, value.to_i + 1, time_period) - return value.to_i + 1 - end - - def self.reset_limit(key) - Cache.delete(key) - end - -end +class RateLimiter + def self.check_limit(key, max_attempts, lockout_time = 1.minute) + return true if Cache.get("#{key}:lockout") + + attempts = Cache.get(key) || 0 + if attempts >= max_attempts + Cache.put("#{key}:lockout", true, lockout_time) + reset_limit(key) + return true + end + false + end + + def self.hit(key, time_period = 1.minute) + value = Cache.get(key) || 0 + Cache.put(key, value.to_i + 1, time_period) + return value.to_i + 1 + end + + def self.reset_limit(key) + Cache.delete(key) + end + +end diff --git a/app/logical/sources/alternates.rb b/app/logical/sources/alternates.rb index f185634b3..1119bba5c 100644 --- a/app/logical/sources/alternates.rb +++ b/app/logical/sources/alternates.rb @@ -1,13 +1,13 @@ -module Sources - module Alternates - def self.all - return [Alternates::Furaffinity, - Alternates::Pixiv] - end - - def self.find(url, default: Alternates::Null) - alternate = all.map {|alternate| alternate.new(url)}.detect(&:match?) - alternate || default&.new(url) - end - end -end \ No newline at end of file +module Sources + module Alternates + def self.all + return [Alternates::Furaffinity, + Alternates::Pixiv] + end + + def self.find(url, default: Alternates::Null) + alternate = all.map {|alternate| alternate.new(url)}.detect(&:match?) + alternate || default&.new(url) + end + end +end diff --git a/app/logical/sources/alternates/furaffinity.rb b/app/logical/sources/alternates/furaffinity.rb index 7608c1b07..ad66caff3 100644 --- a/app/logical/sources/alternates/furaffinity.rb +++ b/app/logical/sources/alternates/furaffinity.rb @@ -1,23 +1,23 @@ -module Sources - module Alternates - class Furaffinity < Base - IMAGE_TO_ARTIST = /facdn\.net\/art\/([0-9a-zA-Z_.~\-]+)/ - SUBMISSION_URL = /furaffinity\.net\/view\/(\d+)/ - - def force_https? - true - end - - def domains - ["furaffinity.net", "facdn.net"] - end - - def parse - if @url =~ IMAGE_TO_ARTIST - @gallery_url = "https://www.furaffinity.net/user/#{$1}/" - @direct_url = @url - end - end - end - end -end +module Sources + module Alternates + class Furaffinity < Base + IMAGE_TO_ARTIST = /facdn\.net\/art\/([0-9a-zA-Z_.~\-]+)/ + SUBMISSION_URL = /furaffinity\.net\/view\/(\d+)/ + + def force_https? + true + end + + def domains + ["furaffinity.net", "facdn.net"] + end + + def parse + if @url =~ IMAGE_TO_ARTIST + @gallery_url = "https://www.furaffinity.net/user/#{$1}/" + @direct_url = @url + end + end + end + end +end diff --git a/app/logical/sources/alternates/null.rb b/app/logical/sources/alternates/null.rb index 4e5d5b7e6..498e2aec9 100644 --- a/app/logical/sources/alternates/null.rb +++ b/app/logical/sources/alternates/null.rb @@ -1,7 +1,7 @@ -module Sources - module Alternates - class Null < Base - - end - end -end \ No newline at end of file +module Sources + module Alternates + class Null < Base + + end + end +end diff --git a/app/logical/sources/strategies/pixiv_slim.rb b/app/logical/sources/strategies/pixiv_slim.rb index fc3699070..55f515f83 100644 --- a/app/logical/sources/strategies/pixiv_slim.rb +++ b/app/logical/sources/strategies/pixiv_slim.rb @@ -1,70 +1,70 @@ -# Pixiv -# -# * https://i.pximg.net/img-original/img/2014/10/03/18/10/20/46324488_p0.png -# -# * https://i.pximg.net/c/250x250_80_a2/img-master/img/2014/10/29/09/27/19/46785915_p0_square1200.jpg -# * https://i.pximg.net/img-master/img/2014/10/03/18/10/20/46324488_p0_master1200.jpg -# -# * https://www.pixiv.net/member_illust.php?mode=medium&illust_id=46324488 -# * https://www.pixiv.net/member_illust.php?mode=manga&illust_id=46324488 -# * https://www.pixiv.net/member_illust.php?mode=manga_big&illust_id=46324488&page=0 -# -# * https://www.pixiv.net/member.php?id=339253 -# * https://www.pixiv.net/member_illust.php?id=339253&type=illust -# * https://www.pixiv.net/u/9202877 -# * https://www.pixiv.net/stacc/noizave -# * http://www.pixiv.me/noizave -# -# Fanbox -# -# * https://fanbox.pixiv.net/images/post/39714/JvjJal8v1yLgc5DPyEI05YpT.png -# * https://pixiv.pximg.net/fanbox/public/images/creator/1566167/profile/Ix6bnJmTaOAFZhXHLbWyIY1e.jpeg -# -# * https://pixiv.pximg.net/c/400x400_90_a2_g5/fanbox/public/images/creator/1566167/profile/Ix6bnJmTaOAFZhXHLbWyIY1e.jpeg -# * https://pixiv.pximg.net/c/1200x630_90_a2_g5/fanbox/public/images/post/186919/cover/VCI1Mcs2rbmWPg0mmiTisovn.jpeg -# -# * https://www.pixiv.net/fanbox/creator/1566167/post/39714 -# * https://www.pixiv.net/fanbox/creator/1566167 -# -# Novels -# -# * https://i.pximg.net/novel-cover-original/img/2019/01/14/01/15/05/10617324_d84daae89092d96bbe66efafec136e42.jpg -# * https://i.pximg.net/c/600x600/novel-cover-master/img/2019/01/14/01/15/05/10617324_d84daae89092d96bbe66efafec136e42_master1200.jpg -# * https://img-novel.pximg.net/img-novel/work_main/XtFbt7gsymsvyaG45lZ8/1554.jpg?20190107110435 -# -# * https://www.pixiv.net/novel/show.php?id=10617324 -# * https://novel.pixiv.net/works/1554 -# -# Sketch -# -# * https://img-sketch.pixiv.net/uploads/medium/file/4463372/8906921629213362989.jpg -# * https://img-sketch.pximg.net/c!/w=540,f=webp:jpeg/uploads/medium/file/4463372/8906921629213362989.jpg -# * https://sketch.pixiv.net/items/1588346448904706151 -# * https://sketch.pixiv.net/@0125840 -# - -module Sources - module Strategies - class PixivSlim < Base - def domains - ["pixiv.net", "pximg.net"] - end - - def site_name - "Pixiv" - end - - def canonical_url - image_url - end - - def image_urls - [url] - end - - def headers - { "Referer" => "https://www.pixiv.net"} - end - end - end -end +# Pixiv +# +# * https://i.pximg.net/img-original/img/2014/10/03/18/10/20/46324488_p0.png +# +# * https://i.pximg.net/c/250x250_80_a2/img-master/img/2014/10/29/09/27/19/46785915_p0_square1200.jpg +# * https://i.pximg.net/img-master/img/2014/10/03/18/10/20/46324488_p0_master1200.jpg +# +# * https://www.pixiv.net/member_illust.php?mode=medium&illust_id=46324488 +# * https://www.pixiv.net/member_illust.php?mode=manga&illust_id=46324488 +# * https://www.pixiv.net/member_illust.php?mode=manga_big&illust_id=46324488&page=0 +# +# * https://www.pixiv.net/member.php?id=339253 +# * https://www.pixiv.net/member_illust.php?id=339253&type=illust +# * https://www.pixiv.net/u/9202877 +# * https://www.pixiv.net/stacc/noizave +# * http://www.pixiv.me/noizave +# +# Fanbox +# +# * https://fanbox.pixiv.net/images/post/39714/JvjJal8v1yLgc5DPyEI05YpT.png +# * https://pixiv.pximg.net/fanbox/public/images/creator/1566167/profile/Ix6bnJmTaOAFZhXHLbWyIY1e.jpeg +# +# * https://pixiv.pximg.net/c/400x400_90_a2_g5/fanbox/public/images/creator/1566167/profile/Ix6bnJmTaOAFZhXHLbWyIY1e.jpeg +# * https://pixiv.pximg.net/c/1200x630_90_a2_g5/fanbox/public/images/post/186919/cover/VCI1Mcs2rbmWPg0mmiTisovn.jpeg +# +# * https://www.pixiv.net/fanbox/creator/1566167/post/39714 +# * https://www.pixiv.net/fanbox/creator/1566167 +# +# Novels +# +# * https://i.pximg.net/novel-cover-original/img/2019/01/14/01/15/05/10617324_d84daae89092d96bbe66efafec136e42.jpg +# * https://i.pximg.net/c/600x600/novel-cover-master/img/2019/01/14/01/15/05/10617324_d84daae89092d96bbe66efafec136e42_master1200.jpg +# * https://img-novel.pximg.net/img-novel/work_main/XtFbt7gsymsvyaG45lZ8/1554.jpg?20190107110435 +# +# * https://www.pixiv.net/novel/show.php?id=10617324 +# * https://novel.pixiv.net/works/1554 +# +# Sketch +# +# * https://img-sketch.pixiv.net/uploads/medium/file/4463372/8906921629213362989.jpg +# * https://img-sketch.pximg.net/c!/w=540,f=webp:jpeg/uploads/medium/file/4463372/8906921629213362989.jpg +# * https://sketch.pixiv.net/items/1588346448904706151 +# * https://sketch.pixiv.net/@0125840 +# + +module Sources + module Strategies + class PixivSlim < Base + def domains + ["pixiv.net", "pximg.net"] + end + + def site_name + "Pixiv" + end + + def canonical_url + image_url + end + + def image_urls + [url] + end + + def headers + { "Referer" => "https://www.pixiv.net"} + end + end + end +end diff --git a/app/logical/tag_category.rb b/app/logical/tag_category.rb index f7832a879..746dd100e 100644 --- a/app/logical/tag_category.rb +++ b/app/logical/tag_category.rb @@ -1,91 +1,91 @@ -class TagCategory - module Mappings - # Returns a hash mapping various tag categories to a numerical value. - def mapping - @@mapping ||= Hash[ - Danbooru.config.full_tag_config_info.map {|k,v| v["extra"].map {|y| [y,v["category"]]}} - .reduce([],:+)] - .update(Hash[Danbooru.config.full_tag_config_info.map {|k,v| [v["short"],v["category"]]}]) - .update( Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["category"]]}]) - end - - # Returns a hash mapping more suited for views - def canonical_mapping - @@canonical_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k.capitalize,v["category"]]}] - end - - # Returns a hash mapping numerical category values to their string equivalent. - def reverse_mapping - @@reverse_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [v["category"],k]}] - end - - # Returns a hash mapping for the short name usage in metatags - def short_name_mapping - @@short_name_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [v["short"],k]}] - end - - # Returns a hash mapping for humanized_essential_tag_string (models/post.rb) - def humanized_mapping - @@humanized_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["humanized"]]}] - end - - # Returns a hash mapping for split_tag_list_html (presenters/tag_set_presenter.rb) - def header_mapping - @@header_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["header"]]}] - end - - # Returns a hash mapping for related tag buttons (javascripts/related_tag.js.erb) - def related_button_mapping - @@related_button_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["relatedbutton"]]}] - end - - def mod_only_mapping - @@mod_only_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["mod_only"] || false]}] - end - - # Returns a hash mapping for CSS (stylesheets/posts.scss.erb) - def css_mapping - @@css_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [v["category"],v["css"]]}] - end - end - - module Lists - def categories - @@categories ||= Danbooru.config.full_tag_config_info.keys - end - - def category_ids - @@category_ids ||= canonical_mapping.values - end - - def short_name_list - @@short_name_list ||= short_name_mapping.keys - end - - def humanized_list - Danbooru.config.humanized_tag_category_list - end - - def split_header_list - Danbooru.config.split_tag_header_list - end - - def categorized_list - Danbooru.config.categorized_tag_list - end - - def related_button_list - Danbooru.config.related_tag_button_list - end - end - - module Regexes - def short_name_regex - @@short_name_regex ||= short_name_list.join("|") - end - end - - extend Mappings - extend Lists - extend Regexes -end +class TagCategory + module Mappings + # Returns a hash mapping various tag categories to a numerical value. + def mapping + @@mapping ||= Hash[ + Danbooru.config.full_tag_config_info.map {|k,v| v["extra"].map {|y| [y,v["category"]]}} + .reduce([],:+)] + .update(Hash[Danbooru.config.full_tag_config_info.map {|k,v| [v["short"],v["category"]]}]) + .update( Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["category"]]}]) + end + + # Returns a hash mapping more suited for views + def canonical_mapping + @@canonical_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k.capitalize,v["category"]]}] + end + + # Returns a hash mapping numerical category values to their string equivalent. + def reverse_mapping + @@reverse_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [v["category"],k]}] + end + + # Returns a hash mapping for the short name usage in metatags + def short_name_mapping + @@short_name_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [v["short"],k]}] + end + + # Returns a hash mapping for humanized_essential_tag_string (models/post.rb) + def humanized_mapping + @@humanized_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["humanized"]]}] + end + + # Returns a hash mapping for split_tag_list_html (presenters/tag_set_presenter.rb) + def header_mapping + @@header_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["header"]]}] + end + + # Returns a hash mapping for related tag buttons (javascripts/related_tag.js.erb) + def related_button_mapping + @@related_button_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["relatedbutton"]]}] + end + + def mod_only_mapping + @@mod_only_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [k,v["mod_only"] || false]}] + end + + # Returns a hash mapping for CSS (stylesheets/posts.scss.erb) + def css_mapping + @@css_mapping ||= Hash[Danbooru.config.full_tag_config_info.map {|k,v| [v["category"],v["css"]]}] + end + end + + module Lists + def categories + @@categories ||= Danbooru.config.full_tag_config_info.keys + end + + def category_ids + @@category_ids ||= canonical_mapping.values + end + + def short_name_list + @@short_name_list ||= short_name_mapping.keys + end + + def humanized_list + Danbooru.config.humanized_tag_category_list + end + + def split_header_list + Danbooru.config.split_tag_header_list + end + + def categorized_list + Danbooru.config.categorized_tag_list + end + + def related_button_list + Danbooru.config.related_tag_button_list + end + end + + module Regexes + def short_name_regex + @@short_name_regex ||= short_name_list.join("|") + end + end + + extend Mappings + extend Lists + extend Regexes +end diff --git a/app/logical/tags_preview.rb b/app/logical/tags_preview.rb index bf69ec04c..cfe24145b 100644 --- a/app/logical/tags_preview.rb +++ b/app/logical/tags_preview.rb @@ -1,41 +1,41 @@ -class TagsPreview - def initialize(tags: nil) - @tags = Tag.scan_tags(tags).map {|x| {a: x, type: 'tag'}} - aliases - implications - tag_types - end - - def aliases - names = @tags.map{ |tag| tag[:a] }.reject {|y| y.blank?} - aliased = TagAlias.to_aliased_with_originals(names).reject {|k,v| k == v } - @tags.map! do |tag| - if aliased[tag[:a]] - {a: tag[:a], b: aliased[tag[:a]], type: 'alias'} - else - tag - end - end - end - - def implications - names = @tags.map {|tag| tag[:b] || tag[:a] } - implications = TagImplication.descendants_with_originals(names) - implications.each do |implication, descendants| - @tags += descendants.map { |descendant| {a: implication, b: descendant, type: 'implication'} } - end - end - - def tag_types - names = @tags.map { |tag| tag[:b] || tag[:a] } - categories = Tag.categories_for(names) - @tags.map! do |tag| - tag[:tagType] = categories.fetch(tag[:b] || tag[:a], -1) - tag - end - end - - def serializable_hash(**options) - @tags - end -end +class TagsPreview + def initialize(tags: nil) + @tags = Tag.scan_tags(tags).map {|x| {a: x, type: 'tag'}} + aliases + implications + tag_types + end + + def aliases + names = @tags.map{ |tag| tag[:a] }.reject {|y| y.blank?} + aliased = TagAlias.to_aliased_with_originals(names).reject {|k,v| k == v } + @tags.map! do |tag| + if aliased[tag[:a]] + {a: tag[:a], b: aliased[tag[:a]], type: 'alias'} + else + tag + end + end + end + + def implications + names = @tags.map {|tag| tag[:b] || tag[:a] } + implications = TagImplication.descendants_with_originals(names) + implications.each do |implication, descendants| + @tags += descendants.map { |descendant| {a: implication, b: descendant, type: 'implication'} } + end + end + + def tag_types + names = @tags.map { |tag| tag[:b] || tag[:a] } + categories = Tag.categories_for(names) + @tags.map! do |tag| + tag[:tagType] = categories.fetch(tag[:b] || tag[:a], -1) + tag + end + end + + def serializable_hash(**options) + @tags + end +end diff --git a/app/logical/user_throttle.rb b/app/logical/user_throttle.rb index 6bd3216ce..cf09f34eb 100644 --- a/app/logical/user_throttle.rb +++ b/app/logical/user_throttle.rb @@ -1,79 +1,79 @@ -class UserThrottle - def initialize(options, user) - @prefix = options[:prefix] || "thtl:" - @duration = options[:duration] || 1.minute - @user_id = user.id - @max_rate = options[:max] || user.api_burst_limit - - @cached_rate = 0 - end - - def accept? - (@max_rate - current_rate) > 0 - end - - def cached_count - @max_rate - @cached_rate - end - - def uncached_count - @max_rate - current_rate - end - - def throttled? - if accept? - hit! - false - else - true - end - end - - private - - def cache_duration - (@duration / 60.seconds).to_i + 1 - end - - def current_rate - t = Time.now - ckey = current_key(t) - pkey = previous_key(t) - tdiff = t.to_i - ctime(t)*@duration.to_i - hits = redis_client.mget(ckey, pkey) - @cached_rate = (hits[1].to_f * ((@duration.to_i-tdiff)/@duration.to_f) + hits[0].to_f).to_i - end - - def hit! - t = Time.now - ckey = current_key(t) - redis_client.multi do - redis_client.incr(ckey) - redis_client.expire(ckey, cache_duration.minutes) - end - end - - def current_key(t) - "#{throttle_prefix}#{ctime(t)}" - end - - def previous_key(t) - "#{throttle_prefix}#{ptime(t)}" - end - - def ctime(t) - ((t.to_i / @duration.to_i)).to_i - end - - def ptime(t) - ((t.to_i / @duration.to_i) - 1).to_i - end - - def throttle_prefix - "#{@prefix}#{@user_id}:" - end - - def redis_client - @@client ||= ::Redis.new(url: Danbooru.config.redis_url) - end -end +class UserThrottle + def initialize(options, user) + @prefix = options[:prefix] || "thtl:" + @duration = options[:duration] || 1.minute + @user_id = user.id + @max_rate = options[:max] || user.api_burst_limit + + @cached_rate = 0 + end + + def accept? + (@max_rate - current_rate) > 0 + end + + def cached_count + @max_rate - @cached_rate + end + + def uncached_count + @max_rate - current_rate + end + + def throttled? + if accept? + hit! + false + else + true + end + end + + private + + def cache_duration + (@duration / 60.seconds).to_i + 1 + end + + def current_rate + t = Time.now + ckey = current_key(t) + pkey = previous_key(t) + tdiff = t.to_i - ctime(t)*@duration.to_i + hits = redis_client.mget(ckey, pkey) + @cached_rate = (hits[1].to_f * ((@duration.to_i-tdiff)/@duration.to_f) + hits[0].to_f).to_i + end + + def hit! + t = Time.now + ckey = current_key(t) + redis_client.multi do + redis_client.incr(ckey) + redis_client.expire(ckey, cache_duration.minutes) + end + end + + def current_key(t) + "#{throttle_prefix}#{ctime(t)}" + end + + def previous_key(t) + "#{throttle_prefix}#{ptime(t)}" + end + + def ctime(t) + ((t.to_i / @duration.to_i)).to_i + end + + def ptime(t) + ((t.to_i / @duration.to_i) - 1).to_i + end + + def throttle_prefix + "#{@prefix}#{@user_id}:" + end + + def redis_client + @@client ||= ::Redis.new(url: Danbooru.config.redis_url) + end +end diff --git a/app/mailers/maintenance/user/email_confirmation_mailer.rb b/app/mailers/maintenance/user/email_confirmation_mailer.rb index 8784f23f4..3da4e7d46 100644 --- a/app/mailers/maintenance/user/email_confirmation_mailer.rb +++ b/app/mailers/maintenance/user/email_confirmation_mailer.rb @@ -1,14 +1,14 @@ -module Maintenance - module User - class EmailConfirmationMailer < ActionMailer::Base - add_template_helper ApplicationHelper - add_template_helper UsersHelper - default :from => Danbooru.config.mail_from_addr, :content_type => "text/html" - - def confirmation(user) - @user = user - mail(:to => @user.email, :subject => "#{Danbooru.config.app_name} account confirmation") - end - end - end -end +module Maintenance + module User + class EmailConfirmationMailer < ActionMailer::Base + add_template_helper ApplicationHelper + add_template_helper UsersHelper + default :from => Danbooru.config.mail_from_addr, :content_type => "text/html" + + def confirmation(user) + @user = user + mail(:to => @user.email, :subject => "#{Danbooru.config.app_name} account confirmation") + end + end + end +end diff --git a/app/models/edit_history.rb b/app/models/edit_history.rb index c5d66f5b6..fcebb2705 100644 --- a/app/models/edit_history.rb +++ b/app/models/edit_history.rb @@ -1,14 +1,14 @@ -class EditHistory < ApplicationRecord - self.table_name = 'edit_histories' - belongs_to :versionable, polymorphic: true - belongs_to :user - - attr_accessor :difference - - - TYPE_MAP = { - comment: 'Comment', - forum: 'ForumPost', - blip: 'Blip' - } -end \ No newline at end of file +class EditHistory < ApplicationRecord + self.table_name = 'edit_histories' + belongs_to :versionable, polymorphic: true + belongs_to :user + + attr_accessor :difference + + + TYPE_MAP = { + comment: 'Comment', + forum: 'ForumPost', + blip: 'Blip' + } +end diff --git a/app/models/post_report_reason.rb b/app/models/post_report_reason.rb index 2ac8f9fe8..0aaedbd80 100644 --- a/app/models/post_report_reason.rb +++ b/app/models/post_report_reason.rb @@ -15,4 +15,4 @@ class PostReportReason < ApplicationRecord reasons.each {|x| js_map[x.id] = x.description} js_map end -end \ No newline at end of file +end diff --git a/app/models/post_set_maintainer.rb b/app/models/post_set_maintainer.rb index 53b49f3a3..36b7810a3 100644 --- a/app/models/post_set_maintainer.rb +++ b/app/models/post_set_maintainer.rb @@ -1,149 +1,149 @@ -class PostSetMaintainer < ApplicationRecord - belongs_to :user - belongs_to :post_set - - validate :ensure_not_set_owner, on: :create - validate :ensure_set_public, on: :create - validate :ensure_maintainer_count, on: :create - validate :ensure_not_duplicate, on: :create - - after_create :notify_maintainer - - def notify_maintainer - body = "\"#{post_set.creator.name}\":/users/#{post_set.creator_id} invited you to be a maintainer of the \"#{post_set.name}\":/post_sets/#{post_set_id} set. This would allow you to add and remove posts from it. - -\"Click here\":/post_set_maintainers/#{id}/approve to approve the request and become a maintainer. - -\"Click here\":/post_set_maintainers/#{id}/deny to deny the request. - -\"Click here\":/post_set_maintainers/#{id}/block to deny the request and prevent yourself from being invited to this set again in the future." - Dmail.create_automated( - to_id: user_id, - title: "You were invite to be a maintainer of #{post_set.name}", - body: body - ) - end - - def notify_destroy - - end - - def cancel! - if status == 'pending' - self.status = 'cooldown' - save - return - end - - if status == 'approved' - body = "\"#{post_set.creator.name}\":/users/#{post_set.creator_id} removed you as a maintainer of the \"#{post_set.name}\":/post_sets/#{post_set.id} set." - Dmail.create_automated( - to_id: user_id, - title: "You were removed as a set maintainer of #{post_set.name}", - body: body - ) - end - destroy - end - - def approve! - self.status = 'approved' - save - Dmail.create_automated( - to_id: post_set.creator_id, - title: "#{user.name} approved your invite to maintain #{post_set.name}", - body: "\"#{user.name}\":/users/#{user_id} approved your invite to maintain \"#{post_set.name}\":/post_sets/#{post_set.id}." - ) - end - - def deny! - if status == "pending" - Dmail.create_automated( - to_id: post_set.creator_id, - title: "#{user.name} denied your invite to maintain #{post_set.name}", - body: "\"#{user.name}\":/users/#{user.id} denied your invite to maintain \"#{post_set.name}\":/post_sets/#{post_set.id}." - ) - elsif status == "approved" - Dmail.create_automated( - to_id: post_set.creator_id, - title: "#{user.name} removed themselves as a maintainer of #{post_set.name}", - body: "\"#{user.name}\":/users/#{user.id} removed themselves as a maintainer of \"#{post_set.name}\":/post_sets/#{post_set.id}." - ) - end - destroy - end - - def block! - if status == "approved" - Dmail.create_automated( - to_id: post_set.creator_id, - title: "#{user.name} removed themselves as a maintainer of #{post_set.name}", - body: "\"#{user.name}\":/users/#{user.id} removed themselves as a maintainer of \"#{post_set.name}\":/post_sets/#{post_set.id} and blocked all future invites." - ) - elsif status == "pending" - Dmail.create_automated( - to_id: post_set.creator_id, - title: "#{user.name} denied your invite to maintain #{post_set.name}", - body: "\"#{user.name}\":/users/#{user.id} denied your invite to maintain \"#{post_set.name}\":/post_sets/#{post_set.id} and blocked all future invites." - ) - end - self.status = 'blocked' - save - end - - module ValidaitonMethods - def ensure_not_set_owner - if post_set.creator_id == user_id - errors.add(:user, "owns this set and can't be added as a maintainer") - false - end - end - - def ensure_maintainer_count - if PostSetMaintainer.where(post_set_id: post_set_id).count >= 75 - errors.add(:post_set, "current have too many maintainers") - false - end - end - - def ensure_not_duplicate - existing = PostSetMaintainer.where(post_set_id: post_set_id, user_id: user_id).first - if existing.nil? - return - end - if ['approved', 'pending'].include?(existing.status) - errors.add(:base, "Already a maintainer of this set") - return false - end - if existing.status == 'blocked' - errors.add(:base, 'User has blocked you from inviting them to maintain this set') - return false - end - if existing.status == 'cooldown' && existing.created_at > 24.hours.ago - errors.add(:base, "User has been invited to maintain this set too recently") - return false - end - end - - def ensure_set_public - unless post_set.is_public - errors.add(:post_set, 'must be public') - false - end - end - end - - def maintained(user) - where(user_id: user.id, status: 'approved').joins(:post_set).where('post_set.is_public = true') - end - - def self.active - where(status: 'approved') - end - - def self.pending - where(status: 'pending') - end - - include ValidaitonMethods -end +class PostSetMaintainer < ApplicationRecord + belongs_to :user + belongs_to :post_set + + validate :ensure_not_set_owner, on: :create + validate :ensure_set_public, on: :create + validate :ensure_maintainer_count, on: :create + validate :ensure_not_duplicate, on: :create + + after_create :notify_maintainer + + def notify_maintainer + body = "\"#{post_set.creator.name}\":/users/#{post_set.creator_id} invited you to be a maintainer of the \"#{post_set.name}\":/post_sets/#{post_set_id} set. This would allow you to add and remove posts from it. + +\"Click here\":/post_set_maintainers/#{id}/approve to approve the request and become a maintainer. + +\"Click here\":/post_set_maintainers/#{id}/deny to deny the request. + +\"Click here\":/post_set_maintainers/#{id}/block to deny the request and prevent yourself from being invited to this set again in the future." + Dmail.create_automated( + to_id: user_id, + title: "You were invite to be a maintainer of #{post_set.name}", + body: body + ) + end + + def notify_destroy + + end + + def cancel! + if status == 'pending' + self.status = 'cooldown' + save + return + end + + if status == 'approved' + body = "\"#{post_set.creator.name}\":/users/#{post_set.creator_id} removed you as a maintainer of the \"#{post_set.name}\":/post_sets/#{post_set.id} set." + Dmail.create_automated( + to_id: user_id, + title: "You were removed as a set maintainer of #{post_set.name}", + body: body + ) + end + destroy + end + + def approve! + self.status = 'approved' + save + Dmail.create_automated( + to_id: post_set.creator_id, + title: "#{user.name} approved your invite to maintain #{post_set.name}", + body: "\"#{user.name}\":/users/#{user_id} approved your invite to maintain \"#{post_set.name}\":/post_sets/#{post_set.id}." + ) + end + + def deny! + if status == "pending" + Dmail.create_automated( + to_id: post_set.creator_id, + title: "#{user.name} denied your invite to maintain #{post_set.name}", + body: "\"#{user.name}\":/users/#{user.id} denied your invite to maintain \"#{post_set.name}\":/post_sets/#{post_set.id}." + ) + elsif status == "approved" + Dmail.create_automated( + to_id: post_set.creator_id, + title: "#{user.name} removed themselves as a maintainer of #{post_set.name}", + body: "\"#{user.name}\":/users/#{user.id} removed themselves as a maintainer of \"#{post_set.name}\":/post_sets/#{post_set.id}." + ) + end + destroy + end + + def block! + if status == "approved" + Dmail.create_automated( + to_id: post_set.creator_id, + title: "#{user.name} removed themselves as a maintainer of #{post_set.name}", + body: "\"#{user.name}\":/users/#{user.id} removed themselves as a maintainer of \"#{post_set.name}\":/post_sets/#{post_set.id} and blocked all future invites." + ) + elsif status == "pending" + Dmail.create_automated( + to_id: post_set.creator_id, + title: "#{user.name} denied your invite to maintain #{post_set.name}", + body: "\"#{user.name}\":/users/#{user.id} denied your invite to maintain \"#{post_set.name}\":/post_sets/#{post_set.id} and blocked all future invites." + ) + end + self.status = 'blocked' + save + end + + module ValidaitonMethods + def ensure_not_set_owner + if post_set.creator_id == user_id + errors.add(:user, "owns this set and can't be added as a maintainer") + false + end + end + + def ensure_maintainer_count + if PostSetMaintainer.where(post_set_id: post_set_id).count >= 75 + errors.add(:post_set, "current have too many maintainers") + false + end + end + + def ensure_not_duplicate + existing = PostSetMaintainer.where(post_set_id: post_set_id, user_id: user_id).first + if existing.nil? + return + end + if ['approved', 'pending'].include?(existing.status) + errors.add(:base, "Already a maintainer of this set") + return false + end + if existing.status == 'blocked' + errors.add(:base, 'User has blocked you from inviting them to maintain this set') + return false + end + if existing.status == 'cooldown' && existing.created_at > 24.hours.ago + errors.add(:base, "User has been invited to maintain this set too recently") + return false + end + end + + def ensure_set_public + unless post_set.is_public + errors.add(:post_set, 'must be public') + false + end + end + end + + def maintained(user) + where(user_id: user.id, status: 'approved').joins(:post_set).where('post_set.is_public = true') + end + + def self.active + where(status: 'approved') + end + + def self.pending + where(status: 'pending') + end + + include ValidaitonMethods +end diff --git a/app/models/tag_type_version.rb b/app/models/tag_type_version.rb index 42e5775e9..7bab8d5e4 100644 --- a/app/models/tag_type_version.rb +++ b/app/models/tag_type_version.rb @@ -1,29 +1,29 @@ -class TagTypeVersion < ApplicationRecord - belongs_to :tag - belongs_to_creator - - module SearchMethods - def search(params = {}) - q = super.includes(:creator, :tag) - - if params[:tag].present? - tag = Tag.find_by_normalized_name(params[:tag]) - q = q.where(tag_id: tag.id) if tag - end - - if params[:user_id].present? - q = q.where('creator_id = ?', params[:user_id]) - end - if params[:user_name].present? - name = User.find_by_name(params[:user_name]) - q = q.where('creator_id = ? ', name.id) if id - end - - q = q.order(id: :desc) - - q - end - end - - extend SearchMethods -end \ No newline at end of file +class TagTypeVersion < ApplicationRecord + belongs_to :tag + belongs_to_creator + + module SearchMethods + def search(params = {}) + q = super.includes(:creator, :tag) + + if params[:tag].present? + tag = Tag.find_by_normalized_name(params[:tag]) + q = q.where(tag_id: tag.id) if tag + end + + if params[:user_id].present? + q = q.where('creator_id = ?', params[:user_id]) + end + if params[:user_name].present? + name = User.find_by_name(params[:user_name]) + q = q.where('creator_id = ? ', name.id) if id + end + + q = q.order(id: :desc) + + q + end + end + + extend SearchMethods +end diff --git a/app/models/user_status.rb b/app/models/user_status.rb index d78239725..bbea49ebf 100644 --- a/app/models/user_status.rb +++ b/app/models/user_status.rb @@ -1,7 +1,7 @@ -class UserStatus < ApplicationRecord - belongs_to :user - - def self.for_user(user_id) - where("user_statuses.user_id = ?", user_id) - end -end +class UserStatus < ApplicationRecord + belongs_to :user + + def self.for_user(user_id) + where("user_statuses.user_id = ?", user_id) + end +end diff --git a/app/views/admin/dashboards/_aliases.html.erb b/app/views/admin/dashboards/_aliases.html.erb index e69de29bb..8b1378917 100644 --- a/app/views/admin/dashboards/_aliases.html.erb +++ b/app/views/admin/dashboards/_aliases.html.erb @@ -0,0 +1 @@ + diff --git a/app/views/admin/exceptions/index.html.erb b/app/views/admin/exceptions/index.html.erb index 9be9c2d04..5204eb1be 100644 --- a/app/views/admin/exceptions/index.html.erb +++ b/app/views/admin/exceptions/index.html.erb @@ -1,30 +1,30 @@ - - - - - - - - - - - - - <%- @exception_logs.each do |exception_log| %> - - - - - - - - - <% end %> - -
Created AtCodeVersionClass NameMessageStacktrace
<%= exception_log.created_at.strftime("%b %d, %Y %l:%M %p") %><%= exception_log.code %><%= exception_log.version %><%= exception_log.class_name %><%= exception_log.message %> - <%= link_to "View", admin_exception_path(exception_log) %> -
- -
- <%= numbered_paginator(@exception_logs) %> -
+ + + + + + + + + + + + + <%- @exception_logs.each do |exception_log| %> + + + + + + + + + <% end %> + +
Created AtCodeVersionClass NameMessageStacktrace
<%= exception_log.created_at.strftime("%b %d, %Y %l:%M %p") %><%= exception_log.code %><%= exception_log.version %><%= exception_log.class_name %><%= exception_log.message %> + <%= link_to "View", admin_exception_path(exception_log) %> +
+ +
+ <%= numbered_paginator(@exception_logs) %> +
diff --git a/app/views/admin/exceptions/show.html.erb b/app/views/admin/exceptions/show.html.erb index a8e7e6fdd..806e74b02 100644 --- a/app/views/admin/exceptions/show.html.erb +++ b/app/views/admin/exceptions/show.html.erb @@ -1,16 +1,16 @@ -
-
-

<%= @exception_log.class_name %>

-

<%= @exception_log.message %>

-

- Error Code: <%= @exception_log.code %>
- Created At: <%= @exception_log.created_at.strftime("%b %d, %Y %l:%M %p") %>
- Version: <%= @exception_log.version %>
- IP Address: <%= link_to_ip @exception_log.ip_addr %> -

-
- Extra Params: -
<%= JSON.pretty_generate(@exception_log.extra_params) %>
- Stacktrace: -
<%= @exception_log.trace %>
-
+
+
+

<%= @exception_log.class_name %>

+

<%= @exception_log.message %>

+

+ Error Code: <%= @exception_log.code %>
+ Created At: <%= @exception_log.created_at.strftime("%b %d, %Y %l:%M %p") %>
+ Version: <%= @exception_log.version %>
+ IP Address: <%= link_to_ip @exception_log.ip_addr %> +

+
+ Extra Params: +
<%= JSON.pretty_generate(@exception_log.extra_params) %>
+ Stacktrace: +
<%= @exception_log.trace %>
+
diff --git a/app/views/admin/users/edit_blacklist.html.erb b/app/views/admin/users/edit_blacklist.html.erb index a18064d01..66f67115e 100644 --- a/app/views/admin/users/edit_blacklist.html.erb +++ b/app/views/admin/users/edit_blacklist.html.erb @@ -1,9 +1,9 @@ -
-

View User Blacklist

-
- <%= form_tag({action: "update_blacklist"}, method: :post) do %> - <%= text_area "user", "blacklisted_tags", size: "60x20" %> - <%= submit_tag "Save", name: nil %> - <% end %> -
-
+
+

View User Blacklist

+
+ <%= form_tag({action: "update_blacklist"}, method: :post) do %> + <%= text_area "user", "blacklisted_tags", size: "60x20" %> + <%= submit_tag "Save", name: nil %> + <% end %> +
+
diff --git a/app/views/admin/users/password_reset.html.erb b/app/views/admin/users/password_reset.html.erb index c0871c97a..cb637be3f 100644 --- a/app/views/admin/users/password_reset.html.erb +++ b/app/views/admin/users/password_reset.html.erb @@ -1,12 +1,12 @@ -
-

Reset Password

- - <% if @reset_key %> - <% if @user.email.blank? %> -

Password reset request created, but <%= @user.name %> has no email address associated with their account.
- <% else %> -

Password reset email successfully sent to <%= @user.name %> (<%= @user.email %>)
- <% end %> - Their password reset URL is: <%= edit_maintenance_user_password_reset_url(:host => Danbooru.config.hostname, :only_path => false, :key => @reset_key.key, :uid => @reset_key.user_id) %>

- <% end %> -
+
+

Reset Password

+ + <% if @reset_key %> + <% if @user.email.blank? %> +

Password reset request created, but <%= @user.name %> has no email address associated with their account.
+ <% else %> +

Password reset email successfully sent to <%= @user.name %> (<%= @user.email %>)
+ <% end %> + Their password reset URL is: <%= edit_maintenance_user_password_reset_url(:host => Danbooru.config.hostname, :only_path => false, :key => @reset_key.key, :uid => @reset_key.user_id) %>

+ <% end %> +
diff --git a/app/views/admin/users/request_password_reset.html.erb b/app/views/admin/users/request_password_reset.html.erb index 3ed13c26e..f7ecc153b 100644 --- a/app/views/admin/users/request_password_reset.html.erb +++ b/app/views/admin/users/request_password_reset.html.erb @@ -1,21 +1,21 @@ -
-

Reset Password

- -
- <%= form_tag(password_reset_admin_user_path(@user)) do %> - - - - - - - - - - -
<%= text_field "user", "name", {value: @user ? @user.name : "", "data-autocomplete": 'user'} %>
<%= password_field "admin", "password", autocomplete: :off %>
- - <%= submit_tag "Reset" %> - <% end %> -
-
+
+

Reset Password

+ +
+ <%= form_tag(password_reset_admin_user_path(@user)) do %> + + + + + + + + + + +
<%= text_field "user", "name", {value: @user ? @user.name : "", "data-autocomplete": 'user'} %>
<%= password_field "admin", "password", autocomplete: :off %>
+ + <%= submit_tag "Reset" %> + <% end %> +
+
diff --git a/app/views/blips/_form.html.erb b/app/views/blips/_form.html.erb index 35efdbee5..9cc438ed4 100644 --- a/app/views/blips/_form.html.erb +++ b/app/views/blips/_form.html.erb @@ -1,11 +1,11 @@ -
- <%= error_messages_for :blip %> - <%= simple_form_for(blip, :html => {:style => ("display: none;" if local_assigns[:hidden]), :class => "edit_blip"}) do |f| %> - <% if blip.new_record? %> - <%= f.hidden_field :response_to %> - <% end %> - <%= dtext_field "blip", "body", :value => blip.body, :input_id => "blip_body_for_#{blip.id}", :preview_id => "dtext-preview-for-#{blip.id}" %> - <%= f.button :submit, "Submit" %> - <%= dtext_preview_button "blip", "body", :input_id => "blip_body_for_#{blip.id}", :preview_id => "dtext-preview-for-#{blip.id}" %> - <% end %> -
+
+ <%= error_messages_for :blip %> + <%= simple_form_for(blip, :html => {:style => ("display: none;" if local_assigns[:hidden]), :class => "edit_blip"}) do |f| %> + <% if blip.new_record? %> + <%= f.hidden_field :response_to %> + <% end %> + <%= dtext_field "blip", "body", :value => blip.body, :input_id => "blip_body_for_#{blip.id}", :preview_id => "dtext-preview-for-#{blip.id}" %> + <%= f.button :submit, "Submit" %> + <%= dtext_preview_button "blip", "body", :input_id => "blip_body_for_#{blip.id}", :preview_id => "dtext-preview-for-#{blip.id}" %> + <% end %> +
diff --git a/app/views/blips/_quick_search.html.erb b/app/views/blips/_quick_search.html.erb index 3f65b6d6e..6c581dc29 100644 --- a/app/views/blips/_quick_search.html.erb +++ b/app/views/blips/_quick_search.html.erb @@ -1,3 +1,3 @@ -<%= form_tag(blips_path, :method => :get) do %> - <%= text_field "search", "body_matches", :id => "quick_search_body_matches", :placeholder => "Search blips" %> -<% end %> +<%= form_tag(blips_path, :method => :get) do %> + <%= text_field "search", "body_matches", :id => "quick_search_body_matches", :placeholder => "Search blips" %> +<% end %> diff --git a/app/views/blips/partials/index/_list.html.erb b/app/views/blips/partials/index/_list.html.erb index be59fc6d9..5331a5a9b 100644 --- a/app/views/blips/partials/index/_list.html.erb +++ b/app/views/blips/partials/index/_list.html.erb @@ -1,10 +1,10 @@ -
- <% if blips.empty? %> -

No blips

- <% else %> - <% blips.each do |blip| %> - <% next unless blip.can_view?(current_user) %> -
<%= render partial: "blip/blip", locals: {blip: blip} %>
- <% end %> - <% end %> -
+
+ <% if blips.empty? %> +

No blips

+ <% else %> + <% blips.each do |blip| %> + <% next unless blip.can_view?(current_user) %> +
<%= render partial: "blip/blip", locals: {blip: blip} %>
+ <% end %> + <% end %> +
diff --git a/app/views/edit_histories/index.html.erb b/app/views/edit_histories/index.html.erb index 9618ceb1f..d688259a6 100644 --- a/app/views/edit_histories/index.html.erb +++ b/app/views/edit_histories/index.html.erb @@ -1,37 +1,37 @@ -
-
-

Recent Edits

- - - - - - - - - - - - - - - - <% @edit_history.each do |edit| %> - - - - - - - - - - <% end %> - -
TypeDateIP AddressEditorBodySubject
<%= link_to "Show", action: "show", id: edit.versionable_id, type: edit.versionable_type %><%= edit.versionable_type %><%= edit.updated_at.strftime("%b %d, %Y %I:%M %p") %><%= link_to_ip edit.ip_addr %><%= link_to_user edit.user %><%= edit.body[0..30] %><%= edit.subject&[0..30] %>
- -
- <%= numbered_paginator(@edit_history) %> -
-
-
+
+
+

Recent Edits

+ + + + + + + + + + + + + + + + <% @edit_history.each do |edit| %> + + + + + + + + + + <% end %> + +
TypeDateIP AddressEditorBodySubject
<%= link_to "Show", action: "show", id: edit.versionable_id, type: edit.versionable_type %><%= edit.versionable_type %><%= edit.updated_at.strftime("%b %d, %Y %I:%M %p") %><%= link_to_ip edit.ip_addr %><%= link_to_user edit.user %><%= edit.body[0..30] %><%= edit.subject&[0..30] %>
+ +
+ <%= numbered_paginator(@edit_history) %> +
+
+
diff --git a/app/views/edit_histories/show.html.erb b/app/views/edit_histories/show.html.erb index 81d1d9556..3ac22c1fd 100644 --- a/app/views/edit_histories/show.html.erb +++ b/app/views/edit_histories/show.html.erb @@ -1,26 +1,26 @@ -
-
-

Edits for <%= h params[:type] %> #<%= h params[:id] %>

- -
- <% @edits.each_with_index do |edit, idx| %> -
-
-
<%= link_to_user edit.user %>
- "><%= edit.created_at.strftime("%b %d, %Y %I:%M %p") %> -
<%= link_to_ip edit.ip_addr %>
-
-
-
- <% if edit.version > 1 %> - <%= edit.diff(@edits[idx-1]) %> - <% else %> - <%= edit.body %> - <% end %> -
-
-
- <% end %> -
-
-
+
+
+

Edits for <%= h params[:type] %> #<%= h params[:id] %>

+ +
+ <% @edits.each_with_index do |edit, idx| %> +
+
+
<%= link_to_user edit.user %>
+ "><%= edit.created_at.strftime("%b %d, %Y %I:%M %p") %> +
<%= link_to_ip edit.ip_addr %>
+
+
+
+ <% if edit.version > 1 %> + <%= edit.diff(@edits[idx-1]) %> + <% else %> + <%= edit.body %> + <% end %> +
+
+
+ <% end %> +
+
+
diff --git a/app/views/email_blacklists/_search.html.erb b/app/views/email_blacklists/_search.html.erb index 1f8944a39..c621f3539 100644 --- a/app/views/email_blacklists/_search.html.erb +++ b/app/views/email_blacklists/_search.html.erb @@ -1,6 +1,6 @@ -<%= simple_form_for(:search, url: email_blacklists_path, method: :get, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> - <%= f.input :pattern, label: "Domain", hint: "Use * for wildcard", input_html: { value: params[:search][:domain]} %> - <%= f.input :reason, label: "Ban Reason", input_html: { value: params[:search][:reason] } %> - <%= f.input :order, collection: [["Recently created", "id"], ["Last updated", "updated_at"], ["Domain", "domain"], ["Reason", "reason"]], selected: params[:search][:order] %> - <%= f.submit "Search" %> -<% end %> \ No newline at end of file +<%= simple_form_for(:search, url: email_blacklists_path, method: :get, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> + <%= f.input :pattern, label: "Domain", hint: "Use * for wildcard", input_html: { value: params[:search][:domain]} %> + <%= f.input :reason, label: "Ban Reason", input_html: { value: params[:search][:reason] } %> + <%= f.input :order, collection: [["Recently created", "id"], ["Last updated", "updated_at"], ["Domain", "domain"], ["Reason", "reason"]], selected: params[:search][:order] %> + <%= f.submit "Search" %> +<% end %> diff --git a/app/views/iqdb_queries/show.html+xhr.erb b/app/views/iqdb_queries/show.html+xhr.erb index 1e6f5999d..3b6cd062e 100644 --- a/app/views/iqdb_queries/show.html+xhr.erb +++ b/app/views/iqdb_queries/show.html+xhr.erb @@ -1 +1 @@ -<%= render "iqdb_queries/matches" %> \ No newline at end of file +<%= render "iqdb_queries/matches" %> diff --git a/app/views/moderator/ip_addrs/_ip_listing.json.erb b/app/views/moderator/ip_addrs/_ip_listing.json.erb index bb9f4c563..45801c1ba 100644 --- a/app/views/moderator/ip_addrs/_ip_listing.json.erb +++ b/app/views/moderator/ip_addrs/_ip_listing.json.erb @@ -1 +1 @@ -<%= raw @results.map {|ip_addr, count| {ip_addr: ip_addr.to_s, count: count}}.to_json %> \ No newline at end of file +<%= raw @results.map {|ip_addr, count| {ip_addr: ip_addr.to_s, count: count}}.to_json %> diff --git a/app/views/moderator/ip_addrs/_search.html.erb b/app/views/moderator/ip_addrs/_search.html.erb index 2efa7320d..cec6fa939 100644 --- a/app/views/moderator/ip_addrs/_search.html.erb +++ b/app/views/moderator/ip_addrs/_search.html.erb @@ -1,10 +1,10 @@ -
- It is possible to search for IP address wildcards using CIDR notation, but only if searching for a single IP addr. You probably want '/24' at the end for IPv4 wildcards. -
-<%= simple_form_for(:search, method: :get, url: moderator_ip_addrs_path, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> - <%= f.input :user_id, label: "User IDs", input_html: { value: params[:search][:user_id] } %> - <%= f.input :user_name, label: "User Names", input_html: { value: params[:search][:user_name] } %> - <%= f.input :ip_addr, label: "IP Addresses", input_html: { value: params[:search][:ip_addr] } %> - <%= f.input :with_history, label: "With History", as: :boolean, input_html: { checked: params[:search][:with_history] } %> - <%= f.submit "Search" %> -<% end %> +
+ It is possible to search for IP address wildcards using CIDR notation, but only if searching for a single IP addr. You probably want '/24' at the end for IPv4 wildcards. +
+<%= simple_form_for(:search, method: :get, url: moderator_ip_addrs_path, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> + <%= f.input :user_id, label: "User IDs", input_html: { value: params[:search][:user_id] } %> + <%= f.input :user_name, label: "User Names", input_html: { value: params[:search][:user_name] } %> + <%= f.input :ip_addr, label: "IP Addresses", input_html: { value: params[:search][:ip_addr] } %> + <%= f.input :with_history, label: "With History", as: :boolean, input_html: { checked: params[:search][:with_history] } %> + <%= f.submit "Search" %> +<% end %> diff --git a/app/views/moderator/ip_addrs/_user_listing.json.erb b/app/views/moderator/ip_addrs/_user_listing.json.erb index f77e094e8..477f1fec2 100644 --- a/app/views/moderator/ip_addrs/_user_listing.json.erb +++ b/app/views/moderator/ip_addrs/_user_listing.json.erb @@ -1 +1 @@ -<%= raw @results[:sums].to_json %> +<%= raw @results[:sums].to_json %> diff --git a/app/views/post_report_reasons/edit.html.erb b/app/views/post_report_reasons/edit.html.erb index d052e88ec..d50ec54ed 100644 --- a/app/views/post_report_reasons/edit.html.erb +++ b/app/views/post_report_reasons/edit.html.erb @@ -1,16 +1,16 @@ -
-
-

Edit Post Report Reason

- -
- <%= simple_form_for(@reason) do |f| %> - <%= f.input :reason, as: :string %> - <%= f.input :description, as: :string %> - <%= f.button :submit, "Edit" %> - <% end %> -
-
-
- - -<%= render partial: "secondary_links" %> +
+
+

Edit Post Report Reason

+ +
+ <%= simple_form_for(@reason) do |f| %> + <%= f.input :reason, as: :string %> + <%= f.input :description, as: :string %> + <%= f.button :submit, "Edit" %> + <% end %> +
+
+
+ + +<%= render partial: "secondary_links" %> diff --git a/app/views/post_sets/_add_dialog.html.erb b/app/views/post_sets/_add_dialog.html.erb index 3940d6101..af395d222 100644 --- a/app/views/post_sets/_add_dialog.html.erb +++ b/app/views/post_sets/_add_dialog.html.erb @@ -1,12 +1,12 @@ -
-
- - -
- -
- -
-
+
+
+ + +
+ +
+ +
+
diff --git a/app/views/posts/partials/common/_anon_blacklist.html.erb b/app/views/posts/partials/common/_anon_blacklist.html.erb index 57493783a..07c30a3be 100644 --- a/app/views/posts/partials/common/_anon_blacklist.html.erb +++ b/app/views/posts/partials/common/_anon_blacklist.html.erb @@ -1,7 +1,7 @@ - + diff --git a/app/views/static/_guest_warning.html.erb b/app/views/static/_guest_warning.html.erb index 5aa7de7b6..775799b22 100644 --- a/app/views/static/_guest_warning.html.erb +++ b/app/views/static/_guest_warning.html.erb @@ -1,20 +1,20 @@ - + diff --git a/app/views/static/error.atom.erb b/app/views/static/error.atom.erb index e69de29bb..8b1378917 100644 --- a/app/views/static/error.atom.erb +++ b/app/views/static/error.atom.erb @@ -0,0 +1 @@ + diff --git a/app/views/static/too_many_requests.html.erb b/app/views/static/too_many_requests.html.erb index 4d9f56c85..f4b278912 100644 --- a/app/views/static/too_many_requests.html.erb +++ b/app/views/static/too_many_requests.html.erb @@ -1,2 +1,2 @@

Too Many Requests

-

Please rate limit yourself

\ No newline at end of file +

Please rate limit yourself

diff --git a/app/views/tag_type_versions/index.html.erb b/app/views/tag_type_versions/index.html.erb index 6cefdd227..5fa6cc5cc 100644 --- a/app/views/tag_type_versions/index.html.erb +++ b/app/views/tag_type_versions/index.html.erb @@ -1,40 +1,40 @@ -
-
- <%= render partial: 'search' %> -
- - - - - - - - - - - - - - <% @tag_versions.each do |change| %> - - - - - - - - - - <% end %> - -
TagDateUserOld TypeNew typeLocked
<%= link_to change.tag.name, edit_tag_path(change.tag) %> - <%= change.created_at.strftime("%b %d") %> - <%= link_to_user change.creator %>"><%= Tag.category_for_value(change.old_type) %>"><%= Tag.category_for_value(change.new_type) %><%= change.is_locked %>
-
- -
- <%= sequential_paginator(@tag_versions) %> -
-
-
- +
+
+ <%= render partial: 'search' %> +
+ + + + + + + + + + + + + + <% @tag_versions.each do |change| %> + + + + + + + + + + <% end %> + +
TagDateUserOld TypeNew typeLocked
<%= link_to change.tag.name, edit_tag_path(change.tag) %> + <%= change.created_at.strftime("%b %d") %> + <%= link_to_user change.creator %>"><%= Tag.category_for_value(change.old_type) %>"><%= Tag.category_for_value(change.new_type) %><%= change.is_locked %>
+
+ +
+ <%= sequential_paginator(@tag_versions) %> +
+
+
+ diff --git a/app/views/tickets/_secondary_links.html.erb b/app/views/tickets/_secondary_links.html.erb index 1434a29c0..5b3075de2 100644 --- a/app/views/tickets/_secondary_links.html.erb +++ b/app/views/tickets/_secondary_links.html.erb @@ -1,11 +1,11 @@ -<% content_for(:secondary_links) do %> - - <%= subnav_link_to 'List', tickets_path %> - <% unless CurrentUser.is_anonymous? %> - <%= subnav_link_to 'Mine', tickets_path(search: {creator_id: CurrentUser.id}) %> - <% end %> - <% if CurrentUser.is_admin? %> - <%= subnav_link_to 'Claimed', tickets_path(search: {claimant_id: CurrentUser.id}) %> - <% end %> - -<% end %> \ No newline at end of file +<% content_for(:secondary_links) do %> + + <%= subnav_link_to 'List', tickets_path %> + <% unless CurrentUser.is_anonymous? %> + <%= subnav_link_to 'Mine', tickets_path(search: {creator_id: CurrentUser.id}) %> + <% end %> + <% if CurrentUser.is_admin? %> + <%= subnav_link_to 'Claimed', tickets_path(search: {claimant_id: CurrentUser.id}) %> + <% end %> + +<% end %> diff --git a/app/views/tickets/new.html.erb b/app/views/tickets/new.html.erb index 40f8dab87..b2f9e27f0 100644 --- a/app/views/tickets/new.html.erb +++ b/app/views/tickets/new.html.erb @@ -1,66 +1,66 @@ -
-
- - <%= simple_form_for(@ticket) do |f| %> - <% @found_item = true %> - <% if params[:type].nil? %> - <% @found_item = false %> -
- To submit a ticket about a problematic comment, click "Report" on the comment itself.
- To submit a ticket about a problematic forum post, click "Report" on the post itself.
- To submit a ticket about a problematic pool, click "Report" on the pool page itself.
- To submit a ticket about a problematic set, click "Report" on the set page itself.
- To submit a ticket about a problematic user, click "Report" on the user's profile page.
- To submit a ticket about a problematic private message, click "Report PM" above the PM itself.
- To submit a username request, click "Request Username Change" on the user home page.
-
- <% elsif CurrentUser.is_anonymous? %> - <% @found_item = false %> -
- You must be logged in to submit a ticket. Please log in and try again. -
- <% elsif @ticket.type_valid %> - <%= render partial: "tickets/new_types/#{@ticket.qtype}" %> - <% else %> - <% @found_item = false %> -
- Hmm, it seems you tried to report something that doesn't make sense. -
- <% end %> - - <% if @found_item %> - <%= f.hidden_field :disp_id %> - <%= f.hidden_field :qtype %> - -
-
- - <% if params[:type] == "namechange" %> -

Note: Multiple name change requests made within a short period of time may not be - honored

- <%= f.input :reason, as: :text, maxlength: 20 %>
- <% else %> -

Note: Abuse of this system will lead to disciplinary action

- <%= dtext_field "ticket", "reason", :value => @ticket.reason, :input_id => "ticket_reason", :preview_id => "dtext-preview-for-ticket-reason" %> - <% end %> - -
- <% if params[:type] == "namechange" %> - <%= submit_tag "Submit Request" %> - <% else %> - <%= submit_tag "Submit Complaint" %> <%= dtext_preview_button "ticket", "reason", :input_id => "ticket_reason", :preview_id => "dtext-preview-for-ticket-reason" %> - <% end %> - <% end %> - <% end %> -
-
- -<% render partial: 'secondary_links' %> +
+
+ + <%= simple_form_for(@ticket) do |f| %> + <% @found_item = true %> + <% if params[:type].nil? %> + <% @found_item = false %> +
+ To submit a ticket about a problematic comment, click "Report" on the comment itself.
+ To submit a ticket about a problematic forum post, click "Report" on the post itself.
+ To submit a ticket about a problematic pool, click "Report" on the pool page itself.
+ To submit a ticket about a problematic set, click "Report" on the set page itself.
+ To submit a ticket about a problematic user, click "Report" on the user's profile page.
+ To submit a ticket about a problematic private message, click "Report PM" above the PM itself.
+ To submit a username request, click "Request Username Change" on the user home page.
+
+ <% elsif CurrentUser.is_anonymous? %> + <% @found_item = false %> +
+ You must be logged in to submit a ticket. Please log in and try again. +
+ <% elsif @ticket.type_valid %> + <%= render partial: "tickets/new_types/#{@ticket.qtype}" %> + <% else %> + <% @found_item = false %> +
+ Hmm, it seems you tried to report something that doesn't make sense. +
+ <% end %> + + <% if @found_item %> + <%= f.hidden_field :disp_id %> + <%= f.hidden_field :qtype %> + +
+
+ + <% if params[:type] == "namechange" %> +

Note: Multiple name change requests made within a short period of time may not be + honored

+ <%= f.input :reason, as: :text, maxlength: 20 %>
+ <% else %> +

Note: Abuse of this system will lead to disciplinary action

+ <%= dtext_field "ticket", "reason", :value => @ticket.reason, :input_id => "ticket_reason", :preview_id => "dtext-preview-for-ticket-reason" %> + <% end %> + +
+ <% if params[:type] == "namechange" %> + <%= submit_tag "Submit Request" %> + <% else %> + <%= submit_tag "Submit Complaint" %> <%= dtext_preview_button "ticket", "reason", :input_id => "ticket_reason", :preview_id => "dtext-preview-for-ticket-reason" %> + <% end %> + <% end %> + <% end %> +
+
+ +<% render partial: 'secondary_links' %> diff --git a/app/views/tickets/new_types/_blip.html.erb b/app/views/tickets/new_types/_blip.html.erb index 023fd9231..b3ecf3a04 100644 --- a/app/views/tickets/new_types/_blip.html.erb +++ b/app/views/tickets/new_types/_blip.html.erb @@ -1,12 +1,12 @@ -<% unless @ticket.blip %> - <% @found_item = false %> -
That blip does not exist.
-<% else %> -
-

You are reporting the following blip:

-
<%= link_to_user(@ticket.blip.creator) %>
- "><%= time_ago_in_words(@ticket.blip.created_at) %> ago -

- <%= format_text(@ticket.blip.body) %> -
-<% end %> \ No newline at end of file +<% unless @ticket.blip %> + <% @found_item = false %> +
That blip does not exist.
+<% else %> +
+

You are reporting the following blip:

+
<%= link_to_user(@ticket.blip.creator) %>
+ "><%= time_ago_in_words(@ticket.blip.created_at) %> ago +

+ <%= format_text(@ticket.blip.body) %> +
+<% end %> diff --git a/app/views/tickets/new_types/_comment.html.erb b/app/views/tickets/new_types/_comment.html.erb index ca4e02ea8..20e685416 100644 --- a/app/views/tickets/new_types/_comment.html.erb +++ b/app/views/tickets/new_types/_comment.html.erb @@ -1,13 +1,13 @@ -<% unless @ticket.comment %> - <% @found_item = false %> -
That comment does not exist.
-<% else %> -
- <% @comment = @ticket.comment %> -

You are reporting the following comment:

-
<%= link_to_user @comment.creator %>
- "><%= time_ago_in_words(@comment.created_at) %> ago -

- <%= format_text(@comment.body) %> -
-<% end %> \ No newline at end of file +<% unless @ticket.comment %> + <% @found_item = false %> +
That comment does not exist.
+<% else %> +
+ <% @comment = @ticket.comment %> +

You are reporting the following comment:

+
<%= link_to_user @comment.creator %>
+ "><%= time_ago_in_words(@comment.created_at) %> ago +

+ <%= format_text(@comment.body) %> +
+<% end %> diff --git a/app/views/tickets/new_types/_dmail.html.erb b/app/views/tickets/new_types/_dmail.html.erb index 925022b00..d6ef0f407 100644 --- a/app/views/tickets/new_types/_dmail.html.erb +++ b/app/views/tickets/new_types/_dmail.html.erb @@ -1,13 +1,13 @@ -<% unless @ticket.dmail && @ticket.dmail.visible_to?(CurrentUser.user) %> - <% @found_item = false %> -
That message does not exist.
-<% else %> -
- <% @dmail = @ticket.dmail %> -

You are reporting the following private message:

-
<%= link_to_user @dmail.from %>
- "><%= time_ago_in_words(@dmail.created_at) %> - ago - <%= format_text(@dmail.body) %> -
-<% end %> \ No newline at end of file +<% unless @ticket.dmail && @ticket.dmail.visible_to?(CurrentUser.user) %> + <% @found_item = false %> +
That message does not exist.
+<% else %> +
+ <% @dmail = @ticket.dmail %> +

You are reporting the following private message:

+
<%= link_to_user @dmail.from %>
+ "><%= time_ago_in_words(@dmail.created_at) %> + ago + <%= format_text(@dmail.body) %> +
+<% end %> diff --git a/app/views/tickets/new_types/_forum.html.erb b/app/views/tickets/new_types/_forum.html.erb index 1978fcf42..0ed028ed2 100644 --- a/app/views/tickets/new_types/_forum.html.erb +++ b/app/views/tickets/new_types/_forum.html.erb @@ -1,12 +1,12 @@ -<% unless @ticket.forum %> - <% @found_item = false %> -
That forum post does not exist.
-<% else %> -
- <% @forum = @ticket.forum %> -

You are reporting the following forum post:

-
<%= link_to_user(@forum.creator) %>
- "><%= time_ago_in_words(@forum.created_at) %> ago - <%= format_text(@forum.body) %> -
-<% end %> \ No newline at end of file +<% unless @ticket.forum %> + <% @found_item = false %> +
That forum post does not exist.
+<% else %> +
+ <% @forum = @ticket.forum %> +

You are reporting the following forum post:

+
<%= link_to_user(@forum.creator) %>
+ "><%= time_ago_in_words(@forum.created_at) %> ago + <%= format_text(@forum.body) %> +
+<% end %> diff --git a/app/views/tickets/new_types/_namechange.html.erb b/app/views/tickets/new_types/_namechange.html.erb index ece4c4f54..045652869 100644 --- a/app/views/tickets/new_types/_namechange.html.erb +++ b/app/views/tickets/new_types/_namechange.html.erb @@ -1,18 +1,18 @@ -<% unless (params[:disp_id].to_i == current_user.id) %> - <% @found_item = false %> -
You can only change your own username.
-<% else %> -
-

You are requesting to change your username.

-

Usernames may contain: -

-

The name change is not automated, but must be approved by an Administrator. - Requests are usually handled within 24 hours, but it may take up to 3 days to process. - Once the name change has been approved your old username is able to used by other users. - Please ensure that you are willing to risk losing your name!

-
-<% end %> \ No newline at end of file +<% unless (params[:disp_id].to_i == current_user.id) %> + <% @found_item = false %> +
You can only change your own username.
+<% else %> +
+

You are requesting to change your username.

+

Usernames may contain: +

+

The name change is not automated, but must be approved by an Administrator. + Requests are usually handled within 24 hours, but it may take up to 3 days to process. + Once the name change has been approved your old username is able to used by other users. + Please ensure that you are willing to risk losing your name!

+
+<% end %> diff --git a/app/views/tickets/new_types/_pool.html.erb b/app/views/tickets/new_types/_pool.html.erb index 1130d8863..2e5062239 100644 --- a/app/views/tickets/new_types/_pool.html.erb +++ b/app/views/tickets/new_types/_pool.html.erb @@ -1,14 +1,14 @@ -<% unless @ticket.pool %> - <% @found_item = false %> -
That pool does not exist.
-<% else %> -
- <% @pool = @ticket.pool %> -

You are reporting the following pool:

-
<%= fast_link_to(@pool.name, controller: "pools", id: @pool.id) %>
-
<%= link_to_user(@pool.creator) %>
- "> - <%= time_ago_in_words(@pool.created_at) %>ago - -
-<% end %> \ No newline at end of file +<% unless @ticket.pool %> + <% @found_item = false %> +
That pool does not exist.
+<% else %> +
+ <% @pool = @ticket.pool %> +

You are reporting the following pool:

+
<%= fast_link_to(@pool.name, controller: "pools", id: @pool.id) %>
+
<%= link_to_user(@pool.creator) %>
+ "> + <%= time_ago_in_words(@pool.created_at) %>ago + +
+<% end %> diff --git a/app/views/tickets/new_types/_set.html.erb b/app/views/tickets/new_types/_set.html.erb index 59333c1a3..f25caafa6 100644 --- a/app/views/tickets/new_types/_set.html.erb +++ b/app/views/tickets/new_types/_set.html.erb @@ -1,12 +1,12 @@ -<% unless @ticket.set %> - <% @found_item = false %> -
That set does not exist.
-<% else %> -
- <% @set = @ticket.set %> -

You are reporting the following set:

-
<%= fast_link_to(@set.name, controller: "set", action: "show", id: @set.id) %>
-
<%= link_to_user(@set.creator) %>
- "><%= time_ago_in_words(@set.created_at) %> ago -
-<% end %> +<% unless @ticket.set %> + <% @found_item = false %> +
That set does not exist.
+<% else %> +
+ <% @set = @ticket.set %> +

You are reporting the following set:

+
<%= fast_link_to(@set.name, controller: "set", action: "show", id: @set.id) %>
+
<%= link_to_user(@set.creator) %>
+ "><%= time_ago_in_words(@set.created_at) %> ago +
+<% end %> diff --git a/app/views/tickets/new_types/_user.html.erb b/app/views/tickets/new_types/_user.html.erb index 5efc0137e..adc9eef76 100644 --- a/app/views/tickets/new_types/_user.html.erb +++ b/app/views/tickets/new_types/_user.html.erb @@ -1,8 +1,8 @@ -<% unless @ticket.accused %> - <% @found_item = false %> -
That user does not exist.
-<% else %> -
- You are reporting/commending <%= link_to_user(@ticket.accused) %>. -
-<% end %> +<% unless @ticket.accused %> + <% @found_item = false %> +
That user does not exist.
+<% else %> +
+ You are reporting/commending <%= link_to_user(@ticket.accused) %>. +
+<% end %> diff --git a/app/views/tickets/new_types/_wiki.html.erb b/app/views/tickets/new_types/_wiki.html.erb index f5195c8d3..4f36b55b9 100644 --- a/app/views/tickets/new_types/_wiki.html.erb +++ b/app/views/tickets/new_types/_wiki.html.erb @@ -1,12 +1,12 @@ -<% unless @ticket.wiki %> - <% @found_item = false %> -
That wiki page does not exist.
-<% else %> -
- <% @wiki = @ticket.wiki %> -

You are reporting the following wiki page:

-
<%= link_to_wiki @wiki.title %>
- "><%= time_ago_in_words(@wiki.created_at) %> ago - <%= format_text(@wiki.body) %> -
-<% end %> \ No newline at end of file +<% unless @ticket.wiki %> + <% @found_item = false %> +
That wiki page does not exist.
+<% else %> +
+ <% @wiki = @ticket.wiki %> +

You are reporting the following wiki page:

+
<%= link_to_wiki @wiki.title %>
+ "><%= time_ago_in_words(@wiki.created_at) %> ago + <%= format_text(@wiki.body) %> +
+<% end %> diff --git a/app/views/tickets/types/_blip.html.erb b/app/views/tickets/types/_blip.html.erb index 20e2cae00..7ce8cff7b 100644 --- a/app/views/tickets/types/_blip.html.erb +++ b/app/views/tickets/types/_blip.html.erb @@ -1,13 +1,13 @@ -<% if @ticket.blip %> - - Reported Blip - - <%= link_to "Blip by #{@ticket.blip.creator_name}", blip_path(@ticket.blip) %> - - -<% else %> - - Reported Blip - Blip has been deleted - -<% end %> \ No newline at end of file +<% if @ticket.blip %> + + Reported Blip + + <%= link_to "Blip by #{@ticket.blip.creator_name}", blip_path(@ticket.blip) %> + + +<% else %> + + Reported Blip + Blip has been deleted + +<% end %> diff --git a/app/views/tickets/types/_comment.html.erb b/app/views/tickets/types/_comment.html.erb index 0297f9144..d8c530173 100644 --- a/app/views/tickets/types/_comment.html.erb +++ b/app/views/tickets/types/_comment.html.erb @@ -1,14 +1,14 @@ -<% if @ticket.comment %> - - Reported Comment - - <%= fast_link_to("Comment by #{@ticket.comment.creator_name}", comment_path(@ticket.comment)) %> on - <%= fast_link_to("post ##{@ticket.comment.post_id}", post_path(@ticket.comment.post_id)) %> - - -<% else %> - - Reported Comment - Comment has been deleted - -<% end %> \ No newline at end of file +<% if @ticket.comment %> + + Reported Comment + + <%= fast_link_to("Comment by #{@ticket.comment.creator_name}", comment_path(@ticket.comment)) %> on + <%= fast_link_to("post ##{@ticket.comment.post_id}", post_path(@ticket.comment.post_id)) %> + + +<% else %> + + Reported Comment + Comment has been deleted + +<% end %> diff --git a/app/views/tickets/types/_dmail.html.erb b/app/views/tickets/types/_dmail.html.erb index 5ee4c178a..d63ab33e4 100644 --- a/app/views/tickets/types/_dmail.html.erb +++ b/app/views/tickets/types/_dmail.html.erb @@ -1,13 +1,13 @@ - - Reported Message - - <% if @ticket.can_see_details?(CurrentUser) %> - <% @dmail = @ticket.dmail %> - <%= link_to "Message", dmail_path(@ticket.dmail) %> - sent from <%= link_to_user @ticket.dmail.from %> to - <%= link_to_user @ticket.dmail.to %> - <% else %> - Confidential - <% end %> - - \ No newline at end of file + + Reported Message + + <% if @ticket.can_see_details?(CurrentUser) %> + <% @dmail = @ticket.dmail %> + <%= link_to "Message", dmail_path(@ticket.dmail) %> + sent from <%= link_to_user @ticket.dmail.from %> to + <%= link_to_user @ticket.dmail.to %> + <% else %> + Confidential + <% end %> + + diff --git a/app/views/tickets/types/_namechange.html.erb b/app/views/tickets/types/_namechange.html.erb index e69de29bb..8b1378917 100644 --- a/app/views/tickets/types/_namechange.html.erb +++ b/app/views/tickets/types/_namechange.html.erb @@ -0,0 +1 @@ + diff --git a/app/views/tickets/types/_pool.html.erb b/app/views/tickets/types/_pool.html.erb index d38b2abfb..9741d2c53 100644 --- a/app/views/tickets/types/_pool.html.erb +++ b/app/views/tickets/types/_pool.html.erb @@ -1,6 +1,6 @@ -<% if @ticket.pool %> - - Reported Pool - <%= fast_link_to(@ticket.pool.name, controller: "pools", id: @ticket.pool.id) %> - -<% end %> \ No newline at end of file +<% if @ticket.pool %> + + Reported Pool + <%= fast_link_to(@ticket.pool.name, controller: "pools", id: @ticket.pool.id) %> + +<% end %> diff --git a/app/views/tickets/types/_set.html.erb b/app/views/tickets/types/_set.html.erb index bd6c666d5..ddcbb3383 100644 --- a/app/views/tickets/types/_set.html.erb +++ b/app/views/tickets/types/_set.html.erb @@ -1,6 +1,6 @@ -<% if (@set = PostSet.find_by_id(@ticket.disp_id)) %> - - Reported Set - <%= fast_link_to(@set.name, controller: "set", action: "show", id: @set.id) %> - -<% end %> \ No newline at end of file +<% if (@set = PostSet.find_by_id(@ticket.disp_id)) %> + + Reported Set + <%= fast_link_to(@set.name, controller: "set", action: "show", id: @set.id) %> + +<% end %> diff --git a/app/views/tickets/types/_user.html.erb b/app/views/tickets/types/_user.html.erb index 9b359855c..21d4c0bab 100644 --- a/app/views/tickets/types/_user.html.erb +++ b/app/views/tickets/types/_user.html.erb @@ -1,8 +1,8 @@ - - Reported User - <% if @ticket.can_see_details?(CurrentUser.user) %> - <%= link_to_user(@ticket.accused) %> - <% else %> - Confidential - <% end %> - \ No newline at end of file + + Reported User + <% if @ticket.can_see_details?(CurrentUser.user) %> + <%= link_to_user(@ticket.accused) %> + <% else %> + Confidential + <% end %> + diff --git a/app/views/upload_whitelists/_search.html.erb b/app/views/upload_whitelists/_search.html.erb index 479377b0a..881dbc340 100644 --- a/app/views/upload_whitelists/_search.html.erb +++ b/app/views/upload_whitelists/_search.html.erb @@ -1,7 +1,7 @@ -<%= simple_form_for(:search, url: upload_whitelists_path, method: :get, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> - <%= f.input :pattern, label: "Pattern", hint: "Use * for wildcard", input_html: { value: params[:search][:pattern]} %> - <%= f.input :note, label: "Note", as: "string", input_html: { value: params[:search][:note] } %> - <%= f.input :reason, label: "Ban Reason", input_html: { value: params[:search][:reason] } %> - <%= f.input :order, collection: [["Recently created", "id"], ["Last updated", "updated_at"], ["Pattern", "pattern"], ["Note", "note"]], selected: params[:search][:order] %> - <%= f.submit "Search" %> -<% end %> \ No newline at end of file +<%= simple_form_for(:search, url: upload_whitelists_path, method: :get, defaults: { required: false }, html: { class: "inline-form" }) do |f| %> + <%= f.input :pattern, label: "Pattern", hint: "Use * for wildcard", input_html: { value: params[:search][:pattern]} %> + <%= f.input :note, label: "Note", as: "string", input_html: { value: params[:search][:note] } %> + <%= f.input :reason, label: "Ban Reason", input_html: { value: params[:search][:reason] } %> + <%= f.input :order, collection: [["Recently created", "id"], ["Last updated", "updated_at"], ["Pattern", "pattern"], ["Note", "note"]], selected: params[:search][:order] %> + <%= f.submit "Search" %> +<% end %> diff --git a/app/views/upload_whitelists/edit.html.erb b/app/views/upload_whitelists/edit.html.erb index 3b901de01..c37fab0c0 100644 --- a/app/views/upload_whitelists/edit.html.erb +++ b/app/views/upload_whitelists/edit.html.erb @@ -1,22 +1,22 @@ -
-
-

Upload Whitelist

- - <%= error_messages_for "whitelist" %> - - <%= simple_form_for(@whitelist) do |f| %> - <%= f.input :pattern, label: "Pattern", as: :string %> - <%= f.input :note, label: "Note", as: :string %> - <%= f.input :allowed, label: "Upload Allowed", as: :boolean %> - <%= f.input :reason, label: "Ban Reason", as: :string %> - <%= f.input :hidden, label: "Hidden From Users", as: :boolean %> - <%= f.button :submit, "Save" %> - <% end %> -
-
- -<%= render "secondary_links" %> - -<% content_for(:page_title) do %> - Edit Upload Whitelist - <%= Danbooru.config.app_name %> -<% end %> +
+
+

Upload Whitelist

+ + <%= error_messages_for "whitelist" %> + + <%= simple_form_for(@whitelist) do |f| %> + <%= f.input :pattern, label: "Pattern", as: :string %> + <%= f.input :note, label: "Note", as: :string %> + <%= f.input :allowed, label: "Upload Allowed", as: :boolean %> + <%= f.input :reason, label: "Ban Reason", as: :string %> + <%= f.input :hidden, label: "Hidden From Users", as: :boolean %> + <%= f.button :submit, "Save" %> + <% end %> +
+
+ +<%= render "secondary_links" %> + +<% content_for(:page_title) do %> + Edit Upload Whitelist - <%= Danbooru.config.app_name %> +<% end %> diff --git a/app/views/users/upload_limit.html.erb b/app/views/users/upload_limit.html.erb index 3942390bf..1522b1a20 100644 --- a/app/views/users/upload_limit.html.erb +++ b/app/views/users/upload_limit.html.erb @@ -1,44 +1,44 @@ -

Upload Limit

-
- <% unless CurrentUser.can_upload_free? %> -

You can currently upload <%= CurrentUser.upload_limit %> posts. This limit is based on the following formula:

- - - -

- This means you are able to upload a maximum of <%= CurrentUser.upload_limit %> unapproved posts at a time. - Once a moderator approves some of your posts, you can upload more.
- You cannot upload anything within the first week of registration.
- If your limit ends up negative due to a large number of deleted posts, please contact <%= Danbooru.config.contact_email %> to have it corrected. -

- <% end %> - -

- <% unless CurrentUser.can_upload_free? %> - In addition to this, you are limited to 30 uploads per hour. - You also may not upload if you have no remaining tag edits per hour. - <% else %> - You are limited to 30 uploads per hour. - <% end %> -

- - - - <% unless CurrentUser.can_upload_free? %> -

- If either of these limits reaches zero, you may not upload until some time has passed and these limits increase automatically. -

- <% else %> -

- If this limit reaches zero, you may not upload until some time has passed and the limit increases automatically. -

- <% end %> -
+

Upload Limit

+
+ <% unless CurrentUser.can_upload_free? %> +

You can currently upload <%= CurrentUser.upload_limit %> posts. This limit is based on the following formula:

+ + + +

+ This means you are able to upload a maximum of <%= CurrentUser.upload_limit %> unapproved posts at a time. + Once a moderator approves some of your posts, you can upload more.
+ You cannot upload anything within the first week of registration.
+ If your limit ends up negative due to a large number of deleted posts, please contact <%= Danbooru.config.contact_email %> to have it corrected. +

+ <% end %> + +

+ <% unless CurrentUser.can_upload_free? %> + In addition to this, you are limited to 30 uploads per hour. + You also may not upload if you have no remaining tag edits per hour. + <% else %> + You are limited to 30 uploads per hour. + <% end %> +

+ + + + <% unless CurrentUser.can_upload_free? %> +

+ If either of these limits reaches zero, you may not upload until some time has passed and these limits increase automatically. +

+ <% else %> +

+ If this limit reaches zero, you may not upload until some time has passed and the limit increases automatically. +

+ <% end %> +
diff --git a/config/deploy/production.rb b/config/deploy/production.rb index 697e1f9a9..437b49345 100644 --- a/config/deploy/production.rb +++ b/config/deploy/production.rb @@ -6,4 +6,4 @@ server "saitou", :roles => %w(web app) server "oogaki", :roles => %w(worker) set :linked_files, fetch(:linked_files, []).push(".env.production") -set :rbenv_path, "/home/danbooru/.rbenv" \ No newline at end of file +set :rbenv_path, "/home/danbooru/.rbenv" diff --git a/config/docker/compose.yml b/config/docker/compose.yml index 7c9a36414..6e5ca844d 100644 --- a/config/docker/compose.yml +++ b/config/docker/compose.yml @@ -67,4 +67,4 @@ services: - db - memcached - archives - - redis \ No newline at end of file + - redis diff --git a/config/docker/danbooru-base b/config/docker/danbooru-base index e883a695c..893cca7a8 100644 --- a/config/docker/danbooru-base +++ b/config/docker/danbooru-base @@ -46,4 +46,4 @@ RUN yarn install COPY script/install/database.yml.templ /app/config/database.yml COPY script/install/danbooru_local_config.rb.templ /app/config/danbooru_local_config.rb EXPOSE 3000 -CMD sleep 1d \ No newline at end of file +CMD sleep 1d diff --git a/config/initializers/elasticsearch.rb b/config/initializers/elasticsearch.rb index a360d374d..93ba1e9fe 100644 --- a/config/initializers/elasticsearch.rb +++ b/config/initializers/elasticsearch.rb @@ -1 +1 @@ -Elasticsearch::Model.client = Elasticsearch::Client.new host: Danbooru.config.elasticsearch_host +Elasticsearch::Model.client = Elasticsearch::Client.new host: Danbooru.config.elasticsearch_host diff --git a/config/initializers/mailgun.rb b/config/initializers/mailgun.rb index 5a21dc1dd..aa5d120e0 100644 --- a/config/initializers/mailgun.rb +++ b/config/initializers/mailgun.rb @@ -1,3 +1,3 @@ -Mailgun.configure do |config| - config.api_key = Danbooru.config.mailgun_api_key -end +Mailgun.configure do |config| + config.api_key = Danbooru.config.mailgun_api_key +end diff --git a/config/initializers/mechanize_patch.rb b/config/initializers/mechanize_patch.rb index a8b830610..2cb949227 100644 --- a/config/initializers/mechanize_patch.rb +++ b/config/initializers/mechanize_patch.rb @@ -61,4 +61,4 @@ if Rails.env.test? alias_method :fetch_without_retry, :fetch alias_method :fetch, :fetch_with_retry end -end \ No newline at end of file +end diff --git a/config/initializers/serialization_method.rb b/config/initializers/serialization_method.rb index f4c16e2e4..aba3586bf 100644 --- a/config/initializers/serialization_method.rb +++ b/config/initializers/serialization_method.rb @@ -1 +1 @@ -ActiveModelSerializers.config.adapter = :json +ActiveModelSerializers.config.adapter = :json diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index b00f1cd47..19b9ea24d 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,9 +1,9 @@ -require 'sidekiq' - -Sidekiq.configure_server do |config| - config.redis = { url: Danbooru.config.redis_url } -end - -Sidekiq.configure_client do |config| - config.redis = { url: Danbooru.config.redis_url } -end +require 'sidekiq' + +Sidekiq.configure_server do |config| + config.redis = { url: Danbooru.config.redis_url } +end + +Sidekiq.configure_client do |config| + config.redis = { url: Danbooru.config.redis_url } +end diff --git a/config/secrets.yml b/config/secrets.yml index a3d89cfec..1273bd836 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -23,4 +23,4 @@ production: staging: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> - \ No newline at end of file + diff --git a/config/unicorn/staging.rb b/config/unicorn/staging.rb index 4bb84cebe..fb4a72e76 100644 --- a/config/unicorn/staging.rb +++ b/config/unicorn/staging.rb @@ -44,4 +44,4 @@ after_fork do |server, worker| if defined?(ActiveRecord::Base) ActiveRecord::Base.establish_connection end -end \ No newline at end of file +end diff --git a/db/seeds.yml b/db/seeds.yml index f5d59ebb4..02662c3a4 100644 --- a/db/seeds.yml +++ b/db/seeds.yml @@ -1,446 +1,446 @@ -images: - - tags: zoodystopia 2016 anthro bandage black_nose brown_fur canine clothed clothing - collar disney fox fur gloves_(marking) green_eyes looking_at_viewer male mammal - markings multicolored_fur nick_wilde open_shirt orange_fur pantssad shirt shock_collar - simple_background solo standing turningtides_(artist) white_background zootopia - url: https://static1.e621.net/data/87/8f/878f64f8df553ce09218bc9b1083b4e3.png - - tags: 5:4 2016 3_toes anthro barefoot canine claws clothed clothing cuddling disney - duo fabienne_growley female flat_chested fox green_eyes ipoke judy_hopps lagomorph - male mammal nick_wilde peter_moosebridge phone purple_eyes rabbit sitting smile - sofa soles television toes zootopia - url: https://static1.e621.net/data/62/f1/62f197461e755a7d4bd5884dc8ff20d6.jpg - - tags: begging begging_pose blue_fur blue_tail canine chest_tuft dipstick_tail facial_markings - fan_character feral feralized fluffy fur looking_away male mammal markings mask_(marking) - multicolored_fur multicolored_tail nintendo pokémon pokémon_(species) portrait red_eyes - riolu simple_background smile solo tuft two_tone_fur two_tone_tail umpherio_(umpherio) - video_games white_background white_fur white_tail xnirox - url: https://static1.e621.net/data/97/38/973887346d669d97c7a75b7324855773.png - - tags: felid pantherine 2017 armor big_breasts black_lips blue_eyes blue_hair bodysuit - breasts clothed clothing f-r95 female fingerless_gloves fluffy fluffy_tail gloves - hair inner_ear_fluff inside knee_pads long_tail looking_away looking_outside mammal - pink_noseshoulder_pads sitting skinsuit snow_leopard solo space spots tight_clothing - toeless_footwear yuna_snowleopard - url: https://static1.e621.net/data/34/7f/347fec14942b176b074c1cad64c31ad2.png - - tags: back_muscles 2015 anthro ass_up bed bedroom black_fur black_stripes book bookshelf - butt crawling feline fireplace fur green_eyes hax_(artist) inside kenket lofi - lying male mammal morning multicolored_fur nude on_floor on_front one_eye_closed - orange_fur painting pawpads platerug shaded solo striped_body stripes table tiger - vase white_fur window - url: https://static1.e621.net/data/sample/6f/f4/6ff406e64fe870f43512d863a8fd119b.jpg - - tags: pink_eyes 2018 anthro canine clothed clothing cookie digital_media_(artwork) - dog female food fur hair looking_at_viewer mammal nana_(fadey) open_mouthsmile - solo standing tofu93 - url: https://static1.e621.net/data/sample/0f/01/0f01bc5401835aa1a082b19e83a0e956.jpg - - tags: 2013 anthro beverage blue_fur blue_hair borny_(character) canine clothing - coffee digital_media_(artwork) food fox fur green_eyes hair hoodie male mammal - open_mouth phonesolo wolfy-nail - url: https://static1.e621.net/data/sample/ac/9f/ac9f231b988d4b6f43b66e89e1d5578e.jpg - - tags: clothed detailed_background fully_clothed holding_object menacing outside - standing yellow_sclera 2015 anthro cheetah clothing feline female flashlight gun - handgun mammal muscular muscular_female pistol police ranged_weaponsolo street_lamp - sunrise tirrel uniform weapon - url: https://static1.e621.net/data/sample/d3/ae/d3aee9d4de485f2be935e84ebbd971b7.jpg - - tags: 2015 ambiguous_gender anthro blue_eyes clothing cosplay costume day detailed_background - dragon dreamworks falvie fudge_the_otter how_to_train_your_dragon kigurumi mammal - membranous_wings mustelid night_fury open_mouth otter outsidesitting sky smile - solo star starry_sky sunset toothless wings - url: https://static1.e621.net/data/sample/0f/d1/0fd1d92190633265fb32a800d65c82d7.jpg - - tags: holding_object food ambiguous_gender beverage black_fur blue_fur blush canine - chigiri clothing coffee cup first_person_view fur happy long_ears lucario mammal - nintendo one_eye_closed pokémon red_eyes sitting smile solo steam video_games wink - url: https://static1.e621.net/data/5a/c6/5ac6787ce0216184bb1737ffc97972e7.png - - tags: android animatronic anthro canine clothed clothing exposed_endoskeleton eye_patch - eyewear five_nights_at_freddy's fox foxy_(fnaf) fur hook hook_hand machine male - mammal naoren piratered_fur robot simple_background solo topless video_games white_background - yellow_eyes - url: https://static1.e621.net/data/17/0a/170ad0093d771d4b99c59f9626712578.png - - tags: 2015 finger_claws 5_fingers <3 anthro blush boss_monster breasts caprine claws - clothed clothing eyebrows eyelashes female fur gastropod goat hi-biki hi_res horn - long_ears looking_at_viewer mammal poserobe simple_background smile snail solo - toriel undertale video_games white_fur wide_hips - url: https://static1.e621.net/data/sample/31/16/31162bd0709f5c79726eb55a05997237.jpg - - tags: 2017 4_toes anthro arnou barefoot black_fur black_nose blue_eyes canine clothed - clothing cuddling day detailed_background digitigrade duo fur hoodie koul male - male/male mammal outside red_eyes smile toes tree wolf wulfcole - url: https://static1.e621.net/data/sample/e2/4e/e24e60d0e2604a1e18de6ec698462e75.jpg - - tags: 2014 anthro black_nose blue_eyes blush brown_fur clothed clothing collar countershade_face - countershading female flower flower_in_hair fur headshot_portrait kiki looking_away - mammal markings multicolored_fur mustelid open_mouth otter plant portrait rarakiesimple_background - solo spots teeth tongue two_tone_fur whiskers white_fur - url: https://static1.e621.net/data/8d/8e/8d8ec834c0b6bd02181510e3bc3f7e4d.png - - tags: pretending anthro antlers brown_fur cellphone cervine cloud deer duo feline - fur green_eyes hi_res horn humor imminent_death lion male mammal nbowa outside - phone predator/preyselfie sky tirrel tirrel_(character) tongue tongue_out tree - url: https://static1.e621.net/data/sample/d9/0e/d90ea5d58bbb37f6c08d054946a478f9.jpg - - tags: "... ambiguous_gender anthro black_fur blue_fur blush canine close-up crossed_arms - fur icon jia looking_at_viewer lucario mammal nintendo pokémon pokémon_(species) red_eyes - simple_background solo tan_fur video_games white_background" - url: https://static1.e621.net/data/sample/db/b6/dbb6db28e0514bb981f417edf6479c9a.jpg - - tags: winged_arms wings ... absurd_res anthro avian beak bird blush breath_of_the_wild - clothed clothing dialogue english_text feathers hi_res kass_(zelda) male muscular - muscular_male nintendo outsiderito sketch solo tacklebox text the_legend_of_zelda - video_games - url: https://static1.e621.net/data/sample/c6/a3/c6a32022972d9807cfaae5000f45b2c4.jpg - - tags: too_early_for_this 2014 5_fingers annoyed anthro beverage big_eyebrows black_eyebrows - black_eyes black_fur black_hair black_nose black_shirt blue_fur bust_portrait - canine clothed clothing coffee coffee_mug countertop crossed_arms cup dialogue - digital_media_(artwork) ear_piercing english_text eyebrows facial_hair facial_piercing - food fur gauged_ear goatee grumpy hair holding_cup holding_object hot_drink lip_piercing - lol_comments looking_at_viewer male mammal multicolored_fur multicolored_hair - nose_piercing nose_ring open_mouth piercing portrait profanityreaction_image restricted_palette - shirt signature simple_background sitting sky3 skye_blue solo speech_bubble steam - striped_ears table teeth text thick_eyebrows two_tone_fur two_tone_hair white_background - white_fur white_hair wolf - url: https://static1.e621.net/data/sample/16/61/1661025f6995846607e709c6da99e123.jpg - - tags: 2013 ambiguous_gender black_eyes cloud cloudscape colorful detailed_background - feral fish happy lol_comments marine open_mouth outside rainbow rainbow_archreaction_image - shark sky solo sparkles spunky_(artist) super_gay teeth - url: https://static1.e621.net/data/e5/03/e503e7d3465337448b715cfd6457edd0.jpg - - tags: 2017 anthro belly big_breasts breasts brown_hair canine chinese_clothing chinese_dress - cleavage cleavage_cutout clothed clothing dress female food fox gradient_background - hair hairclip hi_res kemono long_hair looking_at_viewer mammal purple_eyessetouchi_kurage - simple_background slightly_chubby solo voluptuous waiter wide_hips - url: https://static1.e621.net/data/sample/b1/0d/b10d8740126b4fb20d4b21920d131c8f.jpg - - tags: brown_hair orange_hair sitting striped_body striped_fur striped_tail 2018 - <3 anthro black_topwear blue_eyes blue_topwear breasts clothed clothing collaboration - countershade_legs countershade_torso countershading day deymos digital_media_(artwork) - dipstick_tail domestic_cat felid feline felis female fingerless_(marking) flower - fully_clothed fur hair inside iskra legwear looking_aside mammal multicolored_body - multicolored_fur multicolored_tail orange_body orange_fur panties pink_nose plantshaded - shirt solo stripes sunflower tan_body tan_fur thigh_highs underwear url vera_(iskra) - white_legwear window - url: https://static1.e621.net/data/sample/80/8d/808d424fd5c3ccbaddac9fc5b92f028a.jpg - - tags: 2016 anthro blush buckteeth canine disney duo embarrassed english_text female - fireworks fox freedomthai fur green_eyes grey_fur half-closed_eyes hand_on_head - hi_res holding_object judy_hopps lagomorph larger_male long_ears male male/female - mammal nick_wilde night open_mouth orange_fur outside pen predator/prey purple_eyes - rabbitromantic_ambiance size_difference smaller_female smile smirk tears teeth - text zootopia - url: https://static1.e621.net/data/sample/c6/32/c6321f137f68f99f2bee51dba3bf1de5.jpg - - tags: ambiguous_gender capcom cub dragon horn kneeling kosian looking_at_viewer - membranous_wings monster_hunter red_eyes rukodiora scalie simple_background solo - video_games white_background wings young - url: https://static1.e621.net/data/sample/da/92/da922cd07342972262e98de824595cd1.jpg - - tags: 2014 anthro beach bikini bikini_top blue_eyes bottomless clothed clothing - cloud detailed_background digital_media_(artwork) ear_piercing falvie fangs female - grin hair looking_at_viewer mammal markings mustelid neck_tuft otter outside piercingsand - seaside short_hair sky smile solo swimsuit tuft water white_hair - url: https://static1.e621.net/data/sample/aa/3f/aa3f6074e6c14ff78b40ff51f109869b.jpg - - tags: casual_nudity day eyebrows eyelashes grey_hair half-closed_eyes looking_aside - multicolored_fur multicolored_hair partially_submerged skinny_dipping slim snout - sunlight swimming tan_fur thick_tail 2015 anthro back_muscles blonde_hair brown_eyes - brown_fur brown_hair brown_nose butt digital_media_(artwork) eyewear fangs female - feral fish fur goggles hair hi_res high-angle_view mammal marine mikhaila mouth_hold - mustelid nude otter patreonshort_hair solo teeth tsampikos water wet wide_hips - url: https://static1.e621.net/data/sample/82/ab/82abacf96b5e3bde9d92ef6e5e0197eb.jpg - - tags: 5_fingers anthro_on_anthro black_nose blush brown_fur brown_nose brown_stripes - brown_tail canid cheek_tuft chest_tuft embrace eyebrows felid fluffy fluffy_tail - gloves_(marking) glowing_ears glowing_fur glowing_spots green_fur green_spots - holding_object holding_plush humanoid_hands interspecies markings orange_tail - pantherine romantic_couple snout spots spotted_fur striped_fur striped_tail tan_belly - tan_fur tuft white_belly white_tail anthro bed bed_sheet bedding bioluminescence - brown_hair canine cuddling digital_media_(artwork) duo eyes_closed fox fur gabe_(mytigertail) - glowing hair hug inside lan lying male male/male mammal multicolored_fur mytigertail - nude on_bed on_side open_mouth orange_fur orange_stripes pillow plushie rating:q - sleeping smile spooning stripes tiger two_tone_fur white_fur zeta-haru - url: https://static1.e621.net/data/sample/b8/89/b889bbc7002cc1152ed7f1c8e3a14670.jpg - - tags: 2014 3:2 afternoon alien big_ears black_scales blue_eyes blue_fur blue_nose - claws clothed clothing cosplay costume crossover daww disney dragon dreamworks - duo experiment_(species) feral fish food fur grasp green_sclera hat head_tuft - headgear holding_food holding_object how_to_train_your_dragon inside lilo_and_stitch - long_ears looking_down looking_up lying male marine membranous_wings night_fury - no_sclera offering_(disambiguation) offering_food offering_to_another on_front - on_ground outstretched_arms raised_arm scales scalie scarf sharp_teeth size_difference - smile standing stitch sunlight teeth toe_claws toothless tsaoshin wings - url: https://static1.e621.net/data/50/cc/50cc1f4f731dca8cb66fdb9fd42bc57d.png - - tags: 2017 ambiguous_form ambiguous_gender big_ears brown_eyes canid canine derp_eyes - dipstick_ears ears_down english_text fangs felisrandomis fennec fox frown fur - headshot_portrait humor inner_ear_fluff lol_comments mammal multiple_poses open_mouth - open_smile portrait pose screaming simple_background smile solo tan_fur teeth - text the_truth tongue weasyl - url: https://static1.e621.net/data/79/d7/79d74e8154dcea5339ff51f77fd3c98b.png - - tags: 2018 anthro black_hair blue_eyes blush canid canine canis clothing domestic_dog - faceless_male female hair human male mammal on_lap sally_(povinne10) talilly tongue - tongue_out - url: https://static1.e621.net/data/08/1e/081e279f730cccb5948853e8d1ea6a9f.jpg - - tags: 2018 <3 ambiguous_gender blush coal_(rakkuguy) eyes_closed happy human kobold - mammal motion_lines one_eye_closed open_mouth petting rakkuguy scalie simple_background - smile tailwag tongue tongue_out white_background - url: https://static1.e621.net/data/48/5d/485d385d6bb518ee12c78747054e827c.jpg - - tags: 2018 <3 3_toes ambiguous/ambiguous ambiguous_gender anthro anthro_on_anthro - blue_fur butt canid canine cewljoke chest_tuft cute_fangs duo evolutionary_family - eyes_closed fur hindpaw hi_res hug kneeling level_difference lucario mammal nintendo - nude pawpads paws pink_pawpads pokémon pokémon_(species) red_eyes riolu signature - simple_background smile spikes toes tuft video_games white_background wholesome - url: https://static1.e621.net/data/69/14/6914390405ab241003e48b4cfeeea5f3.png - - tags: 2017 absurd_res ambiguous_gender anatomy black_background blep canid canine - cross-eyed diagram english_text feral fox fur hi_res humor mammal meme red_fox - riot_the_red_fox simple_background sitting solo text tongue tongue_out whiskers - zillion_ross - url: https://static1.e621.net/data/8b/a7/8ba7610b0a2b91d91aebf4a55e131aa7.png - - tags: 2018 4_toes anatomy black_background black_fur black_hair black_nose blue_fur - blue_hair blue_tongue canid canine claws diagram ear_piercing english_text feral - fox fur fur_markings gloves_(marking) hair hi_res humor industrial_piercing male - mammal markings meme mostly_nude multicolored_fur multicolored_hair open_mouth - original_character_do_not_steal owo owo_whats_this paws piercing quadruped restricted_palette - scarf simple_background socks_(marking) solo teeth text the_truth toe_claws toes - tongue two_tone_hair white_fur zillion_ross - url: https://static1.e621.net/data/63/3b/633bbadd77a49e662768428ffc026491.png - - tags: 2017 <3 alcohol avian beak beer beverage bird black_feathers bottle corvid - crow deep_throat digital_media_(artwork) english_text feathers feral hi_res humor - lol_comments oral oral_penetration penetration solo swish talons text wings - url: https://static1.e621.net/data/7c/d9/7cd90352fa57ddaeb3f422de355e727c.jpg - - tags: 2017 5_fingers alternate_form anthro canid canine clothed clothing cup cups_on_ears - cute_fangs dagger detailed_background dialogue digital_media_(artwork) dutch_angle - english_text fox fur gregg_(nitw) happy inside jacket knife koul looking_at_viewer - male mammal melee_weapon night_in_the_woods open_mouth orange_fur smile solo speech_bubble - text video_games weapon - url: https://static1.e621.net/data/4f/be/4fbe36ed49bf8d501edb8509a554837d.jpg - - tags: ambiguous_gender canid canine conditional_dnp daww derp_eyes digital_media_(artwork) - digital_painting_(artwork) ears_back eyes_closed feral flexible fluffy fox full-length_portrait - fur humor lol_comments mammal markings oops orange_fur paws playing portrait red_fox - side_view simple_background snow socks_(marking) solo trunchbull upside_down whiskers - white_background white_fur - url: https://static1.e621.net/data/94/d1/94d108d2e4ed476a113f93e7768accce.jpg - - tags: anthro canid canine clothed clothing english_text fangs female fur hair image_macro - impact_(font) jurassic_park mammal meme nasusbot open_mouth parody profanity reaction_image - skrillex smile solo teeth text - url: https://static1.e621.net/data/cb/a4/cba428d3227dd7358dbf63787c759e8d.png - - tags: "<3 3_toes ambiguous_gender anthro barefoot biped black_fur black_markings - blue_fur blue_tail blush canid canine cel_shading cheek_tuft collar digital_media_(artwork) - digitigrade facial_markings feet fur fur_tuft gloves_(marking) gradient_background - kneeling leash leash_in_mouth lucario mammal markings mouth_hold multicolored_fur - neck_tuft nintendo nude object_in_mouth paws pink_background pokémon pokémon_(species) - pseudo_clothing rakkuguy red_eyes shaded side_view simple_background smile snout - solo spikes submissive toes tuft video_games white_background yellow_fur" - url: https://static1.e621.net/data/a1/1e/a11e49bd7c556049770b3e905e9528ef.png - - tags: 2013 4_fingers anthro barefoot beverage black_fur black_nose canid canine - clothed clothing coffee coffee_mug cup dipstick_ears dipstick_tail english_text - eyes_closed fennec fingerless_(marking) fluffy fluffy_tail food fox fully_clothed - fur gloves_(marking) hair hi_res inner_ear_fluff lying male mammal markings multicolored_tail - orange_fur orange_hair pants reaching shirt side_view simple_background sleeping - socks_(marking) solo sound_effects text thanshuhai tired toeless_(marking) tongue - tongue_out white_background white_fur zzz - url: https://static1.e621.net/data/8d/eb/8deb2ae9fe81f9f6383a24c591bdd3be.png - - tags: 2016 alolan_vulpix altered_reflection ambiguous_gender black_nose brown_eyes - brown_hair canid canine contrast digital_media_(artwork) duality feral fur grey_nose - hair hindpaw hi_res inner_ear_fluff looking_at_viewer mammal multi_tail nintendo - paws pokémon pokémon_(species) realistic reflection regional_variant solo split_screen - standing symmetry tamberella tan_fur video_games vulpix white_fur - url: https://static1.e621.net/data/7e/11/7e11e929a5c5b58078d600d3aa23cf21.jpg - - tags: anthro canid canine clothed clothing disney edit english_text fox fully_clothed - gradient_background lyrics male mammal michael_jackson music nick_wilde simple_background - smile smooth_criminal solo song sound text zootopia 羽默空_(artist) - url: https://static1.e621.net/data/fc/09/fc090f0332c2ae9e91bb6953179bceaf.jpg - - tags: anthro antlers brown_fur cellphone cervid cloud duo felid fur green_eyes hi_res - horn humor imminent_death lion male mammal nbowa outside pantherine phone predator/prey - pretending selfie sky tirrel tirrel_(character) tongue tongue_out tree - url: https://static1.e621.net/data/d9/0e/d90ea5d58bbb37f6c08d054946a478f9.jpg - - tags: 2016 anthro black_fur black_hair black_nose blizzard_entertainment bound breasts - canid canine cheek_tuft conditional_dnp crying digital_media_(artwork) domestic_cat - dream_eater duo e621 english_text eyelashes fan_character felid feline felis female - feral floof flora_fauna fluffy food food_creature fruit fur green_eyes hair hi_res - horn humor impact_(font) kingdom_hearts lol_comments looking_up mammal melon meloncat - melonyan meme meow_wow meta nude paralee_(character) plant poof profanity rainbow - ratte sad square_enix tardar_sauce tears technicolor_yawn text tuft video_games - vomit wall_of_text warcraft watermelon were werecanid werecanine werewolf worgen - url: https://static1.e621.net/data/42/2a/422aaf2c210d6e0e48480ce419b06896.png - - tags: 2016 <3 4_fingers abstract_background anthro asriel_dreemurr big_eyes black_background - blush boss_monster bovid braeburned brown_background caprine cheek_tuft clothing - cute_fangs digital_media_(artwork) fangs feels fur gesture goat gradient_background - green_clothing green_topwear hair half-length_portrait hand_heart head_tuft hi_res - long_ears looking_at_viewer love male mammal multicolored_clothing open_mouth - pink_tongue portrait sharp_teeth signature simple_background smile solo sweater - teeth tongue tuft undertale video_games white_fur yellow_bottomwear yellow_clothing - young - url: https://static1.e621.net/data/14/e7/14e7eff45c61ba29e02f4f59846dc6bc.png - - tags: "... <3 absurd_res ambiguous_gender beady_eyes blep dialogue english_text - feral forked_tongue hi_res iron_and_whine python reptile scalie simple_background - snake solo text tongue tongue_out traditional_media_(artwork) white_background" - url: https://static1.e621.net/data/7f/6a/7f6af5deef179238510cfa1d606ef81f.jpg - - tags: 2016 alantka anthro canid canine cuddling detailed_background disney duo embrace - eyes_closed female forest fox fur gloves_(marking) green_eyes grey_fur judy_hopps - lagomorph long_ears looking_down male mammal markings nick_wilde orange_fur outside - predator/prey rabbit romantic_couple size_difference smile style_parody tree zootopia - url: https://static1.e621.net/data/e1/28/e128617350d9e02bf816f0d4d529c210.jpg - - tags: 2016 absurd_res anthro barefoot bed bedroom bracelet buckteeth canid canine - choker dancing dennyvixen dipstick_tail disney duo earbuds eyes_closed female - fox fur gloves_(marking) good_morning grey_fur happy headphones hi_res inner_ear_fluff - inside ipod ipod_nano jewelry judy_hopps lagomorph long_ears male mammal markings - multicolored_tail nick_wilde on_bed open_mouth orange_fur pawpads portable_music_player - predator/prey rabbit smile teeth two_tone_tail upscale zootopia - url: https://static1.e621.net/data/2e/d4/2ed4a63c7105f9e6ca099033403b242a.png - - tags: ">.< :< :> :| •≠• :3 ambiguous_gender black_eyes :d d: expressions food_creature - frown group humor looking_at_viewer low_res mint not_furry :o o3o open_mouth plastic - real smile tic_tac tongue tongue_out w4nw4n x_x" - url: https://static1.e621.net/data/e5/1e/e51edfb8ec608817cca55d9bf7579c47.jpg - - tags: absurd_res anthro bed bouquet canid canine canis clothing duo eyes_closed - female flower_bouquet hair hi_res human larger_anthro larger_female male mammal - size_difference sleeping smaller_human smaller_male spooning vanchamarl were werecanid - werecanine werewolf wholesome wolf zephra - url: https://static1.e621.net/data/14/b5/14b5352ee09a0dee5a565f5c0e6bfb3c.png - - tags: 2016 anthro blue_eyes boss_monster bovid caprine cellphone crossover disney - english_text female fur goat holding_object horn image_macro long_ears mammal - meme monsters_inc open_mouth parody phone pixar reaction_image solo sulley taken_(movie) - text toriel undertale video_games white_fur wolfjedisamuel - url: https://static1.e621.net/data/fb/52/fb52b8b36ecb85eaf155855a23e70f24.png - - tags: animated anthro asriel_dreemurr blush boss_monster bovid caprine clothing - computer edit empty_eyes english_text floppy_ears goat happy hyperactive lol_comments - male mammal o_o simple_background smile solo text undertale undertale-tales video_games - url: https://static1.e621.net/data/bf/3c/bf3ce93ea4f3e7e3719c59b6557343b0.gif - - tags: 2016 angry anthro antlers bell cervid collar computer furry_problems green_eyes - horn laptop lol_comments male mammal reaction_image solo tirrel tirrel_(character) - url: https://static1.e621.net/data/9c/39/9c39de16aa06ea3afbc0ca4cd3137960.jpg - - tags: anthro big_breasts black_fur black_nose blue_eyes breasts claws clothed clothing - english_text female fur giant_panda gillpanda gillpanda_(character) looking_at_viewer - mammal morbidly_obese motivational_poster multicolored_fur obese overweight overweight_female - pawpads pen sharp_teeth simple_background smile solo teeth text thumbs_up two_tone_fur - ursid white_background white_fur - url: https://static1.e621.net/data/fa/67/fa67485134b0ee19fdaa49a68161f4f5.jpg - - tags: 2015 anthro asriel_dreemurr big_eyes boss_monster bovid caprine clothed clothing - fangs fatz_geronimo goat hoodie horn long_ears male mammal purple_background reaction_image - simple_background solo undertale video_games wide_eyed - url: https://static1.e621.net/data/f1/8d/f18db1184cf4c62d7afbdf8fd28f39f7.png - - tags: 2015 anatomy anthro asriel_dreemurr boss_monster bovid bukoya-star caprine - chart child clothed clothing cub english_text flower fur goat green_eyes grey_background - hi_res long_ears looking_at_viewer male mammal open_mouth plant simple_background - solo text undertale video_games white_fur young - url: https://static1.e621.net/data/b6/33/b633e381a700c619f7ea22666cf6b93d.jpg - - tags: 2015 <3 anthro asriel_dreemurr_(god_form) blue_background boss_monster bovid - caprine clothed clothing digital_media_(artwork) eating fluffy_hair fur gem goat - hair horn looking_at_viewer male mammal pocky red_eyes robe saturnspace simple_background - solo undertale video_games white_fur white_hair - url: https://static1.e621.net/data/8b/80/8b8000f1845841e50515eb0aa224abfb.png - - tags: 2015 ambiguous_gender baseball_cap beady_eyes black_eyes digital_media_(artwork) - feral forked_tongue grey_tongue half-length_portrait hat lol_comments meme mostly_nude - portrait purple_headwear python reptile scalie simple_background smile snake solo - tongue tongue_out unknown_artist white_background - url: https://static1.e621.net/data/bf/f6/bff630817262325b514eee7ff197802e.png - - tags: 2015 ambiguous_gender avian beak bird bread cere_(feature) columbid common_pigeon - crumbs cryptid-creations derp_eyes doing_it_wrong feathers feral flour folded_wings - food humor in_bread lol_comments meme pigeon red_eyes simple_background solo watermark - what white_background - url: https://static1.e621.net/data/f9/1f/f91f92ac563c3bbe4e569d68a46dfafe.png - - tags: 2015 ambiguous_gender anthro blue_eyes clothing cosplay costume day detailed_background - dragon dreamworks falvie fudge_the_otter how_to_train_your_dragon kigurumi mammal - membranous_wings mustelid night_fury open_mouth otter outside sitting sky smile - solo star starry_sky sunset toothless wings - url: https://static1.e621.net/data/0f/d1/0fd1d92190633265fb32a800d65c82d7.png - - tags: 2015 5_fingers ambiguous_gender anthro black_lips black_nose canid canine - canis controller domestic_cat duo eye_contact felid feline felis fluffy fluffy_tail - fur grey_fur handpaw hax_(artist) inside jackal kenket lamp lofi long_mouth looking_at_another - looking_down looking_up lying mammal no_sclera nude on_back orange_eyes pawpads - paws pink_nose reaching remote_control romantic_couple shaded side_view slice_of_life - smile snout sofa table tv_remote whiskers white_fur yellow_eyes - url: https://static1.e621.net/data/0c/09/0c09080148c52ed89f16fe8fbc731dcf.jpg - - tags: 2012 anthro beverage black_fur building cafe camera_view canid canine car - chair cheek_tuft clothed clothing coffee coffee_mug coffee_shop cup detailed_background - digital_media_(artwork) eyebrows fog food fox fur green_eyes hair half-length_portrait - high-angle_view inside looking_at_viewer male mammal multicolored_fur orange_fur - orange_hair portrait red_fox selfie sitting slice_of_life smile solo table thanshuhai - tuft vehicle white_fur - url: https://static1.e621.net/data/a0/47/a0476a240b0b780b926d831a3e6426ea.png - - tags: angry blue_body blue_eyes blue_hair blush dialogue english_text equine eyelashes - eyes_closed female friendship_is_magic hair horn horse humor long_hair mammal - my_little_pony open_mouth orange_background pink_tongue princess_luna_(mlp) profanity - reaction_image simple_background solo sweat teeth text the_truth tongue unknown_artist - winged_unicorn wings - url: https://static1.e621.net/data/ef/e5/efe507d244c5841d8496ce52f4f706a6.png - - tags: "... ambiguous_gender bed bedding black_fur blanket checkered_background domestic_cat - english_text felid feline felis female fur garfield_(series) lying mae_(nitw) - mammal night_in_the_woods on_bed on_front pattern_background reaction_image simple_background - solo speech_bubble text under_covers unknown_artist video_games" - url: https://static1.e621.net/data/19/43/194344f13372ea3e80ef007dd56463c2.png - - tags: 2015 anthro cheetah clothed clothing detailed_background felid feline female - flashlight fully_clothed gun handgun holding_object mammal menacing muscular muscular_female - outside pistol police ranged_weapon solo standing street_lamp sunrise tirrel uniform - weapon yellow_sclera - url: https://static1.e621.net/data/d3/ae/d3aee9d4de485f2be935e84ebbd971b7.jpg - - tags: 2015 anthro antlers bell blue_eyes brown_hair canid canine car cervid cheetah - clothed clothing collar comic dialogue driver driving duo english_text felid feline - female green_eyes hair hat headlight hi_res horn humor inside_car male mammal - outside police profanity running text tirrel tirrel_(character) uniform vehicle - url: https://static1.e621.net/data/ed/e7/ede74f19c7adc6115fb751d729eceaf8.jpg - - tags: 2013 ambiguous_gender angry brown_fur canid canine chibi dipstick_tail english_text - feral fox fur humor mammal markings multicolored_fur multicolored_tail orange_fur - profanity running serious simple_background socks_(marking) solo technicolorpie - technicolor_pie text two_tone_tail white_background white_fur yellow_fur - url: https://static1.e621.net/data/44/53/4453fcdd6d4ce1cf6d6da88c9a35bafc.png - - tags: 2013 abstract_background ambiguous_gender anthro arm_support blonde_hair bow_tie - bust_portrait clothed clothing coat cosplay digital_media_(artwork) felid fur - gene_wilder hair half-closed_eyes hat humor inner_ear_fluff leaning_on_elbow lol_comments - long_hair low_res mammal meme pantherine parody portrait reaction_image smile - solo tassy tiger top_hat willy_wonka willy_wonka_and_the_chocolate_factory yellow_eyes - yellow_fur - url: https://static1.e621.net/data/d1/bb/d1bbf569513c5acf13b1be36d1d64bff.png - - tags: begging begging_pose blue_fur blue_tail canid canine chest_tuft conditional_dnp - dipstick_tail facial_markings fan_character feral feralized fluffy fur looking_away - male mammal markings mask_(marking) multicolored_fur multicolored_tail nintendo - pokémon pokémon_(species) portrait red_eyes riolu simple_background smile solo - tuft two_tone_fur two_tone_tail umpherio_(umpherio) video_games white_background - white_fur white_tail xnirox - url: https://static1.e621.net/data/97/38/973887346d669d97c7a75b7324855773.png - - tags: 2014 <3 anthro avian beak bird black_eyes black_nose blue_body blue_feathers - blue_jay blush brown_fur cartoon_network chest_tuft comic corvid dialogue duo - english_text eyes_closed fangs feathers fur grey_beak hi_res kissing kissing_cheek - love male male/male mammal markings mordecai_(regular_show) open_beak open_mouth - procyonid raccoon regular_show rigby_(regular_show) romantic_couple simple_background - stripes surprise tan_fur teeth text tongue tuft white_background white_body white_feathers - wholesome xiamtheferret - url: https://static1.e621.net/data/ca/c9/cac98850f5b5b48440c100ad800caac1.png - - tags: anthro blonde_hair blue_eyes bone_necklace breasts carnivore clothed clothing - digital_media_(artwork) domestic_cat eating eyebrows felid feline felis female - food front_view hair half-length_portrait holding_food holding_object inuki inuki_(character) - jewelry mammal meat melloque necklace pink_nose ponytail portrait shirt shirt_logo - signature simple_background smile solo steak teeth - url: https://static1.e621.net/data/63/43/63433706609c428f2027986940547834.png - - tags: 2015 applejack_(mlp) blonde_hair cutie_mark earth_pony equine face_paint feathers - female feral friendship_is_magic green_eyes hair headdress hi_res horse jewelry - looking_at_viewer mammal my_little_pony native_american necklace pony portrait - santagiera solo teeth - url: https://static1.e621.net/data/ac/85/ac85e5ea07ae712946bb897bff734d59.jpg - - tags: 2015 animatronic anthro avian beak beverage bird blue_eyes blush bonnie_(fnaf) - canid canine cellphone chica_(fnaf) chicken eye_patch eyewear five_nights_at_freddy's - food fox foxy_(fnaf) freddy_(fnaf) group happy hat humor kissing lagomorph laugh - looking_away machine male male/male mammal phone purple_eyes rabbit robot smile - spin_the_bottle ursid video_games xiamtheferret yellow_eyes - url: https://static1.e621.net/data/be/55/be5581393bcf2451ca90c16ba48c694c.png - - tags: 2014 anthro antiander blue_eyes canid canine clothed clothing dress feathered_wings - feathers female fox gloves hair heterochromia hi_res holly_(plant) long_hair mammal - plant solo source_request white_hair wings - url: https://static1.e621.net/data/7c/8a/7c8a07df68f6b8c93d425158396df811.png - - tags: 2012 ambiguous_gender black_fur black_nose eeveelution fadingsky feral fire - fur markings nintendo pink_background pokémon pokémon_(species) red_eyes simple_background - smoke solo umbreon video_games yellow_markings - url: https://static1.e621.net/data/d8/2f/d82fc9c3bfa78c17db4d117950063124.png - - tags: 2014 ass_up avian beak blue_eyes blue_fur braeburned digital_media_(artwork) - earth_pony equine feathered_wings feathers female feral friendship_is_magic fur - gilda_(mlp) group gryphon hair horse laser laser_pointer mammal multicolored_hair - my_little_pony pegasus pink_fur pink_hair pinkie_pie_(mlp) pony purple_eyes rainbow_dash_(mlp) - rainbow_hair tongue tongue_out wings yellow_eyes - url: https://static1.e621.net/data/8c/08/8c08e77a944dd6df29eb3e908f5bd93f.png - - tags: ambiguous_gender anthro bust_portrait canid canine canis close-up darkwingo - dingo eye_reflection fluffy green_background green_eyes head_tilt hi_res hybrid - jewelry mammal markings necklace portrait scar simple_background smile solo thanshuhai - wolf - url: https://static1.e621.net/data/d7/10/d710ff227b96e59a655d152ac2fcc9f7.jpg - - tags: 2014 <3 anthro beverage beverage_can black_hair blue_hair blue_highlights - clothing collar digital_media_(artwork) domestic_cat fangs felid feline felis - female food gradient_hair green_eyes hair highlights jacket looking_at_viewer - mammal smile solo tentacletongue wolfy-nail young - url: https://static1.e621.net/data/86/94/86942ce7f5be8ba952fef914c5593d2e.jpg - - tags: 2012 ambiguous_gender bed bedding blanket blue_eyes eeveelution feral hi_res - looking_at_viewer lying nintendo on_bed on_front open_mouth pawpads pokémon pokémon_(species) - shadow solo tartii under_covers vaporeon video_games watermark - url: https://static1.e621.net/data/c0/d4/c0d4964ebc0fb0eeddb61bc03cbc6a2b.jpg - - tags: 2014 5:4 anthro atryl avian beak black_feathers brown_feathers cloud digital_media_(artwork) - duo eye_contact feathered_wings feathers female friendship_is_magic genevieve_(mlp) - grass greta_(mlp) grey_eyes gryphon hug my_little_pony one_eye_closed outside - sky smile white_feathers wings wink - url: https://static1.e621.net/data/67/c9/67c952de260ede67d0fe507bb99d3a6e.png - - tags: 2014 3_toes ambiguous_gender animated anthro ass_up black_scales butt digitigrade - dragon felid feral group hindpaw humor inside_train lamp loop low_res male mammal - membranous_wings metro multicolored_scales paws pushing rubble scales scalie size_difference - solo_focus subway tirrel toes train tunnel two_tone_scales vehicle white_scales - wings - url: https://static1.e621.net/data/7d/0d/7d0de8443bad63b6bd56a24ca0d0fb98.gif +images: + - tags: zoodystopia 2016 anthro bandage black_nose brown_fur canine clothed clothing + collar disney fox fur gloves_(marking) green_eyes looking_at_viewer male mammal + markings multicolored_fur nick_wilde open_shirt orange_fur pantssad shirt shock_collar + simple_background solo standing turningtides_(artist) white_background zootopia + url: https://static1.e621.net/data/87/8f/878f64f8df553ce09218bc9b1083b4e3.png + - tags: 5:4 2016 3_toes anthro barefoot canine claws clothed clothing cuddling disney + duo fabienne_growley female flat_chested fox green_eyes ipoke judy_hopps lagomorph + male mammal nick_wilde peter_moosebridge phone purple_eyes rabbit sitting smile + sofa soles television toes zootopia + url: https://static1.e621.net/data/62/f1/62f197461e755a7d4bd5884dc8ff20d6.jpg + - tags: begging begging_pose blue_fur blue_tail canine chest_tuft dipstick_tail facial_markings + fan_character feral feralized fluffy fur looking_away male mammal markings mask_(marking) + multicolored_fur multicolored_tail nintendo pokémon pokémon_(species) portrait red_eyes + riolu simple_background smile solo tuft two_tone_fur two_tone_tail umpherio_(umpherio) + video_games white_background white_fur white_tail xnirox + url: https://static1.e621.net/data/97/38/973887346d669d97c7a75b7324855773.png + - tags: felid pantherine 2017 armor big_breasts black_lips blue_eyes blue_hair bodysuit + breasts clothed clothing f-r95 female fingerless_gloves fluffy fluffy_tail gloves + hair inner_ear_fluff inside knee_pads long_tail looking_away looking_outside mammal + pink_noseshoulder_pads sitting skinsuit snow_leopard solo space spots tight_clothing + toeless_footwear yuna_snowleopard + url: https://static1.e621.net/data/34/7f/347fec14942b176b074c1cad64c31ad2.png + - tags: back_muscles 2015 anthro ass_up bed bedroom black_fur black_stripes book bookshelf + butt crawling feline fireplace fur green_eyes hax_(artist) inside kenket lofi + lying male mammal morning multicolored_fur nude on_floor on_front one_eye_closed + orange_fur painting pawpads platerug shaded solo striped_body stripes table tiger + vase white_fur window + url: https://static1.e621.net/data/sample/6f/f4/6ff406e64fe870f43512d863a8fd119b.jpg + - tags: pink_eyes 2018 anthro canine clothed clothing cookie digital_media_(artwork) + dog female food fur hair looking_at_viewer mammal nana_(fadey) open_mouthsmile + solo standing tofu93 + url: https://static1.e621.net/data/sample/0f/01/0f01bc5401835aa1a082b19e83a0e956.jpg + - tags: 2013 anthro beverage blue_fur blue_hair borny_(character) canine clothing + coffee digital_media_(artwork) food fox fur green_eyes hair hoodie male mammal + open_mouth phonesolo wolfy-nail + url: https://static1.e621.net/data/sample/ac/9f/ac9f231b988d4b6f43b66e89e1d5578e.jpg + - tags: clothed detailed_background fully_clothed holding_object menacing outside + standing yellow_sclera 2015 anthro cheetah clothing feline female flashlight gun + handgun mammal muscular muscular_female pistol police ranged_weaponsolo street_lamp + sunrise tirrel uniform weapon + url: https://static1.e621.net/data/sample/d3/ae/d3aee9d4de485f2be935e84ebbd971b7.jpg + - tags: 2015 ambiguous_gender anthro blue_eyes clothing cosplay costume day detailed_background + dragon dreamworks falvie fudge_the_otter how_to_train_your_dragon kigurumi mammal + membranous_wings mustelid night_fury open_mouth otter outsidesitting sky smile + solo star starry_sky sunset toothless wings + url: https://static1.e621.net/data/sample/0f/d1/0fd1d92190633265fb32a800d65c82d7.jpg + - tags: holding_object food ambiguous_gender beverage black_fur blue_fur blush canine + chigiri clothing coffee cup first_person_view fur happy long_ears lucario mammal + nintendo one_eye_closed pokémon red_eyes sitting smile solo steam video_games wink + url: https://static1.e621.net/data/5a/c6/5ac6787ce0216184bb1737ffc97972e7.png + - tags: android animatronic anthro canine clothed clothing exposed_endoskeleton eye_patch + eyewear five_nights_at_freddy's fox foxy_(fnaf) fur hook hook_hand machine male + mammal naoren piratered_fur robot simple_background solo topless video_games white_background + yellow_eyes + url: https://static1.e621.net/data/17/0a/170ad0093d771d4b99c59f9626712578.png + - tags: 2015 finger_claws 5_fingers <3 anthro blush boss_monster breasts caprine claws + clothed clothing eyebrows eyelashes female fur gastropod goat hi-biki hi_res horn + long_ears looking_at_viewer mammal poserobe simple_background smile snail solo + toriel undertale video_games white_fur wide_hips + url: https://static1.e621.net/data/sample/31/16/31162bd0709f5c79726eb55a05997237.jpg + - tags: 2017 4_toes anthro arnou barefoot black_fur black_nose blue_eyes canine clothed + clothing cuddling day detailed_background digitigrade duo fur hoodie koul male + male/male mammal outside red_eyes smile toes tree wolf wulfcole + url: https://static1.e621.net/data/sample/e2/4e/e24e60d0e2604a1e18de6ec698462e75.jpg + - tags: 2014 anthro black_nose blue_eyes blush brown_fur clothed clothing collar countershade_face + countershading female flower flower_in_hair fur headshot_portrait kiki looking_away + mammal markings multicolored_fur mustelid open_mouth otter plant portrait rarakiesimple_background + solo spots teeth tongue two_tone_fur whiskers white_fur + url: https://static1.e621.net/data/8d/8e/8d8ec834c0b6bd02181510e3bc3f7e4d.png + - tags: pretending anthro antlers brown_fur cellphone cervine cloud deer duo feline + fur green_eyes hi_res horn humor imminent_death lion male mammal nbowa outside + phone predator/preyselfie sky tirrel tirrel_(character) tongue tongue_out tree + url: https://static1.e621.net/data/sample/d9/0e/d90ea5d58bbb37f6c08d054946a478f9.jpg + - tags: "... ambiguous_gender anthro black_fur blue_fur blush canine close-up crossed_arms + fur icon jia looking_at_viewer lucario mammal nintendo pokémon pokémon_(species) red_eyes + simple_background solo tan_fur video_games white_background" + url: https://static1.e621.net/data/sample/db/b6/dbb6db28e0514bb981f417edf6479c9a.jpg + - tags: winged_arms wings ... absurd_res anthro avian beak bird blush breath_of_the_wild + clothed clothing dialogue english_text feathers hi_res kass_(zelda) male muscular + muscular_male nintendo outsiderito sketch solo tacklebox text the_legend_of_zelda + video_games + url: https://static1.e621.net/data/sample/c6/a3/c6a32022972d9807cfaae5000f45b2c4.jpg + - tags: too_early_for_this 2014 5_fingers annoyed anthro beverage big_eyebrows black_eyebrows + black_eyes black_fur black_hair black_nose black_shirt blue_fur bust_portrait + canine clothed clothing coffee coffee_mug countertop crossed_arms cup dialogue + digital_media_(artwork) ear_piercing english_text eyebrows facial_hair facial_piercing + food fur gauged_ear goatee grumpy hair holding_cup holding_object hot_drink lip_piercing + lol_comments looking_at_viewer male mammal multicolored_fur multicolored_hair + nose_piercing nose_ring open_mouth piercing portrait profanityreaction_image restricted_palette + shirt signature simple_background sitting sky3 skye_blue solo speech_bubble steam + striped_ears table teeth text thick_eyebrows two_tone_fur two_tone_hair white_background + white_fur white_hair wolf + url: https://static1.e621.net/data/sample/16/61/1661025f6995846607e709c6da99e123.jpg + - tags: 2013 ambiguous_gender black_eyes cloud cloudscape colorful detailed_background + feral fish happy lol_comments marine open_mouth outside rainbow rainbow_archreaction_image + shark sky solo sparkles spunky_(artist) super_gay teeth + url: https://static1.e621.net/data/e5/03/e503e7d3465337448b715cfd6457edd0.jpg + - tags: 2017 anthro belly big_breasts breasts brown_hair canine chinese_clothing chinese_dress + cleavage cleavage_cutout clothed clothing dress female food fox gradient_background + hair hairclip hi_res kemono long_hair looking_at_viewer mammal purple_eyessetouchi_kurage + simple_background slightly_chubby solo voluptuous waiter wide_hips + url: https://static1.e621.net/data/sample/b1/0d/b10d8740126b4fb20d4b21920d131c8f.jpg + - tags: brown_hair orange_hair sitting striped_body striped_fur striped_tail 2018 + <3 anthro black_topwear blue_eyes blue_topwear breasts clothed clothing collaboration + countershade_legs countershade_torso countershading day deymos digital_media_(artwork) + dipstick_tail domestic_cat felid feline felis female fingerless_(marking) flower + fully_clothed fur hair inside iskra legwear looking_aside mammal multicolored_body + multicolored_fur multicolored_tail orange_body orange_fur panties pink_nose plantshaded + shirt solo stripes sunflower tan_body tan_fur thigh_highs underwear url vera_(iskra) + white_legwear window + url: https://static1.e621.net/data/sample/80/8d/808d424fd5c3ccbaddac9fc5b92f028a.jpg + - tags: 2016 anthro blush buckteeth canine disney duo embarrassed english_text female + fireworks fox freedomthai fur green_eyes grey_fur half-closed_eyes hand_on_head + hi_res holding_object judy_hopps lagomorph larger_male long_ears male male/female + mammal nick_wilde night open_mouth orange_fur outside pen predator/prey purple_eyes + rabbitromantic_ambiance size_difference smaller_female smile smirk tears teeth + text zootopia + url: https://static1.e621.net/data/sample/c6/32/c6321f137f68f99f2bee51dba3bf1de5.jpg + - tags: ambiguous_gender capcom cub dragon horn kneeling kosian looking_at_viewer + membranous_wings monster_hunter red_eyes rukodiora scalie simple_background solo + video_games white_background wings young + url: https://static1.e621.net/data/sample/da/92/da922cd07342972262e98de824595cd1.jpg + - tags: 2014 anthro beach bikini bikini_top blue_eyes bottomless clothed clothing + cloud detailed_background digital_media_(artwork) ear_piercing falvie fangs female + grin hair looking_at_viewer mammal markings mustelid neck_tuft otter outside piercingsand + seaside short_hair sky smile solo swimsuit tuft water white_hair + url: https://static1.e621.net/data/sample/aa/3f/aa3f6074e6c14ff78b40ff51f109869b.jpg + - tags: casual_nudity day eyebrows eyelashes grey_hair half-closed_eyes looking_aside + multicolored_fur multicolored_hair partially_submerged skinny_dipping slim snout + sunlight swimming tan_fur thick_tail 2015 anthro back_muscles blonde_hair brown_eyes + brown_fur brown_hair brown_nose butt digital_media_(artwork) eyewear fangs female + feral fish fur goggles hair hi_res high-angle_view mammal marine mikhaila mouth_hold + mustelid nude otter patreonshort_hair solo teeth tsampikos water wet wide_hips + url: https://static1.e621.net/data/sample/82/ab/82abacf96b5e3bde9d92ef6e5e0197eb.jpg + - tags: 5_fingers anthro_on_anthro black_nose blush brown_fur brown_nose brown_stripes + brown_tail canid cheek_tuft chest_tuft embrace eyebrows felid fluffy fluffy_tail + gloves_(marking) glowing_ears glowing_fur glowing_spots green_fur green_spots + holding_object holding_plush humanoid_hands interspecies markings orange_tail + pantherine romantic_couple snout spots spotted_fur striped_fur striped_tail tan_belly + tan_fur tuft white_belly white_tail anthro bed bed_sheet bedding bioluminescence + brown_hair canine cuddling digital_media_(artwork) duo eyes_closed fox fur gabe_(mytigertail) + glowing hair hug inside lan lying male male/male mammal multicolored_fur mytigertail + nude on_bed on_side open_mouth orange_fur orange_stripes pillow plushie rating:q + sleeping smile spooning stripes tiger two_tone_fur white_fur zeta-haru + url: https://static1.e621.net/data/sample/b8/89/b889bbc7002cc1152ed7f1c8e3a14670.jpg + - tags: 2014 3:2 afternoon alien big_ears black_scales blue_eyes blue_fur blue_nose + claws clothed clothing cosplay costume crossover daww disney dragon dreamworks + duo experiment_(species) feral fish food fur grasp green_sclera hat head_tuft + headgear holding_food holding_object how_to_train_your_dragon inside lilo_and_stitch + long_ears looking_down looking_up lying male marine membranous_wings night_fury + no_sclera offering_(disambiguation) offering_food offering_to_another on_front + on_ground outstretched_arms raised_arm scales scalie scarf sharp_teeth size_difference + smile standing stitch sunlight teeth toe_claws toothless tsaoshin wings + url: https://static1.e621.net/data/50/cc/50cc1f4f731dca8cb66fdb9fd42bc57d.png + - tags: 2017 ambiguous_form ambiguous_gender big_ears brown_eyes canid canine derp_eyes + dipstick_ears ears_down english_text fangs felisrandomis fennec fox frown fur + headshot_portrait humor inner_ear_fluff lol_comments mammal multiple_poses open_mouth + open_smile portrait pose screaming simple_background smile solo tan_fur teeth + text the_truth tongue weasyl + url: https://static1.e621.net/data/79/d7/79d74e8154dcea5339ff51f77fd3c98b.png + - tags: 2018 anthro black_hair blue_eyes blush canid canine canis clothing domestic_dog + faceless_male female hair human male mammal on_lap sally_(povinne10) talilly tongue + tongue_out + url: https://static1.e621.net/data/08/1e/081e279f730cccb5948853e8d1ea6a9f.jpg + - tags: 2018 <3 ambiguous_gender blush coal_(rakkuguy) eyes_closed happy human kobold + mammal motion_lines one_eye_closed open_mouth petting rakkuguy scalie simple_background + smile tailwag tongue tongue_out white_background + url: https://static1.e621.net/data/48/5d/485d385d6bb518ee12c78747054e827c.jpg + - tags: 2018 <3 3_toes ambiguous/ambiguous ambiguous_gender anthro anthro_on_anthro + blue_fur butt canid canine cewljoke chest_tuft cute_fangs duo evolutionary_family + eyes_closed fur hindpaw hi_res hug kneeling level_difference lucario mammal nintendo + nude pawpads paws pink_pawpads pokémon pokémon_(species) red_eyes riolu signature + simple_background smile spikes toes tuft video_games white_background wholesome + url: https://static1.e621.net/data/69/14/6914390405ab241003e48b4cfeeea5f3.png + - tags: 2017 absurd_res ambiguous_gender anatomy black_background blep canid canine + cross-eyed diagram english_text feral fox fur hi_res humor mammal meme red_fox + riot_the_red_fox simple_background sitting solo text tongue tongue_out whiskers + zillion_ross + url: https://static1.e621.net/data/8b/a7/8ba7610b0a2b91d91aebf4a55e131aa7.png + - tags: 2018 4_toes anatomy black_background black_fur black_hair black_nose blue_fur + blue_hair blue_tongue canid canine claws diagram ear_piercing english_text feral + fox fur fur_markings gloves_(marking) hair hi_res humor industrial_piercing male + mammal markings meme mostly_nude multicolored_fur multicolored_hair open_mouth + original_character_do_not_steal owo owo_whats_this paws piercing quadruped restricted_palette + scarf simple_background socks_(marking) solo teeth text the_truth toe_claws toes + tongue two_tone_hair white_fur zillion_ross + url: https://static1.e621.net/data/63/3b/633bbadd77a49e662768428ffc026491.png + - tags: 2017 <3 alcohol avian beak beer beverage bird black_feathers bottle corvid + crow deep_throat digital_media_(artwork) english_text feathers feral hi_res humor + lol_comments oral oral_penetration penetration solo swish talons text wings + url: https://static1.e621.net/data/7c/d9/7cd90352fa57ddaeb3f422de355e727c.jpg + - tags: 2017 5_fingers alternate_form anthro canid canine clothed clothing cup cups_on_ears + cute_fangs dagger detailed_background dialogue digital_media_(artwork) dutch_angle + english_text fox fur gregg_(nitw) happy inside jacket knife koul looking_at_viewer + male mammal melee_weapon night_in_the_woods open_mouth orange_fur smile solo speech_bubble + text video_games weapon + url: https://static1.e621.net/data/4f/be/4fbe36ed49bf8d501edb8509a554837d.jpg + - tags: ambiguous_gender canid canine conditional_dnp daww derp_eyes digital_media_(artwork) + digital_painting_(artwork) ears_back eyes_closed feral flexible fluffy fox full-length_portrait + fur humor lol_comments mammal markings oops orange_fur paws playing portrait red_fox + side_view simple_background snow socks_(marking) solo trunchbull upside_down whiskers + white_background white_fur + url: https://static1.e621.net/data/94/d1/94d108d2e4ed476a113f93e7768accce.jpg + - tags: anthro canid canine clothed clothing english_text fangs female fur hair image_macro + impact_(font) jurassic_park mammal meme nasusbot open_mouth parody profanity reaction_image + skrillex smile solo teeth text + url: https://static1.e621.net/data/cb/a4/cba428d3227dd7358dbf63787c759e8d.png + - tags: "<3 3_toes ambiguous_gender anthro barefoot biped black_fur black_markings + blue_fur blue_tail blush canid canine cel_shading cheek_tuft collar digital_media_(artwork) + digitigrade facial_markings feet fur fur_tuft gloves_(marking) gradient_background + kneeling leash leash_in_mouth lucario mammal markings mouth_hold multicolored_fur + neck_tuft nintendo nude object_in_mouth paws pink_background pokémon pokémon_(species) + pseudo_clothing rakkuguy red_eyes shaded side_view simple_background smile snout + solo spikes submissive toes tuft video_games white_background yellow_fur" + url: https://static1.e621.net/data/a1/1e/a11e49bd7c556049770b3e905e9528ef.png + - tags: 2013 4_fingers anthro barefoot beverage black_fur black_nose canid canine + clothed clothing coffee coffee_mug cup dipstick_ears dipstick_tail english_text + eyes_closed fennec fingerless_(marking) fluffy fluffy_tail food fox fully_clothed + fur gloves_(marking) hair hi_res inner_ear_fluff lying male mammal markings multicolored_tail + orange_fur orange_hair pants reaching shirt side_view simple_background sleeping + socks_(marking) solo sound_effects text thanshuhai tired toeless_(marking) tongue + tongue_out white_background white_fur zzz + url: https://static1.e621.net/data/8d/eb/8deb2ae9fe81f9f6383a24c591bdd3be.png + - tags: 2016 alolan_vulpix altered_reflection ambiguous_gender black_nose brown_eyes + brown_hair canid canine contrast digital_media_(artwork) duality feral fur grey_nose + hair hindpaw hi_res inner_ear_fluff looking_at_viewer mammal multi_tail nintendo + paws pokémon pokémon_(species) realistic reflection regional_variant solo split_screen + standing symmetry tamberella tan_fur video_games vulpix white_fur + url: https://static1.e621.net/data/7e/11/7e11e929a5c5b58078d600d3aa23cf21.jpg + - tags: anthro canid canine clothed clothing disney edit english_text fox fully_clothed + gradient_background lyrics male mammal michael_jackson music nick_wilde simple_background + smile smooth_criminal solo song sound text zootopia 羽默空_(artist) + url: https://static1.e621.net/data/fc/09/fc090f0332c2ae9e91bb6953179bceaf.jpg + - tags: anthro antlers brown_fur cellphone cervid cloud duo felid fur green_eyes hi_res + horn humor imminent_death lion male mammal nbowa outside pantherine phone predator/prey + pretending selfie sky tirrel tirrel_(character) tongue tongue_out tree + url: https://static1.e621.net/data/d9/0e/d90ea5d58bbb37f6c08d054946a478f9.jpg + - tags: 2016 anthro black_fur black_hair black_nose blizzard_entertainment bound breasts + canid canine cheek_tuft conditional_dnp crying digital_media_(artwork) domestic_cat + dream_eater duo e621 english_text eyelashes fan_character felid feline felis female + feral floof flora_fauna fluffy food food_creature fruit fur green_eyes hair hi_res + horn humor impact_(font) kingdom_hearts lol_comments looking_up mammal melon meloncat + melonyan meme meow_wow meta nude paralee_(character) plant poof profanity rainbow + ratte sad square_enix tardar_sauce tears technicolor_yawn text tuft video_games + vomit wall_of_text warcraft watermelon were werecanid werecanine werewolf worgen + url: https://static1.e621.net/data/42/2a/422aaf2c210d6e0e48480ce419b06896.png + - tags: 2016 <3 4_fingers abstract_background anthro asriel_dreemurr big_eyes black_background + blush boss_monster bovid braeburned brown_background caprine cheek_tuft clothing + cute_fangs digital_media_(artwork) fangs feels fur gesture goat gradient_background + green_clothing green_topwear hair half-length_portrait hand_heart head_tuft hi_res + long_ears looking_at_viewer love male mammal multicolored_clothing open_mouth + pink_tongue portrait sharp_teeth signature simple_background smile solo sweater + teeth tongue tuft undertale video_games white_fur yellow_bottomwear yellow_clothing + young + url: https://static1.e621.net/data/14/e7/14e7eff45c61ba29e02f4f59846dc6bc.png + - tags: "... <3 absurd_res ambiguous_gender beady_eyes blep dialogue english_text + feral forked_tongue hi_res iron_and_whine python reptile scalie simple_background + snake solo text tongue tongue_out traditional_media_(artwork) white_background" + url: https://static1.e621.net/data/7f/6a/7f6af5deef179238510cfa1d606ef81f.jpg + - tags: 2016 alantka anthro canid canine cuddling detailed_background disney duo embrace + eyes_closed female forest fox fur gloves_(marking) green_eyes grey_fur judy_hopps + lagomorph long_ears looking_down male mammal markings nick_wilde orange_fur outside + predator/prey rabbit romantic_couple size_difference smile style_parody tree zootopia + url: https://static1.e621.net/data/e1/28/e128617350d9e02bf816f0d4d529c210.jpg + - tags: 2016 absurd_res anthro barefoot bed bedroom bracelet buckteeth canid canine + choker dancing dennyvixen dipstick_tail disney duo earbuds eyes_closed female + fox fur gloves_(marking) good_morning grey_fur happy headphones hi_res inner_ear_fluff + inside ipod ipod_nano jewelry judy_hopps lagomorph long_ears male mammal markings + multicolored_tail nick_wilde on_bed open_mouth orange_fur pawpads portable_music_player + predator/prey rabbit smile teeth two_tone_tail upscale zootopia + url: https://static1.e621.net/data/2e/d4/2ed4a63c7105f9e6ca099033403b242a.png + - tags: ">.< :< :> :| •≠• :3 ambiguous_gender black_eyes :d d: expressions food_creature + frown group humor looking_at_viewer low_res mint not_furry :o o3o open_mouth plastic + real smile tic_tac tongue tongue_out w4nw4n x_x" + url: https://static1.e621.net/data/e5/1e/e51edfb8ec608817cca55d9bf7579c47.jpg + - tags: absurd_res anthro bed bouquet canid canine canis clothing duo eyes_closed + female flower_bouquet hair hi_res human larger_anthro larger_female male mammal + size_difference sleeping smaller_human smaller_male spooning vanchamarl were werecanid + werecanine werewolf wholesome wolf zephra + url: https://static1.e621.net/data/14/b5/14b5352ee09a0dee5a565f5c0e6bfb3c.png + - tags: 2016 anthro blue_eyes boss_monster bovid caprine cellphone crossover disney + english_text female fur goat holding_object horn image_macro long_ears mammal + meme monsters_inc open_mouth parody phone pixar reaction_image solo sulley taken_(movie) + text toriel undertale video_games white_fur wolfjedisamuel + url: https://static1.e621.net/data/fb/52/fb52b8b36ecb85eaf155855a23e70f24.png + - tags: animated anthro asriel_dreemurr blush boss_monster bovid caprine clothing + computer edit empty_eyes english_text floppy_ears goat happy hyperactive lol_comments + male mammal o_o simple_background smile solo text undertale undertale-tales video_games + url: https://static1.e621.net/data/bf/3c/bf3ce93ea4f3e7e3719c59b6557343b0.gif + - tags: 2016 angry anthro antlers bell cervid collar computer furry_problems green_eyes + horn laptop lol_comments male mammal reaction_image solo tirrel tirrel_(character) + url: https://static1.e621.net/data/9c/39/9c39de16aa06ea3afbc0ca4cd3137960.jpg + - tags: anthro big_breasts black_fur black_nose blue_eyes breasts claws clothed clothing + english_text female fur giant_panda gillpanda gillpanda_(character) looking_at_viewer + mammal morbidly_obese motivational_poster multicolored_fur obese overweight overweight_female + pawpads pen sharp_teeth simple_background smile solo teeth text thumbs_up two_tone_fur + ursid white_background white_fur + url: https://static1.e621.net/data/fa/67/fa67485134b0ee19fdaa49a68161f4f5.jpg + - tags: 2015 anthro asriel_dreemurr big_eyes boss_monster bovid caprine clothed clothing + fangs fatz_geronimo goat hoodie horn long_ears male mammal purple_background reaction_image + simple_background solo undertale video_games wide_eyed + url: https://static1.e621.net/data/f1/8d/f18db1184cf4c62d7afbdf8fd28f39f7.png + - tags: 2015 anatomy anthro asriel_dreemurr boss_monster bovid bukoya-star caprine + chart child clothed clothing cub english_text flower fur goat green_eyes grey_background + hi_res long_ears looking_at_viewer male mammal open_mouth plant simple_background + solo text undertale video_games white_fur young + url: https://static1.e621.net/data/b6/33/b633e381a700c619f7ea22666cf6b93d.jpg + - tags: 2015 <3 anthro asriel_dreemurr_(god_form) blue_background boss_monster bovid + caprine clothed clothing digital_media_(artwork) eating fluffy_hair fur gem goat + hair horn looking_at_viewer male mammal pocky red_eyes robe saturnspace simple_background + solo undertale video_games white_fur white_hair + url: https://static1.e621.net/data/8b/80/8b8000f1845841e50515eb0aa224abfb.png + - tags: 2015 ambiguous_gender baseball_cap beady_eyes black_eyes digital_media_(artwork) + feral forked_tongue grey_tongue half-length_portrait hat lol_comments meme mostly_nude + portrait purple_headwear python reptile scalie simple_background smile snake solo + tongue tongue_out unknown_artist white_background + url: https://static1.e621.net/data/bf/f6/bff630817262325b514eee7ff197802e.png + - tags: 2015 ambiguous_gender avian beak bird bread cere_(feature) columbid common_pigeon + crumbs cryptid-creations derp_eyes doing_it_wrong feathers feral flour folded_wings + food humor in_bread lol_comments meme pigeon red_eyes simple_background solo watermark + what white_background + url: https://static1.e621.net/data/f9/1f/f91f92ac563c3bbe4e569d68a46dfafe.png + - tags: 2015 ambiguous_gender anthro blue_eyes clothing cosplay costume day detailed_background + dragon dreamworks falvie fudge_the_otter how_to_train_your_dragon kigurumi mammal + membranous_wings mustelid night_fury open_mouth otter outside sitting sky smile + solo star starry_sky sunset toothless wings + url: https://static1.e621.net/data/0f/d1/0fd1d92190633265fb32a800d65c82d7.png + - tags: 2015 5_fingers ambiguous_gender anthro black_lips black_nose canid canine + canis controller domestic_cat duo eye_contact felid feline felis fluffy fluffy_tail + fur grey_fur handpaw hax_(artist) inside jackal kenket lamp lofi long_mouth looking_at_another + looking_down looking_up lying mammal no_sclera nude on_back orange_eyes pawpads + paws pink_nose reaching remote_control romantic_couple shaded side_view slice_of_life + smile snout sofa table tv_remote whiskers white_fur yellow_eyes + url: https://static1.e621.net/data/0c/09/0c09080148c52ed89f16fe8fbc731dcf.jpg + - tags: 2012 anthro beverage black_fur building cafe camera_view canid canine car + chair cheek_tuft clothed clothing coffee coffee_mug coffee_shop cup detailed_background + digital_media_(artwork) eyebrows fog food fox fur green_eyes hair half-length_portrait + high-angle_view inside looking_at_viewer male mammal multicolored_fur orange_fur + orange_hair portrait red_fox selfie sitting slice_of_life smile solo table thanshuhai + tuft vehicle white_fur + url: https://static1.e621.net/data/a0/47/a0476a240b0b780b926d831a3e6426ea.png + - tags: angry blue_body blue_eyes blue_hair blush dialogue english_text equine eyelashes + eyes_closed female friendship_is_magic hair horn horse humor long_hair mammal + my_little_pony open_mouth orange_background pink_tongue princess_luna_(mlp) profanity + reaction_image simple_background solo sweat teeth text the_truth tongue unknown_artist + winged_unicorn wings + url: https://static1.e621.net/data/ef/e5/efe507d244c5841d8496ce52f4f706a6.png + - tags: "... ambiguous_gender bed bedding black_fur blanket checkered_background domestic_cat + english_text felid feline felis female fur garfield_(series) lying mae_(nitw) + mammal night_in_the_woods on_bed on_front pattern_background reaction_image simple_background + solo speech_bubble text under_covers unknown_artist video_games" + url: https://static1.e621.net/data/19/43/194344f13372ea3e80ef007dd56463c2.png + - tags: 2015 anthro cheetah clothed clothing detailed_background felid feline female + flashlight fully_clothed gun handgun holding_object mammal menacing muscular muscular_female + outside pistol police ranged_weapon solo standing street_lamp sunrise tirrel uniform + weapon yellow_sclera + url: https://static1.e621.net/data/d3/ae/d3aee9d4de485f2be935e84ebbd971b7.jpg + - tags: 2015 anthro antlers bell blue_eyes brown_hair canid canine car cervid cheetah + clothed clothing collar comic dialogue driver driving duo english_text felid feline + female green_eyes hair hat headlight hi_res horn humor inside_car male mammal + outside police profanity running text tirrel tirrel_(character) uniform vehicle + url: https://static1.e621.net/data/ed/e7/ede74f19c7adc6115fb751d729eceaf8.jpg + - tags: 2013 ambiguous_gender angry brown_fur canid canine chibi dipstick_tail english_text + feral fox fur humor mammal markings multicolored_fur multicolored_tail orange_fur + profanity running serious simple_background socks_(marking) solo technicolorpie + technicolor_pie text two_tone_tail white_background white_fur yellow_fur + url: https://static1.e621.net/data/44/53/4453fcdd6d4ce1cf6d6da88c9a35bafc.png + - tags: 2013 abstract_background ambiguous_gender anthro arm_support blonde_hair bow_tie + bust_portrait clothed clothing coat cosplay digital_media_(artwork) felid fur + gene_wilder hair half-closed_eyes hat humor inner_ear_fluff leaning_on_elbow lol_comments + long_hair low_res mammal meme pantherine parody portrait reaction_image smile + solo tassy tiger top_hat willy_wonka willy_wonka_and_the_chocolate_factory yellow_eyes + yellow_fur + url: https://static1.e621.net/data/d1/bb/d1bbf569513c5acf13b1be36d1d64bff.png + - tags: begging begging_pose blue_fur blue_tail canid canine chest_tuft conditional_dnp + dipstick_tail facial_markings fan_character feral feralized fluffy fur looking_away + male mammal markings mask_(marking) multicolored_fur multicolored_tail nintendo + pokémon pokémon_(species) portrait red_eyes riolu simple_background smile solo + tuft two_tone_fur two_tone_tail umpherio_(umpherio) video_games white_background + white_fur white_tail xnirox + url: https://static1.e621.net/data/97/38/973887346d669d97c7a75b7324855773.png + - tags: 2014 <3 anthro avian beak bird black_eyes black_nose blue_body blue_feathers + blue_jay blush brown_fur cartoon_network chest_tuft comic corvid dialogue duo + english_text eyes_closed fangs feathers fur grey_beak hi_res kissing kissing_cheek + love male male/male mammal markings mordecai_(regular_show) open_beak open_mouth + procyonid raccoon regular_show rigby_(regular_show) romantic_couple simple_background + stripes surprise tan_fur teeth text tongue tuft white_background white_body white_feathers + wholesome xiamtheferret + url: https://static1.e621.net/data/ca/c9/cac98850f5b5b48440c100ad800caac1.png + - tags: anthro blonde_hair blue_eyes bone_necklace breasts carnivore clothed clothing + digital_media_(artwork) domestic_cat eating eyebrows felid feline felis female + food front_view hair half-length_portrait holding_food holding_object inuki inuki_(character) + jewelry mammal meat melloque necklace pink_nose ponytail portrait shirt shirt_logo + signature simple_background smile solo steak teeth + url: https://static1.e621.net/data/63/43/63433706609c428f2027986940547834.png + - tags: 2015 applejack_(mlp) blonde_hair cutie_mark earth_pony equine face_paint feathers + female feral friendship_is_magic green_eyes hair headdress hi_res horse jewelry + looking_at_viewer mammal my_little_pony native_american necklace pony portrait + santagiera solo teeth + url: https://static1.e621.net/data/ac/85/ac85e5ea07ae712946bb897bff734d59.jpg + - tags: 2015 animatronic anthro avian beak beverage bird blue_eyes blush bonnie_(fnaf) + canid canine cellphone chica_(fnaf) chicken eye_patch eyewear five_nights_at_freddy's + food fox foxy_(fnaf) freddy_(fnaf) group happy hat humor kissing lagomorph laugh + looking_away machine male male/male mammal phone purple_eyes rabbit robot smile + spin_the_bottle ursid video_games xiamtheferret yellow_eyes + url: https://static1.e621.net/data/be/55/be5581393bcf2451ca90c16ba48c694c.png + - tags: 2014 anthro antiander blue_eyes canid canine clothed clothing dress feathered_wings + feathers female fox gloves hair heterochromia hi_res holly_(plant) long_hair mammal + plant solo source_request white_hair wings + url: https://static1.e621.net/data/7c/8a/7c8a07df68f6b8c93d425158396df811.png + - tags: 2012 ambiguous_gender black_fur black_nose eeveelution fadingsky feral fire + fur markings nintendo pink_background pokémon pokémon_(species) red_eyes simple_background + smoke solo umbreon video_games yellow_markings + url: https://static1.e621.net/data/d8/2f/d82fc9c3bfa78c17db4d117950063124.png + - tags: 2014 ass_up avian beak blue_eyes blue_fur braeburned digital_media_(artwork) + earth_pony equine feathered_wings feathers female feral friendship_is_magic fur + gilda_(mlp) group gryphon hair horse laser laser_pointer mammal multicolored_hair + my_little_pony pegasus pink_fur pink_hair pinkie_pie_(mlp) pony purple_eyes rainbow_dash_(mlp) + rainbow_hair tongue tongue_out wings yellow_eyes + url: https://static1.e621.net/data/8c/08/8c08e77a944dd6df29eb3e908f5bd93f.png + - tags: ambiguous_gender anthro bust_portrait canid canine canis close-up darkwingo + dingo eye_reflection fluffy green_background green_eyes head_tilt hi_res hybrid + jewelry mammal markings necklace portrait scar simple_background smile solo thanshuhai + wolf + url: https://static1.e621.net/data/d7/10/d710ff227b96e59a655d152ac2fcc9f7.jpg + - tags: 2014 <3 anthro beverage beverage_can black_hair blue_hair blue_highlights + clothing collar digital_media_(artwork) domestic_cat fangs felid feline felis + female food gradient_hair green_eyes hair highlights jacket looking_at_viewer + mammal smile solo tentacletongue wolfy-nail young + url: https://static1.e621.net/data/86/94/86942ce7f5be8ba952fef914c5593d2e.jpg + - tags: 2012 ambiguous_gender bed bedding blanket blue_eyes eeveelution feral hi_res + looking_at_viewer lying nintendo on_bed on_front open_mouth pawpads pokémon pokémon_(species) + shadow solo tartii under_covers vaporeon video_games watermark + url: https://static1.e621.net/data/c0/d4/c0d4964ebc0fb0eeddb61bc03cbc6a2b.jpg + - tags: 2014 5:4 anthro atryl avian beak black_feathers brown_feathers cloud digital_media_(artwork) + duo eye_contact feathered_wings feathers female friendship_is_magic genevieve_(mlp) + grass greta_(mlp) grey_eyes gryphon hug my_little_pony one_eye_closed outside + sky smile white_feathers wings wink + url: https://static1.e621.net/data/67/c9/67c952de260ede67d0fe507bb99d3a6e.png + - tags: 2014 3_toes ambiguous_gender animated anthro ass_up black_scales butt digitigrade + dragon felid feral group hindpaw humor inside_train lamp loop low_res male mammal + membranous_wings metro multicolored_scales paws pushing rubble scales scalie size_difference + solo_focus subway tirrel toes train tunnel two_tone_scales vehicle white_scales + wings + url: https://static1.e621.net/data/7d/0d/7d0de8443bad63b6bd56a24ca0d0fb98.gif diff --git a/script/fixes/101_migrate_mod_actions.rb b/script/fixes/101_migrate_mod_actions.rb index 45ed4c38f..ab9a48e9a 100644 --- a/script/fixes/101_migrate_mod_actions.rb +++ b/script/fixes/101_migrate_mod_actions.rb @@ -1,14 +1,14 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'config', 'environment')) - -ModAction.find_each do |p| - begin - p.values = p.values_old - p.save!(validate: false) - rescue Encoding::UndefinedConversionError => e - # Interacting with the model at all throws the exception again. Yay rails. - rescue => e - puts "#{p.id} has an exception" - end -end +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'config', 'environment')) + +ModAction.find_each do |p| + begin + p.values = p.values_old + p.save!(validate: false) + rescue Encoding::UndefinedConversionError => e + # Interacting with the model at all throws the exception again. Yay rails. + rescue => e + puts "#{p.id} has an exception" + end +end diff --git a/test/factories/upload_whitelist.rb b/test/factories/upload_whitelist.rb index 5605fccf3..e25e3c293 100644 --- a/test/factories/upload_whitelist.rb +++ b/test/factories/upload_whitelist.rb @@ -1,4 +1,4 @@ -FactoryBot.define do - factory(:upload_whitelist) do - end -end \ No newline at end of file +FactoryBot.define do + factory(:upload_whitelist) do + end +end diff --git a/test/functional/maintenance/user/deletions_controller_test.rb b/test/functional/maintenance/user/deletions_controller_test.rb index a303343e9..6f2adbbf1 100644 --- a/test/functional/maintenance/user/deletions_controller_test.rb +++ b/test/functional/maintenance/user/deletions_controller_test.rb @@ -24,4 +24,4 @@ module Maintenance end end end -end \ No newline at end of file +end diff --git a/test/functional/maintenance/user/email_changes_controller_test.rb b/test/functional/maintenance/user/email_changes_controller_test.rb index 0b4c51b3b..d26807ae7 100644 --- a/test/functional/maintenance/user/email_changes_controller_test.rb +++ b/test/functional/maintenance/user/email_changes_controller_test.rb @@ -36,4 +36,4 @@ module Maintenance end end end -end \ No newline at end of file +end