dir_model 0.4.0 → 0.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 55a68864ee18333c18a59e6e8a8331aedf90ed0f
4
- data.tar.gz: cf8dee9636172ce581287536d1bc903ec155690a
3
+ metadata.gz: 3a463aecfe9ed4b92a734acdca662de128f7e342
4
+ data.tar.gz: 512616906b07badd6ee5ebb1b4a3c797d6a8cade
5
5
  SHA512:
6
- metadata.gz: edbca7458a28490260d7f50495e10540ed6cfad0422bbdede0aaeb8d01393a33f7c4ddded2c4d2207784823b2615e0de887863c8217e3400e33c0f323882ce60
7
- data.tar.gz: 73bd59243eaffcd38e75522434cf5f40a3014efc6556df4bb90214992a0066fb600d53f8037c8b7e8634d79407f45ace2e80c63a8ae6db20754896153da6db1b
6
+ metadata.gz: e46872a46024038ba6997fe2b4967f9e85f349f5f58ede009bc17eaf8ccc47d47c47243e714cd91a936525c3eea646d1afaf59f5987ee4007cf08408052b9cac
7
+ data.tar.gz: 9fdf00b25d1318468b1907f4ad574b8e5a98e1f776fb7c3524ad29549bd17cb8f7ffcdbf097808d8be409e6d01810463b3c94e4e5bc3b66bb8b44be6d3e9be64
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ### VERSION 0.5.0
2
+
3
+ * Add relation has_one to a dir_model
4
+ * `file:` must be unique, you can't defined several file in the same dir_model
5
+ * Simplification of `lib/dir_model/import.rb`
6
+
7
+ ### VERSION 0.4.0
8
+ ### VERSION 0.3.4
9
+ ### VERSION 0.3.3
10
+ ### VERSION 0.3.2
11
+
1
12
  ### VERSION 0.3.1
2
13
 
3
14
  * Technical changes, Simplication of Path, use Array skill to give previous, current and next Path instead of using Enumerator
data/README.md CHANGED
@@ -23,7 +23,7 @@ Or install it yourself as:
23
23
  ### Import
24
24
 
25
25
  ```ruby
26
- class ImageDir
26
+ class BasicDirModel
27
27
  include DirModel::Model
28
28
 
29
29
  file :image, regex: -> { /Zones\/Sector_(?<sector_id>.*)\/Zone_(?<zone_id>.*)\.(?<extension>png|jpg)/i }
@@ -35,33 +35,48 @@ named matches are available under `matches[:sector_id]` or directly when you cal
35
35
  An implementation possible of Import
36
36
 
37
37
  ```ruby
38
- class ImageImportDir < ImageDir
38
+ class BasicImportDirModel < BasicDirModel
39
39
  include DirModel::Import
40
40
 
41
- def assign!
42
- model.send(method, image)
43
- end
44
-
45
41
  protected
46
42
 
47
43
  def model
48
44
  Project.find(context[:project_id]).sectors.find(sector_id).zones.find(zone_id)
49
45
  end
50
-
51
- def method
52
- :blueprint
53
- end
54
46
  end
55
47
  ```
56
48
 
57
49
  You can have access at the file through
58
50
 
59
- `ImageImportDir.new(source_path, project_id: 42).image`
51
+ `BasicImportDirModel.new(source_path, project_id: 42).image`
52
+
53
+ #### Relation
54
+
55
+ A dir_model can have a relation like `has_one` basically is
56
+
57
+ ```ruby
58
+ class ChildImportDirModel
59
+ include DirModel::Model
60
+ include DirModel::Import
61
+ file :metadata, regex: -> { /Zones\/Sector_(?<sector_id>.*)\/Zone_(?<zone_id>.*)\.(?<extension>json)/i }
62
+ end
63
+ ```
64
+
65
+ ```ruby
66
+ class ParentImportDirModel < BasicImportDirModel
67
+ has_one :dependency, ChildImportDirModel
68
+ end
69
+ ```
70
+
71
+ ```ruby
72
+ parent_instance.dependency # => ChildImportDirModel
73
+ child.parent # => parent_instance
74
+ ```
60
75
 
61
76
  ### Export
62
77
 
63
78
  ```ruby
64
- class ImageDir
79
+ class BasicDirModel
65
80
  include DirModel::Model
66
81
 
67
82
  file :image, path: -> { "#{dir}/#{sub_dir}" }, name: -> { image_name }
@@ -73,7 +88,7 @@ end
73
88
  If you don't know the extension of your image it will be automatically discover, but this works only for image so if you send, for instance, a json file you have to explicitly provide extension on the `:name` options
74
89
 
75
90
  ```ruby
76
- class ImageExportDir < ImageDir
91
+ class BasicExportDirModel < BasicDirModel
77
92
  include DirModel::Export
78
93
 
79
94
  def dir
@@ -106,7 +121,7 @@ fixture_models = [
106
121
  })
107
122
  ]
108
123
 
109
- exporter = DirModel::Export::AggregateDir.new(ImageExportDir)
124
+ exporter = DirModel::Export::AggregateDir.new(BasicExportDirModel)
110
125
 
111
126
  exporter.generate do |dir|
112
127
  models.each { |model| dir << model }
@@ -119,7 +134,7 @@ an skip? method based on the name of file :image is create, this method is named
119
134
 
120
135
  default implementation
121
136
  ```
122
- def image_skip?
137
+ def skip?
123
138
  image.present?
124
139
  end
125
140
  ```
@@ -128,7 +143,7 @@ NOTE Safe to override on your Exporter
128
143
  In fact this is equivalent to
129
144
 
130
145
  ```
131
- def image_skip?
146
+ def skip?
132
147
  source_model.zone.present?
133
148
  end
134
149
  ```
@@ -155,15 +170,3 @@ def image_extension
155
170
  end
156
171
  ```
157
172
  Otherwise return nil, safe to override on your Exporter
158
-
159
- ## zip_dir
160
- Use [`zip_dir`](https://github.com/FinalCAD/zip_dir) to zip DirModel::Export instances:
161
- ```ruby
162
- # Zip
163
- zipper = ZipDir::Zipper.new
164
- zip_file = zipper.generate do |z|
165
- z.add_and_cleanup_dir __dir_model_export__
166
- end
167
- ```
168
-
169
- **Ensure that `require zip_dir` occurs before `dir_model` (for now)**
data/UPGRADE.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Upgrading
2
2
 
3
- # Upgrading from 0.3.0 to 0.3.1
3
+ # Upgrading from 0.4.0 to 0.5.0
4
4
 
5
- * Nothing todo
5
+ * Ensure you have only on definition of `file:` by dir_model
6
6
 
7
7
  # Upgrading from 0.2.0 to 0.3.0
8
8
 
@@ -25,7 +25,7 @@ end
25
25
  for a DirModel
26
26
 
27
27
  ```
28
- class ImageDir
28
+ class BasicDirModel
29
29
  include DirModel
30
30
 
31
31
  file :image, path: -> { "#{dir}/#{sub_dir}" }, name: -> { "#{image_name}.png" }
@@ -4,11 +4,9 @@ module DirModel
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- self.file_names.each do |*args|
8
- define_skip_method(*args)
9
- define_file_method(*args)
10
- define_extension_method(*args)
11
- end
7
+ define_skip_method(self.file_name)
8
+ define_file_method(self.file_name)
9
+ define_extension_method(self.file_name)
12
10
  end
13
11
 
14
12
  module ClassMethods
@@ -18,7 +16,7 @@ module DirModel
18
16
  # Define default skip method for a file
19
17
  # @param file_name [Symbol] the file: name
20
18
  def define_skip_method(file_name)
21
- define_method("#{file_name}_skip?") do
19
+ define_method(:skip?) do
22
20
  !self.public_send(file_name).try(:present?)
23
21
  end
24
22
  end
@@ -32,20 +32,19 @@ module DirModel
32
32
  def generate
33
33
  cleanup if generated?
34
34
 
35
- self.class.file_names.each do |file_name|
36
- options = self.class.options(file_name)
35
+ file_name = self.class.file_name
36
+ options = self.class.options
37
37
 
38
- next if self.send("#{file_name}_skip?")
38
+ return if self.send(:skip?)
39
39
 
40
- dir_path = get_value_of(options[:path])
41
- file_path = File.join(dir_path, get_value_of(options[:name]))
40
+ dir_path = get_value_of(options[:path])
41
+ file_path = File.join(dir_path, get_value_of(options[:name]))
42
42
 
43
- mkdir { File.join(@root_path, dir_path) }
43
+ mkdir { File.join(@root_path, dir_path) }
44
44
 
45
- file_path = ensure_extension(file_path, file_name)
45
+ file_path = ensure_extension(file_path, file_name)
46
46
 
47
- File.open(File.join(@root_path, file_path), 'wb') {|f| f.write(self.public_send(file_name).read) }
48
- end
47
+ File.open(File.join(@root_path, file_path), 'wb') {|f| f.write(self.public_send(file_name).read) }
49
48
  ensure
50
49
  @generated = true
51
50
  end
@@ -60,7 +59,7 @@ module DirModel
60
59
  ext ||= FastImage.type(self.public_send(file_method_name))
61
60
  unless ext
62
61
  # You have to provide an extension i.e name: 'file.json
63
- raise StandardError.new("options :name should provide an extension")
62
+ raise StandardError.new("extension guessing failed, please provide explicit extension in :name option")
64
63
  end
65
64
 
66
65
  file_path_with_extension = file_path + '.' + ext.to_s
@@ -6,8 +6,8 @@ module DirModel
6
6
  attr_reader :index
7
7
  attr_reader :current_path
8
8
 
9
- def initialize(path)
10
- @path, @index = path, -1
9
+ def initialize(dir_path)
10
+ @path, @index = dir_path, -1
11
11
  reset!
12
12
  end
13
13
 
@@ -44,6 +44,14 @@ module DirModel
44
44
  set_end unless current_path
45
45
  current_path
46
46
  end
47
+
48
+ def set_position(index)
49
+ @index = index
50
+ end
51
+
52
+ def rewind
53
+ set_position(-1)
54
+ end
47
55
 
48
56
  protected
49
57
 
@@ -5,15 +5,11 @@ module DirModel
5
5
  attr_reader :context, :source_path, :index, :previous
6
6
 
7
7
  def initialize(path, options={})
8
+ super # set parent
8
9
  @source_path, @context = path, OpenStruct.new(options[:context])
9
- @index, @previous = options[:index], options[:previous].try(:dup)
10
- @load_state = :ghost
11
- @file_infos = {}
12
- end
13
-
14
- def matches
15
- load
16
- file_infos[:options][:match]
10
+ @index, @previous = options[:index], options[:previous].try(:dup)
11
+ @load_state = :ghost
12
+ @file_infos = {}
17
13
  end
18
14
 
19
15
  def skip?
@@ -23,15 +19,27 @@ module DirModel
23
19
 
24
20
  def method_missing(name, *args, &block)
25
21
  load
26
- matches[name]
27
- rescue IndexError
22
+ @_match[name]
23
+ rescue
28
24
  super
29
25
  end
30
26
 
31
27
  module ClassMethods
32
28
  def next(path, context={}, previous=nil)
33
29
  path.read_path
34
- new(path.current_path, index: path.index, context: context, previous: previous)
30
+ dir_model = new(path.current_path, index: path.index, context: context, previous: previous)
31
+
32
+ if dir_model.has_relations?
33
+ current_position = path.index
34
+ path.rewind
35
+ loop do # loop until find related file (has_one relation)
36
+ path.read_path
37
+ break if dir_model.append_dir_model(path.current_path, index: path.index, context: context)
38
+ end
39
+ path.set_position(current_position)
40
+ end
41
+
42
+ dir_model
35
43
  end
36
44
  end
37
45
 
@@ -41,28 +49,12 @@ module DirModel
41
49
 
42
50
  def match?
43
51
  return if load_state == :loaded
44
- @_match = loader { find_match }
52
+ @_match = find_match.tap { @load_state = :loaded }
45
53
  end
46
54
  alias_method :load, :match?
47
55
 
48
56
  def find_match
49
- self.class.file_names.each do |file_name|
50
- options = self.class.options(file_name)
51
-
52
- if match = (source_path||'').match(options[:regex].call)
53
- @file_infos = { file: file_name, options: options.merge(match: match) }
54
- return true
55
- end
56
- end
57
- false
57
+ @_match = (source_path||'').match(self.class.options[:regex].call)
58
58
  end
59
-
60
- def loader
61
- @load_state = :loading
62
- result = yield
63
- @load_state = :loaded
64
- result
65
- end
66
-
67
59
  end
68
60
  end
@@ -10,26 +10,27 @@ module DirModel
10
10
 
11
11
  module ClassMethods
12
12
  # @return [Array<Symbol>] file names for the row model
13
- def file_names
14
- files.keys
13
+ def file_name
14
+ files.keys.first
15
15
  end
16
16
 
17
17
  # @param [Symbol] file_name name of file to find option
18
18
  # @return [Hash] options for the file_name
19
- def options(file_name)
19
+ def options
20
20
  files[file_name]
21
21
  end
22
22
 
23
23
  # @param [Symbol] file_name name of file to find index
24
24
  # @return [Integer] index of the file_name
25
25
  def index(file_name)
26
- file_names.index file_name
26
+ 0
27
27
  end
28
28
 
29
29
  protected
30
30
 
31
31
  def file(file_name, options={})
32
32
  merge_files(file_name.to_sym => options)
33
+ raise ArgumentError.new("You cannot define more of one file: but you can add relations, see README") if files.keys.size > 1
33
34
  end
34
35
 
35
36
  end
@@ -0,0 +1,67 @@
1
+ module DirModel
2
+ module Model
3
+ module Relations
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ inherited_class_hash :has_one_relationship
7
+ end
8
+
9
+ # @return [Boolean] returns true, if the instance is a child
10
+ def child?
11
+ !!parent
12
+ end
13
+
14
+ def has_relations?
15
+ has_one?
16
+ end
17
+
18
+ # Appends model to the parent and returns it
19
+ #
20
+ # @return [Model] return the child if it is valid, otherwise returns nil
21
+ def append_dir_model(source_path, options={})
22
+ relation_name = self.class.has_one_relationship.keys.first
23
+ related_class = self.class.has_one_relationship.values.first
24
+
25
+ related_dir_model = related_class.new(source_path, options.reverse_merge(parent: self))
26
+
27
+ unless related_dir_model.skip?
28
+ public_send("#{relation_name}=", related_dir_model)
29
+ related_dir_model
30
+ else
31
+ nil
32
+ end
33
+ end
34
+
35
+ def has_one?
36
+ false
37
+ end
38
+
39
+ class_methods do
40
+ # Defines a relationship between a dir model
41
+ #
42
+ # @param [Symbol] relation_name the name of the relation
43
+ # @param [DirModel::Import] dir_model_class class of the relation
44
+ def has_one(relation_name, dir_model_class)
45
+ raise "for now, DirModel's has_one may only be called once" if @_has_one_relationship.present?
46
+
47
+ relation_name = relation_name.to_sym
48
+
49
+ merge_has_one_relationship(relation_name => dir_model_class)
50
+
51
+ define_method(:has_one?) do
52
+ true
53
+ end
54
+
55
+ define_method("#{relation_name}=") do |value|
56
+ instance_variable_set("@#{relation_name}", value)
57
+ end
58
+
59
+ define_method(relation_name) do
60
+ instance_variable_get("@#{relation_name}")
61
+ end
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -5,6 +5,18 @@ module DirModel
5
5
  included do
6
6
  include Utils
7
7
  include Files
8
+ include Relations
9
+
10
+ # @return [Model] return the parent, if this instance is a child
11
+ attr_reader :parent
8
12
  end
13
+
14
+ # @param [NilClass] path not used here, see {Input}
15
+ # @param [Hash] options
16
+ # @option options [String] :parent if the instance is a child, pass the parent
17
+ def initialize(path=nil, options={})
18
+ @parent = options[:parent]
19
+ end
20
+
9
21
  end
10
22
  end
@@ -1,3 +1,3 @@
1
1
  module DirModel
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
data/lib/dir_model.rb CHANGED
@@ -8,6 +8,7 @@ require 'dir_model/utils'
8
8
 
9
9
  require 'dir_model/model'
10
10
  require 'dir_model/model/files'
11
+ require 'dir_model/model/relations'
11
12
 
12
13
  require 'dir_model/export/files'
13
14
  require 'dir_model/export'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dir_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Chung
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-12-09 00:00:00.000000000 Z
11
+ date: 2015-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,6 +80,7 @@ files:
80
80
  - lib/dir_model/import/path.rb
81
81
  - lib/dir_model/model.rb
82
82
  - lib/dir_model/model/files.rb
83
+ - lib/dir_model/model/relations.rb
83
84
  - lib/dir_model/utils.rb
84
85
  - lib/dir_model/version.rb
85
86
  homepage: https://github.com/FinalCAD/dir_model