ebook_renamer 0.1.10 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +26 -8
- data/ebook_renamer.gemspec +25 -24
- data/lib/ebook_renamer.rb +1 -1
- data/lib/ebook_renamer/cli.rb +62 -24
- data/lib/ebook_renamer/{utils.rb → ebook_renamer.rb} +8 -62
- data/lib/ebook_renamer/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06938f447fa5bb2e2ca8c39497555ad4af092481
|
4
|
+
data.tar.gz: 43bb582e47b7a996b18b68389a8e035bb98681be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01b405b2d3073da7ddf8595b793fe01ceb5b05621f9514d25a996678e9678fa9bccee357f9da23c4f50291bf959ec3fdbba9f2aec07159436233acce3e561813
|
7
|
+
data.tar.gz: c60b7a3ca43687844b4d9f006abf66d058e64de45db6280ed7b3114b4ea80a3b42db9b08a7b3bca8cbee61afebc00d101928d23c64bb09692e5c3dfb5c765da7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
### Changelog
|
2
2
|
|
3
|
+
#### 0.1.11
|
4
|
+
|
5
|
+
- Make use of [filename_cleaner][] gem for renaming filename
|
6
|
+
- Add new options
|
7
|
+
* `--downcase` to allow downcase of each word in the filename
|
8
|
+
* `--capitalize` to allow capitalization of each word in the filename
|
9
|
+
- Fix the style with rubocop
|
10
|
+
- Improve README.md
|
11
|
+
|
3
12
|
#### 0.1.10
|
4
13
|
|
5
14
|
- Code refactoring
|
@@ -82,5 +91,6 @@
|
|
82
91
|
- Initial release
|
83
92
|
|
84
93
|
[agile_utils]: https://rubygems.org/gems/agile_utils
|
94
|
+
[filename_cleaner]: https://rubygems.org/gems/filename_cleaner
|
85
95
|
[code_lister]: https://rubygems.org/gems/code_lister
|
86
96
|
[Semantic Versioning]: http://semver.org
|
data/README.md
CHANGED
@@ -132,6 +132,18 @@ ebook_renamer --base-dir . --recursive --commit
|
|
132
132
|
ebook_renamer -b . -r -c
|
133
133
|
```
|
134
134
|
|
135
|
+
### Misc Options
|
136
|
+
In addition to the above usage, you can also use the two new flags `--downcase` or
|
137
|
+
`--capitalize`
|
138
|
+
|
139
|
+
```shell
|
140
|
+
# Lowercase each word in the result filename
|
141
|
+
ebook_renamer --base-dir . --recursive --downcase --commit
|
142
|
+
|
143
|
+
# Capitalize each word in the result filename
|
144
|
+
ebook_renamer --base-dir . --recursive --capitalize --commit
|
145
|
+
```
|
146
|
+
|
135
147
|
### Usage/Synopsis
|
136
148
|
|
137
149
|
```
|
@@ -139,16 +151,22 @@ Usage:
|
|
139
151
|
ebook_renamer
|
140
152
|
|
141
153
|
Options:
|
142
|
-
-b, [--base-dir=BASE_DIR]
|
143
|
-
|
144
|
-
-r, [--recursive], [--no-recursive]
|
145
|
-
|
146
|
-
-s, [--sep-string=SEP_STRING]
|
147
|
-
|
148
|
-
-
|
149
|
-
|
154
|
+
-b, [--base-dir=BASE_DIR] # Base directory
|
155
|
+
# Default: . (current directory)
|
156
|
+
-r, [--recursive], [--no-recursive] # Search for files recursively
|
157
|
+
# Default: --recursive
|
158
|
+
-s, [--sep-string=SEP_STRING] # Separator string between words in output filename
|
159
|
+
# Default: . (dot string)
|
160
|
+
-d, [--downcase], [--no-downcase] # Convert each word in the filename to lowercase
|
161
|
+
# Default: --no-downcase
|
162
|
+
-t, [--capitalize], [--no-capitalize] # Capitalize each word in the filename
|
163
|
+
# Default: --no-capitalize
|
164
|
+
-c, [--commit], [--no-commit] # Make change permanent
|
165
|
+
# Default: --no-commit
|
166
|
+
-v, [--version], [--no-version] # Display version information
|
150
167
|
|
151
168
|
Rename multiple ebook files (pdf,epub,mobi) from a given directory
|
169
|
+
|
152
170
|
```
|
153
171
|
|
154
172
|
### Contributing
|
data/ebook_renamer.gemspec
CHANGED
@@ -1,40 +1,41 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "ebook_renamer/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = "ebook_renamer"
|
8
8
|
spec.version = EbookRenamer::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ["Burin Choomnuan"]
|
10
|
+
spec.email = ["agilecreativity@gmail.com"]
|
11
11
|
spec.description = %q{Bulk rename of ebook files (pdf, epub, mobi) based on embedded metadata}
|
12
12
|
spec.summary = %q{Rename multiple ebook files (pdf, epub, mobi) based on existing metadata if available}
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
15
|
-
spec.files = Dir.glob(
|
13
|
+
spec.homepage = "https://github.com/agilecreativity/ebook_renamer"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.files = Dir.glob("{bin,lib}/**/*") + %w[Gemfile
|
16
16
|
Rakefile
|
17
17
|
ebook_renamer.gemspec
|
18
18
|
README.md
|
19
19
|
CHANGELOG.md
|
20
20
|
LICENSE
|
21
21
|
.rubocop.yml
|
22
|
-
.gitignore
|
22
|
+
.gitignore]
|
23
23
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
24
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
|
-
spec.require_paths = [
|
26
|
-
spec.add_runtime_dependency
|
27
|
-
spec.add_runtime_dependency
|
28
|
-
spec.add_runtime_dependency
|
29
|
-
spec.
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_development_dependency
|
36
|
-
spec.add_development_dependency
|
37
|
-
spec.add_development_dependency
|
38
|
-
spec.add_development_dependency
|
39
|
-
spec.add_development_dependency
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
spec.add_runtime_dependency "thor", "~> 0.19"
|
27
|
+
spec.add_runtime_dependency "agile_utils", "~> 0.1"
|
28
|
+
spec.add_runtime_dependency "code_lister", "~> 0.1"
|
29
|
+
spec.add_runtime_dependency "filename_cleaner", "~> 0.3.8"
|
30
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
31
|
+
spec.add_development_dependency "rake"
|
32
|
+
spec.add_development_dependency "awesome_print", "~> 1.2"
|
33
|
+
spec.add_development_dependency "minitest-spec-context", "~> 0.0.3"
|
34
|
+
spec.add_development_dependency "guard-minitest", "~> 2.2"
|
35
|
+
spec.add_development_dependency "minitest", "~> 5.3"
|
36
|
+
spec.add_development_dependency "guard", "~> 2.6"
|
37
|
+
spec.add_development_dependency "pry", "~> 0.9"
|
38
|
+
spec.add_development_dependency "gem-ctags", "~> 1.0"
|
39
|
+
spec.add_development_dependency "yard", "~> 0.8"
|
40
|
+
spec.add_development_dependency "rubocop", "~> 0.20"
|
40
41
|
end
|
data/lib/ebook_renamer.rb
CHANGED
data/lib/ebook_renamer/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "agile_utils"
|
2
2
|
require "code_lister"
|
3
|
+
require "filename_cleaner"
|
3
4
|
require "fileutils"
|
4
5
|
require_relative "../ebook_renamer"
|
5
6
|
module EbookRenamer
|
@@ -9,11 +10,21 @@ module EbookRenamer
|
|
9
10
|
method_option *AgileUtils::Options::RECURSIVE
|
10
11
|
method_option :sep_string,
|
11
12
|
aliases: "-s",
|
12
|
-
desc: "Separator string between
|
13
|
+
desc: "Separator string between each word in output filename",
|
13
14
|
default: "."
|
15
|
+
method_option :downcase,
|
16
|
+
aliases: "-d",
|
17
|
+
type: :boolean,
|
18
|
+
desc: "Convert each word in the output filename to lowercase",
|
19
|
+
default: false
|
20
|
+
method_option :capitalize,
|
21
|
+
type: :boolean,
|
22
|
+
aliases: "-t",
|
23
|
+
desc: "Capitalize each word in the output filename",
|
24
|
+
default: false
|
14
25
|
method_option :commit,
|
15
26
|
aliases: "-c",
|
16
|
-
desc: "Make
|
27
|
+
desc: "Make your changes permanent",
|
17
28
|
type: :boolean,
|
18
29
|
default: false
|
19
30
|
method_option *AgileUtils::Options::VERSION
|
@@ -31,20 +42,27 @@ module EbookRenamer
|
|
31
42
|
desc "usage", "Display help screen"
|
32
43
|
def usage
|
33
44
|
puts <<-EOS
|
45
|
+
|
34
46
|
Usage:
|
35
47
|
ebook_renamer
|
36
48
|
|
37
49
|
Options:
|
38
|
-
-b, [--base-dir=BASE_DIR]
|
39
|
-
|
40
|
-
-r, [--recursive], [--no-recursive]
|
41
|
-
|
42
|
-
-s, [--sep-string=SEP_STRING]
|
43
|
-
|
44
|
-
-
|
45
|
-
|
50
|
+
-b, [--base-dir=BASE_DIR] # Base directory
|
51
|
+
# Default: . (current directory)
|
52
|
+
-r, [--recursive], [--no-recursive] # Search for files recursively
|
53
|
+
# Default: --recursive
|
54
|
+
-s, [--sep-string=SEP_STRING] # Separator string between each word in output filename
|
55
|
+
# Default: '.' (dot string)
|
56
|
+
-d, [--downcase], [--no-downcase] # Convert each word in the output filename to lowercase
|
57
|
+
# Default: --no-downcase
|
58
|
+
-t, [--capitalize], [--no-capitalize] # Capitalize each word in the output filename
|
59
|
+
# Default: --no-capitalize
|
60
|
+
-c, [--commit], [--no-commit] # Make your changes permanent
|
61
|
+
# Default: --no-commit
|
62
|
+
-v, [--version], [--no-version] # Display version information
|
46
63
|
|
47
64
|
Rename multiple ebook files (pdf,epub,mobi) from a given directory
|
65
|
+
|
48
66
|
EOS
|
49
67
|
end
|
50
68
|
|
@@ -53,13 +71,6 @@ Rename multiple ebook files (pdf,epub,mobi) from a given directory
|
|
53
71
|
private
|
54
72
|
|
55
73
|
# Rename the file from the given directory
|
56
|
-
#
|
57
|
-
# @param args [Hash<Symbol, Object>] options argument
|
58
|
-
# possible options
|
59
|
-
# :base_dir - the base directory
|
60
|
-
# :recursive - perform the rename recursively (true|false)
|
61
|
-
# :commit - make the rename permanent (true|false)
|
62
|
-
# :exts - list of extensions to be processed default to ['epub,mobi,pdf']
|
63
74
|
def execute(options = {})
|
64
75
|
input_files = CodeLister.files(options)
|
65
76
|
if input_files.empty?
|
@@ -88,16 +99,28 @@ Rename multiple ebook files (pdf,epub,mobi) from a given directory
|
|
88
99
|
|
89
100
|
def compare_and_rename(input_file, meta_hash, options, index, total)
|
90
101
|
if identical_name?(input_file, meta_hash)
|
91
|
-
|
92
|
-
|
102
|
+
base_name = File.basename(input_file, ".*")
|
103
|
+
name = downcase_or_capitalize(base_name, options)
|
104
|
+
name = "#{File.dirname(input_file)}/#{name}#{File.extname(input_file)}"
|
105
|
+
output_file = File.expand_path(name)
|
106
|
+
else
|
107
|
+
output_file = compute_name(input_file, meta_hash, options)
|
93
108
|
end
|
94
|
-
|
109
|
+
rename_if_not_the_same(input_file, output_file, index: index,
|
110
|
+
total: total,
|
111
|
+
commit: options[:commit])
|
112
|
+
end
|
113
|
+
|
114
|
+
def rename_if_not_the_same(input_file, output_file, options = {})
|
115
|
+
index = options[:index]
|
116
|
+
total = options[:total]
|
117
|
+
commit = options[:commit]
|
95
118
|
if input_file != output_file
|
96
119
|
puts "#{index + 1} of #{total} old name : #{input_file}"
|
97
120
|
puts "#{index + 1} of #{total} new name : #{output_file}"
|
98
|
-
FileUtils.mv(input_file, output_file) if
|
121
|
+
FileUtils.mv(input_file, output_file) if commit
|
99
122
|
else
|
100
|
-
puts "#{index + 1} of #{total} skip name: #{input_file} [
|
123
|
+
puts "#{index + 1} of #{total} skip name: #{input_file} [title is the same as the filename]"
|
101
124
|
end
|
102
125
|
end
|
103
126
|
|
@@ -109,13 +132,28 @@ Rename multiple ebook files (pdf,epub,mobi) from a given directory
|
|
109
132
|
|
110
133
|
# Compute the new name from metadata
|
111
134
|
#
|
112
|
-
# @todo make use of filename cleaner gem
|
113
135
|
def compute_name(input_file, meta_hash, options)
|
114
136
|
extension = File.extname(input_file)
|
115
137
|
name = formatted_name(meta_hash, sep_char: " by ")
|
116
|
-
name =
|
138
|
+
name = FilenameCleaner.sanitize(name, options[:sep_string], false)
|
139
|
+
name = downcase_or_capitalize(name, options)
|
117
140
|
name = "#{File.dirname(input_file)}/#{name}#{extension}"
|
118
141
|
File.expand_path(name)
|
119
142
|
end
|
143
|
+
|
144
|
+
# Post processing of the name
|
145
|
+
def downcase_or_capitalize(name, options)
|
146
|
+
downcase = options[:downcase]
|
147
|
+
capitalize = options[:capitalize]
|
148
|
+
sep_string = options[:sep_string]
|
149
|
+
if capitalize
|
150
|
+
name = name.split(sep_string).map(&:capitalize).join(sep_string)
|
151
|
+
else
|
152
|
+
if downcase
|
153
|
+
name = name.split(sep_string).map(&:downcase).join(sep_string)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
name
|
157
|
+
end
|
120
158
|
end
|
121
159
|
end
|
@@ -48,27 +48,6 @@ module EbookRenamer
|
|
48
48
|
hash
|
49
49
|
end
|
50
50
|
|
51
|
-
# Clean the filename to remove the special characters
|
52
|
-
#
|
53
|
-
# @param [String] filename input file
|
54
|
-
# @param [String] sep_char separator character to use
|
55
|
-
#
|
56
|
-
# @return [String] the new file name with special characters replaced or removed.
|
57
|
-
def sanitize_filename(filename, sep_char = nil)
|
58
|
-
dot = "."
|
59
|
-
# Note exclude the '.' (dot)
|
60
|
-
filename.gsub!(/[^0-9A-Za-z\-_ ]/, dot)
|
61
|
-
# replace multiple occurrences of a given char with a dot
|
62
|
-
["-", "_", " "].each do |c|
|
63
|
-
filename.gsub!(/#{Regexp.quote(c)}+/, dot)
|
64
|
-
end
|
65
|
-
|
66
|
-
# replace multiple occurrence of dot with one dot
|
67
|
-
filename.gsub!(/#{Regexp.quote(dot)}+/, dot)
|
68
|
-
return filename.gsub!(/#{Regexp.quote(dot)}+/, sep_char) if sep_char
|
69
|
-
filename.strip
|
70
|
-
end
|
71
|
-
|
72
51
|
# Return formatted file name using the metadata values
|
73
52
|
#
|
74
53
|
# @param [Hash<Symbol,String>] meta_hash output from the program 'ebook-meta' or 'exiftoo'
|
@@ -77,6 +56,8 @@ module EbookRenamer
|
|
77
56
|
if hash.nil? || fields.nil?
|
78
57
|
fail ArgumentError.new("Argument must not be nil")
|
79
58
|
end
|
59
|
+
# Let's not continue if we have no title metadata
|
60
|
+
fail "No title found" unless meta_hash.fetch("title", nil)
|
80
61
|
|
81
62
|
# The keys that we get from the 'mdls' or 'exiftool'
|
82
63
|
args = {
|
@@ -92,48 +73,13 @@ module EbookRenamer
|
|
92
73
|
|
93
74
|
# Note: only show if we have the value for title
|
94
75
|
result = []
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
result << meta_hash[k]
|
101
|
-
end
|
76
|
+
keys.each do |key|
|
77
|
+
value = meta_hash.fetch(key, nil)
|
78
|
+
# Note: don't add 'Author(s)' => 'Unknown' to keep the result clean
|
79
|
+
if value && value.downcase != "unknown"
|
80
|
+
result << meta_hash[key]
|
102
81
|
end
|
103
|
-
return result.join(sep_char)
|
104
|
-
end
|
105
|
-
# Note: if no title we choose to return empty value for result
|
106
|
-
""
|
107
|
-
end
|
108
|
-
|
109
|
-
# Ensure that the values in hash are sanitized
|
110
|
-
#
|
111
|
-
# @param [Hash<Symbol,String>] hash input hash to be sanitized
|
112
|
-
# @return [Hash<Symbol,String>] original hash with values sanitized
|
113
|
-
# @see #sanitize_filename
|
114
|
-
def sanitize_values(hash = {})
|
115
|
-
hash.each do |key, value|
|
116
|
-
hash[key] = sanitize_filename(value, " ")
|
117
82
|
end
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
# List files base on given options
|
122
|
-
# options:
|
123
|
-
# :recursive - process the directory recursively (default false)
|
124
|
-
# :exts - list of extensions to be search (default ['epub','mobi','pdf'])
|
125
|
-
#
|
126
|
-
# @param base_dir [String] the starting directory
|
127
|
-
# @param options [Hash<Symbol,Object>] the options to be used
|
128
|
-
# @return [List<String>] list of matching files or empty list if none are found
|
129
|
-
def files(base_dir = Dir.pwd, options = {})
|
130
|
-
args = {
|
131
|
-
recursive: false,
|
132
|
-
exts: %w[epub mobi pdf]
|
133
|
-
}.merge(options)
|
134
|
-
|
135
|
-
wildcard = args[:recursive] ? "**" : ""
|
136
|
-
patterns = File.join(base_dir, wildcard, "*.{#{(args[:exts]).join(",")}}")
|
137
|
-
Dir.glob(patterns) || []
|
83
|
+
result.join(sep_char)
|
138
84
|
end
|
139
85
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ebook_renamer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Burin Choomnuan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: filename_cleaner
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.3.8
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.3.8
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -225,8 +239,8 @@ files:
|
|
225
239
|
- ebook_renamer.gemspec
|
226
240
|
- lib/ebook_renamer.rb
|
227
241
|
- lib/ebook_renamer/cli.rb
|
242
|
+
- lib/ebook_renamer/ebook_renamer.rb
|
228
243
|
- lib/ebook_renamer/logger.rb
|
229
|
-
- lib/ebook_renamer/utils.rb
|
230
244
|
- lib/ebook_renamer/version.rb
|
231
245
|
homepage: https://github.com/agilecreativity/ebook_renamer
|
232
246
|
licenses:
|