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.1 KiB

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