imagesorter 1.0.0 → 1.0.1

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: f5ce17c344a92e399f3654dfef66291a1ab44fe5
4
- data.tar.gz: aefc58447eb3ae56149cd7a0190889446680dcd0
3
+ metadata.gz: 64e5b3c929c90c57ea0da7cab2671f5da16b7ce7
4
+ data.tar.gz: 2ccf08ee293fee96fae9db196bb484039b895da9
5
5
  SHA512:
6
- metadata.gz: 5aab53b23f7146ac247d76ca4dd5a8095655363c1277d968522db98677d0a148a696d090c18573cb678c54e5a996549c00009b78bb50ee5d1415b92f933f0d20
7
- data.tar.gz: cdd1a773adc3a435e68455818f5b59241979b4335d4ccc14a64818fe6e6fb82ee2879b49624ccae648541b08216bca371d844c97589de2e182bf50e47c79f8e6
6
+ metadata.gz: a456b17664abb93d4fd8838a1b044bc48748ef37b44f950438db762359b48f290293169e8ef815edd336381dc77cede7db61ae86e51b1542022cceb19ae4e31e
7
+ data.tar.gz: 9f6876751171848f87fe56bce6b8d491b28803025d67117d118fcea493d50b940c58702b9806e0796653dbc56db42442c88ef508b42bdcbcbf15dea1015f6fcc
@@ -1,7 +1,7 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
- TargetRubyVersion: 2.1
4
+ TargetRubyVersion: 2.4
5
5
 
6
6
  Metrics/LineLength:
7
7
  Max: 160
@@ -1,33 +1,21 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2017-08-09 21:58:47 +0300 using RuboCop version 0.49.1.
3
+ # on 2019-11-02 20:56:11 +0200 using RuboCop version 0.76.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 2
9
+ # Offense count: 3
10
10
  Metrics/AbcSize:
11
- Max: 38
11
+ Max: 19
12
12
 
13
- # Offense count: 7
14
- # Configuration parameters: CountComments.
13
+ # Offense count: 5
14
+ # Configuration parameters: CountComments, ExcludedMethods.
15
15
  Metrics/MethodLength:
16
- Max: 54
16
+ Max: 14
17
17
 
18
18
  # Offense count: 1
19
19
  # Configuration parameters: CountKeywordArgs.
20
20
  Metrics/ParameterLists:
21
21
  Max: 7
22
-
23
- # Offense count: 6
24
- Style/Documentation:
25
- Exclude:
26
- - 'spec/**/*'
27
- - 'test/**/*'
28
- - 'lib/imagesorter/file_batch_processor.rb'
29
- - 'lib/imagesorter/file_exif_categorizer.rb'
30
- - 'lib/imagesorter/file_stat_categorizer.rb'
31
- - 'lib/imagesorter/file_system_processor.rb'
32
- - 'lib/imagesorter/gem.rb'
33
- - 'lib/imagesorter/option_parser.rb'
@@ -1,9 +1,9 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.1
5
- - 2.2
6
- - 2.3
4
+ - 2.4
5
+ - 2.5
6
+ - 2.6
7
7
  - ruby-head
8
8
 
9
9
  before_install:
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.0.1] - 2019-11-02
8
+ ### Fixed
9
+ - Added missing require for OptionParser
10
+ ### Added
11
+ - .cr2 extension as a default
12
+ ### Changed
13
+ - Drop support for deprecated Rubies, 2.4 required
14
+
7
15
  ## [1.0.0] - 2017-08-12
8
16
  ### Added
9
17
  - Initial release
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
4
  require 'bundler'
3
5
  require 'rspec/core/rake_task'
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift File.expand_path('lib', __dir__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'imagesorter'
7
- s.version = File.read(File.expand_path('../version', __FILE__)).strip
7
+ s.version = File.read(File.expand_path('version', __dir__)).strip
8
8
  s.description = 'Command line tool for sorting photos and videos'
9
9
  s.summary = 'Command line tool for sorting photos and videos'
10
10
  s.authors = ['Joakim Antman']
@@ -19,16 +19,16 @@ Gem::Specification.new do |s|
19
19
  s.bindir = 'exe'
20
20
  s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
 
22
- s.required_ruby_version = '>= 2.1'
22
+ s.required_ruby_version = '>= 2.4'
23
23
 
24
24
  s.add_dependency 'exifr'
25
25
  s.add_dependency 'progressbar'
26
26
  s.add_dependency 'r18n-core'
27
27
 
28
- s.add_development_dependency 'rubocop'
29
- s.add_development_dependency 'rspec'
30
- s.add_development_dependency 'simplecov'
31
28
  s.add_development_dependency 'bundler'
32
- s.add_development_dependency 'rake'
33
29
  s.add_development_dependency 'pry'
30
+ s.add_development_dependency 'rake'
31
+ s.add_development_dependency 'rspec'
32
+ s.add_development_dependency 'rubocop'
33
+ s.add_development_dependency 'simplecov'
34
34
  end
@@ -5,6 +5,7 @@ require 'fileutils'
5
5
  require 'ostruct'
6
6
  require 'r18n-core'
7
7
  require 'exifr/jpeg'
8
+ require 'json'
8
9
 
9
10
  R18n.set('en')
10
11
 
@@ -12,8 +12,9 @@ module Imagesorter
12
12
 
13
13
  time = exif.date_time
14
14
  return nil if time.nil?
15
+
15
16
  file.time = time
16
- rescue
17
+ rescue StandardError
17
18
  nil
18
19
  end
19
20
  end
@@ -10,6 +10,7 @@ module Imagesorter
10
10
  def process(file)
11
11
  time = file.file.send(@stat)
12
12
  return nil if time.nil?
13
+
13
14
  file.time = time
14
15
  end
15
16
  end
@@ -27,26 +27,18 @@ module Imagesorter
27
27
  rescue Interrupt
28
28
  puts 'FAIL: INTERRUPTED'
29
29
  exit 1
30
- rescue => e
30
+ rescue StandardError => e
31
31
  puts e
32
+ puts e.backtrace
32
33
  exit 2
33
34
  end
34
35
 
35
36
  private
36
37
 
37
38
  def setup_logger
39
+ Imagesorter.logger = Logger.new(@options.logfile) if @options.logfile
38
40
 
39
- if @options.logfile
40
- Imagesorter.logger = Logger.new(@options.logfile)
41
- end
42
-
43
- if @options.verbose == true
44
- Imagesorter.logger.level = Logger::DEBUG
45
- elsif @options.silent == true && !@options.logfile
46
- Imagesorter.logger.level = Logger::FATAL
47
- else
48
- Imagesorter.logger.level = Logger::INFO
49
- end
41
+ Imagesorter.logger.level = resolve_log_level
50
42
 
51
43
  Imagesorter.logger.formatter = proc do |severity, datetime, _progname, msg|
52
44
  date_format = datetime.strftime('%Y-%m-%d %H:%M:%S')
@@ -58,6 +50,14 @@ module Imagesorter
58
50
  end
59
51
  end
60
52
 
53
+ def resolve_log_level
54
+ return Logger::DEBUG if @options.verbose == true
55
+
56
+ return Logger::FATAL if @options.silent == true && !@options.logfile
57
+
58
+ Logger::INFO
59
+ end
60
+
61
61
  def setup_locale
62
62
  R18n.locale(@options.locale)
63
63
  R18n.set(@options.locale)
@@ -65,18 +65,16 @@ module Imagesorter
65
65
 
66
66
  def batch_options
67
67
  options = {
68
- source: @options.source,
69
- recursive: @options.recursive,
68
+ source: @options.source,
69
+ recursive: @options.recursive,
70
70
  extensions: @options.extensions,
71
- processor: Imagesorter::FileSystemProcessor.new(destination: @options.dest,
71
+ processor: Imagesorter::FileSystemProcessor.new(destination: @options.dest,
72
72
  destination_fmt: @options.destination_format,
73
- copy_mode: @options.copy_mode,
74
- test: @options.test)
73
+ copy_mode: @options.copy_mode,
74
+ test: @options.test)
75
75
  }
76
76
 
77
- if progressbar_enabled?
78
- options[:progress_proc] = proc { |progress_options| progress(progress_options) }
79
- end
77
+ options[:progress_proc] = proc { |progress_options| progress(progress_options) } if progressbar_enabled?
80
78
 
81
79
  options
82
80
  end
@@ -88,7 +86,7 @@ module Imagesorter
88
86
  end
89
87
 
90
88
  def finalize
91
- @progressbar.finish if @progressbar
89
+ @progressbar&.finish
92
90
  end
93
91
 
94
92
  def progressbar_enabled?
@@ -54,6 +54,7 @@ module Imagesorter
54
54
 
55
55
  def collect_file_from_dir(dir, file)
56
56
  return if file =~ /^\.\.?$/
57
+
57
58
  full_path = File.join(dir, file)
58
59
 
59
60
  if File.directory?(full_path)
@@ -80,12 +81,11 @@ module Imagesorter
80
81
  queue_categorizing(file)
81
82
  end
82
83
  end
83
- require 'json'
84
+
84
85
  def queue_categorizing(file)
85
86
  queue_job do
86
87
  file.process!(@categorizer)
87
-
88
- Imagesorter.logger.debug "#{file.file.path} metadata: #{JSON.pretty_generate(file.to_h)}"
88
+ # Imagesorter.logger.debug "#{file.file.path} metadata: #{JSON.pretty_generate(file.to_h)}"
89
89
 
90
90
  increment(@categorizer.step_name)
91
91
  queue_proceesing(file)
@@ -94,6 +94,7 @@ module Imagesorter
94
94
 
95
95
  def queue_proceesing(file)
96
96
  return if @processor.nil?
97
+
97
98
  queue_job do
98
99
  file.process!(@processor)
99
100
  increment(@processor.step_name)
@@ -102,6 +103,7 @@ module Imagesorter
102
103
 
103
104
  def increment(step)
104
105
  return if @progress_proc.nil?
106
+
105
107
  @progress_proc.call(step: step.ljust(14, ' '),
106
108
  total_steps: @total_steps)
107
109
  end
@@ -23,39 +23,17 @@ module Imagesorter
23
23
  def process(file)
24
24
  source = file.file.path
25
25
 
26
- destination_params = {
27
- full_name: File.basename(source),
28
- name: File.basename(source, '.*'),
29
- extension: File.extname(source).delete('.')
30
- }
31
-
32
- dest = begin
33
- File.join(@destination, format(l(file.time, @destination_fmt), file.to_h.merge(destination_params)))
34
- rescue KeyError => e
35
- Imagesorter.logger.warn e.message
36
-
37
- key = /^key<(.*)> not found$/.match(e.message)[1]
38
-
39
- unless key.nil?
40
- destination_params[key.to_sym] = ''
41
- retry
42
- else
43
- raise
44
- end
45
- end
46
-
47
- return if dest.nil?
48
-
49
- dest = handle_duplicate(source, dest)
26
+ dest = handle_duplicate(source, format_destination(file, full_name: File.basename(source),
27
+ name: File.basename(source, '.*'),
28
+ extension: File.extname(source).delete('.')))
50
29
 
51
30
  return if dest.nil?
52
31
 
53
- dest_dir = File.dirname(dest)
54
-
55
32
  Imagesorter.logger.info "#{step_name} #{source} to #{dest}"
56
33
 
57
34
  return if @test
58
35
 
36
+ dest_dir = File.dirname(dest)
59
37
  FileUtils.mkdir_p(dest_dir) unless File.directory?(dest_dir)
60
38
 
61
39
  if @copy_mode == :move
@@ -65,7 +43,21 @@ module Imagesorter
65
43
  end
66
44
  end
67
45
 
46
+ def format_destination(file, destination_params)
47
+ File.join(@destination, format(l(file.time, @destination_fmt), file.to_h.merge(destination_params)))
48
+ rescue KeyError => e
49
+ Imagesorter.logger.warn e.message
50
+
51
+ key = /^key<(.*)> not found$/.match(e.message)[1]
52
+
53
+ raise if key.nil?
54
+
55
+ destination_params[key.to_sym] = ''
56
+ retry
57
+ end
58
+
68
59
  def handle_duplicate(source, dest)
60
+ return nil if dest.nil?
69
61
  return dest unless File.exist?(dest)
70
62
 
71
63
  return nil if FileUtils.identical?(source, dest) # skip if identical
@@ -74,7 +66,7 @@ module Imagesorter
74
66
  extname = File.extname(dest)
75
67
  dirname = File.dirname(dest)
76
68
 
77
- sequence = 1 # TODO, Figure out current sequence number
69
+ sequence = 1
78
70
 
79
71
  handle_duplicate(source, File.join(dirname, "#{basename}_#{sequence}#{extname}"))
80
72
  end
@@ -14,7 +14,7 @@ module Imagesorter
14
14
  # Gem related helpers
15
15
  module Gem
16
16
  def self.root
17
- @root ||= File.expand_path('../../..', __FILE__)
17
+ @root ||= File.expand_path('../..', __dir__)
18
18
  end
19
19
 
20
20
  def self.version
@@ -1,19 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'optparse'
4
+
3
5
  module Imagesorter
4
6
  module OptionParser
5
7
  DEFAULT_OPTIONS = {
6
- silent: false,
7
- test: false,
8
+ silent: false,
9
+ test: false,
8
10
  recursive: false,
9
11
  copy_mode: :copy,
10
- threads: 1,
11
- locale: 'en-us',
12
- extensions: %w[JPG JPEG MP4 MOV],
12
+ threads: 1,
13
+ locale: 'en-us',
14
+ extensions: %w[JPG JPEG MP4 MOV PNG CR2],
13
15
  destination_format: '%Y/%m/%d/%{full_name}' # rubocop:disable Style/FormatStringToken
14
16
  }.freeze
15
17
 
16
- def self.parse(argv)
18
+ def self.parse(argv) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
17
19
  options = OpenStruct.new(DEFAULT_OPTIONS)
18
20
 
19
21
  # rubocop:disable Metrics/BlockLength
@@ -81,6 +83,7 @@ module Imagesorter
81
83
  exit
82
84
  end
83
85
  end
86
+ # rubocop:enable Metrics/BlockLength
84
87
 
85
88
  parser.parse!(argv)
86
89
 
@@ -97,6 +100,7 @@ module Imagesorter
97
100
  mandatory = %i[source dest]
98
101
  missing = mandatory.select { |param| options[param].nil? }
99
102
  return if missing.empty?
103
+
100
104
  raise ::OptionParser::MissingArgument, missing.join(', ')
101
105
  end
102
106
  end
data/version CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.0.1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imagesorter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joakim Antman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-12 00:00:00.000000000 Z
11
+ date: 2019-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: exifr
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rubocop
56
+ name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: pry
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: simplecov
84
+ name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: bundler
98
+ name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: rake
112
+ name: rubocop
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -123,7 +123,7 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: pry
126
+ name: simplecov
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -180,7 +180,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
180
180
  requirements:
181
181
  - - ">="
182
182
  - !ruby/object:Gem::Version
183
- version: '2.1'
183
+ version: '2.4'
184
184
  required_rubygems_version: !ruby/object:Gem::Requirement
185
185
  requirements:
186
186
  - - ">="
@@ -188,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
188
  version: '0'
189
189
  requirements: []
190
190
  rubyforge_project:
191
- rubygems_version: 2.4.6
191
+ rubygems_version: 2.6.14
192
192
  signing_key:
193
193
  specification_version: 4
194
194
  summary: Command line tool for sorting photos and videos