document_file 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -1,22 +1,20 @@
1
1
  h1. Document File
2
2
 
3
- An attempt to create a simple model layer that abstracts flat text files. Text files 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. They consist of a preambel written in YAML (also called YAML front matter), and some content in the format you prefer, e.g. Textile.
4
4
 
5
5
 
6
6
  h2. Example
7
7
 
8
8
  As an example let's assume we have a directory called "documents" containing the following files:
9
9
 
10
- <pre><code>
11
- documents/
10
+ <pre><code>documents/
12
11
  |-foo.textile
13
12
  |-bar.textile
14
13
  </code></pre>
15
14
 
16
15
  Documents look somehow like this. The part between the @---@s is the YAML front matter. After the second @---@, there is one blank line, followed by the content of the file. All items in the YAML front matter and the content are accessible by Document File.
17
16
 
18
- <pre><code>
19
- ---
17
+ <pre><code>---
20
18
  id: 1
21
19
  title: The shizzle!
22
20
  tags: [tag]
@@ -30,8 +28,8 @@ I like the flowers.
30
28
 
31
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:
32
30
 
33
- <pre><code>
34
- class MyDocument < DocumentFile::Base
31
+ <pre><code>class MyDocument
32
+ include DocumentFile
35
33
  self.documents_dir = './documents'
36
34
  end
37
35
  </code></pre>
@@ -41,36 +39,34 @@ h2. Available functionality
41
39
 
42
40
  h3. Dynamic finders
43
41
 
44
- <pre><code>
45
- doc = MyDocument.find_by_title("The shizzle!") # => returns the document
42
+ <pre><code>doc = MyDocument.find_by_title("The shizzle!") # => returns the document
46
43
  doc = MyDocument.find_by_number_of_foos(42) # => returns the document
47
44
  doc = MyDocument.find_by_file_name("foo.textile") # => returns the document
48
45
 
49
- docs = MyDocument.find_all_by_status("published") # => [doc_1, doc2, ...]
50
- docs = MyDocument.find_all_by_tag("tag") # => [doc_1, doc2, ...]
46
+ docs = MyDocument.find_all_by_status("published") # => [doc_1, doc_2, ...]
47
+ docs = MyDocument.find_all_by_tag("tag") # => [doc_1, doc_2, ...]
51
48
  </code></pre>
52
49
 
50
+
53
51
  h3. Listing documents by Array attributes
54
52
 
55
- <pre><code>
56
- docs = MyDocument.by_tags
57
- # => Returns {"tag" => [doc_1, doc2, ...], "tag_2" => [doc_1, doc_3, ...], ...}
53
+ <pre><code>docs = MyDocument.by_tags
54
+ # => Returns {"tag" => [doc_1, doc_2, ...], "tag_2" => [doc_1, doc_3, ...], ...}
58
55
  </code></pre>
59
56
 
57
+
60
58
  h3. Chaining
61
59
 
62
- <pre><code>
63
- docs = MyDocument.find_all_by_status("published").by_tags
64
- # => Returns {"tag" => [doc_1, doc2, ...], ...}
60
+ <pre><code>docs = MyDocument.find_all_by_status("published").by_tags
61
+ # => Returns {"tag" => [doc_1, doc_2, ...], ...}
65
62
  docs = MyDocument.find_all_by_status("published").find_all_by_tag("tag")
66
- # => Returns [doc_1, doc2, ...]
63
+ # => Returns [doc_1, doc_2, ...]
67
64
  </code></pre>
68
65
 
69
66
 
70
67
  h3. Accessing the attributes of single documents
71
68
 
72
- <pre><code>
73
- doc.title # => "The shizzle!"
69
+ <pre><code>doc.title # => "The shizzle!"
74
70
  doc.tags # => ["tag"]
75
71
  doc.content # => "I like the flowers."
76
72
  doc.filename # => "foo"
@@ -82,15 +78,13 @@ h3. Initializing single documents
82
78
 
83
79
  This will even work without setting the @documents_dir@ class variable.
84
80
 
85
- <pre><code>
86
- doc = MyDocument.new('./documents/document-file.textile')
81
+ <pre><code>doc = MyDocument.new('./documents/document-file.textile')
87
82
  </code></pre>
88
83
 
89
84
  h3. Reloading
90
85
 
91
86
  If any of the files change, you must manually reload them:
92
- <pre><code>
93
- MyDocument.reload!
87
+ <pre><code>MyDocument.reload!
94
88
  </code></pre>
95
89
 
96
90
 
data/lib/document_file.rb CHANGED
@@ -1,3 +1,76 @@
1
- require 'document_file/base'
1
+ require 'active_support/core_ext/class'
2
+ require 'active_support/concern.rb'
2
3
  require 'document_file/collection'
3
4
  require 'document_file/version'
5
+ require 'yaml'
6
+
7
+ module DocumentFile
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ class_inheritable_accessor :documents_dir
12
+ self.documents_dir = './documents'
13
+ end
14
+
15
+ attr_reader :content, :file_path, :data
16
+
17
+ def initialize(new_file_path)
18
+ @file_path = new_file_path
19
+ read_yaml
20
+ end
21
+
22
+ def file_name
23
+ File.basename file_name_with_extension, file_extension
24
+ end
25
+
26
+ def file_name_with_extension
27
+ self.file_path.split('/').last
28
+ end
29
+
30
+ def file_extension
31
+ File.extname file_name_with_extension
32
+ end
33
+
34
+ private
35
+ def read_yaml
36
+ @content = File.read(@file_path)
37
+
38
+ if @content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
39
+ @content = @content[($1.size + $2.size)..-1]
40
+ @data = YAML.load($1)
41
+ end
42
+ @data ||= {}
43
+ define_dynamic_methods
44
+ end
45
+
46
+ def define_dynamic_methods
47
+ @data.each do |attribute_name, value|
48
+ attribute_reader = "def #{attribute_name}; @data['#{attribute_name}']; end"
49
+ self.class.module_eval attribute_reader
50
+ end
51
+ end
52
+
53
+ module ClassMethods
54
+ @@documents = nil
55
+
56
+ def all
57
+ return @@documents if @@documents
58
+ reload!
59
+ end
60
+
61
+ def reload!
62
+ if File.directory?(documents_dir)
63
+ file_paths = Dir.glob("#{documents_dir}/*.*")
64
+ @@documents = Collection.new file_paths.map { |file_path| self.new file_path }
65
+ else
66
+ []
67
+ end
68
+ end
69
+
70
+ private
71
+ def method_missing(method_name, *args)
72
+ all.respond_to?(method_name) ? self.all.send(method_name, *args) : super
73
+ end
74
+ end
75
+ end
76
+
@@ -24,7 +24,7 @@ module DocumentFile
24
24
  end
25
25
 
26
26
  def self.ensure_document(document)
27
- raise ArgumentError unless document.is_a? DocumentFile::Base
27
+ raise ArgumentError unless document.class.include? DocumentFile
28
28
  end
29
29
 
30
30
  def define_dynamic_finders(attributes_hash)
@@ -1,3 +1,3 @@
1
1
  module DocumentFile
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -1,10 +1,6 @@
1
1
  require './test/test_base'
2
2
 
3
3
  describe MyDocument do
4
- before do
5
- MyDocument.documents_dir = TEST_DIR + '/documents'
6
- end
7
-
8
4
  describe 'when finding all document_files' do
9
5
  before do
10
6
  @document_files = MyDocument.all
@@ -26,6 +22,10 @@ describe MyDocument do
26
22
  )
27
23
  end
28
24
 
25
+ it 'should know the documents_dir' do
26
+ assert_equal MyDocument.documents_dir, @document_file.documents_dir
27
+ end
28
+
29
29
  it 'should initialize the content' do
30
30
  assert_equal "I like the flowers.\n", @document_file.content
31
31
  end
data/test/test_base.rb CHANGED
@@ -8,5 +8,7 @@ $LOAD_PATH.unshift lib_dir unless $LOAD_PATH.include?(lib_dir)
8
8
  require 'document_file'
9
9
  TEST_DIR = File.dirname(__FILE__)
10
10
 
11
- class MyDocument < DocumentFile::Base
11
+ class MyDocument
12
+ include DocumentFile
13
+ self.documents_dir = (TEST_DIR + '/documents')
12
14
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
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-08-26 00:00:00 +02:00
17
+ date: 2010-09-01 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -41,12 +41,8 @@ extensions: []
41
41
  extra_rdoc_files: []
42
42
 
43
43
  files:
44
- - Gemfile
45
- - Gemfile.lock
46
44
  - LICENSE
47
45
  - README.textile
48
- - Rakefile
49
- - lib/document_file/base.rb
50
46
  - lib/document_file/collection.rb
51
47
  - lib/document_file/version.rb
52
48
  - lib/document_file.rb
data/Gemfile DELETED
@@ -1 +0,0 @@
1
- gemspec :path => '.'
data/Gemfile.lock DELETED
@@ -1,16 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- document_file (0.0.4)
5
- activesupport (~> 3.0.0)
6
-
7
- GEM
8
- specs:
9
- activesupport (3.0.0.rc)
10
-
11
- PLATFORMS
12
- ruby
13
-
14
- DEPENDENCIES
15
- activesupport (~> 3.0.0)
16
- document_file!
data/Rakefile DELETED
@@ -1,5 +0,0 @@
1
- require 'rake/testtask'
2
- task :default => :test
3
- Rake::TestTask.new(:test) do |t|
4
- t.test_files = FileList['test/*_test.rb']
5
- end
@@ -1,71 +0,0 @@
1
- require 'yaml'
2
-
3
- module DocumentFile
4
- class Base
5
- @@documents_dir = './documents'
6
- @@documents = nil
7
- attr_reader :content, :file_path, :data
8
-
9
- def initialize(new_file_path)
10
- @file_path = new_file_path
11
- read_yaml
12
- end
13
-
14
- def file_name
15
- File.basename file_name_with_extension, file_extension
16
- end
17
-
18
- def file_name_with_extension
19
- self.file_path.split('/').last
20
- end
21
-
22
- def file_extension
23
- File.extname file_name_with_extension
24
- end
25
-
26
- def self.all
27
- return @@documents if @@documents
28
- self.reload!
29
- end
30
-
31
- def self.reload!
32
- if File.directory?(@@documents_dir)
33
- file_paths = Dir.glob("#{@@documents_dir}/*.*")
34
- @@documents = Collection.new file_paths.map { |file_path| self.new file_path }
35
- else
36
- []
37
- end
38
- end
39
-
40
- def self.documents_dir
41
- @@documents_dir
42
- end
43
-
44
- def self.documents_dir=(new_dir)
45
- @@documents_dir = new_dir
46
- end
47
-
48
- private
49
- def read_yaml
50
- @content = File.read(@file_path)
51
-
52
- if @content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
53
- @content = @content[($1.size + $2.size)..-1]
54
- @data = YAML.load($1)
55
- end
56
- @data ||= {}
57
- define_dynamic_methods
58
- end
59
-
60
- def define_dynamic_methods
61
- @data.each do |attribute_name, value|
62
- attribute_reader = "def #{attribute_name}; @data['#{attribute_name}']; end"
63
- self.class.module_eval attribute_reader
64
- end
65
- end
66
-
67
- def self.method_missing(method_name, *args)
68
- self.all.respond_to?(method_name) ? self.all.send(method_name, *args) : super
69
- end
70
- end
71
- end