mez 0.8.1
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/mez +33 -0
- data/lib/mez/VERSION.rb +3 -0
- data/lib/mez.rb +116 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9229e10affa135c3ce6542006affa29d1cf148da
|
4
|
+
data.tar.gz: e0559af63b3b33677d6b907f70e4e8f971d42cc2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 98b194786f55dfed6770da15fcb8d2c01fcf974538503aea4799a8a34ed7ea34b9f9bb33d4edfc72898a7c5573f43b3dc445daec8839775cc78c3d1f0b8aee06
|
7
|
+
data.tar.gz: b00f64269b83b2a72202fac60890946dec3719d1d2786f370672bf999f05458bb5006ed153f269204fb02ac8a08126580a21aeb34e22a93b975bf6057ad448dc
|
data/bin/mez
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'mez'
|
3
|
+
|
4
|
+
unless File.exist?(File.join(Mez::APP_DIR, 'folders.json'))
|
5
|
+
os_prefix = OS.windows? ? 'c:/files/' : '~/'
|
6
|
+
puts 'You are missing your configuration file!'
|
7
|
+
puts "It should be at #{Mez::CONFIG}, and should look like this:
|
8
|
+
|
9
|
+
{
|
10
|
+
\"projects\": [
|
11
|
+
\"#{os_prefix}work projects\",
|
12
|
+
\"#{os_prefix}personal projects\" ],
|
13
|
+
\"books\": [
|
14
|
+
\"#{os_prefix}fiction\",
|
15
|
+
\"#{os_prefix}nonfiction\" ]
|
16
|
+
}"
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
|
20
|
+
total_size = 0
|
21
|
+
total_difference = 0
|
22
|
+
|
23
|
+
Mez.intro_line
|
24
|
+
JSON.parse(File.read(Mez::CONFIG)).each do |name, folderset|
|
25
|
+
size = Mez.setsize(folderset)
|
26
|
+
Mez.update(name, size)
|
27
|
+
total_size += size
|
28
|
+
yesterday = Mez.yesterday_size(name)
|
29
|
+
difference = yesterday ? size - yesterday : 0
|
30
|
+
total_difference += difference
|
31
|
+
Mez.report(name, size, difference)
|
32
|
+
end
|
33
|
+
Mez.closing_line(total_size, total_difference)
|
data/lib/mez/VERSION.rb
ADDED
data/lib/mez.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# Configuration and the SQLite database are stored in ~/.mez/ on macOS
|
2
|
+
# and Linux, and in %localappdata%/mez on Windows.
|
3
|
+
require 'sqlite3'
|
4
|
+
require 'date'
|
5
|
+
require 'os'
|
6
|
+
require 'json'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'win32ole' if OS.windows?
|
9
|
+
|
10
|
+
module Mez
|
11
|
+
APP_DIR = if OS.windows?
|
12
|
+
File.join(File.expand_path('~'), 'appdata', 'local', 'mez')
|
13
|
+
else
|
14
|
+
File.join(File.expand_path('~'), '.mez')
|
15
|
+
end
|
16
|
+
CONFIG = File.join(APP_DIR, 'folders.json')
|
17
|
+
DB = if File.exist?(File.join(APP_DIR, 'folders.db'))
|
18
|
+
SQLite3::Database.new(File.join(APP_DIR, 'folders.db'))
|
19
|
+
else
|
20
|
+
FileUtils.mkdir_p(APP_DIR) unless File.exist?(APP_DIR)
|
21
|
+
db = SQLite3::Database.new(File.join(APP_DIR, 'folders.db'))
|
22
|
+
db.execute('CREATE TABLE folders (name string, date string, size int,
|
23
|
+
PRIMARY KEY ("name", "date"))')
|
24
|
+
db
|
25
|
+
end
|
26
|
+
|
27
|
+
# Calculates the size of a folder and its contents as an integer.
|
28
|
+
# On Windows, uses the Win32 API, which caches folder information and makes
|
29
|
+
# repeated calls to this function very fast. On other systems, sums individual
|
30
|
+
# file sizes.
|
31
|
+
#
|
32
|
+
# @param folder [String] a path to a folder, eg '~/books' or 'c:\books'
|
33
|
+
# @return [Integer] the folder's size in bytes
|
34
|
+
def self.folder_size(folder)
|
35
|
+
if OS.windows?
|
36
|
+
# Much faster for repeated calls than calculating sizes in Ruby.
|
37
|
+
WIN32OLE.new('Scripting.FileSystemObject').getFolder(folder).size.to_i
|
38
|
+
else
|
39
|
+
size = 0
|
40
|
+
Dir.glob(File.join(folder, '**', '*')) { |file| size += File.size(file) }
|
41
|
+
size
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Uses commas as separators to make large numbers human-readable.
|
46
|
+
#
|
47
|
+
# @param num [Integer] any integer, eg -48151
|
48
|
+
# @return [String] a human readable number, eg "-48,151"
|
49
|
+
def self.humanise(num)
|
50
|
+
(prefix(num) == '-' ? '-' : '') + num
|
51
|
+
.abs
|
52
|
+
.to_s
|
53
|
+
.split('')
|
54
|
+
.reverse
|
55
|
+
.each_slice(3)
|
56
|
+
.map(&:join)
|
57
|
+
.join(',')
|
58
|
+
.reverse
|
59
|
+
end
|
60
|
+
|
61
|
+
# Provide a "+" or "-" prefix based on whether `n` is positive or negative.
|
62
|
+
#
|
63
|
+
# @param n [Number]
|
64
|
+
# @return [String] "+" or "-"
|
65
|
+
def self.prefix(n)
|
66
|
+
n >= 0 ? '+' : '-'
|
67
|
+
end
|
68
|
+
|
69
|
+
# Format a number for the 'change' column, meaning a + or - prefix and a
|
70
|
+
# number in bytes converted to a comma-separated number in IEC megabytes.
|
71
|
+
#
|
72
|
+
# @param n [Integer] size differential in bytes
|
73
|
+
# @return [String] "+48,151"
|
74
|
+
def self.difference_report(n)
|
75
|
+
n.zero? ? '' : prefix(n) + humanise(n.abs / 1_000_000)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.yesterday_size(name)
|
79
|
+
DB.get_first_value('SELECT size FROM folders
|
80
|
+
WHERE name = ? AND date <> ?
|
81
|
+
ORDER BY date DESC
|
82
|
+
LIMIT 1', name, Date.today.to_s)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.report(name, size, difference)
|
86
|
+
puts name.ljust(54) +
|
87
|
+
humanise(size / 1_000_000).rjust(10) +
|
88
|
+
difference_report(difference).rjust(16)
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.intro_line
|
92
|
+
puts "\nFOLDERSET".ljust(56) + 'SIZE (MB)' + 'CHANGE (MB)'.rjust(16)
|
93
|
+
puts('-' * 80)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Take an array of folder names, and return their total size in bytes.
|
97
|
+
#
|
98
|
+
# @param [Array<String>] array of folder names
|
99
|
+
# @return [Integer] total size of all folders and their contents
|
100
|
+
def self.setsize(folderset)
|
101
|
+
folderset.reduce(0) { |acc, elem| acc + Mez.folder_size(elem) }
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.closing_line(total_size, total_difference)
|
105
|
+
puts('-' * 80)
|
106
|
+
puts 'TOTAL SIZE: ' +
|
107
|
+
humanise(total_size / 1_000_000) +
|
108
|
+
('TOTAL CHANGE: ' + humanise(total_difference / 1_000_000)).rjust(59)
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.update(name, size)
|
112
|
+
DB.execute('INSERT OR REPLACE INTO folders
|
113
|
+
(name, size, date)
|
114
|
+
VALUES (?,?,?)', name, size, Date.today.to_s)
|
115
|
+
end
|
116
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mez
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Plant
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: os
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.9.6
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.9.6
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.5'
|
55
|
+
description:
|
56
|
+
email: ryan@ryanplant.net
|
57
|
+
executables:
|
58
|
+
- mez
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- bin/mez
|
63
|
+
- lib/mez.rb
|
64
|
+
- lib/mez/VERSION.rb
|
65
|
+
homepage: https://github.com/ryantriangles/mez
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
metadata: {}
|
69
|
+
post_install_message: Please configure your folders.json!
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.5.1
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: A CLI utility to track directory sizes over time
|
89
|
+
test_files: []
|