about summary refs log tree commit diff
path: root/app/lib/rss_builder.rb
blob: 63ddba2e8ed584a4f5a6da88489242f0c6b0d7c6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# frozen_string_literal: true

class RSSBuilder
  class ItemBuilder
    def initialize
      @item = Ox::Element.new('item')
    end

    def title(str)
      @item << (Ox::Element.new('title') << str)

      self
    end

    def link(str)
      @item << Ox::Element.new('guid').tap do |guid|
        guid['isPermalink'] = 'true'
        guid << str
      end

      @item << (Ox::Element.new('link') << str)

      self
    end

    def pub_date(date)
      @item << (Ox::Element.new('pubDate') << date.to_formatted_s(:rfc822))

      self
    end

    def description(str)
      @item << (Ox::Element.new('description') << str)

      self
    end

    def enclosure(url, type, size)
      @item << Ox::Element.new('enclosure').tap do |enclosure|
        enclosure['url']    = url
        enclosure['length'] = size
        enclosure['type']   = type
      end

      self
    end

    def to_element
      @item
    end
  end

  def initialize
    @document = Ox::Document.new(version: '1.0')
    @channel  = Ox::Element.new('channel')

    @document << (rss << @channel)
  end

  def title(str)
    @channel << (Ox::Element.new('title') << str)

    self
  end

  def link(str)
    @channel << (Ox::Element.new('link') << str)

    self
  end

  def image(str)
    @channel << Ox::Element.new('image').tap do |image|
      image << (Ox::Element.new('url') << str)
      image << (Ox::Element.new('title') << '')
      image << (Ox::Element.new('link') << '')
    end

    @channel << (Ox::Element.new('webfeeds:icon') << str)

    self
  end

  def cover(str)
    @channel << Ox::Element.new('webfeeds:cover').tap do |cover|
      cover['image'] = str
    end

    self
  end

  def logo(str)
    @channel << (Ox::Element.new('webfeeds:logo') << str)

    self
  end

  def accent_color(str)
    @channel << (Ox::Element.new('webfeeds:accentColor') << str)

    self
  end

  def description(str)
    @channel << (Ox::Element.new('description') << str)

    self
  end

  def item
    @channel << ItemBuilder.new.tap do |item|
      yield item
    end.to_element

    self
  end

  def to_xml
    ('<?xml version="1.0" encoding="UTF-8"?>' + Ox.dump(@document, effort: :tolerant)).force_encoding('UTF-8')
  end

  private

  def rss
    Ox::Element.new('rss').tap do |rss|
      rss['version']        = '2.0'
      rss['xmlns:webfeeds'] = 'http://webfeeds.org/rss/1.0'
    end
  end
end