android_file_sorter 1.0.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 +7 -0
- data/bin/android_file_sorter +5 -0
- data/lib/android_file_sorter.rb +20 -0
- data/lib/android_file_sorter/description.rb +32 -0
- data/lib/android_file_sorter/directory_statistic.rb +48 -0
- data/lib/android_file_sorter/entries_validator.rb +57 -0
- data/lib/android_file_sorter/file_renamer.rb +86 -0
- metadata +71 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d9fb4eaf951e6d95590e161669d09c9f5a21ec28
|
4
|
+
data.tar.gz: ef6020b61e28e6c08c15d6a707c8e35c4b709971
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 990f7426d0d7c7aa6b249a2ea1cd75c2f6bc7d0b27f5cbca213dcf0237a43f00a8d19e7ae8b39f5552da2c4e887563cbd16ea617f5c545eb3e92937be977f49e
|
7
|
+
data.tar.gz: 7de11f598f8a04d95899a013c4e3888f59236ebfdc23dff6eea89e2b27f5fe13f7db9676cb6205a4add28da537f614b2f34e2e2955407b88d1d8b2998d62ed12
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "android_file_sorter/directory_statistic"
|
2
|
+
require "android_file_sorter/entries_validator"
|
3
|
+
require "android_file_sorter/description"
|
4
|
+
require "android_file_sorter/file_renamer"
|
5
|
+
require "time"
|
6
|
+
|
7
|
+
class AndroidFileSorter
|
8
|
+
|
9
|
+
def initialize(current_directory)
|
10
|
+
@cwd = current_directory
|
11
|
+
end
|
12
|
+
|
13
|
+
def rename_all
|
14
|
+
EntriesValidator.new(@cwd).validate_entries
|
15
|
+
DirectoryStatistic.new(@cwd).render_stats
|
16
|
+
FileRenamer.new(@cwd).process_files
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Description
|
2
|
+
|
3
|
+
def documentation
|
4
|
+
puts <<-DOC
|
5
|
+
|
6
|
+
How do your files get renamed?
|
7
|
+
------------------------------
|
8
|
+
You are naming filesets, not files. That means that if you have eleven files recorded on the
|
9
|
+
same day, after your provide your new name e.g. "My birthday", all files recorded on the same day
|
10
|
+
will be renamed to "My_birthday".
|
11
|
+
For convenience, AnroidFileSorter will give each file a number "My_birthday_1" and remove a time stamp.
|
12
|
+
This way, you will still know the order in which files were recorded (pictures or videos taken).
|
13
|
+
Final name will include a date stamp however, so our example files will be named
|
14
|
+
"My_birthday_2015-08-15_Tue_1".
|
15
|
+
|
16
|
+
DOC
|
17
|
+
end
|
18
|
+
|
19
|
+
def options
|
20
|
+
puts <<-OPTIONS
|
21
|
+
Proceed with renaming your files:
|
22
|
+
- [ l ] leave a fileset as is
|
23
|
+
- [ a ] let AFS name files for you
|
24
|
+
- [ d ] show documentation
|
25
|
+
- [ e ] exit program
|
26
|
+
- [ r ] rename files yourself
|
27
|
+
|
28
|
+
OPTIONS
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class DirectoryStatistic
|
2
|
+
|
3
|
+
def initialize(current_directory)
|
4
|
+
@user_files = Dir.entries(current_directory).select { |file| ![ ".", "..", ".DS_Store"].include?(file) }
|
5
|
+
@stats = { dates: {},
|
6
|
+
formats: {},
|
7
|
+
sum: 0 }
|
8
|
+
end
|
9
|
+
|
10
|
+
def render_stats
|
11
|
+
compile_statistic
|
12
|
+
|
13
|
+
if @stats[:sum].zero?
|
14
|
+
puts "Your directory is empty. Please put some files in it."
|
15
|
+
exit
|
16
|
+
else
|
17
|
+
puts "Total number of all files: #{@stats[:sum]}"
|
18
|
+
puts "Formats:"
|
19
|
+
@stats[:formats].each { |format, count| puts(" #{format}: #{count}") }
|
20
|
+
puts "Dates:"
|
21
|
+
@stats[:dates].each { |date, count| puts(" #{date}: #{count}") }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def compile_statistic
|
28
|
+
@user_files.each do |file|
|
29
|
+
count_format(file.split(".").last.to_sym)
|
30
|
+
count_date(DateTime.parse(file.split("_").first))
|
31
|
+
@stats[:sum] += 1
|
32
|
+
end
|
33
|
+
@stats
|
34
|
+
end
|
35
|
+
|
36
|
+
def count_format(format)
|
37
|
+
formats = @stats[:formats]
|
38
|
+
@stats[:formats][format] = formats.has_key?(format) ? formats[format] + 1 : 1
|
39
|
+
end
|
40
|
+
|
41
|
+
def count_date(date_time)
|
42
|
+
date = date_time.strftime("%Y-%m-%d").to_sym
|
43
|
+
dates = @stats[:dates]
|
44
|
+
@stats[:dates][date] = dates.has_key?(date) ? dates[date] + 1 : 1
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class EntriesValidator
|
2
|
+
|
3
|
+
def initialize(current_directory)
|
4
|
+
@cwd = current_directory
|
5
|
+
@valid_formats = [ "jpg", "mp4" ]
|
6
|
+
@system_files = [ ".", "..", ".DS_Store" ]
|
7
|
+
end
|
8
|
+
|
9
|
+
def validate_entries
|
10
|
+
user_files = Dir.entries(@cwd).select { |file| !@system_files.include?(file) }
|
11
|
+
filtered_entries = filter_entries(user_files)
|
12
|
+
if invalid_entries?(filtered_entries)
|
13
|
+
notify_user(filtered_entries)
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def filter_entries(user_files)
|
21
|
+
invalid_entries = {
|
22
|
+
dirs: [],
|
23
|
+
invalid_formats: [],
|
24
|
+
invalid_lengths: []
|
25
|
+
}
|
26
|
+
user_files.each do |e|
|
27
|
+
if Dir.exist?(e)
|
28
|
+
invalid_entries[:dirs] << e
|
29
|
+
elsif !@valid_formats.include?(e.split(".").last)
|
30
|
+
invalid_entries[:invalid_formats] << e
|
31
|
+
elsif e.length != 19
|
32
|
+
invalid_entries[:invalid_lengths] << e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
invalid_entries
|
36
|
+
end
|
37
|
+
|
38
|
+
def invalid_entries?(entries)
|
39
|
+
entries.values.each { |val| return true unless val.empty? }
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
def notify_user(entries)
|
44
|
+
dir_count = entries[:dirs].count
|
45
|
+
invalid_formats = entries[:invalid_formats].count
|
46
|
+
invalid_lengths = entries[:invalid_lengths].count
|
47
|
+
puts "Your directory must be empty."
|
48
|
+
puts "It must not contain any directories or files that are not images or videos."
|
49
|
+
puts "Currently your working directory contains:"
|
50
|
+
puts " directories: #{dir_count}" unless dir_count.zero?
|
51
|
+
puts " files with invalid formats: #{invalid_formats}" unless invalid_formats.zero?
|
52
|
+
puts " files with invalid lengths: #{invalid_lengths}" unless invalid_lengths.zero?
|
53
|
+
puts "Please empty your directory. Afterwards, copy your images into it."
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
class FileRenamer
|
2
|
+
include Description
|
3
|
+
|
4
|
+
def initialize(current_directory)
|
5
|
+
@cwd = current_directory
|
6
|
+
@user_files = Dir.entries(@cwd).select { |file| ![ ".", "..", ".DS_Store" ].include?(file) }
|
7
|
+
@filesets = collect_filesets
|
8
|
+
@file_dates = @filesets.keys
|
9
|
+
end
|
10
|
+
|
11
|
+
def process_files
|
12
|
+
documentation
|
13
|
+
rename_files
|
14
|
+
end
|
15
|
+
|
16
|
+
def rename_files
|
17
|
+
options
|
18
|
+
|
19
|
+
loop do
|
20
|
+
date = @file_dates.first
|
21
|
+
puts "Next file set: #{date}."
|
22
|
+
print ">> "
|
23
|
+
|
24
|
+
case gets.chomp
|
25
|
+
when "l"
|
26
|
+
@file_dates.shift
|
27
|
+
when "a"
|
28
|
+
@file_dates.shift
|
29
|
+
automatic_renaming(date)
|
30
|
+
when "d"
|
31
|
+
documentation
|
32
|
+
when "e"
|
33
|
+
puts "Exiting program."
|
34
|
+
exit
|
35
|
+
when "r"
|
36
|
+
@file_dates.shift
|
37
|
+
puts "Enter a fileset name:"
|
38
|
+
print ">> "
|
39
|
+
user_filename = gets.chomp.gsub(/\s/, "_")
|
40
|
+
user_renaming(date, user_filename)
|
41
|
+
else
|
42
|
+
puts "Enter one of the available options."
|
43
|
+
options
|
44
|
+
end
|
45
|
+
|
46
|
+
if @file_dates.empty?
|
47
|
+
puts "All of your files are renamed."
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def automatic_renaming(date)
|
56
|
+
@filesets[date].inject(0) do |memo, file|
|
57
|
+
file_array = file.split(".")
|
58
|
+
timestamp, format = file_array.first, file_array.last
|
59
|
+
datetime = DateTime.parse(timestamp).strftime("%Y-%m-%d_%a")
|
60
|
+
new_filename = "#{datetime}_#{memo += 1}.#{format}"
|
61
|
+
File.rename(file, new_filename)
|
62
|
+
memo
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def user_renaming(date, user_filename)
|
67
|
+
@filesets[date].inject(0) do |memo, file|
|
68
|
+
file_array = file.split(".")
|
69
|
+
timestamp, format = file_array.first, file_array.last
|
70
|
+
day = DateTime.parse(timestamp).strftime("%a")
|
71
|
+
new_filename = "#{user_filename}_#{date}_#{day}_#{memo += 1}.#{format}"
|
72
|
+
File.rename(file, new_filename)
|
73
|
+
memo
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def collect_filesets
|
78
|
+
@user_files.each_with_object({}) do |file, obj|
|
79
|
+
date = DateTime.parse(file.split(".").first).strftime("%Y-%m-%d")
|
80
|
+
obj[date] = [] unless obj[date]
|
81
|
+
obj[date] << file
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: android_file_sorter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- dariodaic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.1.7
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.1.7
|
33
|
+
description: Tiny gem for managing files copied from Android OS 4.3.
|
34
|
+
email:
|
35
|
+
- dariodaic5.1@gmail.com
|
36
|
+
executables:
|
37
|
+
- android_file_sorter
|
38
|
+
extensions: []
|
39
|
+
extra_rdoc_files: []
|
40
|
+
files:
|
41
|
+
- bin/android_file_sorter
|
42
|
+
- lib/android_file_sorter.rb
|
43
|
+
- lib/android_file_sorter/description.rb
|
44
|
+
- lib/android_file_sorter/directory_statistic.rb
|
45
|
+
- lib/android_file_sorter/entries_validator.rb
|
46
|
+
- lib/android_file_sorter/file_renamer.rb
|
47
|
+
homepage:
|
48
|
+
licenses:
|
49
|
+
- MIT
|
50
|
+
metadata: {}
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 2.2.0
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 2.4.8
|
68
|
+
signing_key:
|
69
|
+
specification_version: 4
|
70
|
+
summary: Ruby script for renaming files copied from Android OS 4.3.
|
71
|
+
test_files: []
|