alexandria-book-collection-manager 0.7.1 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. checksums.yaml +5 -5
  2. data/.github/dependabot.yml +9 -0
  3. data/.gitignore +5 -2
  4. data/.hound.yml +2 -0
  5. data/.rubocop.yml +113 -45
  6. data/.rubocop_todo.yml +82 -170
  7. data/.simplecov +5 -1
  8. data/.travis.yml +45 -0
  9. data/.yardopts +1 -1
  10. data/CHANGELOG.md +60 -0
  11. data/ChangeLog.0 +33 -35
  12. data/Gemfile +6 -5
  13. data/INSTALL.md +164 -0
  14. data/README.md +52 -42
  15. data/Rakefile +95 -109
  16. data/TODO.md +9 -1
  17. data/alexandria-book-collection-manager.gemspec +52 -45
  18. data/bin/alexandria +31 -53
  19. data/doc/AUTHORS +61 -0
  20. data/doc/BUGS +31 -0
  21. data/doc/FAQ +365 -0
  22. data/doc/HACKING +19 -0
  23. data/doc/NEWS +341 -0
  24. data/doc/alexandria.1 +120 -0
  25. data/doc/cuecat_support.rdoc +67 -0
  26. data/doc/dependency_decisions.yml +80 -0
  27. data/lib/alexandria.rb +29 -37
  28. data/lib/alexandria/about.rb +52 -51
  29. data/lib/alexandria/book_providers.rb +94 -101
  30. data/lib/alexandria/book_providers/adlibris.rb +45 -85
  31. data/lib/alexandria/book_providers/amazon_aws.rb +105 -113
  32. data/lib/alexandria/book_providers/amazon_ecs_util.rb +293 -324
  33. data/lib/alexandria/book_providers/barnes_and_noble.rb +54 -53
  34. data/lib/alexandria/book_providers/douban.rb +29 -51
  35. data/lib/alexandria/book_providers/proxis.rb +42 -59
  36. data/lib/alexandria/book_providers/pseudomarc.rb +79 -99
  37. data/lib/alexandria/book_providers/siciliano.rb +68 -70
  38. data/lib/alexandria/book_providers/thalia.rb +46 -45
  39. data/lib/alexandria/book_providers/web.rb +17 -33
  40. data/lib/alexandria/book_providers/worldcat.rb +74 -102
  41. data/lib/alexandria/book_providers/z3950.rb +170 -174
  42. data/lib/alexandria/config.rb +5 -3
  43. data/lib/alexandria/console.rb +10 -21
  44. data/lib/alexandria/default_preferences.rb +37 -0
  45. data/lib/alexandria/execution_queue.rb +17 -15
  46. data/lib/alexandria/export_format.rb +47 -0
  47. data/lib/alexandria/export_library.rb +188 -302
  48. data/lib/alexandria/import_library.rb +114 -155
  49. data/lib/alexandria/import_library_csv.rb +46 -96
  50. data/lib/alexandria/library_collection.rb +79 -0
  51. data/lib/alexandria/library_sort_order.rb +45 -0
  52. data/lib/alexandria/library_store.rb +233 -0
  53. data/lib/alexandria/logging.rb +15 -19
  54. data/lib/alexandria/models/book.rb +15 -20
  55. data/lib/alexandria/models/library.rb +81 -363
  56. data/lib/alexandria/net.rb +7 -6
  57. data/lib/alexandria/preferences.rb +73 -91
  58. data/lib/alexandria/scanners.rb +4 -2
  59. data/lib/alexandria/scanners/{cuecat.rb → cue_cat.rb} +24 -20
  60. data/lib/alexandria/scanners/keyboard.rb +10 -8
  61. data/lib/alexandria/smart_library.rb +135 -171
  62. data/lib/alexandria/ui.rb +17 -15
  63. data/lib/alexandria/ui/about_dialog.rb +49 -0
  64. data/lib/alexandria/ui/{dialogs/acquire_dialog.rb → acquire_dialog.rb} +129 -152
  65. data/lib/alexandria/ui/alert_dialog.rb +64 -0
  66. data/lib/alexandria/ui/bad_isbns_dialog.rb +41 -0
  67. data/lib/alexandria/ui/{dialogs/barcode_animation.rb → barcode_animation.rb} +18 -15
  68. data/lib/alexandria/ui/{dialogs/book_properties_dialog.rb → book_properties_dialog.rb} +44 -61
  69. data/lib/alexandria/ui/{dialogs/book_properties_dialog_base.rb → book_properties_dialog_base.rb} +84 -89
  70. data/lib/alexandria/ui/builder_base.rb +9 -27
  71. data/lib/alexandria/ui/callbacks.rb +188 -186
  72. data/lib/alexandria/ui/columns.rb +2 -0
  73. data/lib/alexandria/ui/completion_models.rb +12 -23
  74. data/lib/alexandria/ui/confirm_erase_dialog.rb +33 -0
  75. data/lib/alexandria/ui/conflict_while_copying_dialog.rb +34 -0
  76. data/lib/alexandria/ui/dndable.rb +10 -8
  77. data/lib/alexandria/ui/error_dialog.rb +25 -0
  78. data/lib/alexandria/ui/export_dialog.rb +139 -0
  79. data/lib/alexandria/ui/icons.rb +49 -65
  80. data/lib/alexandria/ui/iconview.rb +15 -13
  81. data/lib/alexandria/ui/iconview_tooltips.rb +43 -58
  82. data/lib/alexandria/ui/import_dialog.rb +157 -0
  83. data/lib/alexandria/ui/init.rb +23 -33
  84. data/lib/alexandria/ui/keep_bad_isbn_dialog.rb +36 -0
  85. data/lib/alexandria/ui/libraries_combo.rb +18 -14
  86. data/lib/alexandria/ui/listview.rb +77 -88
  87. data/lib/alexandria/ui/main_app.rb +26 -26
  88. data/lib/alexandria/ui/misc_dialogs.rb +10 -0
  89. data/lib/alexandria/ui/multi_drag_treeview.rb +30 -41
  90. data/lib/alexandria/ui/{dialogs/new_book_dialog.rb → new_book_dialog.rb} +168 -215
  91. data/lib/alexandria/ui/new_book_dialog_manual.rb +139 -0
  92. data/lib/alexandria/ui/new_provider_dialog.rb +100 -0
  93. data/lib/alexandria/ui/new_smart_library_dialog.rb +74 -0
  94. data/lib/alexandria/ui/preferences_dialog.rb +313 -0
  95. data/lib/alexandria/ui/provider_preferences_base_dialog.rb +95 -0
  96. data/lib/alexandria/ui/provider_preferences_dialog.rb +35 -0
  97. data/lib/alexandria/ui/really_delete_dialog.rb +53 -0
  98. data/lib/alexandria/ui/{sidepane.rb → sidepane_manager.rb} +62 -72
  99. data/lib/alexandria/ui/skip_entry_dialog.rb +33 -0
  100. data/lib/alexandria/ui/smart_library_properties_dialog.rb +60 -0
  101. data/lib/alexandria/ui/{dialogs/smart_library_properties_dialog_base.rb → smart_library_properties_dialog_base.rb} +96 -172
  102. data/lib/alexandria/ui/smart_library_rule_box.rb +119 -0
  103. data/lib/alexandria/ui/sound.rb +13 -13
  104. data/lib/alexandria/ui/ui_manager.rb +262 -283
  105. data/lib/alexandria/undo_manager.rb +3 -0
  106. data/lib/alexandria/version.rb +6 -19
  107. data/lib/alexandria/web_themes.rb +24 -21
  108. data/po/Makefile +2 -2
  109. data/po/cs.po +993 -880
  110. data/po/cy.po +957 -874
  111. data/po/de.po +990 -869
  112. data/po/el.po +989 -869
  113. data/po/es.po +985 -865
  114. data/po/fr.po +986 -870
  115. data/po/ga.po +907 -823
  116. data/po/gl.po +981 -865
  117. data/po/it.po +986 -868
  118. data/po/ja.po +969 -853
  119. data/po/mk.po +983 -863
  120. data/po/nb.po +979 -863
  121. data/po/nl.po +983 -864
  122. data/po/pl.po +1020 -969
  123. data/po/pt.po +988 -861
  124. data/po/pt_BR.po +984 -868
  125. data/po/ru.po +992 -873
  126. data/po/sk.po +987 -869
  127. data/po/sv.po +977 -861
  128. data/po/uk.po +975 -865
  129. data/po/zh_TW.po +976 -860
  130. data/schemas/alexandria.schemas +25 -3
  131. data/share/alexandria/glade/acquire_dialog__builder.glade +15 -12
  132. data/share/alexandria/glade/book_properties_dialog__builder.glade +171 -299
  133. data/share/alexandria/glade/main_app__builder.glade +24 -33
  134. data/share/alexandria/glade/new_book_dialog__builder.glade +27 -59
  135. data/share/alexandria/glade/preferences_dialog__builder.glade +250 -290
  136. data/share/gnome/help/alexandria/C/introduction.xml +0 -8
  137. data/share/gnome/help/alexandria/C/searching.xml +1 -1
  138. data/share/gnome/help/alexandria/C/smart-libraries.xml +2 -2
  139. data/share/gnome/help/alexandria/C/working-with-libraries.xml +1 -1
  140. data/share/gnome/help/alexandria/fr/alexandria.xml +1 -1
  141. data/share/gnome/help/alexandria/ja/introduction.xml +0 -8
  142. data/share/gnome/help/alexandria/ja/smart-libraries.xml +1 -1
  143. data/spec/alexandria/book_providers/world_cat_provider_spec.rb +160 -0
  144. data/spec/alexandria/book_providers_spec.rb +77 -210
  145. data/spec/alexandria/book_spec.rb +16 -12
  146. data/spec/alexandria/console_spec.rb +27 -0
  147. data/spec/alexandria/export_library_spec.rb +130 -0
  148. data/spec/alexandria/library_spec.rb +130 -172
  149. data/spec/alexandria/library_store_spec.rb +37 -0
  150. data/spec/alexandria/preferences_spec.rb +46 -17
  151. data/spec/alexandria/scanners/cue_cat_spec.rb +52 -0
  152. data/spec/alexandria/smart_library_spec.rb +32 -25
  153. data/spec/alexandria/ui/about_dialog_spec.rb +14 -0
  154. data/spec/alexandria/ui/acquire_dialog_spec.rb +14 -0
  155. data/spec/alexandria/ui/alert_dialog_spec.rb +16 -0
  156. data/spec/alexandria/ui/bad_isbns_dialog_spec.rb +14 -0
  157. data/spec/alexandria/ui/book_properties_dialog_spec.rb +17 -0
  158. data/spec/alexandria/ui/confirm_erase_dialog_spec.rb +14 -0
  159. data/spec/alexandria/ui/conflict_while_copying_dialog_spec.rb +16 -0
  160. data/spec/alexandria/ui/error_dialog_spec.rb +14 -0
  161. data/spec/alexandria/ui/export_dialog_spec.rb +15 -0
  162. data/spec/alexandria/ui/icons_spec.rb +26 -0
  163. data/spec/alexandria/ui/iconview_spec.rb +9 -21
  164. data/spec/alexandria/ui/import_dialog_spec.rb +41 -0
  165. data/spec/alexandria/ui/keep_bad_isbn_dialog_spec.rb +17 -0
  166. data/spec/alexandria/ui/main_app_spec.rb +8 -33
  167. data/spec/alexandria/ui/new_book_dialog_manual_spec.rb +15 -0
  168. data/spec/alexandria/ui/new_book_dialog_spec.rb +22 -0
  169. data/spec/alexandria/ui/new_provider_dialog_spec.rb +30 -0
  170. data/spec/alexandria/ui/new_smart_library_dialog_spec.rb +39 -0
  171. data/spec/alexandria/ui/preferences_dialog_spec.rb +14 -0
  172. data/spec/alexandria/ui/provider_preferences_dialog_spec.rb +34 -0
  173. data/spec/alexandria/ui/really_delete_dialog_spec.rb +16 -0
  174. data/spec/alexandria/ui/sidepane_manager_spec.rb +15 -0
  175. data/spec/alexandria/ui/skip_entry_dialog_spec.rb +14 -0
  176. data/spec/alexandria/ui/smart_library_properties_dialog_spec.rb +32 -0
  177. data/spec/alexandria/ui/sound_spec.rb +4 -2
  178. data/spec/alexandria/ui/ui_manager_spec.rb +45 -20
  179. data/spec/end_to_end/basic_run_spec.rb +57 -0
  180. data/spec/spec_helper.rb +66 -33
  181. data/tasks/setup.rb +5 -3
  182. data/tasks/spec.rake +18 -3
  183. data/util/rake/fileinstall.rb +38 -40
  184. data/util/rake/gettextgenerate.rb +15 -70
  185. data/util/rake/omfgenerate.rb +10 -10
  186. metadata +176 -60
  187. data/INSTALL.rdoc +0 -148
  188. data/dogtail/basic_run_test.py +0 -9
  189. data/lib/alexandria/book_providers/bol_it.rb +0 -160
  190. data/lib/alexandria/book_providers/deastore.rb +0 -273
  191. data/lib/alexandria/book_providers/ibs_it.rb +0 -147
  192. data/lib/alexandria/book_providers/mcu.rb +0 -169
  193. data/lib/alexandria/book_providers/renaud.rb +0 -140
  194. data/lib/alexandria/book_providers/webster_it.rb +0 -167
  195. data/lib/alexandria/ui/dialogs/about_dialog.rb +0 -59
  196. data/lib/alexandria/ui/dialogs/alert_dialog.rb +0 -70
  197. data/lib/alexandria/ui/dialogs/bad_isbns_dialog.rb +0 -43
  198. data/lib/alexandria/ui/dialogs/export_dialog.rb +0 -171
  199. data/lib/alexandria/ui/dialogs/import_dialog.rb +0 -196
  200. data/lib/alexandria/ui/dialogs/misc_dialogs.rb +0 -85
  201. data/lib/alexandria/ui/dialogs/new_book_dialog_manual.rb +0 -154
  202. data/lib/alexandria/ui/dialogs/new_smart_library_dialog.rb +0 -74
  203. data/lib/alexandria/ui/dialogs/preferences_dialog.rb +0 -578
  204. data/lib/alexandria/ui/dialogs/smart_library_properties_dialog.rb +0 -57
  205. data/spec/alexandria/scanners/cuecat_spec.rb +0 -65
  206. data/spec/alexandria/ui/dialogs_spec.rb +0 -94
  207. data/spec/alexandria/ui/sidepane_spec.rb +0 -27
  208. data/spec/alexandria/ui/ui_utilities_spec.rb +0 -60
  209. data/spec/alexandria/utilities_spec.rb +0 -50
  210. data/tasks/dogtail.rake +0 -4
@@ -1,60 +1,29 @@
1
- # Copyright (C) 2004-2006 Laurent Sansonetti
2
- # Copyright (C) 2011, 2015, 2016 Matijs van Zuijlen
3
- #
4
- # Alexandria is free software; you can redistribute it and/or
5
- # modify it under the terms of the GNU General Public License as
6
- # published by the Free Software Foundation; either version 2 of the
7
- # License, or (at your option) any later version.
8
- #
9
- # Alexandria is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # General Public License for more details.
1
+ # frozen_string_literal: true
2
+
3
+ # This file is part of Alexandria.
13
4
  #
14
- # You should have received a copy of the GNU General Public
15
- # License along with Alexandria; see the file COPYING. If not,
16
- # write to the Free Software Foundation, Inc., 51 Franklin Street,
17
- # Fifth Floor, Boston, MA 02110-1301 USA.
5
+ # See the file README.md for authorship and licensing information.
18
6
 
19
- require 'gdk_pixbuf2'
7
+ require "gdk_pixbuf2"
8
+ require "alexandria/ui/builder_base"
9
+ require "alexandria/ui/error_dialog"
10
+ require "alexandria/ui/keep_bad_isbn_dialog"
20
11
 
21
12
  module Alexandria
22
13
  class DuplicateBookException < NameError
23
14
  end
24
15
 
25
16
  module UI
26
- class KeepBadISBNDialog < AlertDialog
27
- include GetText
28
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
29
-
30
- def initialize(parent, book)
31
- super(parent, _("Invalid ISBN '%s'") % book.isbn,
32
- Gtk::Stock::DIALOG_QUESTION,
33
- [[Gtk::Stock::CANCEL, :cancel],
34
- [_('_Keep'), :ok]],
35
- _("The book titled '%s' has an invalid ISBN, but still " \
36
- 'exists in the providers libraries. Do you want to ' \
37
- 'keep the book but change the ISBN or cancel the addition?') % book.title)
38
- self.default_response = Gtk::ResponseType::OK
39
- show_all && (@response = run)
40
- destroy
41
- end
42
-
43
- def keep?
44
- @response == :ok
45
- end
46
- end
47
-
48
17
  class NewBookDialog < BuilderBase
49
18
  include Logging
50
19
  include GetText
51
20
  extend GetText
52
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
21
+ GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
53
22
  @@last_criterion_was_not_isbn = false
54
23
 
55
24
  def initialize(parent, selected_library = nil, &block)
56
- super('new_book_dialog__builder.glade', widget_names)
57
- log.info { 'New Book Dialog' }
25
+ super("new_book_dialog__builder.glade", widget_names)
26
+ log.info { "New Book Dialog" }
58
27
  @new_book_dialog.transient_for = @parent = parent
59
28
  @block = block
60
29
  @destroyed = false
@@ -63,34 +32,33 @@ module Alexandria
63
32
  @progressbar.hide
64
33
  end
65
34
 
35
+ def show
36
+ @new_book_dialog.show
37
+ end
38
+
66
39
  def widget_names
67
- [:liststore1, :liststore2, :new_book_dialog, :dialog_vbox1,
68
- :dialog_action_area1, :button_help, :button_cancel,
69
- :button_add, :table1, :keep_open, :combo_libraries,
70
- :cellrenderertext1, :eventbox_entry_isbn, :entry_isbn,
71
- :label3, :hbox2, :eventbox_combo_search, :combo_search,
72
- :cellrenderertext2, :eventbox_entry_search, :entry_search,
73
- :button_find, :scrolledwindow, :treeview_results,
74
- :title_radiobutton, :isbn_radiobutton, :progressbar]
40
+ [:new_book_dialog, :button_add, :button_cancel, :button_find,
41
+ :button_help, :combo_libraries, :combo_search, :entry_isbn,
42
+ :entry_search, :eventbox_combo_search, :eventbox_entry_isbn,
43
+ :eventbox_entry_search, :isbn_radiobutton, :keep_open, :progressbar,
44
+ :scrolledwindow, :title_radiobutton, :treeview_results]
75
45
  end
76
46
 
77
47
  def setup_dialog_gui
78
- libraries = Libraries.instance.all_regular_libraries
79
- if @selected_library.is_a?(SmartLibrary)
80
- @selected_library = libraries.first
81
- end
48
+ libraries = LibraryCollection.instance.all_regular_libraries
49
+ @selected_library = libraries.first if @selected_library.is_a?(SmartLibrary)
82
50
  @combo_libraries.populate_with_libraries(libraries,
83
51
  @selected_library)
84
52
 
85
53
  @treeview_results.model = Gtk::ListStore.new(String, String,
86
54
  GdkPixbuf::Pixbuf)
87
- @treeview_results.selection.mode = Gtk::SELECTION_MULTIPLE
88
- @treeview_results.selection.signal_connect('changed') do
55
+ @treeview_results.selection.mode = :multiple
56
+ @treeview_results.selection.signal_connect("changed") do
89
57
  @button_add.sensitive = true
90
58
  end
91
59
 
92
60
  renderer = Gtk::CellRendererPixbuf.new
93
- col = Gtk::TreeViewColumn.new('', renderer)
61
+ col = Gtk::TreeViewColumn.new("", renderer)
94
62
  col.set_cell_data_func(renderer) do |_column, cell, _model, iter|
95
63
  pixbuf = iter[2]
96
64
  max_height = 25
@@ -104,7 +72,7 @@ module Alexandria
104
72
  end
105
73
  @treeview_results.append_column(col)
106
74
 
107
- col = Gtk::TreeViewColumn.new('', Gtk::CellRendererText.new,
75
+ col = Gtk::TreeViewColumn.new("", Gtk::CellRendererText.new,
108
76
  text: 0)
109
77
  @treeview_results.append_column(col)
110
78
 
@@ -123,14 +91,14 @@ module Alexandria
123
91
  @find_thread = nil
124
92
  @image_thread = nil
125
93
 
126
- @new_book_dialog.signal_connect('destroy') {
94
+ @new_book_dialog.signal_connect("destroy") do
127
95
  @new_book_dialog.destroy
128
96
  @destroyed = true
129
- }
97
+ end
130
98
  end
131
99
 
132
100
  def on_criterion_toggled(item)
133
- log.debug { 'on_criterion_toggled' }
101
+ log.debug { "on_criterion_toggled" }
134
102
  return unless item.active?
135
103
 
136
104
  # There used to be a strange effect here (pre SVN r1022).
@@ -175,19 +143,19 @@ module Alexandria
175
143
 
176
144
  def on_changed(entry)
177
145
  ok = !entry.text.strip.empty?
178
- decode_cuecat?(@entry_isbn) if entry == @entry_isbn
146
+ decode_cuecat(@entry_isbn) if entry == @entry_isbn
179
147
  (entry == @entry_isbn ? @button_add : @button_find).sensitive = ok
180
148
  end
181
149
 
182
150
  def image_error_dialog(error)
183
151
  ErrorDialog.new(
184
152
  @parent,
185
- _('A problem occurred while downloading images'),
153
+ _("A problem occurred while downloading images"),
186
154
  error)
187
155
  end
188
156
 
189
157
  def get_images_async
190
- log.info { 'get_images_async' }
158
+ log.info { "get_images_async" }
191
159
  @images = {}
192
160
  @image_error = nil
193
161
  @image_thread = Thread.new do
@@ -197,7 +165,7 @@ module Alexandria
197
165
  uri = result[1]
198
166
  if uri
199
167
  if URI.parse(uri).scheme.nil?
200
- File.open(uri, 'r') do |io|
168
+ File.open(uri, "r") do |io|
201
169
  @images[i] = io.read
202
170
  end
203
171
  else
@@ -205,33 +173,32 @@ module Alexandria
205
173
  end
206
174
  end
207
175
  end
208
- rescue => e
209
- @image_error = e.message
176
+ rescue StandardError => ex
177
+ @image_error = ex.message
210
178
  end
211
179
  end
212
180
 
213
181
  GLib::Timeout.add(100) do
214
182
  if @image_error
215
- image_error_dialog(@image_error)
183
+ image_error_dialog(@image_error).display
216
184
  else
217
185
  @images.each_pair do |key, value|
218
- begin
219
- loader = GdkPixbuf::PixbufLoader.new
220
- loader.last_write(value)
221
- pixbuf = loader.pixbuf
222
-
223
- if pixbuf.width > 1
224
- iter = @treeview_results.model.get_iter(key.to_s)
225
- unless @treeview_results.model.iter_is_valid?(iter)
226
- raise 'Iter is invalid! %s' % iter
227
- end
228
- iter[2] = pixbuf # I bet you this is it!
186
+ loader = GdkPixbuf::PixbufLoader.new
187
+ loader.last_write(value)
188
+ pixbuf = loader.pixbuf
189
+
190
+ if pixbuf.width > 1
191
+ iter = @treeview_results.model.get_iter(key.to_s)
192
+ unless @treeview_results.model.iter_is_valid?(iter)
193
+ raise format(_("Iter is invalid! %s"), iter)
229
194
  end
230
195
 
231
- @images.delete(key)
232
- rescue => e
233
- image_error_dialog(e.message)
196
+ iter[2] = pixbuf # I bet you this is it!
234
197
  end
198
+
199
+ @images.delete(key)
200
+ rescue StandardError => ex
201
+ image_error_dialog(ex.message).display
235
202
  end
236
203
  end
237
204
 
@@ -247,7 +214,7 @@ module Alexandria
247
214
  end
248
215
 
249
216
  def on_find
250
- log.info { 'on_find' }
217
+ log.info { "on_find" }
251
218
  mode = case @combo_search.active
252
219
  when 0
253
220
  BookProviders::SEARCH_BY_TITLE
@@ -257,28 +224,19 @@ module Alexandria
257
224
  BookProviders::SEARCH_BY_KEYWORD
258
225
  end
259
226
 
260
- # @progressbar.show
261
- # progress_pulsing = GLib::Timeout.add(100) do
262
- # if @destroyed
263
- # false
264
- # else
265
- # @progressbar.pulse
266
- # true
267
- # end
268
- # end
269
-
270
227
  criterion = @entry_search.text.strip
271
228
  @treeview_results.model.clear
272
- log.info {
273
- 'TreeStore Model: %s columns; ref_counts: %s' %
274
- [@treeview_results.model.n_columns, @treeview_results.model.ref_count]
275
- }
229
+ log.info do
230
+ format("TreeStore Model: %s columns; ref_counts: %s",
231
+ @treeview_results.model.n_columns,
232
+ @treeview_results.model.ref_count)
233
+ end
276
234
 
277
235
  @find_error = nil
278
236
  @results = nil
279
237
 
280
- @find_thread.kill if @find_thread
281
- @image_thread.kill if @image_thread
238
+ @find_thread&.kill
239
+ @image_thread&.kill
282
240
 
283
241
  notify_start_add_by_isbn
284
242
  GLib::Idle.add do
@@ -289,8 +247,8 @@ module Alexandria
289
247
  @results = Alexandria::BookProviders.search(criterion, mode)
290
248
 
291
249
  log.info { "got #{@results.length} results" }
292
- rescue => e
293
- @find_error = e.message
250
+ rescue StandardError => ex
251
+ @find_error = ex.message
294
252
  ensure
295
253
  Alexandria::BookProviders.instance.delete_observer(self)
296
254
  # notify_end_add_by_isbn
@@ -305,28 +263,13 @@ module Alexandria
305
263
 
306
264
  # Err... continue == false if @find_error
307
265
  continue = if @find_error
308
- ErrorDialog.new(@parent,
309
- _('Unable to find matches for your search'),
310
- @find_error)
266
+ ErrorDialog.new(@new_book_dialog,
267
+ _("Unable to find matches for your search"),
268
+ @find_error).display
311
269
  false
312
270
  elsif @results
313
271
  log.info { "Got results: #{@results[0]}..." }
314
- @results.each do |book, _cover|
315
- s = _('%s, by %s') % [book.title,
316
- book.authors.join(', ')]
317
- similar_books = @results.find { |book2, _cover2|
318
- (book.title == book2.title) &&
319
- (book.authors == book2.authors)
320
- }
321
- if similar_books.length > 1
322
- s += " (#{book.edition}, #{book.publisher})"
323
- end
324
- log.info { 'Copying %s into tree view.' % book.title }
325
- iter = @treeview_results.model.append
326
- iter[0] = s
327
- iter[1] = book.ident
328
- iter[2] = Icons::BOOK
329
- end
272
+ copy_results_to_treeview_model(@results, @treeview_results.model)
330
273
 
331
274
  # Kick off the image download thread.
332
275
  if @find_thread.alive?
@@ -345,48 +288,55 @@ module Alexandria
345
288
  # continue == false if @find_error OR if results are returned
346
289
  # timeout ends if continue is false!
347
290
 
348
- unless continue
349
- unless @find_thread.alive? # This happens after find_thread is done
350
- unless @destroyed
351
- # GLib::Source.remove(progress_pulsing)
352
- # @progressbar.hide
353
- notify_end_add_by_isbn
354
- @button_add.sensitive = false
355
- end
356
- end
291
+ # @find_thread.alive? happens after find_thread is done
292
+ unless continue || @find_thread.alive? || @destroyed
293
+ notify_end_add_by_isbn
294
+ @button_add.sensitive = false
357
295
  end
358
296
 
359
297
  continue # timeout loop condition
360
298
  end
361
299
  end
362
300
 
363
- def decode_cuecat?(entry) # srsly?
364
- if entry.text =~ /^\..*?\..*?\.(.*?)\.$/
365
- tmp = Regexp.last_match[1].tr('a-zA-Z0-9+-', ' -_')
366
- tmp = ((32 + tmp.length * 3 / 4).to_i.chr << tmp).unpack('u')[0]
367
- tmp.chomp!("\000")
368
- entry.text = tmp.gsub!(/./) { |c| (c[0] ^ 67).chr }
369
- if entry.text.count('^ -~') > 0
370
- entry.text = 'Bad scan result'
301
+ def copy_results_to_treeview_model(results, model)
302
+ results.each do |book, _cover_url|
303
+ s = format(_("%s, by %s"), book.title, book.authors.join(", "))
304
+ similar_books = results.find do |book2, _cover2|
305
+ (book.title == book2.title) &&
306
+ (book.authors == book2.authors)
371
307
  end
308
+ s += " (#{book.edition}, #{book.publisher})" if similar_books.length > 1
309
+ log.info { format(_("Copying %s into tree view."), book.title) }
310
+ iter = model.append
311
+ iter[0] = s
312
+ iter[1] = book.ident
313
+ iter[2] = Icons::BOOK
372
314
  end
373
315
  end
374
316
 
317
+ def decode_cuecat(entry)
318
+ return unless entry.text =~ /^\..*?\..*?\.(.*?)\.$/
319
+
320
+ tmp = Regexp.last_match[1].tr("a-zA-Z0-9+-", " -_")
321
+ tmp = ((32 + tmp.length * 3 / 4).to_i.chr << tmp).unpack1("u")
322
+ tmp.chomp!("\000")
323
+ entry.text = tmp.gsub!(/./) { |c| (c[0] ^ 67).chr }
324
+ entry.text = "Bad scan result" if entry.text.count("^ -~") > 0
325
+ end
326
+
375
327
  def on_results_button_press_event(_widget, event)
376
328
  # double left click
377
- if (event.event_type == :'2button_press') && (event.button == 1)
378
- on_add
379
- end
329
+ on_add if (event.event_type == :'2button_press') && (event.button == 1)
380
330
  end
381
331
 
382
332
  def add_single_book_by_isbn(library, is_new)
383
333
  # Perform the ISBN search via the providers.
384
334
  isbn = begin
385
335
  Library.canonicalise_isbn(@entry_isbn.text)
386
- rescue
336
+ rescue StandardError
387
337
  raise _("Couldn't validate the EAN/ISBN you " \
388
- 'provided. Make sure it is written ' \
389
- 'correctly, and try again.')
338
+ "provided. Make sure it is written " \
339
+ "correctly, and try again.")
390
340
  end
391
341
  assert_not_exist(library, @entry_isbn.text)
392
342
  @button_add.sensitive = false
@@ -398,24 +348,20 @@ module Alexandria
398
348
  # MAJOR HACK, add this again...
399
349
  Alexandria::BookProviders.instance.add_observer(self)
400
350
  book, cover_url = Alexandria::BookProviders.isbn_search(isbn)
401
- # prov = FakeBookProviders.new()
402
- # prov.add_observer(self)
403
- # book, cover_url = prov.isbn_search(isbn)
404
351
 
405
352
  notify_end_add_by_isbn
406
353
 
407
354
  if book
408
-
409
- puts "adding book #{book} to library"
355
+ log.debug { "adding book #{book} to library" }
410
356
  add_book_to_library(library, book, cover_url)
411
- @entry_isbn.text = ''
357
+ @entry_isbn.text = ""
412
358
 
413
359
  post_addition([book], library, is_new)
414
360
  else
415
361
  post_addition([], library, is_new)
416
362
  end
417
- rescue Alexandria::BookProviders::NoResultsError => e
418
- @find_error = e.message
363
+ rescue Alexandria::BookProviders::NoResultsError => ex
364
+ @find_error = ex.message
419
365
  @button_add.sensitive = true
420
366
  notify_end_add_by_isbn
421
367
  ensure
@@ -430,22 +376,28 @@ module Alexandria
430
376
 
431
377
  def add_selected_books(library, _is_new)
432
378
  books_to_add = []
433
- @treeview_results.selection.selected_each do |_model, _path, iter|
379
+ @treeview_results.selection.each do |_model, _path, iter|
434
380
  @results.each do |book, cover|
435
381
  next unless book.ident == iter[1]
436
- begin
437
- next unless assert_not_exist(library, book.isbn)
438
- rescue Alexandria::Library::NoISBNError
439
- puts 'noisbn'
382
+
383
+ isbn = book.isbn
384
+ if isbn.nil? || isbn.empty?
385
+ log.debug { "noisbn" }
440
386
  book.isbn = book.saved_ident = nil
441
387
  books_to_add << [book, cover]
442
388
  next
443
- rescue Alexandria::Library::InvalidISBNError
444
- puts "invalidisbn #{book.isbn}"
445
- next unless
446
- KeepBadISBNDialog.new(@parent, book).keep?
389
+ end
390
+
391
+ isbn = Library.canonicalise_ean(isbn)
392
+ unless isbn
393
+ log.debug { "invalidisbn #{book.isbn}" }
394
+ next unless KeepBadISBNDialog.new(@new_book_dialog, book).keep?
395
+
447
396
  book.isbn = book.saved_ident = nil
448
397
  end
398
+
399
+ book.isbn = isbn
400
+ assert_not_exist(library, isbn)
449
401
  books_to_add << [book, cover]
450
402
  end
451
403
  end
@@ -456,15 +408,13 @@ module Alexandria
456
408
  end
457
409
 
458
410
  def add_book_to_library(library, book, cover_uri)
459
- unless cover_uri.nil?
460
- library.save_cover(book, cover_uri)
461
- end
411
+ library.save_cover(book, cover_uri) unless cover_uri.nil?
462
412
  library << book
463
413
  library.save(book)
464
414
  end
465
415
 
466
416
  def post_addition(books, library, is_new_library)
467
- puts "post_addition #{books.size}"
417
+ log.debug { "post_addition #{books.size}" }
468
418
  return if books.empty?
469
419
 
470
420
  # books, a 1d array of Alexandria::Book
@@ -478,7 +428,7 @@ module Alexandria
478
428
  @entry_search.grab_focus
479
429
  else
480
430
  @button_add.sensitive = true #
481
- @entry_isbn.text = '' # blank ISBN field
431
+ @entry_isbn.text = "" # blank ISBN field
482
432
  @entry_isbn.grab_focus
483
433
  end
484
434
 
@@ -491,11 +441,12 @@ module Alexandria
491
441
 
492
442
  def on_add
493
443
  return unless @button_add.sensitive?
494
- @find_thread.kill if @find_thread
495
- @image_thread.kill if @image_thread
444
+
445
+ @find_thread&.kill
446
+ @image_thread&.kill
496
447
 
497
448
  begin
498
- libraries = Libraries.instance.all_libraries
449
+ libraries = LibraryCollection.instance.all_libraries
499
450
  library, is_new_library =
500
451
  @combo_libraries.selection_from_libraries(libraries)
501
452
 
@@ -510,16 +461,16 @@ module Alexandria
510
461
 
511
462
  # Do not destroy if there is no addition.
512
463
  # return unless book_was_added
513
-
514
- rescue => e
515
- ErrorDialog.new(@parent, _("Couldn't add the book"), e.message)
464
+ rescue StandardError => ex
465
+ # FIXME: Message containing <> should be displayed correctly.
466
+ ErrorDialog.new(@new_book_dialog, _("Couldn't add the book"), ex.message).display
516
467
  end
517
468
  # books_to_add
518
469
  end
519
470
 
520
471
  def on_cancel
521
- @find_thread.kill if @find_thread
522
- @image_thread.kill if @image_thread
472
+ @find_thread&.kill
473
+ @image_thread&.kill
523
474
  @new_book_dialog.destroy
524
475
  end
525
476
 
@@ -538,10 +489,10 @@ module Alexandria
538
489
 
539
490
  def notify_end_add_by_isbn
540
491
  MainApp.instance.appbar.children.first.visible = false
541
- if @progress_pulsing
542
- GLib::Source.remove(@progress_pulsing)
543
- @progress_pulsing = nil
544
- end
492
+ return unless @progress_pulsing
493
+
494
+ GLib::Source.remove(@progress_pulsing)
495
+ @progress_pulsing = nil
545
496
  end
546
497
 
547
498
  def update(status, provider)
@@ -557,25 +508,26 @@ module Alexandria
557
508
  end
558
509
 
559
510
  def on_focus
560
- if @isbn_radiobutton.active? && @entry_isbn.text.strip.empty?
561
- clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD)
562
- if (text = clipboard.wait_for_text)
563
- if Library.valid_isbn?(text) || Library.valid_ean?(text) ||
564
- Library.valid_upc?(text)
565
- GLib::Idle.add do
566
- @entry_isbn.text = text
567
- @entry_isbn.grab_focus
568
- @entry_isbn.select_region(0, -1) # select all...
569
- # @button_add.grab_focus
570
- false
571
- end
572
- log.debug { "Setting ISBN field to #{text}" }
573
- puts text # required, strangely, to prevent GUI strangeness
574
- # above last checked with ruby-gnome2 0.17.1 2009-12-09
575
- # if this puts is commented out, the cursor disappears
576
- # from the @entry_isbn box... weird, ne? - CathalMagus
577
- end
511
+ return unless @isbn_radiobutton.active? && @entry_isbn.text.strip.empty?
512
+
513
+ clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD)
514
+ text = clipboard.wait_for_text or return
515
+
516
+ if Library.valid_isbn?(text) || Library.valid_ean?(text) ||
517
+ Library.valid_upc?(text)
518
+ GLib::Idle.add do
519
+ @entry_isbn.text = text
520
+ @entry_isbn.grab_focus
521
+ @entry_isbn.select_region(0, -1) # select all...
522
+ # @button_add.grab_focus
523
+ false
578
524
  end
525
+ log.debug { "Setting ISBN field to #{text}" }
526
+ # FIXME: Get rid of this puts!
527
+ puts text # required, strangely, to prevent GUI strangeness
528
+ # above last checked with ruby-gnome2 0.17.1 2009-12-09
529
+ # if this puts is commented out, the cursor disappears
530
+ # from the @entry_isbn box... weird, ne? - CathalMagus
579
531
  end
580
532
  end
581
533
 
@@ -583,19 +535,18 @@ module Alexandria
583
535
  if (event.event_type == :button_press) &&
584
536
  (event.button == 1)
585
537
 
586
- radio, target_widget, box2, box3 = case widget
587
- when @eventbox_entry_search
588
- [@title_radiobutton, @entry_search,
589
- @eventbox_combo_search, @eventbox_entry_isbn]
590
-
591
- when @eventbox_combo_search
592
- [@title_radiobutton, @combo_search,
593
- @eventbox_entry_search, @eventbox_entry_isbn]
594
-
595
- when @eventbox_entry_isbn
596
- [@isbn_radiobutton, @entry_isbn,
597
- @eventbox_entry_search, @eventbox_combo_search]
598
- end
538
+ radio, target_widget, box2, box3 =
539
+ case widget
540
+ when @eventbox_entry_search
541
+ [@title_radiobutton, @entry_search,
542
+ @eventbox_combo_search, @eventbox_entry_isbn]
543
+ when @eventbox_combo_search
544
+ [@title_radiobutton, @combo_search,
545
+ @eventbox_entry_search, @eventbox_entry_isbn]
546
+ when @eventbox_entry_isbn
547
+ [@isbn_radiobutton, @entry_isbn,
548
+ @eventbox_entry_search, @eventbox_combo_search]
549
+ end
599
550
  radio.active = true
600
551
  target_widget.grab_focus
601
552
  widget.above_child = false
@@ -604,7 +555,7 @@ module Alexandria
604
555
  end
605
556
 
606
557
  def on_help
607
- Alexandria::UI.display_help(@preferences_dialog, 'add-book-by-isbn')
558
+ Alexandria::UI.display_help(@preferences_dialog, "add-book-by-isbn")
608
559
  end
609
560
 
610
561
  private
@@ -612,12 +563,14 @@ module Alexandria
612
563
  def assert_not_exist(library, isbn)
613
564
  # Check that the book doesn't already exist in the library.
614
565
  isbn13 = Library.canonicalise_ean(isbn)
615
- puts isbn13
616
- if (book = library.find { |bk| bk.isbn == isbn13 })
617
- raise DuplicateBookException, _("'%s' already exists in '%s' (titled '%s').") % \
618
- [isbn, library.name, book.title.sub('&', '&amp;')]
619
- end
620
- true
566
+ return unless isbn13
567
+
568
+ book = library.find { |bk| bk.isbn == isbn13 }
569
+ return unless book
570
+
571
+ raise DuplicateBookException,
572
+ format(_("'%s' already exists in '%s' (titled '%s')."),
573
+ isbn, library.name, book.title.sub("&", "&amp;"))
621
574
  end
622
575
  end
623
576
  end