flannel 0.1.5 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- :minor: 1
3
- :patch: 5
2
+ :minor: 2
3
+ :patch: 1
4
4
  :major: 0
5
5
  :build:
data/flannel.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{flannel}
8
- s.version = "0.1.5"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jamal Hansen"]
12
- s.date = %q{2010-01-10}
12
+ s.date = %q{2010-01-14}
13
13
  s.email = %q{jamal.hansen@gmail.com}
14
14
  s.executables = ["quilt-it~", "quilt-it"]
15
15
  s.extra_rdoc_files = [
@@ -50,14 +50,17 @@ Gem::Specification.new do |s|
50
50
  "features/wiki_links.feature",
51
51
  "flannel.gemspec",
52
52
  "lib/flannel.rb",
53
+ "lib/flannel/cache_location_does_not_exist_error.rb",
53
54
  "lib/flannel/cutting_board.rb",
54
55
  "lib/flannel/feed_parser.rb",
56
+ "lib/flannel/file_cache.rb",
55
57
  "lib/flannel/shears.rb",
56
58
  "lib/flannel/square.rb",
57
59
  "lib/flannel/stripe.rb",
58
60
  "lib/flannel/wrappable.rb",
59
61
  "test/cutting_board_test.rb",
60
62
  "test/feed_parser_test.rb",
63
+ "test/file_cache_test.rb",
61
64
  "test/flannel_test.rb",
62
65
  "test/shears_test.rb",
63
66
  "test/square_test.rb",
@@ -72,6 +75,7 @@ Gem::Specification.new do |s|
72
75
  s.summary = %q{A soft comfortable worn in markup language for Ruby}
73
76
  s.test_files = [
74
77
  "test/test_helper.rb",
78
+ "test/file_cache_test.rb",
75
79
  "test/stripe_test.rb",
76
80
  "test/cutting_board_test.rb",
77
81
  "test/feed_parser_test.rb",
data/lib/flannel.rb CHANGED
@@ -4,6 +4,7 @@ require 'flannel/square'
4
4
  require 'flannel/shears'
5
5
  require 'flannel/stripe'
6
6
  require 'flannel/feed_parser'
7
+ require 'flannel/file_cache'
7
8
 
8
9
  module Flannel
9
10
  def self.quilt markup, params={}
@@ -0,0 +1,4 @@
1
+ module Flannel
2
+ class Flannel::CacheLocationDoesNotExistError < RuntimeError
3
+ end
4
+ end
@@ -1,14 +1,12 @@
1
- #require 'shears'
2
-
3
1
 
4
2
  module Flannel
5
3
  class CuttingBoard
6
4
  def initialize params={}
7
- @wiki_link= params[:wiki_link]
5
+ @params = params
8
6
  end
9
7
 
10
8
  def cut markup
11
- shears = Flannel::Shears.new
9
+ shears = Flannel::Shears.new @params
12
10
  squares = shears.cut markup
13
11
  squares.map { |square| square.to_h }.join("\n\n")
14
12
  end
@@ -3,6 +3,10 @@ require 'open-uri'
3
3
 
4
4
  module Flannel
5
5
  class FeedParser
6
+ def initialize params={}
7
+ @cache = params[:cache] if params.has_key?(:cache)
8
+ end
9
+
6
10
  def sub_feeds(url)
7
11
  url = format_url(url)
8
12
  get_news(url)
@@ -15,7 +19,10 @@ module Flannel
15
19
  end
16
20
 
17
21
  def get_document url
18
- open(url)
22
+ doc = @cache.retrieve(url) if @cache
23
+ doc = open(url) unless doc
24
+ @cache.save url, doc if @cache
25
+ doc
19
26
  end
20
27
 
21
28
  def format_item(link, title)
@@ -24,19 +31,16 @@ module Flannel
24
31
 
25
32
  def get_news url
26
33
  item_string = ""
27
- #begin
28
- doc = Hpricot.XML(get_document(url))
29
34
 
30
- (doc/"item").each do |item|
31
- link = (item/"link").inner_html
32
- title = (item/"title").inner_html
33
- item_string << format_item(link, title)
34
- end
35
-
36
- item_string
37
- #rescue
38
- # "Error retrieving data."
39
- #end
35
+ doc = Hpricot.XML(get_document(url))
36
+
37
+ (doc/"item").each do |item|
38
+ link = (item/"link").inner_html
39
+ title = (item/"title").inner_html
40
+ item_string << format_item(link, title)
41
+ end
42
+
43
+ item_string
40
44
  end
41
45
  end
42
46
  end
@@ -0,0 +1,52 @@
1
+ require 'flannel/cache_location_does_not_exist_error'
2
+ require 'digest/md5'
3
+
4
+ module Flannel
5
+ class FileCache
6
+ attr_reader :seconds_till_expiration
7
+
8
+ def initialize cache_location, seconds_till_expiration=3600
9
+ unless File.exists?(cache_location) && File.directory?(cache_location)
10
+ raise CacheLocationDoesNotExistError
11
+ end
12
+
13
+ @cache_location = cache_location
14
+ @seconds_till_expiration = seconds_till_expiration
15
+ end
16
+
17
+ def save url, data
18
+ key = generate_key url
19
+ File.open(File.join(@cache_location, key), 'w') {|f| f.write(data) }
20
+ end
21
+
22
+ def retrieve url
23
+ key = generate_key url
24
+ file = File.join(@cache_location, key)
25
+
26
+ return nil unless File.exists?(file)
27
+
28
+ saved_at = File.mtime(file)
29
+ expires_at = saved_at + @seconds_till_expiration
30
+
31
+ if Time.now >= expires_at
32
+ File.delete(file)
33
+ return nil
34
+ end
35
+
36
+ read file
37
+ end
38
+
39
+ private
40
+ def generate_key url
41
+ Digest::MD5.hexdigest(url)
42
+ end
43
+
44
+ def read file
45
+ data = ''
46
+ File.open(file, "r") { |f|
47
+ data = f.read
48
+ }
49
+ data
50
+ end
51
+ end
52
+ end
@@ -3,6 +3,10 @@
3
3
 
4
4
  module Flannel
5
5
  class Shears
6
+ def initialize params={}
7
+ @params = params
8
+ end
9
+
6
10
  def cut markup
7
11
  @squares = []
8
12
  @square = Flannel::Square.new
@@ -23,7 +27,7 @@ module Flannel
23
27
 
24
28
  def shift_square
25
29
  @squares << @square unless @square.blank?
26
- @square = Flannel::Square.new
30
+ @square = Flannel::Square.new @params
27
31
  end
28
32
 
29
33
  def need_new_square? line
@@ -9,11 +9,13 @@ module Flannel
9
9
  @tags ={:preformatted => "pre", :feed => "ul", :list => "ul", :header_1 => "h1", :header_2 => "h2", :header_3 => "h3", :header_4 => "h4", :header_5 => "h5", :header_6 => "h6"}
10
10
  @stripes = []
11
11
  @style = :paragraph
12
+ @params = params
12
13
  end
13
14
 
14
15
  def << text
15
16
  text = text.strip unless @style == :preformatted
16
- @stripes << Flannel::Stripe.stitch(text, :style=>@style)
17
+ @params[:style] = @style
18
+ @stripes << Flannel::Stripe.stitch(text, @params.dup)
17
19
  end
18
20
 
19
21
  def to_s
@@ -1,5 +1,3 @@
1
- #require 'wrappable'
2
- #require 'feed_parser'
3
1
 
4
2
  module Flannel
5
3
  class Stripe
@@ -12,22 +10,19 @@ module Flannel
12
10
 
13
11
  def initialize weave="", params={}
14
12
  @weave = weave
15
- @wiki_link = params[:wiki_link]
16
- @style = params[:style]
13
+ @params = params
17
14
  end
18
15
 
19
16
  def wiki_link topic
20
- if @wiki_link
21
- @wiki_link.call(permalink topic)
17
+ if @params[:wiki_link]
18
+ @params[:wiki_link].call(permalink topic)
22
19
  else
23
20
  permalink topic[1..-2]
24
21
  end
25
22
  end
26
23
 
27
24
  def permalink topic
28
- require 'iconv'
29
- # thanks to ismasan http://snippets.dzone.com/posts/show/4457
30
- (Iconv.new('US-ASCII//TRANSLIT', 'utf-8').iconv topic).gsub(/[^\w\s\-]/,'').gsub(/[^\w]|[\_]/,' ').split.join('-').downcase
25
+ topic.gsub(%r{[^/\w\s\-]},'').gsub(%r{[^\w/]|[\_]},' ').split.join('-').downcase
31
26
  end
32
27
 
33
28
  def empty?
@@ -36,12 +31,17 @@ module Flannel
36
31
 
37
32
  def build_wiki_links
38
33
  return @weave if preformatted
39
- @weave.gsub(/-\w(.*?)\w>/) { |match| %{<a href="#{wiki_link match}">#{match[1..-2]}</a>}}
34
+ @weave.gsub(/-\w(.*?)\w>/) { |match| %{<a href="#{wiki_link match}">#{format_link_display(match)}</a>}}
35
+ end
36
+
37
+ def format_link_display text
38
+ text[1..-2].split("/").last
40
39
  end
41
40
 
42
41
  def to_h
42
+
43
43
  if feed
44
- parser = Flannel::FeedParser.new
44
+ parser = Flannel::FeedParser.new @params
45
45
  parser.sub_feeds @weave
46
46
  else
47
47
  text = build_wiki_links
@@ -50,15 +50,15 @@ module Flannel
50
50
  end
51
51
 
52
52
  def preformatted
53
- @style == :preformatted
53
+ @params[:style] == :preformatted
54
54
  end
55
55
 
56
56
  def list
57
- @style == :list
57
+ @params[:style] == :list
58
58
  end
59
59
 
60
60
  def feed
61
- @style == :feed
61
+ @params[:style] == :feed
62
62
  end
63
63
 
64
64
  def markup text
@@ -2,6 +2,20 @@ require 'test_helper'
2
2
  require 'mocha'
3
3
 
4
4
  class FeedTest < Test::Unit::TestCase
5
+ context "wiring" do
6
+ setup do
7
+ @rubyyot = File.read(File.join(File.dirname(__FILE__), "..", "features", "fixtures", "rubyyot.rss"))
8
+ @expected_rubyyot = "<ul><li>\n <a href='http://blog.rubyyot"
9
+ end
10
+
11
+ should "be set up for feeds" do
12
+ feed = "http://blog.rubyyot.com/tag/rubyyot/feed/rss"
13
+ body = Flannel.quilt "& #{feed}"
14
+
15
+ assert_equal(@expected_rubyyot, body[0..40])
16
+ end
17
+ end
18
+
5
19
  context "bootstrapping test" do
6
20
  setup do
7
21
  @devlicious = File.read(File.join(File.dirname(__FILE__), "..", "features", "fixtures", "devlicious.rss"))
@@ -0,0 +1,114 @@
1
+ require 'test_helper'
2
+ require 'mocha'
3
+
4
+ class FileCacheTest < Test::Unit::TestCase
5
+ context "Creating File cache" do
6
+ should "require a location" do
7
+ begin
8
+ cache = Flannel::FileCache.new
9
+ assert_fail "should have raised ArgumentError"
10
+ rescue ArgumentError => e
11
+ assert true
12
+ end
13
+ end
14
+
15
+ should "require a valid location" do
16
+ begin
17
+ cache = Flannel::FileCache.new "foo/bar"
18
+ assert_fail "should have raised Flannel::CacheLocationDoesNotExistError"
19
+ rescue Flannel::CacheLocationDoesNotExistError => e
20
+ assert true
21
+ end
22
+ end
23
+ end
24
+
25
+ context "Generating a key" do
26
+ setup do
27
+ @cache = Flannel::FileCache.new "tmp"
28
+ end
29
+
30
+ should "be private" do
31
+ begin
32
+ key = @cache.generate_key "http://example.com"
33
+ assert_fail "generate_key should be private"
34
+ rescue NoMethodError => e
35
+ assert true
36
+ end
37
+ end
38
+
39
+ should "make MD5 hash" do
40
+ url = "http://example.com"
41
+ key = @cache.send :generate_key, url
42
+ assert_equal(Digest::MD5.hexdigest(url), key)
43
+ end
44
+ end
45
+
46
+ context "saving a file" do
47
+ setup do
48
+ clear_dir "tmp"
49
+ @url = "http://example.com"
50
+ @cache_location = "tmp"
51
+ @cache = Flannel::FileCache.new @cache_location
52
+ @key = @cache.send :generate_key, @url
53
+ end
54
+
55
+ should "save data to a file" do
56
+ @cache.save @url, "some data"
57
+ assert File.exists?(File.join(@cache_location, @key)), "cache did not save data"
58
+ end
59
+ end
60
+
61
+ context "retrieving data" do
62
+ setup do
63
+ clear_dir "tmp"
64
+ @url = "http://example.com"
65
+ @cache_location = "tmp"
66
+ @data = "this is some data"
67
+ @cache = Flannel::FileCache.new @cache_location
68
+ @key = @cache.send :generate_key, @url
69
+ end
70
+
71
+ should "should return the saved data" do
72
+ @cache.save @url, @data
73
+ data = @cache.retrieve @url
74
+ assert_equal @data, data
75
+ end
76
+
77
+ should "should return nil if there is no data" do
78
+ data = @cache.retrieve @url
79
+ assert_nil data
80
+ end
81
+ end
82
+
83
+ context "expiration" do
84
+ setup do
85
+ clear_dir "tmp"
86
+ @url = "http://example.com"
87
+ @cache_location = "tmp"
88
+ @data = "this is some data"
89
+ end
90
+
91
+ should "accept an expiration time" do
92
+ cache = Flannel::FileCache.new @cache_location, 1
93
+ assert_equal 1, cache.seconds_till_expiration
94
+ end
95
+
96
+ should "default expiration to 1 hour" do
97
+ cache = Flannel::FileCache.new @cache_location
98
+ assert_equal 3600, cache.seconds_till_expiration
99
+ end
100
+
101
+ should "miss when content is expired" do
102
+ cache = Flannel::FileCache.new @cache_location, 1
103
+ cache.save @url, @data
104
+ sleep 1
105
+ assert_nil(cache.retrieve(@url))
106
+ end
107
+
108
+ should "hit when content is not expired" do
109
+ cache = Flannel::FileCache.new @cache_location, 2
110
+ cache.save @url, @data
111
+ assert_equal(@data, cache.retrieve(@url))
112
+ end
113
+ end
114
+ end
data/test/square_test.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'test_helper'
2
- require 'stripe'
3
2
 
4
3
  class SquareTest < Test::Unit::TestCase
5
4
  context "basic behavior" do
data/test/stripe_test.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'test_helper'
2
- #require 'stripe'
2
+ require 'flannel/stripe'
3
3
 
4
4
  class StripeTest < Test::Unit::TestCase
5
5
  context "basic operations" do
@@ -23,13 +23,12 @@ class StripeTest < Test::Unit::TestCase
23
23
  context "building wiki links" do
24
24
  setup do
25
25
  wiki_link = lambda { |keyword| "http://www.example.com/foo/#{keyword}"}
26
- @stripe = Flannel::Stripe.stitch "the -roof is on fire>", :wiki_link =>
27
- wiki_link
26
+ @stripe = Flannel::Stripe.stitch "the -roof is on fire>", :wiki_link => wiki_link
28
27
  end
29
28
 
30
29
  should "build wiki links based on a lambda" do
31
30
  assert_equal "http://www.example.com/foo/cheese",
32
- @stripe.wiki_link("cheese")
31
+ @stripe.wiki_link("-cheese>")
33
32
  end
34
33
 
35
34
  should "find and replace wiki link markup" do
@@ -39,13 +38,26 @@ wiki_link
39
38
 
40
39
  should "permalink topics when making wiki links" do
41
40
  assert_equal "http://www.example.com/foo/cheese-tastes-good",
42
- @stripe.wiki_link("cheese tastes good")
41
+ @stripe.wiki_link("-cheese tastes good>")
43
42
  end
44
43
 
45
44
  should "not be greedy in matching" do
46
45
  stripe = Flannel::Stripe.stitch("a -foo> and a -bar>.")
47
- assert_equal 'a <a href="foo">foo</a> and a <a href="bar">bar</a>.',
48
- stripe.build_wiki_links
46
+ assert_equal 'a <a href="foo">foo</a> and a <a href="bar">bar</a>.', stripe.build_wiki_links
47
+ end
48
+ end
49
+
50
+ context "subdirectories" do
51
+ setup do
52
+ @stripe = Flannel::Stripe.stitch "I think it -cheese/tastes good>."
53
+ end
54
+
55
+ should "handle subdirectories" do
56
+ assert_equal "cheese/tastes-good", @stripe.wiki_link("-cheese/tastes good>")
57
+ end
58
+
59
+ should "not display directory info" do
60
+ assert_equal 'I think it <a href="cheese/tastes-good">tastes good</a>.', @stripe.build_wiki_links
49
61
  end
50
62
  end
51
63
 
data/test/test_helper.rb CHANGED
@@ -1,10 +1,27 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
3
  require 'shoulda'
4
+ require 'fileutils'
4
5
 
5
6
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
7
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
8
  require 'flannel'
8
9
 
9
10
  class Test::Unit::TestCase
11
+ def assert_fail message
12
+ assert false, message
13
+ end
14
+
15
+ def clear_dir dirname
16
+ Dir.foreach(dirname) do |f|
17
+ path = File.join(dirname, f)
18
+ if f == '.' or f == '..' then
19
+ next
20
+ elsif
21
+ File.directory?(path) then FileUtils.rm_rf(path)
22
+ else
23
+ FileUtils.rm( path )
24
+ end
25
+ end
26
+ end
10
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flannel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamal Hansen
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-10 00:00:00 -06:00
12
+ date: 2010-01-14 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -76,14 +76,17 @@ files:
76
76
  - features/wiki_links.feature
77
77
  - flannel.gemspec
78
78
  - lib/flannel.rb
79
+ - lib/flannel/cache_location_does_not_exist_error.rb
79
80
  - lib/flannel/cutting_board.rb
80
81
  - lib/flannel/feed_parser.rb
82
+ - lib/flannel/file_cache.rb
81
83
  - lib/flannel/shears.rb
82
84
  - lib/flannel/square.rb
83
85
  - lib/flannel/stripe.rb
84
86
  - lib/flannel/wrappable.rb
85
87
  - test/cutting_board_test.rb
86
88
  - test/feed_parser_test.rb
89
+ - test/file_cache_test.rb
87
90
  - test/flannel_test.rb
88
91
  - test/shears_test.rb
89
92
  - test/square_test.rb
@@ -119,6 +122,7 @@ specification_version: 3
119
122
  summary: A soft comfortable worn in markup language for Ruby
120
123
  test_files:
121
124
  - test/test_helper.rb
125
+ - test/file_cache_test.rb
122
126
  - test/stripe_test.rb
123
127
  - test/cutting_board_test.rb
124
128
  - test/feed_parser_test.rb