vera 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 +4 -4
- data/Gemfile.lock +4 -1
- data/README.md +14 -1
- data/bin/vera +12 -0
- data/lib/vera.rb +4 -0
- data/lib/vera/exiftool.rb +3 -3
- data/lib/vera/icons.rb +19 -0
- data/lib/vera/lister.rb +4 -0
- data/lib/vera/media.rb +29 -0
- data/lib/vera/mediatype.rb +11 -0
- data/lib/vera/renamer.rb +16 -14
- data/lib/vera/safe.rb +123 -0
- data/lib/vera/timestamp.rb +4 -4
- data/lib/vera/version.rb +1 -1
- data/vera.gemspec +2 -1
- metadata +21 -5
- data/gif/renamer.gif +0 -0
- data/vera-0.1.1.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 017aa63fe7bc5058567a110906bdf079707d561ffd256b0727b54ee23bb8f5e2
|
4
|
+
data.tar.gz: 8d20048815f689d5bf553f4df47ba2d7337f6bb221a0e2a1c0168c15af0763b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 288bee8f35014fbb71b2bbfdfd6aa53fde38e865301fcf0355243d8f019557e2d8e2d7fc77c6445b7f23ab3595f42ebb8560a5357b79cd06b08438c8e84583d9
|
7
|
+
data.tar.gz: 1925c8dac7c1d6231708822bcb1dea6cd8baa330e20db088f0284afc2e963f9ad43d99e60593645356fadcb7756a6074e05b47844cf8fe7083546c0bc3f41451
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
vera (0.
|
4
|
+
vera (0.3.0)
|
5
|
+
colorize
|
5
6
|
commander
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
10
11
|
ast (2.4.2)
|
12
|
+
colorize (0.8.1)
|
11
13
|
commander (4.5.2)
|
12
14
|
highline (~> 2.0.0)
|
13
15
|
diff-lcs (1.4.4)
|
@@ -47,6 +49,7 @@ GEM
|
|
47
49
|
unicode-display_width (2.0.0)
|
48
50
|
|
49
51
|
PLATFORMS
|
52
|
+
ruby
|
50
53
|
x86_64-darwin-19
|
51
54
|
|
52
55
|
DEPENDENCIES
|
data/README.md
CHANGED
@@ -57,9 +57,22 @@ This command works on JPG, MOV, HEIC and ARW files.
|
|
57
57
|
|
58
58
|

|
59
59
|
|
60
|
+
### Safe
|
61
|
+
|
62
|
+
Should I delete all this media files? Is it **safe**? This command helps you understand that. This command will find the files even if you have changed the original file name of the files.
|
63
|
+
|
64
|
+
```bash
|
65
|
+
# Are all the media files in Folder backed up in MY_EXTERNAL_HD?
|
66
|
+
vera safe --path="Folder" --backup="/Volumes/MY_EXTERNAL_HD"
|
67
|
+
```
|
68
|
+
|
69
|
+
You can see it working here:
|
70
|
+
|
71
|
+

|
72
|
+
|
60
73
|
If you want to add more commands, feel free to contribute with a PR to Vera. In the next section I explain how to start working on it.
|
61
74
|
|
62
|
-
##
|
75
|
+
## Development
|
63
76
|
|
64
77
|
After checking out the repo, run `install.sh` to install dependencies. Then, run `rake spec` to run the tests.
|
65
78
|
|
data/bin/vera
CHANGED
@@ -31,3 +31,15 @@ command :rename do |c|
|
|
31
31
|
Vera::Renamer::execute(options)
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
35
|
+
command :safe do |c|
|
36
|
+
c.syntax = 'vera safe [options] --backup="/backupFolder"'
|
37
|
+
c.summary = 'Are this media files safe to delete?'
|
38
|
+
c.description = 'Searches if all the files in the current folder are in your backup folder recursevely.'
|
39
|
+
c.example 'description', 'vera safe --backup="/backupFolder"'
|
40
|
+
c.option '--path PATH', 'Where to execute the command. Default value is the current directory.'
|
41
|
+
c.option '--backup PATH', 'Your backup folder'
|
42
|
+
c.action do |args, options|
|
43
|
+
Vera::Safe::execute(options)
|
44
|
+
end
|
45
|
+
end
|
data/lib/vera.rb
CHANGED
data/lib/vera/exiftool.rb
CHANGED
@@ -6,12 +6,12 @@ module Vera
|
|
6
6
|
`exiftool "-FileCreateDate<#{date_property}" "-FileModifyDate<#{date_property}" #{files_string} 2>/dev/null`
|
7
7
|
end
|
8
8
|
|
9
|
-
def self.
|
10
|
-
system(
|
9
|
+
def self.installed?
|
10
|
+
system('which exiftool >/dev/null')
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.change_filename_with_date(date_property, files_string)
|
14
|
-
system("exiftool '-FileName<$#{date_property}-$filename' -d \"%Y-%m-%d\" #{
|
14
|
+
system("exiftool '-FileName<$#{date_property}-$filename' -d \"%Y-%m-%d\" #{files_string} 2>/dev/null")
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/vera/icons.rb
ADDED
data/lib/vera/lister.rb
CHANGED
@@ -7,5 +7,9 @@ module Vera
|
|
7
7
|
.map { |file| { path: "#{path}/#{file}", filename: file } }
|
8
8
|
.select { |file| ext == File.extname(file[:filename]).gsub('.', '') }
|
9
9
|
end
|
10
|
+
|
11
|
+
def self.all_media_files_recursive(path)
|
12
|
+
`find #{path.gsub(' ', '\ ')} -type f | grep -E "#{MediaType.all.join('|')}"`.split("\n")
|
13
|
+
end
|
10
14
|
end
|
11
15
|
end
|
data/lib/vera/media.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
module Vera
|
6
|
+
class Media
|
7
|
+
attr_reader :path, :size
|
8
|
+
|
9
|
+
def initialize(path)
|
10
|
+
@path = path
|
11
|
+
size = File.size(@path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def filename
|
15
|
+
File.basename(@path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def partial_hash
|
19
|
+
chunk_size = 1024 * 5
|
20
|
+
chunk = File.read(@path, chunk_size)
|
21
|
+
Digest::SHA1.hexdigest(chunk)
|
22
|
+
end
|
23
|
+
|
24
|
+
def real_hash
|
25
|
+
chunk = File.read(@path)
|
26
|
+
Digest::SHA1.hexdigest(chunk)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/vera/renamer.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Vera
|
2
4
|
class Renamer
|
3
5
|
def self.execute(options)
|
4
|
-
unless Exiftool.
|
5
|
-
puts "
|
6
|
+
unless Exiftool.installed?
|
7
|
+
puts ''"
|
6
8
|
You need to install exiftool to use vera. You can run the following command to do it:
|
7
9
|
bash <(curl -Ls https://git.io/JtbuH)
|
8
|
-
"
|
10
|
+
"''
|
9
11
|
return
|
10
12
|
end
|
11
13
|
path = options.path
|
@@ -14,27 +16,27 @@ module Vera
|
|
14
16
|
rename path
|
15
17
|
end
|
16
18
|
|
17
|
-
def self.rename
|
18
|
-
rename_files_with_date path,
|
19
|
-
rename_files_with_date path,
|
20
|
-
rename_files_with_date path,
|
21
|
-
rename_files_with_date path,
|
19
|
+
def self.rename(path)
|
20
|
+
rename_files_with_date path, 'ARW', 'DateTimeOriginal'
|
21
|
+
rename_files_with_date path, 'JPG', 'DateTimeOriginal'
|
22
|
+
rename_files_with_date path, 'HEIC', 'DateTimeOriginal'
|
23
|
+
rename_files_with_date path, 'MOV', 'CreationDate'
|
22
24
|
end
|
23
25
|
|
24
|
-
def self.rename_files_with_date
|
25
|
-
puts "
|
26
|
+
def self.rename_files_with_date(path, ext, date_property)
|
27
|
+
puts "#{Icons.check} Adding creation date to #{ext} files in the filename"
|
26
28
|
files = Lister.all_files(path, ext)
|
27
29
|
files = Renamer.exclude_already_renamed_files(files)
|
28
30
|
if files.empty?
|
29
31
|
puts "No files to rename for #{ext} file type."
|
30
32
|
return
|
31
33
|
end
|
32
|
-
files_string = files.map { |f| "\"#{f[:path]}\"" }.join(
|
33
|
-
puts "
|
34
|
+
files_string = files.map { |f| "\"#{f[:path]}\"" }.join(' ')
|
35
|
+
puts "#{Icons.cross} Something went wrong" unless Exiftool.change_filename_with_date(date_property, files_string)
|
34
36
|
end
|
35
37
|
|
36
|
-
def self.exclude_already_renamed_files
|
37
|
-
files.select { |f| f[:filename].match(/\d
|
38
|
+
def self.exclude_already_renamed_files(files)
|
39
|
+
files.select { |f| f[:filename].match(/\d+-\d+-\d+-/).nil? }
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
data/lib/vera/safe.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'colorize'
|
3
|
+
|
4
|
+
module Vera
|
5
|
+
class Safe
|
6
|
+
def self.execute(options)
|
7
|
+
unless Exiftool.installed?
|
8
|
+
puts "
|
9
|
+
You need to install exiftool to use vera. You can run the following command to do it:
|
10
|
+
bash <(curl -Ls https://git.io/JtbuH)
|
11
|
+
"
|
12
|
+
return
|
13
|
+
end
|
14
|
+
path = options.path
|
15
|
+
path = Dir.pwd if options.path.nil?
|
16
|
+
path = File.expand_path(path)
|
17
|
+
backup_path = File.expand_path(options.backup)
|
18
|
+
|
19
|
+
unless File.directory?(path)
|
20
|
+
puts "#{path} is not a valid directory.".red
|
21
|
+
return
|
22
|
+
end
|
23
|
+
|
24
|
+
unless File.directory?(backup_path)
|
25
|
+
puts "#{backup_path} is not a valid directory.".red
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
29
|
+
safe_to_delete_path? path, backup_path
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.safe_to_delete_path?(path, backup_path)
|
33
|
+
backup_media_files = Lister.all_media_files_recursive(backup_path)
|
34
|
+
.map { |f| Media.new(f) }
|
35
|
+
|
36
|
+
media_files = Lister.all_media_files_recursive(path)
|
37
|
+
.map { |f| Media.new(f) }
|
38
|
+
|
39
|
+
print_folders(path, backup_path)
|
40
|
+
print_number_of_files(media_files, backup_media_files)
|
41
|
+
|
42
|
+
select_candidates = candidates_by_file_size(media_files, backup_media_files)
|
43
|
+
found_files = candidates_by_partial_hash(select_candidates)
|
44
|
+
|
45
|
+
print_list_of_files(found_files, backup_path)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.candidates_by_file_size(media_files, backup_media_files)
|
49
|
+
media_files.map do |media|
|
50
|
+
{
|
51
|
+
media: media,
|
52
|
+
candidates: backup_media_files.select { |c| c.size == media.size }
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.candidates_by_partial_hash(media_files)
|
58
|
+
media_files.map do |hash|
|
59
|
+
media = hash[:media]
|
60
|
+
file_found = hash[:candidates].find do |m|
|
61
|
+
media.partial_hash == m.partial_hash
|
62
|
+
end
|
63
|
+
|
64
|
+
{
|
65
|
+
media: media,
|
66
|
+
file_found: file_found,
|
67
|
+
found: !file_found.nil?
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.print_folders(path, backup_path)
|
73
|
+
message = "Trying to find #{path} files in #{backup_path}"
|
74
|
+
|
75
|
+
print_separator message.length
|
76
|
+
puts message.yellow
|
77
|
+
print_separator message.length
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.print_number_of_files(media_files, backup_files)
|
81
|
+
backup_message = "In a total of #{backup_files.length} media files in your backup folder..."
|
82
|
+
|
83
|
+
print_separator backup_message.length
|
84
|
+
puts "Searching #{media_files.length} media files...".yellow
|
85
|
+
puts backup_message.yellow
|
86
|
+
print_separator backup_message.length
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.print_separator length
|
90
|
+
length.times { print "-" }
|
91
|
+
print "\n"
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.print_list_of_files(files, backup_dir)
|
95
|
+
found_message = "#{Icons.check} #{files.select { |f| f[:found] }.length } file(s) found"
|
96
|
+
not_found_message = "#{Icons.cross} #{files.reject { |f| f[:found] }.length } file(s) not found"
|
97
|
+
|
98
|
+
files.sort_by { |x| [(x[:found] ? 0 : 1), x[:path]] }
|
99
|
+
.each do |f|
|
100
|
+
found = f[:found]
|
101
|
+
found_in = f[:file_found].path.gsub(backup_dir, '')
|
102
|
+
filename = f[:media].filename.ljust(15, ' ')
|
103
|
+
|
104
|
+
puts "#{Icons.check} #{filename} #{Icons.arrow} #{found_in}" if found
|
105
|
+
puts "#{Icons.cross} #{filename} not found." unless found
|
106
|
+
end
|
107
|
+
|
108
|
+
print_separator not_found_message.length
|
109
|
+
puts found_message
|
110
|
+
puts not_found_message
|
111
|
+
print_separator not_found_message.length
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.filter_real_hash(hash)
|
115
|
+
{
|
116
|
+
media: hash[:media],
|
117
|
+
candidates: hash[:candidates].find do |m|
|
118
|
+
media.real_hash == m.real_hash
|
119
|
+
end
|
120
|
+
}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/vera/timestamp.rb
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
module Vera
|
4
4
|
class Timestamp
|
5
5
|
def self.execute(options)
|
6
|
-
unless Exiftool.
|
7
|
-
puts "
|
6
|
+
unless Exiftool.installed?
|
7
|
+
puts ''"
|
8
8
|
You need to install exiftool to use vera. You can run the following command to do it:
|
9
9
|
bash <(curl -Ls https://git.io/JtbuH)
|
10
|
-
"
|
10
|
+
"''
|
11
11
|
return
|
12
12
|
end
|
13
13
|
path = options.path
|
@@ -25,7 +25,7 @@ module Vera
|
|
25
25
|
|
26
26
|
def self.rename_files_with_date(path, ext, date_property)
|
27
27
|
files = Lister.all_files(path, ext)
|
28
|
-
puts "
|
28
|
+
puts "#{Icons.check} Correcting timestamp for #{files.length} #{ext} files..."
|
29
29
|
if files.empty?
|
30
30
|
puts 'Nothing to do here'
|
31
31
|
return
|
data/lib/vera/version.rb
CHANGED
data/vera.gemspec
CHANGED
@@ -17,12 +17,13 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.require_paths = ['lib']
|
18
18
|
|
19
19
|
spec.add_dependency 'commander'
|
20
|
+
spec.add_dependency 'colorize'
|
20
21
|
|
21
22
|
spec.add_development_dependency 'rake', '~> 13.0'
|
22
23
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
23
24
|
spec.add_development_dependency 'rubocop', '~> 1.7'
|
24
25
|
|
25
|
-
spec.files = Dir['./**/*'].reject { |file| file =~ %r{\./(bin|log|pkg|script|spec|test|vendor)} }
|
26
|
+
spec.files = Dir['./**/*'].reject { |file| file =~ %r{\./(bin|log|pkg|script|spec|test|vendor|gif)} }
|
26
27
|
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
27
28
|
spec.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
28
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vera
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Cortés
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: commander
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: colorize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,15 +94,17 @@ files:
|
|
80
94
|
- "./LICENSE.txt"
|
81
95
|
- "./README.md"
|
82
96
|
- "./Rakefile"
|
83
|
-
- "./gif/renamer.gif"
|
84
97
|
- "./install.sh"
|
85
98
|
- "./lib/vera.rb"
|
86
99
|
- "./lib/vera/exiftool.rb"
|
100
|
+
- "./lib/vera/icons.rb"
|
87
101
|
- "./lib/vera/lister.rb"
|
102
|
+
- "./lib/vera/media.rb"
|
103
|
+
- "./lib/vera/mediatype.rb"
|
88
104
|
- "./lib/vera/renamer.rb"
|
105
|
+
- "./lib/vera/safe.rb"
|
89
106
|
- "./lib/vera/timestamp.rb"
|
90
107
|
- "./lib/vera/version.rb"
|
91
|
-
- "./vera-0.1.1.gem"
|
92
108
|
- "./vera.gemspec"
|
93
109
|
- "./vera.jpg"
|
94
110
|
- bin/vera
|
@@ -113,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
129
|
- !ruby/object:Gem::Version
|
114
130
|
version: '0'
|
115
131
|
requirements: []
|
116
|
-
rubygems_version: 3.
|
132
|
+
rubygems_version: 3.1.2
|
117
133
|
signing_key:
|
118
134
|
specification_version: 4
|
119
135
|
summary: CLI tool to organize and manage media files
|
data/gif/renamer.gif
DELETED
Binary file
|
data/vera-0.1.1.gem
DELETED
Binary file
|