dir_model 0.2.0 → 0.3.0

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