glibrary 1.0.1 → 1.1.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 +4 -4
- data/bin/glibrary +21 -26
- data/exec_helpers/command_line_parse.rb +52 -0
- data/exec_helpers/error_handler.rb +35 -0
- data/exec_helpers/exec_helper.rb +4 -0
- data/exec_helpers/user_prompt.rb +78 -0
- data/globals/errors.rb +23 -0
- data/{modules → globals}/google_api_url.rb +0 -0
- data/lib/book_search.rb +38 -38
- data/lib/user_book.rb +2 -2
- data/lib/user_library.rb +5 -8
- data/modules/file_helper.rb +14 -0
- metadata +10 -7
- data/modules/command_line_parse.rb +0 -55
- data/modules/error_handler.rb +0 -38
- data/modules/errors.rb +0 -25
- data/modules/exec_helper.rb +0 -24
- data/modules/user_prompt.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6fe6f6ce56c501c33ad281b7d6acc4b2fc32d3a39e522a06d95044bdffb2212
|
4
|
+
data.tar.gz: 0106ee481b834da946078dca94cc28a3ae64705944b588005dfbe4930dadae5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ddacb58256ab459b1028e76b81ce4d848a4cfefd6003f914780dd879f50fafbba025d1416dc353fe3ba8c1e4b472a4239af45bae72123723d46b0b539659383
|
7
|
+
data.tar.gz: 88bb81b0bf751f001f287474553fa76ff71cf3d97c7f87e129b709cf86bc5c506eb3151a15bf43537807755887d4f570912cc063faa313ebc8f8fddd2b8ebef9
|
data/bin/glibrary
CHANGED
@@ -3,51 +3,46 @@ require 'json'
|
|
3
3
|
require 'io/console'
|
4
4
|
|
5
5
|
require_relative '../modules/api_query'
|
6
|
-
require_relative '../
|
7
|
-
require_relative '../
|
8
|
-
require_relative '../
|
9
|
-
require_relative '../
|
10
|
-
require_relative '../
|
11
|
-
require_relative '../
|
6
|
+
require_relative '../exec_helpers/command_line_parse'
|
7
|
+
require_relative '../globals/errors'
|
8
|
+
require_relative '../exec_helpers/error_handler'
|
9
|
+
require_relative '../exec_helpers/exec_helper'
|
10
|
+
require_relative '../globals/google_api_url'
|
11
|
+
require_relative '../exec_helpers/user_prompt'
|
12
12
|
|
13
13
|
require_relative '../lib/book_search'
|
14
14
|
require_relative '../lib/user_book'
|
15
15
|
require_relative '../lib/user_library'
|
16
16
|
|
17
|
-
include ExecHelper
|
18
|
-
include UserPrompt
|
19
|
-
include CommandLineParse
|
20
|
-
include ErrorHandler
|
21
|
-
|
22
17
|
CURRENT_DIR = File.join(File.dirname(__FILE__))
|
23
|
-
DEFAULT_FILENAME = File.join File.expand_path("..", CURRENT_DIR), "saved_libraries", "library.json"
|
24
18
|
|
25
|
-
|
19
|
+
DEFAULT_FILENAME = File.join( File.expand_path("..", CURRENT_DIR),
|
20
|
+
"saved_libraries", "library.json" )
|
26
21
|
|
27
|
-
|
28
|
-
|
29
|
-
command_line_parse! #this function processes @filename and fills the @options hash.
|
22
|
+
process_args! # processes and modifies ARGV
|
23
|
+
filename = FileHelper.prepare(DEFAULT_FILENAME)
|
30
24
|
|
31
|
-
|
25
|
+
options = get_cli_options
|
26
|
+
filename = options.delete(:filename) if options[:filename]
|
27
|
+
library_mode = options.delete(:library_mode)
|
32
28
|
|
33
|
-
if library_mode
|
29
|
+
if library_mode
|
34
30
|
|
35
31
|
with_library_mode_error_handling do
|
36
|
-
|
37
|
-
library_mode_user_prompt
|
32
|
+
user_library = UserLibrary.new(filename: filename)
|
33
|
+
library_mode_user_prompt(user_library)
|
38
34
|
end
|
39
35
|
|
40
36
|
else
|
41
37
|
|
42
38
|
with_search_mode_error_handling do
|
43
|
-
|
44
|
-
|
39
|
+
persistent_library = UserLibrary.new(filename: filename)
|
40
|
+
temp_booklist = UserLibrary.new(nonpersistent: true)
|
45
41
|
|
46
|
-
search_results =
|
47
|
-
search_results.
|
48
|
-
@temp_booklist.pretty_print
|
42
|
+
search_results = BookSearch.new(options)
|
43
|
+
search_results.selected.each { |info| temp_booklist.add(UserBook.new(info)) }
|
49
44
|
|
50
|
-
search_mode_user_prompt
|
45
|
+
search_mode_user_prompt(temp_booklist, persistent_library)
|
51
46
|
end
|
52
47
|
|
53
48
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
def abort_library_mode
|
4
|
+
puts "Library file not found, cannot display."
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
|
8
|
+
def print_help_message(opts)
|
9
|
+
puts ""
|
10
|
+
puts opts
|
11
|
+
puts "[query]: all other arguments will be treated as general search keywords"
|
12
|
+
puts ""
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_cli_options
|
16
|
+
options = {}
|
17
|
+
OptionParser.new do |opts|
|
18
|
+
opts.banner = "Usage: glibrary [options...] [query]"
|
19
|
+
|
20
|
+
opts.on("-t", "--title=TITLE", "Specify a title keyword") do |t|
|
21
|
+
options[:title] = t
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("-a", "--author=AUTHOR", "Specify an author keyword") do |a|
|
25
|
+
options[:author] = a
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("-p", "--publisher=PUBLISHER", "Specify a publisher keyword") do |p|
|
29
|
+
options[:publisher] = p
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("-f", "--lib-file=LIBFILE",
|
33
|
+
"Select a library save file. Otherwise, a default save file will be used.") do |libfile|
|
34
|
+
abort_library_mode if ARGV.include?("-l") && !File.exist?(libfile)
|
35
|
+
options[:filename] = libfile
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on("-l", "--library", "See your reading list; ignores all search options") do
|
39
|
+
return { filename: options[:filename], library_mode: true }
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on("-h", "--help", "Prints this help") do
|
43
|
+
print_help_message(opts)
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
end.parse!
|
47
|
+
|
48
|
+
options[:search] = ARGV.join('+')
|
49
|
+
|
50
|
+
options
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../globals/errors'
|
2
|
+
|
3
|
+
def with_library_mode_error_handling
|
4
|
+
begin
|
5
|
+
yield
|
6
|
+
rescue UserQuits
|
7
|
+
puts "\nEnjoy your day."
|
8
|
+
rescue Errno::EACCES
|
9
|
+
puts "\nYou don't have permission to write to the file you specified. Quitting immediately"
|
10
|
+
puts ""
|
11
|
+
end
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_search_mode_error_handling
|
16
|
+
begin
|
17
|
+
yield
|
18
|
+
rescue UserQuits
|
19
|
+
puts "\nThanks for browsing. Library file saved"
|
20
|
+
puts ""
|
21
|
+
rescue Errno::EACCES
|
22
|
+
puts "\nYou don't have permission to write to the file you specified. Quitting immediately"
|
23
|
+
puts ""
|
24
|
+
rescue NoInternetError
|
25
|
+
puts "\nNo internet connection. Please connect to the internet and try again."
|
26
|
+
puts ""
|
27
|
+
rescue SearchError
|
28
|
+
puts "\nThere was an error with your query; be careful to format it well"
|
29
|
+
puts ""
|
30
|
+
rescue NoResults
|
31
|
+
puts "\nNo results."
|
32
|
+
puts ""
|
33
|
+
end
|
34
|
+
exit
|
35
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative '../globals/errors'
|
2
|
+
|
3
|
+
def verify_selection(selection, regexp)
|
4
|
+
raise SelectionError unless selection =~ regexp
|
5
|
+
raise UserQuits if selection =~ /\A[Qq]\Z/
|
6
|
+
end
|
7
|
+
|
8
|
+
def process_selection(selection)
|
9
|
+
return selection.to_i - 1
|
10
|
+
end
|
11
|
+
|
12
|
+
def handle_successful_prompt_completion(selected_book)
|
13
|
+
puts ""
|
14
|
+
puts "The book \"#{selected_book['title']}\" has been added to your reading list."
|
15
|
+
end
|
16
|
+
|
17
|
+
def prompt(prompt, regexp, library, suppress = nil)
|
18
|
+
print prompt
|
19
|
+
s = suppress || STDIN.gets.strip
|
20
|
+
verify_selection(s, regexp)
|
21
|
+
s = process_selection(s)
|
22
|
+
raise NotABook unless s <= library.size
|
23
|
+
return s
|
24
|
+
end
|
25
|
+
|
26
|
+
def library_mode_user_prompt(lib)
|
27
|
+
while true
|
28
|
+
begin
|
29
|
+
lib.pretty_print
|
30
|
+
|
31
|
+
i = prompt( "Select a book number to delete, or type \"q\" to quit: ", /\A([0-9]+|[qQ])\Z/,
|
32
|
+
lib)
|
33
|
+
|
34
|
+
lib.delete(i)
|
35
|
+
lib.save
|
36
|
+
|
37
|
+
puts "Your library now looks like this."
|
38
|
+
puts ""
|
39
|
+
rescue SelectionError
|
40
|
+
puts "\nSorry, your selection was invalid. Please try again."
|
41
|
+
rescue NotABook
|
42
|
+
puts "\nSorry, your selection was invalid. Make sure your selection is in the provided range."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def search_mode_user_prompt(temp_booklist, persistent_library)
|
49
|
+
|
50
|
+
temp_booklist.pretty_print
|
51
|
+
|
52
|
+
while true
|
53
|
+
begin
|
54
|
+
|
55
|
+
i = prompt( "Enter a number (1-5) to add a book to your reading list (or q to quit): ",
|
56
|
+
/\A[1-5]|[qQ]\Z/, temp_booklist )
|
57
|
+
selected_book = temp_booklist[i]
|
58
|
+
|
59
|
+
persistent_library << selected_book
|
60
|
+
persistent_library.save
|
61
|
+
|
62
|
+
handle_successful_prompt_completion(selected_book)
|
63
|
+
puts "Would you like to add another?"
|
64
|
+
puts ""
|
65
|
+
rescue BookDuplicateError
|
66
|
+
puts "\nThat book is already in your reading list. Would you like to add another?"
|
67
|
+
puts ""
|
68
|
+
rescue SelectionError
|
69
|
+
puts "\nSorry, your selection was invalid. Please try again."
|
70
|
+
puts ""
|
71
|
+
rescue NotABook
|
72
|
+
puts "\nSorry, your selection was invalid. Make sure your selection is within the range of available options."
|
73
|
+
puts ""
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
data/globals/errors.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class SearchError < StandardError
|
2
|
+
end
|
3
|
+
|
4
|
+
class BookDuplicateError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class NoInternetError < StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
class NoResults < StandardError
|
11
|
+
end
|
12
|
+
|
13
|
+
class SelectionError < StandardError
|
14
|
+
end
|
15
|
+
|
16
|
+
class NotABook < StandardError
|
17
|
+
end
|
18
|
+
|
19
|
+
class UserQuits < StandardError
|
20
|
+
end
|
21
|
+
|
22
|
+
class PersistenceError < StandardError
|
23
|
+
end
|
File without changes
|
data/lib/book_search.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'json'
|
2
2
|
require_relative '../modules/api_query'
|
3
|
-
require_relative '../
|
4
|
-
require_relative '../
|
3
|
+
require_relative '../globals/google_api_url'
|
4
|
+
require_relative '../globals/errors'
|
5
5
|
|
6
6
|
class BookSearch
|
7
7
|
include ApiQuery
|
8
8
|
include Enumerable
|
9
|
-
|
9
|
+
|
10
10
|
|
11
|
-
attr_reader :
|
11
|
+
attr_reader :selected, :full_results, :url
|
12
12
|
|
13
13
|
def initialize(args)
|
14
14
|
@args = args.dup
|
@@ -30,61 +30,61 @@ class BookSearch
|
|
30
30
|
num = full_results['totalItems']
|
31
31
|
raise NoResults unless num > 0
|
32
32
|
|
33
|
-
@
|
34
|
-
@
|
33
|
+
@selected = full_results['items'].first(num_results)
|
34
|
+
@selected.map! { |res| self.class.format_hash res }
|
35
35
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def each
|
39
39
|
return to_enum :each unless block_given?
|
40
|
-
|
40
|
+
selected.each { |r| yield(r) }
|
41
41
|
end
|
42
42
|
|
43
43
|
def [](index)
|
44
|
-
|
44
|
+
selected[index]
|
45
45
|
end
|
46
46
|
|
47
47
|
private
|
48
|
-
|
49
|
-
def make_url_arg_list(args)
|
50
|
-
url = ["?q="]
|
48
|
+
class << self
|
51
49
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
url << args.map do |k,v|
|
56
|
-
k = ("in" + k) if %w[title author publisher].include?(k)
|
57
|
-
"%s:%s" % [k, v]
|
50
|
+
def make_url(args)
|
51
|
+
(BASE_API_URL + make_url_arg_list(args)).gsub(/ /, "+")
|
58
52
|
end
|
59
53
|
|
60
|
-
|
61
|
-
|
62
|
-
|
54
|
+
def make_url_arg_list(args)
|
55
|
+
url = ["?q="]
|
56
|
+
|
57
|
+
q = args.delete('search')
|
58
|
+
url << q.to_s
|
63
59
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
60
|
+
url << args.map do |k,v|
|
61
|
+
k = ("in" + k) if %w[title author publisher].include?(k)
|
62
|
+
"%s:%s" % [k, v]
|
63
|
+
end
|
69
64
|
|
70
|
-
|
71
|
-
|
72
|
-
%i[search title author publisher subject isbn lccn oclc].include?(k)
|
65
|
+
url.reject!(&:empty?)
|
66
|
+
url[0] + url[1, url.length-1].join("+")
|
73
67
|
end
|
74
|
-
end
|
75
68
|
|
69
|
+
def format_args(args)
|
70
|
+
result = args.map { |k, v| [k,v].map(&:to_s) }.to_h
|
71
|
+
result.reject! { |k, v| v.empty? }
|
72
|
+
return result.to_h
|
73
|
+
end
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
def searchable_arguments?(args)
|
76
|
+
args.keys.any? do |k|
|
77
|
+
%i[search title author publisher subject isbn lccn oclc].include?(k)
|
78
|
+
end
|
79
|
+
end
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
def format_hash(hash)
|
82
|
+
hash['volumeInfo'].merge( { 'id' => hash['id'] } )
|
83
|
+
end
|
84
84
|
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
def args
|
86
|
+
@args
|
87
|
+
end
|
88
88
|
end
|
89
89
|
|
90
90
|
end
|
data/lib/user_book.rb
CHANGED
data/lib/user_library.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'json'
|
2
|
-
require_relative '../
|
3
|
-
require_relative '../modules/
|
2
|
+
require_relative '../globals/errors'
|
3
|
+
require_relative '../modules/file_helper'
|
4
4
|
require_relative 'user_book'
|
5
5
|
|
6
6
|
|
7
7
|
class UserLibrary
|
8
8
|
include Enumerable
|
9
|
-
|
10
|
-
include Errors
|
9
|
+
|
11
10
|
|
12
11
|
attr_reader :books, :filename
|
13
12
|
|
@@ -96,13 +95,11 @@ class UserLibrary
|
|
96
95
|
|
97
96
|
def set_filename(name)
|
98
97
|
@nonpersistent = false
|
99
|
-
@filename = name
|
100
|
-
prepare_filename_for_os!
|
98
|
+
@filename = FileHelper.prepare(name)
|
101
99
|
end
|
102
100
|
|
103
101
|
def determine_filename!
|
104
|
-
@filename =
|
105
|
-
prepare_filename_for_os!
|
102
|
+
@filename = FileHelper.prepare(@filename)
|
106
103
|
end
|
107
104
|
|
108
105
|
def get_raw_JSON_data
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../globals/errors'
|
2
|
+
|
3
|
+
module FileHelper
|
4
|
+
def self.prepare_for_os(filename)
|
5
|
+
ENV.values.any? { |v| v =~ /[A-Z]:\\Windows/i } ?
|
6
|
+
filename.gsub(/\//, '\\') : filename
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.prepare(filename)
|
10
|
+
filename = File.absolute_path(filename)
|
11
|
+
FileHelper.prepare_for_os(filename)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glibrary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Engelbert
|
@@ -19,16 +19,17 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- bin/glibrary
|
22
|
+
- exec_helpers/command_line_parse.rb
|
23
|
+
- exec_helpers/error_handler.rb
|
24
|
+
- exec_helpers/exec_helper.rb
|
25
|
+
- exec_helpers/user_prompt.rb
|
26
|
+
- globals/errors.rb
|
27
|
+
- globals/google_api_url.rb
|
22
28
|
- lib/book_search.rb
|
23
29
|
- lib/user_book.rb
|
24
30
|
- lib/user_library.rb
|
25
31
|
- modules/api_query.rb
|
26
|
-
- modules/
|
27
|
-
- modules/error_handler.rb
|
28
|
-
- modules/errors.rb
|
29
|
-
- modules/exec_helper.rb
|
30
|
-
- modules/google_api_url.rb
|
31
|
-
- modules/user_prompt.rb
|
32
|
+
- modules/file_helper.rb
|
32
33
|
- saved_libraries/.gitkeep
|
33
34
|
homepage: https://github.com/pmengelbert/g_library
|
34
35
|
licenses:
|
@@ -38,6 +39,8 @@ post_install_message:
|
|
38
39
|
rdoc_options: []
|
39
40
|
require_paths:
|
40
41
|
- modules
|
42
|
+
- exec_helpers
|
43
|
+
- globals
|
41
44
|
- saved_libraries
|
42
45
|
- lib
|
43
46
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require_relative 'errors'
|
2
|
-
|
3
|
-
module CommandLineParse
|
4
|
-
require 'optparse'
|
5
|
-
include Errors
|
6
|
-
|
7
|
-
def handle_nonexistent_file
|
8
|
-
(puts "Library file not found, cannot display."; exit)
|
9
|
-
puts "Creating new file"
|
10
|
-
end
|
11
|
-
|
12
|
-
def print_help_message(opts)
|
13
|
-
puts ""
|
14
|
-
puts opts
|
15
|
-
puts "[query]: all other arguments will be treated as general search keywords"
|
16
|
-
puts ""
|
17
|
-
end
|
18
|
-
|
19
|
-
def command_line_parse!
|
20
|
-
OptionParser.new do |opts|
|
21
|
-
opts.banner = "Usage: glibrary [options...] [query]"
|
22
|
-
|
23
|
-
opts.on("-t", "--title=TITLE", "Specify a title keyword") do |t|
|
24
|
-
@options[:title] = t
|
25
|
-
end
|
26
|
-
|
27
|
-
opts.on("-a", "--author=AUTHOR", "Specify an author keyword") do |a|
|
28
|
-
@options[:author] = a
|
29
|
-
end
|
30
|
-
|
31
|
-
opts.on("-p", "--publisher=PUBLISHER", "Specify a publisher keyword") do |p|
|
32
|
-
@options[:publisher] = p
|
33
|
-
end
|
34
|
-
|
35
|
-
opts.on("-f", "--lib-file=LIBFILE",
|
36
|
-
"Select a library save file. Otherwise, a default save file will be used.") do |libfile|
|
37
|
-
@filename = File.absolute_path(libfile)
|
38
|
-
handle_nonexistent_file if ARGV.include?("-l") && !File.exist?(@filename)
|
39
|
-
end
|
40
|
-
|
41
|
-
opts.on("-l", "--library", "See your reading list; ignores all search options") do
|
42
|
-
@options = nil
|
43
|
-
return
|
44
|
-
end
|
45
|
-
|
46
|
-
opts.on("-h", "--help", "Prints this help") do
|
47
|
-
print_help_message(opts)
|
48
|
-
exit
|
49
|
-
end
|
50
|
-
end.parse!
|
51
|
-
|
52
|
-
@options[:search] = ARGV.join('+')
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
data/modules/error_handler.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require_relative 'errors'
|
2
|
-
|
3
|
-
module ErrorHandler
|
4
|
-
def with_library_mode_error_handling
|
5
|
-
begin
|
6
|
-
yield
|
7
|
-
rescue UserQuits
|
8
|
-
puts "\nEnjoy your day."
|
9
|
-
rescue Errno::EACCES
|
10
|
-
puts "\nYou don't have permission to write to the file you specified. Quitting immediately"
|
11
|
-
puts ""
|
12
|
-
end
|
13
|
-
exit
|
14
|
-
end
|
15
|
-
|
16
|
-
def with_search_mode_error_handling
|
17
|
-
begin
|
18
|
-
yield
|
19
|
-
rescue UserQuits
|
20
|
-
puts "\nThanks for browsing. Library file saved"
|
21
|
-
puts ""
|
22
|
-
rescue Errno::EACCES
|
23
|
-
puts "\nYou don't have permission to write to the file you specified. Quitting immediately"
|
24
|
-
puts ""
|
25
|
-
rescue NoInternetError
|
26
|
-
puts "\nNo internet connection. Please connect to the internet and try again."
|
27
|
-
puts ""
|
28
|
-
rescue SearchError
|
29
|
-
puts "\nThere was an error with your query; be careful to format it well"
|
30
|
-
puts ""
|
31
|
-
rescue NoResults
|
32
|
-
puts "\nNo results."
|
33
|
-
puts ""
|
34
|
-
end
|
35
|
-
exit
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
data/modules/errors.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module Errors
|
2
|
-
class SearchError < StandardError
|
3
|
-
end
|
4
|
-
|
5
|
-
class BookDuplicateError < StandardError
|
6
|
-
end
|
7
|
-
|
8
|
-
class NoInternetError < StandardError
|
9
|
-
end
|
10
|
-
|
11
|
-
class NoResults < StandardError
|
12
|
-
end
|
13
|
-
|
14
|
-
class SelectionError < StandardError
|
15
|
-
end
|
16
|
-
|
17
|
-
class NotABook < StandardError
|
18
|
-
end
|
19
|
-
|
20
|
-
class UserQuits < StandardError
|
21
|
-
end
|
22
|
-
|
23
|
-
class PersistenceError < StandardError
|
24
|
-
end
|
25
|
-
end
|
data/modules/exec_helper.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require_relative 'errors'
|
2
|
-
|
3
|
-
module ExecHelper
|
4
|
-
include Errors
|
5
|
-
|
6
|
-
def process_args!(args = ARGV)
|
7
|
-
args << '-h' if args.empty?
|
8
|
-
args << args.delete("-l") if args.include?("-l")
|
9
|
-
end
|
10
|
-
|
11
|
-
def library_mode?
|
12
|
-
@options.nil?
|
13
|
-
end
|
14
|
-
|
15
|
-
def prepare_filename_for_os!
|
16
|
-
@filename.gsub!(/\//, '\\') if ENV.values.any? { |v| v =~ /[A-Z]:\\Windows/i }
|
17
|
-
end
|
18
|
-
|
19
|
-
def perform_search
|
20
|
-
search = @options[:search] || ARGV.join('+')
|
21
|
-
s = BookSearch.new(search: search, title: @options[:title], author: @options[:author],
|
22
|
-
publisher: @options[:publisher])
|
23
|
-
end
|
24
|
-
end
|
data/modules/user_prompt.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require_relative 'errors'
|
2
|
-
|
3
|
-
module UserPrompt
|
4
|
-
include Errors
|
5
|
-
|
6
|
-
def verify_selection(selection, regexp)
|
7
|
-
raise SelectionError unless selection =~ regexp
|
8
|
-
raise UserQuits if selection =~ /\A[Qq]\Z/
|
9
|
-
end
|
10
|
-
|
11
|
-
def process_selection(selection)
|
12
|
-
return selection.to_i - 1
|
13
|
-
end
|
14
|
-
|
15
|
-
def handle_successful_prompt_completion(selected_book)
|
16
|
-
puts ""
|
17
|
-
puts "The book \"#{selected_book['title']}\" has been added to your reading list."
|
18
|
-
end
|
19
|
-
|
20
|
-
def prompt(prompt, regexp, library, suppress = nil)
|
21
|
-
print prompt
|
22
|
-
s = suppress || STDIN.gets.strip
|
23
|
-
verify_selection(s, regexp)
|
24
|
-
s = process_selection(s)
|
25
|
-
raise NotABook unless s <= library.size
|
26
|
-
return s
|
27
|
-
end
|
28
|
-
|
29
|
-
def library_mode_user_prompt
|
30
|
-
while true
|
31
|
-
begin
|
32
|
-
i = prompt( "Select a book number to delete, or type \"q\" to quit: ", /\A([0-9]+|[qQ])\Z/,
|
33
|
-
@library )
|
34
|
-
|
35
|
-
@library.delete(i)
|
36
|
-
@library.save
|
37
|
-
@library.pretty_print
|
38
|
-
|
39
|
-
puts "Your library now looks like this."
|
40
|
-
puts ""
|
41
|
-
rescue SelectionError
|
42
|
-
puts "\nSorry, your selection was invalid. Please try again."
|
43
|
-
rescue NotABook
|
44
|
-
puts "\nSorry, your selection was invalid. Make sure your selection is in the provided range."
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
|
50
|
-
def search_mode_user_prompt
|
51
|
-
while true
|
52
|
-
begin
|
53
|
-
i = prompt( "Enter a number (1-5) to add a book to your reading list (or q to quit): ",
|
54
|
-
/\A[1-5]|[qQ]\Z/, @temp_booklist )
|
55
|
-
selected_book = @temp_booklist[i]
|
56
|
-
|
57
|
-
@persistent_library << selected_book
|
58
|
-
@persistent_library.save
|
59
|
-
|
60
|
-
handle_successful_prompt_completion(selected_book)
|
61
|
-
puts "Would you like to add another?"
|
62
|
-
puts ""
|
63
|
-
rescue BookDuplicateError
|
64
|
-
puts "\nThat book is already in your reading list. Would you like to add another?"
|
65
|
-
puts ""
|
66
|
-
rescue SelectionError
|
67
|
-
puts "\nSorry, your selection was invalid. Please try again."
|
68
|
-
puts ""
|
69
|
-
rescue NotABook
|
70
|
-
puts "\nSorry, your selection was invalid. Make sure your selection is within the range of available options."
|
71
|
-
puts ""
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|