imap-feeder 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/.project +23 -0
- data/History.txt +4 -0
- data/License.txt +341 -0
- data/Manifest.txt +48 -0
- data/README.txt +77 -0
- data/Rakefile +4 -0
- data/TODO.txt +11 -0
- data/bin/imap-feeder +68 -0
- data/config/hoe.rb +77 -0
- data/config/requirements.rb +17 -0
- data/lib/imap-feeder.rb +87 -0
- data/lib/imap-feeder/createconfigparser.rb +40 -0
- data/lib/imap-feeder/fakeserver.rb +23 -0
- data/lib/imap-feeder/feedfolder.rb +23 -0
- data/lib/imap-feeder/feedreader.rb +81 -0
- data/lib/imap-feeder/imapfeederconfig.rb +74 -0
- data/lib/imap-feeder/message.rb +152 -0
- data/lib/imap-feeder/messagestore.rb +35 -0
- data/lib/imap-feeder/opmlreader.rb +50 -0
- data/lib/imap-feeder/server.rb +77 -0
- data/lib/imap-feeder/version.rb +9 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +77 -0
- data/settings.rb.example +58 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +15 -0
- data/test/data/encoded.rss +22 -0
- data/test/data/erroneous.yml +7 -0
- data/test/data/last_messages.yaml +0 -0
- data/test/data/rss20_no_body.xml +10 -0
- data/test/data/rss20_one_entry.xml +11 -0
- data/test/data/rss20_two_entries.xml +17 -0
- data/test/data/rss20_with_authors.xml +21 -0
- data/test/data/simple.opml +9 -0
- data/test/functional_test_server.rb +95 -0
- data/test/test_feedreader.rb +92 -0
- data/test/test_imap-feeder.rb +66 -0
- data/test/test_imapfeederconfig.rb +56 -0
- data/test/test_message.rb +312 -0
- data/test/test_messagestore.rb +54 -0
- data/test/test_opmlreader.rb +73 -0
- data/test/testlogger.rb +22 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +137 -0
- data/website/template.rhtml +49 -0
- metadata +175 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,312 @@
|
|
1
|
+
require 'imap-feeder/message'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
$tidy_path = "/usr/lib/libtidy.so"
|
5
|
+
|
6
|
+
class MessageTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_creation
|
9
|
+
m = Message.new(:title => "title", :body => "body")
|
10
|
+
assert_equal("title", m.title)
|
11
|
+
assert_equal("body", m.body)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_creation_with_time
|
15
|
+
t = Time.now.localtime
|
16
|
+
m = Message.new(:title => "title", :body => "body", :time => t)
|
17
|
+
assert_equal("title", m.title)
|
18
|
+
assert_equal("body", m.body)
|
19
|
+
assert_equal(t.rfc2822, m.time)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_creation_title_only
|
23
|
+
m = Message.new(:title => "title")
|
24
|
+
assert_equal("title", m.title)
|
25
|
+
assert_equal("", m.body)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_creation_body_only
|
29
|
+
m = Message.new(:body => "body")
|
30
|
+
assert_equal("", m.title)
|
31
|
+
assert_equal("body", m.body)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_creation_name_with_url
|
35
|
+
m = Message.new(:from => "Mirko Stocker", :url => "http://www.url.ch")
|
36
|
+
assert_equal("Mirko Stocker", m.from)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_format_with_plus
|
40
|
+
t = Time.parse("Mon, Mar 05 2007 15:24:12 +0100")
|
41
|
+
m = Message.new(:title => "C/C++", :body => "body", :time => t)
|
42
|
+
assert_equal(<<EOF, m.format)
|
43
|
+
Date: Mon, 05 Mar 2007 15:24:12 +0100
|
44
|
+
Subject: C/C++
|
45
|
+
From: Unknown <spam@example.org>
|
46
|
+
Content-Type: text/plain;
|
47
|
+
charset="utf-8"
|
48
|
+
Content-Transfer-Encoding: 8bit
|
49
|
+
|
50
|
+
body
|
51
|
+
EOF
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_format
|
55
|
+
t = Time.parse("Mon, Mar 05 2007 15:24:12 +0100")
|
56
|
+
m = Message.new(:title => "title", :body => "body", :time => t)
|
57
|
+
assert_equal(<<EOF, m.format)
|
58
|
+
Date: Mon, 05 Mar 2007 15:24:12 +0100
|
59
|
+
Subject: title
|
60
|
+
From: Unknown <spam@example.org>
|
61
|
+
Content-Type: text/plain;
|
62
|
+
charset="utf-8"
|
63
|
+
Content-Transfer-Encoding: 8bit
|
64
|
+
|
65
|
+
body
|
66
|
+
EOF
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_format_with_url
|
70
|
+
t = Time.parse("Mon, Mar 05 2007 15:26:49 +0100")
|
71
|
+
m = Message.new(:title => "title", :body => "body", :time => t, :url => "http://www.misto.ch")
|
72
|
+
assert_equal(<<EOF, m.format)
|
73
|
+
Date: Mon, 05 Mar 2007 15:26:49 +0100
|
74
|
+
Subject: title
|
75
|
+
From: Unknown <spam@example.org>
|
76
|
+
Content-Type: text/plain;
|
77
|
+
charset="utf-8"
|
78
|
+
Content-Transfer-Encoding: 8bit
|
79
|
+
|
80
|
+
body
|
81
|
+
|
82
|
+
http://www.misto.ch
|
83
|
+
EOF
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_format_multiline
|
87
|
+
t = Time.parse("Mon, Mar 05 2007 15:26:49 +0100")
|
88
|
+
m = Message.new(:title => "title", :body => "<p>body</p>second", :time => t)
|
89
|
+
assert_equal(<<EOF, m.format)
|
90
|
+
Date: Mon, 05 Mar 2007 15:26:49 +0100
|
91
|
+
Subject: title
|
92
|
+
From: Unknown <spam@example.org>
|
93
|
+
Content-Type: text/plain;
|
94
|
+
charset="utf-8"
|
95
|
+
Content-Transfer-Encoding: 8bit
|
96
|
+
|
97
|
+
body
|
98
|
+
|
99
|
+
second
|
100
|
+
EOF
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_format_encoded
|
104
|
+
t = Time.parse("Mon, Mar 05 2007 15:26:16 +0100")
|
105
|
+
m = Message.new(:title => "Xæxøx: …", :body => "<p>body</p>second", :time => t)
|
106
|
+
assert_equal(<<-EOF, m.format)
|
107
|
+
Date: Mon, 05 Mar 2007 15:26:16 +0100
|
108
|
+
Subject: X=?UTF-8?Q?=c3=a6?=x=?UTF-8?Q?=c3=b8?=x: =?UTF-8?Q?=e2=80=a6?=
|
109
|
+
From: Unknown <spam@example.org>
|
110
|
+
Content-Type: text/plain;
|
111
|
+
charset="utf-8"
|
112
|
+
Content-Transfer-Encoding: 8bit
|
113
|
+
|
114
|
+
body
|
115
|
+
|
116
|
+
second
|
117
|
+
EOF
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
class MessageFormatterTest < Test::Unit::TestCase
|
123
|
+
|
124
|
+
def create_message body
|
125
|
+
Message.new(:body => body)
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Paragraphs
|
130
|
+
#
|
131
|
+
def test_one_p
|
132
|
+
m = create_message "<p>X</p>"
|
133
|
+
assert_equal("X", m.body)
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_one_p_with_space
|
137
|
+
m = create_message "<p >X</p >"
|
138
|
+
assert_equal("X", m.body)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_one_p_in_the_middle
|
142
|
+
m = create_message "X<p>Y</p>Z"
|
143
|
+
assert_equal("X\n\nY\n\nZ", m.body)
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_p_with_spaces
|
147
|
+
m = create_message "X<p >Y</p >Z"
|
148
|
+
assert_equal("X\n\nY\n\nZ", m.body)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_mutliple_p
|
152
|
+
m = create_message "<p>Y</p><p>Z</p>"
|
153
|
+
assert_equal("Y\n\nZ", m.body)
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_font
|
157
|
+
m = create_message "<font>Z</font>"
|
158
|
+
assert_equal("Z", m.body)
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# Linebreak
|
163
|
+
#
|
164
|
+
def test_br_html
|
165
|
+
m = create_message "Y<br>Z"
|
166
|
+
assert_equal("Y\n\nZ", m.body)
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_br_xhtml
|
170
|
+
m = create_message "Y<br/>Z"
|
171
|
+
assert_equal("Y\n\nZ", m.body)
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_br_with_space
|
175
|
+
m = create_message "Y<br />Z"
|
176
|
+
assert_equal("Y\n\nZ", m.body)
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
# Lines
|
181
|
+
#
|
182
|
+
def test_multi_lines
|
183
|
+
m = create_message "Y<br /><br /><br /><br /><br />Z"
|
184
|
+
assert_equal("Y\n\nZ", m.body)
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_sanitize_newlines_with_spaces
|
188
|
+
m = create_message "<p>aa</p>\n \n\t\n \n<p>aa</p>"
|
189
|
+
assert_equal("aa\n\naa", m.body)
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_sanitize_newlines
|
193
|
+
m = create_message "<p>aa</p>\n\n\n\n<p>aa</p>"
|
194
|
+
assert_equal("aa\n\naa", m.body)
|
195
|
+
end
|
196
|
+
|
197
|
+
#
|
198
|
+
# Italic
|
199
|
+
#
|
200
|
+
def test_italic
|
201
|
+
m = create_message "<i>yeah</i>"
|
202
|
+
assert_equal("*yeah*", m.body)
|
203
|
+
end
|
204
|
+
|
205
|
+
#
|
206
|
+
# Strong
|
207
|
+
#
|
208
|
+
def test_strong
|
209
|
+
m = create_message "<strong >g</strong> or <em>s</em>"
|
210
|
+
assert_equal("*g* or *s*", m.body)
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_bold
|
214
|
+
m = create_message "<b >g</b >"
|
215
|
+
assert_equal("*g*", m.body)
|
216
|
+
end
|
217
|
+
|
218
|
+
#
|
219
|
+
# Images
|
220
|
+
#
|
221
|
+
def test_img
|
222
|
+
m = create_message "Juhu <img src='files/smiley.png' alt=':-)' />."
|
223
|
+
assert_equal("Juhu :-).", m.body)
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_img_without_alt
|
227
|
+
m = create_message "Juhu <img src='files/smiley.png'/>."
|
228
|
+
assert_equal("Juhu .", m.body)
|
229
|
+
end
|
230
|
+
|
231
|
+
#
|
232
|
+
# HTML Entities
|
233
|
+
#
|
234
|
+
def test_html_entity
|
235
|
+
m = create_message "…"
|
236
|
+
assert_equal("…", m.body)
|
237
|
+
end
|
238
|
+
def test_html_escaped
|
239
|
+
m = create_message "/lib & /bin"
|
240
|
+
assert_equal("/lib & /bin", m.body)
|
241
|
+
end
|
242
|
+
|
243
|
+
#
|
244
|
+
# Abbreviations
|
245
|
+
#
|
246
|
+
def test_abbr
|
247
|
+
m = create_message '<abbr title="Ruby Development Tool">RDT</abbr>'
|
248
|
+
assert_equal("RDT (Ruby Development Tool)", m.body)
|
249
|
+
end
|
250
|
+
|
251
|
+
#
|
252
|
+
# span
|
253
|
+
#
|
254
|
+
def test_span
|
255
|
+
m = create_message 'Thema <span class="caps">REST</span>'
|
256
|
+
assert_equal("Thema REST", m.body)
|
257
|
+
end
|
258
|
+
|
259
|
+
#
|
260
|
+
# URLs
|
261
|
+
#
|
262
|
+
def test_href
|
263
|
+
m = create_message "Kuck mal <a href=\"http://da.da\">hier</a>!"
|
264
|
+
assert_equal("Kuck mal hier[1]!\n\n[1] http://da.da", m.body)
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_href_with_equal_content
|
268
|
+
m = create_message "Kuck mal <a href=\"http://da.da\">http://da.da</a>!"
|
269
|
+
assert_equal("Kuck mal http://da.da!", m.body)
|
270
|
+
end
|
271
|
+
|
272
|
+
def test_href_single_quotes
|
273
|
+
m = create_message "Kuck mal <a href='http://da.da'>hier</a>!"
|
274
|
+
assert_equal(<<EOS.chomp, m.body)
|
275
|
+
Kuck mal hier[1]!
|
276
|
+
|
277
|
+
[1] http://da.da
|
278
|
+
EOS
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_hrefs
|
282
|
+
m = create_message "Kuck mal <a href=\"http://da.da\">hier\n</a> und <a href=\"http://namal.da\">da</a >!"
|
283
|
+
assert_equal(<<EOS.chomp, m.body)
|
284
|
+
Kuck mal hier[1] und da[2]!
|
285
|
+
|
286
|
+
[1] http://da.da
|
287
|
+
[2] http://namal.da
|
288
|
+
EOS
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_lots_of_hrefs
|
292
|
+
str = "<a href=\"http://da.da\">link</a>\n" * 12
|
293
|
+
|
294
|
+
m = create_message str
|
295
|
+
assert_equal(<<EOS.chomp, m.body)
|
296
|
+
link[1] link[2] link[3] link[4] link[5] link[6] link[7] link[8] link[9] link[10] link[11] link[12]
|
297
|
+
|
298
|
+
[1] http://da.da
|
299
|
+
[2] http://da.da
|
300
|
+
[3] http://da.da
|
301
|
+
[4] http://da.da
|
302
|
+
[5] http://da.da
|
303
|
+
[6] http://da.da
|
304
|
+
[7] http://da.da
|
305
|
+
[8] http://da.da
|
306
|
+
[9] http://da.da
|
307
|
+
[10] http://da.da
|
308
|
+
[11] http://da.da
|
309
|
+
[12] http://da.da
|
310
|
+
EOS
|
311
|
+
end
|
312
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
require 'imap-feeder/opmlreader'
|
4
|
+
require 'imap-feeder/messagestore'
|
5
|
+
|
6
|
+
class TestingMessageStore < MessageStore
|
7
|
+
def initialize(file)
|
8
|
+
@file = file
|
9
|
+
File.open(@file, "w") do |f|
|
10
|
+
YAML.dump({"INBOX.Planets.Planet KDE" => ["Mirko: It works!"],
|
11
|
+
"INBOX.Planets.Planet Gentoo" => [],
|
12
|
+
"INBOX.Blog.Mirko" => []}, f)
|
13
|
+
end
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def clean
|
18
|
+
File.open(@file, "w").close
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class TestMessageStore < Test::Unit::TestCase
|
23
|
+
|
24
|
+
FILE_NAME = "#{File.dirname(__FILE__)}/data/last_messages.yaml"
|
25
|
+
|
26
|
+
def setup
|
27
|
+
@store = TestingMessageStore.new(FILE_NAME)
|
28
|
+
end
|
29
|
+
|
30
|
+
def teardown
|
31
|
+
@store.clean
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_get_archived
|
35
|
+
title = @store.get_archived "INBOX.Planets.Planet KDE"
|
36
|
+
assert_equal("Mirko: It works!", title.first)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_add_new
|
40
|
+
@store.add_new("INBOX.Planets.Planet KDE", ["Erstes", "Zweites"])
|
41
|
+
title = @store.get_archived "INBOX.Planets.Planet KDE"
|
42
|
+
assert_equal("Erstes", title[0])
|
43
|
+
assert_equal("Zweites", title[1])
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_store_and_save
|
47
|
+
@store.add_new("INBOX.Planets.Planet KDE", ["FAKE"])
|
48
|
+
title = @store.get_archived("INBOX.Planets.Planet KDE")
|
49
|
+
@store.save
|
50
|
+
saved_store = MessageStore.new(FILE_NAME)
|
51
|
+
saved_title = saved_store.get_archived("INBOX.Planets.Planet KDE")
|
52
|
+
assert_equal(title, saved_title)
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'imap-feeder/opmlreader'
|
2
|
+
|
3
|
+
class OpmlReaderTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_simple_without_urls
|
6
|
+
result = OpmlReader.get(<<-EOF)
|
7
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
8
|
+
<opml version="1.0" >
|
9
|
+
<body>
|
10
|
+
<outline isOpen="false" text="Planets">
|
11
|
+
</outline>
|
12
|
+
</body>
|
13
|
+
</opml>
|
14
|
+
EOF
|
15
|
+
assert_equal("", result.name)
|
16
|
+
assert_equal("Planets", result[0].name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_character_conversion
|
20
|
+
result = OpmlReader.get(<<-EOF)
|
21
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
22
|
+
<opml version="1.0" >
|
23
|
+
<body>
|
24
|
+
<outline isOpen="false" text="Mirko.Stocker's">
|
25
|
+
</outline>
|
26
|
+
</body>
|
27
|
+
</opml>
|
28
|
+
EOF
|
29
|
+
assert_equal("", result.name)
|
30
|
+
assert_equal("Mirko_Stocker_s", result[0].name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_simple_one_category
|
34
|
+
result = OpmlReader.get(<<-EOF)
|
35
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
36
|
+
<opml version="1.0" >
|
37
|
+
<body>
|
38
|
+
<outline isOpen="false" text="Planets">
|
39
|
+
<outline title="Planet KDE" xmlUrl="http://planetkde.org/rss20.xml"/>
|
40
|
+
<outline xmlUrl="http://planet.gentoo.org/rss20.xml" title="Planet Gentoo"/>
|
41
|
+
</outline>
|
42
|
+
</body>
|
43
|
+
</opml>
|
44
|
+
EOF
|
45
|
+
assert_equal("", result.name)
|
46
|
+
assert_equal("Planets", result[0].name)
|
47
|
+
assert_equal("Planet KDE", result[0].urls[0].name)
|
48
|
+
assert_equal("http://planetkde.org/rss20.xml", result[0].urls[0].url)
|
49
|
+
assert_equal("Planet Gentoo", result[0].urls[1].name)
|
50
|
+
assert_equal("http://planet.gentoo.org/rss20.xml", result[0].urls[1].url)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def test_simple_category_with_sub
|
55
|
+
result = OpmlReader.get(<<-EOF)
|
56
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
57
|
+
<opml version="1.0" >
|
58
|
+
<body>
|
59
|
+
<outline isOpen="false" text="Planets">
|
60
|
+
<outline isOpen="false" text="Satelites">
|
61
|
+
<outline title="The Satelite" xmlUrl="http://misto.ch"/>
|
62
|
+
</outline>
|
63
|
+
</outline>
|
64
|
+
</body>
|
65
|
+
</opml>
|
66
|
+
EOF
|
67
|
+
assert_equal("", result.name)
|
68
|
+
assert_equal("Planets", result[0].name)
|
69
|
+
assert_equal("Satelites", result[0].children[0].name)
|
70
|
+
assert_equal("The Satelite", result[0].children[0].urls[0].name)
|
71
|
+
assert_equal("http://misto.ch", result[0].children[0].urls[0].url)
|
72
|
+
end
|
73
|
+
end
|
data/test/testlogger.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class TestLogger
|
2
|
+
attr_reader :debug_msg, :warn_msg, :error_msg, :info_msg
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@debug_msg = []
|
6
|
+
@warn_msg = []
|
7
|
+
@error_msg = []
|
8
|
+
@info_msg = []
|
9
|
+
end
|
10
|
+
def debug(msg)
|
11
|
+
@debug_msg << msg
|
12
|
+
end
|
13
|
+
def warn(msg)
|
14
|
+
@warn_msg << msg
|
15
|
+
end
|
16
|
+
def error(msg)
|
17
|
+
@error_msg << msg
|
18
|
+
end
|
19
|
+
def info(msg)
|
20
|
+
@info_msg << msg
|
21
|
+
end
|
22
|
+
end
|