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 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,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "android_file_sorter"
4
+
5
+ AndroidFileSorter.new(Dir.pwd).rename_all
@@ -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: []