Skip to content
Snippets Groups Projects
Commit 58b3f4fd authored by Eugen Rochko's avatar Eugen Rochko
Browse files

Fix #329 - avatar errors no longer prevent remote accounts from being saved

(without avatar). Also improved search position of exact matches
parent 2b2797d6
No related branches found
No related tags found
No related merge requests found
......@@ -50,15 +50,14 @@ class Account < ApplicationRecord
# PuSH subscriptions
has_many :subscriptions, dependent: :destroy
pg_search_scope :search_for, against: { username: 'A', domain: 'B' }, using: { tsearch: { prefix: true } }
pg_search_scope :search_for, against: { username: 'A', domain: 'B' },
using: { tsearch: { prefix: true } }
scope :remote, -> { where.not(domain: nil) }
scope :local, -> { where(domain: nil) }
scope :without_followers, -> { where('(select count(f.id) from follows as f where f.target_account_id = accounts.id) = 0') }
scope :with_followers, -> { where('(select count(f.id) from follows as f where f.target_account_id = accounts.id) > 0') }
scope :expiring, -> (time) { where(subscription_expires_at: nil).or(where('subscription_expires_at < ?', time)).remote.with_followers }
scope :with_counters, -> { select('accounts.*, (select count(f.id) from follows as f where f.target_account_id = accounts.id) as followers_count, (select count(f.id) from follows as f where f.account_id = accounts.id) as following_count, (select count(s.id) from statuses as s where s.account_id = accounts.id) as statuses_count') }
scope :expiring, ->(time) { where(subscription_expires_at: nil).or(where('subscription_expires_at < ?', time)).remote.with_followers }
def follow!(other_account)
active_relationships.where(target_account: other_account).first_or_create!(target_account: other_account)
......@@ -114,9 +113,15 @@ class Account < ApplicationRecord
OStatus2::Subscription.new(remote_url, secret: secret, lease_seconds: 86_400 * 30, webhook: webhook_url, hub: hub_url)
end
def ping!(atom_url, hubs)
return unless local? && !Rails.env.development?
OStatus2::Publication.new(atom_url, hubs).publish
def save_with_optional_avatar!
save!
rescue ActiveRecord::RecordInvalid => invalid
if invalid.record.errors[:avatar_file_size] || invalid[:avatar_content_type]
self.avatar = nil
retry
end
raise invalid
end
def avatar_remote_url=(url)
......
......@@ -29,7 +29,8 @@ class Status < ApplicationRecord
default_scope { order('id desc') }
scope :with_counters, -> { select('statuses.*, (select count(r.id) from statuses as r where r.reblog_of_id = statuses.id) as reblogs_count, (select count(f.id) from favourites as f where f.status_id = statuses.id) as favourites_count') }
scope :remote, -> { where.not(uri: nil) }
scope :local, -> { where(uri: nil) }
cache_associated :account, :media_attachments, :tags, :stream_entry, mentions: :account, reblog: [:account, :stream_entry, :tags, :media_attachments, mentions: :account], thread: :account
......
......@@ -6,13 +6,16 @@ class SearchService < BaseService
username, domain = query.gsub(/\A@/, '').split('@')
results = if domain.nil?
Account.search_for(username)
else
Account.search_for("#{username} #{domain}")
end
if domain.nil?
exact_match = Account.find_local(username)
results = Account.search_for(username)
else
exact_match = Account.find_remote(username, domain)
results = Account.search_for("#{username} #{domain}")
end
results = results.limit(limit)
results = results.limit(limit).to_a
results = [exact_match] + results.reject { |a| a.id == exact_match.id } if exact_match
if resolve && results.empty? && !domain.nil?
results = [FollowRemoteAccountService.new.call("#{username}@#{domain}")]
......
# frozen_string_literal: true
class UnsubscribeService < BaseService
def call(account)
subscription = account.subscription(api_subscription_url(account.id))
response = subscription.unsubscribe
unless response.successful?
Rails.logger.debug "PuSH unsubscribe for #{account.acct} failed: #{response.message}"
end
account.secret = ''
account.subscription_expires_at = nil
account.save!
rescue HTTP::Error, OpenSSL::SSL::SSLError
Rails.logger.debug "PuSH subscription request for #{account.acct} could not be made due to HTTP or SSL error"
end
end
......@@ -15,7 +15,8 @@ class UpdateRemoteProfileService < BaseService
old_hub_url = account.hub_url
account.hub_url = hub_link['href'] if !hub_link.nil? && !hub_link['href'].blank? && (hub_link['href'] != old_hub_url)
account.save!
account.save_with_optional_avatar!
SubscribeService.new.call(account) if resubscribe && (account.hub_url != old_hub_url)
end
......
......@@ -6,6 +6,7 @@ class HubPingWorker
def perform(account_id)
account = Account.find(account_id)
account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url])
return unless account.local?
OStatus2::Publication.new(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]).publish
end
end
......@@ -11,18 +11,9 @@ namespace :mastodon do
namespace :push do
desc 'Unsubscribes from PuSH updates of feeds nobody follows locally'
task clear: :environment do
include RoutingHelper
Account.remote.without_followers.where.not(subscription_expires_at: nil).find_each do |a|
Rails.logger.debug "PuSH unsubscribing from #{a.acct}"
begin
a.subscription(api_subscription_url(a.id)).unsubscribe
rescue HTTP::Error, OpenSSL::SSL::SSLError
Rails.logger.debug "PuSH unsubscribing from #{a.acct} failed due to an HTTP or SSL error"
ensure
a.update!(secret: '', subscription_expires_at: nil)
end
UnsubscribeService.new.call(a)
end
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment