dir_model 0.2.0 → 0.3.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: 446e930d0a4af01c2fd5a48cbfb3e742e0a35b32
4
- data.tar.gz: 8abc4fe852ccdfb4a259babd81e3ee080f33e8ab
3
+ metadata.gz: b37d3d709550ebba94791438eb647ff38631caaa
4
+ data.tar.gz: 6897081d0e48e834a5e641b33097ec5b6bfd8e23
5
5
  SHA512:
6
- metadata.gz: 58278e1b4641a695da21cc21f91c696517d85807ff0824175cfe32884e097863b5658871571498092c2b2b46a3990c9f65d7d27be6b5ee5a7ad7cc948a89206d
7
- data.tar.gz: 409e249c4c01de393961daef38df9c464ee8c79870efa7fc4633a65fba65743d0d57248b6bf59a709c17d6f82f7e698c50912e10e52825ba8196707542c47892
6
+ metadata.gz: 6e4ea16033776a1d2d3b6a6e331b8ee4660b56365a2c4b5014e700aad49b5157b7ff7579f056de55eaf7b077bffb332d402e5ead8f5870a15a8bd2d9390d7020
7
+ data.tar.gz: fa6270d818cca60016271b3a3bd31ba40982227cc817dcd320f530c892c6876c267a4d3d59c5196ecd2361aac9e81acc74c1323ff6265e2c6e8b2f260c8172ba
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ### VERSION 0.3.0
2
+
3
+ * Add Import feature
4
+
1
5
  ### VERSION 0.2.0
2
6
 
3
7
  * Apply [CsvRowModel](https://github.com/FinalCAD/csv_row_model) pattern for export.
data/README.md CHANGED
@@ -20,15 +20,59 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
+ ### Import
24
+
25
+ ```ruby
26
+ class ImageDir
27
+ include DirModel::Model
28
+
29
+ file :image, regex: -> { /Zones\/Sector_(?<sector_id>.*)\/Zone_(?<zone_id>.*)\.(?<extension>png|jpg)/i }
30
+ end
31
+ ```
32
+
33
+ named matches are available under `matches[:sector_id]` or directly when you calling `sector_id`
34
+
35
+ An implementation possible of Import
36
+
37
+ ```ruby
38
+ class ImageImportDir < ImageDir
39
+ include DirModel::Import
40
+
41
+ def assign!
42
+ model.send(method, image)
43
+ end
44
+
45
+ protected
46
+
47
+ def model
48
+ Project.find(context[:project_id]).sectors.find(sector_id).zones.find(zone_id)
49
+ end
50
+
51
+ def method
52
+ :blueprint
53
+ end
54
+ end
55
+ ```
56
+
57
+ You can have access at the file through
58
+
59
+ `ImageImportDir.new(source_path, project_id: 42).image`
60
+
23
61
  ### Export
24
62
 
25
63
  ```ruby
26
64
  class ImageDir
27
- include DirModel
65
+ include DirModel::Model
28
66
 
29
- file :image, path: -> { "#{dir}/#{sub_dir}" }, name: -> { "#{image_name}.png" }
67
+ file :image, path: -> { "#{dir}/#{sub_dir}" }, name: -> { image_name }
30
68
  end
69
+ ```
31
70
 
71
+ `path` and `name` can take Proc or String if doesn't have any interpolation.
72
+
73
+ 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
+
75
+ ```ruby
32
76
  class ImageExportDir < ImageDir
33
77
  include DirModel::Export
34
78
 
data/UPGRADE.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Upgrading
2
2
 
3
+ * Model is now a module you have to change include from `include DirModel` to `include DirModel::Model`
4
+
5
+ # Upgrading from 0.2.0 to 0.3.0
6
+
7
+
3
8
  # Upgrading from 0.1.0 to 0.2.0
4
9
 
5
10
  You have to change
data/dir_model.gemspec CHANGED
@@ -20,4 +20,5 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency 'activesupport', '~> 4.2'
22
22
  spec.add_dependency 'inherited_class_var', '~> 0.1'
23
+ spec.add_dependency 'fastimage', '~> 1.8'
23
24
  end
@@ -1,3 +1,5 @@
1
+ require 'fastimage'
2
+
1
3
  module DirModel
2
4
  module Export
3
5
 
@@ -25,18 +27,39 @@ module DirModel
25
27
  def generate
26
28
  cleanup if generated?
27
29
 
28
- self.class.files.each do |file_name, options|
29
- dir_path = instance_exec(&options[:path])
30
- file_path = File.join(dir_path, instance_exec(&options[:name]))
30
+ self.class.file_names.each do |file_name|
31
+ options = self.class.options(file_name)
32
+
33
+ dir_path = get_value_of(options[:path])
34
+ file_path = File.join(dir_path, get_value_of(options[:name]))
31
35
 
32
36
  mkdir { File.join(@root_path, dir_path) }
33
37
 
38
+ file_path = ensure_extension(file_path, file_name)
39
+
34
40
  File.open(File.join(@root_path, file_path), 'wb') {|f| f.write(self.public_send(file_name).read) }
35
41
  end
36
42
  ensure
37
43
  @generated = true
38
44
  end
39
45
 
46
+ def ensure_extension(file_path, file_method_name)
47
+ file_path_with_extension = file_path
48
+ if File.extname(file_path).blank?
49
+ if ext = FastImage.type(self.public_send(file_method_name))
50
+ file_path_with_extension = file_path + '.' + ext.to_s
51
+ else
52
+ raise StandardError.new("options :name should provid an extension")
53
+ end
54
+ end
55
+ file_path_with_extension
56
+ end
57
+
58
+ def get_value_of(string_or_proc)
59
+ return string_or_proc if string_or_proc.is_a?(String)
60
+ instance_exec(&string_or_proc)
61
+ end
62
+
40
63
  def cleanup
41
64
  FileUtils.remove_entry @root_path
42
65
  @generated = false
@@ -0,0 +1,57 @@
1
+ require 'forwardable'
2
+
3
+ module DirModel
4
+ module Import
5
+ class Dir # File
6
+ extend Forwardable
7
+
8
+ attr_reader :index
9
+ attr_reader :path
10
+ attr_reader :import_dir_model_class
11
+ attr_reader :context
12
+ attr_reader :current_dir_model
13
+ attr_reader :previous_dir_model
14
+
15
+ def_delegators :@path, :end?
16
+
17
+ def initialize(source_path, import_dir_model_class, context={})
18
+ @path, @import_dir_model_class, @context = Path.new(source_path), import_dir_model_class, context.to_h.symbolize_keys
19
+ reset
20
+ end
21
+
22
+ def reset
23
+ path.reset!
24
+ @index = -1
25
+ @current_dir_model = nil
26
+ end
27
+
28
+ def each(context={})
29
+ return to_enum(__callee__) unless block_given?
30
+
31
+ while self.next(context)
32
+ next if skip?
33
+ yield current_dir_model
34
+ end
35
+ end
36
+
37
+ def next(context={})
38
+ return if end?
39
+
40
+ context = context.to_h.reverse_merge(self.context)
41
+ @previous_dir_model = current_dir_model
42
+ @current_dir_model = import_dir_model_class.next(path, context, previous_dir_model)
43
+ @index += 1
44
+ @current_dir_model = @index = nil if end?
45
+
46
+ current_dir_model
47
+ end
48
+
49
+ private
50
+
51
+ def skip?
52
+ !!current_dir_model.try(:skip?)
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,80 @@
1
+ module DirModel
2
+ module Import
3
+ class Path # Csv
4
+
5
+ attr_reader :path
6
+ attr_reader :index
7
+ attr_reader :current_path
8
+ attr_reader :previous_path
9
+
10
+ def initialize(path)
11
+ @path = path
12
+ reset!
13
+ end
14
+
15
+ def size
16
+ @size ||= ruby_path.size
17
+ end
18
+
19
+ def reset!
20
+ @index = -1
21
+ @current_path = @ruby_path = @previous_path = nil
22
+ end
23
+
24
+ def start?
25
+ index == -1
26
+ end
27
+
28
+ def end?
29
+ index.nil?
30
+ end
31
+
32
+ def next_path
33
+ @next_path ||= _read_path
34
+ end
35
+
36
+ def read_path
37
+ @previous_path = @current_path
38
+ unless caching_value?
39
+ @current_path = _read_path { forward! }
40
+ end
41
+ current_path
42
+ end
43
+
44
+ protected
45
+
46
+ def caching_value?
47
+ if @next_path
48
+ @current_path = @next_path
49
+ @next_path = nil
50
+ forward!
51
+ true
52
+ else
53
+ false
54
+ end
55
+ end
56
+
57
+ def ruby_path
58
+ @ruby_path ||= Pathname.glob("#{path}/**/*").each
59
+ end
60
+
61
+ def _read_path
62
+ path = ruby_path.next.to_path
63
+ yield if block_given?
64
+ path
65
+ rescue StopIteration
66
+ set_end
67
+ nil
68
+ end
69
+
70
+ def forward!
71
+ @index += 1
72
+ end
73
+
74
+ def set_end
75
+ @current_path = @index = nil
76
+ end
77
+
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,73 @@
1
+ module DirModel
2
+ module Import
3
+ extend ActiveSupport::Concern
4
+
5
+ attr_reader :context, :source_path, :index, :previous
6
+
7
+ def initialize(path, options={})
8
+ @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]
17
+ end
18
+
19
+ def image
20
+ File.open(source_path)
21
+ end
22
+
23
+ def skip?
24
+ load
25
+ !@_match
26
+ end
27
+
28
+ def method_missing(name, *args, &block)
29
+ load
30
+ matches[name]
31
+ rescue IndexError
32
+ super
33
+ end
34
+
35
+ module ClassMethods
36
+ def next(path, context={}, previous=nil)
37
+ path.read_path
38
+ new(path.current_path, index: path.index, context: context, previous: previous)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :load_state, :file_infos
45
+
46
+ def match?
47
+ return if load_state == :loaded
48
+
49
+ @_match ||= begin
50
+ loader do
51
+ self.class.file_names.each do |file_name|
52
+ options = self.class.options(file_name)
53
+
54
+ if match = (source_path||'').match(options[:regex].call)
55
+ @file_infos = { file: file_name, options: options.merge(match: match) }
56
+ return true
57
+ end
58
+ end
59
+ false
60
+ end
61
+ end
62
+ end
63
+ alias_method :load, :match?
64
+
65
+ def loader
66
+ @load_state = :loading
67
+ result = yield
68
+ @load_state = :loaded
69
+ result
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,38 @@
1
+ module DirModel
2
+ module Model
3
+ module Files
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include InheritedClassVar
8
+ inherited_class_hash :files
9
+ end
10
+
11
+ module ClassMethods
12
+ # @return [Array<Symbol>] file names for the row model
13
+ def file_names
14
+ files.keys
15
+ end
16
+
17
+ # @param [Symbol] file_name name of file to find option
18
+ # @return [Hash] options for the file_name
19
+ def options(file_name)
20
+ files[file_name]
21
+ end
22
+
23
+ # @param [Symbol] file_name name of file to find index
24
+ # @return [Integer] index of the file_name
25
+ def index(file_name)
26
+ file_names.index file_name
27
+ end
28
+
29
+ protected
30
+
31
+ def file(file_name, options={})
32
+ merge_files(file_name.to_sym => options)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ module DirModel
2
+ module Model
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Utils
7
+ include Files
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module DirModel
2
- VERSION = "0.2.0"
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/dir_model.rb CHANGED
@@ -1,37 +1,20 @@
1
+ require 'inherited_class_var'
2
+
1
3
  require 'dir_model/version'
2
4
 
3
5
  require 'active_support/concern'
4
6
 
5
7
  require 'dir_model/utils'
6
8
 
7
- require 'dir_model/core_ext/dir'
8
- require 'dir_model/core_ext/zip_dir/zipper'
9
+ require 'dir_model/model'
10
+ require 'dir_model/model/files'
9
11
 
10
12
  require 'dir_model/export'
11
13
  require 'dir_model/export/aggregate_dir'
12
14
 
13
- require 'inherited_class_var'
15
+ require 'dir_model/import'
16
+ require 'dir_model/import/dir'
17
+ require 'dir_model/import/path'
14
18
 
15
19
  module DirModel
16
- extend ActiveSupport::Concern
17
-
18
- included do
19
- include Utils
20
- include InheritedClassVar
21
- inherited_class_hash :files
22
- end
23
-
24
- module ClassMethods
25
-
26
- # @return [Array<Symbol>] file names
27
- def file_names
28
- files.keys
29
- end
30
-
31
- protected
32
-
33
- def file(file_name, options={})
34
- merge_files(file_name.to_sym => options)
35
- end
36
- end
37
20
  end
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.2.0
4
+ version: 0.3.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-11-19 00:00:00.000000000 Z
11
+ date: 2015-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fastimage
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.8'
41
55
  description:
42
56
  email:
43
57
  - hello@stevenchung.ca
@@ -58,10 +72,13 @@ files:
58
72
  - bin/setup
59
73
  - dir_model.gemspec
60
74
  - lib/dir_model.rb
61
- - lib/dir_model/core_ext/dir.rb
62
- - lib/dir_model/core_ext/zip_dir/zipper.rb
63
75
  - lib/dir_model/export.rb
64
76
  - lib/dir_model/export/aggregate_dir.rb
77
+ - lib/dir_model/import.rb
78
+ - lib/dir_model/import/dir.rb
79
+ - lib/dir_model/import/path.rb
80
+ - lib/dir_model/model.rb
81
+ - lib/dir_model/model/files.rb
65
82
  - lib/dir_model/utils.rb
66
83
  - lib/dir_model/version.rb
67
84
  homepage: https://github.com/FinalCAD/dir_model
@@ -1,10 +0,0 @@
1
- class Dir
2
- class << self
3
- def clean_entries(dir)
4
- entries = entries(dir)
5
- entries.delete '.'
6
- entries.delete '..'
7
- entries
8
- end
9
- end
10
- end
@@ -1,10 +0,0 @@
1
- if defined?(ZipDir)
2
- class ZipDir::Zipper
3
- def add_and_cleanup_dir(dir)
4
- return unless dir.valid?
5
-
6
- dir.entry_paths.each { |path| add_path path }
7
- dir.cleanup
8
- end
9
- end
10
- end