note_serializer.rb 6.8 KB

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