feedtools-cache-yaml 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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