concord_cacher 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'spec/rake/spectask'
6
6
  require './lib/concord_cacher.rb'
7
7
 
8
8
  require 'echoe'
9
- Echoe.new('concord_cacher', '0.0.5') do |p|
9
+ Echoe.new('concord_cacher', '0.1.0') do |p|
10
10
  p.description = "concord_cacher provides support for locally caching a resource and all referenced resources in multiple different ways. It is intended for using with other Concord Consortium projects and not necessarily for outside projects."
11
11
  p.summary = "Support for locally caching a resource and all referenced resources in multiple different ways"
12
12
  p.url = "http://github.com/psndcsrv/concord_cacher"
@@ -2,12 +2,12 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{concord_cacher}
5
- s.version = "0.0.5"
5
+ s.version = "0.1.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Aaron Unger"]
9
9
  s.cert_chain = ["/Users/aunger/gem-public_cert.pem"]
10
- s.date = %q{2010-03-26}
10
+ s.date = %q{2010-04-05}
11
11
  s.description = %q{concord_cacher provides support for locally caching a resource and all referenced resources in multiple different ways. It is intended for using with other Concord Consortium projects and not necessarily for outside projects.}
12
12
  s.email = %q{aunger @nospam@ concord.org}
13
13
  s.extra_rdoc_files = ["README.textile", "lib/concord_cacher.rb", "lib/concord/cacher.rb", "lib/concord/diy_local_cacher.rb", "lib/concord/java_proxy_cacher.rb"]
@@ -3,240 +3,65 @@ class ::Concord::Cacher
3
3
  require 'open-uri'
4
4
  require 'cgi'
5
5
  require 'rexml/document'
6
-
7
- DEBUG = false
8
6
 
9
- # scan for anything that matches (http://[^'"]+)
10
- URL_REGEX = /(http[s]?:\/\/[^'"]+)/i
11
- # the imageBytes can be referenced by a OTImage object
12
- SRC_REGEX = /(?:src|href|imageBytes|authoredDataURL)[ ]?=[ ]?['"]([^'"]+)/i
13
- NLOGO_REGEX = /import-drawing "([^"]+)"/i
14
- MW_REGEX = /<resource>(.*?mml)<\/resource>/
15
- ALWAYS_SKIP_REGEX = /^(mailto|jres)/i
16
- RECURSE_ONCE_REGEX = /html$/i # (resourceFile =~ /otml$/ || resourceFile =~ /html/)
17
- RECURSE_FOREVER_REGEX = /(otml|cml|mml|nlogo)$/i
18
-
19
- attr_reader :otml_url, :cache_dir, :uuid, :errors
7
+ attr_reader :main_resource, :errors
20
8
 
21
9
  def initialize(opts = {})
22
- defaults = {:rewrite_urls => false, :verbose => false, :cache_headers => true, :create_map => true}
23
- opts = defaults.merge(opts)
24
10
  raise ArgumentError, "Must include :url, and :cache_dir in the options hash." unless opts[:url] && opts[:cache_dir]
25
- @rewrite_urls = opts[:rewrite_urls]
26
- @cache_dir = opts[:cache_dir]
27
- @verbose = opts[:verbose]
28
- @cache_headers = opts[:cache_headers]
29
- @create_map = opts[:create_map]
30
- url = opts[:url]
31
- @filename = File.basename(url, ".otml")
32
- @content = ""
33
- open(url) do |r|
34
- @content_headers = r.respond_to?("meta") ? r.meta : {}
35
- @content_headers['_http_version'] = "HTTP/1.1 #{r.respond_to?("status") ? r.status.join(" ") : "200 OK"}"
36
- @content = r.read
37
- end
38
- @uuid = generate_uuid
39
- if (URI.parse(url).kind_of?(URI::HTTP))
40
- @otml_url = url
11
+
12
+ @main_resource = Concord::Resource.new
13
+ @main_resource.url = opts.delete(:url)
14
+ @main_resource.cache_dir = opts.delete(:cache_dir)
15
+ @main_resource.extras = opts
16
+ @main_resource.uri = URI.parse(@main_resource.url)
17
+ @main_resource.load
18
+
19
+ calculate_main_file_absolute_url
20
+ end
21
+
22
+ def calculate_main_file_absolute_url
23
+ orig_uri = @main_resource.uri
24
+ codebase = ''
25
+ if ((orig_uri.kind_of?(URI::HTTP) || orig_uri.kind_of?(URI::HTTPS)) && orig_uri.absolute?)
26
+ @main_resource.uri = orig_uri
41
27
  else
42
28
  # this probably references something on the local fs. we need to extract the document's codebase, if there is ony
43
- if @content =~ /<otrunk[^>]+codebase[ ]?=[ ]?['"]([^'"]+)/
44
- # @otml_url = "#{$1}/#{@filename}.otml"
45
- @otml_url = "#{$1}"
46
- @content.sub!(/codebase[ ]?=[ ]?['"][^'"]+['"]/,"")
29
+ if @main_resource.content =~ /<otrunk[^>]+codebase[ ]?=[ ]?['"]([^'"]+)/
30
+ codebase = "#{$1}"
31
+ @main_resource.content.sub!(/codebase[ ]?=[ ]?['"][^'"]+['"]/,"")
32
+ codebase.sub!(/\/$/,'')
33
+ codebase = "#{codebase}/#{@main_resource.remote_filename}" unless codebase =~ /otml$/
34
+ @main_resource.uri = URI.parse(codebase)
47
35
  else
48
- @otml_url = url
36
+ @main_resource.uri = orig_uri
49
37
  end
50
38
  end
51
39
 
52
- @otml_url.sub!(/[^\/]+$/,"")
53
-
54
- @errors = {}
55
-
56
- @url_to_hash_map = {}
57
- end
40
+ if @main_resource.uri.relative?
41
+ # we need the main URI to be absolute so that we can use it to resolve references
42
+ file_root = URI.parse("file:///")
43
+ @main_resource.uri = file_root.merge(@main_resource.uri)
44
+ end
45
+ end
58
46
 
59
47
  def cache
60
48
  copy_otml_to_local_cache
61
-
62
- write_url_to_hash_map if @create_map
63
- end
64
-
65
- def generate_main_filename
66
- raise NotImplementedError, "You should be using this class through one of its sub-classes!"
49
+ print_errors if ::Concord::Resource.verbose
67
50
  end
68
-
69
- def generate_filename(opts = {})
70
- raise NotImplementedError, "You should be using this class through one of its sub-classes!"
71
- end
72
-
73
- def generate_uuid
74
- raise NotImplementedError, "You should be using this class through one of its sub-classes!"
75
- end
76
51
 
77
52
  def copy_otml_to_local_cache
78
53
  # save the file in the local server directories
79
- filename = generate_main_filename
80
-
81
- # open the otml file from the specified url or grab the embedded content
82
- uri = URI.parse(@otml_url)
83
- if uri.relative?
84
- # we need the main URI to be absolute so that we can use it to resolve references
85
- file_root = URI.parse("file:///")
86
- uri = file_root.merge(uri)
87
- end
88
- @content = parse_file("#{@cache_dir}#{@filename}", @content, @cache_dir, uri, true)
89
-
90
- write_resource(@cache_dir + filename, @content)
91
- write_property_map(@cache_dir + filename + ".hdrs", @content_headers) if @cache_headers
92
- @url_to_hash_map[@otml_url + @filename + ".otml"] = filename
93
-
94
- puts "\nThere were #{@errors.length} artifacts with errors.\n" if @verbose
95
- @errors.each do |k,v|
96
- puts "In #{k}:" if @verbose
97
- v.uniq.each do |e|
98
- puts " #{e}" if @verbose
99
- end
100
- end
101
- end
102
-
103
- def parse_file(orig_filename, content, cache_dir, parent_url, recurse)
104
- short_filename = /\/([^\/]+)$/.match(orig_filename)[1]
105
- print "\n#{short_filename}: " if @verbose
106
- processed_lines = []
107
- lines = content.split("\n")
108
- lines.each do |line|
109
- line = CGI.unescapeHTML(line)
110
- match_indexes = []
111
- while (
112
- ( match = (
113
- URL_REGEX.match(line) ||
114
- SRC_REGEX.match(line) ||
115
- (/.*\.nlogo/.match(short_filename) ? NLOGO_REGEX.match(line) : nil) ||
116
- (/.*\.(:?cml|mml)/.match(short_filename) ? MW_REGEX.match(line) : nil)
117
- )
118
- ) && (! match_indexes.include?(match.begin(1)))
119
- )
120
- print "\nMatched url: #{match[1]}: " if DEBUG
121
- match_indexes << match.begin(1)
122
- # get the resource from that location, save it locally
123
- # match_url = match[1].gsub(/\s+/,"").gsub(/[\?\#&;=\+,<>"\{\}\|\\\^\[\]].*$/,"")
124
- match_url = match[1]
125
- # puts("pre: #{match[1]}, post: #{match_url}") if DEBUG
126
- begin
127
- resource_url = URI.parse(CGI.unescapeHTML(match_url))
128
- rescue
129
- @errors[parent_url] ||= []
130
- @errors[parent_url] << "Bad URL: '#{CGI.unescapeHTML(match_url)}', skipping."
131
- print 'x' if @verbose
132
- next
133
- end
134
- if (resource_url.relative?)
135
- # relative URL's need to have their parent document's codebase appended before trying to download
136
- resource_url = parent_url.merge(resource_url.to_s)
137
- end
138
- resourceFile = match_url
139
- resourceFile = resourceFile.gsub(/http[s]?:\/\//,"")
140
- resourceFile = resourceFile.gsub(/\/$/,"")
141
-
142
- if (resourceFile.length < 1) || ALWAYS_SKIP_REGEX.match(resourceFile)
143
- print "S" if @verbose
144
- next
145
- end
146
-
147
- begin
148
- resource_content = ""
149
- resource_headers = {}
150
- open(resource_url.scheme == 'file' ? resource_url.path : resource_url.to_s) do |r|
151
- resource_headers = r.respond_to?("meta") ? r.meta : {}
152
- resource_headers['_http_version'] = "HTTP/1.1 #{r.respond_to?("status") ? r.status.join(" ") : "200 OK"}"
153
- resource_content = r.read
154
- end
155
- rescue OpenURI::HTTPError, Timeout::Error, Errno::ENOENT => e
156
- @errors[parent_url] ||= []
157
- @errors[parent_url] << "Problem getting file: #{resource_url.to_s}, Error: #{e}"
158
- print 'X' if @verbose
159
- next
160
- end
161
-
162
- localFile = generate_filename(:content => resource_content, :url => resource_url)
163
- @url_to_hash_map[resource_url.to_s] = localFile
164
- line.sub!(match_url.to_s,localFile.to_s) if @rewrite_urls
165
-
166
-
167
- # skip downloading already existing files.
168
- # because we're working with sha1 hashes we can be reasonably certain the content is a complete match
169
- if File.exists?(cache_dir + localFile)
170
- print 's' if @verbose
171
- else
172
- # if it's an otml/html file, we should parse it too (only one level down)
173
- if (recurse && (RECURSE_ONCE_REGEX.match(resourceFile) || RECURSE_FOREVER_REGEX.match(resourceFile)))
174
- puts "recursively parsing '#{resource_url.to_s}'" if DEBUG
175
- recurse_further = false
176
- if RECURSE_FOREVER_REGEX.match(resourceFile)
177
- recurse_further = true
178
- end
179
- begin
180
- write_resource(cache_dir + localFile, "") # touch the file so that we avoid recursion
181
- resource_content = parse_file(cache_dir + resourceFile, resource_content, cache_dir, resource_url, recurse_further)
182
- rescue OpenURI::HTTPError => e
183
- @errors[parent_url] ||= []
184
- @errors[parent_url] << "Problem getting or writing file: #{resource_url.to_s}, Error: #{e}"
185
- print 'X' if @verbose
186
- next
187
- end
188
- end
189
- begin
190
- write_resource(cache_dir + localFile, resource_content)
191
- write_property_map(cache_dir + localFile + ".hdrs", resource_headers) if @cache_headers
192
- print "." if @verbose
193
- rescue Exception => e
194
- @errors[parent_url] ||= []
195
- @errors[parent_url] << "Problem getting or writing file: #{resource_url.to_s}, Error: #{e}"
196
- print 'X' if @verbose
197
- end
198
- end
199
- end
200
- processed_lines << line
201
- end
202
-
203
- print ".\n" if @verbose
204
- return processed_lines.join("\n")
205
- end
206
-
207
- def write_resource(filename, content)
208
- f = File.new(filename, "w")
209
- f.write(content)
210
- f.flush
211
- f.close
54
+ @main_resource.should_recurse = true
55
+ @main_resource.process
56
+ @main_resource.write
212
57
  end
213
58
 
214
- def write_url_to_hash_map
215
- load_existing_map if (File.exists?(@cache_dir + "url_map.xml"))
216
- write_property_map(@cache_dir + "url_map.xml", @url_to_hash_map)
217
- end
218
-
219
- def write_property_map(filename, hash_map)
220
- File.open(filename, "w") do |f|
221
- f.write('<?xml version="1.0" encoding="UTF-8"?>' + "\n")
222
- f.write('<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">' + "\n")
223
- f.write('<properties>' + "\n")
224
- hash_map.each do |url,hash|
225
- f.write("<entry key='#{CGI.escapeHTML(url)}'>#{hash}</entry>\n")
226
- end
227
- f.write('</properties>' + "\n")
228
- f.flush
229
- end
230
- end
231
-
232
- def load_existing_map
233
- map_content = ::REXML::Document.new(File.new(@cache_dir + "url_map.xml")).root
234
- map_content.elements.each("entry") do |entry|
235
- k = entry.attributes["key"]
236
- if ! (@url_to_hash_map.include? k)
237
- val = entry.text
238
- @url_to_hash_map[k] = val
239
- # puts "Adding previously defined url: #{k} => #{val}" if DEBUG
59
+ def print_errors
60
+ puts "\nThere were #{@errors.length} artifacts with errors.\n"
61
+ ::Concord::Resource.errors.each do |k,v|
62
+ puts "In #{k}:"
63
+ v.uniq.each do |e|
64
+ puts " #{e}"
240
65
  end
241
66
  end
242
67
  end
@@ -1,35 +1,15 @@
1
+ require 'concord/cacher'
2
+
1
3
  class ::Concord::DiyLocalCacher < ::Concord::Cacher
2
- require 'uri'
3
- require 'digest/sha1'
4
- require 'fileutils'
4
+ require 'concord/resource'
5
+ require 'concord/filename_generators/diy_generator'
5
6
 
6
7
  def initialize(opts = {})
7
- raise InvalidArgumentError, "Must include :activity in the options hash." unless opts[:activity]
8
- @activity = opts[:activity]
9
- opts[:cache_headers] ||= false
10
- opts[:create_map] ||= false
11
- opts[:rewrite_urls] ||= true
8
+ raise ::ArgumentError, "Must include :activity in the options hash." unless opts[:activity]
9
+ ::Concord::Resource.cache_headers = false
10
+ ::Concord::Resource.rewrite_urls = true
11
+ ::Concord::Resource.create_map = false
12
+ ::Concord::Resource.filename_generator = ::Concord::FilenameGenerators::DiyGenerator
12
13
  super
13
14
  end
14
-
15
- def generate_main_filename
16
- "#{generate_uuid}.otml"
17
- end
18
-
19
- def generate_uuid
20
- @activity.uuid
21
- end
22
-
23
- def generate_filename(opts = {})
24
- raise InvalidArgumentError, "Must include :url key in opts" unless opts[:url]
25
- raise InvalidArgumentError, ":url value must be an instance of URI" unless opts[:url].kind_of?(::URI)
26
- uri = opts[:url]
27
- uri_path = uri.path.split('/')
28
- uri_path = ["","index.html"] if uri_path.size == 0
29
- uri_path.unshift("") if uri_path.size == 1
30
- file_ext = uri_path[-1].split('.')[-1]
31
- file = ::Digest::SHA1.hexdigest(uri.to_s)
32
- file += ".#{file_ext}" if file_ext
33
- return file
34
- end
35
15
  end
@@ -1,16 +1,40 @@
1
+ require 'concord/cacher'
2
+
1
3
  class ::Concord::JavaProxyCacher < ::Concord::Cacher
2
4
  require 'digest/sha1'
5
+ require 'concord/helper'
6
+ require 'concord/resource'
7
+ require 'concord/filename_generators/java_proxy_generator'
3
8
 
4
- def generate_main_filename
5
- generate_filename(:content => @content)
9
+ include ::Concord::Helper
10
+
11
+ def initialize(opts = {})
12
+ ::Concord::Resource.create_map = true
13
+ ::Concord::Resource.cache_headers = true
14
+ ::Concord::Resource.rewrite_urls = false
15
+ ::Concord::Resource.filename_generator = ::Concord::FilenameGenerators::JavaProxyGenerator
16
+ super
17
+ end
18
+
19
+ def cache
20
+ super
21
+ write_url_to_hash_map
6
22
  end
7
23
 
8
- def generate_uuid
9
- generate_filename(:content => @content)
24
+ def write_url_to_hash_map
25
+ load_existing_map if (File.exists?(@main_resource.cache_dir + "url_map.xml"))
26
+ write_property_map(@main_resource.cache_dir + "url_map.xml", ::Concord::Resource.url_map)
10
27
  end
11
28
 
12
- def generate_filename(opts = {})
13
- raise InvalidArgumentError, "Must include :content key in opts" unless opts[:content]
14
- ::Digest::SHA1.hexdigest(opts[:content])
29
+ def load_existing_map
30
+ map_content = ::REXML::Document.new(File.new(@main_resource.cache_dir + "url_map.xml")).root
31
+ map_content.elements.each("entry") do |entry|
32
+ k = entry.attributes["key"]
33
+ if ! (::Concord::Resource.url_map.include? k)
34
+ val = entry.text
35
+ ::Concord::Resource.url_map[k] = val
36
+ # puts "Adding previously defined url: #{k} => #{val}" if DEBUG
37
+ end
38
+ end
15
39
  end
16
40
  end
@@ -2,7 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  module Concord
5
- require 'concord/cacher'
5
+ require 'concord/filename_generators'
6
6
  require 'concord/diy_local_cacher'
7
7
  require 'concord/java_proxy_cacher'
8
8
  end
@@ -7,7 +7,7 @@
7
7
  <root>
8
8
  <OTText>
9
9
  <!-- Absolute references -->
10
- <a href="http://loops.diy.concord.org/">Visit the Concord Website</a>
10
+ <a href="http://www.concord.org/~aunger/">Visit the Concord Website</a>
11
11
  <img src="http://portal.concord.org/images/icons/chart_bar.png" />
12
12
  <OTBlob imageBytes="http://portal.concord.org/images/icons/chart_pie.png" />
13
13
 
@@ -10,31 +10,20 @@ require 'fileutils'
10
10
 
11
11
  include FileUtils
12
12
 
13
- require 'openssl'
14
- module OpenSSL
15
- module SSL
16
- remove_const :VERIFY_PEER
17
- end
18
- end
19
- OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
20
-
21
13
  SPEC_ROOT = File.expand_path(File.dirname(__FILE__))
22
14
 
23
- $\ = "<br/>\n"
24
-
25
15
  describe 'DIY Local Cacher' do
26
16
  include CacheHelper
27
17
 
28
18
  before(:each) do
29
19
  @klass = Concord::DiyLocalCacher
30
20
  @cache = File.join(SPEC_ROOT, '..', 'tmp','diy_local')
31
- rm_rf(@cache)
32
21
  mkdir_p(@cache)
33
22
  @cache += '/'
34
23
  end
35
24
 
36
25
  after(:each) do
37
- # rm_rf(@cache)
26
+ rm_rf(@cache)
38
27
  end
39
28
 
40
29
  def mockup(file)
@@ -68,7 +57,6 @@ describe 'DIY Local Cacher' do
68
57
  end
69
58
 
70
59
  it 'should create a cached file of the original url' do
71
- url = File.join(SPEC_ROOT,'data','empty.otml')
72
60
  cache('empty.otml', :activity => mockup('empty.otml'))
73
61
  exists?('hash.otml')
74
62
  end
@@ -79,6 +67,13 @@ describe 'DIY Local Cacher' do
79
67
  cache('empty.otml', :activity => mockup('empty.otml'))
80
68
  does_not_exist?("#{expected_filename}.hdrs")
81
69
  end
70
+
71
+ it 'should strip the codebase from the otrunk element' do
72
+ cache('codebase.otml', :activity => mockup('codebase.otml'))
73
+
74
+ file_content = File.read(File.join(@cache,'hash.otml'))
75
+ file_content.should_not match(/<otrunk.*?codebase=.*?>/)
76
+ end
82
77
  end
83
78
 
84
79
  describe 'standard uri syntax' do
@@ -113,7 +108,7 @@ describe 'DIY Local Cacher' do
113
108
  it 'should cache 6 referenced files' do
114
109
  expected_files = []
115
110
  expected_files << 'hash.otml' # element_reference.otml
116
- expected_files << filename_for('http://loops.diy.concord.org/')
111
+ expected_files << filename_for('http://www.concord.org/~aunger/')
117
112
  expected_files << filename_for('http://portal.concord.org/images/icons/chart_bar.png')
118
113
  expected_files << filename_for('http://portal.concord.org/images/icons/chart_pie.png')
119
114
  expected_files << filename_for('resources/text.txt', File.join(SPEC_ROOT,'data','element_reference.otml'))
@@ -131,7 +126,7 @@ describe 'DIY Local Cacher' do
131
126
  it 'should rewrite the urls in the main otml file' do
132
127
  expected_urls = []
133
128
  unexpected_urls = []
134
- unexpected_urls << 'http://loops.diy.concord.org/'
129
+ unexpected_urls << 'http://www.concord.org/~aunger/'
135
130
  unexpected_urls << 'http://portal.concord.org/images/icons/chart_bar.png'
136
131
  unexpected_urls << 'http://portal.concord.org/images/icons/chart_pie.png'
137
132
  unexpected_urls << File.join('resources','text.txt')
@@ -248,18 +243,59 @@ describe 'DIY Local Cacher' do
248
243
  end
249
244
 
250
245
  describe 'embedded nlogo files' do
246
+ it 'should download absolute referenced nlogo files' do
247
+ expected_files = []
248
+ expected_files << filename_for('http://otrunk.concord.org/examples/LOOPS/models/Spaceship.1D.docking.nlogo')
249
+
250
+ cache('nlogo_absolute.otml', :activity => mockup('nlogo_absolute.otml'))
251
+
252
+ expected_files.each do |f|
253
+ exists?(f)
254
+ end
255
+ end
256
+
257
+ it 'should download relative referenced nlogo files' do
258
+ expected_files = []
259
+ expected_files << filename_for('resources/nlogo/SpaceRescue.Practice1.nlogo', File.join(SPEC_ROOT,'data','nlogo_relative.otml'))
260
+
261
+ cache('nlogo_relative.otml', :activity => mockup('nlogo_relative.otml'))
262
+
263
+ expected_files.each do |f|
264
+ exists?(f)
265
+ end
266
+ end
267
+
251
268
  it 'should correctly download resources referenced from within netlogo model files'
252
269
  end
253
270
 
254
271
  describe 'embedded mw files' do
255
- it 'should download absolute referenced cml files'
256
- it 'should download relative referenced cml files'
272
+ it 'should download absolute referenced cml files' do
273
+ expected_files = []
274
+ expected_files << filename_for('http://otrunk.concord.org/examples/LOOPS/models/statesofmatter/statesOfMatterPage1.cml')
275
+
276
+ cache('mw_model_absolute.otml', :activity => mockup('mw_model_absolute.otml'))
277
+
278
+ expected_files.each do |f|
279
+ exists?(f)
280
+ end
281
+ end
282
+
283
+ it 'should download relative referenced cml files' do
284
+ expected_files = []
285
+ expected_files << filename_for('resources/statesofmatter/statesOfMatterPage1.cml', File.join(SPEC_ROOT,'data','mw_model_relative.otml'))
286
+
287
+ cache('mw_model_relative.otml', :activity => mockup('mw_model_relative.otml'))
288
+
289
+ expected_files.each do |f|
290
+ exists?(f)
291
+ end
292
+ end
257
293
 
258
294
  it 'should correctly download mmls referenced from within mw cml files' do
259
295
  expected_files = []
260
296
  expected_files << filename_for('http://otrunk.concord.org/examples/LOOPS/models/statesofmatter/statesOfMatterPage1$0.mml')
261
297
 
262
- cache('mw_model.otml', :activity => mockup('mw_model.otml'), :verbose => true)
298
+ cache('mw_model_absolute.otml', :activity => mockup('mw_model_absolute.otml'))
263
299
 
264
300
  expected_files.each do |f|
265
301
  exists?(f)
@@ -271,7 +307,12 @@ describe 'DIY Local Cacher' do
271
307
  end
272
308
 
273
309
  describe 'never cache' do
274
- it 'should always skip mailto and jres references'
310
+ it 'should always skip some references' do
311
+ url = File.join(SPEC_ROOT,'data','always_skip.otml')
312
+ expected_filename = 'hash.otml'
313
+ cache('always_skip.otml', :activity => mockup('always_skip.otml'))
314
+ cache_size.should == 1
315
+ end
275
316
  end
276
317
 
277
318
  describe 'recursion limits' do
@@ -1,6 +1,6 @@
1
1
  module CacheHelper
2
2
  def cache(file, opts = {})
3
- options = {:url => File.join(SPEC_ROOT,'data',file), :cache_dir => @cache, :verbose => false}.merge(opts)
3
+ options = {:url => File.join(SPEC_ROOT,'data',file), :cache_dir => @cache}.merge(opts)
4
4
  cacher = @klass.new(options)
5
5
  cacher.cache
6
6
  end
@@ -19,4 +19,12 @@ module CacheHelper
19
19
  def cache_size
20
20
  Dir.glob(@cache + "/**/*").select{|f| File.file?(f) }.size
21
21
  end
22
- end
22
+ end
23
+
24
+ require 'openssl'
25
+ module OpenSSL
26
+ module SSL
27
+ remove_const :VERIFY_PEER
28
+ end
29
+ end
30
+ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
@@ -10,14 +10,6 @@ require 'fileutils'
10
10
 
11
11
  include FileUtils
12
12
 
13
- require 'openssl'
14
- module OpenSSL
15
- module SSL
16
- remove_const :VERIFY_PEER
17
- end
18
- end
19
- OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
20
-
21
13
  SPEC_ROOT = File.expand_path(File.dirname(__FILE__))
22
14
 
23
15
 
@@ -74,6 +66,20 @@ describe 'Java Proxy Cacher' do
74
66
  does_not_exist?('8f0ebcb45d7ba71a541d4781329f4a6900c7ee65') # http://portal.concord.org/images/icons/delete.png
75
67
  end
76
68
 
69
+ it 'should handle a url with trailing spaces gracefully' do
70
+ url = File.join(SPEC_ROOT,'data','url_with_space.otml')
71
+ expected_filename = ::Digest::SHA1.hexdigest(File.read(url))
72
+
73
+ lambda {
74
+ cache('url_with_space.otml')
75
+ }.should_not raise_error
76
+
77
+ cache_size.should == 5
78
+
79
+ exists?(expected_filename)
80
+ exists?('d1cea238486aeeba9215d56bf71efc243754fe48') # http://portal.concord.org/images/icons/chart_line.png
81
+ end
82
+
77
83
  it 'should handle an empty url gracefully' do
78
84
  url = File.join(SPEC_ROOT,'data','empty_url.otml')
79
85
  expected_filename = ::Digest::SHA1.hexdigest(File.read(url))
@@ -120,8 +126,8 @@ describe 'Java Proxy Cacher' do
120
126
  describe 'element references syntax' do
121
127
  it 'should cache 6 referenced files' do
122
128
  expected_files = []
123
- expected_files << '9f945e576290efa874842b4ee07ab437d9d94a67' # element_reference.otml
124
- expected_files << 'd9a2565586307e2924c953dfe788154749e93799' # http://loops.diy.concord.org/
129
+ expected_files << '836ba09d9d7288cf735f555e7a9b9b314ad2f6ef' # element_reference.otml
130
+ expected_files << '20e89b62dda582d80e1832050f4998d64c801c03' # http://www.concord.org/~aunger/
125
131
  expected_files << '4e9576a56db3d142113b8905d7aa93e31c9f441b' # http://portal.concord.org/images/icons/chart_bar.png
126
132
  expected_files << '41f082b7e69a399679a47acfdcd7e7a204e49745' # http://portal.concord.org/images/icons/chart_pie.png
127
133
  expected_files << 'cbe7ac86926fd3b8aa8659842a1d8c299d8966a7' # resources/text.txt
@@ -191,7 +197,12 @@ describe 'Java Proxy Cacher' do
191
197
  end
192
198
 
193
199
  describe 'never cache' do
194
- it 'should always skip mailto and jres references'
200
+ it 'should always skip some references' do
201
+ url = File.join(SPEC_ROOT,'data','always_skip.otml')
202
+ expected_filename = ::Digest::SHA1.hexdigest(File.read(url))
203
+ cache('always_skip.otml')
204
+ cache_size.should == 3
205
+ end
195
206
  end
196
207
 
197
208
  describe 'recursion limits' do
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 5
9
- version: 0.0.5
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Aaron Unger
@@ -35,7 +35,7 @@ cert_chain:
35
35
  8kT2T2VF
36
36
  -----END CERTIFICATE-----
37
37
 
38
- date: 2010-03-26 00:00:00 -04:00
38
+ date: 2010-04-05 00:00:00 -04:00
39
39
  default_executable:
40
40
  dependencies: []
41
41
 
metadata.gz.sig CHANGED
Binary file