atom_builder_helper.rb 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. # frozen_string_literal: true
  2. module AtomBuilderHelper
  3. def stream_updated_at
  4. if @account.stream_entries.last
  5. (@account.updated_at > @account.stream_entries.last.created_at ? @account.updated_at : @account.stream_entries.last.created_at)
  6. else
  7. @account.updated_at
  8. end
  9. end
  10. def entry(xml, is_root = false, &block)
  11. if is_root
  12. root_tag(xml, :entry, &block)
  13. else
  14. xml.entry(&block)
  15. end
  16. end
  17. def feed(xml, &block)
  18. root_tag(xml, :feed, &block)
  19. end
  20. def unique_id(xml, date, id, type)
  21. xml.id_ TagManager.instance.unique_tag(date, id, type)
  22. end
  23. def simple_id(xml, id)
  24. xml.id_ id
  25. end
  26. def published_at(xml, date)
  27. xml.published date.iso8601
  28. end
  29. def updated_at(xml, date)
  30. xml.updated date.iso8601
  31. end
  32. def verb(xml, verb)
  33. xml['activity'].send('verb', TagManager::VERBS[verb])
  34. end
  35. def content(xml, content)
  36. xml.content({ type: 'html' }, content) unless content.blank?
  37. end
  38. def title(xml, title)
  39. xml.title strip_tags(title || '').truncate(80)
  40. end
  41. def author(xml, &block)
  42. xml.author(&block)
  43. end
  44. def category(xml, term)
  45. xml.category(term: term)
  46. end
  47. def target(xml, &block)
  48. xml['activity'].object(&block)
  49. end
  50. def object_type(xml, type)
  51. xml['activity'].send('object-type', TagManager::TYPES[type])
  52. end
  53. def uri(xml, uri)
  54. xml.uri uri
  55. end
  56. def name(xml, name)
  57. xml.name name
  58. end
  59. def summary(xml, summary)
  60. xml.summary(summary) unless summary.blank?
  61. end
  62. def subtitle(xml, subtitle)
  63. xml.subtitle(subtitle) unless subtitle.blank?
  64. end
  65. def link_alternate(xml, url)
  66. xml.link(rel: 'alternate', type: 'text/html', href: url)
  67. end
  68. def link_self(xml, url)
  69. xml.link(rel: 'self', type: 'application/atom+xml', href: url)
  70. end
  71. def link_hub(xml, url)
  72. xml.link(rel: 'hub', href: url)
  73. end
  74. def link_salmon(xml, url)
  75. xml.link(rel: 'salmon', href: url)
  76. end
  77. def portable_contact(xml, account)
  78. xml['poco'].preferredUsername account.username
  79. xml['poco'].displayName(account.display_name) unless account.display_name.blank?
  80. xml['poco'].note(Formatter.instance.simplified_format(account)) unless account.note.blank?
  81. end
  82. def in_reply_to(xml, uri, url)
  83. xml['thr'].send('in-reply-to', ref: uri, href: url, type: 'text/html')
  84. end
  85. def link_mention(xml, account)
  86. xml.link(:rel => 'mentioned', :href => TagManager.instance.uri_for(account), 'ostatus:object-type' => TagManager::TYPES[:person])
  87. end
  88. def link_enclosure(xml, media)
  89. xml.link(rel: 'enclosure', href: full_asset_url(media.file.url(:original, false)), type: media.file_content_type, length: media.file_file_size)
  90. end
  91. def link_avatar(xml, account)
  92. single_link_avatar(xml, account, :original, 120)
  93. end
  94. def logo(xml, url)
  95. xml.logo url
  96. end
  97. def email(xml, email)
  98. xml.email email
  99. end
  100. def conditionally_formatted(activity)
  101. if activity.is_a?(Status)
  102. Formatter.instance.format(activity.reblog? ? activity.reblog : activity)
  103. elsif activity.nil?
  104. nil
  105. else
  106. activity.content
  107. end
  108. end
  109. def link_visibility(xml, item)
  110. return unless item.respond_to?(:visibility) && item.public_visibility?
  111. xml.link(:rel => 'mentioned', :href => TagManager::COLLECTIONS[:public], 'ostatus:object-type' => TagManager::TYPES[:collection])
  112. end
  113. def include_author(xml, account)
  114. object_type xml, :person
  115. uri xml, TagManager.instance.uri_for(account)
  116. name xml, account.username
  117. email xml, account.local? ? "#{account.acct}@#{Rails.configuration.x.local_domain}" : account.acct
  118. summary xml, account.note
  119. link_alternate xml, TagManager.instance.url_for(account)
  120. link_avatar xml, account
  121. portable_contact xml, account
  122. end
  123. def include_entry(xml, stream_entry)
  124. unique_id xml, stream_entry.created_at, stream_entry.activity_id, stream_entry.activity_type
  125. published_at xml, stream_entry.created_at
  126. updated_at xml, stream_entry.updated_at
  127. title xml, stream_entry.title
  128. content xml, conditionally_formatted(stream_entry.activity)
  129. verb xml, stream_entry.verb
  130. link_self xml, account_stream_entry_url(stream_entry.account, stream_entry, format: 'atom')
  131. link_alternate xml, account_stream_entry_url(stream_entry.account, stream_entry)
  132. object_type xml, stream_entry.object_type
  133. # Comments need thread element
  134. if stream_entry.threaded?
  135. in_reply_to xml, TagManager.instance.uri_for(stream_entry.thread), TagManager.instance.url_for(stream_entry.thread)
  136. end
  137. if stream_entry.targeted?
  138. target(xml) do
  139. simple_id xml, TagManager.instance.uri_for(stream_entry.target)
  140. if stream_entry.target.object_type == :person
  141. include_author xml, stream_entry.target
  142. else
  143. object_type xml, stream_entry.target.object_type
  144. title xml, stream_entry.target.title
  145. link_alternate xml, TagManager.instance.url_for(stream_entry.target)
  146. end
  147. # Statuses have content and author
  148. if stream_entry.target.is_a?(Status)
  149. content xml, conditionally_formatted(stream_entry.target)
  150. verb xml, stream_entry.target.verb
  151. published_at xml, stream_entry.target.created_at
  152. updated_at xml, stream_entry.target.updated_at
  153. author(xml) do
  154. include_author xml, stream_entry.target.account
  155. end
  156. link_visibility xml, stream_entry.target
  157. stream_entry.target.mentions.each do |mention|
  158. link_mention xml, mention.account
  159. end
  160. stream_entry.target.media_attachments.each do |media|
  161. link_enclosure xml, media
  162. end
  163. stream_entry.target.tags.each do |tag|
  164. category xml, tag.name
  165. end
  166. category(xml, 'nsfw') if stream_entry.target.sensitive?
  167. end
  168. end
  169. end
  170. link_visibility xml, stream_entry.activity
  171. stream_entry.mentions.each do |mentioned|
  172. link_mention xml, mentioned
  173. end
  174. return unless stream_entry.activity.is_a?(Status)
  175. stream_entry.activity.media_attachments.each do |media|
  176. link_enclosure xml, media
  177. end
  178. stream_entry.activity.tags.each do |tag|
  179. category xml, tag.name
  180. end
  181. category(xml, 'nsfw') if stream_entry.activity.sensitive?
  182. end
  183. private
  184. def root_tag(xml, tag, &block)
  185. xml.send(tag, {
  186. 'xmlns' => TagManager::XMLNS,
  187. 'xmlns:thr' => TagManager::THR_XMLNS,
  188. 'xmlns:activity' => TagManager::AS_XMLNS,
  189. 'xmlns:poco' => TagManager::POCO_XMLNS,
  190. 'xmlns:media' => TagManager::MEDIA_XMLNS,
  191. 'xmlns:ostatus' => TagManager::OS_XMLNS,
  192. }, &block)
  193. end
  194. def single_link_avatar(xml, account, size, px)
  195. xml.link('rel' => 'avatar', 'type' => account.avatar_content_type, 'media:width' => px, 'media:height' => px, 'href' => full_asset_url(account.avatar.url(size, false)))
  196. end
  197. end