note_serializer.rb 5.7 KB

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