photein 0.1.4 → 0.1.6

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
  SHA256:
3
- metadata.gz: 4c649546f68f5f0547d94bc0dace264051b1b1fd4f37620e7a769939bc6330cd
4
- data.tar.gz: 0e57a9fff26bf6aab6a49676cea4cf3213626693013ce80e4a9d616051e96091
3
+ metadata.gz: 3490aa4f980df5aed87bc73a127ab9908229edb18e5369377e75c459704f91f5
4
+ data.tar.gz: 4fac58b8aaaf96eda55b07496e7b0fc99bb347863ffe3d50ad75429f7f9940f8
5
5
  SHA512:
6
- metadata.gz: '072889b598976c14a89994fe61ecd24c47f73d34e3f8c090df002ddb92684ca145285bf7b891e98023f0947ed04e602b0335dc0504dcddfe8dba1b7689d1911d'
7
- data.tar.gz: e355d41fe3ce4c9bf86ac243524abecac43f595df2eb67f43344098a0e3348edad55ab43af6746efd421021c53706aed0f0b76b1cfe63dfcefb8cdc69ad53174
6
+ metadata.gz: 8a414155ee73eac20adf275cb57d593f433531b7e7c70390b5cfa887e16b1e2247f39aea0e31cecc1e2e31b8cd0e093e640c3cf3558ced57a3573893540a8e71
7
+ data.tar.gz: c8187a8cfa3f54bf5e2e1e1c9ea8ba4ccd02242fee55b220f8528380c77f8f1c7769bac0e497bf129bbd5a895640124360f8b74ec06d7423236ff052dd2d067c
data/lib/photein/image.rb CHANGED
@@ -85,8 +85,8 @@ module Photein
85
85
  Time.strptime(filename, 'IMG-%Y%m%d-WA%M%S')
86
86
  when /^IMG_\d{8}_\d{6}_\d{3}$/ # Telegram: datetime in milliseconds (at download)
87
87
  Time.strptime(filename, 'IMG_%Y%m%d_%H%M%S_%L')
88
- when /^signal-\d{4}(-\d{2}){5}[-\d]*$/ # Signal: datetime + optional counter (at receipt)
89
- Time.strptime(filename[0, 26], 'signal-%F-%H-%M-%S')
88
+ when /^signal-\d{4}-\d{2}-\d{2}-\d{6}( \(\d+\))?$/ # Signal: datetime + optional counter (at receipt)
89
+ Time.strptime(filename[0, 24], 'signal-%F-%H%M%S')
90
90
  when /^\d{13}$/ # LINE: UNIX time in milliseconds (at download)
91
91
  Time.strptime(filename[0..-4], '%s')
92
92
  else
@@ -54,9 +54,10 @@ module Photein
54
54
  FileUtils.chmod('-x', dest_path, noop: Photein::Config.dry_run)
55
55
  end
56
56
  end
57
- end.compact.each(&:join)
58
-
59
- FileUtils.rm(path, noop: Photein::Config.dry_run || Photein::Config.keep)
57
+ end.compact.map(&:join).then do |threads|
58
+ # e.g.: with --library-web only, .dngs are skipped, so DON'T DELETE!
59
+ FileUtils.rm(path, noop: threads.empty? || Photein::Config.dry_run || Photein::Config.keep)
60
+ end
60
61
  end
61
62
 
62
63
  private
@@ -106,25 +107,22 @@ module Photein
106
107
  @extname ||= NORMAL_EXTNAME_MAP[path.extname.downcase] || path.extname.downcase
107
108
  end
108
109
 
109
- def resolve_name_collision(filename)
110
- raise ArgumentError, 'Invalid filename' if filename.to_s.include?('*')
111
-
112
- collision_glob = Pathname(filename).sub_ext("*#{filename.extname}")
113
-
114
- case Dir[collision_glob].length
115
- when 0 # if no files found, no biggie
116
- when 1 # if one file found, WITH OR WITHOUT COUNTER, reset counter to a
117
- if Dir[collision_glob].first != collision_glob.sub('*', 'a') # don't try if it's already a lone, correctly-countered file
118
- Photein.logger.info('conflicting timestamp found; adding counter to existing file')
119
- FileUtils.mv(Dir[collision_glob].first, collision_glob.sub('*', 'a'), noop: Photein::Config.dry_run)
120
- end
121
- else # TODO: if multiple files found, rectify them?
110
+ def resolve_name_collision(pathname)
111
+ raise ArgumentError, 'Invalid filename' if pathname.to_s.include?('*')
112
+
113
+ collisions = Dir[pathname.sub_ext("*#{pathname.extname}")]
114
+
115
+ case collisions.length
116
+ when 0
117
+ return pathname
118
+ when 1
119
+ return pathname.sub_ext("+1#{pathname.extname}")
120
+ else # TODO: what to do for heterogeneous suffixes?
121
+ collisions.tap { |c| c.delete(pathname.to_s) }.max
122
+ .slice(/(?<=^#{pathname.to_s.delete_suffix(pathname.extname)}).*(?=#{pathname.extname}$)/)
123
+ .tap { |counter| raise 'Unresolved timestamp conflict' unless counter&.match?(/^\+[1-8]$/) }
124
+ .then { |counter| pathname.sub_ext("#{counter.next}#{pathname.extname}") }
122
125
  end
123
-
124
- # return the next usable filename
125
- Dir[collision_glob].max&.slice(/.(?=#{Regexp.escape(collision_glob.extname)})/)&.next
126
- .tap { |counter| raise 'Unresolved timestamp conflict' unless [*Array('a'..'z'), nil].include?(counter) }
127
- .then { |counter| filename.sub_ext("#{counter}#{filename.extname}") }
128
126
  end
129
127
 
130
128
  class << self
@@ -132,7 +130,7 @@ module Photein
132
130
  file = Pathname(file)
133
131
  raise Errno::ENOENT, "#{file}" unless file.exist?
134
132
 
135
- [Image, Video].find { |type| type::SUPPORTED_FORMATS.include?(file.extname) }
133
+ [Image, Video].find { |type| type::SUPPORTED_FORMATS.include?(file.extname.downcase) }
136
134
  .tap { |type| raise ArgumentError, "#{file}: Invalid media file" if type.nil? }
137
135
  .then { |type| type.new(file) }
138
136
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Photein
4
- VERSION = '0.1.4'
4
+ VERSION = '0.1.6'
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: photein
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Lue
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-30 00:00:00.000000000 Z
11
+ date: 2024-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logger
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: mediainfo
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,48 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ostruct
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.6'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.6'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pstore
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.1'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.1'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rexml
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.4'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.4'
83
139
  - !ruby/object:Gem::Dependency
84
140
  name: streamio-ffmpeg
85
141
  requirement: !ruby/object:Gem::Requirement
@@ -159,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
215
  - !ruby/object:Gem::Version
160
216
  version: '0'
161
217
  requirements: []
162
- rubygems_version: 3.3.7
218
+ rubygems_version: 3.5.16
163
219
  signing_key:
164
220
  specification_version: 4
165
221
  summary: Import/rename photos & videos from one directory to another.