dir_size_renamer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ DirSizeRenamer
2
+ ==============
3
+
4
+ This console utility lets you rename subdirectories within a specified directory, so that subdirectories' names contain their sizes.
5
+
6
+ DirSizeRenamer goes through all files within each subfolder recursively, calculating their sizes.
7
+
8
+ What it does
9
+ ------------
10
+
11
+ Directory structure before using DirSizeRenamer:
12
+
13
+ * backups
14
+ * G 2012-04-17 12;40;29 (Full)
15
+ * G 2012-04-18 09;45;04 (Differential)
16
+ * G 2012-04-18 19;15;24 (Differential)
17
+ * G 2012-04-19 19;11;22 (Differential)
18
+ * G 2012-04-20 19;12;22 (Full)
19
+ * G 2012-04-23 19;12;14 (Differential)
20
+ * G 2012-04-24 19;12;15 (Differential)
21
+ * H 2012-04-17 22;08;23 (Full)
22
+ * H 2012-04-18 10;03;33 (Differential)
23
+ * H 2012-04-18 19;35;54 (Differential)
24
+ * H 2012-04-19 19;30;49 (Differential)
25
+ * H 2012-04-21 04;04;29 (Full)
26
+ * H 2012-04-23 19;30;24 (Differential)
27
+ * H 2012-04-24 19;31;37 (Differential)
28
+
29
+ Directory structure after applying DirSizeRenamer to the `backups` folder:
30
+
31
+ * backups
32
+ * G 2012-04-17 12;40;29 (Full) [466.965GB]
33
+ * G 2012-04-18 09;45;04 (Differential) [965.34MB]
34
+ * G 2012-04-18 19;15;24 (Differential) [1.279GB]
35
+ * G 2012-04-19 19;11;22 (Differential) [1.954GB]
36
+ * G 2012-04-20 19;12;22 (Full) [469.197GB]
37
+ * G 2012-04-23 19;12;14 (Differential) [1001.337MB]
38
+ * G 2012-04-24 19;12;15 (Differential) [2.13GB]
39
+ * H 2012-04-17 22;08;23 (Full) [886.031GB]
40
+ * H 2012-04-18 10;03;33 (Differential) [485.532MB]
41
+ * H 2012-04-18 19;35;54 (Differential) [5.975GB]
42
+ * H 2012-04-19 19;30;49 (Differential) [7.922GB]
43
+ * H 2012-04-21 04;04;29 (Full) [892.858GB]
44
+ * H 2012-04-23 19;30;24 (Differential) [5.343GB]
45
+ * H 2012-04-24 19;31;37 (Differential) [6.822GB]
46
+
47
+ File Access Warning
48
+ -------------------
49
+
50
+ Please note that it will skip files if it has no access to their sizes. Thus, subfolder sizes may appear inaccurate. To resolve this issue, either make sure that the user running the program has access to all target files, or run DirSizeRenamer with `rvmsudo`.
51
+
52
+ If you use `rvmsudo` and you escape characters or wrap directory name into quotes, then you should escape the quotes and backslashes. This is not a feature of DirSizeRenamer, it's how POSIX works.
53
+
54
+ Usage
55
+ -----
56
+
57
+ dir_size_renamer -d <directory> [options]
58
+
59
+ -d, --directory Target directory. dir_size_renamer will process subdirectories within it. Mandatory!
60
+ -f, --force Process and re-rename already renamed subdirectories.
61
+ -v, --verbose Report results to console.
62
+ -u, --undo Derename mode. No calculation is done, sizes are removed from directory names.
63
+ -h, --help Display this help message.
64
+
65
+ ### Examples
66
+
67
+ Rename the subdirectories that don't contain sizes in their names:
68
+ dir_size_renamer -d /mnt/backups
69
+
70
+ Rename the subdirectories that don't contain sizes in their names, and display the results in console:
71
+ dir_size_renamer -d /mnt/backups -v
72
+
73
+ The above command is the recommended usage for renaming backups.
74
+
75
+ Rename all the subdirectories, recalculate sizes for those subdirectories that already had sizes in their names:
76
+ dir_size_renamer -d /mnt/backups -f
77
+
78
+ Remove sizes from all subdirectories:
79
+ dir_size_renamer -d /mnt/backups -u
80
+
81
+ Disclaimer
82
+ ----------
83
+
84
+ I hope this script will not ruin your filesystem! I does not ruin mine at least. If it ruins yours, i don't take responsibility!
85
+
86
+ Authors and license
87
+ -------------------
88
+
89
+ Coded by Andrey 'lolmaus' Mikhaylov. lolmaus@gmail.com
90
+
91
+ DirSizeRenamer is released under the Ruby license.
92
+
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require "dir_size_renamer"
7
+ require "slop"
8
+
9
+ opts = Slop.parse(help: true) do
10
+ banner "Usage: dir_size_renamer -d <directory> [options]\n"
11
+ on :d, :directory, "Target directory. dir_size_renamer will process subdirectories within it.", :argument => :optional
12
+ on :f, :force, "Process and re-rename already renamed subdirectories."
13
+ on :v, :verbose, "Report results to console."
14
+ on :u, :undo, "Derename mode. No calculation is done, sizes are removed from directory names."
15
+ end
16
+
17
+ if not (opts[:directory] or opts.force? or opts.verbose? or opts.undo?)
18
+ puts opts.to_s
19
+ elsif not opts.help?
20
+ if opts.force? and opts.undo?
21
+ puts "Please choose either undo renaming or force renaming."
22
+ elsif opts[:directory]
23
+
24
+ dir = opts[:directory].gsub("\\","/")
25
+
26
+ if Dir.exists?(dir)
27
+
28
+ if opts.undo?
29
+ DirSizeRenamer.new(dir, verbose: opts.verbose?).rename_undo!
30
+ else
31
+ DirSizeRenamer.new(dir, verbose: opts.verbose?, rerename: opts.force?).rename!
32
+ end
33
+
34
+ else
35
+ puts "Target directory does not exist or is inaccessible: " + opts[:directory]
36
+ end
37
+ else
38
+ puts "Directory not specified."
39
+ end
40
+ end
@@ -0,0 +1,66 @@
1
+ require_relative 'subfolder'
2
+ require 'chronic_duration'
3
+
4
+ class DirSizeRenamer
5
+
6
+ def initialize(directory, options = { verbose: false, rerename: false })
7
+ # An existing directory should be provided
8
+ raise "Invalid path given: #{directory}" if not Dir.exists?(directory)
9
+ @directory = directory
10
+ @verbose = options[:verbose]
11
+ @rerename = options[:rerename]
12
+ end
13
+
14
+ def rename!
15
+
16
+ start_time = Time.now
17
+
18
+ report "Starting to rename directories within #{@directory}"
19
+
20
+ Dir["#{@directory}/*/"].each do |dir|
21
+ subfolder = Subfolder.new(dir.chomp("/"))
22
+
23
+ report("Processing #{File.basename(subfolder.directory)}... ", inline: true)
24
+
25
+ # Derenaming during renaming is necessary only in rerename mode
26
+ # and only if actual size does not match size in the name
27
+ subfolder.remove_size_from_name! if @rerename == true and not subfolder.name_matches_size?
28
+
29
+ subfolder.add_path_to_name! if not subfolder.name_contains_size?
30
+ report(subfolder.size_human_readable,skip_time: true)
31
+
32
+ end
33
+
34
+ report "Finished! Elapsed time: #{ChronicDuration.output(Time.now - start_time)}"
35
+ end
36
+
37
+ def rename_undo!
38
+ report "Starting to derename directories within #{@directory}"
39
+
40
+ Dir["#{@directory}/*/"].each do |dir|
41
+ subfolder = Subfolder.new(dir.chomp("/"))
42
+
43
+ report("Processing #{File.basename(subfolder.directory)}... ")
44
+ subfolder.remove_size_from_name! if subfolder.name_contains_size?
45
+ #report(subfolder.size_human_readable,skip_time: true) if @verbose
46
+
47
+ end
48
+
49
+ report "Finished derenaming!"
50
+ end
51
+
52
+ private
53
+ def report(text, options = {inline: false, skip_time: false})
54
+
55
+ return unless @verbose
56
+
57
+ print "[#{Time.new.strftime("%H:%M:%S")}] " unless options[:skip_time]
58
+
59
+ if options[:inline]
60
+ print text
61
+ else
62
+ puts text
63
+ end
64
+
65
+ end
66
+ end
data/lib/subfolder.rb ADDED
@@ -0,0 +1,84 @@
1
+ require 'find'
2
+
3
+ class Subfolder
4
+
5
+ attr_reader :directory
6
+
7
+ def self.renamed_eof_regex
8
+ / \[\d+(\.\d{1,3})?[KMGT]?B\]$/
9
+ end
10
+
11
+ def initialize(directory)
12
+ # An existing directory should be provided
13
+ raise "Invalid path given: #{directory}" if not Dir.exists?(directory)
14
+ @directory = directory
15
+ end
16
+
17
+ def calc_size!
18
+ dirsize = 0
19
+ Find.find(@directory) do |f|
20
+ dirsize += File.stat(f).size if File.exists?(f) and not File.symlink?(f)
21
+ end
22
+
23
+ @size = dirsize
24
+
25
+ end
26
+
27
+ def size
28
+ @size or calc_size!
29
+ end
30
+
31
+ def name_contains_size?
32
+ @directory =~ Subfolder.renamed_eof_regex
33
+ end
34
+
35
+ def name_matches_size?
36
+ name_contains_size? and (@directory =~ / \[#{size_human_readable}\]/)
37
+ end
38
+
39
+ def add_path_to_name!
40
+ new_name = name_with_size
41
+ File.rename(@directory, new_name)
42
+ @directory = new_name
43
+ end
44
+
45
+ def remove_size_from_name!
46
+ return if not name_contains_size?
47
+ new_name = name_without_size
48
+ File.rename(@directory, new_name)
49
+ @directory = new_name
50
+ end
51
+
52
+ def size_human_readable
53
+ Subfolder.size_human_readable(size)
54
+ end
55
+
56
+ def self.size_human_readable(number_of_bytes)
57
+ raise "Tried to convert invalid value to human-readable file size: #{number_of_bytes}, #{number_of_bytes.class}" if (number_of_bytes.class != Fixnum \
58
+ and number_of_bytes.class != Bignum) \
59
+ or number_of_bytes < 0
60
+ return "0B" if number_of_bytes == 0
61
+ units = %w{B KB MB GB TB}
62
+ e = (Math.log(number_of_bytes)/Math.log(1024)).floor
63
+ s = "%.3f" % (number_of_bytes.to_f / 1024**e)
64
+ s.sub(/\.?0*$/, units[e])
65
+ end
66
+
67
+ def self.remove_size_from_string(name)
68
+ name.gsub(Subfolder.renamed_eof_regex,"")
69
+ end
70
+
71
+ private
72
+ def name_with_size
73
+ "#{@directory} [#{Subfolder.size_human_readable(size)}]"
74
+ end
75
+
76
+ def name_without_size
77
+ Subfolder.remove_size_from_string(@directory)
78
+ end
79
+
80
+
81
+
82
+ end
83
+
84
+
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dir_size_renamer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrey 'lolmaus' Mikhaylov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-25 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: This console utility lets you rename subdirectories within a specified
15
+ directory, so that subdirectories' names contain their sizes.
16
+ email: lolmaus@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/dir_size_renamer.rb
22
+ - lib/subfolder.rb
23
+ - bin/dir_size_renamer
24
+ - README.md
25
+ homepage: https://github.com/lolmaus/dir_size_renamer
26
+ licenses: []
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 1.8.16
46
+ signing_key:
47
+ specification_version: 3
48
+ summary: DirSizeRenamer
49
+ test_files: []