zsff 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +6 -0
  3. data/README.txt +52 -0
  4. data/Rakefile +18 -0
  5. data/lib/zsff.rb +112 -0
  6. data/test/test_zsff.rb +113 -0
  7. metadata +69 -0
@@ -0,0 +1,4 @@
1
+ == 1.0.0 / 2008-01-15
2
+
3
+ * Initial release. Contains parse function, which includes validation.
4
+
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/zsff.rb
6
+ test/test_zsff.rb
@@ -0,0 +1,52 @@
1
+ zsff
2
+ by Erik Peterson
3
+ http://subwindow.com/zsff
4
+
5
+ == DESCRIPTION:
6
+
7
+ A parser/validator for ZSFF feeds.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ Right now, only one function: parse. This does the validation and parsing all in one step. This is intended to be used by any reader (who would take care of what links have been read, etc).
12
+
13
+ == SYNOPSIS:
14
+
15
+ results = Zsff.parse(url)
16
+ results[:errors] #Any errors encountered while parsing
17
+ results[:warnings] #Any warnings encountered while parsing
18
+ results[:attrs] #A hash for the author, title, etc information from the feed
19
+ results[:links] #List of links in the feed
20
+
21
+ == REQUIREMENTS:
22
+
23
+ None
24
+
25
+ == INSTALL:
26
+
27
+ sudo gem install, anything else
28
+
29
+ == LICENSE:
30
+
31
+ (The MIT License)
32
+
33
+ Copyright (c) 2008 Erik Peterson
34
+
35
+ Permission is hereby granted, free of charge, to any person obtaining
36
+ a copy of this software and associated documentation files (the
37
+ 'Software'), to deal in the Software without restriction, including
38
+ without limitation the rights to use, copy, modify, merge, publish,
39
+ distribute, sublicense, and/or sell copies of the Software, and to
40
+ permit persons to whom the Software is furnished to do so, subject to
41
+ the following conditions:
42
+
43
+ The above copyright notice and this permission notice shall be
44
+ included in all copies or substantial portions of the Software.
45
+
46
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
47
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
48
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
49
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
50
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
51
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
52
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,18 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/zsff.rb'
6
+
7
+ Hoe.new('zsff', Zsff::VERSION) do |p|
8
+ p.rubyforge_name = 'zsff'
9
+ p.author = 'Erik Peterson'
10
+ p.email = 'erik@subwindow.com'
11
+ p.summary = 'A parser/validator for ZSFF feeds'
12
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
13
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
14
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
+ p.remote_rdoc_dir = ''
16
+ end
17
+
18
+ # vim: syntax=Ruby
@@ -0,0 +1,112 @@
1
+ # Author:: Erik Peterson (mailto:erik@subwindow.com)
2
+ # Copyright:: Copyright (c) 2008 Erik Peterson
3
+ # License:: MIT
4
+
5
+ # This class parses and validates a Zsff feed by URL or a raw feed string
6
+
7
+ require 'net/http'
8
+ require 'open-uri'
9
+ class Zsff
10
+ VERSION = '1.0.0'
11
+ attr_accessor :url
12
+ attr_accessor :contents
13
+ attr_accessor :errors
14
+ attr_accessor :warnings
15
+ attr_accessor :version
16
+ attr_accessor :author
17
+ attr_accessor :title
18
+ attr_accessor :site
19
+ attr_accessor :subtitle
20
+ attr_accessor :copyright
21
+ attr_accessor :content_type
22
+ attr_accessor :links
23
+
24
+ def initialize(attributes = nil)
25
+ self.attributes = attributes unless attributes.nil?
26
+ @errors = []
27
+ @warnings = []
28
+ @links = []
29
+ end
30
+
31
+ def self.parse_url(url)
32
+ parser = self.new(:url => url)
33
+ parser.parse
34
+ return parser
35
+ end
36
+
37
+ def self.parse_contents(contents)
38
+ parser = self.new(:contents => contents)
39
+ parser.parse
40
+ return parser
41
+ end
42
+
43
+ def attributes=(attributes)
44
+ attributes.each do |k, v|
45
+ send(k.to_s + "=", v)
46
+ end
47
+ end
48
+
49
+ def parse
50
+ if self.url
51
+ begin
52
+ uri = URI.parse(url)
53
+ @contents = Net::HTTP.get(uri)
54
+ rescue
55
+ @errors.push("Invalid URL")
56
+ return false
57
+ end
58
+ end
59
+
60
+ parse_contents
61
+
62
+ return @errors.size == 0
63
+ end
64
+
65
+ def parse_contents
66
+ begin
67
+ raw = @contents.split(/\n\n/)
68
+ @errors.push("Must have two line breaks between Attributes section and Links section") and return if raw.size < 2
69
+
70
+ @version = raw.first.split(/\n/).first
71
+ raw.first.split(/\n/)[1..-1].each do |attribute|
72
+ parts = attribute.split(":")
73
+ next if parts.size < 2
74
+ self.send(parts.first.downcase.gsub(/-/, "_") + "=", parts[1..-1].join(":").strip)
75
+ end
76
+
77
+ error_if :version, @version.nil? || @version.match(/ZSFF 1\.[0-9]/).nil?
78
+ error_if :author, @author.nil? || @author == ""
79
+ error_if :title, @title.nil? || @title == ""
80
+ error_if :site, @site.nil? || @site == ""
81
+ warn_if :site, @site.nil? || !is_valid_url?(@site)
82
+ warn_if :subtitle, @subtitle.nil? || @subtitle == ""
83
+ warn_if :copyright, @copyright.nil? || @copyright == ""
84
+ error_if :content_type, @content_type.nil? || @content_type.match(/.*\/.*/).nil?
85
+
86
+ items = raw.last.split(/\n/)
87
+ items.each do |item|
88
+ warnings.push("Item '#{item}' does not appear to be a valid URL") and next unless is_valid_url?(item)
89
+ unless item.match(/\.page$/)
90
+ content = items.select{|i|item.gsub(/\.(php|php3|asp|aspx|htm|cfm|html)$/, "") + ".page" == i}.first
91
+ @links.push({:link => item, :content => content})
92
+ end
93
+ end
94
+ #rescue
95
+ # @errors.push("Cannot parse ZSFF file")
96
+ end
97
+
98
+ end
99
+
100
+ private
101
+ def error_if(attribute, condition)
102
+ @errors.push("Invalid #{attribute.to_s.capitalize} declaration.") if condition
103
+ end
104
+
105
+ def warn_if(attribute, condition)
106
+ @warnings.push("#{attribute.to_s.capitalize} may be invalid.") if condition
107
+ end
108
+
109
+ def is_valid_url?(url)
110
+ !url.match(/(^$)|(^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$)/ix).nil?
111
+ end
112
+ end
@@ -0,0 +1,113 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/zsff'
3
+ class ZsffTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_parse_url
6
+ parser = Zsff.new(:url => "http://subwindow.com/articles.zsff")
7
+
8
+ assert_equal true, parser.parse
9
+ assert_equal [], parser.errors
10
+ assert_equal [], parser.warnings
11
+ assert_equal "ZSFF 1.0", parser.version
12
+ assert_equal "Erik Peterson", parser.author
13
+ assert_equal "subWindow Blog", parser.title
14
+ assert_equal "http://www.subwindow.com/", parser.site
15
+ assert_equal "Just another crappy programmer's blog", parser.subtitle
16
+ assert_equal "2008", parser.copyright
17
+ assert_equal "text/plain", parser.content_type
18
+ assert parser.links.size > 2
19
+ end
20
+
21
+ def test_static_parse_url
22
+ parser = Zsff::parse_url("http://subwindow.com/articles.zsff")
23
+
24
+ assert_equal [], parser.errors
25
+ assert_equal [], parser.warnings
26
+ end
27
+
28
+ def test_static_parse_contents
29
+ zsff = <<ZSFFSTR
30
+ ZSFF 1.0
31
+ Author: Erik Peterson
32
+ Title: subWindow Blog
33
+ Site: http://www.subwindow.com/
34
+ Subtitle: Just another crappy programmer's blog
35
+ Copyright: 2008
36
+ Content-type: text/plain
37
+
38
+ http://subwindow.com/articles/3.page
39
+ http://subwindow.com/articles/3.html
40
+ http://subwindow.com/articles/2
41
+ http://subwindow.com/articles/2.page
42
+ http://subwindow.com/articles/1
43
+ ZSFFSTR
44
+
45
+ parser = Zsff::parse_contents(zsff)
46
+
47
+ assert_equal [], parser.errors
48
+ assert_equal [], parser.warnings
49
+ end
50
+
51
+ def test_parse_string
52
+ zsff = <<ZSFFSTR
53
+ ZSFF 1.0
54
+ Author: Erik Peterson
55
+ Title: subWindow Blog
56
+ Site: http://www.subwindow.com/
57
+ Subtitle: Just another crappy programmer's blog
58
+ Copyright: 2008
59
+ Content-type: text/plain
60
+
61
+ http://subwindow.com/articles/3.page
62
+ http://subwindow.com/articles/3.html
63
+ http://subwindow.com/articles/2
64
+ http://subwindow.com/articles/2.page
65
+ http://subwindow.com/articles/1
66
+ ZSFFSTR
67
+
68
+ parser = Zsff.new(:contents => zsff)
69
+ assert_equal true, parser.parse
70
+ assert_equal [], parser.errors
71
+ assert_equal [], parser.warnings
72
+ assert_equal "ZSFF 1.0", parser.version
73
+ assert_equal "Erik Peterson", parser.author
74
+ assert_equal "subWindow Blog", parser.title
75
+ assert_equal "http://www.subwindow.com/", parser.site
76
+ assert_equal "Just another crappy programmer's blog", parser.subtitle
77
+ assert_equal "2008", parser.copyright
78
+ assert_equal "text/plain", parser.content_type
79
+ assert_equal 3, parser.links.size
80
+ assert_equal "http://subwindow.com/articles/3.html", parser.links[0][:link]
81
+ assert_equal "http://subwindow.com/articles/3.page", parser.links[0][:content]
82
+ assert_equal "http://subwindow.com/articles/2", parser.links[1][:link]
83
+ assert_equal "http://subwindow.com/articles/2.page", parser.links[1][:content]
84
+ assert_equal "http://subwindow.com/articles/1", parser.links[2][:link]
85
+ assert_equal nil, parser.links[2][:content]
86
+ end
87
+
88
+ def test_fail_parse
89
+ zsff = "THIS IS NOT A VALID ZSFF FEED"
90
+
91
+ parser = Zsff.new(:url => zsff)
92
+ assert_equal false, parser.parse
93
+ assert parser.errors.include?("Invalid URL")
94
+ end
95
+
96
+ def test_fail_links
97
+ zsff = <<ZSFFSTR
98
+ ZSFF 1.0
99
+ Author: Erik Peterson
100
+ Title: subWindow Blog
101
+ Site: http://www.subwindow.com/
102
+ Subtitle: Just another crappy programmer's blog
103
+ Copyright: 2008
104
+ Content-type: text/plain
105
+ http://subwindow.com/articles/3
106
+ http://subwindow.com/articles/2
107
+ ZSFFSTR
108
+
109
+ parser = Zsff.new(:contents => zsff)
110
+ assert_equal false, parser.parse
111
+ assert parser.errors.include?("Must have two line breaks between Attributes section and Links section")
112
+ end
113
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zsff
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Erik Peterson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-01-17 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.4.0
23
+ version:
24
+ description: "== FEATURES/PROBLEMS: Right now, only one function: parse. This does the validation and parsing all in one step. This is intended to be used by any reader (who would take care of what links have been read, etc). == SYNOPSIS: results = Zsff.parse(url) results[:errors] #Any errors encountered while parsing results[:warnings] #Any warnings encountered while parsing results[:attrs] #A hash for the author, title, etc information from the feed results[:links] #List of links in the feed == REQUIREMENTS:"
25
+ email: erik@subwindow.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - History.txt
32
+ - Manifest.txt
33
+ - README.txt
34
+ files:
35
+ - History.txt
36
+ - Manifest.txt
37
+ - README.txt
38
+ - Rakefile
39
+ - lib/zsff.rb
40
+ - test/test_zsff.rb
41
+ has_rdoc: true
42
+ homepage: " by Erik Peterson"
43
+ post_install_message:
44
+ rdoc_options:
45
+ - --main
46
+ - README.txt
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project: zsff
64
+ rubygems_version: 1.0.1
65
+ signing_key:
66
+ specification_version: 2
67
+ summary: A parser/validator for ZSFF feeds
68
+ test_files:
69
+ - test/test_zsff.rb