document_file 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -1,6 +1,6 @@
1
1
  h1. Document File
2
2
 
3
- Document file is an object mapper for plain text documents. The documents look like the ones used in "jekyll":http://github.com/mojombo/jekyll. They consist of a preambel written in YAML (also called YAML front matter), and some content in the format you prefer, e.g. Textile.
3
+ Document file is an object mapper for plain text documents. The documents look like the ones used in "jekyll":http://github.com/mojombo/jekyll, "toto":http://github.com/cloudhead/toto or "Serious":http://github.com/colszowka/serious. They consist of a preambel written in YAML (also called YAML front matter), and some content in the format you prefer, e.g. Textile. This enables you to write documents in your favorite editor and access the content and metadata in your Ruby scripts.
4
4
 
5
5
 
6
6
  h2. Example
@@ -16,19 +16,20 @@ Documents look somehow like this. The part between the @---@s is the YAML front
16
16
 
17
17
  <pre><code>---
18
18
  id: 1
19
- title: The shizzle!
20
- tags: [tag]
19
+ title: Ruby is great
20
+ tags: [programming, software]
21
21
  number_of_foos: 42
22
22
  status: published
23
23
  ---
24
24
 
25
- I like the flowers.
25
+ I like Ruby.
26
26
  </code></pre>
27
27
 
28
28
 
29
- In order to access the documents in the folder, you have to create a document class that inherits from @DocumentFile::Base@. Inside the class definition, you must set the @documents_dir@ class variable in order to tell Document File where to look for files. In our little example, we will do the following:
29
+ In order to access the documents in the folder, you have to create a document class that includes @DocumentFile@. Inside the class definition, you must set the @documents_dir@ class variable in order to tell Document File where to look for files. In our little example, we will do the following and assume the above file has been saved as @./documents/2010-09-13-ruby-stuff.textile@:
30
30
 
31
- <pre><code>class MyDocument
31
+ <pre><code>require 'document_file'
32
+ class MyDocument
32
33
  include DocumentFile
33
34
  self.documents_dir = './documents'
34
35
  end
@@ -39,38 +40,47 @@ h2. Available functionality
39
40
 
40
41
  h3. Dynamic finders
41
42
 
42
- <pre><code>doc = MyDocument.find_by_title("The shizzle!") # => returns the document
43
- doc = MyDocument.find_by_number_of_foos(42) # => returns the document
44
- doc = MyDocument.find_by_file_name("foo.textile") # => returns the document
43
+ <pre><code>doc = MyDocument.find_by_title("Ruby is great") # => returns the document
44
+ doc = MyDocument.find_by_number_of_foos(42) # => returns the document
45
+ doc = MyDocument.find_by_file_name("2010-09-13-ruby-stuff") # => returns the document
45
46
 
46
47
  docs = MyDocument.find_all_by_status("published") # => [doc_1, doc_2, ...]
47
- docs = MyDocument.find_all_by_tag("tag") # => [doc_1, doc_2, ...]
48
+ docs = MyDocument.find_all_by_tag("programming") # => [doc_1, doc_2, ...]
48
49
  </code></pre>
49
50
 
50
51
 
51
52
  h3. Listing documents by Array attributes
52
53
 
53
54
  <pre><code>docs = MyDocument.by_tags
54
- # => Returns {"tag" => [doc_1, doc_2, ...], "tag_2" => [doc_1, doc_3, ...], ...}
55
+ # => Returns {"programming" => [doc_1, doc_2, ...], "software" => [doc_1, doc_3, ...], ...}
55
56
  </code></pre>
56
57
 
57
58
 
59
+ h3. Listing documents by the date attribute
60
+
61
+ Document file tries to parse the filename of your documents to create a date attribute. In order to use the automatic parsing, the filenames have to start with a date string, e.g. @2010-09-13-ruby-stuff.textile@. If you don't want to set the date in the filename, you can still do it in the YAML front matter with e.g. @date: 2010-09-10@.
62
+
63
+ <pre><code>docs = MyDocument.find_all_by_date(2010) # => returns all documents from 2010
64
+ docs = MyDocument.find_all_by_date(2010, 9) # => returns all documents from Sep., 2010
65
+ docs = MyDocument.find_all_by_date(2010, 9, 13) # => returns all documents from Sep. 13th, 2010
66
+ </code></pre>
67
+
58
68
  h3. Chaining
59
69
 
60
70
  <pre><code>docs = MyDocument.find_all_by_status("published").by_tags
61
- # => Returns {"tag" => [doc_1, doc_2, ...], ...}
62
- docs = MyDocument.find_all_by_status("published").find_all_by_tag("tag")
71
+ # => Returns {"programming" => [doc_1, doc_2, ...], ...}
72
+ docs = MyDocument.find_all_by_status("published").find_all_by_tag("programming")
63
73
  # => Returns [doc_1, doc_2, ...]
64
74
  </code></pre>
65
75
 
66
76
 
67
77
  h3. Accessing the attributes of single documents
68
78
 
69
- <pre><code>doc.title # => "The shizzle!"
70
- doc.tags # => ["tag"]
71
- doc.content # => "I like the flowers."
72
- doc.filename # => "foo"
73
- doc.file_name_with_extension # => "foo.textile"
79
+ <pre><code>doc.title # => "Ruby is great"
80
+ doc.tags # => ["programming", "software"]
81
+ doc.content # => "I like Ruby."
82
+ doc.file_name # => "2010-08-12-my-post"
83
+ doc.file_name_with_extension # => "2010-08-12-my-post.textile"
74
84
  doc.file_extension # => ".textile"
75
85
  </code></pre>
76
86
 
@@ -91,4 +101,4 @@ If any of the files change, you must manually reload them:
91
101
  h2. Author
92
102
 
93
103
  Written by "Ralph von der Heyden":http://rvdh.de. Don't hesitate to contact me if you have any further questions.
94
- Follow me on "Twitter":http://twitter.com/ralph.
104
+ Follow me on "Twitter":http://twitter.com/ralph!
@@ -14,6 +14,7 @@ module DocumentFile
14
14
  collection.each do |document|
15
15
  self.ensure_document(document)
16
16
  attributes_hash = document.data.merge({'file_name' => document.file_name})
17
+ attributes_hash.delete 'date'
17
18
  collection.define_dynamic_finders attributes_hash
18
19
  end
19
20
  collection
@@ -27,6 +28,21 @@ module DocumentFile
27
28
  raise ArgumentError unless document.class.include? DocumentFile
28
29
  end
29
30
 
31
+ def find_all_by_date(*args)
32
+ return if args.size == 0
33
+
34
+ date_parts = %w(year month day)
35
+ docs = self
36
+ args.size.times do |i|
37
+ docs = docs.select { |doc| doc.date.send(date_parts[i]) == args[i] }
38
+ end
39
+ self.class.new docs
40
+ end
41
+
42
+ def find_by_date(*args)
43
+ find_all_by_date(*args).first
44
+ end
45
+
30
46
  def define_dynamic_finders(attributes_hash)
31
47
  attributes_hash.each do |attribute, value|
32
48
  define_find_all_by attribute, value
@@ -1,3 +1,3 @@
1
1
  module DocumentFile
2
- VERSION = "0.0.5"
2
+ VERSION = '0.0.6'
3
3
  end
data/lib/document_file.rb CHANGED
@@ -15,7 +15,11 @@ module DocumentFile
15
15
  attr_reader :content, :file_path, :data
16
16
 
17
17
  def initialize(new_file_path)
18
- @file_path = new_file_path
18
+ @file_path = if File.exist? new_file_path
19
+ new_file_path
20
+ else
21
+ [self.documents_dir, new_file_path].join('/')
22
+ end
19
23
  read_yaml
20
24
  end
21
25
 
@@ -40,12 +44,19 @@ private
40
44
  @data = YAML.load($1)
41
45
  end
42
46
  @data ||= {}
47
+ if !@data.has_key? 'date'
48
+ begin
49
+ match = File.basename(@file_path).match(/(\d{4})-(\d{1,2})-(\d{1,2}).*/)
50
+ @data['date'] = Date.new(match[1].to_i, match[2].to_i, match[3].to_i)
51
+ rescue NoMethodError => err
52
+ end
53
+ end
43
54
  define_dynamic_methods
44
55
  end
45
56
 
46
57
  def define_dynamic_methods
47
- @data.each do |attribute_name, value|
48
- attribute_reader = "def #{attribute_name}; @data['#{attribute_name}']; end"
58
+ @data.each do |attribute, value|
59
+ attribute_reader = "def #{attribute}; @data['#{attribute}']; end"
49
60
  self.class.module_eval attribute_reader
50
61
  end
51
62
  end
@@ -61,7 +72,7 @@ private
61
72
  def reload!
62
73
  if File.directory?(documents_dir)
63
74
  file_paths = Dir.glob("#{documents_dir}/*.*")
64
- @@documents = Collection.new file_paths.map { |file_path| self.new file_path }
75
+ @@documents = Collection.new file_paths.map { |fp| self.new fp }
65
76
  else
66
77
  []
67
78
  end
@@ -4,9 +4,7 @@ describe DocumentFile::Collection do
4
4
  describe 'when adding documents to the collection' do
5
5
  before do
6
6
  @collection = DocumentFile::Collection.new
7
- @document = MyDocument.new(
8
- TEST_DIR + '/documents/2010-08-08-test-document-file.textile'
9
- )
7
+ @document = MyDocument.new('2010-08-08-test-document-file.textile')
10
8
  end
11
9
 
12
10
  it 'should not accept non-documents' do
@@ -62,11 +60,36 @@ describe DocumentFile::Collection do
62
60
  end
63
61
 
64
62
  it 'should accept documents' do
65
- document = MyDocument.new(
66
- TEST_DIR + '/documents/2010-08-08-test-document-file.textile'
67
- )
63
+ document = MyDocument.new '2010-08-08-test-document-file.textile'
68
64
  collection = DocumentFile::Collection.new [document]
69
65
  assert document, collection.first
70
66
  end
71
67
  end
68
+
69
+ describe 'when finding documents by date' do
70
+ it 'should return a collection' do
71
+ documents = MyDocument.find_all_by_date 2010
72
+ assert_equal documents.class, DocumentFile::Collection
73
+ end
74
+
75
+ it 'should return all documents with the year specified' do
76
+ documents = MyDocument.find_all_by_date 2010
77
+ assert_equal 2, documents.size
78
+ end
79
+
80
+ it 'should return all documents with the year and month specified' do
81
+ documents = MyDocument.find_all_by_date 2010, 8
82
+ assert_equal 2, documents.size
83
+ end
84
+
85
+ it 'should return all documents with the year, month and day specified' do
86
+ documents = MyDocument.find_all_by_date 2010, 8, 8
87
+ assert_equal 1, documents.size
88
+ end
89
+
90
+ it 'should return the first match' do
91
+ document = MyDocument.find_by_date 2010, 8
92
+ assert_equal 1, document.id
93
+ end
94
+ end
72
95
  end
@@ -17,9 +17,7 @@ describe MyDocument do
17
17
 
18
18
  describe 'when initializing a MyDocument' do
19
19
  before do
20
- @document_file = MyDocument.new(
21
- TEST_DIR + '/documents/2010-08-08-test-document-file.textile'
22
- )
20
+ @document_file = MyDocument.new('2010-08-08-test-document-file.textile')
23
21
  end
24
22
 
25
23
  it 'should know the documents_dir' do
@@ -44,6 +42,68 @@ describe MyDocument do
44
42
  assert_equal Fixnum, @document_file.number_of_foos.class
45
43
  assert_equal 42, @document_file.number_of_foos
46
44
  end
45
+
46
+ it 'should work with absolute path' do
47
+ document_file = MyDocument.new(
48
+ TEST_DIR + '/documents/2010-08-08-test-document-file.textile'
49
+ )
50
+ assert_equal MyDocument, document_file.class
51
+ end
52
+ end
53
+
54
+ describe 'when initializing the date' do
55
+ after do
56
+ remove_document @file_name if @file_name
57
+ end
58
+
59
+ it 'should initialize the date from the filename' do
60
+ document_file = MyDocument.new '2010-08-08-test-document-file.textile'
61
+ assert_equal Date.new(2010, 8, 8), document_file.date
62
+ end
63
+
64
+ it 'should initialize the date from the YAML front matter' do
65
+ @file_name = 'date-test-1.textile'
66
+ add_document @file_name, <<-eos
67
+ ---
68
+ id: 5
69
+ title: Date test 1
70
+ date: 2010-09-10
71
+ ---
72
+
73
+ I like the dates.
74
+ eos
75
+ document_file = MyDocument.new @file_name
76
+ assert_equal Date.new(2010, 9, 10), document_file.date
77
+ end
78
+
79
+ it 'should prefer the date from the YAML front matter' do
80
+ @file_name = '2010-08-15-date-test-1.textile'
81
+ add_document @file_name, <<-eos
82
+ ---
83
+ id: 5
84
+ title: Date test 2
85
+ date: 2010-08-20
86
+ ---
87
+
88
+ I like the dates.
89
+ eos
90
+ document_file = MyDocument.new @file_name
91
+ assert_equal Date.new(2010, 8, 20), document_file.date
92
+ end
93
+
94
+ it 'should not set a date if neither filename nor YAML date is set' do
95
+ @file_name = 'date-test-1.textile'
96
+ add_document @file_name, <<-eos
97
+ ---
98
+ id: 5
99
+ title: Date test 3
100
+ ---
101
+
102
+ I like the dates.
103
+ eos
104
+ document_file = MyDocument.new @file_name
105
+ assert_nil document_file.date
106
+ end
47
107
  end
48
108
 
49
109
  describe 'when listing document_files by an Array attribute' do
@@ -130,30 +190,31 @@ describe MyDocument do
130
190
 
131
191
  describe 'when getting the file name or file path' do
132
192
  before do
133
- @file_path = './test/documents/2010-08-08-test-document-file.textile'
193
+ @file_name = '2010-08-08-test-document-file.textile'
134
194
  end
135
195
 
136
196
  it 'should show the right file name' do
137
- document_file = MyDocument.new @file_path
197
+ document_file = MyDocument.new @file_name
138
198
  file_name = '2010-08-08-test-document-file'
139
199
  assert_equal file_name, document_file.file_name
140
200
  end
141
201
 
142
202
  it 'should show the right file name with extension' do
143
- document_file = MyDocument.new @file_path
203
+ document_file = MyDocument.new @file_name
144
204
  file_name = '2010-08-08-test-document-file.textile'
145
205
  assert_equal file_name, document_file.file_name_with_extension
146
206
  end
147
207
 
148
208
  it 'should show the right extension' do
149
- document_file = MyDocument.new @file_path
209
+ document_file = MyDocument.new @file_name
150
210
  extension = '.textile'
151
211
  assert_equal extension, document_file.file_extension
152
212
  end
153
213
 
154
214
  it 'should show the right file path' do
155
- document_file = MyDocument.new @file_path
156
- assert_equal @file_path, document_file.file_path
215
+ document_file = MyDocument.new @file_name
216
+ expected_path = [MyDocument.documents_dir, @file_name].join('/')
217
+ assert_equal expected_path, document_file.file_path
157
218
  end
158
219
  end
159
220
 
@@ -177,6 +238,7 @@ describe MyDocument do
177
238
  @document_files_before = MyDocument.all
178
239
  @tmp_dir = "#{@default_dir}-#{Time.now.to_i}-#{rand(999999)}-test"
179
240
  FileUtils.cp_r @default_dir, @tmp_dir
241
+ MyDocument.documents_dir = @tmp_dir
180
242
  end
181
243
 
182
244
  after do
@@ -184,7 +246,7 @@ describe MyDocument do
184
246
  end
185
247
 
186
248
  it 'should get updated document_files' do
187
- updated_document_file = <<-eos
249
+ add_document '2010-08-08-test-document-file.textile', <<-eos
188
250
  ---
189
251
  id: 1
190
252
  title: The shuzzle!
@@ -194,9 +256,6 @@ number_of_foos: 48
194
256
 
195
257
  I like the foos.
196
258
  eos
197
- document_file_file_name = "#{@tmp_dir}/2010-08-08-test-document-file.textile"
198
- File.open(document_file_file_name, 'w') {|f| f.write(updated_document_file) }
199
- MyDocument.documents_dir = @tmp_dir
200
259
  MyDocument.reload!
201
260
  document_files_after = MyDocument.all
202
261
 
@@ -208,7 +267,7 @@ eos
208
267
  end
209
268
 
210
269
  it 'should get new document_files' do
211
- new_document_file = <<-eos
270
+ add_document '2010-08-15-new-test-document_file.textile', <<-eos
212
271
  ---
213
272
  id: 3
214
273
  title: The shuzzle!
@@ -218,9 +277,6 @@ number_of_foos: 48
218
277
 
219
278
  I like the cows.
220
279
  eos
221
- document_file_file_name = "#{@tmp_dir}/2010-08-15-new-test-document_file.textile"
222
- File.open(document_file_file_name, 'w') {|f| f.write(new_document_file) }
223
- MyDocument.documents_dir = @tmp_dir
224
280
  MyDocument.reload!
225
281
  document_files_after = MyDocument.all
226
282
 
@@ -236,13 +292,21 @@ eos
236
292
  end
237
293
 
238
294
  it 'should not show deleted document_files' do
239
- document_file_file_name = "#{@tmp_dir}/2010-08-08-test-document-file.textile"
240
- FileUtils.rm document_file_file_name
241
- MyDocument.documents_dir = @tmp_dir
295
+ remove_document '2010-08-08-test-document-file.textile' # has id 1
242
296
  MyDocument.reload!
243
297
  document_files_after = MyDocument.all
244
- refute_equal @document_files_before.map(&:id), document_files_after.map(&:id)
298
+ refute document_files_after.map(&:id).include? 1
245
299
  end
246
300
  end
301
+
302
+ def add_document(file_name, content)
303
+ complete_file_name = [MyDocument.documents_dir, file_name].join('/')
304
+ File.open(complete_file_name, 'w') {|f| f.write(content) }
305
+ end
306
+
307
+ def remove_document(file_name)
308
+ complete_file_name = [MyDocument.documents_dir, file_name].join('/')
309
+ FileUtils.rm complete_file_name if File.exist? complete_file_name
310
+ end
247
311
  end
248
312
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 5
9
- version: 0.0.5
8
+ - 6
9
+ version: 0.0.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ralph von der Heyden
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-01 00:00:00 +02:00
17
+ date: 2010-09-08 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: 3.0.0
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
- description: " Makes your plain text files accessible in Ruby. Supports YAML front matter.\n"
35
+ description: " Document file is an object mapper for plain text documents. The documents look like the ones used in jekyll (http://github.com/mojombo/jekyll). They consist of a preambel written in YAML (also called YAML front matter), and some content in the format you prefer, e.g. Textile. This enables you to write documents in your favorite editor and access the content and metadata of these in your Ruby scripts.\n"
36
36
  email: ralph@rvdh.de
37
37
  executables: []
38
38
 
@@ -82,6 +82,6 @@ rubyforge_project:
82
82
  rubygems_version: 1.3.7
83
83
  signing_key:
84
84
  specification_version: 3
85
- summary: Write documents in your fav editor. Read them in your Ruby app.
85
+ summary: Document file is an object mapper for plain text documents.
86
86
  test_files: []
87
87