-
Notifications
You must be signed in to change notification settings - Fork 0
/
rss.ex
126 lines (102 loc) · 2.32 KB
/
rss.ex
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
defmodule Blog.Rss do
@moduledoc """
A Serum plugin that generates an RSS feed.
## Using the Plugin
# serum.exs:
%{
server_root: "https://example.io",
plugins: [
Rss
]
}
"""
require EEx
alias Serum.File
alias Serum.GlobalBindings
@behaviour Serum.Plugin
@title "Rasjonell's Blog"
@url "https://www.rasjonell.tech"
@blog_desc "Random rants about technology"
@impl true
def name, do: "RSS Feed Generator"
@impl true
def version, do: "0.1.0"
@impl true
def elixir, do: ">= 1.7.0"
@impl true
def serum, do: ">= 1.2.0"
@impl true
def description do
"Generates an RSS feed for /posts"
end
@impl true
def implements do
[build_succeeded: 3]
end
@impl true
def build_succeeded(_src, dest, _args) do
:all_posts
|> GlobalBindings.get()
|> build_feed(dest)
|> create_file(dest)
|> File.write()
:ok
end
defp build_feed(posts, dest) do
items = posts |> Enum.map(&(generate_item_from_post(&1, dest)))
feed(channel(), items)
end
defp create_file(rss_feed, dest) do
%File{
out_data: rss_feed,
dest: Path.join(dest, "rss.xml")
}
end
defp generate_item_from_post(post, dest) do
title = post.title
link = "#{@url}#{post.url}"
desc = get_full_content(post, dest)
item(title, desc, link)
end
defp get_full_content(post, dest) do
src = Path.join(dest, post.url)
{:ok, file} = %Serum.File{src: src} |> Serum.File.read()
file.in_data
end
defp feed(channel, items) do
"""
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
#{channel}
#{Enum.join items, ""}
</channel>
</rss>
"""
end
defp item(title, desc, link) do
"""
<item>
<title>#{title}</title>
<description><![CDATA[#{desc}]]></description>
<pubDate>#{current_date()}</pubDate>
<link>#{link}</link>
<guid>#{link}</guid>
</item>
"""
end
defp channel do
"""
<title>#{@title}</title>
<link>#{@url}</link>
<description>#{@blog_desc}</description>
<lastBuildDate>#{current_date()}</lastBuildDate>
<language>en-us</language>
"""
end
defp current_date do
{:ok, current_date} = Timex.now
|> Timex.format("{RFC822}")
current_date
end
end