Fail loudly if we forget to whitelist a param instead of silently ignoring it. misc models: convert to strong params. artist commentaries: convert to strong params. * Disallow changing or setting post_id to a nonexistent post. artists: convert to strong params. * Disallow setting `is_banned` in create/update actions. Changing it this way instead of with the ban/unban actions would leave the artist in a partially banned state. bans: convert to strong params. * Disallow changing the user_id after the ban has been created. comments: convert to strong params. favorite groups: convert to strong params. news updates: convert to strong params. post appeals: convert to strong params. post flags: convert to strong params. * Disallow users from setting the `is_deleted` / `is_resolved` flags. ip bans: convert to strong params. user feedbacks: convert to strong params. * Disallow users from setting `disable_dmail_notification` when creating feedbacks. * Disallow changing the user_id after the feedback has been created. notes: convert to strong params. wiki pages: convert to strong params. * Also fix non-Builders being able to delete wiki pages. saved searches: convert to strong params. pools: convert to strong params. * Disallow setting `post_count` or `is_deleted` in create/update actions. janitor trials: convert to strong params. post disapprovals: convert to strong params. * Factor out quick-mod bar to shared partial. * Fix quick-mod bar to use `Post#is_approvable?` to determine visibility of Approve button. dmail filters: convert to strong params. password resets: convert to strong params. user name change requests: convert to strong params. posts: convert to strong params. users: convert to strong params. * Disallow setting password_hash, last_logged_in_at, last_forum_read_at, has_mail, and dmail_filter_attributes[user_id]. * Remove initialize_default_image_size (dead code). uploads: convert to strong params. * Remove `initialize_status` because status already defaults to pending in the database. tag aliases/implications: convert to strong params. tags: convert to strong params. forum posts: convert to strong params. * Disallow changing the topic_id after creating the post. * Disallow setting is_deleted (destroy/undelete actions should be used instead). * Remove is_sticky / is_locked (nonexistent attributes). forum topics: convert to strong params. * merges https://github.com/evazion/danbooru/tree/wip-rails-5.1 * lock pg gem to 0.21 (1.0.0 is incompatible with rails 5.1.4) * switch to factorybot and change all references Co-authored-by: r888888888 <r888888888@gmail.com> Co-authored-by: evazion <noizave@gmail.com> add diffs
140 lines
3.7 KiB
Ruby
140 lines
3.7 KiB
Ruby
class SavedSearch < ApplicationRecord
|
|
module ListbooruMethods
|
|
extend ActiveSupport::Concern
|
|
|
|
module ClassMethods
|
|
def enabled?
|
|
Danbooru.config.aws_sqs_saved_search_url.present?
|
|
end
|
|
|
|
def posts_search_available?
|
|
enabled? && CurrentUser.is_gold?
|
|
end
|
|
|
|
def sqs_service
|
|
SqsService.new(Danbooru.config.aws_sqs_saved_search_url)
|
|
end
|
|
|
|
def post_ids(user_id, label = nil)
|
|
return [] unless enabled?
|
|
label = normalize_label(label) if label
|
|
|
|
Cache.get("ss-#{user_id}-#{Cache.hash(label)}", 60) do
|
|
queries = SavedSearch.queries_for(user_id, label)
|
|
return [] if queries.empty?
|
|
|
|
json = {
|
|
"key" => Danbooru.config.listbooru_auth_key,
|
|
"queries" => queries
|
|
}.to_json
|
|
|
|
uri = "#{Danbooru.config.listbooru_server}/v2/search"
|
|
|
|
resp = HTTParty.post(uri, Danbooru.config.httparty_options.merge(body: json))
|
|
if resp.success?
|
|
resp.body.to_s.scan(/\d+/).map(&:to_i)
|
|
else
|
|
raise "HTTP error code: #{resp.code} #{resp.message}"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
include ListbooruMethods
|
|
|
|
attr_accessor :disable_labels
|
|
belongs_to :user
|
|
validates :query, :presence => true
|
|
validate :validate_count
|
|
before_create :update_user_on_create
|
|
after_destroy :update_user_on_destroy
|
|
after_save {|rec| Cache.delete(SavedSearch.cache_key(rec.user_id))}
|
|
after_destroy {|rec| Cache.delete(SavedSearch.cache_key(rec.user_id))}
|
|
before_validation :normalize
|
|
scope :labeled, lambda {|label| where("labels @> string_to_array(?, '~~~~')", label)}
|
|
|
|
def self.normalize_label(label)
|
|
label.to_s.strip.downcase.gsub(/[[:space:]]/, "_")
|
|
end
|
|
|
|
def self.search_labels(user_id, params)
|
|
labels = labels_for(user_id)
|
|
|
|
if params[:label].present?
|
|
query = Regexp.escape(params[:label]).gsub("\\*", ".*")
|
|
query = ".*#{query}.*" unless query.include?("*")
|
|
query = /\A#{query}\z/
|
|
labels = labels.grep(query)
|
|
end
|
|
|
|
labels
|
|
end
|
|
|
|
def self.labels_for(user_id)
|
|
Cache.get(cache_key(user_id)) do
|
|
SavedSearch.where(user_id: user_id).order("label").pluck("distinct unnest(labels) as label")
|
|
end
|
|
end
|
|
|
|
def self.cache_key(user_id)
|
|
"ss-labels-#{user_id}"
|
|
end
|
|
|
|
def self.queries_for(user_id, label = nil, options = {})
|
|
if label
|
|
SavedSearch.where(user_id: user_id).labeled(label).map(&:normalized_query).sort.uniq
|
|
else
|
|
SavedSearch.where(user_id: user_id).map(&:normalized_query).sort.uniq
|
|
end
|
|
end
|
|
|
|
def normalized_query
|
|
Tag.normalize_query(query, sort: true)
|
|
end
|
|
|
|
def normalize
|
|
self.query = Tag.normalize_query(query, sort: false)
|
|
self.labels = labels.map {|x| SavedSearch.normalize_label(x)}.reject {|x| x.blank?}
|
|
end
|
|
|
|
def validate_count
|
|
if user.saved_searches.count + 1 > user.max_saved_searches
|
|
self.errors[:user] << "can only have up to #{user.max_saved_searches} " + "saved search".pluralize(user.max_saved_searches)
|
|
end
|
|
end
|
|
|
|
def update_user_on_create
|
|
if !user.has_saved_searches?
|
|
user.update_attribute(:has_saved_searches, true)
|
|
end
|
|
end
|
|
|
|
def update_user_on_destroy
|
|
if user.saved_searches.count == 0
|
|
user.update_attribute(:has_saved_searches, false)
|
|
end
|
|
end
|
|
|
|
def label_string
|
|
labels.join(" ")
|
|
end
|
|
|
|
def label_string=(val)
|
|
self.labels = val.to_s.split(/[[:space:]]+/)
|
|
end
|
|
|
|
def labels=(labels)
|
|
labels = labels.map { |label| SavedSearch.normalize_label(label) }
|
|
super(labels)
|
|
end
|
|
|
|
def disable_labels=(value)
|
|
CurrentUser.update(disable_categorized_saved_searches: true) if value == "1"
|
|
end
|
|
|
|
def disable_labels=(value)
|
|
CurrentUser.update(disable_categorized_saved_searches: true) if value == "1"
|
|
end
|
|
end
|