ebook_renamer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 244dbff6a80aa66460a633d9ca1e77d7c2d11054
4
+ data.tar.gz: 7db39857c19b170eb76ea19d62cd85a444505c77
5
+ SHA512:
6
+ metadata.gz: b1d5b29908281d629b7e6dbdab770b8a59902caf6c985332e5cce282389b963c0359d321683194c698a3a74b90d5b9899e02b3a3350f06c7303a8b9c5e274bf8
7
+ data.tar.gz: 57536decad2872912f5c507de4de1fb04d7fa2b5b590353ce6255a78a5128688d841a48a58fb44a4a3988dc4dce8f4b9ef4b567734d04923d84a8418ee75fe6e
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ ## Note for testing only!!
19
+ misc/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.1
data/.yardopts ADDED
@@ -0,0 +1,2 @@
1
+ # see: http://rubydoc.info/gems/yard/file/README.md
2
+ --no-private --protected lib/**/*.rb - README.md LICENSE
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ebook_renamer.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,23 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+ guard 'minitest' do
4
+ # with Minitest::Unit
5
+ watch(%r|^test/(.*)\/?test_(.*)\.rb|)
6
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
7
+ watch(%r|^test/test_helper\.rb|) { "test" }
8
+
9
+ # with Minitest::Spec
10
+ # watch(%r|^spec/(.*)_spec\.rb|)
11
+ # watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ # watch(%r|^spec/spec_helper\.rb|) { "spec" }
13
+
14
+ # Rails 3.2
15
+ # watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/controllers/#{m[1]}_test.rb" }
16
+ # watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
17
+ # watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
18
+
19
+ # Rails
20
+ # watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/functional/#{m[1]}_test.rb" }
21
+ # watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
22
+ # watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
23
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Burin Choomnuan
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ ## EbookRenamer
2
+
3
+ Simple utility to perform bulk rename of the ebooks(epub,mobi,pdf) based on
4
+ the metadata within the ebook itself (if available).
5
+
6
+ ### Installation
7
+
8
+ * You will need to install the [Calibre](http://www.calibre-ebook.com/) and
9
+ [Calibre CLI](http://manual.calibre-ebook.com/cli/cli-index.html)
10
+
11
+ * Then install the gem
12
+
13
+ ```sh
14
+ $bundle
15
+ $gem install ebook_renamer
16
+ ```
17
+
18
+ ### Usage
19
+
20
+ Run the following command from the directory that contain the file(s) that
21
+ you want to rename.
22
+
23
+ ```sh
24
+ # cd to the directory containing the file you like to rename
25
+ cd ~/Dropbox/ebooks/
26
+
27
+ # or specify the directory as an option
28
+ ebook_renamer --base-dir ~/Dropbox/ebooks/samples
29
+
30
+ # If you like to see the usage try
31
+ ebook_renamer --help
32
+
33
+ # Run the command without to see what will be changed without making any changes (dry-run)
34
+ ebook_rename --recursive
35
+
36
+ # Once you are happy with what you see, then
37
+ ebook_renamer --recusive --commit
38
+ ```
39
+
40
+ ### Output of `ebook_renamer --help`
41
+
42
+ ```
43
+ Usage: ebook_renamer [options]
44
+
45
+ Examples:
46
+
47
+ 1) $ebook_renamer
48
+
49
+ 2) $ebook_renamer --base-dir ~/Dropbox/ebooks
50
+
51
+ 3) $ebook_renamer --base-dir ~/Dropbox/ebooks
52
+ --recursive
53
+
54
+ 4) $ebook_renamer --base-dir ~/Dropbox/ebooks
55
+ --recursive
56
+
57
+ 5) $ebook_renamer --base-dir ~/Dropbox/ebooks
58
+ --recursive
59
+ --commit
60
+ Options:
61
+
62
+ -b, --base-dir directory Starting directory [default - current directory]
63
+ -r, --recursive Process the files recursively [default - false]
64
+ -c, --commit Perform the actual rename [default - false]
65
+ -v, --version Display version number
66
+ -h, --help Display this screen
67
+ ```
68
+
69
+ ### Contributing
70
+
71
+ 1. Fork it
72
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
73
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
74
+ 4. Make sure that you add the tests and ensure that all tests are passed
75
+ 5. Push to the branch (`git push origin my-new-feature`)
76
+ 6. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'lib/ebook_renamer'
6
+ t.test_files = FileList['test/lib/ebook_renamer/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => :test
11
+
12
+ ## see: http://erniemiller.org/2014/02/05/7-lines-every-gems-rakefile-should-have/
13
+ task :irb do
14
+ require 'irb'
15
+ require 'awesome_print'
16
+ require 'irb/completion'
17
+ require 'ebook_renamer'
18
+ include EbookRenamer
19
+ ARGV.clear
20
+ IRB.start
21
+ end
22
+
23
+ ## see: http://lucapette.com/pry/pry-everywhere/
24
+ task :pry do
25
+ require 'pry'
26
+ require 'awesome_print'
27
+ require 'ebook_renamer'
28
+ include EbookRenamer
29
+ ARGV.clear
30
+ Pry.start
31
+ end
data/bin/ebook_renamer ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ begin
3
+ require 'pry'
4
+ require 'ebook_renamer'
5
+ rescue LoadError
6
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
7
+ require 'ebook_renamer'
8
+ end
9
+
10
+ include EbookRenamer
11
+ include EbookRenamer::Options
12
+ require 'ostruct'
13
+
14
+ begin
15
+ options = parse_options()
16
+ EbookRenamer.logger.info "Your options: #{options}"
17
+ # Note: if we need to adjust the path to the executable
18
+ EbookRenamer.configure do |config|
19
+ config.meta_binary = '/usr/bin/ebook-meta'
20
+ end
21
+
22
+ cli = EbookRenamer::CLI.new(EbookRenamer.configuration)
23
+ cli.rename(options[:base_dir], options)
24
+ exit 0
25
+ rescue ArgumentError => e
26
+ puts e
27
+ exit 1
28
+ end
29
+ # vim: ft=ruby
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ebook_renamer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ebook_renamer"
8
+ spec.version = EbookRenamer::VERSION
9
+ spec.authors = ["Burin Choomnuan"]
10
+ spec.email = ["agilecreativity@gmail.com"]
11
+ spec.description = %q{Bulk rename of ebook files based on available metadata}
12
+ spec.summary = %q{Rename multiple ebook files (epub, mobi, pdf) based on existing metadata in the file}
13
+ spec.homepage = "https://github.com/agilecreativity/ebook_renamer"
14
+ spec.license = "MIT"
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+ # Generated dependencies
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+ # additional dependencies
23
+ spec.add_development_dependency "minitest-spec-context", "~> 0.0.3"
24
+ spec.add_development_dependency "guard-minitest", "~> 2.2"
25
+ spec.add_development_dependency "minitest", "~> 4.2"
26
+ spec.add_development_dependency "awesome_print", "~> 1.2"
27
+ spec.add_development_dependency "guard", "~> 2.6"
28
+ spec.add_development_dependency "pry", "~> 0.9"
29
+ spec.add_development_dependency "gem-ctags", "~> 1.0"
30
+ spec.add_development_dependency "yard", "~> 0.8"
31
+ end
@@ -0,0 +1,7 @@
1
+ require 'ebook_renamer/version'
2
+ require 'ebook_renamer/logger'
3
+ require 'ebook_renamer/constant'
4
+ require 'ebook_renamer/helpers'
5
+ require 'ebook_renamer/configuration'
6
+ require 'ebook_renamer/options'
7
+ require 'ebook_renamer/cli'
@@ -0,0 +1,54 @@
1
+ module EbookRenamer
2
+ class CLI
3
+
4
+ attr_accessor :config
5
+
6
+ # Constructor for the class
7
+ #
8
+ # @param [Configuration] config the configuration class
9
+ def initialize(config = Configuration.new)
10
+ @config = config
11
+ end
12
+
13
+ # Rename the file from the given directory
14
+ # Using the with the argurment options as follow
15
+ # :recursive - perform the rename recursively (true|false)
16
+ # :commit - make the rename permanent (true|false)
17
+ # :exts - list of extensions to be processed default to ['epub,mobi,pdf']
18
+ # @param base_dir [String] base directory default to current directory
19
+ # @param args [Hash<Symbol, Object>] options argument
20
+ def rename(base_dir = Dir.pwd, args = {})
21
+ options = {
22
+ recursive: false,
23
+ commit: false,
24
+ exts: %w(epub mobi pdf).join(",")
25
+ }.merge(args)
26
+
27
+ input_files = Helpers.files(base_dir, options).sort
28
+
29
+ input_files.each do |file|
30
+ puts "Input :#{file}"
31
+ extension = File.extname(file)
32
+ begin
33
+ hash = Helpers.meta_to_hash(Helpers.meta(file, config.ebook_meta_binary))
34
+ formatted_name = Helpers.formatted_name(hash, sep_char: " by ")
35
+ formatted_name = "#{formatted_name}#{extension}"
36
+ new_name = "#{File.dirname(file)}/#{Helpers.sanitize_filename(formatted_name, '.')}"
37
+ puts "Output:#{new_name}"
38
+ # skip if the filename is too long '228'
39
+ # see: https://github.com/rails/rails/commit/ad95a61b62e70b839567c2e91e127fc2a1acb113
40
+ # @todo find out the max file size
41
+ max_allowed_file_size = 220
42
+ if new_name && new_name.size > max_allowed_file_size
43
+ puts "FYI: skip file name too long [#{new_name.size}] : #{new_name}"
44
+ next
45
+ end
46
+ FileUtils.mv(file,new_name) if options[:commit] && file != new_name && new_name.size < max_allowed_file_size
47
+ rescue RuntimeError => e
48
+ puts e.backtrace
49
+ next
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,32 @@
1
+ module EbookRenamer
2
+ class Configuration
3
+
4
+ attr_accessor :meta_binary
5
+
6
+ def initialize
7
+ @meta_binary = '/usr/bin/ebook-meta'
8
+ end
9
+
10
+ def to_s
11
+ <<-END.gsub(/^\s+\|/, '')
12
+ | ebook-meta : #{ebook_meta_binary}
13
+ END
14
+ end
15
+ end
16
+
17
+ class << self
18
+ attr_writer :configuration
19
+
20
+ def configuration
21
+ @configuration ||= Configuration.new
22
+ end
23
+
24
+ def reset
25
+ @configuration = Configuration.new
26
+ end
27
+
28
+ def configure
29
+ yield(configuration)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ module EbookRenamer
2
+ # The Calibre metadata extraction tool (epub, mobi)
3
+ CALIBRE_CLI_BINARY = '/usr/bin/ebook-meta'
4
+
5
+ # The Calibre metadata extraction tool
6
+ CALIBRE_META_CLI = '/usr/bin/ebook-meta'
7
+
8
+ # Support URL for Calibre's CLI tool
9
+ CALIBRE_CLI_URL = 'http://manual.calibre-ebook.com/cli/cli-index.html'
10
+
11
+ # Exiftool binary executable (for pdf, also `mdls` on OSX)
12
+ EXIFTOOL_BINARY = '/usr/local/bin/exiftool'
13
+
14
+ # On OSX, `brew install exiftool`
15
+ EXIFTOOL_URL = 'http://www.sno.phy.queensu.ca/~phil/exiftool/'
16
+
17
+ # Attribute keys
18
+ META_KEYS = %w[title authors(s) publisher languages published rights identifiers]
19
+ end
@@ -0,0 +1,171 @@
1
+ require 'open3'
2
+ require 'fileutils'
3
+ require 'shellwords'
4
+
5
+ module EbookRenamer
6
+ class Helpers
7
+ class << self
8
+
9
+ # Extract meta data from the input file using the ebook-meta tool
10
+ #
11
+ # @param [String] filename the input file name
12
+ # @param [String] binary the executable for use to extract the metadata
13
+ # @return [String] result of the output from running the command
14
+ def meta(filename, binary = 'ebook-meta')
15
+ command = [
16
+ binary,
17
+ Shellwords.escape(filename)
18
+ ]
19
+
20
+ stdout_str, stderr_str, status = Open3.capture3(command.join(" "))
21
+ raise "Problem processing #{filename}" unless status.success?
22
+ stdout_str
23
+ end
24
+
25
+ # Convert the output string to hash
26
+ #
27
+ # @param [String] text output string from the 'ebook-meta' command
28
+ # @return [Hash<String,String>] hash pair for the input string
29
+ def meta_to_hash(text)
30
+ hash = {}
31
+ return hash if text.nil?
32
+ result_list = []
33
+
34
+ text.split(/\n/).each do |meta|
35
+ # split by the first ':' string
36
+ list = meta.split /^(.*?):/
37
+
38
+ # ignore the empty string element
39
+ list.delete_at(0)
40
+
41
+ unless list.empty?
42
+ list.map(&:strip!)
43
+ # downcase the first item to make it easy
44
+ result_list << [list[0].downcase, list[1]]
45
+ hash = Hash[*result_list.flatten]
46
+ end
47
+ end
48
+ hash
49
+ end
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
+
60
+ # Note exclude the '.' (dot)
61
+ filename.gsub!(/[^0-9A-Za-z\-_ ]/, dot)
62
+
63
+ # replace multiple occurrences of a given char with a dot
64
+ ['-','_',' '].each do |c|
65
+ filename.gsub!(/#{Regexp.quote(c)}+/, dot)
66
+ end
67
+
68
+ # replace multiple occurrence of dot with one dot
69
+ filename.gsub!(/#{Regexp.quote(dot)}+/, dot)
70
+
71
+ if sep_char
72
+ # File.basename("demo.txt", ".*") #=> "demo"
73
+ name_only = File.basename(filename, ".*")
74
+ # File.extname("demo.txt") #=> ".txt"
75
+ ext_only = File.extname(filename)
76
+ name_only.gsub!(/#{Regexp.quote(dot)}+/, sep_char)
77
+ return "#{name_only}#{ext_only}"
78
+ end
79
+
80
+ filename.strip
81
+ end
82
+
83
+ # Cross-platform way of finding an executable in the $PATH.
84
+ #
85
+ # @param command [String] the command to look up
86
+ # @return [String, NilClass] full path to the executable file or nil if the
87
+ # executable is not valid or available.
88
+ # Example:
89
+ # which('ruby') #=> /usr/bin/ruby
90
+ # which('bad-executable') #=> nil
91
+ def which(command)
92
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
93
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
94
+ exts.each { |ext|
95
+ exe = File.join(path, "#{command}#{ext}")
96
+ return exe if File.executable? exe
97
+ }
98
+ end
99
+ return nil
100
+ end
101
+
102
+ # Return formatted file name using the metadata values
103
+ #
104
+ # @param [Hash<Symbol,String>] meta_hash output from the program 'ebook-meta' or 'exiftoo'
105
+ # @param [Hash<Symbol,String>] fields list of fields that will be used to set the name
106
+ def formatted_name(meta_hash = {}, fields = {})
107
+ if hash.nil? || fields.nil?
108
+ raise ArgumentError.new("Argument must not be nil")
109
+ end
110
+
111
+ # The keys that we get from the 'mdls' or 'exiftool'
112
+ args = {
113
+ keys: ['title',
114
+ 'author(s)'],
115
+ sep_char: ' '
116
+ }.merge(fields)
117
+
118
+ keys = args[:keys]
119
+ sep_char = args[:sep_char]
120
+
121
+ # Note: only show if we have the value for title
122
+ result = []
123
+ if meta_hash.fetch('title', nil)
124
+ keys.each do |k|
125
+ value = meta_hash.fetch(k, nil)
126
+ # Note: don't add 'Author(s)' => 'Unknown' to keep the result clean
127
+ if value && value.downcase != 'unknown'
128
+ result << meta_hash[k]
129
+ end
130
+ end
131
+ return result.join(sep_char)
132
+ end
133
+ # Note: if no title we choose to return empty value for result
134
+ return ""
135
+ end
136
+
137
+ # Ensure that the values in hash are sanitized
138
+ #
139
+ # @param [Hash<Symbol,String>] hash input hash to be sanitized
140
+ # @return [Hash<Symbol,String>] original hash with values sanitized
141
+ # @see #sanitize_filename
142
+ def sanitize_values(hash = {})
143
+ hash.each do |key, value|
144
+ hash[key] = sanitize_filename(value, " ")
145
+ end
146
+ hash
147
+ end
148
+
149
+ # List files base on given options
150
+ # options:
151
+ # :recursive - process the directory recursively (default false)
152
+ # :exts - list of extensions to be search (default ['epub','mobi','pdf'])
153
+ #
154
+ # @param base_dir [String] the starting directory
155
+ # @param options [Hash<Symbol,Object>] the options to be used
156
+ # @return [List<String>] list of matching files or empty list if none are found
157
+ def files(base_dir = Dir.pwd, options = {})
158
+ args = {
159
+ recursive: false,
160
+ exts: %w(epub mobi pdf).join(',')
161
+ }.merge(options)
162
+
163
+ raise ArgumentError.new("Invalid directory #{base_dir}") unless File.directory?(base_dir)
164
+
165
+ wildcard = args[:recursive] ? '**' : ''
166
+ patterns = File.join(base_dir, wildcard, "*.{#{args[:exts]}}")
167
+ Dir.glob(patterns) || []
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,10 @@
1
+ require 'logger'
2
+ module EbookRenamer
3
+ class << self
4
+ attr_writer :logger
5
+ # @return [Logger] the Logger for the project
6
+ def logger
7
+ @logger ||= Logger.new STDOUT
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,62 @@
1
+ require 'optparse'
2
+
3
+ module EbookRenamer::Options
4
+
5
+ def parse_options()
6
+ options = {}
7
+
8
+ option_parser = OptionParser.new do |opts|
9
+ opts.banner = <<-END.gsub(/^\s+\|/, '')
10
+ |
11
+ | Usage: ebook_renamer [options]
12
+ |
13
+ | Examples:
14
+ |
15
+ | 1) $ebook_renamer
16
+ |
17
+ | 2) $ebook_renamer --base-dir ~/Dropbox/ebooks
18
+ |
19
+ | 3) $ebook_renamer --base-dir ~/Dropbox/ebooks
20
+ | --recursive
21
+ |
22
+ | 4) $ebook_renamer --base-dir ~/Dropbox/ebooks
23
+ | --recursive
24
+ |
25
+ | 5) $ebook_renamer --base-dir ~/Dropbox/ebooks
26
+ | --recursive
27
+ | --commit
28
+ |
29
+ | Options:
30
+ |
31
+ END
32
+
33
+ options[:base_dir] ||= Dir.pwd
34
+ opts.on('-b', '--base-dir directory', 'Starting directory [default - current directory]') do |base_dir|
35
+ options[:base_dir] = base_dir
36
+ end
37
+
38
+ options[:recursive] = false
39
+ opts.on('-r', '--recursive', 'Process the files recursively [default - false]') do
40
+ options[:recursive] = true
41
+ end
42
+
43
+ options[:commit] = false
44
+ opts.on('-c', '--commit', 'Perform the actual rename [default - false]') do
45
+ options[:commit] = true
46
+ end
47
+
48
+ opts.on('-v', '--version', 'Display version number') do
49
+ puts EbookRenamer::VERSION
50
+ exit 0
51
+ end
52
+
53
+ opts.on('-h', '--help', 'Display this screen') do
54
+ puts opts
55
+ exit 0
56
+ end
57
+ end
58
+
59
+ option_parser.parse!
60
+ options
61
+ end
62
+ end
@@ -0,0 +1,3 @@
1
+ module EbookRenamer
2
+ VERSION = "0.0.1"
3
+ end
Binary file
Binary file
@@ -0,0 +1,22 @@
1
+ require_relative '../../test_helper'
2
+ describe EbookRenamer do
3
+
4
+ before :each do
5
+ EbookRenamer.configure do |config|
6
+ config.meta_binary = '/usr/bin/ebook-meta'
7
+ end
8
+ end
9
+
10
+ after :each do
11
+ EbookRenamer.reset
12
+ end
13
+
14
+ it "uses the updated configuration" do
15
+ EbookRenamer.configuration.meta_binary.must_equal '/usr/bin/ebook-meta'
16
+ config = EbookRenamer.configure do |config|
17
+ config.meta_binary = "ebook-meta"
18
+ end
19
+ EbookRenamer.configuration.meta_binary.must_equal 'ebook-meta'
20
+ end
21
+
22
+ end
@@ -0,0 +1,123 @@
1
+ require_relative '../../test_helper'
2
+ describe EbookRenamer do
3
+
4
+ subject { EbookRenamer::Helpers }
5
+
6
+ before do
7
+ @sample = EbookRenamer::Helpers.meta("./test/fixtures/ebooks/demo1.pdf")
8
+ end
9
+
10
+ context "#meta" do
11
+ it "raises error on invalid input" do
12
+ ->{ subject.meta("invalid-filename") }.must_raise RuntimeError
13
+ end
14
+
15
+ it "returns valid valid input" do
16
+ @sample.wont_be_nil
17
+ end
18
+
19
+ end
20
+
21
+ context "#meta_to_hash" do
22
+ it 'returns empty hash' do
23
+ subject.meta_to_hash(nil).must_be_empty
24
+ end
25
+ it 'returns non-empty hash' do
26
+ hash = EbookRenamer::Helpers.meta_to_hash(@sample)
27
+ hash.wont_be_empty
28
+ end
29
+
30
+ describe 'invalid format' do
31
+ it 'return empty hash' do
32
+ subject.meta_to_hash('aa bb').must_equal({})
33
+ end
34
+ end
35
+
36
+ describe 'valid format' do
37
+ # extract list of 'key' : 'value' from the input
38
+ let(:sample) {
39
+ <<-END
40
+ Aaaa : BBbb
41
+ CcCc : DddD
42
+ EeeE : FFFF:gggg
43
+ hhhh : iiii:JJJJ:kkkk
44
+ END
45
+ }
46
+
47
+ let(:result) { subject.meta_to_hash(sample) }
48
+
49
+ it "returns proper type for result" do
50
+ result.must_be_instance_of Hash
51
+ end
52
+
53
+ it 'uses lowercase for result keys' do
54
+ result.keys.must_equal ['aaaa','cccc','eeee','hhhh']
55
+ end
56
+
57
+ it 'retains original cases for result values' do
58
+ result.values.must_equal ['BBbb','DddD','FFFF:gggg','iiii:JJJJ:kkkk']
59
+ end
60
+ end
61
+ end
62
+
63
+ context "#sanitize_filename" do
64
+ it "must be defined" do
65
+ subject.must_respond_to :sanitize_filename
66
+ end
67
+
68
+ it "replaces multiple valid chars with one" do
69
+ subject.sanitize_filename('Valid- -fil3_name......___ .txt').must_equal('Valid.fil3.name.txt')
70
+ end
71
+
72
+ it "replaces multiple valid chars with one" do
73
+ subject.sanitize_filename('valid filename_.txt').must_equal('valid.filename.txt')
74
+ end
75
+
76
+ it "uses sepc_char correctly" do
77
+ subject.sanitize_filename('valid.file name.txt','_').must_equal('valid_file_name.txt')
78
+ end
79
+ end
80
+
81
+ context '#which' do
82
+ describe 'valid executable' do
83
+ it 'works with valid executable' do
84
+ subject.which('ruby').wont_be_nil
85
+ end
86
+ end
87
+ describe 'invalid executable' do
88
+ it 'works with invalid executable' do
89
+ subject.which('@not-a-valid-executable!').must_be_nil
90
+ end
91
+ end
92
+ end
93
+
94
+ context '#formatted_name' do
95
+ describe 'invalid parameters' do
96
+ it 'raises exception on nil arguments' do
97
+ -> { subject.formatted_name({}, nil)}.must_raise ArgumentError
98
+ end
99
+ it 'returns nil on empty hash' do
100
+ subject.formatted_name({}, {}).must_be_empty
101
+ end
102
+ end
103
+
104
+ describe 'valid parameters' do
105
+ it 'returns result based on single key' do
106
+ subject.formatted_name({'title' => 'The Firm',
107
+ 'author' => 'John Grisham',
108
+ 'page count' => 399 },
109
+ keys: ['title']).must_equal 'The Firm'
110
+ end
111
+
112
+ it 'returns result based for multiple keys' do
113
+ subject.formatted_name({'title' => 'The Firm',
114
+ 'author' => 'John Grisham',
115
+ 'page count' => '399' },
116
+ sep_char: ':',
117
+ keys: ['title',
118
+ 'author',
119
+ 'page count']).must_equal 'The Firm:John Grisham:399'
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,6 @@
1
+ require_relative '../../test_helper'
2
+ describe EbookRenamer do
3
+ it "must be defined" do
4
+ EbookRenamer::VERSION.wont_be_nil
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require 'minitest-spec-context'
4
+ require 'awesome_print'
5
+
6
+ require_relative '../lib/ebook_renamer'
metadata ADDED
@@ -0,0 +1,221 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ebook_renamer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Burin Choomnuan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-spec-context
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.0.3
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: awesome_print
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.6'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.6'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.9'
125
+ - !ruby/object:Gem::Dependency
126
+ name: gem-ctags
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: yard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.8'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.8'
153
+ description: Bulk rename of ebook files based on available metadata
154
+ email:
155
+ - agilecreativity@gmail.com
156
+ executables:
157
+ - ebook_renamer
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - ".gitignore"
162
+ - ".ruby-version"
163
+ - ".yardopts"
164
+ - Gemfile
165
+ - Guardfile
166
+ - LICENSE
167
+ - README.md
168
+ - Rakefile
169
+ - bin/ebook_renamer
170
+ - ebook_renamer.gemspec
171
+ - lib/ebook_renamer.rb
172
+ - lib/ebook_renamer/cli.rb
173
+ - lib/ebook_renamer/configuration.rb
174
+ - lib/ebook_renamer/constant.rb
175
+ - lib/ebook_renamer/helpers.rb
176
+ - lib/ebook_renamer/logger.rb
177
+ - lib/ebook_renamer/options.rb
178
+ - lib/ebook_renamer/version.rb
179
+ - test/fixtures/ebooks/demo1.pdf
180
+ - test/fixtures/ebooks/demo2.epub
181
+ - test/fixtures/ebooks/subdir/demo3.pdf
182
+ - test/fixtures/ebooks/subdir/demo4.epub
183
+ - test/lib/ebook_renamer/configuration_test.rb
184
+ - test/lib/ebook_renamer/helpers_test.rb
185
+ - test/lib/ebook_renamer/version_test.rb
186
+ - test/test_helper.rb
187
+ homepage: https://github.com/agilecreativity/ebook_renamer
188
+ licenses:
189
+ - MIT
190
+ metadata: {}
191
+ post_install_message:
192
+ rdoc_options: []
193
+ require_paths:
194
+ - lib
195
+ required_ruby_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ required_rubygems_version: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ requirements: []
206
+ rubyforge_project:
207
+ rubygems_version: 2.2.2
208
+ signing_key:
209
+ specification_version: 4
210
+ summary: Rename multiple ebook files (epub, mobi, pdf) based on existing metadata
211
+ in the file
212
+ test_files:
213
+ - test/fixtures/ebooks/demo1.pdf
214
+ - test/fixtures/ebooks/demo2.epub
215
+ - test/fixtures/ebooks/subdir/demo3.pdf
216
+ - test/fixtures/ebooks/subdir/demo4.epub
217
+ - test/lib/ebook_renamer/configuration_test.rb
218
+ - test/lib/ebook_renamer/helpers_test.rb
219
+ - test/lib/ebook_renamer/version_test.rb
220
+ - test/test_helper.rb
221
+ has_rdoc: