You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
5.3 KiB

  1. # frozen_string_literal: true
  2. class ActivityPub::NoteSerializer < ActivityPub::Serializer
  3. context_extensions :atom_uri, :conversation, :sensitive,
  4. :hashtag, :emoji, :focal_point, :blurhash
  5. attributes :id, :type, :summary,
  6. :in_reply_to, :published, :url,
  7. :attributed_to, :to, :cc, :sensitive,
  8. :atom_uri, :in_reply_to_atom_uri,
  9. :conversation
  10. attribute :content
  11. attribute :content_map, if: :language?
  12. has_many :media_attachments, key: :attachment
  13. has_many :virtual_tags, key: :tag
  14. has_one :replies, serializer: ActivityPub::CollectionSerializer, if: :local?
  15. has_many :poll_options, key: :one_of, if: :poll_and_not_multiple?
  16. has_many :poll_options, key: :any_of, if: :poll_and_multiple?
  17. attribute :end_time, if: :poll_and_expires?
  18. attribute :closed, if: :poll_and_expired?
  19. def id
  20. raise Mastodon::NotPermittedError, 'Local-only statuses should not be serialized' if object.local_only?
  21. ActivityPub::TagManager.instance.uri_for(object)
  22. end
  23. def type
  24. object.preloadable_poll ? 'Question' : 'Note'
  25. end
  26. def summary
  27. object.spoiler_text.presence
  28. end
  29. def content
  30. Formatter.instance.format(object)
  31. end
  32. def content_map
  33. { object.language => Formatter.instance.format(object) }
  34. end
  35. def replies
  36. replies = object.self_replies(5).pluck(:id, :uri)
  37. last_id = replies.last&.first
  38. ActivityPub::CollectionPresenter.new(
  39. type: :unordered,
  40. id: ActivityPub::TagManager.instance.replies_uri_for(object),
  41. first: ActivityPub::CollectionPresenter.new(
  42. type: :unordered,
  43. part_of: ActivityPub::TagManager.instance.replies_uri_for(object),
  44. items: replies.map(&:second),
  45. next: last_id ? ActivityPub::TagManager.instance.replies_uri_for(object, page: true, min_id: last_id) : nil
  46. )
  47. )
  48. end
  49. def language?
  50. object.language.present?
  51. end
  52. def in_reply_to
  53. return unless object.reply? && !object.thread.nil?
  54. if object.thread.uri.nil? || object.thread.uri.start_with?('http')
  55. ActivityPub::TagManager.instance.uri_for(object.thread)
  56. else
  57. object.thread.url
  58. end
  59. end
  60. def published
  61. object.created_at.iso8601
  62. end
  63. def url
  64. ActivityPub::TagManager.instance.url_for(object)
  65. end
  66. def attributed_to
  67. ActivityPub::TagManager.instance.uri_for(object.account)
  68. end
  69. def to
  70. ActivityPub::TagManager.instance.to(object)
  71. end
  72. def cc
  73. ActivityPub::TagManager.instance.cc(object)
  74. end
  75. def virtual_tags
  76. object.active_mentions.to_a.sort_by(&:id) + object.tags + object.emojis
  77. end
  78. def atom_uri
  79. return unless object.local?
  80. OStatus::TagManager.instance.uri_for(object)
  81. end
  82. def in_reply_to_atom_uri
  83. return unless object.reply? && !object.thread.nil?
  84. OStatus::TagManager.instance.uri_for(object.thread)
  85. end
  86. def conversation
  87. return if object.conversation.nil?
  88. if object.conversation.uri?
  89. object.conversation.uri
  90. else
  91. OStatus::TagManager.instance.unique_tag(object.conversation.created_at, object.conversation.id, 'Conversation')
  92. end
  93. end
  94. def local?
  95. object.account.local?
  96. end
  97. def poll_options
  98. object.preloadable_poll.loaded_options
  99. end
  100. def poll_and_multiple?
  101. object.preloadable_poll&.multiple?
  102. end
  103. def poll_and_not_multiple?
  104. object.preloadable_poll && !object.preloadable_poll.multiple?
  105. end
  106. def closed
  107. object.preloadable_poll.expires_at.iso8601
  108. end
  109. alias end_time closed
  110. def poll_and_expires?
  111. object.preloadable_poll&.expires_at&.present?
  112. end
  113. def poll_and_expired?
  114. object.preloadable_poll&.expired?
  115. end
  116. class MediaAttachmentSerializer < ActivityPub::Serializer
  117. include RoutingHelper
  118. attributes :type, :media_type, :url, :name, :blurhash
  119. attribute :focal_point, if: :focal_point?
  120. def type
  121. 'Document'
  122. end
  123. def name
  124. object.description
  125. end
  126. def media_type
  127. object.file_content_type
  128. end
  129. def url
  130. object.local? ? full_asset_url(object.file.url(:original, false)) : object.remote_url
  131. end
  132. def focal_point?
  133. object.file.meta.is_a?(Hash) && object.file.meta['focus'].is_a?(Hash)
  134. end
  135. def focal_point
  136. [object.file.meta['focus']['x'], object.file.meta['focus']['y']]
  137. end
  138. end
  139. class MentionSerializer < ActivityPub::Serializer
  140. attributes :type, :href, :name
  141. def type
  142. 'Mention'
  143. end
  144. def href
  145. ActivityPub::TagManager.instance.uri_for(object.account)
  146. end
  147. def name
  148. "@#{object.account.acct}"
  149. end
  150. end
  151. class TagSerializer < ActivityPub::Serializer
  152. include RoutingHelper
  153. attributes :type, :href, :name
  154. def type
  155. 'Hashtag'
  156. end
  157. def href
  158. tag_url(object)
  159. end
  160. def name
  161. "##{object.name}"
  162. end
  163. end
  164. class CustomEmojiSerializer < ActivityPub::EmojiSerializer
  165. end
  166. class OptionSerializer < ActivityPub::Serializer
  167. class RepliesSerializer < ActivityPub::Serializer
  168. attributes :type, :total_items
  169. def type
  170. 'Collection'
  171. end
  172. def total_items
  173. object.votes_count
  174. end
  175. end
  176. attributes :type, :name
  177. has_one :replies, serializer: ActivityPub::NoteSerializer::OptionSerializer::RepliesSerializer
  178. def type
  179. 'Note'
  180. end
  181. def name
  182. object.title
  183. end
  184. def replies
  185. object
  186. end
  187. end
  188. end