Update profile information and download avatar of remote accounts
This commit is contained in:
		
							parent
							
								
									2825991e09
								
							
						
					
					
						commit
						ad5ae3f60e
					
				
					 9 changed files with 87 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -100,7 +100,7 @@ module AtomHelper
 | 
			
		|||
  def disambiguate_uri(target)
 | 
			
		||||
    if target.local?
 | 
			
		||||
      if target.object_type == :person
 | 
			
		||||
        profile_url(name: target.username)
 | 
			
		||||
        profile_url(target)
 | 
			
		||||
      else
 | 
			
		||||
        unique_tag(target.stream_entry.created_at, target.stream_entry.activity_id, target.stream_entry.activity_type)
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			@ -112,9 +112,9 @@ module AtomHelper
 | 
			
		|||
  def disambiguate_url(target)
 | 
			
		||||
    if target.local?
 | 
			
		||||
      if target.object_type == :person
 | 
			
		||||
        profile_url(name: target.username)
 | 
			
		||||
        profile_url(target)
 | 
			
		||||
      else
 | 
			
		||||
        status_url(name: target.stream_entry.account.username, id: target.stream_entry.id)
 | 
			
		||||
        status_url(target)
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      target.url
 | 
			
		||||
| 
						 | 
				
			
			@ -125,12 +125,21 @@ module AtomHelper
 | 
			
		|||
    xml.link(rel: 'mentioned', href: disambiguate_uri(account))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def link_avatar(xml, account)
 | 
			
		||||
    xml.link(rel: 'avatar', type: account.avatar_content_type, href: asset_url(account.avatar.url(:large)))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def logo(xml, url)
 | 
			
		||||
    xml.logo url
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def include_author(xml, account)
 | 
			
		||||
    object_type      xml, :person
 | 
			
		||||
    uri              xml, profile_url(name: account.username)
 | 
			
		||||
    uri              xml, profile_url(account)
 | 
			
		||||
    name             xml, account.username
 | 
			
		||||
    summary          xml, account.note
 | 
			
		||||
    link_alternate   xml, profile_url(name: account.username)
 | 
			
		||||
    link_alternate   xml, profile_url(account)
 | 
			
		||||
    link_avatar      xml, account
 | 
			
		||||
    portable_contact xml, account
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +169,7 @@ module AtomHelper
 | 
			
		|||
        if stream_entry.target.object_type == :person
 | 
			
		||||
          summary          xml, stream_entry.target.content
 | 
			
		||||
          portable_contact xml, stream_entry.target
 | 
			
		||||
          link_avatar      xml, stream_entry.target
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Statuses have content
 | 
			
		||||
| 
						 | 
				
			
			@ -177,6 +187,6 @@ module AtomHelper
 | 
			
		|||
  private
 | 
			
		||||
 | 
			
		||||
  def root_tag(xml, tag, &block)
 | 
			
		||||
    xml.send(tag, { :xmlns => 'http://www.w3.org/2005/Atom', 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0' }, &block)
 | 
			
		||||
    xml.send(tag, { :xmlns => 'http://www.w3.org/2005/Atom', 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', 'xmlns:media' => 'http://purl.org/syndication/atommedia' }, &block)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,16 +58,7 @@ class FollowRemoteAccountService < BaseService
 | 
			
		|||
 | 
			
		||||
  def get_profile(xml, account)
 | 
			
		||||
    author = xml.at_xpath('/xmlns:feed/xmlns:author')
 | 
			
		||||
 | 
			
		||||
    if author.at_xpath('./poco:displayName').nil?
 | 
			
		||||
      account.display_name = account.username
 | 
			
		||||
    else
 | 
			
		||||
      account.display_name = author.at_xpath('./poco:displayName').content
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    unless author.at_xpath('./poco:note').nil?
 | 
			
		||||
      account.note = author.at_xpath('./poco:note').content
 | 
			
		||||
    end
 | 
			
		||||
    update_remote_profile_service.(author, account)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def magic_key_to_pem(magic_key)
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +72,10 @@ class FollowRemoteAccountService < BaseService
 | 
			
		|||
    key.to_pem
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def update_remote_profile_service
 | 
			
		||||
    @update_remote_profile_service ||= UpdateRemoteProfileService.new
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def http_client
 | 
			
		||||
    HTTP
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,10 @@ class ProcessFeedService < BaseService
 | 
			
		|||
  def call(body, account)
 | 
			
		||||
    xml = Nokogiri::XML(body)
 | 
			
		||||
 | 
			
		||||
    unless xml.at_xpath('/xmlns:feed').nil?
 | 
			
		||||
      update_remote_profile_service.(xml.at_xpath('/xmlns:feed/xmlns:author'), account)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    xml.xpath('//xmlns:entry').each do |entry|
 | 
			
		||||
      next unless [:note, :comment, :activity].includes? object_type(entry)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,4 +130,8 @@ class ProcessFeedService < BaseService
 | 
			
		|||
  def process_mentions_service
 | 
			
		||||
    @process_mentions_service ||= ProcessMentionsService.new
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def update_remote_profile_service
 | 
			
		||||
    @update_remote_profile_service ||= UpdateRemoteProfileService.new
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,8 @@ class ProcessInteractionService < BaseService
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    if salmon.verify(envelope, account.keypair)
 | 
			
		||||
      update_remote_profile_service.(xml.at_xpath('/xmlns:entry/xmlns:author'), account)
 | 
			
		||||
 | 
			
		||||
      case verb(xml)
 | 
			
		||||
      when :follow
 | 
			
		||||
        follow!(account, target_account)
 | 
			
		||||
| 
						 | 
				
			
			@ -86,4 +88,8 @@ class ProcessInteractionService < BaseService
 | 
			
		|||
  def process_feed_service
 | 
			
		||||
    @process_feed_service ||= ProcessFeedService.new
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def update_remote_profile_service
 | 
			
		||||
    @update_remote_profile_service ||= UpdateRemoteProfileService.new
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										19
									
								
								app/services/update_remote_profile_service.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/services/update_remote_profile_service.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
class UpdateRemoteProfileService < BaseService
 | 
			
		||||
  def call(author_xml, account)
 | 
			
		||||
    if author_xml.at_xpath('./poco:displayName').nil?
 | 
			
		||||
      account.display_name = account.username
 | 
			
		||||
    else
 | 
			
		||||
      account.display_name = author_xml.at_xpath('./poco:displayName').content
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    unless author_xml.at_xpath('./poco:note').nil?
 | 
			
		||||
      account.note = author_xml.at_xpath('./poco:note').content
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    unless author_xml.at_xpath('./xmlns:link[@rel="avatar"]').nil?
 | 
			
		||||
      account.avatar_remote_url = author_xml.at_xpath('./xmlns:link[@rel="avatar"]').attribute('href').value
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    account.save!
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -4,12 +4,13 @@ Nokogiri::XML::Builder.new do |xml|
 | 
			
		|||
    title      xml, @account.display_name
 | 
			
		||||
    subtitle   xml, @account.note
 | 
			
		||||
    updated_at xml, stream_updated_at
 | 
			
		||||
    logo       xml, asset_url(@account.avatar.url(:medium))
 | 
			
		||||
 | 
			
		||||
    author(xml) do
 | 
			
		||||
      include_author xml, @account
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    link_alternate xml, profile_url(name: @account.username)
 | 
			
		||||
    link_alternate xml, profile_url(@account)
 | 
			
		||||
    link_self      xml, atom_user_stream_url(id: @account.id)
 | 
			
		||||
    link_hub       xml, HUB_URL
 | 
			
		||||
    link_salmon    xml, salmon_url(@account)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,4 +7,4 @@
 | 
			
		|||
  %span.num= status.favourites.count
 | 
			
		||||
 | 
			
		||||
- if status.reply?
 | 
			
		||||
  = link_to 'View conversation', status_url(status.thread), class: 'conversation-link'
 | 
			
		||||
  = link_to "In response to #{status.thread.account.acct}", status_url(status.thread), class: 'conversation-link'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -112,4 +112,12 @@ RSpec.describe AtomHelper, type: :helper do
 | 
			
		|||
  describe '#include_entry' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#link_avatar' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#logo' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,27 @@
 | 
			
		|||
require 'rails_helper'
 | 
			
		||||
 | 
			
		||||
RSpec.describe ProfileHelper, type: :helper do
 | 
			
		||||
  describe '#display_name' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#profile_url' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#status_url' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#avatar_for_status_url' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#entry_classes' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#relative_time' do
 | 
			
		||||
    pending
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Reference in a new issue