rubocop: fix various Rubocop warnings.
This commit is contained in:
57
.rubocop.yml
57
.rubocop.yml
@@ -18,6 +18,9 @@ Layout/CaseIndentation:
|
|||||||
Layout/EmptyLineAfterGuardClause:
|
Layout/EmptyLineAfterGuardClause:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/EmptyLineBetweenDefs:
|
||||||
|
AllowAdjacentOneLineDefs: true
|
||||||
|
|
||||||
Layout/EndAlignment:
|
Layout/EndAlignment:
|
||||||
EnforcedStyleAlignWith: variable
|
EnforcedStyleAlignWith: variable
|
||||||
|
|
||||||
@@ -44,7 +47,7 @@ Metrics/AbcSize:
|
|||||||
|
|
||||||
Metrics/BlockLength:
|
Metrics/BlockLength:
|
||||||
Max: 50
|
Max: 50
|
||||||
ExcludedMethods:
|
IgnoredMethods:
|
||||||
- concerning
|
- concerning
|
||||||
- context
|
- context
|
||||||
- should
|
- should
|
||||||
@@ -66,7 +69,7 @@ Metrics/ModuleLength:
|
|||||||
Max: 500
|
Max: 500
|
||||||
|
|
||||||
Metrics/ParameterLists:
|
Metrics/ParameterLists:
|
||||||
Max: 4
|
Max: 6
|
||||||
|
|
||||||
Metrics/PerceivedComplexity:
|
Metrics/PerceivedComplexity:
|
||||||
Max: 20
|
Max: 20
|
||||||
@@ -74,18 +77,43 @@ Metrics/PerceivedComplexity:
|
|||||||
Lint/InheritException:
|
Lint/InheritException:
|
||||||
EnforcedStyle: standard_error
|
EnforcedStyle: standard_error
|
||||||
|
|
||||||
|
Naming/HeredocDelimiterNaming:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
Naming/MethodParameterName:
|
Naming/MethodParameterName:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Naming/PredicateName:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/Blank:
|
||||||
|
UnlessPresent: false
|
||||||
|
|
||||||
|
Rails/DynamicFindBy:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/HasManyOrHasOneDependent:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
Rails/HttpStatus:
|
Rails/HttpStatus:
|
||||||
EnforcedStyle: numeric
|
EnforcedStyle: numeric
|
||||||
|
|
||||||
|
Rails/InverseOf:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/Alias:
|
||||||
|
EnforcedStyle: prefer_alias_method
|
||||||
|
|
||||||
Style/AsciiComments:
|
Style/AsciiComments:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/CommentAnnotation:
|
Style/CommentAnnotation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Style/ConditionalAssignment:
|
||||||
|
EnforcedStyle: assign_inside_condition
|
||||||
|
IncludeTernaryExpressions: false
|
||||||
|
|
||||||
Style/Documentation:
|
Style/Documentation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
@@ -104,6 +132,9 @@ Style/FloatDivision:
|
|||||||
Style/FrozenStringLiteralComment:
|
Style/FrozenStringLiteralComment:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Style/GuardClause:
|
||||||
|
MinBodyLength: 20
|
||||||
|
|
||||||
Style/HashSyntax:
|
Style/HashSyntax:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
@@ -113,12 +144,20 @@ Style/IfUnlessModifier:
|
|||||||
Style/MutableConstant:
|
Style/MutableConstant:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Style/NegatedIf:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
Style/NumericPredicate:
|
Style/NumericPredicate:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/PercentLiteralDelimiters:
|
Style/PercentLiteralDelimiters:
|
||||||
PreferredDelimiters:
|
PreferredDelimiters:
|
||||||
"default": "[]"
|
"default": "{}"
|
||||||
|
"%i": "[]"
|
||||||
|
"%I": "[]"
|
||||||
|
"%w": "[]"
|
||||||
|
"%W": "[]"
|
||||||
|
"%r": "{}"
|
||||||
|
|
||||||
Style/ParallelAssignment:
|
Style/ParallelAssignment:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
@@ -134,7 +173,7 @@ Style/SpecialGlobalVars:
|
|||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/StringLiterals:
|
Style/StringLiterals:
|
||||||
Enabled: false
|
EnforcedStyle: double_quotes
|
||||||
|
|
||||||
Style/StringLiteralsInInterpolation:
|
Style/StringLiteralsInInterpolation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
@@ -142,8 +181,18 @@ Style/StringLiteralsInInterpolation:
|
|||||||
Style/SymbolArray:
|
Style/SymbolArray:
|
||||||
MinSize: 10
|
MinSize: 10
|
||||||
|
|
||||||
|
Style/SymbolProc:
|
||||||
|
IgnoredMethods:
|
||||||
|
- respond_with
|
||||||
|
|
||||||
Style/TernaryParentheses:
|
Style/TernaryParentheses:
|
||||||
EnforcedStyle: require_parentheses_when_complex
|
EnforcedStyle: require_parentheses_when_complex
|
||||||
|
|
||||||
|
Style/TrailingCommaInArrayLiteral:
|
||||||
|
EnforcedStyleForMultiline: consistent_comma
|
||||||
|
|
||||||
|
Style/TrailingCommaInHashLiteral:
|
||||||
|
EnforcedStyleForMultiline: consistent_comma
|
||||||
|
|
||||||
Style/WordArray:
|
Style/WordArray:
|
||||||
MinSize: 10
|
MinSize: 10
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
class ApplicationComponent < ViewComponent::Base
|
class ApplicationComponent < ViewComponent::Base
|
||||||
delegate :link_to_user, :time_ago_in_words_tagged, :format_text, :external_link_to, :tag_class, to: :helpers
|
delegate :link_to_user, :time_ago_in_words_tagged, :format_text, :external_link_to, :tag_class, to: :helpers
|
||||||
delegate :edit_icon, :delete_icon, :undelete_icon, :flag_icon, :upvote_icon,
|
delegate :edit_icon, :delete_icon, :undelete_icon, :flag_icon, :upvote_icon, :downvote_icon, :link_icon, :sticky_icon, :unsticky_icon, to: :helpers
|
||||||
:downvote_icon, :link_icon, :sticky_icon, :unsticky_icon, to: :helpers
|
|
||||||
|
|
||||||
def policy(subject)
|
def policy(subject)
|
||||||
Pundit.policy!(current_user, subject)
|
Pundit.policy!(current_user, subject)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ class CommentComponent < ApplicationComponent
|
|||||||
attr_reader :comment, :context, :dtext_data, :current_user
|
attr_reader :comment, :context, :dtext_data, :current_user
|
||||||
|
|
||||||
def initialize(comment:, current_user:, context: nil, dtext_data: nil)
|
def initialize(comment:, current_user:, context: nil, dtext_data: nil)
|
||||||
|
super
|
||||||
@comment = comment
|
@comment = comment
|
||||||
@context = context
|
@context = context
|
||||||
@dtext_data = dtext_data
|
@dtext_data = dtext_data
|
||||||
@@ -11,7 +12,7 @@ class CommentComponent < ApplicationComponent
|
|||||||
end
|
end
|
||||||
|
|
||||||
def dimmed?
|
def dimmed?
|
||||||
comment.is_deleted? || (!comment.is_sticky? && comment.score <= current_user.comment_threshold/2.0)
|
comment.is_deleted? || (!comment.is_sticky? && comment.score <= current_user.comment_threshold / 2.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
def thresholded?
|
def thresholded?
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ class CommentSectionComponent < ApplicationComponent
|
|||||||
attr_reader :post, :comments, :current_user, :limit, :dtext_data
|
attr_reader :post, :comments, :current_user, :limit, :dtext_data
|
||||||
|
|
||||||
def initialize(post:, current_user:, limit: nil)
|
def initialize(post:, current_user:, limit: nil)
|
||||||
|
super
|
||||||
@post = post
|
@post = post
|
||||||
@current_user = current_user
|
@current_user = current_user
|
||||||
@limit = limit
|
@limit = limit
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
class ForumPostComponent < ApplicationComponent
|
class ForumPostComponent < ApplicationComponent
|
||||||
attr_reader :forum_post, :original_forum_post_id, :dtext_data, :moderation_reports, :current_user
|
attr_reader :forum_post, :original_forum_post_id, :dtext_data, :moderation_reports, :current_user
|
||||||
|
|
||||||
delegate :link_to_user, :time_ago_in_words_tagged, :format_text, :policy, to: :helpers
|
delegate :link_to_user, :time_ago_in_words_tagged, :format_text, :policy, to: :helpers
|
||||||
|
|
||||||
with_collection_parameter :forum_post
|
with_collection_parameter :forum_post
|
||||||
@@ -17,6 +18,7 @@ class ForumPostComponent < ApplicationComponent
|
|||||||
end
|
end
|
||||||
|
|
||||||
def initialize(forum_post:, original_forum_post_id: nil, dtext_data: nil, current_user: User.anonymous)
|
def initialize(forum_post:, original_forum_post_id: nil, dtext_data: nil, current_user: User.anonymous)
|
||||||
|
super
|
||||||
@forum_post = forum_post
|
@forum_post = forum_post
|
||||||
@original_forum_post_id = original_forum_post_id
|
@original_forum_post_id = original_forum_post_id
|
||||||
@dtext_data = dtext_data
|
@dtext_data = dtext_data
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
<% if policy(forum_post).create? %>
|
<% if policy(forum_post).create? %>
|
||||||
<li><%= link_to "Reply", new_forum_post_path(post_id: forum_post.id), method: :get, remote: true %></li>
|
<li><%= link_to "Reply", new_forum_post_path(post_id: forum_post.id), method: :get, remote: true %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if policy(forum_post).destroy? && !forum_post.is_original_post?(original_forum_post_id) %>
|
<% if policy(forum_post).destroy? && !forum_post.is_original_post?(original_forum_post_id) %>
|
||||||
<% if forum_post.is_deleted %>
|
<% if forum_post.is_deleted %>
|
||||||
<li><%= link_to "Undelete", undelete_forum_post_path(forum_post.id), method: :post, remote: true %></li>
|
<li><%= link_to "Undelete", undelete_forum_post_path(forum_post.id), method: :post, remote: true %></li>
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
<li><%= link_to "Delete", forum_post_path(forum_post.id), "data-confirm": "Are you sure you want to delete this forum post?", method: :delete, remote: true %></li>
|
<li><%= link_to "Delete", forum_post_path(forum_post.id), "data-confirm": "Are you sure you want to delete this forum post?", method: :delete, remote: true %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if policy(forum_post).update? %>
|
<% if policy(forum_post).update? %>
|
||||||
<% if forum_post.is_original_post?(original_forum_post_id) %>
|
<% if forum_post.is_original_post?(original_forum_post_id) %>
|
||||||
<li><%= link_to "Edit", edit_forum_topic_path(forum_post.topic), id: "edit_forum_topic_link_#{forum_post.topic.id}", class: "edit_forum_topic_link" %></li>
|
<li><%= link_to "Edit", edit_forum_topic_path(forum_post.topic), id: "edit_forum_topic_link_#{forum_post.topic.id}", class: "edit_forum_topic_link" %></li>
|
||||||
@@ -37,12 +39,15 @@
|
|||||||
<li><%= link_to "Edit", edit_forum_post_path(forum_post.id), id: "edit_forum_post_link_#{forum_post.id}", class: "edit_forum_post_link" %></li>
|
<li><%= link_to "Edit", edit_forum_post_path(forum_post.id), id: "edit_forum_post_link_#{forum_post.id}", class: "edit_forum_post_link" %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if policy(forum_post).reportable? %>
|
<% if policy(forum_post).reportable? %>
|
||||||
<li><%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "ForumPost", model_id: forum_post.id }), remote: true, title: "Report this forum post to the moderators" %></li>
|
<li><%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "ForumPost", model_id: forum_post.id }), remote: true, title: "Report this forum post to the moderators" %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if has_moderation_reports? %>
|
<% if has_moderation_reports? %>
|
||||||
<li class="moderation-report-notice">Reported (<%= link_to pluralize(forum_post.moderation_reports.length, "report"), moderation_reports_path(search: { model_type: "ForumPost", model_id: forum_post.id }) %>)</li>
|
<li class="moderation-report-notice">Reported (<%= link_to pluralize(forum_post.moderation_reports.length, "report"), moderation_reports_path(search: { model_type: "ForumPost", model_id: forum_post.id }) %>)</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if forum_post.bulk_update_request.present? %>
|
<% if forum_post.bulk_update_request.present? %>
|
||||||
<menu class="votes" id="forum-post-votes-for-<%= forum_post.id %>">
|
<menu class="votes" id="forum-post-votes-for-<%= forum_post.id %>">
|
||||||
<%= render "forum_post_votes/list", votes: forum_post.votes, forum_post: forum_post %>
|
<%= render "forum_post_votes/list", votes: forum_post.votes, forum_post: forum_post %>
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
class PaginatorComponent < ApplicationComponent
|
class PaginatorComponent < ApplicationComponent
|
||||||
attr_reader :records, :window, :params
|
attr_reader :records, :window, :params
|
||||||
|
|
||||||
delegate :current_page, :prev_page, :next_page, :total_pages, :paginator_mode, :paginator_page_limit, to: :records
|
delegate :current_page, :prev_page, :next_page, :total_pages, :paginator_mode, :paginator_page_limit, to: :records
|
||||||
delegate :ellipsis_icon, :chevron_left_icon, :chevron_right_icon, to: :helpers
|
delegate :ellipsis_icon, :chevron_left_icon, :chevron_right_icon, to: :helpers
|
||||||
|
|
||||||
def initialize(records:, params:, window: 4)
|
def initialize(records:, params:, window: 4)
|
||||||
|
super
|
||||||
@records = records
|
@records = records
|
||||||
@window = window
|
@window = window
|
||||||
@params = params
|
@params = params
|
||||||
@@ -25,7 +27,7 @@ class PaginatorComponent < ApplicationComponent
|
|||||||
("..." unless left == 2),
|
("..." unless left == 2),
|
||||||
(left..right).to_a,
|
(left..right).to_a,
|
||||||
("..." unless right == last_page - 1),
|
("..." unless right == last_page - 1),
|
||||||
(last_page unless last_page == 1)
|
(last_page unless last_page == 1),
|
||||||
].flatten.compact
|
].flatten.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ class PostNavbarComponent < ApplicationComponent
|
|||||||
attr_reader :post, :current_user, :search
|
attr_reader :post, :current_user, :search
|
||||||
|
|
||||||
def initialize(post:, current_user:, search: nil)
|
def initialize(post:, current_user:, search: nil)
|
||||||
|
super
|
||||||
@post = post
|
@post = post
|
||||||
@current_user = current_user
|
@current_user = current_user
|
||||||
@search = search.presence || "status:any"
|
@search = search.presence || "status:any"
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ class PostPreviewComponent < ApplicationComponent
|
|||||||
with_collection_parameter :post
|
with_collection_parameter :post
|
||||||
|
|
||||||
attr_reader :post, :tags, :show_deleted, :show_cropped, :link_target, :pool, :similarity, :recommended, :compact, :size, :current_user, :options
|
attr_reader :post, :tags, :show_deleted, :show_cropped, :link_target, :pool, :similarity, :recommended, :compact, :size, :current_user, :options
|
||||||
|
|
||||||
delegate :external_link_to, :time_ago_in_words_tagged, :empty_heart_icon, to: :helpers
|
delegate :external_link_to, :time_ago_in_words_tagged, :empty_heart_icon, to: :helpers
|
||||||
|
|
||||||
def initialize(post:, tags: "", show_deleted: false, show_cropped: true, link_target: post, pool: nil, similarity: nil, recommended: nil, compact: nil, size: nil, current_user: CurrentUser.user, **options)
|
def initialize(post:, tags: "", show_deleted: false, show_cropped: true, link_target: post, pool: nil, similarity: nil, recommended: nil, compact: nil, size: nil, current_user: CurrentUser.user, **options)
|
||||||
|
super
|
||||||
@post = post
|
@post = post
|
||||||
@tags = tags.presence
|
@tags = tags.presence
|
||||||
@show_deleted = show_deleted
|
@show_deleted = show_deleted
|
||||||
@@ -44,7 +46,7 @@ class PostPreviewComponent < ApplicationComponent
|
|||||||
|
|
||||||
{
|
{
|
||||||
width: [(downscale_ratio * post.image_width).floor, post.image_width].min,
|
width: [(downscale_ratio * post.image_width).floor, post.image_width].min,
|
||||||
height: [(downscale_ratio * post.image_height).floor, post.image_height].min
|
height: [(downscale_ratio * post.image_height).floor, post.image_height].min,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ width: 0, height: 0 }
|
{ width: 0, height: 0 }
|
||||||
@@ -70,7 +72,7 @@ class PostPreviewComponent < ApplicationComponent
|
|||||||
def data_attributes
|
def data_attributes
|
||||||
attributes = {
|
attributes = {
|
||||||
"data-id" => post.id,
|
"data-id" => post.id,
|
||||||
"data-has-sound" => post.has_tag?('video_with_sound|flash_with_sound'),
|
"data-has-sound" => post.has_tag?("video_with_sound|flash_with_sound"),
|
||||||
"data-tags" => post.tag_string,
|
"data-tags" => post.tag_string,
|
||||||
"data-pools" => post.pool_string,
|
"data-pools" => post.pool_string,
|
||||||
"data-approver-id" => post.approver_id,
|
"data-approver-id" => post.approver_id,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ class PostVotesComponent < ApplicationComponent
|
|||||||
attr_reader :post, :current_user
|
attr_reader :post, :current_user
|
||||||
|
|
||||||
def initialize(post:, current_user:)
|
def initialize(post:, current_user:)
|
||||||
|
super
|
||||||
@post = post
|
@post = post
|
||||||
@current_user = current_user
|
@current_user = current_user
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
class SourceDataComponent < ApplicationComponent
|
class SourceDataComponent < ApplicationComponent
|
||||||
attr_reader :source
|
attr_reader :source
|
||||||
|
|
||||||
delegate :spinner_icon, :external_site_icon, to: :helpers
|
delegate :spinner_icon, :external_site_icon, to: :helpers
|
||||||
|
|
||||||
def initialize(source:)
|
def initialize(source:)
|
||||||
|
super
|
||||||
@source = source
|
@source = source
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,18 @@
|
|||||||
|
|
||||||
class TagListComponent < ApplicationComponent
|
class TagListComponent < ApplicationComponent
|
||||||
attr_reader :tags, :current_query, :show_extra_links
|
attr_reader :tags, :current_query, :show_extra_links
|
||||||
|
|
||||||
delegate :humanized_number, to: :helpers
|
delegate :humanized_number, to: :helpers
|
||||||
|
|
||||||
def initialize(tags: [], current_query: nil, show_extra_links: false)
|
def initialize(tags: [], current_query: nil, show_extra_links: false)
|
||||||
|
super
|
||||||
@tags = tags
|
@tags = tags
|
||||||
@current_query = current_query
|
@current_query = current_query
|
||||||
@show_extra_links = show_extra_links
|
@show_extra_links = show_extra_links
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.tags_from_names(tag_names)
|
def self.tags_from_names(tag_names)
|
||||||
names_to_tags = Tag.where(name: tag_names).map { |tag| [tag.name, tag] }.to_h
|
names_to_tags = Tag.where(name: tag_names).index_by(&:name)
|
||||||
|
|
||||||
tag_names.map do |name|
|
tag_names.map do |name|
|
||||||
names_to_tags.fetch(name) { Tag.new(name: name).freeze }
|
names_to_tags.fetch(name) { Tag.new(name: name).freeze }
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ class ApplicationController < ActionController::Base
|
|||||||
render_error_page(401, exception, template: "sessions/new")
|
render_error_page(401, exception, template: "sessions/new")
|
||||||
when ActionController::InvalidAuthenticityToken, ActionController::UnpermittedParameters, ActionController::InvalidCrossOriginRequest
|
when ActionController::InvalidAuthenticityToken, ActionController::UnpermittedParameters, ActionController::InvalidCrossOriginRequest
|
||||||
render_error_page(403, exception)
|
render_error_page(403, exception)
|
||||||
when ActiveSupport::MessageVerifier::InvalidSignature # raised by `find_signed!`
|
when ActiveSupport::MessageVerifier::InvalidSignature, # raised by `find_signed!`
|
||||||
render_error_page(403, exception, template: "static/access_denied", message: "Access denied")
|
User::PrivilegeError,
|
||||||
when User::PrivilegeError, Pundit::NotAuthorizedError
|
Pundit::NotAuthorizedError
|
||||||
render_error_page(403, exception, template: "static/access_denied", message: "Access denied")
|
render_error_page(403, exception, template: "static/access_denied", message: "Access denied")
|
||||||
when ActiveRecord::RecordNotFound
|
when ActiveRecord::RecordNotFound
|
||||||
render_error_page(404, exception, message: "That record was not found.")
|
render_error_page(404, exception, message: "That record was not found.")
|
||||||
@@ -183,7 +183,7 @@ class ApplicationController < ActionController::Base
|
|||||||
return if CurrentUser.user.is_anonymous?
|
return if CurrentUser.user.is_anonymous?
|
||||||
|
|
||||||
last_authenticated_at = session[:last_authenticated_at]
|
last_authenticated_at = session[:last_authenticated_at]
|
||||||
if last_authenticated_at.blank? || Time.parse(last_authenticated_at) < 60.minutes.ago
|
if last_authenticated_at.blank? || Time.zone.parse(last_authenticated_at) < 60.minutes.ago
|
||||||
redirect_to confirm_password_session_path(url: request.fullpath)
|
redirect_to confirm_password_session_path(url: request.fullpath)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -197,7 +197,7 @@ class ApplicationController < ActionController::Base
|
|||||||
params[:search] ||= ActionController::Parameters.new
|
params[:search] ||= ActionController::Parameters.new
|
||||||
|
|
||||||
deep_reject_blank = lambda do |hash|
|
deep_reject_blank = lambda do |hash|
|
||||||
hash.reject { |k, v| v.blank? || (v.is_a?(Hash) && deep_reject_blank.call(v).blank?) }
|
hash.reject { |_k, v| v.blank? || (v.is_a?(Hash) && deep_reject_blank.call(v).blank?) }
|
||||||
end
|
end
|
||||||
nonblank_search_params = deep_reject_blank.call(params[:search])
|
nonblank_search_params = deep_reject_blank.call(params[:search])
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class ArtistsController < ApplicationController
|
|||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@artist = authorize Artist.find(params[:id])
|
@artist = authorize Artist.find(params[:id])
|
||||||
@artist.update_attribute(:is_deleted, true)
|
@artist.update(is_deleted: true)
|
||||||
redirect_to(artist_path(@artist), :notice => "Artist deleted")
|
redirect_to(artist_path(@artist), :notice => "Artist deleted")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ class CommentVotesController < ApplicationController
|
|||||||
|
|
||||||
def index
|
def index
|
||||||
@comment_votes = authorize CommentVote.visible(CurrentUser.user).paginated_search(params, count_pages: true)
|
@comment_votes = authorize CommentVote.visible(CurrentUser.user).paginated_search(params, count_pages: true)
|
||||||
@comment_votes = @comment_votes.includes(:user, comment: [:creator, post: [:uploader]]) if request.format.html?
|
@comment_votes = @comment_votes.includes(:user, comment: [:creator, { post: [:uploader] }]) if request.format.html?
|
||||||
|
|
||||||
respond_with(@comment_votes)
|
respond_with(@comment_votes)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class CommentsController < ApplicationController
|
|||||||
|
|
||||||
def index_by_post
|
def index_by_post
|
||||||
@limit = params.fetch(:limit, 20)
|
@limit = params.fetch(:limit, 20)
|
||||||
@posts = Post.where("last_comment_bumped_at IS NOT NULL").user_tag_match(params[:tags]).reorder("last_comment_bumped_at DESC NULLS LAST").paginate(params[:page], limit: @limit, search_count: params[:search])
|
@posts = Post.where.not(last_comment_bumped_at: nil).user_tag_match(params[:tags]).reorder("last_comment_bumped_at DESC NULLS LAST").paginate(params[:page], limit: @limit, search_count: params[:search])
|
||||||
|
|
||||||
if request.format.html?
|
if request.format.html?
|
||||||
@posts = @posts.includes(comments: [:creator])
|
@posts = @posts.includes(comments: [:creator])
|
||||||
|
|||||||
@@ -8,33 +8,25 @@ class DelayedJobsController < ApplicationController
|
|||||||
|
|
||||||
def cancel
|
def cancel
|
||||||
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
|
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
|
||||||
if !@job.locked_at?
|
@job.fail! unless @job.locked_at?
|
||||||
@job.fail!
|
|
||||||
end
|
|
||||||
respond_with(@job)
|
respond_with(@job)
|
||||||
end
|
end
|
||||||
|
|
||||||
def retry
|
def retry
|
||||||
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
|
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
|
||||||
if !@job.locked_at?
|
@job.update(failed_at: nil, attempts: 0) unless @job.locked_at?
|
||||||
@job.update(failed_at: nil, attempts: 0)
|
|
||||||
end
|
|
||||||
respond_with(@job)
|
respond_with(@job)
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
|
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
|
||||||
if !@job.locked_at?
|
@job.update(run_at: Time.zone.now) unless @job.locked_at?
|
||||||
@job.update(run_at: Time.now)
|
|
||||||
end
|
|
||||||
respond_with(@job)
|
respond_with(@job)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
|
@job = authorize Delayed::Job.find(params[:id]), policy_class: DelayedJobPolicy
|
||||||
if !@job.locked_at?
|
@job.destroy unless @job.locked_at?
|
||||||
@job.destroy
|
|
||||||
end
|
|
||||||
respond_with(@job)
|
respond_with(@job)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ class DtextPreviewsController < ApplicationController
|
|||||||
def create
|
def create
|
||||||
@inline = params[:inline].to_s.truthy?
|
@inline = params[:inline].to_s.truthy?
|
||||||
@disable_mentions = params[:disable_mentions].to_s.truthy?
|
@disable_mentions = params[:disable_mentions].to_s.truthy?
|
||||||
|
@html = helpers.format_text(params[:body], inline: @inline, disable_mentions: @disable_mentions)
|
||||||
|
|
||||||
render inline: "<%= format_text(params[:body], inline: @inline, disable_mentions: @disable_mentions) %>"
|
render html: @html
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class ForumTopicsController < ApplicationController
|
|||||||
|
|
||||||
def mark_all_as_read
|
def mark_all_as_read
|
||||||
authorize ForumTopic
|
authorize ForumTopic
|
||||||
CurrentUser.user.update_attribute(:last_forum_read_at, Time.now)
|
CurrentUser.user.update(last_forum_read_at: Time.zone.now)
|
||||||
ForumTopicVisit.prune!(CurrentUser.user)
|
ForumTopicVisit.prune!(CurrentUser.user)
|
||||||
redirect_to forum_topics_path, :notice => "All topics marked as read"
|
redirect_to forum_topics_path, :notice => "All topics marked as read"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ class IpAddressesController < ApplicationController
|
|||||||
def index
|
def index
|
||||||
@ip_addresses = authorize IpAddress.visible(CurrentUser.user).paginated_search(params)
|
@ip_addresses = authorize IpAddress.visible(CurrentUser.user).paginated_search(params)
|
||||||
|
|
||||||
if search_params[:group_by] == "ip_addr"
|
case search_params[:group_by]
|
||||||
|
when "ip_addr"
|
||||||
@ip_addresses = @ip_addresses.group_by_ip_addr(search_params[:ipv4_masklen], search_params[:ipv6_masklen])
|
@ip_addresses = @ip_addresses.group_by_ip_addr(search_params[:ipv4_masklen], search_params[:ipv6_masklen])
|
||||||
elsif search_params[:group_by] == "user"
|
when "user"
|
||||||
@ip_addresses = @ip_addresses.group_by_user.includes(:user)
|
@ip_addresses = @ip_addresses.group_by_user.includes(:user)
|
||||||
else
|
else
|
||||||
@ip_addresses = @ip_addresses.includes(:user, :model)
|
@ip_addresses = @ip_addresses.includes(:user, :model)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ module Maintenance
|
|||||||
class VerificationError < StandardError; end
|
class VerificationError < StandardError; end
|
||||||
|
|
||||||
before_action :validate_sig, :only => [:destroy]
|
before_action :validate_sig, :only => [:destroy]
|
||||||
rescue_from VerificationError, :with => :render_403
|
rescue_from VerificationError, with: :render_verification_error
|
||||||
|
|
||||||
def show
|
def show
|
||||||
end
|
end
|
||||||
@@ -17,15 +17,15 @@ module Maintenance
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def render_403
|
def render_verification_error
|
||||||
render plain: "", :status => 403
|
render plain: "", status: 403
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_sig
|
def validate_sig
|
||||||
verifier = ActiveSupport::MessageVerifier.new(Danbooru.config.email_key, digest: "SHA256", serializer: JSON)
|
verifier = ActiveSupport::MessageVerifier.new(Danbooru.config.email_key, digest: "SHA256", serializer: JSON)
|
||||||
calculated_sig = verifier.generate(params[:user_id].to_s)
|
calculated_sig = verifier.generate(params[:user_id].to_s)
|
||||||
if calculated_sig != params[:sig]
|
if calculated_sig != params[:sig]
|
||||||
raise VerificationError.new
|
raise VerificationError, "Invalid signature"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ class PoolVersionsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_availabililty
|
def check_availabililty
|
||||||
if !PoolVersion.enabled?
|
raise NotImplementedError, "Archive service is not configured. Pool versions are not saved." unless PoolVersion.enabled?
|
||||||
raise NotImplementedError.new("Archive service is not configured. Pool versions are not saved.")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class PoolsController < ApplicationController
|
|||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@pool = authorize Pool.find(params[:id])
|
@pool = authorize Pool.find(params[:id])
|
||||||
@pool.update_attribute(:is_deleted, true)
|
@pool.update(is_deleted: true)
|
||||||
@pool.create_mod_action_for_delete
|
@pool.create_mod_action_for_delete
|
||||||
flash[:notice] = "Pool deleted"
|
flash[:notice] = "Pool deleted"
|
||||||
respond_with(@pool)
|
respond_with(@pool)
|
||||||
@@ -62,7 +62,7 @@ class PoolsController < ApplicationController
|
|||||||
|
|
||||||
def undelete
|
def undelete
|
||||||
@pool = authorize Pool.find(params[:id])
|
@pool = authorize Pool.find(params[:id])
|
||||||
@pool.update_attribute(:is_deleted, false)
|
@pool.update(is_deleted: false)
|
||||||
@pool.create_mod_action_for_undelete
|
@pool.create_mod_action_for_undelete
|
||||||
flash[:notice] = "Pool undeleted"
|
flash[:notice] = "Pool undeleted"
|
||||||
respond_with(@pool)
|
respond_with(@pool)
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ class PostVersionsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_availabililty
|
def check_availabililty
|
||||||
if !PostVersion.enabled?
|
return if PostVersion.enabled?
|
||||||
raise NotImplementedError.new("Archive service is not configured. Post versions are not saved.")
|
raise NotImplementedError, "Archive service is not configured. Post versions are not saved."
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ class PostsController < ApplicationController
|
|||||||
render :template => "static/error", :status => 500
|
render :template => "static/error", :status => 500
|
||||||
else
|
else
|
||||||
response_params = {:q => params[:tags_query], :pool_id => params[:pool_id], :favgroup_id => params[:favgroup_id]}
|
response_params = {:q => params[:tags_query], :pool_id => params[:pool_id], :favgroup_id => params[:favgroup_id]}
|
||||||
response_params.reject! {|key, value| value.blank?}
|
response_params.reject! {|_key, value| value.blank?}
|
||||||
redirect_to post_path(post, response_params)
|
redirect_to post_path(post, response_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ class RecommendedPostsController < ApplicationController
|
|||||||
def index
|
def index
|
||||||
limit = params.fetch(:limit, 100).to_i.clamp(0, 200)
|
limit = params.fetch(:limit, 100).to_i.clamp(0, 200)
|
||||||
@recs = RecommenderService.search(search_params).take(limit)
|
@recs = RecommenderService.search(search_params).take(limit)
|
||||||
@posts = @recs.map { |rec| rec[:post] }
|
@posts = @recs.pluck(:post)
|
||||||
|
|
||||||
respond_with(@recs)
|
respond_with(@recs)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class StaticController < ApplicationController
|
|||||||
|
|
||||||
def sitemap_index
|
def sitemap_index
|
||||||
@sitemap = params[:sitemap]
|
@sitemap = params[:sitemap]
|
||||||
@limit = params.fetch(:limit, 10000).to_i
|
@limit = params.fetch(:limit, 10_000).to_i
|
||||||
|
|
||||||
case @sitemap
|
case @sitemap
|
||||||
when "artists"
|
when "artists"
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class UploadsController < ApplicationController
|
|||||||
def preprocess
|
def preprocess
|
||||||
authorize Upload
|
authorize Upload
|
||||||
@upload, @remote_size = UploadService::ControllerHelper.prepare(
|
@upload, @remote_size = UploadService::ControllerHelper.prepare(
|
||||||
url: params.dig(:upload, :source), file: params.dig(:upload, :file), ref: params.dig(:upload, :referer_url),
|
url: params.dig(:upload, :source), file: params.dig(:upload, :file), ref: params.dig(:upload, :referer_url)
|
||||||
)
|
)
|
||||||
render body: nil
|
render body: nil
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
require 'dtext'
|
|
||||||
|
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
def listing_type(*fields, member_check: true, types: [:revert, :standard])
|
def listing_type(*fields, member_check: true, types: [:revert, :standard])
|
||||||
(fields.reduce(false) { |acc, field| acc || params.dig(:search, field).present? } && (!member_check || CurrentUser.is_member?) ? types[0] : types[1])
|
(fields.reduce(false) { |acc, field| acc || params.dig(:search, field).present? } && (!member_check || CurrentUser.is_member?) ? types[0] : types[1])
|
||||||
@@ -11,8 +9,7 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def diff_name_html(this_name, other_name)
|
def diff_name_html(this_name, other_name)
|
||||||
pattern = Regexp.new('.')
|
DiffBuilder.new(this_name, other_name, /./).build
|
||||||
DiffBuilder.new(this_name, other_name, pattern).build
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff_body_html(record, other, field)
|
def diff_body_html(record, other, field)
|
||||||
@@ -21,7 +18,7 @@ module ApplicationHelper
|
|||||||
return h(diff_record[field]).gsub(/\r?\n/, '<span class="paragraph-mark">¶</span><br>').html_safe
|
return h(diff_record[field]).gsub(/\r?\n/, '<span class="paragraph-mark">¶</span><br>').html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
pattern = Regexp.new('(?:<.+?>)|(?:\w+)|(?:[ \t]+)|(?:\r?\n)|(?:.+?)')
|
pattern = /(?:<.+?>)|(?:\w+)|(?:[ \t]+)|(?:\r?\n)|(?:.+?)/
|
||||||
DiffBuilder.new(record[field], other[field], pattern).build
|
DiffBuilder.new(record[field], other[field], pattern).build
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -32,18 +29,17 @@ module ApplicationHelper
|
|||||||
return type == "previous" ? "New" : ""
|
return type == "previous" ? "New" : ""
|
||||||
end
|
end
|
||||||
|
|
||||||
statuses = []
|
changed_fields = record.class.status_fields.select do |field, status|
|
||||||
record.class.status_fields.each do |field, status|
|
(record.has_attribute?(field) && record[field] != other[field]) ||
|
||||||
if record.has_attribute?(field)
|
(!record.has_attribute?(field) && record.send(field, type))
|
||||||
statuses += [status] if record[field] != other[field]
|
|
||||||
else
|
|
||||||
statuses += [status] if record.send(field, type)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
statuses = changed_fields.map { |field, status| status }
|
||||||
altered = record.updater_id != other.updater_id
|
altered = record.updater_id != other.updater_id
|
||||||
|
|
||||||
%(<div class="version-statuses" data-altered="#{altered}">#{statuses.join("<br>")}</div>).html_safe
|
tag.div(class: "version-statuses", "data-altered": altered) do
|
||||||
|
safe_join(statuses, tag.br)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def wordbreakify(string)
|
def wordbreakify(string)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ module ForumTopicsHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def available_min_user_levels
|
def available_min_user_levels
|
||||||
ForumTopic::MIN_LEVELS.select { |name, level| level <= CurrentUser.level }.to_a
|
ForumTopic::MIN_LEVELS.select { |_name, level| level <= CurrentUser.level }.to_a
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_forum_topic?(topic, read_forum_topics)
|
def new_forum_topic?(topic, read_forum_topics)
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ module PopularPostsHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def date_range_description(date, scale, min_date, max_date)
|
def date_range_description(date, scale, min_date, max_date)
|
||||||
if scale == "day"
|
case scale
|
||||||
|
when "day"
|
||||||
date.strftime("%B %d, %Y")
|
date.strftime("%B %d, %Y")
|
||||||
elsif scale == "week"
|
when "week"
|
||||||
"#{min_date.strftime("%B %d, %Y")} - #{max_date.strftime("%B %d, %Y")}"
|
"#{min_date.strftime("%B %d, %Y")} - #{max_date.strftime("%B %d, %Y")}"
|
||||||
elsif scale == "month"
|
when "month"
|
||||||
date.strftime("%B %Y")
|
date.strftime("%B %Y")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ module PostVersionsHelper
|
|||||||
def post_version_field(post_version, field)
|
def post_version_field(post_version, field)
|
||||||
value = post_version_value(post_version.send(field))
|
value = post_version_value(post_version.send(field))
|
||||||
prefix = (field == :parent_id ? "parent" : field.to_s)
|
prefix = (field == :parent_id ? "parent" : field.to_s)
|
||||||
search = prefix + ":" + value.to_s
|
search = "#{prefix}:#{value}"
|
||||||
display = (field == :rating ? post_version.pretty_rating : value)
|
display = (field == :rating ? post_version.pretty_rating : value)
|
||||||
%(<b>#{field.to_s.titleize}:</b> #{link_to(display, posts_path(:tags => search))}).html_safe
|
%(<b>#{field.to_s.titleize}:</b> #{link_to(display, posts_path(:tags => search))}).html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_version_value(value)
|
def post_version_value(value)
|
||||||
return (value.present? ? value : "none")
|
value.presence || "none"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
module WikiPagesHelper
|
module WikiPagesHelper
|
||||||
def wiki_page_other_names_list(wiki_page)
|
def wiki_page_other_names_list(wiki_page)
|
||||||
names_html = wiki_page.other_names.map {|name| link_to(name, "http://www.pixiv.net/search.php?s_mode=s_tag_full&word=#{u(name)}", :class => "wiki-other-name")}
|
names_html = wiki_page.other_names.map do |name|
|
||||||
names_html.join(" ").html_safe
|
link_to(name, "https://www.pixiv.net/tags/#{u(name)}/artworks", class: "wiki-other-name")
|
||||||
|
end
|
||||||
|
|
||||||
|
safe_join(names_html, " ")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class ApplicationJob < ActiveJob::Base
|
|||||||
queue_as :default
|
queue_as :default
|
||||||
queue_with_priority 0
|
queue_with_priority 0
|
||||||
|
|
||||||
discard_on ActiveJob::DeserializationError do |job, error|
|
discard_on ActiveJob::DeserializationError do |_job, error|
|
||||||
DanbooruLogger.log(error)
|
DanbooruLogger.log(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ module Moderator
|
|||||||
module Queries
|
module Queries
|
||||||
class Artist < ::Struct.new(:user, :count)
|
class Artist < ::Struct.new(:user, :count)
|
||||||
def self.all(min_date, max_level)
|
def self.all(min_date, max_level)
|
||||||
::ArtistVersion.joins(:updater)
|
::ArtistVersion
|
||||||
|
.joins(:updater)
|
||||||
.where("artist_versions.created_at > ?", min_date)
|
.where("artist_versions.created_at > ?", min_date)
|
||||||
.where("users.level <= ?", max_level)
|
.where("users.level <= ?", max_level)
|
||||||
.group(:updater)
|
.group(:updater)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ module Moderator
|
|||||||
module Queries
|
module Queries
|
||||||
class Comment < ::Struct.new(:comment, :count)
|
class Comment < ::Struct.new(:comment, :count)
|
||||||
def self.all(min_date, max_level)
|
def self.all(min_date, max_level)
|
||||||
::CommentVote.joins(comment: [:creator])
|
::CommentVote
|
||||||
|
.joins(comment: [:creator])
|
||||||
.where("comments.score < 0")
|
.where("comments.score < 0")
|
||||||
.where("comment_votes.created_at > ?", min_date)
|
.where("comment_votes.created_at > ?", min_date)
|
||||||
.where("users.level <= ?", max_level)
|
.where("users.level <= ?", max_level)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ module Moderator
|
|||||||
module Queries
|
module Queries
|
||||||
class Note < ::Struct.new(:user, :count)
|
class Note < ::Struct.new(:user, :count)
|
||||||
def self.all(min_date, max_level)
|
def self.all(min_date, max_level)
|
||||||
::NoteVersion.joins(:updater)
|
::NoteVersion
|
||||||
|
.joins(:updater)
|
||||||
.where("note_versions.created_at > ?", min_date)
|
.where("note_versions.created_at > ?", min_date)
|
||||||
.where("users.level <= ?", max_level)
|
.where("users.level <= ?", max_level)
|
||||||
.group(:updater)
|
.group(:updater)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ module Moderator
|
|||||||
module Queries
|
module Queries
|
||||||
class PostAppeal
|
class PostAppeal
|
||||||
def self.all(min_date)
|
def self.all(min_date)
|
||||||
::Post.joins(:appeals).includes(:uploader, :flags, appeals: [:creator])
|
::Post
|
||||||
|
.joins(:appeals).includes(:uploader, :flags, appeals: [:creator])
|
||||||
.deleted
|
.deleted
|
||||||
.where("post_appeals.created_at > ?", min_date)
|
.where("post_appeals.created_at > ?", min_date)
|
||||||
.group(:id)
|
.group(:id)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ module Moderator
|
|||||||
module Queries
|
module Queries
|
||||||
class Upload < ::Struct.new(:user, :count)
|
class Upload < ::Struct.new(:user, :count)
|
||||||
def self.all(min_date, max_level)
|
def self.all(min_date, max_level)
|
||||||
::Post.joins(:uploader)
|
::Post
|
||||||
|
.joins(:uploader)
|
||||||
.where("posts.created_at > ?", min_date)
|
.where("posts.created_at > ?", min_date)
|
||||||
.where("users.level <= ?", max_level)
|
.where("users.level <= ?", max_level)
|
||||||
.group(:uploader)
|
.group(:uploader)
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ module Moderator
|
|||||||
module Queries
|
module Queries
|
||||||
class WikiPage < ::Struct.new(:user, :count)
|
class WikiPage < ::Struct.new(:user, :count)
|
||||||
def self.all(min_date, max_level)
|
def self.all(min_date, max_level)
|
||||||
::WikiPageVersion.joins(:updater)
|
::WikiPageVersion
|
||||||
|
.joins(:updater)
|
||||||
.where("wiki_page_versions.created_at > ?", min_date)
|
.where("wiki_page_versions.created_at > ?", min_date)
|
||||||
.where("users.level <= ?", max_level)
|
.where("users.level <= ?", max_level)
|
||||||
.group(:updater)
|
.group(:updater)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ module Moderator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_row(sums, counts)
|
def add_row(sums, counts)
|
||||||
sums.merge!(counts) { |key, oldcount, newcount| oldcount + newcount }
|
sums.merge!(counts) { |_key, oldcount, newcount| oldcount + newcount }
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_row_id(sums, counts)
|
def add_row_id(sums, counts)
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ class NicoSeigaApiClient
|
|||||||
end
|
end
|
||||||
|
|
||||||
def image_ids
|
def image_ids
|
||||||
if @work_type == "illust"
|
case @work_type
|
||||||
|
when "illust"
|
||||||
[api_response["id"]]
|
[api_response["id"]]
|
||||||
elsif @work_type == "manga"
|
when "manga"
|
||||||
manga_api_response.map do |x|
|
manga_api_response.map do |x|
|
||||||
case x["meta"]["source_url"]
|
case x["meta"]["source_url"]
|
||||||
when %r{/thumb/(\d+)\w}i then Regexp.last_match(1)
|
when %r{/thumb/(\d+)\w}i then Regexp.last_match(1)
|
||||||
@@ -40,20 +41,22 @@ class NicoSeigaApiClient
|
|||||||
end
|
end
|
||||||
|
|
||||||
def user_name
|
def user_name
|
||||||
if @work_type == "illust"
|
case @work_type
|
||||||
|
when "illust"
|
||||||
api_response["nickname"]
|
api_response["nickname"]
|
||||||
elsif @work_type == "manga"
|
when "manga"
|
||||||
user_api_response(user_id)["nickname"]
|
user_api_response(user_id)["nickname"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def api_response
|
def api_response
|
||||||
if @work_type == "illust"
|
case @work_type
|
||||||
|
when "illust"
|
||||||
resp = get("https://sp.seiga.nicovideo.jp/ajax/seiga/im#{@work_id}")
|
resp = get("https://sp.seiga.nicovideo.jp/ajax/seiga/im#{@work_id}")
|
||||||
return {} if resp.blank? || resp.code.to_i == 404
|
return {} if resp.blank? || resp.code.to_i == 404
|
||||||
api_response = JSON.parse(resp)["target_image"]
|
api_response = JSON.parse(resp)["target_image"]
|
||||||
|
|
||||||
elsif @work_type == "manga"
|
when "manga"
|
||||||
resp = http.cache(1.minute).get("#{XML_API}/theme/info?id=#{@work_id}")
|
resp = http.cache(1.minute).get("#{XML_API}/theme/info?id=#{@work_id}")
|
||||||
return {} if resp.blank? || resp.code.to_i == 404
|
return {} if resp.blank? || resp.code.to_i == 404
|
||||||
api_response = Hash.from_xml(resp.to_s)["response"]["theme"]
|
api_response = Hash.from_xml(resp.to_s)["response"]["theme"]
|
||||||
@@ -86,16 +89,13 @@ class NicoSeigaApiClient
|
|||||||
|
|
||||||
# XXX should fail gracefully instead of raising exception
|
# XXX should fail gracefully instead of raising exception
|
||||||
resp = http.cache(1.hour).post("https://account.nicovideo.jp/login/redirector?site=seiga", form: form)
|
resp = http.cache(1.hour).post("https://account.nicovideo.jp/login/redirector?site=seiga", form: form)
|
||||||
raise RuntimeError, "NicoSeiga login failed (status=#{resp.status} url=#{url})" if resp.status != 200
|
raise "NicoSeiga login failed (status=#{resp.status} url=#{url})" if resp.status != 200
|
||||||
|
|
||||||
http
|
http
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(url)
|
def get(url)
|
||||||
resp = login.cache(1.minute).get(url)
|
login.cache(1.minute).get(url)
|
||||||
#raise RuntimeError, "NicoSeiga get failed (status=#{resp.status} url=#{url})" if resp.status != 200
|
|
||||||
|
|
||||||
resp
|
|
||||||
end
|
end
|
||||||
|
|
||||||
memoize :api_response, :manga_api_response, :user_api_response
|
memoize :api_response, :manga_api_response, :user_api_response
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
module NoteSanitizer
|
module NoteSanitizer
|
||||||
ALLOWED_ELEMENTS = %w(
|
ALLOWED_ELEMENTS = %w[
|
||||||
code center tn h1 h2 h3 h4 h5 h6 a span div blockquote br p ul li ol em
|
code center tn h1 h2 h3 h4 h5 h6 a span div blockquote br p ul li ol em
|
||||||
strong small big b i font u s pre ruby rb rt rp rtc sub sup hr wbr
|
strong small big b i font u s pre ruby rb rt rp rtc sub sup hr wbr
|
||||||
)
|
]
|
||||||
|
|
||||||
ALLOWED_ATTRIBUTES = {
|
ALLOWED_ATTRIBUTES = {
|
||||||
:all => %w(style title),
|
:all => %w[style title],
|
||||||
"a" => %w(href),
|
"a" => %w[href],
|
||||||
"span" => %w(class),
|
"span" => %w[class],
|
||||||
"div" => %w(class align),
|
"div" => %w[class align],
|
||||||
"p" => %w(class align),
|
"p" => %w[class align],
|
||||||
"font" => %w(color size)
|
"font" => %w[color size]
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOWED_PROPERTIES = %w(
|
ALLOWED_PROPERTIES = %w[
|
||||||
align-items
|
align-items
|
||||||
background background-color
|
background background-color
|
||||||
border border-color border-image border-radius border-style border-width
|
border border-color border-image border-radius border-style border-width
|
||||||
@@ -48,7 +48,7 @@ module NoteSanitizer
|
|||||||
word-wrap overflow-wrap
|
word-wrap overflow-wrap
|
||||||
writing-mode
|
writing-mode
|
||||||
vertical-align
|
vertical-align
|
||||||
)
|
]
|
||||||
|
|
||||||
def self.sanitize(text)
|
def self.sanitize(text)
|
||||||
text.gsub!(/<( |-|3|:|>|\Z)/, "<\\1")
|
text.gsub!(/<( |-|3|:|>|\Z)/, "<\\1")
|
||||||
|
|||||||
@@ -46,21 +46,23 @@ module PaginationExtension
|
|||||||
end
|
end
|
||||||
|
|
||||||
def is_first_page?
|
def is_first_page?
|
||||||
if paginator_mode == :numbered
|
case paginator_mode
|
||||||
|
when :numbered
|
||||||
current_page == 1
|
current_page == 1
|
||||||
elsif paginator_mode == :sequential_before
|
when :sequential_before
|
||||||
false
|
false
|
||||||
elsif paginator_mode == :sequential_after
|
when :sequential_after
|
||||||
size <= records_per_page
|
size <= records_per_page
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_last_page?
|
def is_last_page?
|
||||||
if paginator_mode == :numbered
|
case paginator_mode
|
||||||
|
when :numbered
|
||||||
current_page >= total_pages
|
current_page >= total_pages
|
||||||
elsif paginator_mode == :sequential_before
|
when :sequential_before
|
||||||
size <= records_per_page
|
size <= records_per_page
|
||||||
elsif paginator_mode == :sequential_after
|
when :sequential_after
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -98,11 +100,12 @@ module PaginationExtension
|
|||||||
# we override a rails internal method to discard that extra record. See
|
# we override a rails internal method to discard that extra record. See
|
||||||
# #2044, #3642.
|
# #2044, #3642.
|
||||||
def records
|
def records
|
||||||
if paginator_mode == :sequential_before
|
case paginator_mode
|
||||||
|
when :sequential_before
|
||||||
super.first(records_per_page)
|
super.first(records_per_page)
|
||||||
elsif paginator_mode == :sequential_after
|
when :sequential_after
|
||||||
super.first(records_per_page).reverse
|
super.first(records_per_page).reverse
|
||||||
elsif paginator_mode == :numbered
|
when :numbered
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ module PostSets
|
|||||||
end
|
end
|
||||||
|
|
||||||
def has_blank_wiki?
|
def has_blank_wiki?
|
||||||
tag.present? && !wiki_page.present?
|
tag.present? && wiki_page.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def wiki_page
|
def wiki_page
|
||||||
@@ -94,7 +94,7 @@ module PostSets
|
|||||||
end
|
end
|
||||||
|
|
||||||
def get_post_count
|
def get_post_count
|
||||||
if %w(json atom xml).include?(format.downcase)
|
if %w[json atom xml].include?(format.downcase)
|
||||||
# no need to get counts for formats that don't use a paginator
|
# no need to get counts for formats that don't use a paginator
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ class RateLimiter
|
|||||||
|
|
||||||
case action
|
case action
|
||||||
when "users:create"
|
when "users:create"
|
||||||
rate, burst = 1.0/5.minutes, 10
|
rate, burst = 1.0 / 5.minutes, 10
|
||||||
when "emails:update", "sessions:create", "moderation_reports:create"
|
when "emails:update", "sessions:create", "moderation_reports:create"
|
||||||
rate, burst = 1.0/1.minute, 10
|
rate, burst = 1.0 / 1.minute, 10
|
||||||
when "dmails:create", "comments:create", "forum_posts:create", "forum_topics:create"
|
when "dmails:create", "comments:create", "forum_posts:create", "forum_topics:create"
|
||||||
rate, burst = 1.0/1.minute, 50
|
rate, burst = 1.0 / 1.minute, 50
|
||||||
when "comment_votes:create", "comment_votes:destroy", "post_votes:create",
|
when "comment_votes:create", "comment_votes:destroy", "post_votes:create",
|
||||||
"post_votes:destroy", "favorites:create", "favorites:destroy", "post_disapprovals:create"
|
"post_votes:destroy", "favorites:create", "favorites:destroy", "post_disapprovals:create"
|
||||||
rate, burst = 1.0/1.second, 200
|
rate, burst = 1.0 / 1.second, 200
|
||||||
else
|
else
|
||||||
rate = user.api_regen_multiplier
|
rate = user.api_regen_multiplier
|
||||||
burst = 200
|
burst = 200
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ module RecommenderService
|
|||||||
|
|
||||||
if user.present?
|
if user.present?
|
||||||
raise User::PrivilegeError unless Pundit.policy!(CurrentUser.user, user).can_see_favorites?
|
raise User::PrivilegeError unless Pundit.policy!(CurrentUser.user, user).can_see_favorites?
|
||||||
max_recommendations = params.fetch(:max_recommendations, user.favorite_count + 500).to_i.clamp(0, 50000)
|
max_recommendations = params.fetch(:max_recommendations, user.favorite_count + 500).to_i.clamp(0, 50_000)
|
||||||
recs = RecommenderService.recommend_for_user(user, tags: params[:post_tags_match], limit: max_recommendations)
|
recs = RecommenderService.recommend_for_user(user, tags: params[:post_tags_match], limit: max_recommendations)
|
||||||
elsif post.present?
|
elsif post.present?
|
||||||
max_recommendations = params.fetch(:max_recommendations, 100).to_i.clamp(0, 1000)
|
max_recommendations = params.fetch(:max_recommendations, 100).to_i.clamp(0, 1000)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class ReportbooruService
|
|||||||
reportbooru_server.present?
|
reportbooru_server.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def missed_search_rankings(expires_in: 1.minutes)
|
def missed_search_rankings(expires_in: 1.minute)
|
||||||
return [] unless enabled?
|
return [] unless enabled?
|
||||||
|
|
||||||
response = http.cache(expires_in).get("#{reportbooru_server}/missed_searches")
|
response = http.cache(expires_in).get("#{reportbooru_server}/missed_searches")
|
||||||
@@ -20,11 +20,11 @@ class ReportbooruService
|
|||||||
body.lines.map(&:split).map { [_1, _2.to_i] }
|
body.lines.map(&:split).map { [_1, _2.to_i] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_search_rankings(date, expires_in: 1.minutes)
|
def post_search_rankings(date, expires_in: 1.minute)
|
||||||
request("#{reportbooru_server}/post_searches/rank?date=#{date}", expires_in)
|
request("#{reportbooru_server}/post_searches/rank?date=#{date}", expires_in)
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_view_rankings(date, expires_in: 1.minutes)
|
def post_view_rankings(date, expires_in: 1.minute)
|
||||||
request("#{reportbooru_server}/post_views/rank?date=#{date}", expires_in)
|
request("#{reportbooru_server}/post_views/rank?date=#{date}", expires_in)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -156,12 +156,12 @@ module Sources::Strategies
|
|||||||
"https://twitter.com/i/web/status/#{status_id}"
|
"https://twitter.com/i/web/status/#{status_id}"
|
||||||
elsif url =~ %r{\Ahttps?://(?:o|image-proxy-origin)\.twimg\.com/\d/proxy\.jpg\?t=(\w+)&}i
|
elsif url =~ %r{\Ahttps?://(?:o|image-proxy-origin)\.twimg\.com/\d/proxy\.jpg\?t=(\w+)&}i
|
||||||
str = Base64.decode64($1)
|
str = Base64.decode64($1)
|
||||||
source = URI.extract(str, ['http', 'https'])
|
source = URI.extract(str, %w[http https])
|
||||||
if source.any?
|
if source.any?
|
||||||
source = source[0]
|
source = source[0]
|
||||||
if source =~ %r{^https?://twitpic.com/show/large/[a-z0-9]+}i
|
if source =~ %r{^https?://twitpic.com/show/large/[a-z0-9]+}i
|
||||||
source.gsub!(%r{show/large/}, "")
|
source.gsub!(%r{show/large/}, "")
|
||||||
index = source.rindex('.')
|
index = source.rindex(".")
|
||||||
source = source[0..index - 1]
|
source = source[0..index - 1]
|
||||||
end
|
end
|
||||||
source
|
source
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class TagCategory
|
|||||||
end
|
end
|
||||||
|
|
||||||
def category_ids_regex
|
def category_ids_regex
|
||||||
@@category_ids_regex ||= "[#{category_ids.join("")}]"
|
@@category_ids_regex ||= "[#{category_ids.join}]"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class TagMover
|
|||||||
old_cosplay_tag = "#{old_tag.name}_(cosplay)"
|
old_cosplay_tag = "#{old_tag.name}_(cosplay)"
|
||||||
new_cosplay_tag = "#{new_tag.name}_(cosplay)"
|
new_cosplay_tag = "#{new_tag.name}_(cosplay)"
|
||||||
|
|
||||||
if Tag.nonempty.where(name: old_cosplay_tag).exists?
|
if Tag.nonempty.exists?(name: old_cosplay_tag)
|
||||||
TagMover.new(old_cosplay_tag, new_cosplay_tag).move!
|
TagMover.new(old_cosplay_tag, new_cosplay_tag).move!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ module TagRelationshipRetirementService
|
|||||||
if topic.nil?
|
if topic.nil?
|
||||||
CurrentUser.as(User.system) do
|
CurrentUser.as(User.system) do
|
||||||
topic = ForumTopic.create!(creator: User.system, title: forum_topic_title, category_id: 1)
|
topic = ForumTopic.create!(creator: User.system, title: forum_topic_title, category_id: 1)
|
||||||
forum_post = ForumPost.create!(creator: User.system, body: forum_topic_body, topic: topic)
|
ForumPost.create!(creator: User.system, body: forum_topic_body, topic: topic)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
topic
|
topic
|
||||||
@@ -45,6 +45,6 @@ module TagRelationshipRetirementService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def is_unused?(name)
|
def is_unused?(name)
|
||||||
!Post.raw_tag_match(name).where("created_at > ?", THRESHOLD.ago).exists?
|
!Post.raw_tag_match(name).exists?(["created_at > ?", THRESHOLD.ago])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
require 'upload_service/controller_helper'
|
|
||||||
require 'upload_service/preprocessor'
|
|
||||||
require 'upload_service/replacer'
|
|
||||||
require 'upload_service/utils'
|
|
||||||
|
|
||||||
class UploadService
|
class UploadService
|
||||||
attr_reader :params, :post, :upload
|
attr_reader :params, :post, :upload
|
||||||
|
|
||||||
|
|||||||
@@ -34,15 +34,13 @@ class UploadService
|
|||||||
|
|
||||||
def in_progress?
|
def in_progress?
|
||||||
if md5.present?
|
if md5.present?
|
||||||
return Upload.where(status: "preprocessing", md5: md5).exists?
|
Upload.exists?(status: "preprocessing", md5: md5)
|
||||||
end
|
elsif Utils.is_downloadable?(source)
|
||||||
|
Upload.exists?(status: "preprocessing", source: source)
|
||||||
if Utils.is_downloadable?(source)
|
else
|
||||||
return Upload.where(status: "preprocessing", source: source).exists?
|
|
||||||
end
|
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def predecessor
|
def predecessor
|
||||||
if md5.present?
|
if md5.present?
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class UploadService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def comment_replacement_message(post, replacement)
|
def comment_replacement_message(post, replacement)
|
||||||
%("#{replacement.creator.name}":[#{Routes.user_path(replacement.creator)}] replaced this post with a new file:\n\n#{replacement_message(post, replacement)})
|
%{"#{replacement.creator.name}":[#{Routes.user_path(replacement.creator)}] replaced this post with a new file:\n\n#{replacement_message(post, replacement)}}
|
||||||
end
|
end
|
||||||
|
|
||||||
def replacement_message(post, replacement)
|
def replacement_message(post, replacement)
|
||||||
@@ -49,7 +49,7 @@ class UploadService
|
|||||||
truncated_source = source.gsub(%r{\Ahttps?://}, "").truncate(64, omission: "...#{source.last(32)}")
|
truncated_source = source.gsub(%r{\Ahttps?://}, "").truncate(64, omission: "...#{source.last(32)}")
|
||||||
|
|
||||||
if source =~ %r{\Ahttps?://}i
|
if source =~ %r{\Ahttps?://}i
|
||||||
%("#{truncated_source}":[#{source}])
|
%{"#{truncated_source}":[#{source}]}
|
||||||
else
|
else
|
||||||
truncated_source
|
truncated_source
|
||||||
end
|
end
|
||||||
@@ -70,7 +70,7 @@ class UploadService
|
|||||||
return "file://#{repl.replacement_file.original_filename}"
|
return "file://#{repl.replacement_file.original_filename}"
|
||||||
end
|
end
|
||||||
|
|
||||||
if !upload.source.present?
|
if upload.source.blank?
|
||||||
raise "No source found in upload for replacement"
|
raise "No source found in upload for replacement"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class UploadService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def is_downloadable?(source)
|
def is_downloadable?(source)
|
||||||
source =~ /^https?:\/\//
|
source =~ %r{\Ahttps?://}
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_resizes(media_file)
|
def generate_resizes(media_file)
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ class UserDeletion
|
|||||||
user.email_address = nil
|
user.email_address = nil
|
||||||
user.last_logged_in_at = nil
|
user.last_logged_in_at = nil
|
||||||
user.last_forum_read_at = nil
|
user.last_forum_read_at = nil
|
||||||
user.favorite_tags = ''
|
user.favorite_tags = ""
|
||||||
user.blacklisted_tags = ''
|
user.blacklisted_tags = ""
|
||||||
user.hide_deleted_posts = false
|
user.hide_deleted_posts = false
|
||||||
user.show_deleted_children = false
|
user.show_deleted_children = false
|
||||||
user.time_zone = "Eastern Time (US & Canada)"
|
user.time_zone = "Eastern Time (US & Canada)"
|
||||||
|
|||||||
@@ -32,22 +32,18 @@ class ArtistVersion < ApplicationRecord
|
|||||||
extend SearchMethods
|
extend SearchMethods
|
||||||
|
|
||||||
def previous
|
def previous
|
||||||
@previous ||= begin
|
@previous ||= ArtistVersion.where("artist_id = ? and created_at < ?", artist_id, created_at).order("created_at desc").limit(1).to_a
|
||||||
ArtistVersion.where("artist_id = ? and created_at < ?", artist_id, created_at).order("created_at desc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@previous.first
|
@previous.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def subsequent
|
def subsequent
|
||||||
@subsequent ||= begin
|
@subsequent ||= ArtistVersion.where("artist_id = ? and created_at > ?", artist_id, created_at).order("created_at asc").limit(1).to_a
|
||||||
ArtistVersion.where("artist_id = ? and created_at > ?", artist_id, created_at).order("created_at asc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@subsequent.first
|
@subsequent.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def current
|
def current
|
||||||
@previous ||= begin
|
@previous ||= begin
|
||||||
ArtistVersion.where("artist_id = ?", artist_id).order("created_at desc").limit(1).to_a
|
ArtistVersion.where(artist_id: artist_id).order("created_at desc").limit(1).to_a
|
||||||
end
|
end
|
||||||
@previous.first
|
@previous.first
|
||||||
end
|
end
|
||||||
@@ -66,17 +62,17 @@ class ArtistVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def other_names_changed(type)
|
def other_names_changed(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
((other_names - other.other_names) | (other.other_names - other_names)).length.positive?
|
((other_names - other.other_names) | (other.other_names - other_names)).length.positive?
|
||||||
end
|
end
|
||||||
|
|
||||||
def urls_changed(type)
|
def urls_changed(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
((urls - other.urls) | (other.urls - urls)).length.positive?
|
((urls - other.urls) | (other.urls - urls)).length.positive?
|
||||||
end
|
end
|
||||||
|
|
||||||
def was_deleted(type)
|
def was_deleted(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
is_deleted && !other.is_deleted
|
is_deleted && !other.is_deleted
|
||||||
else
|
else
|
||||||
@@ -85,7 +81,7 @@ class ArtistVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_undeleted(type)
|
def was_undeleted(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
!is_deleted && other.is_deleted
|
!is_deleted && other.is_deleted
|
||||||
else
|
else
|
||||||
@@ -94,7 +90,7 @@ class ArtistVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_banned(type)
|
def was_banned(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
is_banned && !other.is_banned
|
is_banned && !other.is_banned
|
||||||
else
|
else
|
||||||
@@ -103,7 +99,7 @@ class ArtistVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_unbanned(type)
|
def was_unbanned(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
!is_banned && other.is_banned
|
!is_banned && other.is_banned
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ class Ban < ApplicationRecord
|
|||||||
validates :reason, presence: true
|
validates :reason, presence: true
|
||||||
validate :user, :validate_user_is_bannable, on: :create
|
validate :user, :validate_user_is_bannable, on: :create
|
||||||
|
|
||||||
scope :unexpired, -> { where("bans.created_at + bans.duration > ?", Time.now) }
|
scope :unexpired, -> { where("bans.created_at + bans.duration > ?", Time.zone.now) }
|
||||||
scope :expired, -> { where("bans.created_at + bans.duration <= ?", Time.now) }
|
scope :expired, -> { where("bans.created_at + bans.duration <= ?", Time.zone.now) }
|
||||||
scope :active, -> { unexpired }
|
scope :active, -> { unexpired }
|
||||||
|
|
||||||
def self.search(params)
|
def self.search(params)
|
||||||
@@ -48,7 +48,7 @@ class Ban < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_user_on_destroy
|
def update_user_on_destroy
|
||||||
user.update_attribute(:is_banned, false)
|
user.update!(is_banned: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_name
|
def user_name
|
||||||
@@ -68,7 +68,7 @@ class Ban < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def expired?
|
def expired?
|
||||||
persisted? && expires_at < Time.now
|
persisted? && expires_at < Time.zone.now
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_feedback
|
def create_feedback
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
class BulkUpdateRequest < ApplicationRecord
|
class BulkUpdateRequest < ApplicationRecord
|
||||||
attr_accessor :title
|
attr_accessor :title, :reason
|
||||||
attr_accessor :reason
|
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :forum_topic, optional: true
|
belongs_to :forum_topic, optional: true
|
||||||
belongs_to :forum_post, optional: true
|
belongs_to :forum_post, optional: true
|
||||||
belongs_to :approver, optional: true, class_name: "User"
|
belongs_to :approver, optional: true, class_name: "User"
|
||||||
|
|
||||||
validates_presence_of :reason, on: :create
|
validates :reason, presence: true, on: :create
|
||||||
validates_presence_of :script
|
validates :script, presence: true
|
||||||
validates_presence_of :title, if: ->(rec) {rec.forum_topic_id.blank?}
|
validates :title, presence: true, if: ->(rec) { rec.forum_topic_id.blank? }
|
||||||
validates_presence_of :forum_topic, if: ->(rec) {rec.forum_topic_id.present?}
|
validates :forum_topic, presence: true, if: ->(rec) { rec.forum_topic_id.present? }
|
||||||
validates_inclusion_of :status, :in => %w(pending approved rejected)
|
validates :status, inclusion: { in: %w[pending approved rejected] }
|
||||||
validate :validate_script, if: :script_changed?
|
validate :validate_script, if: :script_changed?
|
||||||
|
|
||||||
before_save :update_tags, if: :script_changed?
|
before_save :update_tags, if: :script_changed?
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ class Comment < ApplicationRecord
|
|||||||
belongs_to :creator, class_name: "User"
|
belongs_to :creator, class_name: "User"
|
||||||
belongs_to_updater
|
belongs_to_updater
|
||||||
|
|
||||||
has_many :moderation_reports, as: :model
|
has_many :moderation_reports, as: :model, dependent: :destroy
|
||||||
has_many :votes, :class_name => "CommentVote", :dependent => :destroy
|
has_many :votes, class_name: "CommentVote", dependent: :destroy
|
||||||
|
|
||||||
validates :body, presence: true, length: { maximum: 15_000 }, if: :body_changed?
|
validates :body, presence: true, length: { maximum: 15_000 }, if: :body_changed?
|
||||||
|
|
||||||
@@ -20,9 +20,9 @@ class Comment < ApplicationRecord
|
|||||||
|
|
||||||
deletable
|
deletable
|
||||||
mentionable(
|
mentionable(
|
||||||
:message_field => :body,
|
message_field: :body,
|
||||||
:title => ->(user_name) {"#{creator.name} mentioned you in a comment on post ##{post_id}"},
|
title: ->(_user_name) {"#{creator.name} mentioned you in a comment on post ##{post_id}"},
|
||||||
:body => ->(user_name) {"@#{creator.name} mentioned you in comment ##{id} on post ##{post_id}:\n\n[quote]\n#{DText.extract_mention(body, "@" + user_name)}\n[/quote]\n"}
|
body: ->(user_name) {"@#{creator.name} mentioned you in comment ##{id} on post ##{post_id}:\n\n[quote]\n#{DText.extract_mention(body, "@#{user_name}")}\n[/quote]\n"}
|
||||||
)
|
)
|
||||||
|
|
||||||
module SearchMethods
|
module SearchMethods
|
||||||
@@ -55,7 +55,7 @@ class Comment < ApplicationRecord
|
|||||||
|
|
||||||
def update_last_commented_at_on_create
|
def update_last_commented_at_on_create
|
||||||
Post.where(:id => post_id).update_all(:last_commented_at => created_at)
|
Post.where(:id => post_id).update_all(:last_commented_at => created_at)
|
||||||
if Comment.where("post_id = ?", post_id).count <= Danbooru.config.comment_threshold && !do_not_bump_post?
|
if Comment.where(post_id: post_id).count <= Danbooru.config.comment_threshold && !do_not_bump_post?
|
||||||
Post.where(:id => post_id).update_all(:last_comment_bumped_at => created_at)
|
Post.where(:id => post_id).update_all(:last_comment_bumped_at => created_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ class CommentVote < ApplicationRecord
|
|||||||
validate :validate_vote_is_unique, if: :is_deleted_changed?
|
validate :validate_vote_is_unique, if: :is_deleted_changed?
|
||||||
validates :score, inclusion: { in: [-1, 1], message: "must be 1 or -1" }
|
validates :score, inclusion: { in: [-1, 1], message: "must be 1 or -1" }
|
||||||
|
|
||||||
before_create :update_score_on_create
|
|
||||||
before_save :update_score_on_delete_or_undelete, if: -> { !new_record? && is_deleted_changed? }
|
before_save :update_score_on_delete_or_undelete, if: -> { !new_record? && is_deleted_changed? }
|
||||||
|
before_create :update_score_on_create
|
||||||
|
|
||||||
deletable
|
deletable
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
require 'digest/sha1'
|
|
||||||
|
|
||||||
class Dmail < ApplicationRecord
|
class Dmail < ApplicationRecord
|
||||||
validate :validate_sender_is_not_limited, on: :create
|
validate :validate_sender_is_not_limited, on: :create
|
||||||
validates :title, presence: true, length: { maximum: 200 }, if: :title_changed?
|
validates :title, presence: true, length: { maximum: 200 }, if: :title_changed?
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ class ForumPost < ApplicationRecord
|
|||||||
|
|
||||||
deletable
|
deletable
|
||||||
mentionable(
|
mentionable(
|
||||||
:message_field => :body,
|
message_field: :body,
|
||||||
:title => ->(user_name) {%{#{creator.name} mentioned you in topic ##{topic_id} (#{topic.title})}},
|
title: ->(_user_name) {%{#{creator.name} mentioned you in topic ##{topic_id} (#{topic.title})}},
|
||||||
:body => ->(user_name) {%{@#{creator.name} mentioned you in topic ##{topic_id} ("#{topic.title}":[#{Routes.forum_topic_path(topic, page: forum_topic_page)}]):\n\n[quote]\n#{DText.extract_mention(body, "@" + user_name)}\n[/quote]\n}}
|
body: ->(user_name) {%{@#{creator.name} mentioned you in topic ##{topic_id} ("#{topic.title}":[#{Routes.forum_topic_path(topic, page: forum_topic_page)}]):\n\n[quote]\n#{DText.extract_mention(body, "@#{user_name}")}\n[/quote]\n}}
|
||||||
)
|
)
|
||||||
|
|
||||||
module SearchMethods
|
module SearchMethods
|
||||||
@@ -74,7 +74,7 @@ class ForumPost < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def voted?(user, score)
|
def voted?(user, score)
|
||||||
votes.where(creator_id: user.id, score: score).exists?
|
votes.exists?(creator_id: user.id, score: score)
|
||||||
end
|
end
|
||||||
|
|
||||||
def autoreport_spam
|
def autoreport_spam
|
||||||
@@ -149,7 +149,7 @@ class ForumPost < ApplicationRecord
|
|||||||
|
|
||||||
def is_original_post?(original_post_id = nil)
|
def is_original_post?(original_post_id = nil)
|
||||||
if original_post_id
|
if original_post_id
|
||||||
return id == original_post_id
|
id == original_post_id
|
||||||
else
|
else
|
||||||
ForumPost.exists?(["id = ? and id = (select _.id from forum_posts _ where _.topic_id = ? order by _.id asc limit 1)", id, topic_id])
|
ForumPost.exists?(["id = ? and id = (select _.id from forum_posts _ where _.topic_id = ? order by _.id asc limit 1)", id, topic_id])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class ForumPostVote < ApplicationRecord
|
|||||||
scope :up, -> {where(score: 1)}
|
scope :up, -> {where(score: 1)}
|
||||||
scope :down, -> {where(score: -1)}
|
scope :down, -> {where(score: -1)}
|
||||||
scope :by, ->(user_id) {where(creator_id: user_id)}
|
scope :by, ->(user_id) {where(creator_id: user_id)}
|
||||||
scope :excluding_user, ->(user_id) {where("creator_id <> ?", user_id)}
|
scope :excluding_user, ->(user_id) { where.not(creator_id: user_id) }
|
||||||
|
|
||||||
def self.visible(user)
|
def self.visible(user)
|
||||||
where(forum_post: ForumPost.visible(user))
|
where(forum_post: ForumPost.visible(user))
|
||||||
@@ -37,14 +37,13 @@ class ForumPostVote < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def vote_type
|
def vote_type
|
||||||
if score == 1
|
case score
|
||||||
return "up"
|
when 1
|
||||||
elsif score == -1
|
"up"
|
||||||
return "down"
|
when -1
|
||||||
elsif score == 0
|
"down"
|
||||||
return "meh"
|
when 0
|
||||||
else
|
"meh"
|
||||||
raise
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ class ForumTopic < ApplicationRecord
|
|||||||
CATEGORIES = {
|
CATEGORIES = {
|
||||||
0 => "General",
|
0 => "General",
|
||||||
1 => "Tags",
|
1 => "Tags",
|
||||||
2 => "Bugs & Features"
|
2 => "Bugs & Features",
|
||||||
}
|
}
|
||||||
|
|
||||||
MIN_LEVELS = {
|
MIN_LEVELS = {
|
||||||
None: 0,
|
None: 0,
|
||||||
Moderator: User::Levels::MODERATOR,
|
Moderator: User::Levels::MODERATOR,
|
||||||
Admin: User::Levels::ADMIN
|
Admin: User::Levels::ADMIN,
|
||||||
}
|
}
|
||||||
|
|
||||||
belongs_to :creator, class_name: "User"
|
belongs_to :creator, class_name: "User"
|
||||||
@@ -17,14 +17,14 @@ class ForumTopic < ApplicationRecord
|
|||||||
has_many :forum_topic_visits
|
has_many :forum_topic_visits
|
||||||
has_one :forum_topic_visit_by_current_user, -> { where(user_id: CurrentUser.id) }, class_name: "ForumTopicVisit"
|
has_one :forum_topic_visit_by_current_user, -> { where(user_id: CurrentUser.id) }, class_name: "ForumTopicVisit"
|
||||||
has_one :original_post, -> { order(id: :asc) }, class_name: "ForumPost", foreign_key: "topic_id", inverse_of: :topic
|
has_one :original_post, -> { order(id: :asc) }, class_name: "ForumPost", foreign_key: "topic_id", inverse_of: :topic
|
||||||
has_many :bulk_update_requests, :foreign_key => "forum_topic_id"
|
has_many :bulk_update_requests
|
||||||
has_many :tag_aliases, :foreign_key => "forum_topic_id"
|
has_many :tag_aliases
|
||||||
has_many :tag_implications, :foreign_key => "forum_topic_id"
|
has_many :tag_implications
|
||||||
|
|
||||||
validates :title, presence: true, length: { maximum: 200 }, if: :title_changed?
|
validates :title, presence: true, length: { maximum: 200 }, if: :title_changed?
|
||||||
validates_associated :original_post
|
validates_associated :original_post
|
||||||
validates_inclusion_of :category_id, :in => CATEGORIES.keys
|
validates :category_id, inclusion: { in: CATEGORIES.keys }
|
||||||
validates_inclusion_of :min_level, :in => MIN_LEVELS.values
|
validates :min_level, inclusion: { in: MIN_LEVELS.values }
|
||||||
|
|
||||||
accepts_nested_attributes_for :original_post
|
accepts_nested_attributes_for :original_post
|
||||||
after_update :update_orignal_post
|
after_update :update_orignal_post
|
||||||
@@ -129,9 +129,9 @@ class ForumTopic < ApplicationRecord
|
|||||||
def mark_as_read!(user = CurrentUser.user)
|
def mark_as_read!(user = CurrentUser.user)
|
||||||
return if user.is_anonymous?
|
return if user.is_anonymous?
|
||||||
|
|
||||||
match = ForumTopicVisit.where(:user_id => user.id, :forum_topic_id => id).first
|
visit = ForumTopicVisit.find_by(user_id: user.id, forum_topic_id: id)
|
||||||
if match
|
if visit
|
||||||
match.update_attribute(:last_read_at, updated_at)
|
visit.update!(last_read_at: updated_at)
|
||||||
else
|
else
|
||||||
ForumTopicVisit.create(:user_id => user.id, :forum_topic_id => id, :last_read_at => updated_at)
|
ForumTopicVisit.create(:user_id => user.id, :forum_topic_id => id, :last_read_at => updated_at)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class IpBan < ApplicationRecord
|
|||||||
deletable
|
deletable
|
||||||
enum category: {
|
enum category: {
|
||||||
full: 0,
|
full: 0,
|
||||||
partial: 100
|
partial: 100,
|
||||||
}, _suffix: "ban"
|
}, _suffix: "ban"
|
||||||
|
|
||||||
def self.visible(user)
|
def self.visible(user)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class ModAction < ApplicationRecord
|
|||||||
ip_ban_undelete: 163,
|
ip_ban_undelete: 163,
|
||||||
mass_update: 1000, # XXX unused
|
mass_update: 1000, # XXX unused
|
||||||
bulk_revert: 1001, # XXX unused
|
bulk_revert: 1001, # XXX unused
|
||||||
other: 2000
|
other: 2000,
|
||||||
}
|
}
|
||||||
|
|
||||||
def self.visible(user)
|
def self.visible(user)
|
||||||
|
|||||||
@@ -2,9 +2,14 @@ class Note < ApplicationRecord
|
|||||||
class RevertError < StandardError; end
|
class RevertError < StandardError; end
|
||||||
|
|
||||||
attr_accessor :html_id
|
attr_accessor :html_id
|
||||||
|
|
||||||
belongs_to :post
|
belongs_to :post
|
||||||
has_many :versions, -> {order("note_versions.id ASC")}, :class_name => "NoteVersion", :dependent => :destroy
|
has_many :versions, -> {order("note_versions.id ASC")}, :class_name => "NoteVersion", :dependent => :destroy
|
||||||
validates_presence_of :x, :y, :width, :height, :body
|
validates :x, presence: true
|
||||||
|
validates :y, presence: true
|
||||||
|
validates :width, presence: true
|
||||||
|
validates :height, presence: true
|
||||||
|
validates :body, presence: true
|
||||||
validate :note_within_image
|
validate :note_within_image
|
||||||
after_save :update_post
|
after_save :update_post
|
||||||
after_save :create_version
|
after_save :create_version
|
||||||
@@ -95,7 +100,7 @@ class Note < ApplicationRecord
|
|||||||
|
|
||||||
def revert_to(version)
|
def revert_to(version)
|
||||||
if id != version.note_id
|
if id != version.note_id
|
||||||
raise RevertError.new("You cannot revert to a previous version of another note.")
|
raise RevertError, "You cannot revert to a previous version of another note."
|
||||||
end
|
end
|
||||||
|
|
||||||
self.x = version.x
|
self.x = version.x
|
||||||
|
|||||||
@@ -11,23 +11,17 @@ class NoteVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def previous
|
def previous
|
||||||
@previous ||= begin
|
@previous ||= NoteVersion.where("note_id = ? and version < ?", note_id, version).order("updated_at desc").limit(1).to_a
|
||||||
NoteVersion.where("note_id = ? and version < ?", note_id, version).order("updated_at desc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@previous.first
|
@previous.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def subsequent
|
def subsequent
|
||||||
@subsequent ||= begin
|
@subsequent ||= NoteVersion.where("note_id = ? and version > ?", note_id, version).order("updated_at asc").limit(1).to_a
|
||||||
NoteVersion.where("note_id = ? and version > ?", note_id, version).order("updated_at asc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@subsequent.first
|
@subsequent.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def current
|
def current
|
||||||
@current ||= begin
|
@current ||= NoteVersion.where(note_id: note_id).order("updated_at desc").limit(1).to_a
|
||||||
NoteVersion.where("note_id = ?", note_id).order("updated_at desc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@current.first
|
@current.first
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -42,17 +36,17 @@ class NoteVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_moved(type)
|
def was_moved(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
x != other.x || y != other.y
|
x != other.x || y != other.y
|
||||||
end
|
end
|
||||||
|
|
||||||
def was_resized(type)
|
def was_resized(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
width != other.width || height != other.height
|
width != other.width || height != other.height
|
||||||
end
|
end
|
||||||
|
|
||||||
def was_deleted(type)
|
def was_deleted(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
!is_active && other.is_active
|
!is_active && other.is_active
|
||||||
else
|
else
|
||||||
@@ -61,7 +55,7 @@ class NoteVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_undeleted(type)
|
def was_undeleted(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
is_active && !other.is_active
|
is_active && !other.is_active
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ class Pool < ApplicationRecord
|
|||||||
|
|
||||||
array_attribute :post_ids, parse: /\d+/, cast: :to_i
|
array_attribute :post_ids, parse: /\d+/, cast: :to_i
|
||||||
|
|
||||||
validates_uniqueness_of :name, case_sensitive: false, if: :name_changed?
|
validates :name, uniqueness: { case_sensitive: false }, if: :name_changed?
|
||||||
validate :validate_name, if: :name_changed?
|
validate :validate_name, if: :name_changed?
|
||||||
validates_inclusion_of :category, :in => %w(series collection)
|
validates :category, inclusion: { in: %w[series collection] }
|
||||||
validate :updater_can_edit_deleted
|
validate :updater_can_edit_deleted
|
||||||
before_validation :normalize_post_ids
|
before_validation :normalize_post_ids
|
||||||
before_validation :normalize_name
|
before_validation :normalize_name
|
||||||
after_save :create_version
|
|
||||||
after_create :synchronize!
|
after_create :synchronize!
|
||||||
|
after_save :create_version
|
||||||
|
|
||||||
deletable
|
deletable
|
||||||
|
|
||||||
@@ -47,9 +47,10 @@ class Pool < ApplicationRecord
|
|||||||
q = q.name_matches(params[:name_matches])
|
q = q.name_matches(params[:name_matches])
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:category] == "series"
|
case params[:category]
|
||||||
|
when "series"
|
||||||
q = q.series
|
q = q.series
|
||||||
elsif params[:category] == "collection"
|
when "collection"
|
||||||
q = q.collection
|
q = q.collection
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -80,7 +81,7 @@ class Pool < ApplicationRecord
|
|||||||
|
|
||||||
def self.named(name)
|
def self.named(name)
|
||||||
if name =~ /^\d+$/
|
if name =~ /^\d+$/
|
||||||
where("pools.id = ?", name.to_i)
|
where(id: name.to_i)
|
||||||
elsif name
|
elsif name
|
||||||
where_ilike(:name, normalize_name_for_search(name))
|
where_ilike(:name, normalize_name_for_search(name))
|
||||||
else
|
else
|
||||||
@@ -93,11 +94,8 @@ class Pool < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def versions
|
def versions
|
||||||
if PoolVersion.enabled?
|
raise NotImplementedError, "Archive service not configured" unless PoolVersion.enabled?
|
||||||
PoolVersion.where("pool_id = ?", id).order("id asc")
|
PoolVersion.where(pool_id: id).order("id asc")
|
||||||
else
|
|
||||||
raise "Archive service not configured"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_series?
|
def is_series?
|
||||||
@@ -126,7 +124,7 @@ class Pool < ApplicationRecord
|
|||||||
|
|
||||||
def revert_to!(version)
|
def revert_to!(version)
|
||||||
if id != version.pool_id
|
if id != version.pool_id
|
||||||
raise RevertError.new("You cannot revert to a previous version of another pool.")
|
raise RevertError, "You cannot revert to a previous version of another pool."
|
||||||
end
|
end
|
||||||
|
|
||||||
self.post_ids = version.post_ids
|
self.post_ids = version.post_ids
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class PoolVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def for_user(user_id)
|
def for_user(user_id)
|
||||||
where("updater_id = ?", user_id)
|
where(updater_id: user_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def for_post_id(post_id)
|
def for_post_id(post_id)
|
||||||
@@ -65,7 +65,7 @@ class PoolVersion < ApplicationRecord
|
|||||||
def self.queue(pool, updater, updater_ip_addr)
|
def self.queue(pool, updater, updater_ip_addr)
|
||||||
# queue updates to sqs so that if archives goes down for whatever reason it won't
|
# queue updates to sqs so that if archives goes down for whatever reason it won't
|
||||||
# block pool updates
|
# block pool updates
|
||||||
raise NotImplementedError.new("Archive service is not configured.") if !enabled?
|
raise NotImplementedError, "Archive service is not configured." if !enabled?
|
||||||
|
|
||||||
json = {
|
json = {
|
||||||
pool_id: pool.id,
|
pool_id: pool.id,
|
||||||
@@ -93,23 +93,17 @@ class PoolVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def previous
|
def previous
|
||||||
@previous ||= begin
|
@previous ||= PoolVersion.where("pool_id = ? and version < ?", pool_id, version).order("version desc").limit(1).to_a
|
||||||
PoolVersion.where("pool_id = ? and version < ?", pool_id, version).order("version desc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@previous.first
|
@previous.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def subsequent
|
def subsequent
|
||||||
@subsequent ||= begin
|
@subsequent ||= PoolVersion.where("pool_id = ? and version > ?", pool_id, version).order("version asc").limit(1).to_a
|
||||||
PoolVersion.where("pool_id = ? and version > ?", pool_id, version).order("version asc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@subsequent.first
|
@subsequent.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def current
|
def current
|
||||||
@current ||= begin
|
@current ||= PoolVersion.where(pool_id: pool_id).order("version desc").limit(1).to_a
|
||||||
PoolVersion.where("pool_id = ?", pool_id).order("version desc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@current.first
|
@current.first
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -126,12 +120,12 @@ class PoolVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def posts_changed(type)
|
def posts_changed(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
((post_ids - other.post_ids) | (other.post_ids - post_ids)).length.positive?
|
((post_ids - other.post_ids) | (other.post_ids - post_ids)).length.positive?
|
||||||
end
|
end
|
||||||
|
|
||||||
def was_deleted(type)
|
def was_deleted(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
is_deleted && !other.is_deleted
|
is_deleted && !other.is_deleted
|
||||||
else
|
else
|
||||||
@@ -140,7 +134,7 @@ class PoolVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_undeleted(type)
|
def was_undeleted(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
!is_deleted && other.is_deleted
|
!is_deleted && other.is_deleted
|
||||||
else
|
else
|
||||||
@@ -149,7 +143,7 @@ class PoolVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_activated(type)
|
def was_activated(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
is_active && !other.is_active
|
is_active && !other.is_active
|
||||||
else
|
else
|
||||||
@@ -158,7 +152,7 @@ class PoolVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_deactivated(type)
|
def was_deactivated(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
!is_active && other.is_active
|
!is_active && other.is_active
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class Post < ApplicationRecord
|
|||||||
before_validation :parse_pixiv_id
|
before_validation :parse_pixiv_id
|
||||||
before_validation :blank_out_nonexistent_parents
|
before_validation :blank_out_nonexistent_parents
|
||||||
before_validation :remove_parent_loops
|
before_validation :remove_parent_loops
|
||||||
validates_uniqueness_of :md5, :on => :create, message: ->(obj, data) { "duplicate: #{Post.find_by_md5(obj.md5).id}"}
|
validates :md5, uniqueness: { message: ->(post, _data) { "duplicate: #{Post.find_by_md5(post.md5).id}" }}, on: :create
|
||||||
validates_inclusion_of :rating, in: %w(s q e), message: "rating must be s, q, or e"
|
validates :rating, inclusion: { in: %w[s q e], message: "rating must be s, q, or e" }
|
||||||
validates :source, length: { maximum: 1200 }
|
validates :source, length: { maximum: 1200 }
|
||||||
validate :added_tags_are_valid
|
validate :added_tags_are_valid
|
||||||
validate :removed_tags_are_valid
|
validate :removed_tags_are_valid
|
||||||
@@ -79,8 +79,8 @@ class Post < ApplicationRecord
|
|||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def delete_files(post_id, md5, file_ext, force: false)
|
def delete_files(post_id, md5, file_ext, force: false)
|
||||||
if Post.where(md5: md5).exists? && !force
|
if Post.exists?(md5: md5) && !force
|
||||||
raise DeletionError.new("Files still in use; skipping deletion.")
|
raise DeletionError, "Files still in use; skipping deletion."
|
||||||
end
|
end
|
||||||
|
|
||||||
Danbooru.config.storage_manager.delete_file(post_id, md5, file_ext, :original)
|
Danbooru.config.storage_manager.delete_file(post_id, md5, file_ext, :original)
|
||||||
@@ -302,7 +302,7 @@ class Post < ApplicationRecord
|
|||||||
flag = flags.create(reason: reason, is_deletion: is_deletion, creator: CurrentUser.user)
|
flag = flags.create(reason: reason, is_deletion: is_deletion, creator: CurrentUser.user)
|
||||||
|
|
||||||
if flag.errors.any?
|
if flag.errors.any?
|
||||||
raise PostFlag::Error.new(flag.errors.full_messages.join("; "))
|
raise PostFlag::Error, flag.errors.full_messages.join("; ")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -311,7 +311,7 @@ class Post < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def disapproved_by?(user)
|
def disapproved_by?(user)
|
||||||
PostDisapproval.where(:user_id => user.id, :post_id => id).exists?
|
PostDisapproval.exists?(user_id: user.id, post_id: id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def autoban
|
def autoban
|
||||||
@@ -353,7 +353,7 @@ class Post < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def source_domain
|
def source_domain
|
||||||
return "" unless source =~ %r!\Ahttps?://!i
|
return "" unless source =~ %r{\Ahttps?://}i
|
||||||
|
|
||||||
url = Addressable::URI.parse(normalized_source)
|
url = Addressable::URI.parse(normalized_source)
|
||||||
url.domain
|
url.domain
|
||||||
@@ -400,11 +400,11 @@ class Post < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def set_tag_count(category, tagcount)
|
def set_tag_count(category, tagcount)
|
||||||
self.send("tag_count_#{category}=", tagcount)
|
send("tag_count_#{category}=", tagcount)
|
||||||
end
|
end
|
||||||
|
|
||||||
def inc_tag_count(category)
|
def inc_tag_count(category)
|
||||||
set_tag_count(category, self.send("tag_count_#{category}") + 1)
|
set_tag_count(category, send("tag_count_#{category}") + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_tag_counts
|
def set_tag_counts
|
||||||
@@ -469,7 +469,7 @@ class Post < ApplicationRecord
|
|||||||
normalized_tags = filter_metatags(normalized_tags)
|
normalized_tags = filter_metatags(normalized_tags)
|
||||||
normalized_tags = TagAlias.to_aliased(normalized_tags)
|
normalized_tags = TagAlias.to_aliased(normalized_tags)
|
||||||
normalized_tags = remove_negated_tags(normalized_tags)
|
normalized_tags = remove_negated_tags(normalized_tags)
|
||||||
normalized_tags = %w(tagme) if normalized_tags.empty?
|
normalized_tags = %w[tagme] if normalized_tags.empty?
|
||||||
normalized_tags = add_automatic_tags(normalized_tags)
|
normalized_tags = add_automatic_tags(normalized_tags)
|
||||||
normalized_tags = remove_invalid_tags(normalized_tags)
|
normalized_tags = remove_invalid_tags(normalized_tags)
|
||||||
normalized_tags = Tag.convert_cosplay_tags(normalized_tags)
|
normalized_tags = Tag.convert_cosplay_tags(normalized_tags)
|
||||||
@@ -496,11 +496,11 @@ class Post < ApplicationRecord
|
|||||||
@negated_tags, tags = tags.partition {|x| x =~ /\A-/i}
|
@negated_tags, tags = tags.partition {|x| x =~ /\A-/i}
|
||||||
@negated_tags = @negated_tags.map {|x| x[1..-1]}
|
@negated_tags = @negated_tags.map {|x| x[1..-1]}
|
||||||
@negated_tags = TagAlias.to_aliased(@negated_tags)
|
@negated_tags = TagAlias.to_aliased(@negated_tags)
|
||||||
return tags - @negated_tags
|
tags - @negated_tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_automatic_tags(tags)
|
def add_automatic_tags(tags)
|
||||||
tags -= %w(incredibly_absurdres absurdres highres lowres huge_filesize flash)
|
tags -= %w[incredibly_absurdres absurdres highres lowres huge_filesize flash]
|
||||||
|
|
||||||
if has_dimensions?
|
if has_dimensions?
|
||||||
if image_width >= 10_000 || image_height >= 10_000
|
if image_width >= 10_000 || image_height >= 10_000
|
||||||
@@ -549,7 +549,7 @@ class Post < ApplicationRecord
|
|||||||
tags -= ["animated_png"]
|
tags -= ["animated_png"]
|
||||||
end
|
end
|
||||||
|
|
||||||
return tags
|
tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_casesensitive_metatags(tags)
|
def apply_casesensitive_metatags(tags)
|
||||||
@@ -574,7 +574,8 @@ class Post < ApplicationRecord
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return tags
|
|
||||||
|
tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_metatags(tags)
|
def filter_metatags(tags)
|
||||||
@@ -582,7 +583,7 @@ class Post < ApplicationRecord
|
|||||||
tags = apply_categorization_metatags(tags)
|
tags = apply_categorization_metatags(tags)
|
||||||
@post_metatags, tags = tags.partition {|x| x =~ /\A(?:-pool|pool|newpool|fav|-fav|child|-child|-favgroup|favgroup|upvote|downvote|status|-status|disapproved):/i}
|
@post_metatags, tags = tags.partition {|x| x =~ /\A(?:-pool|pool|newpool|fav|-fav|child|-child|-favgroup|favgroup|upvote|downvote|status|-status|disapproved):/i}
|
||||||
apply_pre_metatags
|
apply_pre_metatags
|
||||||
return tags
|
tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_categorization_metatags(tags)
|
def apply_categorization_metatags(tags)
|
||||||
@@ -1043,7 +1044,7 @@ class Post < ApplicationRecord
|
|||||||
|
|
||||||
def revert_to(target)
|
def revert_to(target)
|
||||||
if id != target.post_id
|
if id != target.post_id
|
||||||
raise RevertError.new("You cannot revert to a previous version of another post.")
|
raise RevertError, "You cannot revert to a previous version of another post."
|
||||||
end
|
end
|
||||||
|
|
||||||
self.tag_string = target.tags
|
self.tag_string = target.tags
|
||||||
@@ -1359,13 +1360,11 @@ class Post < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def updater_can_change_rating
|
def updater_can_change_rating
|
||||||
if rating_changed? && is_rating_locked?
|
|
||||||
# Don't forbid changes if the rating lock was just now set in the same update.
|
# Don't forbid changes if the rating lock was just now set in the same update.
|
||||||
if !is_rating_locked_changed?
|
if rating_changed? && is_rating_locked? && !is_rating_locked_changed?
|
||||||
errors.add(:rating, "is locked and cannot be changed. Unlock the post first.")
|
errors.add(:rating, "is locked and cannot be changed. Unlock the post first.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def uploader_is_not_limited
|
def uploader_is_not_limited
|
||||||
errors.add(:uploader, "have reached your upload limit") if uploader.upload_limit.limited?
|
errors.add(:uploader, "have reached your upload limit") if uploader.upload_limit.limited?
|
||||||
@@ -1401,7 +1400,7 @@ class Post < ApplicationRecord
|
|||||||
|
|
||||||
def has_artist_tag
|
def has_artist_tag
|
||||||
return if !new_record?
|
return if !new_record?
|
||||||
return if source !~ %r!\Ahttps?://!
|
return if source !~ %r{\Ahttps?://}
|
||||||
return if has_tag?("artist_request") || has_tag?("official_art")
|
return if has_tag?("artist_request") || has_tag?("official_art")
|
||||||
return if tags.any?(&:artist?)
|
return if tags.any?(&:artist?)
|
||||||
return if Sources::Strategies.find(source).is_a?(Sources::Strategies::Null)
|
return if Sources::Strategies.find(source).is_a?(Sources::Strategies::Null)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class PostAppeal < ApplicationRecord
|
|||||||
enum status: {
|
enum status: {
|
||||||
pending: 0,
|
pending: 0,
|
||||||
succeeded: 1,
|
succeeded: 1,
|
||||||
rejected: 2
|
rejected: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
scope :expired, -> { pending.where("post_appeals.created_at < ?", Danbooru.config.moderation_period.ago) }
|
scope :expired, -> { pending.where("post_appeals.created_at < ?", Danbooru.config.moderation_period.ago) }
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class PostApproval < ApplicationRecord
|
|||||||
errors.add(:base, "You cannot approve a post you uploaded")
|
errors.add(:base, "You cannot approve a post you uploaded")
|
||||||
end
|
end
|
||||||
|
|
||||||
if post.approver == user || post.approvals.where(user: user).exists?
|
if post.approver == user || post.approvals.exists?(user: user)
|
||||||
errors.add(:base, "You have previously approved this post and cannot approve it again")
|
errors.add(:base, "You have previously approved this post and cannot approve it again")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class PostDisapproval < ApplicationRecord
|
|||||||
belongs_to :post
|
belongs_to :post
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
validates :user, uniqueness: { scope: :post, message: "have already hidden this post" }
|
validates :user, uniqueness: { scope: :post, message: "have already hidden this post" }
|
||||||
validates_inclusion_of :reason, in: REASONS
|
validates :reason, inclusion: { in: REASONS }
|
||||||
validate :validate_disapproval
|
validate :validate_disapproval
|
||||||
|
|
||||||
scope :with_message, -> { where.not(message: nil) }
|
scope :with_message, -> { where.not(message: nil) }
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ class PostEvent
|
|||||||
include ActiveModel::Serializers::Xml
|
include ActiveModel::Serializers::Xml
|
||||||
|
|
||||||
attr_accessor :event
|
attr_accessor :event
|
||||||
|
|
||||||
delegate :created_at, to: :event
|
delegate :created_at, to: :event
|
||||||
|
|
||||||
def self.find_for_post(post_id)
|
def self.find_for_post(post_id)
|
||||||
@@ -62,11 +63,11 @@ class PostEvent
|
|||||||
|
|
||||||
def attributes
|
def attributes
|
||||||
{
|
{
|
||||||
"creator_id": nil,
|
creator_id: nil,
|
||||||
"created_at": nil,
|
created_at: nil,
|
||||||
"reason": nil,
|
reason: nil,
|
||||||
"status": nil,
|
status: nil,
|
||||||
"type": nil
|
type: nil,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class PostFlag < ApplicationRecord
|
|||||||
enum status: {
|
enum status: {
|
||||||
pending: 0,
|
pending: 0,
|
||||||
succeeded: 1,
|
succeeded: 1,
|
||||||
rejected: 2
|
rejected: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
scope :by_users, -> { where.not(creator: User.system) }
|
scope :by_users, -> { where.not(creator: User.system) }
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class PostReplacement < ApplicationRecord
|
|||||||
def initialize_fields
|
def initialize_fields
|
||||||
self.creator = CurrentUser.user
|
self.creator = CurrentUser.user
|
||||||
self.original_url = post.source
|
self.original_url = post.source
|
||||||
self.tags = post.tag_string + " " + self.tags.to_s
|
self.tags = "#{post.tag_string} #{tags}"
|
||||||
|
|
||||||
self.old_file_ext = post.file_ext
|
self.old_file_ext = post.file_ext
|
||||||
self.old_file_size = post.file_size
|
self.old_file_size = post.file_size
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class PostVersion < ApplicationRecord
|
|||||||
def queue(post)
|
def queue(post)
|
||||||
# queue updates to sqs so that if archives goes down for whatever reason it won't
|
# queue updates to sqs so that if archives goes down for whatever reason it won't
|
||||||
# block post updates
|
# block post updates
|
||||||
raise NotImplementedError.new("Archive service is not configured") if !enabled?
|
raise NotImplementedError, "Archive service is not configured" if !enabled?
|
||||||
|
|
||||||
json = {
|
json = {
|
||||||
"post_id" => post.id,
|
"post_id" => post.id,
|
||||||
@@ -92,7 +92,7 @@ class PostVersion < ApplicationRecord
|
|||||||
"updater_ip_addr" => CurrentUser.ip_addr.to_s,
|
"updater_ip_addr" => CurrentUser.ip_addr.to_s,
|
||||||
"updated_at" => post.updated_at.try(:iso8601),
|
"updated_at" => post.updated_at.try(:iso8601),
|
||||||
"created_at" => post.created_at.try(:iso8601),
|
"created_at" => post.created_at.try(:iso8601),
|
||||||
"tags" => post.tag_string
|
"tags" => post.tag_string,
|
||||||
}
|
}
|
||||||
msg = "add post version\n#{json.to_json}"
|
msg = "add post version\n#{json.to_json}"
|
||||||
sqs_service.send_message(msg, message_group_id: "post:#{post.id}")
|
sqs_service.send_message(msg, message_group_id: "post:#{post.id}")
|
||||||
@@ -117,25 +117,21 @@ class PostVersion < ApplicationRecord
|
|||||||
# HACK: if all the post versions for this post have already been preloaded,
|
# HACK: if all the post versions for this post have already been preloaded,
|
||||||
# we can use that to avoid a SQL query.
|
# we can use that to avoid a SQL query.
|
||||||
if association(:post).loaded? && post && post.association(:versions).loaded?
|
if association(:post).loaded? && post && post.association(:versions).loaded?
|
||||||
ver = [post.versions.sort_by(&:version).reverse.find { |v| v.version < version }]
|
[post.versions.sort_by(&:version).reverse.find { |v| v.version < version }]
|
||||||
else
|
else
|
||||||
ver = PostVersion.where("post_id = ? and version < ?", post_id, version).order("version desc").limit(1).to_a
|
PostVersion.where("post_id = ? and version < ?", post_id, version).order("version desc").limit(1).to_a
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@previous.first
|
@previous.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def subsequent
|
def subsequent
|
||||||
@subsequent ||= begin
|
@subsequent ||= PostVersion.where("post_id = ? and version > ?", post_id, version).order("version asc").limit(1).to_a
|
||||||
PostVersion.where("post_id = ? and version > ?", post_id, version).order("version asc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@subsequent.first
|
@subsequent.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def current
|
def current
|
||||||
@current ||= begin
|
@current ||= PostVersion.where(post_id: post_id).order("version desc").limit(1).to_a
|
||||||
PostVersion.where("post_id = ?", post_id).order("version desc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@current.first
|
@current.first
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -167,11 +163,11 @@ class PostVersion < ApplicationRecord
|
|||||||
|
|
||||||
def changes
|
def changes
|
||||||
delta = {
|
delta = {
|
||||||
:added_tags => added_tags,
|
added_tags: added_tags,
|
||||||
:removed_tags => removed_tags,
|
removed_tags: removed_tags,
|
||||||
:obsolete_removed_tags => [],
|
obsolete_removed_tags: [],
|
||||||
:obsolete_added_tags => [],
|
obsolete_added_tags: [],
|
||||||
:unchanged_tags => []
|
unchanged_tags: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
return delta if post.nil?
|
return delta if post.nil?
|
||||||
@@ -252,9 +248,10 @@ class PostVersion < ApplicationRecord
|
|||||||
removed = changes[:removed_tags] - changes[:obsolete_removed_tags]
|
removed = changes[:removed_tags] - changes[:obsolete_removed_tags]
|
||||||
|
|
||||||
added.each do |tag|
|
added.each do |tag|
|
||||||
if tag =~ /^source:/
|
case tag
|
||||||
|
when /^source:/
|
||||||
post.source = ""
|
post.source = ""
|
||||||
elsif tag =~ /^parent:/
|
when /^parent:/
|
||||||
post.parent_id = nil
|
post.parent_id = nil
|
||||||
else
|
else
|
||||||
escaped_tag = Regexp.escape(tag)
|
escaped_tag = Regexp.escape(tag)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ class SavedSearch < ApplicationRecord
|
|||||||
QUERY_LIMIT = 1000
|
QUERY_LIMIT = 1000
|
||||||
|
|
||||||
attr_reader :disable_labels
|
attr_reader :disable_labels
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
||||||
normalize :query, :normalize_query
|
normalize :query, :normalize_query
|
||||||
@@ -146,7 +147,7 @@ class SavedSearch < ApplicationRecord
|
|||||||
PostQueryBuilder.new(query.to_s).normalized_query(sort: false).to_s
|
PostQueryBuilder.new(query.to_s).normalized_query(sort: false).to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def queries_for(user_id, label: nil, options: {})
|
def queries_for(user_id, label: nil)
|
||||||
searches = SavedSearch.where(user_id: user_id)
|
searches = SavedSearch.where(user_id: user_id)
|
||||||
searches = searches.labeled(label) if label.present?
|
searches = searches.labeled(label) if label.present?
|
||||||
queries = searches.map(&:normalized_query)
|
queries = searches.map(&:normalized_query)
|
||||||
@@ -167,8 +168,8 @@ class SavedSearch < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def rewrite_query(old_name, new_name)
|
def rewrite_query(old_name, new_name)
|
||||||
self.query.gsub!(/(?:\A| )([-~])?#{Regexp.escape(old_name)}(?: |\z)/i) { " #{$1}#{new_name} " }
|
query.gsub!(/(?:\A| )([-~])?#{Regexp.escape(old_name)}(?: |\z)/i) { " #{$1}#{new_name} " }
|
||||||
self.query.strip!
|
query.strip!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Tag < ApplicationRecord
|
|||||||
|
|
||||||
validates :name, tag_name: true, uniqueness: true, on: :create
|
validates :name, tag_name: true, uniqueness: true, on: :create
|
||||||
validates :name, tag_name: true, on: :name
|
validates :name, tag_name: true, on: :name
|
||||||
validates_inclusion_of :category, in: TagCategory.category_ids
|
validates :category, inclusion: { in: TagCategory.category_ids }
|
||||||
|
|
||||||
after_save :update_category_cache, if: :saved_change_to_category?
|
after_save :update_category_cache, if: :saved_change_to_category?
|
||||||
after_save :update_category_post_counts, if: :saved_change_to_category?
|
after_save :update_category_post_counts, if: :saved_change_to_category?
|
||||||
@@ -21,13 +21,13 @@ class Tag < ApplicationRecord
|
|||||||
|
|
||||||
module ApiMethods
|
module ApiMethods
|
||||||
def to_legacy_json
|
def to_legacy_json
|
||||||
return {
|
{
|
||||||
"name" => name,
|
name: name,
|
||||||
"id" => id,
|
id: id,
|
||||||
"created_at" => created_at.try(:strftime, "%Y-%m-%d %H:%M"),
|
created_at: created_at.try(:strftime, "%Y-%m-%d %H:%M"),
|
||||||
"count" => post_count,
|
count: post_count,
|
||||||
"type" => category,
|
type: category,
|
||||||
"ambiguous" => false
|
ambiguous: false,
|
||||||
}.to_json
|
}.to_json
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -255,7 +255,7 @@ class Tag < ApplicationRecord
|
|||||||
|
|
||||||
def abbreviation_matches(abbrev)
|
def abbreviation_matches(abbrev)
|
||||||
abbrev = abbrev.downcase.delete_prefix("/")
|
abbrev = abbrev.downcase.delete_prefix("/")
|
||||||
return none if abbrev !~ /\A[a-z0-9\*]*\z/
|
return none if abbrev !~ /\A[a-z0-9*]*\z/
|
||||||
|
|
||||||
where("regexp_replace(tags.name, ?, '\\1', 'g') LIKE ?", ABBREVIATION_REGEXP.source, abbrev.to_escaped_for_sql_like)
|
where("regexp_replace(tags.name, ?, '\\1', 'g') LIKE ?", ABBREVIATION_REGEXP.source, abbrev.to_escaped_for_sql_like)
|
||||||
end
|
end
|
||||||
@@ -309,7 +309,7 @@ class Tag < ApplicationRecord
|
|||||||
|
|
||||||
def names_matches_with_aliases(name, limit)
|
def names_matches_with_aliases(name, limit)
|
||||||
name = normalize_name(name)
|
name = normalize_name(name)
|
||||||
wildcard_name = name + '*'
|
wildcard_name = "#{name}*"
|
||||||
|
|
||||||
query1 =
|
query1 =
|
||||||
Tag
|
Tag
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ class TagRelationship < ApplicationRecord
|
|||||||
|
|
||||||
before_validation :normalize_names
|
before_validation :normalize_names
|
||||||
validates :status, inclusion: { in: %w[active deleted retired] }
|
validates :status, inclusion: { in: %w[active deleted retired] }
|
||||||
validates_presence_of :antecedent_name, :consequent_name
|
validates :antecedent_name, presence: true
|
||||||
|
validates :consequent_name, presence: true
|
||||||
validates :approver, presence: { message: "must exist" }, if: -> { approver_id.present? }
|
validates :approver, presence: { message: "must exist" }, if: -> { approver_id.present? }
|
||||||
validates :forum_topic, presence: { message: "must exist" }, if: -> { forum_topic_id.present? }
|
validates :forum_topic, presence: { message: "must exist" }, if: -> { forum_topic_id.present? }
|
||||||
validate :antecedent_and_consequent_are_different
|
validate :antecedent_and_consequent_are_different
|
||||||
@@ -110,7 +111,7 @@ class TagRelationship < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.approve!(antecedent_name:, consequent_name:, approver:, forum_topic: nil)
|
def self.approve!(antecedent_name:, consequent_name:, approver:, forum_topic: nil)
|
||||||
ProcessTagRelationshipJob.perform_later(class_name: self.name, approver: approver, antecedent_name: antecedent_name, consequent_name: consequent_name, forum_topic: forum_topic)
|
ProcessTagRelationshipJob.perform_later(class_name: name, approver: approver, antecedent_name: antecedent_name, consequent_name: consequent_name, forum_topic: forum_topic)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.model_restriction(table)
|
def self.model_restriction(table)
|
||||||
|
|||||||
@@ -62,13 +62,14 @@ class Upload < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :as_pending, :replaced_post, :file
|
attr_accessor :as_pending, :replaced_post, :file
|
||||||
|
|
||||||
belongs_to :uploader, :class_name => "User"
|
belongs_to :uploader, :class_name => "User"
|
||||||
belongs_to :post, optional: true
|
belongs_to :post, optional: true
|
||||||
|
|
||||||
before_validation :initialize_attributes, on: :create
|
before_validation :initialize_attributes, on: :create
|
||||||
before_validation :assign_rating_from_tags
|
before_validation :assign_rating_from_tags
|
||||||
# validates :source, format: { with: /\Ahttps?/ }, if: ->(record) {record.file.blank?}, on: :create
|
# validates :source, format: { with: /\Ahttps?/ }, if: ->(record) {record.file.blank?}, on: :create
|
||||||
validates :rating, inclusion: { in: %w(q e s) }, allow_nil: true
|
validates :rating, inclusion: { in: %w[q e s] }, allow_nil: true
|
||||||
validates :md5, confirmation: true, if: ->(rec) { rec.md5_confirmation.present? }
|
validates :md5, confirmation: true, if: ->(rec) { rec.md5_confirmation.present? }
|
||||||
validates_with FileValidator, on: :file
|
validates_with FileValidator, on: :file
|
||||||
serialize :context, JSON
|
serialize :context, JSON
|
||||||
@@ -109,7 +110,7 @@ class Upload < ApplicationRecord
|
|||||||
|
|
||||||
def delete_files
|
def delete_files
|
||||||
# md5 is blank if the upload errored out before downloading the file.
|
# md5 is blank if the upload errored out before downloading the file.
|
||||||
if is_completed? || md5.blank? || Upload.where(md5: md5).exists? || Post.where(md5: md5).exists?
|
if is_completed? || md5.blank? || Upload.exists?(md5: md5) || Post.exists?(md5: md5)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -170,7 +171,7 @@ class Upload < ApplicationRecord
|
|||||||
source = source.unicode_normalize(:nfc)
|
source = source.unicode_normalize(:nfc)
|
||||||
|
|
||||||
# percent encode unicode characters in urls
|
# percent encode unicode characters in urls
|
||||||
if source =~ %r!\Ahttps?://!i
|
if source =~ %r{\Ahttps?://}i
|
||||||
source = Addressable::URI.normalized_encode(source) rescue source
|
source = Addressable::URI.normalized_encode(source) rescue source
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -178,7 +179,7 @@ class Upload < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def source_url
|
def source_url
|
||||||
return nil unless source =~ %r!\Ahttps?://!i
|
return nil unless source =~ %r{\Ahttps?://}i
|
||||||
Addressable::URI.heuristic_parse(source) rescue nil
|
Addressable::URI.heuristic_parse(source) rescue nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
require 'digest/sha1'
|
|
||||||
|
|
||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
class Error < StandardError; end
|
class Error < StandardError; end
|
||||||
class PrivilegeError < StandardError; end
|
class PrivilegeError < StandardError; end
|
||||||
@@ -17,10 +15,7 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Used for `before_action :<role>_only`. Must have a corresponding `is_<role>?` method.
|
# Used for `before_action :<role>_only`. Must have a corresponding `is_<role>?` method.
|
||||||
Roles = Levels.constants.map(&:downcase) + [
|
Roles = Levels.constants.map(&:downcase) + %i[banned approver]
|
||||||
:banned,
|
|
||||||
:approver
|
|
||||||
]
|
|
||||||
|
|
||||||
# candidates for removal:
|
# candidates for removal:
|
||||||
# - enable_post_navigation (disabled by 700)
|
# - enable_post_navigation (disabled by 700)
|
||||||
@@ -36,7 +31,7 @@ class User < ApplicationRecord
|
|||||||
# - enable_recommended_posts
|
# - enable_recommended_posts
|
||||||
# - has_mail
|
# - has_mail
|
||||||
# - is_super_voter
|
# - is_super_voter
|
||||||
BOOLEAN_ATTRIBUTES = %w(
|
BOOLEAN_ATTRIBUTES = %w[
|
||||||
is_banned
|
is_banned
|
||||||
has_mail
|
has_mail
|
||||||
receive_email_notifications
|
receive_email_notifications
|
||||||
@@ -67,7 +62,7 @@ class User < ApplicationRecord
|
|||||||
no_feedback
|
no_feedback
|
||||||
requires_verification
|
requires_verification
|
||||||
is_verified
|
is_verified
|
||||||
)
|
]
|
||||||
|
|
||||||
DEFAULT_BLACKLIST = ["spoilers", "guro", "scat", "furry -rating:s"].join("\n")
|
DEFAULT_BLACKLIST = ["spoilers", "guro", "scat", "furry -rating:s"].join("\n")
|
||||||
|
|
||||||
@@ -104,10 +99,10 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
after_initialize :initialize_attributes, if: :new_record?
|
after_initialize :initialize_attributes, if: :new_record?
|
||||||
validates :name, user_name: true, on: :create
|
validates :name, user_name: true, on: :create
|
||||||
validates_length_of :password, :minimum => 5, :if => ->(rec) { rec.new_record? || rec.password.present?}
|
validates :password, length: { minimum: 5 }, if: ->(rec) { rec.new_record? || rec.password.present? }
|
||||||
validates_inclusion_of :default_image_size, :in => %w(large original)
|
validates :default_image_size, inclusion: { in: %w[large original] }
|
||||||
validates_inclusion_of :per_page, in: (1..PostSets::Post::MAX_PER_PAGE)
|
validates :per_page, inclusion: { in: (1..PostSets::Post::MAX_PER_PAGE) }
|
||||||
validates_confirmation_of :password
|
validates :password, confirmation: true
|
||||||
validates :comment_threshold, inclusion: { in: (-100..5) }
|
validates :comment_threshold, inclusion: { in: (-100..5) }
|
||||||
before_validation :normalize_blacklisted_tags
|
before_validation :normalize_blacklisted_tags
|
||||||
before_create :promote_to_owner_if_first_user
|
before_create :promote_to_owner_if_first_user
|
||||||
@@ -233,13 +228,13 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def anonymous
|
def anonymous
|
||||||
user = User.new(name: "Anonymous", level: Levels::ANONYMOUS, created_at: Time.now)
|
user = User.new(name: "Anonymous", level: Levels::ANONYMOUS, created_at: Time.zone.now)
|
||||||
user.freeze.readonly!
|
user.freeze.readonly!
|
||||||
user
|
user
|
||||||
end
|
end
|
||||||
|
|
||||||
def level_hash
|
def level_hash
|
||||||
return {
|
{
|
||||||
"Restricted" => Levels::RESTRICTED,
|
"Restricted" => Levels::RESTRICTED,
|
||||||
"Member" => Levels::MEMBER,
|
"Member" => Levels::MEMBER,
|
||||||
"Gold" => Levels::GOLD,
|
"Gold" => Levels::GOLD,
|
||||||
@@ -247,7 +242,7 @@ class User < ApplicationRecord
|
|||||||
"Builder" => Levels::BUILDER,
|
"Builder" => Levels::BUILDER,
|
||||||
"Moderator" => Levels::MODERATOR,
|
"Moderator" => Levels::MODERATOR,
|
||||||
"Admin" => Levels::ADMIN,
|
"Admin" => Levels::ADMIN,
|
||||||
"Owner" => Levels::OWNER
|
"Owner" => Levels::OWNER,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -293,7 +288,7 @@ class User < ApplicationRecord
|
|||||||
def promote_to_owner_if_first_user
|
def promote_to_owner_if_first_user
|
||||||
return if Rails.env.test?
|
return if Rails.env.test?
|
||||||
|
|
||||||
if name != Danbooru.config.system_user && !User.where(level: Levels::OWNER).exists?
|
if name != Danbooru.config.system_user && !User.exists?(level: Levels::OWNER)
|
||||||
self.level = Levels::OWNER
|
self.level = Levels::OWNER
|
||||||
self.can_approve_posts = true
|
self.can_approve_posts = true
|
||||||
self.can_upload_free = true
|
self.can_upload_free = true
|
||||||
@@ -386,12 +381,12 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def rewrite_blacklist(old_name, new_name)
|
def rewrite_blacklist(old_name, new_name)
|
||||||
self.blacklisted_tags.gsub!(/(?:^| )([-~])?#{Regexp.escape(old_name)}(?: |$)/i) { " #{$1}#{new_name} " }
|
blacklisted_tags.gsub!(/(?:^| )([-~])?#{Regexp.escape(old_name)}(?: |$)/i) { " #{$1}#{new_name} " }
|
||||||
end
|
end
|
||||||
|
|
||||||
def normalize_blacklisted_tags
|
def normalize_blacklisted_tags
|
||||||
return unless blacklisted_tags.present?
|
return unless blacklisted_tags.present?
|
||||||
self.blacklisted_tags = self.blacklisted_tags.lines.map(&:strip).join("\n")
|
self.blacklisted_tags = blacklisted_tags.lines.map(&:strip).join("\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -615,7 +610,8 @@ class User < ApplicationRecord
|
|||||||
params = params.dup
|
params = params.dup
|
||||||
params[:name_matches] = params.delete(:name) if params[:name].present?
|
params[:name_matches] = params.delete(:name) if params[:name].present?
|
||||||
|
|
||||||
q = search_attributes(params,
|
q = search_attributes(
|
||||||
|
params,
|
||||||
:id, :created_at, :updated_at, :name, :level, :post_upload_count,
|
:id, :created_at, :updated_at, :name, :level, :post_upload_count,
|
||||||
:post_update_count, :note_update_count, :favorite_count, :posts,
|
:post_update_count, :note_update_count, :favorite_count, :posts,
|
||||||
:note_versions, :artist_commentary_versions, :post_appeals,
|
:note_versions, :artist_commentary_versions, :post_appeals,
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
class UserFeedback < ApplicationRecord
|
class UserFeedback < ApplicationRecord
|
||||||
self.table_name = "user_feedback"
|
self.table_name = "user_feedback"
|
||||||
|
|
||||||
|
attr_accessor :disable_dmail_notification
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :creator, class_name: "User"
|
belongs_to :creator, class_name: "User"
|
||||||
attr_accessor :disable_dmail_notification
|
validates :body, presence: true
|
||||||
validates_presence_of :body, :category
|
validates :category, presence: true, inclusion: { in: %w[positive negative neutral] }
|
||||||
validates_inclusion_of :category, :in => %w(positive negative neutral)
|
|
||||||
after_create :create_dmail, unless: :disable_dmail_notification
|
after_create :create_dmail, unless: :disable_dmail_notification
|
||||||
after_update(:if => ->(rec) { CurrentUser.id != rec.creator_id}) do |rec|
|
after_update(:if => ->(rec) { CurrentUser.id != rec.creator_id}) do |rec|
|
||||||
ModAction.log(%{#{CurrentUser.user.name} updated user feedback for "#{rec.user.name}":#{Routes.user_path(rec.user)}}, :user_feedback_update)
|
ModAction.log(%{#{CurrentUser.user.name} updated user feedback for "#{rec.user.name}":#{Routes.user_path(rec.user)}}, :user_feedback_update)
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ class UserNameChangeRequest < ApplicationRecord
|
|||||||
|
|
||||||
validate :not_limited, on: :create
|
validate :not_limited, on: :create
|
||||||
validates :desired_name, user_name: true, confirmation: true, on: :create
|
validates :desired_name, user_name: true, confirmation: true, on: :create
|
||||||
validates_presence_of :original_name, :desired_name
|
validates :original_name, presence: true
|
||||||
|
validates :desired_name, presence: true
|
||||||
|
|
||||||
after_create :update_name!
|
after_create :update_name!
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ class UserNameChangeRequest < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def not_limited
|
def not_limited
|
||||||
if UserNameChangeRequest.unscoped.where(user: user).where("created_at >= ?", 1.week.ago).exists?
|
if UserNameChangeRequest.unscoped.where(user: user).exists?(["created_at >= ?", 1.week.ago])
|
||||||
errors.add(:base, "You can only submit one name change request per week")
|
errors.add(:base, "You can only submit one name change request per week")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class UserUpgrade < ApplicationRecord
|
|||||||
enum upgrade_type: {
|
enum upgrade_type: {
|
||||||
gold: 0,
|
gold: 0,
|
||||||
platinum: 10,
|
platinum: 10,
|
||||||
gold_to_platinum: 20
|
gold_to_platinum: 20,
|
||||||
}, _suffix: "upgrade"
|
}, _suffix: "upgrade"
|
||||||
|
|
||||||
enum status: {
|
enum status: {
|
||||||
@@ -175,7 +175,7 @@ class UserUpgrade < ApplicationRecord
|
|||||||
country: country,
|
country: country,
|
||||||
is_gift: is_gift?,
|
is_gift: is_gift?,
|
||||||
level: level,
|
level: level,
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
update!(stripe_id: checkout.id)
|
update!(stripe_id: checkout.id)
|
||||||
|
|||||||
@@ -118,13 +118,13 @@ class WikiPage < ApplicationRecord
|
|||||||
|
|
||||||
tag_was = Tag.find_by_name(Tag.normalize_name(title_was))
|
tag_was = Tag.find_by_name(Tag.normalize_name(title_was))
|
||||||
if tag_was.present? && !tag_was.empty?
|
if tag_was.present? && !tag_was.empty?
|
||||||
warnings.add(:base, %!Warning: {{#{title_was}}} still has #{tag_was.post_count} #{"post".pluralize(tag_was.post_count)}. Be sure to move the posts!)
|
warnings.add(:base, %{Warning: {{#{title_was}}} still has #{tag_was.post_count} #{"post".pluralize(tag_was.post_count)}. Be sure to move the posts})
|
||||||
end
|
end
|
||||||
|
|
||||||
broken_wikis = WikiPage.linked_to(title_was)
|
broken_wikis = WikiPage.linked_to(title_was)
|
||||||
if broken_wikis.count > 0
|
if broken_wikis.count > 0
|
||||||
broken_wiki_search = Routes.wiki_pages_path(search: { linked_to: title_was })
|
broken_wiki_search = Routes.wiki_pages_path(search: { linked_to: title_was })
|
||||||
warnings.add(:base, %!Warning: [[#{title_was}]] is still linked from "#{broken_wikis.count} #{"other wiki page".pluralize(broken_wikis.count)}":[#{broken_wiki_search}]. Update #{(broken_wikis.count > 1) ? "these wikis" : "this wiki"} to link to [[#{title}]] instead!)
|
warnings.add(:base, %{Warning: [[#{title_was}]] is still linked from "#{broken_wikis.count} #{"other wiki page".pluralize(broken_wikis.count)}":[#{broken_wiki_search}]. Update #{(broken_wikis.count > 1) ? "these wikis" : "this wiki"} to link to [[#{title}]] instead})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ class WikiPage < ApplicationRecord
|
|||||||
|
|
||||||
def revert_to(version)
|
def revert_to(version)
|
||||||
if id != version.wiki_page_id
|
if id != version.wiki_page_id
|
||||||
raise RevertError.new("You cannot revert to a previous version of another wiki page.")
|
raise RevertError, "You cannot revert to a previous version of another wiki page."
|
||||||
end
|
end
|
||||||
|
|
||||||
self.title = version.title
|
self.title = version.title
|
||||||
|
|||||||
@@ -21,23 +21,17 @@ class WikiPageVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def previous
|
def previous
|
||||||
@previous ||= begin
|
@previous ||= WikiPageVersion.where("wiki_page_id = ? and id < ?", wiki_page_id, id).order("id desc").limit(1).to_a
|
||||||
WikiPageVersion.where("wiki_page_id = ? and id < ?", wiki_page_id, id).order("id desc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@previous.first
|
@previous.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def subsequent
|
def subsequent
|
||||||
@subsequent ||= begin
|
@subsequent ||= WikiPageVersion.where("wiki_page_id = ? and id > ?", wiki_page_id, id).order("id asc").limit(1).to_a
|
||||||
WikiPageVersion.where("wiki_page_id = ? and id > ?", wiki_page_id, id).order("id asc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@subsequent.first
|
@subsequent.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def current
|
def current
|
||||||
@current ||= begin
|
@current ||= WikiPageVersion.where(wiki_page_id: wiki_page_id).order("id desc").limit(1).to_a
|
||||||
WikiPageVersion.where("wiki_page_id = ?", wiki_page_id).order("id desc").limit(1).to_a
|
|
||||||
end
|
|
||||||
@current.first
|
@current.first
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -52,12 +46,12 @@ class WikiPageVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def other_names_changed(type)
|
def other_names_changed(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
((other_names - other.other_names) | (other.other_names - other_names)).length.positive?
|
((other_names - other.other_names) | (other.other_names - other_names)).length.positive?
|
||||||
end
|
end
|
||||||
|
|
||||||
def was_deleted(type)
|
def was_deleted(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
is_deleted && !other.is_deleted
|
is_deleted && !other.is_deleted
|
||||||
else
|
else
|
||||||
@@ -66,7 +60,7 @@ class WikiPageVersion < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def was_undeleted(type)
|
def was_undeleted(type)
|
||||||
other = self.send(type)
|
other = send(type)
|
||||||
if type == "previous"
|
if type == "previous"
|
||||||
!is_deleted && other.is_deleted
|
!is_deleted && other.is_deleted
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class ApiKeyPolicy < ApplicationPolicy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def permitted_attributes
|
def permitted_attributes
|
||||||
[:name, :permitted_ip_addresses, permissions: []]
|
[:name, :permitted_ip_addresses, { permissions: [] }]
|
||||||
end
|
end
|
||||||
|
|
||||||
def api_attributes
|
def api_attributes
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class ApplicationPolicy
|
|||||||
# The list of attributes that are permitted to be returned by the API.
|
# The list of attributes that are permitted to be returned by the API.
|
||||||
def api_attributes
|
def api_attributes
|
||||||
# XXX allow inet
|
# XXX allow inet
|
||||||
record.class.attribute_types.reject { |name, attr| attr.type.in?([:inet, :tsvector]) }.keys.map(&:to_sym)
|
record.class.attribute_types.reject { |_name, attr| attr.type.in?([:inet, :tsvector]) }.keys.map(&:to_sym)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The list of attributes that are permitted to be used as data-* attributes
|
# The list of attributes that are permitted to be used as data-* attributes
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ class FavoriteGroupPolicy < ApplicationPolicy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def permitted_attributes
|
def permitted_attributes
|
||||||
[:name, :post_ids_string, :is_public, :post_ids, post_ids: []]
|
[:name, :post_ids_string, :is_public, :post_ids, { post_ids: [] }]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class ForumTopicPolicy < ApplicationPolicy
|
|||||||
def permitted_attributes
|
def permitted_attributes
|
||||||
[
|
[
|
||||||
:title, :category_id, { original_post_attributes: [:id, :body] },
|
:title, :category_id, { original_post_attributes: [:id, :body] },
|
||||||
([:is_sticky, :is_locked, :min_level] if moderate?)
|
([:is_sticky, :is_locked, :min_level] if moderate?),
|
||||||
].compact.flatten
|
].compact.flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class PoolPolicy < ApplicationPolicy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def permitted_attributes
|
def permitted_attributes
|
||||||
[:name, :description, :category, :post_ids, :post_ids_string, post_ids: []]
|
[:name, :description, :category, :post_ids, :post_ids_string, { post_ids: [] }]
|
||||||
end
|
end
|
||||||
|
|
||||||
def api_attributes
|
def api_attributes
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ class PostReplacementPolicy < ApplicationPolicy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def permitted_attributes_for_create
|
def permitted_attributes_for_create
|
||||||
[:replacement_url, :replacement_file, :final_source, :tags]
|
%i[replacement_url replacement_file final_source tags]
|
||||||
end
|
end
|
||||||
|
|
||||||
def permitted_attributes_for_update
|
def permitted_attributes_for_update
|
||||||
[:old_file_ext, :old_file_size, :old_image_width, :old_image_height,
|
%i[
|
||||||
:old_md5, :file_ext, :file_size, :image_width, :image_height, :md5,
|
old_file_ext old_file_size old_image_width old_image_height old_md5
|
||||||
:original_url, :replacement_url]
|
file_ext file_size image_width image_height md5 original_url
|
||||||
|
replacement_url
|
||||||
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -36,15 +36,15 @@ class UserPolicy < ApplicationPolicy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def permitted_attributes_for_update
|
def permitted_attributes_for_update
|
||||||
[
|
%i[
|
||||||
:comment_threshold, :default_image_size, :favorite_tags,
|
comment_threshold default_image_size favorite_tags
|
||||||
:blacklisted_tags, :time_zone, :per_page, :custom_style, :theme,
|
blacklisted_tags time_zone per_page custom_style theme
|
||||||
:receive_email_notifications, :always_resize_images,
|
receive_email_notifications always_resize_images
|
||||||
:new_post_navigation_layout, :enable_private_favorites,
|
new_post_navigation_layout enable_private_favorites
|
||||||
:hide_deleted_posts, :style_usernames, :show_deleted_children,
|
hide_deleted_posts style_usernames show_deleted_children
|
||||||
:disable_categorized_saved_searches, :disable_tagged_filenames,
|
disable_categorized_saved_searches disable_tagged_filenames
|
||||||
:disable_cropped_thumbnails, :disable_mobile_gestures, :enable_safe_mode,
|
disable_cropped_thumbnails disable_mobile_gestures enable_safe_mode
|
||||||
:enable_desktop_mode, :disable_post_tooltips,
|
enable_desktop_mode disable_post_tooltips
|
||||||
].compact
|
].compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
class PostPresenter
|
class PostPresenter
|
||||||
attr_reader :pool, :next_post_in_pool
|
attr_reader :pool, :next_post_in_pool
|
||||||
|
|
||||||
delegate :split_tag_list_text, to: :tag_set_presenter
|
delegate :split_tag_list_text, to: :tag_set_presenter
|
||||||
|
|
||||||
def initialize(post)
|
def initialize(post)
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class TagSetPresenter
|
|||||||
end
|
end
|
||||||
|
|
||||||
def ordered_tags
|
def ordered_tags
|
||||||
names_to_tags = tags.map { |tag| [tag.name, tag] }.to_h
|
names_to_tags = tags.index_by(&:name)
|
||||||
|
|
||||||
tag_names.map do |name|
|
tag_names.map do |name|
|
||||||
names_to_tags[name] || Tag.new(name: name).freeze
|
names_to_tags[name] || Tag.new(name: name).freeze
|
||||||
|
|||||||
Reference in New Issue
Block a user