Class: Federails::Actor
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Federails::Actor
- Includes:
- HandlesDeleteRequests, HasUuid
- Defined in:
- app/models/federails/actor.rb
Overview
Model storing distant actors and links to local ones.
To make a model act as an actor, use the ‘Federails::ActorEntity` concern
See also:
- https://www.w3.org/TR/activitypub/#actor-objects
Defined Under Namespace
Classes: TombstonedError
Class Method Summary collapse
-
.find_by_account(account) ⇒ Federails::Actor?
Searches for an actor from account URI.
- .find_by_federation_url(federated_url) ⇒ Object
- .find_by_federation_url!(federated_url) ⇒ Object
- .find_local_by_username(username) ⇒ Object
- .find_local_by_username!(username) ⇒ Object
- .find_or_create_by_account(account) ⇒ Object
- .find_or_create_by_federation_url(url) ⇒ Object
-
.find_or_create_by_object(object) ⇒ Object
Find or create actor from a given actor hash or actor id (actor’s URL).
Instance Method Summary collapse
- #acct_uri ⇒ Object
- #actor_type ⇒ Object
- #at_address(prefix: '@') ⇒ Object
- #distant? ⇒ Boolean
- #entity_configuration ⇒ Object
- #federated_url ⇒ Object
-
#followed_by?(actor) ⇒ Federails::Following, false
Checks if current actor is followed by the given actor.
- #followers_url ⇒ Object
- #followings_url ⇒ Object
-
#follows?(actor) ⇒ Federails::Following, false
Checks if a given actor follows the current actor.
- #inbox_url ⇒ Object
- #key_id ⇒ Object
- #name ⇒ Object
- #outbox_url ⇒ Object
- #private_key ⇒ Object
- #profile_url ⇒ Object
- #public_key ⇒ Object
- #server ⇒ Object
- #short_at_address ⇒ Object
-
#sync! ⇒ Object
Synchronizes actor with distant data.
- #tombstone! ⇒ Object
- #tombstoned? ⇒ Boolean
- #untombstone! ⇒ Object
- #username ⇒ Object
Methods included from HasUuid
Class Method Details
.find_by_account(account) ⇒ Federails::Actor?
Searches for an actor from account URI
172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'app/models/federails/actor.rb', line 172 def find_by_account(account) parts = Fediverse::Webfinger.split_account account if Fediverse::Webfinger.local_user? parts actor = find_local_by_username! parts[:username] else actor = find_by username: parts[:username], server: parts[:domain] actor ||= Fediverse::Webfinger.fetch_actor(parts[:username], parts[:domain]) end actor end |
.find_by_federation_url(federated_url) ⇒ Object
185 186 187 188 189 190 191 192 193 |
# File 'app/models/federails/actor.rb', line 185 def find_by_federation_url(federated_url) local_route = Utils::Host.local_route federated_url return find_param(local_route[:id]) if local_route && local_route[:controller] == 'federails/server/actors' && local_route[:action] == 'show' actor = find_by federated_url: federated_url return actor if actor Fediverse::Webfinger.fetch_actor_url(federated_url) end |
.find_by_federation_url!(federated_url) ⇒ Object
195 196 197 198 199 200 |
# File 'app/models/federails/actor.rb', line 195 def find_by_federation_url!(federated_url) find_by_federation_url(federated_url).tap do |actor| raise Federails::Actor::TombstonedError if actor.tombstoned? raise ActiveRecord::RecordNotFound if actor.nil? end end |
.find_local_by_username(username) ⇒ Object
230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'app/models/federails/actor.rb', line 230 def find_local_by_username(username) actor = nil Federails::Configuration.actor_types.each_value do |entity| break if actor.present? actor = entity[:class].find_by(entity[:username_field] => username)&.federails_actor end return actor if actor # Last hope: Search for tombstoned actors Federails::Actor.local.tombstoned.find_by username: username end |
.find_local_by_username!(username) ⇒ Object
243 244 245 246 247 |
# File 'app/models/federails/actor.rb', line 243 def find_local_by_username!(username) find_local_by_username(username).tap do |actor| raise ActiveRecord::RecordNotFound if actor.nil? end end |
.find_or_create_by_account(account) ⇒ Object
202 203 204 205 206 207 208 |
# File 'app/models/federails/actor.rb', line 202 def find_or_create_by_account(account) actor = find_by_account account # Create/update distant actors actor.save! unless actor.local? actor end |
.find_or_create_by_federation_url(url) ⇒ Object
210 211 212 213 214 215 216 |
# File 'app/models/federails/actor.rb', line 210 def find_or_create_by_federation_url(url) actor = find_by_federation_url url # Create/update distant actors actor.save! unless actor.local? actor end |
.find_or_create_by_object(object) ⇒ Object
Find or create actor from a given actor hash or actor id (actor’s URL)
219 220 221 222 223 224 225 226 227 228 |
# File 'app/models/federails/actor.rb', line 219 def find_or_create_by_object(object) case object when String find_or_create_by_federation_url object when Hash find_or_create_by_federation_url object['id'] else raise "Unsupported object type for actor (#{object.class})" end end |
Instance Method Details
#acct_uri ⇒ Object
110 111 112 |
# File 'app/models/federails/actor.rb', line 110 def acct_uri "acct:#{username}@#{server}" end |
#actor_type ⇒ Object
73 74 75 |
# File 'app/models/federails/actor.rb', line 73 def actor_type use_entity_attributes? ? entity_configuration[:actor_type] : attributes['actor_type'] end |
#at_address(prefix: '@') ⇒ Object
102 103 104 |
# File 'app/models/federails/actor.rb', line 102 def at_address(prefix: '@') "#{prefix}#{username}@#{server}" end |
#distant? ⇒ Boolean
49 50 51 |
# File 'app/models/federails/actor.rb', line 49 def distant? !local? end |
#entity_configuration ⇒ Object
134 135 136 137 138 |
# File 'app/models/federails/actor.rb', line 134 def entity_configuration raise("Entity not configured for #{entity_type}. Did you use \"acts_as_federails_actor\"?") unless Federails.actor_entity? entity_type Federails.actor_entity entity_type end |
#federated_url ⇒ Object
53 54 55 |
# File 'app/models/federails/actor.rb', line 53 def federated_url use_entity_attributes? ? Federails::Engine.routes.url_helpers.server_actor_url(self) : attributes['federated_url'].presence end |
#followed_by?(actor) ⇒ Federails::Following, false
Checks if current actor is followed by the given actor
127 128 129 130 131 132 |
# File 'app/models/federails/actor.rb', line 127 def followed_by?(actor) list = following_followers.where actor: actor return list.first if list.count == 1 false end |
#followers_url ⇒ Object
85 86 87 |
# File 'app/models/federails/actor.rb', line 85 def followers_url use_entity_attributes? ? Federails::Engine.routes.url_helpers.followers_server_actor_url(self) : attributes['followers_url'] end |
#followings_url ⇒ Object
89 90 91 |
# File 'app/models/federails/actor.rb', line 89 def followings_url use_entity_attributes? ? Federails::Engine.routes.url_helpers.following_server_actor_url(self) : attributes['followings_url'] end |
#follows?(actor) ⇒ Federails::Following, false
Checks if a given actor follows the current actor
117 118 119 120 121 122 |
# File 'app/models/federails/actor.rb', line 117 def follows?(actor) list = following_follows.where target_actor: actor return list.first if list.count == 1 false end |
#inbox_url ⇒ Object
77 78 79 |
# File 'app/models/federails/actor.rb', line 77 def inbox_url use_entity_attributes? ? Federails::Engine.routes.url_helpers.server_actor_inbox_url(self) : attributes['inbox_url'] end |
#key_id ⇒ Object
260 261 262 |
# File 'app/models/federails/actor.rb', line 260 def key_id "#{federated_url}#main-key" end |
#name ⇒ Object
63 64 65 66 67 |
# File 'app/models/federails/actor.rb', line 63 def name value = (entity.send(entity_configuration[:name_field]).to_s if use_entity_attributes?) value || attributes['name'] || username end |
#outbox_url ⇒ Object
81 82 83 |
# File 'app/models/federails/actor.rb', line 81 def outbox_url use_entity_attributes? ? Federails::Engine.routes.url_helpers.server_actor_outbox_url(self) : attributes['outbox_url'] end |
#private_key ⇒ Object
255 256 257 258 |
# File 'app/models/federails/actor.rb', line 255 def private_key ensure_key_pair_exists! self[:private_key] end |
#profile_url ⇒ Object
93 94 95 96 97 98 99 100 |
# File 'app/models/federails/actor.rb', line 93 def profile_url return attributes['profile_url'].presence unless use_entity_attributes? method = entity_configuration[:profile_url_method] return Federails::Engine.routes.url_helpers.server_actor_url self unless method Rails.application.routes.url_helpers.send method, [entity] end |
#public_key ⇒ Object
250 251 252 253 |
# File 'app/models/federails/actor.rb', line 250 def public_key ensure_key_pair_exists! self[:public_key] end |
#server ⇒ Object
69 70 71 |
# File 'app/models/federails/actor.rb', line 69 def server use_entity_attributes? ? Utils::Host.localhost : attributes['server'] end |
#short_at_address ⇒ Object
106 107 108 |
# File 'app/models/federails/actor.rb', line 106 def short_at_address use_entity_attributes? ? "@#{username}" : at_address end |
#sync! ⇒ Object
Synchronizes actor with distant data
143 144 145 146 147 148 149 150 151 152 153 |
# File 'app/models/federails/actor.rb', line 143 def sync! if local? Rails.logger.info 'Ignored attempt to sync a local actor' return false end response = Fediverse::Webfinger.fetch_actor_url(federated_url) new_attributes = response.attributes.except 'id', 'uuid', 'created_at', 'updated_at', 'local', 'entity_id', 'entity_type' update! new_attributes end |
#tombstone! ⇒ Object
159 160 161 |
# File 'app/models/federails/actor.rb', line 159 def tombstone! Federails::Utils::Actor.tombstone! self end |
#tombstoned? ⇒ Boolean
155 156 157 |
# File 'app/models/federails/actor.rb', line 155 def tombstoned? tombstoned_at.present? end |
#untombstone! ⇒ Object
163 164 165 |
# File 'app/models/federails/actor.rb', line 163 def untombstone! Federails::Utils::Actor.untombstone! self end |
#username ⇒ Object
57 58 59 60 61 |
# File 'app/models/federails/actor.rb', line 57 def username return attributes['username'] unless use_entity_attributes? entity.send(entity_configuration[:username_field]).to_s end |