feedtxt 0.0.1 → 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.
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