Merge remote-tracking branch 'glitchsoc/master' into 454-allow-keyword-mutes-to-skip-mentions
Conflicts: app/models/glitch/keyword_mute.rb
This commit is contained in:
@@ -24,14 +24,17 @@ module Remotable
|
||||
Request.new(:get, url).perform do |response|
|
||||
next if response.code != 200
|
||||
|
||||
matches = response.headers['content-disposition']&.match(/filename="([^"]*)"/)
|
||||
filename = matches.nil? ? parsed_url.path.split('/').last : matches[1]
|
||||
content_type = parse_content_type(response.headers.get('content-type').last)
|
||||
extname = detect_extname_from_content_type(content_type)
|
||||
|
||||
if extname.nil?
|
||||
disposition = response.headers.get('content-disposition').last
|
||||
matches = disposition&.match(/filename="([^"]*)"/)
|
||||
filename = matches.nil? ? parsed_url.path.split('/').last : matches[1]
|
||||
extname = filename.nil? ? '' : File.extname(filename)
|
||||
end
|
||||
|
||||
basename = SecureRandom.hex(8)
|
||||
extname = if filename.nil?
|
||||
''
|
||||
else
|
||||
File.extname(filename)
|
||||
end
|
||||
|
||||
send("#{attachment_name}=", StringIO.new(response.body_with_limit(limit)))
|
||||
send("#{attachment_name}_file_name=", basename + extname)
|
||||
@@ -57,4 +60,26 @@ module Remotable
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def detect_extname_from_content_type(content_type)
|
||||
return if content_type.nil?
|
||||
|
||||
type = MIME::Types[content_type].first
|
||||
|
||||
return if type.nil?
|
||||
|
||||
extname = type.extensions.first
|
||||
|
||||
return if extname.nil?
|
||||
|
||||
".#{extname}"
|
||||
end
|
||||
|
||||
def parse_content_type(content_type)
|
||||
return if content_type.nil?
|
||||
|
||||
content_type.split(/\s*;\s*/).first
|
||||
end
|
||||
end
|
||||
|
||||
@@ -51,12 +51,16 @@ module StatusThreadingConcern
|
||||
end
|
||||
|
||||
def descendant_statuses(limit, max_child_id, since_child_id, depth)
|
||||
Status.find_by_sql([<<-SQL.squish, id: id, limit: limit, max_child_id: max_child_id, since_child_id: since_child_id, depth: depth])
|
||||
# use limit + 1 and depth + 1 because 'self' is included
|
||||
depth += 1 if depth.present?
|
||||
limit += 1 if limit.present?
|
||||
|
||||
descendants_with_self = Status.find_by_sql([<<-SQL.squish, id: id, limit: limit, max_child_id: max_child_id, since_child_id: since_child_id, depth: depth])
|
||||
WITH RECURSIVE search_tree(id, path)
|
||||
AS (
|
||||
SELECT id, ARRAY[id]
|
||||
FROM statuses
|
||||
WHERE in_reply_to_id = :id AND COALESCE(id < :max_child_id, TRUE) AND COALESCE(id > :since_child_id, TRUE)
|
||||
WHERE id = :id AND COALESCE(id < :max_child_id, TRUE) AND COALESCE(id > :since_child_id, TRUE)
|
||||
UNION ALL
|
||||
SELECT statuses.id, path || statuses.id
|
||||
FROM search_tree
|
||||
@@ -68,6 +72,8 @@ module StatusThreadingConcern
|
||||
ORDER BY path
|
||||
LIMIT :limit
|
||||
SQL
|
||||
|
||||
descendants_with_self - [self]
|
||||
end
|
||||
|
||||
def find_statuses_from_tree_path(ids, account)
|
||||
|
||||
@@ -67,7 +67,7 @@ class Glitch::KeywordMute < ApplicationRecord
|
||||
|
||||
def matches?(str, required_scope)
|
||||
((required_scope & scope) == required_scope) && \
|
||||
str =~ (whole_word ? boundary_regex_for_keyword : /#{keyword}/i)
|
||||
str =~ (whole_word ? boundary_regex_for_keyword : /#{Regexp.escape(keyword)}/i)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class Status < ApplicationRecord
|
||||
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy
|
||||
has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :thread
|
||||
has_many :mentions, dependent: :destroy
|
||||
has_many :media_attachments, dependent: :destroy
|
||||
has_many :media_attachments, dependent: :nullify
|
||||
|
||||
has_and_belongs_to_many :tags
|
||||
has_and_belongs_to_many :preview_cards
|
||||
@@ -194,7 +194,6 @@ class Status < ApplicationRecord
|
||||
before_validation :set_reblog
|
||||
before_validation :set_visibility
|
||||
before_validation :set_conversation
|
||||
before_validation :set_sensitivity
|
||||
before_validation :set_local
|
||||
|
||||
class << self
|
||||
@@ -317,7 +316,11 @@ class Status < ApplicationRecord
|
||||
# non-followers can see everything that isn't private/direct, but can see stuff they are mentioned in.
|
||||
visibility.push(:private) if account.following?(target_account)
|
||||
|
||||
where(visibility: visibility).or(where(id: account.mentions.select(:status_id)))
|
||||
scope = left_outer_joins(:reblog)
|
||||
|
||||
scope.where(visibility: visibility)
|
||||
.or(scope.where(id: account.mentions.select(:status_id)))
|
||||
.merge(scope.where(reblog_of_id: nil).or(scope.where.not(reblogs_statuses: { account_id: account.excluded_from_timeline_account_ids })))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -388,10 +391,6 @@ class Status < ApplicationRecord
|
||||
self.sensitive = false if sensitive.nil?
|
||||
end
|
||||
|
||||
def set_sensitivity
|
||||
self.sensitive = sensitive || spoiler_text.present?
|
||||
end
|
||||
|
||||
def set_locality
|
||||
if account.domain.nil? && !attribute_changed?(:local_only)
|
||||
self.local_only = marked_local_only?
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class TrendingTags
|
||||
KEY = 'trending_tags'
|
||||
EXPIRE_HISTORY_AFTER = 7.days.seconds
|
||||
THRESHOLD = 5
|
||||
|
||||
class << self
|
||||
def record_use!(tag, account, at_time = Time.now.utc)
|
||||
@@ -11,30 +9,10 @@ class TrendingTags
|
||||
|
||||
increment_historical_use!(tag.id, at_time)
|
||||
increment_unique_use!(tag.id, account.id, at_time)
|
||||
increment_vote!(tag.id, at_time)
|
||||
end
|
||||
|
||||
def get(limit)
|
||||
tag_ids = redis.zrevrange(KEY, 0, limit).map(&:to_i)
|
||||
tags = Tag.where(id: tag_ids).to_a.map { |tag| [tag.id, tag] }.to_h
|
||||
tag_ids.map { |tag_id| tags[tag_id] }.compact
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def increment_vote!(tag_id, at_time)
|
||||
expected = redis.pfcount("activity:tags:#{tag_id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts").to_f
|
||||
expected = 1.0 if expected.zero?
|
||||
observed = redis.pfcount("activity:tags:#{tag_id}:#{at_time.beginning_of_day.to_i}:accounts").to_f
|
||||
|
||||
if expected > observed || observed < THRESHOLD
|
||||
redis.zrem(KEY, tag_id.to_s)
|
||||
else
|
||||
score = ((observed - expected)**2) / expected
|
||||
redis.zadd(KEY, score, tag_id.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
def increment_historical_use!(tag_id, at_time)
|
||||
key = "activity:tags:#{tag_id}:#{at_time.beginning_of_day.to_i}"
|
||||
redis.incrby(key, 1)
|
||||
|
||||
Reference in New Issue
Block a user