alexandria-book-collection-manager 0.7.2 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.github/workflows/ruby.yml +77 -0
  4. data/.gitignore +5 -1
  5. data/.hound.yml +2 -0
  6. data/.rubocop.yml +87 -37
  7. data/.rubocop_todo.yml +62 -191
  8. data/.simplecov +5 -2
  9. data/CHANGELOG.md +63 -0
  10. data/Gemfile +4 -3
  11. data/INSTALL.md +26 -14
  12. data/README.md +52 -42
  13. data/Rakefile +93 -109
  14. data/TODO.md +9 -1
  15. data/alexandria-book-collection-manager.gemspec +50 -43
  16. data/bin/alexandria +30 -53
  17. data/doc/FAQ +2 -6
  18. data/doc/dependency_decisions.yml +27 -8
  19. data/lib/alexandria.rb +27 -37
  20. data/lib/alexandria/about.rb +50 -50
  21. data/lib/alexandria/book_providers.rb +90 -97
  22. data/lib/alexandria/book_providers/adlibris.rb +41 -76
  23. data/lib/alexandria/book_providers/amazon_aws.rb +96 -100
  24. data/lib/alexandria/book_providers/amazon_ecs_util.rb +295 -322
  25. data/lib/alexandria/book_providers/barnes_and_noble.rb +48 -45
  26. data/lib/alexandria/book_providers/douban.rb +26 -42
  27. data/lib/alexandria/book_providers/proxis.rb +44 -55
  28. data/lib/alexandria/book_providers/pseudomarc.rb +77 -85
  29. data/lib/alexandria/book_providers/siciliano.rb +64 -65
  30. data/lib/alexandria/book_providers/thalia.rb +42 -41
  31. data/lib/alexandria/book_providers/web.rb +15 -33
  32. data/lib/alexandria/book_providers/worldcat.rb +70 -97
  33. data/lib/alexandria/book_providers/z3950.rb +160 -173
  34. data/lib/alexandria/config.rb +1 -1
  35. data/lib/alexandria/console.rb +8 -21
  36. data/lib/alexandria/default_preferences.rb +37 -0
  37. data/lib/alexandria/execution_queue.rb +15 -13
  38. data/lib/alexandria/export_format.rb +47 -0
  39. data/lib/alexandria/export_library.rb +193 -300
  40. data/lib/alexandria/import_library.rb +108 -141
  41. data/lib/alexandria/import_library_csv.rb +43 -46
  42. data/lib/alexandria/library_collection.rb +79 -0
  43. data/lib/alexandria/library_sort_order.rb +45 -0
  44. data/lib/alexandria/library_store.rb +233 -0
  45. data/lib/alexandria/logging.rb +11 -13
  46. data/lib/alexandria/models/book.rb +13 -20
  47. data/lib/alexandria/models/library.rb +81 -353
  48. data/lib/alexandria/net.rb +5 -6
  49. data/lib/alexandria/preferences.rb +73 -87
  50. data/lib/alexandria/scanners.rb +2 -2
  51. data/lib/alexandria/scanners/{cuecat.rb → cue_cat.rb} +20 -18
  52. data/lib/alexandria/scanners/keyboard.rb +8 -8
  53. data/lib/alexandria/smart_library.rb +133 -170
  54. data/lib/alexandria/ui.rb +15 -15
  55. data/lib/alexandria/ui/about_dialog.rb +49 -0
  56. data/lib/alexandria/ui/{dialogs/acquire_dialog.rb → acquire_dialog.rb} +119 -136
  57. data/lib/alexandria/ui/alert_dialog.rb +64 -0
  58. data/lib/alexandria/ui/bad_isbns_dialog.rb +41 -0
  59. data/lib/alexandria/ui/{dialogs/barcode_animation.rb → barcode_animation.rb} +16 -15
  60. data/lib/alexandria/ui/{dialogs/book_properties_dialog.rb → book_properties_dialog.rb} +39 -52
  61. data/lib/alexandria/ui/book_properties_dialog_base.rb +318 -0
  62. data/lib/alexandria/ui/builder_base.rb +7 -27
  63. data/lib/alexandria/ui/calendar_popup.rb +58 -0
  64. data/lib/alexandria/ui/callbacks.rb +189 -183
  65. data/lib/alexandria/ui/completion_models.rb +10 -23
  66. data/lib/alexandria/ui/confirm_erase_dialog.rb +33 -0
  67. data/lib/alexandria/ui/conflict_while_copying_dialog.rb +34 -0
  68. data/lib/alexandria/ui/dndable.rb +7 -7
  69. data/lib/alexandria/ui/error_dialog.rb +25 -0
  70. data/lib/alexandria/ui/export_dialog.rb +142 -0
  71. data/lib/alexandria/ui/icons.rb +47 -63
  72. data/lib/alexandria/ui/iconview.rb +12 -10
  73. data/lib/alexandria/ui/iconview_tooltips.rb +41 -54
  74. data/lib/alexandria/ui/import_dialog.rb +157 -0
  75. data/lib/alexandria/ui/init.rb +21 -33
  76. data/lib/alexandria/ui/keep_bad_isbn_dialog.rb +36 -0
  77. data/lib/alexandria/ui/libraries_combo.rb +16 -14
  78. data/lib/alexandria/ui/listview.rb +73 -87
  79. data/lib/alexandria/ui/main_app.rb +24 -26
  80. data/lib/alexandria/ui/misc_dialogs.rb +10 -0
  81. data/lib/alexandria/ui/multi_drag_treeview.rb +28 -41
  82. data/lib/alexandria/ui/{dialogs/new_book_dialog.rb → new_book_dialog.rb} +156 -194
  83. data/lib/alexandria/ui/new_book_dialog_manual.rb +139 -0
  84. data/lib/alexandria/ui/new_provider_dialog.rb +100 -0
  85. data/lib/alexandria/ui/new_smart_library_dialog.rb +74 -0
  86. data/lib/alexandria/ui/preferences_dialog.rb +313 -0
  87. data/lib/alexandria/ui/provider_preferences_base_dialog.rb +95 -0
  88. data/lib/alexandria/ui/provider_preferences_dialog.rb +35 -0
  89. data/lib/alexandria/ui/really_delete_dialog.rb +53 -0
  90. data/lib/alexandria/ui/{sidepane.rb → sidepane_manager.rb} +56 -68
  91. data/lib/alexandria/ui/skip_entry_dialog.rb +33 -0
  92. data/lib/alexandria/ui/smart_library_properties_dialog.rb +60 -0
  93. data/lib/alexandria/ui/smart_library_properties_dialog_base.rb +242 -0
  94. data/lib/alexandria/ui/smart_library_rule_box.rb +119 -0
  95. data/lib/alexandria/ui/sound.rb +11 -13
  96. data/lib/alexandria/ui/ui_manager.rb +236 -251
  97. data/lib/alexandria/undo_manager.rb +1 -0
  98. data/lib/alexandria/version.rb +4 -19
  99. data/lib/alexandria/web_themes.rb +22 -21
  100. data/po/Makefile +2 -2
  101. data/po/cs.po +993 -880
  102. data/po/cy.po +957 -874
  103. data/po/de.po +990 -869
  104. data/po/el.po +989 -869
  105. data/po/es.po +985 -865
  106. data/po/fr.po +986 -870
  107. data/po/ga.po +907 -823
  108. data/po/gl.po +981 -865
  109. data/po/it.po +986 -868
  110. data/po/ja.po +969 -853
  111. data/po/mk.po +983 -863
  112. data/po/nb.po +979 -863
  113. data/po/nl.po +983 -864
  114. data/po/pl.po +1017 -974
  115. data/po/pt.po +988 -861
  116. data/po/pt_BR.po +984 -868
  117. data/po/ru.po +992 -873
  118. data/po/sk.po +987 -869
  119. data/po/sv.po +977 -861
  120. data/po/uk.po +975 -865
  121. data/po/zh_TW.po +976 -860
  122. data/schemas/alexandria.schemas +25 -3
  123. data/share/alexandria/glade/acquire_dialog__builder.glade +15 -12
  124. data/share/alexandria/glade/book_properties_dialog__builder.glade +171 -299
  125. data/share/alexandria/glade/main_app__builder.glade +24 -33
  126. data/share/alexandria/glade/new_book_dialog__builder.glade +27 -59
  127. data/share/alexandria/glade/preferences_dialog__builder.glade +250 -290
  128. data/share/gnome/help/alexandria/C/introduction.xml +0 -8
  129. data/share/gnome/help/alexandria/C/searching.xml +1 -1
  130. data/share/gnome/help/alexandria/C/smart-libraries.xml +2 -2
  131. data/share/gnome/help/alexandria/C/working-with-libraries.xml +1 -1
  132. data/share/gnome/help/alexandria/fr/alexandria.xml +1 -1
  133. data/share/gnome/help/alexandria/ja/introduction.xml +0 -8
  134. data/share/gnome/help/alexandria/ja/smart-libraries.xml +1 -1
  135. data/spec/alexandria/book_providers/world_cat_provider_spec.rb +160 -0
  136. data/spec/alexandria/book_providers_spec.rb +75 -171
  137. data/spec/alexandria/book_spec.rb +12 -10
  138. data/spec/alexandria/console_spec.rb +27 -0
  139. data/spec/alexandria/export_library_spec.rb +130 -0
  140. data/spec/alexandria/library_spec.rb +128 -172
  141. data/spec/alexandria/library_store_spec.rb +37 -0
  142. data/spec/alexandria/preferences_spec.rb +44 -17
  143. data/spec/alexandria/scanners/cue_cat_spec.rb +52 -0
  144. data/spec/alexandria/smart_library_spec.rb +30 -25
  145. data/spec/alexandria/ui/about_dialog_spec.rb +14 -0
  146. data/spec/alexandria/ui/acquire_dialog_spec.rb +14 -0
  147. data/spec/alexandria/ui/alert_dialog_spec.rb +16 -0
  148. data/spec/alexandria/ui/bad_isbns_dialog_spec.rb +14 -0
  149. data/spec/alexandria/ui/book_properties_dialog_spec.rb +17 -0
  150. data/spec/alexandria/ui/confirm_erase_dialog_spec.rb +14 -0
  151. data/spec/alexandria/ui/conflict_while_copying_dialog_spec.rb +16 -0
  152. data/spec/alexandria/ui/error_dialog_spec.rb +14 -0
  153. data/spec/alexandria/ui/export_dialog_spec.rb +36 -0
  154. data/spec/alexandria/ui/icons_spec.rb +26 -0
  155. data/spec/alexandria/ui/iconview_spec.rb +7 -21
  156. data/spec/alexandria/ui/import_dialog_spec.rb +46 -0
  157. data/spec/alexandria/ui/keep_bad_isbn_dialog_spec.rb +17 -0
  158. data/spec/alexandria/ui/main_app_spec.rb +7 -34
  159. data/spec/alexandria/ui/new_book_dialog_manual_spec.rb +15 -0
  160. data/spec/alexandria/ui/new_book_dialog_spec.rb +22 -0
  161. data/spec/alexandria/ui/new_provider_dialog_spec.rb +30 -0
  162. data/spec/alexandria/ui/new_smart_library_dialog_spec.rb +39 -0
  163. data/spec/alexandria/ui/preferences_dialog_spec.rb +14 -0
  164. data/spec/alexandria/ui/provider_preferences_dialog_spec.rb +34 -0
  165. data/spec/alexandria/ui/really_delete_dialog_spec.rb +16 -0
  166. data/spec/alexandria/ui/sidepane_manager_spec.rb +15 -0
  167. data/spec/alexandria/ui/skip_entry_dialog_spec.rb +14 -0
  168. data/spec/alexandria/ui/smart_library_properties_dialog_spec.rb +49 -0
  169. data/spec/alexandria/ui/sound_spec.rb +2 -2
  170. data/spec/alexandria/ui/ui_manager_spec.rb +43 -20
  171. data/spec/end_to_end/basic_run_spec.rb +52 -0
  172. data/spec/spec_helper.rb +65 -33
  173. data/tasks/setup.rb +2 -2
  174. data/tasks/spec.rake +16 -3
  175. data/util/rake/fileinstall.rb +39 -35
  176. data/util/rake/gettextgenerate.rb +7 -7
  177. data/util/rake/omfgenerate.rb +7 -7
  178. metadata +178 -45
  179. data/dogtail/basic_run_test.py +0 -9
  180. data/lib/alexandria/book_providers/deastore.rb +0 -265
  181. data/lib/alexandria/book_providers/mcu.rb +0 -182
  182. data/lib/alexandria/book_providers/renaud.rb +0 -149
  183. data/lib/alexandria/ui/dialogs/about_dialog.rb +0 -61
  184. data/lib/alexandria/ui/dialogs/alert_dialog.rb +0 -72
  185. data/lib/alexandria/ui/dialogs/bad_isbns_dialog.rb +0 -51
  186. data/lib/alexandria/ui/dialogs/book_properties_dialog_base.rb +0 -426
  187. data/lib/alexandria/ui/dialogs/export_dialog.rb +0 -171
  188. data/lib/alexandria/ui/dialogs/import_dialog.rb +0 -196
  189. data/lib/alexandria/ui/dialogs/misc_dialogs.rb +0 -87
  190. data/lib/alexandria/ui/dialogs/new_book_dialog_manual.rb +0 -154
  191. data/lib/alexandria/ui/dialogs/new_smart_library_dialog.rb +0 -74
  192. data/lib/alexandria/ui/dialogs/preferences_dialog.rb +0 -568
  193. data/lib/alexandria/ui/dialogs/smart_library_properties_dialog.rb +0 -59
  194. data/lib/alexandria/ui/dialogs/smart_library_properties_dialog_base.rb +0 -420
  195. data/spec/alexandria/scanners/cuecat_spec.rb +0 -67
  196. data/spec/alexandria/ui/dialogs_spec.rb +0 -96
  197. data/spec/alexandria/ui/sidepane_spec.rb +0 -29
  198. data/spec/alexandria/ui/ui_utilities_spec.rb +0 -62
  199. data/spec/alexandria/utilities_spec.rb +0 -52
  200. data/tasks/dogtail.rake +0 -6
@@ -17,35 +17,35 @@
17
17
  # write to the Free Software Foundation, Inc., 51 Franklin Street,
18
18
  # Fifth Floor, Boston, MA 02110-1301 USA.
19
19
 
20
- require 'gdk_pixbuf2'
21
- require 'gtk3'
20
+ require "gdk_pixbuf2"
21
+ require "gtk3"
22
22
 
23
- require 'alexandria/ui/icons'
24
- require 'alexandria/ui/builder_base'
25
- require 'alexandria/ui/completion_models'
26
- require 'alexandria/ui/libraries_combo'
27
- require 'alexandria/ui/multi_drag_treeview'
28
- require 'alexandria/ui/main_app'
23
+ require "alexandria/ui/icons"
24
+ require "alexandria/ui/builder_base"
25
+ require "alexandria/ui/completion_models"
26
+ require "alexandria/ui/libraries_combo"
27
+ require "alexandria/ui/multi_drag_treeview"
28
+ require "alexandria/ui/main_app"
29
29
 
30
30
  module Alexandria
31
31
  module UI
32
32
  include Logging
33
33
  def self.init_icons
34
- log.info { 'Initializing Icons...' }
34
+ log.info { "Initializing Icons" }
35
35
  Icons.init
36
36
  end
37
37
 
38
38
  def self.start_main_app
39
- puts '==========================' if $DEBUG
40
- log.info { 'Starting MainApp...' }
41
- puts '==========================' if $DEBUG
39
+ log.debug { "==========================" }
40
+ log.info { "Starting MainApp" }
41
+ log.debug { "==========================" }
42
42
  MainApp.instance
43
43
  end
44
44
 
45
45
  def self.start_gtk
46
- puts '====================================' if $DEBUG
47
- log.info { 'Starting Gtk...' }
48
- puts '====================================' if $DEBUG
46
+ log.debug { "====================================" }
47
+ log.info { "Starting Gtk" }
48
+ log.debug { "====================================" }
49
49
  Gtk.main
50
50
  end
51
51
 
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of Alexandria.
4
+ #
5
+ # See the file README.md for authorship and licensing information.
6
+
7
+ module Alexandria
8
+ module UI
9
+ class AboutDialog
10
+ GPL = <<~EOL # rubocop:disable GetText/DecorateString
11
+ Alexandria is free software; you can redistribute it and/or
12
+ modify it under the terms of the GNU General Public License as
13
+ published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version.
15
+
16
+ Alexandria is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public
22
+ License along with Alexandria; see the file COPYING. If not,
23
+ write to the Free Software Foundation, Inc., 51 Franklin Street,
24
+ Fifth Floor, Boston, MA 02110-1301 USA.
25
+ EOL
26
+
27
+ def initialize(parent)
28
+ @dialog = Gtk::AboutDialog.new
29
+ @dialog.name = Alexandria::TITLE
30
+ @dialog.version = Alexandria::DISPLAY_VERSION
31
+ @dialog.copyright = Alexandria::COPYRIGHT
32
+ @dialog.comments = Alexandria::DESCRIPTION
33
+ @dialog.authors = Alexandria::AUTHORS
34
+ @dialog.documenters = Alexandria::DOCUMENTERS
35
+ @dialog.artists = Alexandria::ARTISTS
36
+ @dialog.translator_credits = Alexandria::TRANSLATORS.join("\n")
37
+ @dialog.logo = Icons::ALEXANDRIA
38
+ @dialog.website = Alexandria::WEBSITE_URL
39
+ @dialog.license = GPL
40
+ @dialog.transient_for = parent
41
+ @dialog.signal_connect("response") { @dialog.destroy }
42
+ end
43
+
44
+ def show
45
+ @dialog.show
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,35 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright (C) 2004-2006 Laurent Sansonetti
4
- # Copyright (C) 2007 Cathal Mc Ginley
5
- # Copyright (C) 2011, 2016 Matijs van Zuijlen
3
+ # This file is part of Alexandria.
6
4
  #
7
- # Alexandria is free software; you can redistribute it and/or
8
- # modify it under the terms of the GNU General Public License as
9
- # published by the Free Software Foundation; either version 2 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # Alexandria is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
- # General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU General Public
18
- # License along with Alexandria; see the file COPYING. If not,
19
- # write to the Free Software Foundation, Inc., 51 Franklin Street,
20
- # Fifth Floor, Boston, MA 02110-1301 USA.
5
+ # See the file README.md for authorship and licensing information.
21
6
 
22
- # require 'monitor'
23
- require 'alexandria/scanners/cuecat'
24
- require 'alexandria/scanners/keyboard'
7
+ require "monitor"
8
+ require "alexandria/scanners/cue_cat"
9
+ require "alexandria/scanners/keyboard"
25
10
 
26
- require 'alexandria/ui/sound'
27
- require 'alexandria/ui/dialogs/barcode_animation'
11
+ require "alexandria/ui/builder_base"
12
+ require "alexandria/ui/barcode_animation"
13
+ require "alexandria/ui/error_dialog"
14
+ require "alexandria/ui/sound"
28
15
 
29
16
  module Alexandria
30
17
  module UI
31
- require 'monitor'
32
-
33
18
  # assists in turning on progress bar when searching
34
19
  # and turning it off when all search threads have completed...
35
20
  class SearchThreadCounter < Monitor
@@ -57,14 +42,14 @@ module Alexandria
57
42
  include GetText
58
43
  include Logging
59
44
  extend GetText
60
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
45
+ GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
61
46
 
62
47
  def initialize(parent, selected_library = nil, &block)
63
- super('acquire_dialog__builder.glade', widget_names)
48
+ super("acquire_dialog__builder.glade", widget_names)
64
49
  @acquire_dialog.transient_for = @parent = parent
65
50
  @block = block
66
51
 
67
- libraries = Libraries.instance.all_regular_libraries
52
+ libraries = LibraryCollection.instance.all_regular_libraries
68
53
  selected_library = libraries.first if selected_library.is_a?(SmartLibrary)
69
54
  @combo_libraries.populate_with_libraries(libraries,
70
55
  selected_library)
@@ -79,25 +64,22 @@ module Alexandria
79
64
  @search_threads_running = @search_thread_counter.new_cond
80
65
  end
81
66
 
67
+ def show
68
+ @acquire_dialog.show
69
+ end
70
+
82
71
  def widget_names
83
- [:acquire_dialog, :dialog_vbox1, :dialog_action_area1,
84
- :help_button, :cancel_button, :add_button, :vbox1,
85
- :barcode_label, :scan_area, :scan_frame, :scrolledwindow1,
86
- :barcodes_treeview, :hbox1, :label1, :combo_libraries]
72
+ [:acquire_dialog, :add_button, :barcodes_treeview, :barcode_label,
73
+ :scan_area, :scan_frame, :combo_libraries]
87
74
  end
88
75
 
89
76
  def book_in_library(isbn10, library)
90
77
  isbn13 = Library.canonicalise_ean(isbn10)
91
- # puts "new book #{isbn10} (or #{isbn13})"
92
78
  match = library.find do |book|
93
- # puts "testing #{book.isbn}"
94
79
  (book.isbn == isbn10 || book.isbn == isbn13)
95
- # puts "book #{book.isbn}"
96
- # book == new_book
97
80
  end
98
- # puts "book_in_library match #{match.inspect}"
99
81
  !match.nil?
100
- rescue
82
+ rescue StandardError
101
83
  log.warn { "Failed to check for book #{isbn10} in library #{library}" }
102
84
  true
103
85
  end
@@ -105,7 +87,7 @@ module Alexandria
105
87
  def on_add
106
88
  model = @barcodes_treeview.model
107
89
 
108
- libraries = Libraries.instance.all_libraries
90
+ libraries = LibraryCollection.instance.all_libraries
109
91
  library, is_new_library =
110
92
  @combo_libraries.selection_from_libraries(libraries)
111
93
 
@@ -217,13 +199,13 @@ module Alexandria
217
199
  if isbn_duplicates.empty?
218
200
  @acquire_dialog.destroy unless adding_a_selection
219
201
  else
220
- message = n_('There was %d duplicate',
221
- 'There were %d duplicates',
202
+ message = n_("There was %d duplicate",
203
+ "There were %d duplicates",
222
204
  isbn_duplicates.size) % isbn_duplicates.size
223
205
  title = n_("Couldn't add this book",
224
206
  "Couldn't add these books",
225
207
  isbn_duplicates.size)
226
- ErrorDialog.new(@parent, title, message)
208
+ ErrorDialog.new(@acquire_dialog, title, message).display
227
209
  end
228
210
 
229
211
  @block.call(books, library, is_new_library)
@@ -237,7 +219,7 @@ module Alexandria
237
219
 
238
220
  def read_barcode_scan
239
221
  @animation.start
240
- play_sound('scanning') if @test_scan
222
+ play_sound("scanning") if @test_scan
241
223
  log.debug { "reading scanner data #{@scanner_buffer}" }
242
224
  barcode_text = nil
243
225
  isbn = nil
@@ -247,25 +229,25 @@ module Alexandria
247
229
  isbn = Library.canonicalise_isbn(barcode_text)
248
230
  # TODO: : use an AppFacade
249
231
  # isbn = LookupBook.get_isbn(barcode_text)
250
- rescue StandardError => err
251
- log.error { "Bad scan: #{@scanner_buffer} #{err}" }
232
+ rescue StandardError => ex
233
+ log.error { "Bad scan: #{@scanner_buffer} #{ex}" }
252
234
  ensure
253
- @scanner_buffer = ''
235
+ @scanner_buffer = ""
254
236
  end
255
237
  if isbn
256
238
  log.debug { "Got ISBN #{isbn}" }
257
- play_sound('good_scan')
239
+ play_sound("good_scan")
258
240
 
259
241
  @barcodes_treeview.model.freeze_notify do
260
242
  iter = @barcodes_treeview.model.append
261
243
  iter[0] = isbn
262
244
  iter[1] = Icons::BOOK
263
- iter[2] = ''
245
+ iter[2] = ""
264
246
  end
265
247
  lookup_book(isbn)
266
248
  else
267
- log.debug { 'was not an ISBN barcode' }
268
- play_sound('bad_scan')
249
+ log.debug { "was not an ISBN barcode" }
250
+ play_sound("bad_scan")
269
251
  end
270
252
  end
271
253
 
@@ -346,86 +328,82 @@ module Alexandria
346
328
 
347
329
  def lookup_book(isbn)
348
330
  Thread.new do
349
- begin
350
- start_search
351
- results = Alexandria::BookProviders.isbn_search(isbn)
352
- book = results[0]
353
- cover_uri = results[1]
354
- @book_results[isbn] = results
355
- set_cover_image_async(isbn, cover_uri)
356
-
357
- @barcodes_treeview.model.freeze_notify do
358
- @barcodes_treeview.model.each do |model, path, iter|
359
- if iter[0] == isbn
360
- iter[2] = book.title
361
- model.row_changed(path, iter)
362
- end
331
+ start_search
332
+ results = Alexandria::BookProviders.isbn_search(isbn)
333
+ book = results[0]
334
+ cover_uri = results[1]
335
+ @book_results[isbn] = results
336
+ set_cover_image_async(isbn, cover_uri)
337
+
338
+ @barcodes_treeview.model.freeze_notify do
339
+ @barcodes_treeview.model.each do |model, path, iter|
340
+ if iter[0] == isbn
341
+ iter[2] = book.title
342
+ model.row_changed(path, iter)
363
343
  end
364
344
  end
365
-
366
- @add_button.sensitive = true
367
- rescue StandardError => err
368
- log.error { "Book Search failed: #{err.message}" }
369
- log << err if log.error?
370
- ensure
371
- stop_search
372
345
  end
346
+
347
+ @add_button.sensitive = true
348
+ rescue StandardError => ex
349
+ log.error { "Book Search failed: #{ex.message}" }
350
+ log << ex if log.error?
351
+ ensure
352
+ stop_search
373
353
  end
374
354
  end
375
355
 
376
356
  def set_cover_image_async(isbn, cover_uri)
377
357
  Thread.new do
378
- begin
379
- pixbuf = nil
380
- if cover_uri
381
- image_data = nil
382
- if URI.parse(cover_uri).scheme.nil?
383
- File.open(cover_uri, 'r') do |io|
384
- image_data = io.read
385
- end
386
- else
387
- image_data = URI.parse(cover_uri).read
358
+ pixbuf = nil
359
+ if cover_uri
360
+ image_data = nil
361
+ if URI.parse(cover_uri).scheme.nil?
362
+ File.open(cover_uri, "r") do |io|
363
+ image_data = io.read
388
364
  end
389
- loader = GdkPixbuf::PixbufLoader.new
390
- loader.last_write(image_data)
391
- pixbuf = loader.pixbuf
392
365
  else
393
- pixbuf = Icons::BOOK
366
+ image_data = URI.parse(cover_uri).read
394
367
  end
368
+ loader = GdkPixbuf::PixbufLoader.new
369
+ loader.last_write(image_data)
370
+ pixbuf = loader.pixbuf
371
+ else
372
+ pixbuf = Icons::BOOK
373
+ end
395
374
 
396
- @barcodes_treeview.model.freeze_notify do
397
- @barcodes_treeview.model.each do |model, path, iter|
398
- if iter[0] == isbn
399
- iter[1] = pixbuf
400
- model.row_changed(path, iter)
401
- end
375
+ @barcodes_treeview.model.freeze_notify do
376
+ @barcodes_treeview.model.each do |model, path, iter|
377
+ if iter[0] == isbn
378
+ iter[1] = pixbuf
379
+ model.row_changed(path, iter)
402
380
  end
403
381
  end
404
- rescue StandardError => err
405
- log.error {
406
- "Failed to load cover image icon: #{err.message}"
407
- }
408
- log << err if log.error?
409
382
  end
383
+ rescue StandardError => ex
384
+ log.error do
385
+ "Failed to load cover image icon: #{ex.message}"
386
+ end
387
+ log << ex if log.error?
410
388
  end
411
389
  end
412
390
 
413
391
  def on_destroy
414
- MainApp.instance.ui_manager.set_status_label('')
392
+ MainApp.instance.ui_manager.set_status_label("")
415
393
  notify_end_add_by_isbn
416
394
  # TODO: possibly make sure all threads have stopped running
417
395
  @animation.destroy
418
396
  end
419
397
 
420
398
  def setup_scanner_area
421
- @scanner_buffer = ''
399
+ @scanner_buffer = ""
422
400
  scanner_name = @prefs.barcode_scanner
423
401
 
424
- @scanner = Alexandria::Scanners.find_scanner scanner_name ||
402
+ @scanner = Alexandria::Scanners.find_scanner(scanner_name) ||
425
403
  Alexandria::Scanners.default_scanner # CueCat is default
426
404
 
427
405
  log.debug { "Using #{@scanner.name} scanner" }
428
- message = _('Ready to use %s barcode scanner') % @scanner.name
406
+ message = _("Ready to use %s barcode scanner") % @scanner.name
429
407
  MainApp.instance.ui_manager.set_status_label(message)
430
408
 
431
409
  @prev_time = 0
@@ -435,40 +413,41 @@ module Alexandria
435
413
  @scan_frame.add(@animation.canvas)
436
414
 
437
415
  # attach signals
438
- @scan_area.signal_connect('button-press-event') do |_widget, _event|
416
+ @scan_area.signal_connect("button-press-event") do |_widget, _event|
439
417
  @scan_area.grab_focus
440
418
  end
441
- @scan_area.signal_connect('focus-in-event') do |_widget, _event|
442
- @barcode_label.label = _(format('%s _Barcode Scanner Ready', _(@scanner.display_name)))
443
- @scanner_buffer = ''
419
+ @scan_area.signal_connect("focus-in-event") do |_widget, _event|
420
+ @barcode_label.label =
421
+ _(format("%s _Barcode Scanner Ready", _(@scanner.display_name)))
422
+ @scanner_buffer = ""
444
423
  begin
445
424
  @animation.set_active
446
- rescue StandardError => err
447
- log << err if log.error?
425
+ rescue StandardError => ex
426
+ log << ex if log.error?
448
427
  end
449
428
  end
450
- @scan_area.signal_connect('focus-out-event') do |_widget, _event|
451
- @barcode_label.label = _('Click below to scan _barcodes')
452
- @scanner_buffer = ''
429
+ @scan_area.signal_connect("focus-out-event") do |_widget, _event|
430
+ @barcode_label.label = _("Click below to scan _barcodes")
431
+ @scanner_buffer = ""
453
432
  @animation.set_passive
454
433
  # @scanner_background.destroy
455
434
  end
456
435
 
457
436
  @@debug_index = 0
458
- @scan_area.signal_connect('key-press-event') do |_button, event|
437
+ @scan_area.signal_connect("key-press-event") do |_button, event|
459
438
  # log.debug { event.keyval }
460
439
  # event.keyval == 65293 means Enter key
461
440
  # HACK, this disallows numeric keypad entry of data...
462
441
  if event.keyval < 255
463
442
  if @scanner_buffer.empty?
464
- if event.keyval.chr == '`' # backtick key for devs
443
+ if event.keyval.chr == "`" # backtick key for devs
465
444
  developer_test_scan
466
445
  next
467
446
  else
468
447
  # this is our first character, notify user
469
- log.debug { 'Scanning! Received first character.' }
448
+ log.debug { "Scanning! Received first character." }
470
449
  end
471
- play_sound('scanning')
450
+ play_sound("scanning")
472
451
  end
473
452
  @scanner_buffer << event.keyval.chr
474
453
 
@@ -492,7 +471,7 @@ module Alexandria
492
471
  if @scanner.match? @scanner_buffer
493
472
 
494
473
  Thread.new(@interval, @scanner_buffer) do |interval, buffer|
495
- log.debug { 'Waiting for more scanner input...' }
474
+ log.debug { "Waiting for more scanner input" }
496
475
  GLib::Idle.add do
497
476
  @animation.manual_input
498
477
  false
@@ -500,7 +479,7 @@ module Alexandria
500
479
  time_to_wait = [3, interval * 4].min
501
480
  sleep(time_to_wait)
502
481
  if buffer == @scanner_buffer
503
- log.debug { 'Buffer unchanged; scanning complete' }
482
+ log.debug { "Buffer unchanged; scanning complete" }
504
483
  GLib::Idle.add do
505
484
  @animation.scanner_input
506
485
  false
@@ -511,7 +490,9 @@ module Alexandria
511
490
  @interval = 0
512
491
 
513
492
  else
514
- log.debug { 'Buffer has changed while waiting, reading more characters...' }
493
+ log.debug do
494
+ "Buffer has changed while waiting; reading more characters"
495
+ end
515
496
  end
516
497
  end
517
498
 
@@ -521,36 +502,38 @@ module Alexandria
521
502
 
522
503
  # @sound_player = SoundEffectsPlayer.new
523
504
  @sound_players = {}
524
- @sound_players['scanning'] = SoundEffectsPlayer.new
525
- @sound_players['good_scan'] = SoundEffectsPlayer.new
526
- @sound_players['bad_scan'] = SoundEffectsPlayer.new
505
+ @sound_players["scanning"] = SoundEffectsPlayer.new
506
+ @sound_players["good_scan"] = SoundEffectsPlayer.new
507
+ @sound_players["bad_scan"] = SoundEffectsPlayer.new
527
508
  @test_scan = false
528
509
  end
529
510
 
530
511
  def play_sound(effect)
531
- if effect == 'scanning'
532
- puts "Effect: #{effect}, playing: #{@prefs.play_scanning_sound}" if $DEBUG
512
+ if effect == "scanning"
513
+ log.debug { "Effect: #{effect}, playing: #{@prefs.play_scanning_sound}" }
533
514
  return unless @prefs.play_scanning_sound
534
- @sound_players['scanning'].play('scanning')
515
+
516
+ @sound_players["scanning"].play("scanning")
535
517
  else
536
- puts "Effect: #{effect}, playing: #{@prefs.play_scan_sound}" if $DEBUG
518
+ log.debug { "Effect: #{effect}, playing: #{@prefs.play_scan_sound}" }
537
519
  return unless @prefs.play_scan_sound
520
+
538
521
  # sleep(0.5) # "scanning" effect lasts 0.5 seconds, wait for it to end
539
522
  @sound_players[effect].play(effect)
540
523
  end
541
524
  end
542
525
 
543
526
  def developer_test_scan
544
- log.info { 'Developer test scan.' }
545
- scans = ['.C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3j3C3f1Dxj3Dq.',
546
- '.C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3z0CNj3Dhj1EW.',
547
- '.C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3r2DNbXCxTZCW.',
548
- '.C3nZC3nZC3n2ChnWENz7DxnY.cGf2.ENr7C3z0DNn0ENnWE3nZDhP6.',
549
- '.C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7CNT2CxT2ChP0Dq.',
550
- '.C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7CNT6E3f7CNbWDa.',
551
- '.C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3b3ENjYDxv3EW.',
552
- '.C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3b2DxjZE3b3Dq.',
553
- '.C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3n6CNr6DxvYDa.']
527
+ log.info { "Developer test scan" }
528
+ scans = [".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3j3C3f1Dxj3Dq.",
529
+ ".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3z0CNj3Dhj1EW.",
530
+ ".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3r2DNbXCxTZCW.",
531
+ ".C3nZC3nZC3n2ChnWENz7DxnY.cGf2.ENr7C3z0DNn0ENnWE3nZDhP6.",
532
+ ".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7CNT2CxT2ChP0Dq.",
533
+ ".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7CNT6E3f7CNbWDa.",
534
+ ".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3b3ENjYDxv3EW.",
535
+ ".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3b2DxjZE3b3Dq.",
536
+ ".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3n6CNr6DxvYDa."]
554
537
  @scanner_buffer = scans[@@debug_index % scans.size]
555
538
  @@debug_index += 1
556
539
  @test_scan = true
@@ -569,12 +552,12 @@ module Alexandria
569
552
  text_renderer.editable = false
570
553
 
571
554
  # Add column using our renderer
572
- col = Gtk::TreeViewColumn.new('ISBN', text_renderer, text: 0)
555
+ col = Gtk::TreeViewColumn.new("ISBN", text_renderer, text: 0)
573
556
  @barcodes_treeview.append_column(col)
574
557
 
575
558
  # Middle colulmn is cover-image renderer
576
559
  pixbuf_renderer = Gtk::CellRendererPixbuf.new
577
- col = Gtk::TreeViewColumn.new('Cover', pixbuf_renderer)
560
+ col = Gtk::TreeViewColumn.new("Cover", pixbuf_renderer)
578
561
 
579
562
  col.set_cell_data_func(pixbuf_renderer) do |_column, cell, _model, iter|
580
563
  pixbuf = iter[1]
@@ -593,10 +576,10 @@ module Alexandria
593
576
  @barcodes_treeview.append_column(col)
594
577
 
595
578
  # Add column using the second renderer
596
- col = Gtk::TreeViewColumn.new('Title', text_renderer, text: 2)
579
+ col = Gtk::TreeViewColumn.new("Title", text_renderer, text: 2)
597
580
  @barcodes_treeview.append_column(col)
598
581
 
599
- @barcodes_treeview.model.signal_connect('row-deleted') do |model, _path|
582
+ @barcodes_treeview.model.signal_connect("row-deleted") do |model, _path|
600
583
  @add_button.sensitive = false unless model.iter_first
601
584
  end
602
585
  end