feedtools-cache-yaml 0.0.2

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.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ +++ 0.0.2 2007-05-06
2
+
3
+ + 1 major enhancement:
4
+ + Initial release
data/INSTALL.txt ADDED
@@ -0,0 +1,15 @@
1
+ INSTALLATION for FeedTools::Cache::YAML
2
+ ==============================
3
+
4
+ Requirements:
5
+ - Ruby version 1.8.x
6
+ - FeedTools version 0.2.2 or later
7
+
8
+ Installation:
9
+ $ ruby setup.rb config
10
+ $ ruby setup.rb setup
11
+ # ruby setup.rb install
12
+
13
+ or
14
+
15
+ # gem install feedtools-cache-yaml
data/Manifest.txt ADDED
@@ -0,0 +1,13 @@
1
+ History.txt
2
+ INSTALL.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ TODO
7
+ TUTORIAL.txt
8
+ lib/feedtools-cache-yaml.rb
9
+ lib/feedtools/cache/yaml.rb
10
+ lib/feedtools/cache/yaml/version.rb
11
+ setup.rb
12
+ test/test_feedtools-cache-yaml.rb
13
+ test/test_helper.rb
data/README.txt ADDED
@@ -0,0 +1,19 @@
1
+ README for FeedTools::Cache::YAML
2
+ ==============================
3
+
4
+ What is:
5
+ FeedTools::Cache::YAML provides YAML file cache capability for FeedTools.
6
+
7
+ Requirements:
8
+ - ruby-1.8.x: http://www.ruby-lang.org/
9
+ - FeedTools: http://rubyforge.org/projects/feedtools/
10
+ - 0.2.2 or later
11
+
12
+ Installation:
13
+ see INSTALL.*
14
+
15
+ Documentations:
16
+ see rdoc
17
+
18
+ License:
19
+ Ruby's
data/Rakefile ADDED
@@ -0,0 +1,84 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'feedtools', 'cache', 'yaml', 'version')
13
+
14
+ AUTHOR = 'date'
15
+ EMAIL = "itacchi@gmail.com"
16
+ DESCRIPTION = "YAML cache plugin for FeedTools"
17
+ GEM_NAME = 'feedtools-cache-yaml'
18
+ RUBYFORGE_PROJECT = 'feedtools-cache'
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
21
+
22
+ NAME = "FeedTools::Cache::YAML"
23
+ REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
+ VERS = FeedTools::Cache::YAML::VERSION::STRING + (REV ? ".#{REV}" : "")
25
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
26
+ RDOC_OPTS = ['--quiet', '--title', 'FeedTools::Cache::YAML documentation',
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source"]
31
+
32
+ class Hoe
33
+ def extra_deps
34
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
35
+ end
36
+ end
37
+
38
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
39
+ p.author = AUTHOR
40
+ p.description = DESCRIPTION
41
+ p.email = EMAIL
42
+ p.summary = DESCRIPTION
43
+ p.url = HOMEPATH
44
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
45
+ p.test_globs = ["test/**/test_*.rb"]
46
+ p.clean_globs = CLEAN
47
+
48
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
49
+ p.extra_deps = [ ['feedtools', '>= 0.2.2'] ]
50
+ end
51
+
52
+
53
+ desc 'Generate website files'
54
+ task :website_generate do
55
+ Dir['website/**/*.txt'].each do |txt|
56
+ sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
57
+ end
58
+ end
59
+
60
+ desc 'Upload website files to rubyforge'
61
+ task :website_upload do
62
+ config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
63
+ host = "#{config["username"]}@rubyforge.org"
64
+ remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/"
65
+ local_dir = 'website'
66
+ sh %{rsync -av #{local_dir}/ #{host}:#{remote_dir}}
67
+ end
68
+
69
+ desc 'Generate and upload website files'
70
+ task :website => [:website_generate, :website_upload]
71
+
72
+ desc 'Release the website and new gem version'
73
+ task :deploy => [:check_version, :website, :release]
74
+
75
+ task :check_version do
76
+ unless ENV['VERSION']
77
+ puts 'Must pass a VERSION=x.y.z release version'
78
+ exit
79
+ end
80
+ unless ENV['VERSION'] == VERS
81
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
82
+ exit
83
+ end
84
+ end
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ * tests
2
+ * implement some methods
3
+ * refact code
4
+ * examples
5
+ * find_by_id and id generation
data/TUTORIAL.txt ADDED
@@ -0,0 +1,28 @@
1
+ TUTORIAL for FeedTools::Cache::YAML
2
+ ==============================
3
+
4
+ 1. install ruby
5
+ At first, you install Ruby the Object-Oriented Scripting Language.
6
+ Go http://www.ruby-lang.org/en/.
7
+
8
+ 2. install feedtools
9
+ Just type `gem install feedtools'.
10
+
11
+ 3. install FeedTools::Cache::YAML
12
+ See INSTALL.txt
13
+
14
+ 4. write code
15
+ require 'feedtools'
16
+ require 'feedtools-cache-yaml'
17
+ # or if you manually installed , require 'feedtools/cache/yaml'
18
+
19
+ # set cache configuration
20
+ FeedTools.configurations[:feed_cache] = FeedTools::Cache::YAML
21
+
22
+ # fetch from the web
23
+ feed = FeedTools::Feed.open('http://dontstopmusic.no-ip.org/diary/index.rdf')
24
+ p feed.live? #=> true
25
+
26
+ # use the cache
27
+ feed = FeedTools::Feed.open('http://dontstopmusic.no-ip.org/diary/index.rdf')
28
+ p feed.live? #=> false
@@ -0,0 +1 @@
1
+ Dir[File.join(File.dirname(__FILE__), 'feedtools/**/*.rb')].sort.each { |lib| require lib }
@@ -0,0 +1,303 @@
1
+ require 'yaml'
2
+ require 'etc'
3
+ require 'digest/sha1'
4
+ require 'fileutils'
5
+
6
+ module FeedTools
7
+ module Cache #:nodoc:
8
+ class YAML
9
+ end
10
+ end
11
+ end
12
+
13
+ class FeedTools::Cache::YAML
14
+ # helper class
15
+ class StorePath #:nodoc:
16
+ def initialize(type, key, base_store_path = nil)
17
+ base_store_path ||= defalut_base_store_path
18
+ @path = File.join(base_store_path, type, hash_path(key))
19
+ end
20
+ attr_reader :path
21
+
22
+ def to_s
23
+ @path.to_s
24
+ end
25
+
26
+ private
27
+ def defalut_base_store_path
28
+ ENV['FEEDTOOLS_CACHE_YAML_PATH'] ||
29
+ File.join(Etc.getpwuid.dir, '.feedtools', 'cache', 'yaml')
30
+ end
31
+
32
+ def hash_path(key)
33
+ first_level = key[0].chr
34
+ second_level = key[0..1]
35
+ third_level = key[0..2]
36
+ File.join(first_level, second_level, third_level, key)
37
+ end
38
+ end
39
+
40
+ class IDStorePath < StorePath #:nodoc:
41
+ def initialize(key, base_store_path = nil)
42
+ super('id', key, base_store_path)
43
+ end
44
+ end
45
+
46
+ class URLStorePath < StorePath #:nodoc:
47
+ def initialize(key, base_store_path = nil)
48
+ super('url', key, base_store_path)
49
+ end
50
+ end
51
+
52
+ class NullLogger #:nodoc:
53
+ def method_missing(message, *args)
54
+ end
55
+ end
56
+ end
57
+
58
+ # Caching plugin for FeedTools. Cache feched feed as yaml file.
59
+ #
60
+ # === usage
61
+ # Simple to use, require library and set configuration.
62
+ # require 'feedtools-cache-yaml'
63
+ # or installed by manual
64
+ # require 'feedtools/cache/yaml'
65
+ #
66
+ # FeedTools.configurations[:feed_cache] = FeedTools::Cache::YAML
67
+ #
68
+ # === configuration
69
+ # You can change cache store path.
70
+ # The priority order is the following.
71
+ # 1. path attribute of FeedTools::Cache::YAML
72
+ # 2. FEEDTOOLS_CACHE_YAML_PATH environment variable
73
+ # 3. default ~/.feedtools/cache/yaml
74
+ class FeedTools::Cache::YAML
75
+ # Required by FeedTools.
76
+ ATTRIBUTES = %w(
77
+ id href title link
78
+ feed_data feed_data_type
79
+ http_headers last_retrieved
80
+ )
81
+
82
+ @@path = nil
83
+
84
+ # Required by FeedTools.
85
+ # Find a cached feed by its key.
86
+ # === Parameters
87
+ # [id] <code>String</code>: primary key.
88
+ #
89
+ # === Returns
90
+ # [cached feed] <code>FeedTools::Cache::YAML</code>: cached feed. If not found, returns <code>nil</code>.
91
+ def self.find_by_id(id)
92
+ create_from_yaml_cache(path_by_id(id))
93
+ end
94
+
95
+ # Required by FeedTools.
96
+ # Find a cached feed by its url.
97
+ # === Parameters
98
+ # [url] <code>String</code>: feed url.
99
+ #
100
+ # === Returns
101
+ # [cached feed] <code>FeedTools::Cache::YAML</code>: cached feed. If not found, returns <code>nil</code>.
102
+ def self.find_by_href(url)
103
+ create_from_yaml_cache(path_by_url(url))
104
+ end
105
+
106
+ # Required by FeedTools.
107
+ # TODO: implement this.
108
+ def self.initialize_cache
109
+ # nothing
110
+ end
111
+
112
+ # Required by FeedTools.
113
+ # TODO: implement this.
114
+ #
115
+ # === Returns
116
+ # Currently always true.
117
+ def self.connected?
118
+ true
119
+ end
120
+
121
+ # Required by FeedTools.
122
+ # TODO: implement this.
123
+ #
124
+ # === Returns
125
+ # Currently always true.
126
+ def self.set_up_correctly?
127
+ true
128
+ end
129
+
130
+ # Configured cache store path
131
+ #
132
+ # === Returns
133
+ # [path] <code>String</code> : cache store path you configured. Use FEEDTOOLS_CACHE_YAML_PATH environment variable or default if <code>nil</code>.
134
+ def self.path
135
+ @@path
136
+ end
137
+
138
+ # Set cache store path
139
+ #
140
+ # === Parameters
141
+ # [path] <code>String</code> : set cache store path. You can override default path.
142
+ def self.path=(path)
143
+ @@path = path
144
+ end
145
+
146
+ # Create a FeedTools::Cache::YAML instance object.
147
+ #
148
+ # === Returns
149
+ # [cached feed] <code>FeedTools::Cache::YAML</code> : cached feed.
150
+ def initialize
151
+ @yaml = {}
152
+ @new_record = true
153
+ @logger = NullLogger.new
154
+ end
155
+ # debug logger. Set logger object if use need. Logger output messages when log level is DEBUG.
156
+ attr_accessor :logger
157
+
158
+ # Required by FeedTools.
159
+ #
160
+ # Returns whether it is a new object.
161
+ #
162
+ # === Returns
163
+ # [boolean] <code>true/false</code> : returns <code>true</code> if the instance has not been saved yet. Returns false if the instance loaded from cache.
164
+ def new_record?
165
+ @new_record
166
+ end
167
+
168
+ # Required by FeedTools.
169
+ #
170
+ # Primary key.
171
+ #
172
+ # === Returns
173
+ # [id] <code>String</code> : primary key.
174
+ def id
175
+ @yaml['id']
176
+ end
177
+
178
+ # Required by FeedTools.
179
+ #
180
+ # Set primary key.
181
+ #
182
+ # === Parameters
183
+ # [id] <code>String</code> : primary key.
184
+ def id=(id)
185
+ @yaml['id'] = id
186
+ end
187
+
188
+ # Required by FeedTools.
189
+ #
190
+ # Save new or update instance.
191
+ def save
192
+ unless id
193
+ save_new_cache
194
+ else
195
+ update_cache
196
+ end
197
+ end
198
+
199
+ # Load data from yaml file.
200
+ #
201
+ # === Parameters
202
+ # [path] <code>String</code> : yaml file path.
203
+ def load_cache(path)
204
+ begin
205
+ @yaml = YAML.load_file(path)
206
+ @new_record = false
207
+ debug "load cache: #{path}"
208
+ self
209
+ rescue
210
+ nil
211
+ end
212
+ end
213
+
214
+ def method_missing(message, *args) #:nodoc:
215
+ begin
216
+ if matched = /^(.*)=$/.match(message.to_s)
217
+ set_attribute(matched[1], args.first)
218
+ else
219
+ get_attribute(message.to_s)
220
+ end
221
+ rescue NameError
222
+ raise NoMethodError, "undefined method `#{message}' for #{self.to_s}"
223
+ end
224
+ end
225
+
226
+ private
227
+ def self.create_from_yaml_cache(path)
228
+ self.new.load_cache(path)
229
+ end
230
+
231
+ def self.path_by_id(id)
232
+ IDStorePath.new(id, @@path).path
233
+ end
234
+
235
+ def self.path_by_url(url)
236
+ partical_cache_path = url_to_partical_cache_path(url)
237
+ URLStorePath.new(partical_cache_path, @@path).path
238
+ end
239
+
240
+ def self.url_to_partical_cache_path(url)
241
+ uri = URI.parse(url).normalize
242
+ url = uri.host
243
+ url += ":#{uri.port}" unless uri.port == 80
244
+ url += uri.request_uri
245
+ end
246
+
247
+ def path_by_id
248
+ self.class.path_by_id(id)
249
+ end
250
+
251
+ def path_by_url
252
+ self.class.path_by_url(href)
253
+ end
254
+
255
+ def save_new_cache
256
+ debug "save new cache: #{href}"
257
+ self.id = generate_id
258
+ write_cache(path_by_url)
259
+ FileUtils.mkdir_p(File.dirname(path_by_id))
260
+ FileUtils.symlink(path_by_url, path_by_id)
261
+ end
262
+
263
+ def update_cache
264
+ debug "update cache: #{href}"
265
+ write_cache(path_by_url)
266
+ end
267
+
268
+ def write_cache(file_name)
269
+ debug " write cache: #{file_name}"
270
+ FileUtils.mkdir_p(File.dirname(file_name))
271
+ File.open(file_name, 'w') do |f|
272
+ f.print @yaml.to_yaml
273
+ end
274
+ end
275
+
276
+ def generate_id
277
+ Digest::SHA1.hexdigest('%0x' % object_id + Time.now.to_i.to_s)
278
+ end
279
+
280
+ def get_attribute(attribute)
281
+ if ATTRIBUTES.include?(attribute)
282
+ @yaml[attribute]
283
+ else
284
+ raise NameError
285
+ end
286
+ end
287
+
288
+ def set_attribute(attribute, value)
289
+ if ATTRIBUTES.include?(attribute)
290
+ @yaml[attribute] = value
291
+ else
292
+ raise NameError
293
+ end
294
+ end
295
+
296
+ def debug(message)
297
+ message = "[#{self.class}] #{message}"
298
+ if $DEBUG
299
+ STDERR.puts message
300
+ @logger.debug message
301
+ end
302
+ end
303
+ end