alexandria-book-collection-manager 0.7.9 → 0.7.11

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.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +5 -1
  3. data/.github/workflows/ruby.yml +36 -22
  4. data/.rubocop.yml +12 -3
  5. data/.rubocop_todo.yml +35 -47
  6. data/.simplecov +2 -2
  7. data/CHANGELOG.md +71 -24
  8. data/Gemfile +0 -6
  9. data/Rakefile +5 -5
  10. data/alexandria-book-collection-manager.gemspec +24 -21
  11. data/bin/rake +28 -0
  12. data/bin/rspec +28 -0
  13. data/doc/dependency_decisions.yml +32 -26
  14. data/{bin → exe}/alexandria +1 -3
  15. data/lib/alexandria/about.rb +1 -0
  16. data/lib/alexandria/book_providers/bl_provider.rb +4 -6
  17. data/lib/alexandria/book_providers/{douban.rb → douban_provider.rb} +1 -1
  18. data/lib/alexandria/book_providers/loc_provider.rb +2 -6
  19. data/lib/alexandria/book_providers/sbn_provider.rb +2 -12
  20. data/lib/alexandria/book_providers/thalia_provider.rb +5 -6
  21. data/lib/alexandria/book_providers/{web.rb → website_based_provider.rb} +20 -1
  22. data/lib/alexandria/book_providers/{worldcat.rb → world_cat_provider.rb} +3 -4
  23. data/lib/alexandria/book_providers/z3950_provider.rb +25 -27
  24. data/lib/alexandria/book_providers.rb +14 -10
  25. data/lib/alexandria/config.rb +2 -2
  26. data/lib/alexandria/console.rb +12 -10
  27. data/lib/alexandria/export_format.rb +3 -2
  28. data/lib/alexandria/export_library.rb +35 -40
  29. data/lib/alexandria/import_library.rb +3 -4
  30. data/lib/alexandria/import_library_csv.rb +2 -2
  31. data/lib/alexandria/library_collection.rb +1 -1
  32. data/lib/alexandria/library_store.rb +20 -15
  33. data/lib/alexandria/logging.rb +22 -21
  34. data/lib/alexandria/models/book.rb +1 -2
  35. data/lib/alexandria/models/library.rb +7 -8
  36. data/lib/alexandria/preferences.rb +7 -19
  37. data/lib/alexandria/{book_providers/pseudomarc.rb → pseudo_marc_parser.rb} +2 -2
  38. data/lib/alexandria/scanners/cue_cat.rb +5 -9
  39. data/lib/alexandria/scanners/{keyboard.rb → keyboard_wedge.rb} +3 -3
  40. data/lib/alexandria/scanners.rb +2 -2
  41. data/lib/alexandria/smart_library.rb +9 -5
  42. data/lib/alexandria/ui/acquire_dialog.rb +42 -45
  43. data/lib/alexandria/ui/alert_dialog.rb +3 -3
  44. data/lib/alexandria/ui/barcode_animation.rb +3 -3
  45. data/lib/alexandria/ui/book_properties_dialog.rb +9 -9
  46. data/lib/alexandria/ui/book_properties_dialog_base.rb +13 -14
  47. data/lib/alexandria/ui/builder_base.rb +1 -1
  48. data/lib/alexandria/ui/callbacks.rb +8 -7
  49. data/lib/alexandria/ui/confirm_erase_dialog.rb +1 -0
  50. data/lib/alexandria/ui/conflict_while_copying_dialog.rb +1 -0
  51. data/lib/alexandria/ui/export_dialog.rb +1 -0
  52. data/lib/alexandria/ui/{iconview.rb → icon_view_manager.rb} +1 -0
  53. data/lib/alexandria/ui/icons.rb +2 -2
  54. data/lib/alexandria/ui/iconview_tooltips.rb +1 -1
  55. data/lib/alexandria/ui/init.rb +10 -4
  56. data/lib/alexandria/ui/keep_bad_isbn_dialog.rb +1 -0
  57. data/lib/alexandria/ui/libraries_combo.rb +1 -0
  58. data/lib/alexandria/ui/listview.rb +2 -0
  59. data/lib/alexandria/ui/main_app.rb +3 -1
  60. data/lib/alexandria/ui/multi_drag_treeview.rb +0 -2
  61. data/lib/alexandria/ui/new_book_dialog.rb +15 -20
  62. data/lib/alexandria/ui/new_book_dialog_manual.rb +7 -7
  63. data/lib/alexandria/ui/new_provider_dialog.rb +1 -0
  64. data/lib/alexandria/ui/new_smart_library_dialog.rb +2 -1
  65. data/lib/alexandria/ui/preferences_dialog.rb +4 -4
  66. data/lib/alexandria/ui/provider_preferences_dialog.rb +1 -0
  67. data/lib/alexandria/ui/really_delete_dialog.rb +1 -0
  68. data/lib/alexandria/ui/sidepane_manager.rb +49 -48
  69. data/lib/alexandria/ui/skip_entry_dialog.rb +1 -0
  70. data/lib/alexandria/ui/smart_library_properties_dialog.rb +1 -0
  71. data/lib/alexandria/ui/smart_library_properties_dialog_base.rb +2 -1
  72. data/lib/alexandria/ui/{sound.rb → sound_effects_player.rb} +3 -0
  73. data/lib/alexandria/ui/ui_manager.rb +194 -143
  74. data/lib/alexandria/ui.rb +1 -0
  75. data/lib/alexandria/version.rb +1 -1
  76. data/lib/alexandria/web_themes.rb +1 -1
  77. data/lib/alexandria.rb +6 -5
  78. data/po/Makefile +1 -1
  79. data/po/it.po +64 -82
  80. data/spec/alexandria/book_providers/bl_provider_spec.rb +11 -2
  81. data/spec/alexandria/book_providers/douban_provider_spec.rb +17 -0
  82. data/spec/alexandria/book_providers/loc_provider_spec.rb +10 -2
  83. data/spec/alexandria/book_providers/sbn_provider_spec.rb +10 -2
  84. data/spec/alexandria/book_providers/thalia_provider_spec.rb +9 -1
  85. data/spec/alexandria/book_providers/world_cat_provider_spec.rb +30 -10
  86. data/spec/alexandria/book_providers/z3950_provider_spec.rb +22 -0
  87. data/spec/alexandria/book_spec.rb +5 -3
  88. data/spec/alexandria/console_spec.rb +1 -1
  89. data/spec/alexandria/export_library_spec.rb +65 -19
  90. data/spec/alexandria/library_collection_spec.rb +24 -0
  91. data/spec/alexandria/library_spec.rb +68 -53
  92. data/spec/alexandria/library_store_spec.rb +33 -1
  93. data/spec/alexandria/preferences_spec.rb +7 -7
  94. data/spec/alexandria/pseudo_marc_parser_spec.rb +71 -0
  95. data/spec/alexandria/scanners/cue_cat_spec.rb +11 -4
  96. data/spec/alexandria/scanners/keyboard_wedge_spec.rb +47 -0
  97. data/spec/alexandria/smart_library_spec.rb +7 -5
  98. data/spec/alexandria/ui/about_dialog_spec.rb +2 -2
  99. data/spec/alexandria/ui/acquire_dialog_spec.rb +8 -3
  100. data/spec/alexandria/ui/alert_dialog_spec.rb +6 -4
  101. data/spec/alexandria/ui/bad_isbns_dialog_spec.rb +2 -2
  102. data/spec/alexandria/ui/book_properties_dialog_spec.rb +5 -5
  103. data/spec/alexandria/ui/confirm_erase_dialog_spec.rb +19 -3
  104. data/spec/alexandria/ui/conflict_while_copying_dialog_spec.rb +2 -2
  105. data/spec/alexandria/ui/error_dialog_spec.rb +14 -3
  106. data/spec/alexandria/ui/export_dialog_spec.rb +6 -6
  107. data/spec/alexandria/ui/{iconview_spec.rb → icon_view_manager_spec.rb} +2 -2
  108. data/spec/alexandria/ui/import_dialog_spec.rb +3 -3
  109. data/spec/alexandria/ui/keep_bad_isbn_dialog_spec.rb +2 -2
  110. data/spec/alexandria/ui/main_app_spec.rb +0 -2
  111. data/spec/alexandria/ui/new_book_dialog_manual_spec.rb +5 -5
  112. data/spec/alexandria/ui/new_book_dialog_spec.rb +7 -4
  113. data/spec/alexandria/ui/new_provider_dialog_spec.rb +3 -3
  114. data/spec/alexandria/ui/new_smart_library_dialog_spec.rb +9 -7
  115. data/spec/alexandria/ui/preferences_dialog_spec.rb +2 -2
  116. data/spec/alexandria/ui/provider_preferences_dialog_spec.rb +22 -7
  117. data/spec/alexandria/ui/really_delete_dialog_spec.rb +2 -2
  118. data/spec/alexandria/ui/sidepane_manager_spec.rb +2 -2
  119. data/spec/alexandria/ui/skip_entry_dialog_spec.rb +19 -3
  120. data/spec/alexandria/ui/smart_library_properties_dialog_spec.rb +2 -2
  121. data/spec/alexandria/ui/ui_manager_spec.rb +7 -5
  122. data/spec/end_to_end/basic_run_spec.rb +2 -1
  123. data/spec/spec_helper.rb +26 -33
  124. data/tasks/setup.rb +1 -1
  125. data/util/rake/fileinstall.rb +12 -13
  126. data/util/rake/gettextgenerate.rb +1 -1
  127. data/util/rake/omfgenerate.rb +1 -1
  128. metadata +97 -64
  129. /data/spec/alexandria/ui/{sound_spec.rb → sound_effects_player_spec.rb} +0 -0
@@ -31,8 +31,8 @@ module Alexandria
31
31
  @library.name
32
32
  end
33
33
 
34
- def each(&block)
35
- @sorted.each(&block)
34
+ def each(&)
35
+ @sorted.each(&)
36
36
  end
37
37
 
38
38
  def export_as_onix_xml_archive(filename)
@@ -52,28 +52,30 @@ module Alexandria
52
52
  end
53
53
 
54
54
  def export_as_tellico_xml_archive(filename)
55
- File.open(File.join(Dir.tmpdir, "tellico.xml"), "w") do |io|
55
+ tmpdir = Dir.mktmpdir "tellico_export"
56
+
57
+ File.open(File.join(tmpdir, "tellico.xml"), "w") do |io|
56
58
  to_tellico_document.write(io, 0)
57
59
  end
58
- copy_covers(File.join(Dir.tmpdir, "images"))
59
- Dir.chdir(Dir.tmpdir) do
60
+ copy_covers(File.join(tmpdir, "images"))
61
+ Dir.chdir(tmpdir) do
60
62
  output = `zip -q -r \"#{filename}\" tellico.xml images 2>&1`
61
63
  raise output unless $CHILD_STATUS.success?
62
64
  end
63
- FileUtils.rm_rf(File.join(Dir.tmpdir, "images"))
64
- FileUtils.rm(File.join(Dir.tmpdir, "tellico.xml"))
65
+ FileUtils.rm_rf(File.join(tmpdir, "images"))
66
+ FileUtils.rm(File.join(tmpdir, "tellico.xml"))
65
67
  end
66
68
 
67
69
  def export_as_isbn_list(filename)
68
70
  File.open(filename, "w") do |io|
69
71
  each do |book|
70
- io.puts((book.isbn || ""))
72
+ io.puts(book.isbn || "")
71
73
  end
72
74
  end
73
75
  end
74
76
 
75
77
  def export_as_html(filename, theme)
76
- FileUtils.mkdir(filename) unless File.exist?(filename)
78
+ FileUtils.mkdir_p(filename)
77
79
  Dir.chdir(filename) do
78
80
  copy_covers("pixmaps")
79
81
  FileUtils.cp_r(theme.pixmaps_directory, "pixmaps") if theme.has_pixmaps?
@@ -91,7 +93,7 @@ module Alexandria
91
93
  end
92
94
 
93
95
  def export_as_ipod_notes(filename, _theme)
94
- FileUtils.mkdir(filename) unless File.exist?(filename)
96
+ FileUtils.mkdir_p(filename)
95
97
  tempdir = Dir.getwd
96
98
  Dir.chdir(filename)
97
99
  copy_covers("pixmaps")
@@ -113,7 +115,7 @@ module Alexandria
113
115
  end
114
116
  io.puts book.authors.join(", ")
115
117
  io.puts book.edition
116
- io.puts((book.isbn || ""))
118
+ io.puts(book.isbn || "")
117
119
  # we need to close the files so the iPod can be ejected/unmounted
118
120
  # without us closing Alexandria
119
121
  io.close
@@ -140,6 +142,8 @@ module Alexandria
140
142
  private
141
143
 
142
144
  ONIX_DTD_URL = "http://www.editeur.org/onix/2.1/reference/onix-international.dtd"
145
+ private_constant :ONIX_DTD_URL
146
+
143
147
  def to_onix_document
144
148
  doc = REXML::Document.new
145
149
  doc << REXML::XMLDecl.new
@@ -211,8 +215,8 @@ module Alexandria
211
215
  doc = REXML::Document.new
212
216
  doc << REXML::XMLDecl.new
213
217
  doc << REXML::DocType.new("tellico",
214
- 'PUBLIC "-//Robby Stephenson/DTD Tellico V7.0//EN"' \
215
- ' "http://periapsis.org/tellico/dtd/v7/tellico.dtd"')
218
+ 'PUBLIC "-//Robby Stephenson/DTD Tellico V7.0//EN" ' \
219
+ '"http://periapsis.org/tellico/dtd/v7/tellico.dtd"')
216
220
  tellico = doc.add_element("tellico")
217
221
  tellico.add_attribute("syntaxVersion", "7")
218
222
  tellico.add_namespace("http://periapsis.org/tellico/")
@@ -263,10 +267,10 @@ module Alexandria
263
267
  def xhtml_escape(str)
264
268
  escaped = str.dup
265
269
  # used to occasionally use CGI.escapeHTML
266
- escaped.gsub!(/&/, "&amp;")
267
- escaped.gsub!(/</, "&lt;")
268
- escaped.gsub!(/>/, "&gt;")
269
- escaped.gsub!(/"/, "&quot;")
270
+ escaped.gsub!("&", "&amp;")
271
+ escaped.gsub!("<", "&lt;")
272
+ escaped.gsub!(">", "&gt;")
273
+ escaped.gsub!('"', "&quot;")
270
274
  escaped
271
275
  end
272
276
 
@@ -357,27 +361,18 @@ module Alexandria
357
361
  def to_bibtex
358
362
  generator = "Alexandria " + Alexandria::DISPLAY_VERSION
359
363
  bibtex = +""
360
- bibtex << "\%Generated on #{Date.today} by: #{generator}\n"
361
- bibtex << "\%\n"
364
+ bibtex << "%Generated on #{Date.today} by: #{generator}\n"
365
+ bibtex << "%\n"
362
366
  bibtex << "\n"
363
367
 
364
368
  auths = Hash.new(0)
365
369
  each do |book|
366
- k = (book.authors[0] || "Anonymous").split[0]
367
- if auths.key?(k)
368
- auths[k] += 1
369
- else
370
- auths[k] = 1
371
- end
372
- cite_key = k + auths[k].to_s
370
+ auth_key = (book.authors[0] || "Anonymous").split[0]
371
+ auths[auth_key] += 1
372
+ cite_key = "#{auth_key}#{auths[auth_key]}"
373
373
  bibtex << "@BOOK{#{cite_key},\n"
374
374
  bibtex << 'author = "'
375
- if book.authors != []
376
- bibtex << book.authors[0]
377
- book.authors[1..].each do |author|
378
- bibtex << " and #{latex_escape(author)}"
379
- end
380
- end
375
+ bibtex << book.authors.map { latex_escape(_1) }.join(" and ")
381
376
  bibtex << "\",\n"
382
377
  bibtex << "title = \"#{latex_escape(book.title)}\",\n"
383
378
  bibtex << "publisher = \"#{latex_escape(book.publisher)}\",\n"
@@ -395,14 +390,14 @@ module Alexandria
395
390
  return "" if str.nil?
396
391
 
397
392
  my_str = str.dup
398
- my_str.gsub!(/%/, "\\%")
399
- my_str.gsub!(/~/, "\\textasciitilde")
400
- my_str.gsub!(/&/, "\\\\&")
401
- my_str.gsub!(/\#/, "\\\\#")
402
- my_str.gsub!(/\{/, "\\{")
403
- my_str.gsub!(/\}/, "\\}")
404
- my_str.gsub!(/_/, "\\_")
405
- my_str.gsub!(/\$/, "\\\$")
393
+ my_str.gsub!("%", "\\%")
394
+ my_str.gsub!("~", "\\textasciitilde")
395
+ my_str.gsub!("&", "\\\\&")
396
+ my_str.gsub!("#", "\\\\#")
397
+ my_str.gsub!("{", "\\{")
398
+ my_str.gsub!("}", "\\}")
399
+ my_str.gsub!("_", "\\_")
400
+ my_str.gsub!("$", "\\$")
406
401
  my_str.gsub!(/"(.+)"/, "``\1''")
407
402
  my_str
408
403
  end
@@ -14,6 +14,7 @@ module Alexandria
14
14
  include Logging
15
15
  include GetText
16
16
  extend GetText
17
+
17
18
  bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
18
19
 
19
20
  def self.all
@@ -71,9 +72,7 @@ module Alexandria
71
72
  log.debug { "Starting import_as_tellico_xml_archive... " }
72
73
  return nil unless system("unzip -qqt \"#{filename}\"")
73
74
 
74
- tmpdir = File.join(Dir.tmpdir, "tellico_export")
75
- FileUtils.rm_rf(tmpdir) if File.exist?(tmpdir)
76
- Dir.mkdir(tmpdir)
75
+ tmpdir = Dir.mktmpdir "tellico_import"
77
76
  Dir.chdir(tmpdir) do
78
77
  system("unzip -qq \"#{filename}\"")
79
78
  file = File.exist?("bookcase.xml") ? "bookcase.xml" : "tellico.xml"
@@ -181,7 +180,7 @@ module Alexandria
181
180
  # probably Goodreads' wonky ISBN fields ,,="043432432X",
182
181
  # this is a hack to fix up such files
183
182
  data = File.read(filename)
184
- data.gsub!(/,="/, ',"')
183
+ data.gsub!(',="', ',"')
185
184
  csv_fixed = Tempfile.new("alexandria_import_csv_fixed_")
186
185
  csv_fixed.write(data)
187
186
  csv_fixed.close
@@ -46,7 +46,7 @@ module Alexandria
46
46
 
47
47
  class GoodreadsCSVImport < CSVImport
48
48
  def initialize(header)
49
- super(header)
49
+ super
50
50
  @title = index_of("Title")
51
51
  @author = index_of("Author")
52
52
  @additional_authors = index_of("Additional Authors")
@@ -119,7 +119,7 @@ module Alexandria
119
119
 
120
120
  class LibraryThingCSVImport < CSVImport
121
121
  def initialize(header)
122
- super(header)
122
+ super
123
123
  @title = index_of("'TITLE'")
124
124
  @author = index_of("'AUTHOR (first, last)'")
125
125
  @isbn = index_of("'ISBN'")
@@ -23,7 +23,7 @@ module Alexandria
23
23
  ruined = []
24
24
  deleted = []
25
25
  all_regular_libraries.each do |library|
26
- ruined += library.ruined_books
26
+ library.ruined_books.each { |isbn| ruined << [nil, isbn, library] }
27
27
  # make deleted books from each library accessible so we don't crash on
28
28
  # smart libraries
29
29
  deleted += library.deleted_books
@@ -9,9 +9,10 @@ module Alexandria
9
9
  include Logging
10
10
 
11
11
  FIX_BIGNUM_REGEX =
12
- %r{loaned_since:\s*(!ruby/object:Bignum\s*)?(\d+)\n}.freeze
12
+ %r{loaned_since:\s*(!ruby/object:Bignum\s*)?(\d+)\n}
13
13
 
14
14
  include GetText
15
+
15
16
  bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
16
17
 
17
18
  def initialize(dir)
@@ -32,8 +33,8 @@ module Alexandria
32
33
  rescue Errno::ENOENT
33
34
  FileUtils.mkdir_p(library_dir)
34
35
  end
35
- # Create the default library if there is no library yet.
36
36
 
37
+ # Create the default library if there is no library yet.
37
38
  a << load_library(_("My Library")) if a.empty?
38
39
 
39
40
  a
@@ -43,21 +44,13 @@ module Alexandria
43
44
  test = [0, nil]
44
45
  ruined_books = []
45
46
  library = Library.new(name, self)
46
- FileUtils.mkdir_p(library.path) unless File.exist?(library.path)
47
+ FileUtils.mkdir_p(library.path)
47
48
  Dir.chdir(library.path) do
48
- Dir["*" + Library::EXT[:book]].sort.each do |filename|
49
- test[1] = filename if (test[0]).zero?
49
+ Dir["*" + Library::EXT[:book]].each do |filename|
50
+ test[1] = filename if test[0].zero?
50
51
 
51
52
  unless File.size? test[1]
52
- log.warn { "Book file #{test[1]} was empty" }
53
- md = /([\dxX]{10,13})#{Library::EXT[:book]}/.match(filename)
54
- if md
55
- file_isbn = md[1]
56
- ruined_books << [nil, file_isbn, library]
57
- else
58
- log.warn { "Filename #{filename} does not contain an ISBN" }
59
- # TODO: delete this file...
60
- end
53
+ handle_empty_book_file(test[1], ruined_books)
61
54
  next
62
55
  end
63
56
  book = regularize_book_from_yaml(test[1])
@@ -180,6 +173,18 @@ module Alexandria
180
173
 
181
174
  private
182
175
 
176
+ def handle_empty_book_file(filename, ruined_books)
177
+ log.warn { "Book file #{filename} was empty" }
178
+ md = /([\dxX]{10,13})#{Library::EXT[:book]}/.match(filename)
179
+ if md
180
+ file_isbn = md[1]
181
+ ruined_books << file_isbn
182
+ else
183
+ log.warn { "Filename #{filename} does not contain an ISBN" }
184
+ # TODO: delete this file...
185
+ end
186
+ end
187
+
183
188
  def regularize_book_from_yaml(name)
184
189
  text = File.read(name)
185
190
 
@@ -188,7 +193,7 @@ module Alexandria
188
193
 
189
194
  # The string is removed on load, but can't make it stick, maybe has to do with cache
190
195
 
191
- if /!str:Amazon::Search::Response/.match?(text)
196
+ if text.include?("!str:Amazon::Search::Response")
192
197
  log.debug { "Removing Ruby/Amazon strings from #{name}" }
193
198
  text.gsub!("!str:Amazon::Search::Response", "")
194
199
  end
@@ -37,24 +37,24 @@ module Alexandria
37
37
  super(severity, message, category, &block)
38
38
  end
39
39
 
40
- def debug(source = nil, progname = nil, &block)
41
- add(DEBUG, nil, source, progname, &block)
40
+ def debug(source = nil, progname = nil, &)
41
+ add(DEBUG, nil, source, progname, &)
42
42
  end
43
43
 
44
- def info(source = nil, progname = nil, &block)
45
- add(INFO, nil, source, progname, &block)
44
+ def info(source = nil, progname = nil, &)
45
+ add(INFO, nil, source, progname, &)
46
46
  end
47
47
 
48
- def warn(source = nil, progname = nil, &block)
49
- add(WARN, nil, source, progname, &block)
48
+ def warn(source = nil, progname = nil, &)
49
+ add(WARN, nil, source, progname, &)
50
50
  end
51
51
 
52
- def error(source = nil, progname = nil, &block)
53
- add(ERROR, nil, source, progname, &block)
52
+ def error(source = nil, progname = nil, &)
53
+ add(ERROR, nil, source, progname, &)
54
54
  end
55
55
 
56
- def fatal(source = nil, progname = nil, &block)
57
- add(FATAL, nil, source, progname, &block)
56
+ def fatal(source = nil, progname = nil, &)
57
+ add(FATAL, nil, source, progname, &)
58
58
  end
59
59
 
60
60
  def self.category(source)
@@ -73,6 +73,7 @@ module Alexandria
73
73
  # whithout needing to specify the source each time.
74
74
  class LogWrapper
75
75
  extend Forwardable
76
+
76
77
  def initialize(logger, source)
77
78
  @logger = logger
78
79
  @source = source
@@ -90,24 +91,24 @@ module Alexandria
90
91
  end
91
92
  end
92
93
 
93
- def debug(progname = nil, &block)
94
- @logger.debug(@source, progname, &block)
94
+ def debug(progname = nil, &)
95
+ @logger.debug(@source, progname, &)
95
96
  end
96
97
 
97
- def info(progname = nil, &block)
98
- @logger.info(@source, progname, &block)
98
+ def info(progname = nil, &)
99
+ @logger.info(@source, progname, &)
99
100
  end
100
101
 
101
- def warn(progname = nil, &block)
102
- @logger.warn(@source, progname, &block)
102
+ def warn(progname = nil, &)
103
+ @logger.warn(@source, progname, &)
103
104
  end
104
105
 
105
- def error(progname = nil, &block)
106
- @logger.error(@source, progname, &block)
106
+ def error(progname = nil, &)
107
+ @logger.error(@source, progname, &)
107
108
  end
108
109
 
109
- def fatal(progname = nil, &block)
110
- @logger.fatal(@source, progname, &block)
110
+ def fatal(progname = nil, &)
111
+ @logger.fatal(@source, progname, &)
111
112
  end
112
113
  end
113
114
 
@@ -135,7 +136,7 @@ module Alexandria
135
136
  def self.create_logger
136
137
  logger = Alexandria::Logger.new($stderr)
137
138
 
138
- level = ENV["LOGLEVEL"] ? ENV["LOGLEVEL"].intern : nil
139
+ level = ENV["LOGLEVEL"]&.intern
139
140
  if [:FATAL, :ERROR, :WARN, :INFO, :DEBUG].include? level
140
141
  logger.level = Logger.const_get(level)
141
142
  else
@@ -15,11 +15,10 @@ module Alexandria
15
15
 
16
16
  DEFAULT_RATING = 0
17
17
  MAX_RATING_STARS = 5
18
- VALID_RATINGS = (DEFAULT_RATING..MAX_RATING_STARS).freeze
18
+ VALID_RATINGS = (DEFAULT_RATING..MAX_RATING_STARS)
19
19
 
20
20
  def initialize(title, authors, isbn, publisher, publishing_year,
21
21
  edition)
22
-
23
22
  @title = title
24
23
  @authors = authors
25
24
  @isbn = isbn
@@ -20,11 +20,12 @@ module Alexandria
20
20
  attr_reader :name
21
21
  attr_accessor :ruined_books, :updating, :deleted_books
22
22
 
23
- DEFAULT_DIR = File.join(ENV["HOME"], ".alexandria")
23
+ DEFAULT_DIR = File.join(Dir.home, ".alexandria")
24
24
  EXT = { book: ".yaml", cover: ".cover" }.freeze
25
25
 
26
26
  include GetText
27
27
  extend GetText
28
+
28
29
  bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
29
30
 
30
31
  BOOK_ADDED, BOOK_UPDATED, BOOK_REMOVED = (0..3).to_a
@@ -117,8 +118,7 @@ module Alexandria
117
118
 
118
119
  def self.valid_upc?(upc)
119
120
  numbers = extract_numbers(upc)
120
- ((numbers.length == 17) &&
121
- (upc_checksum(numbers[0..10]) == numbers[11]))
121
+ numbers.length == 17 && upc_checksum(numbers[0..10]) == numbers[11]
122
122
  end
123
123
 
124
124
  AMERICAN_UPC_LOOKUP = {
@@ -167,7 +167,7 @@ module Alexandria
167
167
  elsif valid_upc?(isbn)
168
168
  # Seems to be a valid UPC number.
169
169
  prefix = upc_convert(numbers[0..5])
170
- isbn_sans_chcksm = prefix + numbers[(8 + prefix.length)..17]
170
+ isbn_sans_chcksm = prefix + numbers[(prefix.length + 8)..17]
171
171
  isbn_sans_chcksm + [isbn_checksum(isbn_sans_chcksm)]
172
172
  elsif valid_isbn?(isbn)
173
173
  # Seems to be a valid ISBN number.
@@ -216,8 +216,7 @@ module Alexandria
216
216
  book.saved_ident = book.ident
217
217
  end
218
218
  # #was File.exist? but that returns true for empty files... CathalMagus
219
- already_there = (File.size?(yaml(book)) &&
220
- !@deleted_books.include?(book))
219
+ already_there = File.size?(yaml(book)) && !@deleted_books.include?(book)
221
220
 
222
221
  temp_book = book.dup
223
222
  temp_book.library = nil
@@ -379,7 +378,7 @@ module Alexandria
379
378
  end
380
379
 
381
380
  def copy_covers(somewhere)
382
- FileUtils.rm_rf(somewhere) if File.exist?(somewhere)
381
+ FileUtils.rm_rf(somewhere)
383
382
  FileUtils.mkdir(somewhere)
384
383
  each do |book|
385
384
  next unless File.exist?(cover(book))
@@ -398,7 +397,7 @@ module Alexandria
398
397
  book.ident + (Library.jpeg?(cover(book)) ? ".jpg" : ".gif")
399
398
  end
400
399
 
401
- protected
400
+ private
402
401
 
403
402
  def initialize(name, store = nil)
404
403
  @name = name
@@ -5,7 +5,6 @@
5
5
  # See the file README.md for authorship and licensing information.
6
6
 
7
7
  require "singleton"
8
- require "set"
9
8
  require "alexandria/default_preferences"
10
9
 
11
10
  module Alexandria
@@ -64,7 +63,7 @@ module Alexandria
64
63
 
65
64
  DEFAULT_VALUES.each_key do |var|
66
65
  define_method(var) { generic_getter var }
67
- define_method("#{var}=") { |val| generic_setter var, val }
66
+ define_method(:"#{var}=") { |val| generic_setter var, val }
68
67
  end
69
68
 
70
69
  def get_variable(variable_name)
@@ -120,13 +119,6 @@ module Alexandria
120
119
  # set non-list value
121
120
  exec_gconf_set(var_path, new_value)
122
121
  end
123
- rescue StandardError => ex
124
- log.debug { new_value.inspect }
125
- log.error do
126
- "Could not set GConf setting #{variable_name} to value: #{new_value.inspect}"
127
- end
128
- log << ex.message
129
- log << ex
130
122
  end
131
123
 
132
124
  ##
@@ -161,13 +153,13 @@ module Alexandria
161
153
  end
162
154
 
163
155
  def make_list_string(list)
164
- list.map! { |x| x.gsub(/"/, '\\"') } if get_gconf_type(list.first) == "string"
156
+ list.map! { |x| x.gsub('"', '\\"') } if get_gconf_type(list.first) == "string"
165
157
  contents = list.join(",")
166
158
  "[" + contents + "]"
167
159
  end
168
160
 
169
161
  def exec_gconf_set(var_path, new_value)
170
- if /cols_width/.match?(var_path)
162
+ if var_path.include?("cols_width")
171
163
  log.debug { new_value }
172
164
 
173
165
  # new_value = {}
@@ -175,10 +167,10 @@ module Alexandria
175
167
  type = get_gconf_type(new_value)
176
168
  value_str = new_value
177
169
  if new_value.is_a? String
178
- new_value = new_value.gsub(/"/, '\\"')
170
+ new_value = new_value.gsub('"', '\\"')
179
171
  value_str = "\"#{new_value}\""
180
172
  end
181
- log.debug { value_str } if /cols_width/.match?(var_path)
173
+ log.debug { value_str } if var_path.include?("cols_width")
182
174
  `gconftool-2 --type #{type} --set #{var_path} #{value_str}`
183
175
  end
184
176
 
@@ -245,12 +237,8 @@ module Alexandria
245
237
  when /^\[(.*)\]$/ # list (assume of type String)
246
238
  Regexp.last_match[1].split(",")
247
239
  when /^\((.*)\)$/ # pair (assume of type int)
248
- begin
249
- pair = Regexp.last_match[1].split(",")
250
- [discriminate(pair.first), discriminate(pair.last)]
251
- rescue StandardError
252
- [0, 0]
253
- end
240
+ pair = Regexp.last_match[1].split(",")
241
+ [discriminate(pair.first), discriminate(pair.last)]
254
242
  else
255
243
  value # string
256
244
  end
@@ -43,7 +43,7 @@ module Alexandria
43
43
 
44
44
  def self.get_fields(data, type, stripping, mappings = USMARC_MAPPINGS)
45
45
  field = ""
46
- mappings[type][1..mappings[type].length - 1].each do |part|
46
+ mappings[type][1..(mappings[type].length - 1)].each do |part|
47
47
  if data.first[part]
48
48
  part_data = data.first[part].strip
49
49
  if part_data =~ stripping
@@ -124,7 +124,7 @@ module Alexandria
124
124
 
125
125
  def self.marc_text_to_details(marc)
126
126
  details = {}
127
- marc.each_line do |line|
127
+ marc&.each_line do |line|
128
128
  if line =~ /(\d+)\s*(.+)/
129
129
  code = Regexp.last_match[1]
130
130
  data = Regexp.last_match[2]
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Copyright (C) 2005-2006 Christopher Cyll
4
- # Copyright (C) 2011 Matijs van Zuijlen
4
+ # Copyright (C) 2011, 2014-2022 Matijs van Zuijlen
5
5
  #
6
6
  # Alexandria is free software; you can redistribute it and/or
7
7
  # modify it under the terms of the GNU General Public License as
@@ -60,14 +60,10 @@ module Alexandria
60
60
  code = code[0, 13]
61
61
  end
62
62
 
63
- begin
64
- if Library.valid_upc? code
65
- isbn13 = Library.canonicalise_ean(code)
66
- code = isbn13
67
- type = "IBN"
68
- end
69
- rescue StandardError
70
- log.debug { "Cannot translate UPC (#{type}) code #{code} to ISBN" }
63
+ if Library.valid_upc? code
64
+ isbn13 = Library.canonicalise_ean(code)
65
+ code = isbn13
66
+ type = "IBN"
71
67
  end
72
68
 
73
69
  return code if type == "IBN"
@@ -36,13 +36,13 @@ module Alexandria
36
36
 
37
37
  # Checks if data looks like a completed scan
38
38
  def match?(data)
39
- data.gsub!(/\s/, "")
40
- (data =~ /[0-9]{12,18}/) || (data =~ /[0-9]{9}[0-9Xx]/)
39
+ data = data.gsub(/\s/, "")
40
+ data.match?(/^[0-9]{13,18}$/) || data.match?(/^[0-9]{9}[0-9Xx]$/)
41
41
  end
42
42
 
43
43
  # Gets the essential 13-digits from an ISBN barcode (EAN-13)
44
44
  def decode(data)
45
- data.gsub!(/\s/, "")
45
+ data = data.gsub(/\s/, "")
46
46
  if data.length == 10
47
47
  data
48
48
  elsif data.length >= 13
@@ -40,8 +40,8 @@ module Alexandria
40
40
  registry.find { |scanner| scanner.name == name }
41
41
  end
42
42
 
43
- def self.each_scanner(&block)
44
- registry.each(&block)
43
+ def self.each_scanner(&)
44
+ registry.each(&)
45
45
  end
46
46
 
47
47
  private_class_method :registry
@@ -12,6 +12,7 @@ module Alexandria
12
12
  include Logging
13
13
  include GetText
14
14
  extend GetText
15
+
15
16
  bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
16
17
 
17
18
  ALL_RULES = 1
@@ -148,7 +149,7 @@ module Alexandria
148
149
  if book
149
150
  @cache[book].save(book)
150
151
  else
151
- FileUtils.mkdir_p(base_dir) unless File.exist? base_dir
152
+ FileUtils.mkdir_p(base_dir)
152
153
  File.open(yaml, "w") { |io| io.puts to_hash.to_yaml }
153
154
  end
154
155
  end
@@ -162,7 +163,7 @@ module Alexandria
162
163
  end
163
164
 
164
165
  def copy_covers(somewhere)
165
- FileUtils.rm_rf(somewhere) if File.exist?(somewhere)
166
+ FileUtils.rm_rf(somewhere)
166
167
  FileUtils.mkdir(somewhere)
167
168
  each do |book|
168
169
  library = @cache[book]
@@ -233,6 +234,7 @@ module Alexandria
233
234
  class Rule
234
235
  include GetText
235
236
  extend GetText
237
+
236
238
  bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
237
239
 
238
240
  attr_accessor :operand, :operation, :value
@@ -273,8 +275,8 @@ module Alexandria
273
275
  class LeftOperand < Operand
274
276
  attr_accessor :book_selector
275
277
 
276
- def initialize(book_selector, *args)
277
- super(*args)
278
+ def initialize(book_selector, *)
279
+ super(*)
278
280
  @book_selector = book_selector
279
281
  end
280
282
  end
@@ -289,6 +291,7 @@ module Alexandria
289
291
  module Operands
290
292
  include GetText
291
293
  extend GetText
294
+
292
295
  bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
293
296
 
294
297
  LEFT = [
@@ -321,6 +324,7 @@ module Alexandria
321
324
  include Logging
322
325
  include GetText
323
326
  extend GetText
327
+
324
328
  bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
325
329
 
326
330
  IS_TRUE = Operator.new(:is_true,
@@ -328,7 +332,7 @@ module Alexandria
328
332
  proc { |x| x })
329
333
  IS_NOT_TRUE = Operator.new(:is_not_true,
330
334
  _("is not set"),
331
- proc { |x| !x })
335
+ proc(&:!))
332
336
  IS = Operator.new(:is,
333
337
  _("is"),
334
338
  proc { |x, y| x == y })