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 +2 -2
- data/flannel.gemspec +6 -2
- data/lib/flannel.rb +1 -0
- data/lib/flannel/cache_location_does_not_exist_error.rb +4 -0
- data/lib/flannel/cutting_board.rb +2 -4
- data/lib/flannel/feed_parser.rb +17 -13
- data/lib/flannel/file_cache.rb +52 -0
- data/lib/flannel/shears.rb +5 -1
- data/lib/flannel/square.rb +3 -1
- data/lib/flannel/stripe.rb +14 -14
- data/test/feed_parser_test.rb +14 -0
- data/test/file_cache_test.rb +114 -0
- data/test/square_test.rb +0 -1
- data/test/stripe_test.rb +19 -7
- data/test/test_helper.rb +17 -0
- metadata +6 -2
data/VERSION.yml
CHANGED
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
|
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-
|
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
@@ -1,14 +1,12 @@
|
|
1
|
-
#require 'shears'
|
2
|
-
|
3
1
|
|
4
2
|
module Flannel
|
5
3
|
class CuttingBoard
|
6
4
|
def initialize params={}
|
7
|
-
@
|
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
|
data/lib/flannel/feed_parser.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
data/lib/flannel/shears.rb
CHANGED
@@ -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
|
data/lib/flannel/square.rb
CHANGED
@@ -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
|
-
@
|
17
|
+
@params[:style] = @style
|
18
|
+
@stripes << Flannel::Stripe.stitch(text, @params.dup)
|
17
19
|
end
|
18
20
|
|
19
21
|
def to_s
|
data/lib/flannel/stripe.rb
CHANGED
@@ -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
|
-
@
|
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
|
-
|
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
|
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
|
data/test/feed_parser_test.rb
CHANGED
@@ -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
data/test/stripe_test.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
|
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
|
-
|
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
|
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-
|
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
|