feedtxt 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ae42d0a659477fb4d9c6c3f1e2816283a6c81ed
4
- data.tar.gz: 34c181418101a9488cdf981b2b5808c0bcf2d488
3
+ metadata.gz: 08b6aa5f6093d99cc013764f924c5a1845b8b3f0
4
+ data.tar.gz: ae29161c8ffab020ca196d58dd55cdd0f823308c
5
5
  SHA512:
6
- metadata.gz: 86d6e39f32a34d5f54a0c4e57e2810e1d5b481586e40a1610399eb4686605b5850d6669fa8427f4eed3950c420595b386712d89492e3cc7aece7df7c5848800b
7
- data.tar.gz: 8e2d0e904b4dceeea9ae3ae45580cd9ad7d4f80ddfc78abd49f3c5044636063d7cebadfa19b0dd72d558501e43de64be7f43595c022ababfb03162a965c8b544
6
+ metadata.gz: fa7f505525df6950631f8789b44a52d8216573e52b32e6f452f6448c561adc4339ba5f760101e5451543945722d06bff9392655023d62c6242e7507772787814
7
+ data.tar.gz: 49dfd5b5c1f2747b47c0ef45bdb9580cae8ea745c0a3bc75fce88d5108415b15f92601d5b629bed7fbf75b4cc7bb8901ef1fad1c68e7a11b25c30b88eb3c35fd
@@ -3,4 +3,10 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/feedtxt.rb
6
+ lib/feedtxt/parser.rb
6
7
  lib/feedtxt/version.rb
8
+ test/feeds/spec/example.yaml.txt
9
+ test/feeds/spec/podcast.yaml.txt
10
+ test/helper.rb
11
+ test/test_version.rb
12
+ test/test_yaml.rb
data/README.md CHANGED
@@ -10,7 +10,197 @@
10
10
 
11
11
  ## Usage
12
12
 
13
- To be done.
13
+ Use `Feedtxt::Parser.parse` to read / parse feeds in text (using the Feed.TXT)
14
+ format.
15
+ The parse method will return an array:
16
+
17
+ ```
18
+ [ feed_metadata,
19
+ [
20
+ [ item_metadata, item_content ],
21
+ [ item_metadata, item_content ],
22
+ ...
23
+ ]
24
+ ]
25
+ ```
26
+
27
+ - The 1st element is the feed metadata hash.
28
+ - The 2nd element is the items array.
29
+ - The 1st element in an item array is the item metadata hash.
30
+ - The 2nd element in an item array is the item content.
31
+
32
+ Easier to see it in action. Let's read in:
33
+
34
+ ``` ruby
35
+ require 'feedtxt'
36
+
37
+ text =<<TXT
38
+ |>>>
39
+ title: "My Example Feed"
40
+ home_page_url: "https://example.org/"
41
+ feed_url: "https://example.org/feed.txt"
42
+ </>
43
+ id: "2"
44
+ url: "https://example.org/second-item"
45
+ ---
46
+ This is a second item.
47
+ </>
48
+ id: "1"
49
+ url: "https://example.org/initial-post"
50
+ ---
51
+ Hello, world!
52
+ <<<|
53
+ TXT
54
+
55
+ feed = Feedtxt::Parser.parse( text )
56
+ pp feed
57
+ ```
58
+
59
+ resulting in:
60
+
61
+ ``` ruby
62
+ [
63
+ {"title" =>"My Example Feed",
64
+ "home_page_url"=>"https://example.org/",
65
+ "feed_url" =>"https://example.org/feed.txt"
66
+ },
67
+ [[
68
+ {"id" =>"2",
69
+ "url"=>"https://example.org/second-item"
70
+ },
71
+ "This is a second item."
72
+ ],
73
+ [
74
+ {"id"=>"1",
75
+ "url"=>"https://example.org/initial-post"
76
+ },
77
+ "Hello, world!"
78
+ ]]
79
+ ]
80
+ ```
81
+
82
+ and use like:
83
+
84
+ ``` ruby
85
+
86
+ feed_metadata = feed[0]
87
+ feed_items = feed[1]
88
+
89
+ feed_metadata[ 'title' ]
90
+ # => "My Example Feed"
91
+ feed_metadata[ 'feed_url' ]
92
+ # => "https://example.org/feed.txt"
93
+
94
+ item = feed_items[0] # or feed[1][0]
95
+ item_metadata = item[0] # or feed[1][0][0]
96
+ item_content = item[1] # or feed[1][0][1]
97
+
98
+ item_metadata[ 'id' ]
99
+ # => "2"
100
+ item_metadata[ 'url' ]
101
+ # => "https://example.org/second-item"
102
+ item_content
103
+ # => "This is a second item."
104
+
105
+ item = feed_items[1] # or feed[1][1]
106
+ item_metadata = item[0] # or feed[1][1][0]
107
+ item_content = item[1] # or feed[1][1][1]
108
+
109
+ item_metadata[ 'id' ]
110
+ # => "1"
111
+ item_metadata[ 'url' ]
112
+ # => "https://example.org/initial-post"
113
+ item_content
114
+ # => "Hello, world!"
115
+ ...
116
+ ```
117
+
118
+ Another example. Let's try a podcast:
119
+
120
+
121
+ ``` ruby
122
+ text =<<TXT
123
+ |>>>
124
+ comment: "This is a podcast feed. You can add..."
125
+ title: "The Record"
126
+ home_page_url: "http://therecord.co/"
127
+ feed_url: "http://therecord.co/feed.txt"
128
+ </>
129
+ id: "http://therecord.co/chris-parrish"
130
+ title: "Special #1 - Chris Parrish"
131
+ url: "http://therecord.co/chris-parrish"
132
+ summary: "Brent interviews Chris Parrish, co-host of The Record and one-half of Aged & Distilled."
133
+ published: 2014-05-09T14:04:00-07:00
134
+ attachments:
135
+ - url: "http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a"
136
+ mime_type: "audio/x-m4a"
137
+ size_in_bytes: 89970236
138
+ duration_in_seconds: 6629
139
+ ---
140
+ Chris has worked at [Adobe][1] and as a founder of Rogue Sheep, which won an Apple Design Award for Postage.
141
+ Chris's new company is Aged & Distilled with Guy English - which shipped [Napkin](2),
142
+ a Mac app for visual collaboration. Chris is also the co-host of The Record.
143
+ He lives on [Bainbridge Island][3], a quick ferry ride from Seattle.
144
+
145
+ [1]: http://adobe.com/
146
+ [2]: http://aged-and-distilled.com/napkin/
147
+ [3]: http://www.ci.bainbridge-isl.wa.us/
148
+ <<<|
149
+ TXT
150
+
151
+ feed = Feedtxt::Parser.parse( text )
152
+ pp feed
153
+ ```
154
+
155
+ resulting in:
156
+
157
+ ``` ruby
158
+ [{"comment"=>"This is a podcast feed. You can add...",
159
+ "title"=>"The Record",
160
+ "home_page_url"=>"http://therecord.co/",
161
+ "feed_url"=>"http://therecord.co/feed.txt"
162
+ },
163
+ [
164
+ [{"id"=>"http://therecord.co/chris-parrish",
165
+ "title"=>"Special #1 - Chris Parrish",
166
+ "url"=>"http://therecord.co/chris-parrish",
167
+ "summary"=>"Brent interviews Chris Parrish, co-host of The Record and...",
168
+ "published"=>2014-05-09 23:04:00 +0200,
169
+ "attachments"=>
170
+ [{"url"=>"http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a",
171
+ "mime_type"=>"audio/x-m4a",
172
+ "size_in_bytes"=>89970236,
173
+ "duration_in_seconds"=>6629}]
174
+ },
175
+ "Chris has worked at [Adobe][1] and as a founder of Rogue Sheep..."
176
+ ]
177
+ ]
178
+ ]
179
+ ```
180
+
181
+ and use like:
182
+
183
+ ``` ruby
184
+ feed_metadata = feed[0]
185
+ feed_items = feed[1]
186
+
187
+ feed_metadata[ 'title' ]
188
+ # => "The Record"
189
+ feed_metadata[ 'feed_url' ]
190
+ # => "http://therecord.co/feed.txt"
191
+
192
+ item = feed_items[0] # or feed[1][0]
193
+ item_metadata = item[0] # or feed[1][0][0]
194
+ item_content = item[1] # or feed[1][0][1]
195
+
196
+ item_metadata[ 'title' ]
197
+ # => "Special #1 - Chris Parrish"
198
+ item_metadata[ 'url' ]
199
+ # => "http://therecord.co/chris-parrish
200
+ item_content
201
+ # => "Chris has worked at [Adobe][1] and as a founder of Rogue Sheep..."
202
+ ...
203
+ ```
14
204
 
15
205
 
16
206
  ## License
@@ -16,6 +16,7 @@ require 'logutils'
16
16
 
17
17
  # our own code
18
18
  require 'feedtxt/version' # let it always go first
19
+ require 'feedtxt/parser'
19
20
 
20
21
 
21
22
 
@@ -0,0 +1,91 @@
1
+ # encoding: utf-8
2
+
3
+ module Feedtxt
4
+
5
+
6
+ class Parser
7
+
8
+ include LogUtils::Logging
9
+
10
+
11
+ ### convenience class/factory method
12
+ def self.parse( text, opts={} )
13
+ self.new( text ).parse
14
+ end
15
+
16
+ ### Note: lets keep/use same API as RSS::Parser for now
17
+ def initialize( text )
18
+ @text = text
19
+ end
20
+
21
+
22
+
23
+ FEED_BEGIN_RX = %r{^\|>>>$}
24
+ FEED_END_RX = %r{^<<<\|$}
25
+ FEED_NEXT_RX = %r{^</>$} ## pass 1: split/break up blocks
26
+ FEED_META_RX = %r{^---$} ## pass 2: break up item into metadata and content block
27
+
28
+
29
+ def parse
30
+
31
+ ## find start marker e.g. |>>>
32
+ ## todo: use regex - allow three or more >>>>>> or <<<<<<
33
+ ## todo: allow spaces before and after
34
+
35
+
36
+ ## todo/fix:
37
+ ## use index-like finder return posbeg and posend!!!
38
+ ## regex is not fixed length/width; we need to know the length
39
+ ## check what is the best way? use regex match or something???
40
+
41
+ posbeg = @text.index( FEED_BEGIN_RX )
42
+ if posbeg.nil?
43
+ ## nothing found return empty array for now; return nil - why? why not?
44
+ puts "warn !!! no begin marker found e.g. |>>>"
45
+ return []
46
+ end
47
+
48
+ posend = @text.index( FEED_END_RX, posbeg )
49
+ if posend.nil?
50
+ ## nothing found return empty array for now; return nil - why? why not?
51
+ puts "warn !!! no end marker found e.g. <<<|"
52
+ return []
53
+ end
54
+
55
+ ## cutoff - get text between begin and end marker
56
+ buf = @text[ posbeg+4...posend ].strip
57
+ ## pp buf
58
+
59
+ ####
60
+ ## pass 1: split blocks by </>
61
+ ### todo: allow <<<</>>>>
62
+
63
+ blocks = buf.split( FEED_NEXT_RX )
64
+ ## pp blocks
65
+
66
+ ## 1st block is feed meta data
67
+ block1st = blocks.shift ## get/remove 1st block from blocks
68
+ feed_metadata = YAML.load( block1st.strip )
69
+
70
+ feed_items = []
71
+ blocks.each do |block|
72
+ ### note: do NOT use split e.g.--- is used by markdown
73
+ ## only search for first --- to split (all others get ignored)
74
+ ## todo: make three dashes --- (3) not hard-coded (allow more)
75
+ posmeta = block.index( FEED_META_RX )
76
+ item = []
77
+ item[0] = block[0...posmeta].strip
78
+ item[1] = block[posmeta+3..-1].strip
79
+
80
+ item_metadata = YAML.load( item[0] )
81
+ item_content = item[1]
82
+
83
+ feed_items << [item_metadata, item_content]
84
+ end
85
+
86
+ [ feed_metadata, feed_items ]
87
+ end # method parse
88
+
89
+
90
+ end # class Parser
91
+ end # module Feedtxt
@@ -3,8 +3,8 @@
3
3
  module Feedtxt
4
4
 
5
5
  MAJOR = 0
6
- MINOR = 0
7
- PATCH = 1
6
+ MINOR = 1
7
+ PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -0,0 +1,15 @@
1
+ |>>>
2
+ title: "My Example Feed"
3
+ home_page_url: "https://example.org/"
4
+ feed_url: "https://example.org/feed.txt"
5
+ </>
6
+ id: "2"
7
+ url: "https://example.org/second-item"
8
+ ---
9
+ This is a second item.
10
+ </>
11
+ id: "1"
12
+ url: "https://example.org/initial-post"
13
+ ---
14
+ Hello, world!
15
+ <<<|
@@ -0,0 +1,26 @@
1
+ |>>>
2
+ comment: "This is a podcast feed. You can add this feed to your podcast client using the following URL: http://therecord.co/feed.json"
3
+ title: "The Record"
4
+ home_page_url: "http://therecord.co/"
5
+ feed_url: "http://therecord.co/feed.txt"
6
+ </>
7
+ id: "http://therecord.co/chris-parrish"
8
+ title: "Special #1 - Chris Parrish"
9
+ url: "http://therecord.co/chris-parrish"
10
+ summary: "Brent interviews Chris Parrish, co-host of The Record and one-half of Aged & Distilled."
11
+ published: 2014-05-09T14:04:00-07:00
12
+ attachments:
13
+ - url: "http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a"
14
+ mime_type: "audio/x-m4a"
15
+ size_in_bytes: 89970236
16
+ duration_in_seconds: 6629
17
+ ---
18
+ Chris has worked at [Adobe][1] and as a founder of Rogue Sheep, which won an Apple Design Award for Postage.
19
+ Chris's new company is Aged & Distilled with Guy English - which shipped [Napkin](2),
20
+ a Mac app for visual collaboration. Chris is also the co-host of The Record.
21
+ He lives on [Bainbridge Island][3], a quick ferry ride from Seattle.
22
+
23
+ [1]: http://adobe.com/
24
+ [2]: http://aged-and-distilled.com/napkin/
25
+ [3]: http://www.ci.bainbridge-isl.wa.us/
26
+ <<<|
@@ -0,0 +1,23 @@
1
+ ## $:.unshift(File.dirname(__FILE__))
2
+
3
+
4
+ ## minitest setup
5
+
6
+ require 'minitest/autorun'
7
+
8
+ require 'logutils'
9
+ require 'textutils'
10
+
11
+
12
+ ## our own code
13
+ require 'feedtxt'
14
+
15
+
16
+
17
+ LogUtils::Logger.root.level = :debug
18
+
19
+
20
+ def read_text( name )
21
+ text = File.read( "#{Feedtxt.root}/test/feeds/#{name}.txt" )
22
+ text
23
+ end
@@ -0,0 +1,19 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_version.rb
4
+ # or better
5
+ # rake test
6
+
7
+ require 'helper'
8
+
9
+
10
+ class TestVersion < MiniTest::Test
11
+
12
+ def test_version
13
+
14
+ puts "Feedtxt: #{Feedtxt::VERSION}"
15
+
16
+ assert true
17
+ end
18
+
19
+ end # class TestVersion
@@ -0,0 +1,72 @@
1
+ ###
2
+ # to run use
3
+ # ruby -I ./lib -I ./test test/test_yaml.rb
4
+ # or better
5
+ # rake test
6
+
7
+ require 'helper'
8
+
9
+
10
+ class TestYaml < MiniTest::Test
11
+
12
+ def test_example
13
+
14
+ text = read_text( 'spec/example.yaml' )
15
+ pp text
16
+
17
+ feed = Feedtxt::Parser.parse( text )
18
+ pp feed
19
+
20
+ ## pp feed.to_json
21
+
22
+ exp = [
23
+ {"title"=>"My Example Feed",
24
+ "home_page_url"=>"https://example.org/",
25
+ "feed_url"=>"https://example.org/feed.txt"},
26
+ [[
27
+ {"id"=>"2", "url"=>"https://example.org/second-item"},
28
+ "This is a second item."
29
+ ],
30
+ [
31
+ {"id"=>"1", "url"=>"https://example.org/initial-post"},
32
+ "Hello, world!"
33
+ ]]]
34
+
35
+
36
+ assert_equal exp, feed
37
+ end
38
+
39
+ def test_podcast
40
+
41
+ text = read_text( 'spec/podcast.yaml' )
42
+ pp text
43
+
44
+ feed = Feedtxt::Parser.parse( text )
45
+ pp feed
46
+
47
+ ## pp feed.to_json
48
+
49
+ exp =[{"comment"=>
50
+ "This is a podcast feed. You can add this feed to your podcast client using the following URL: http://therecord.co/feed.json",
51
+ "title"=>"The Record",
52
+ "home_page_url"=>"http://therecord.co/",
53
+ "feed_url"=>"http://therecord.co/feed.txt"},
54
+ [[{"id"=>"http://therecord.co/chris-parrish",
55
+ "title"=>"Special #1 - Chris Parrish",
56
+ "url"=>"http://therecord.co/chris-parrish",
57
+ "summary"=>
58
+ "Brent interviews Chris Parrish, co-host of The Record and one-half of Aged & Distilled.",
59
+ "published"=>DateTime.new( 2014, 5, 9, 23, 4, 0, '+02'),
60
+ "attachments"=>
61
+ [{"url"=>
62
+ "http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a",
63
+ "mime_type"=>"audio/x-m4a",
64
+ "size_in_bytes"=>89970236,
65
+ "duration_in_seconds"=>6629}]},
66
+ "Chris has worked at [Adobe][1] and as a founder of Rogue Sheep, which won an Apple Design Award for Postage.\nChris's new company is Aged & Distilled with Guy English - which shipped [Napkin](2),\na Mac app for visual collaboration. Chris is also the co-host of The Record.\nHe lives on [Bainbridge Island][3], a quick ferry ride from Seattle.\n\n[1]: http://adobe.com/\n[2]: http://aged-and-distilled.com/napkin/\n[3]: http://www.ci.bainbridge-isl.wa.us/"]]]
67
+
68
+ assert_equal exp, feed
69
+ end
70
+
71
+
72
+ end # class TestYaml
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feedtxt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
@@ -53,7 +53,13 @@ files:
53
53
  - README.md
54
54
  - Rakefile
55
55
  - lib/feedtxt.rb
56
+ - lib/feedtxt/parser.rb
56
57
  - lib/feedtxt/version.rb
58
+ - test/feeds/spec/example.yaml.txt
59
+ - test/feeds/spec/podcast.yaml.txt
60
+ - test/helper.rb
61
+ - test/test_version.rb
62
+ - test/test_yaml.rb
57
63
  homepage: https://github.com/feedtxt/feedtxt
58
64
  licenses:
59
65
  - Public Domain