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
@@ -12,15 +12,16 @@ module Alexandria
12
12
  class NewBookDialogManual < BookPropertiesDialogBase
13
13
  include GetText
14
14
  extend GetText
15
+
15
16
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
16
17
 
17
- TMP_COVER_FILE = File.join(Dir.tmpdir, "tmp_cover")
18
18
  def initialize(parent, library, &on_add_cb)
19
- super(parent, TMP_COVER_FILE)
19
+ tmp_cover_file = File.join(Dir.mktmpdir("cover"), "tmp_cover")
20
+ super(parent, tmp_cover_file)
20
21
 
21
22
  @library = library
22
23
  @on_add_cb = on_add_cb
23
- FileUtils.rm_f(TMP_COVER_FILE)
24
+ FileUtils.rm_f(@cover_file)
24
25
 
25
26
  cancel_button = Gtk::Button.new(stock_id: Gtk::Stock::CANCEL)
26
27
  cancel_button.signal_connect("clicked") { on_cancel }
@@ -89,8 +90,7 @@ module Alexandria
89
90
  raise AddError, _("A binding must be provided.")
90
91
  end
91
92
 
92
- authors = []
93
- @treeview_authors.model.each { |_m, _p, i| authors << i[0] }
93
+ authors = @treeview_authors.model.map { |_m, _p, i| i[0] }
94
94
  if authors.empty?
95
95
  raise AddError, _("At least one author must be " \
96
96
  "provided.")
@@ -110,8 +110,8 @@ module Alexandria
110
110
  book.tags = @entry_tags.text.split
111
111
  @library << book
112
112
  @library.save(book)
113
- if File.exist?(TMP_COVER_FILE) && !@delete_cover_file
114
- FileUtils.cp(TMP_COVER_FILE, @library.cover(book))
113
+ if File.exist?(@cover_file) && !@delete_cover_file
114
+ FileUtils.cp(@cover_file, @library.cover(book))
115
115
  end
116
116
  @on_add_cb.call(book)
117
117
  @book_properties_dialog.destroy
@@ -10,6 +10,7 @@ module Alexandria
10
10
  module UI
11
11
  class NewProviderDialog < ProviderPreferencesBaseDialog
12
12
  include GetText
13
+
13
14
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
14
15
 
15
16
  def initialize(parent)
@@ -8,10 +8,11 @@ module Alexandria
8
8
  module UI
9
9
  class NewSmartLibraryDialog < SmartLibraryPropertiesDialogBase
10
10
  include GetText
11
+
11
12
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
12
13
 
13
14
  def initialize(parent)
14
- super(parent)
15
+ super
15
16
 
16
17
  dialog.add_buttons([Gtk::Stock::CANCEL, :cancel],
17
18
  [Gtk::Stock::NEW, :ok])
@@ -5,7 +5,7 @@
5
5
  # See the file README.md for authorship and licensing information.
6
6
 
7
7
  require "alexandria/scanners/cue_cat"
8
- require "alexandria/scanners/keyboard"
8
+ require "alexandria/scanners/keyboard_wedge"
9
9
  require "alexandria/ui/builder_base"
10
10
  require "alexandria/ui/provider_preferences_dialog"
11
11
  require "alexandria/ui/new_provider_dialog"
@@ -15,6 +15,7 @@ module Alexandria
15
15
  class PreferencesDialog < BuilderBase
16
16
  include Logging
17
17
  include GetText
18
+
18
19
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
19
20
 
20
21
  def initialize(parent, &changed_block)
@@ -301,9 +302,8 @@ module Alexandria
301
302
  end
302
303
 
303
304
  def update_priority
304
- priority = []
305
- @treeview_providers.model.each do |_model, _path, iter|
306
- priority << iter[1]
305
+ priority = @treeview_providers.model.map do |_model, _path, iter|
306
+ iter[1]
307
307
  end
308
308
  Preferences.instance.providers_priority = priority
309
309
  BookProviders.instance.update_priority
@@ -10,6 +10,7 @@ module Alexandria
10
10
  module UI
11
11
  class ProviderPreferencesDialog < ProviderPreferencesBaseDialog
12
12
  include GetText
13
+
13
14
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
14
15
 
15
16
  def initialize(parent, provider)
@@ -10,6 +10,7 @@ module Alexandria
10
10
  module UI
11
11
  class ReallyDeleteDialog < AlertDialog
12
12
  include GetText
13
+
13
14
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
14
15
 
15
16
  def initialize(parent, library, books = nil)
@@ -11,6 +11,7 @@ module Alexandria
11
11
  class SidepaneManager
12
12
  include Logging
13
13
  include GetText
14
+
14
15
  attr_accessor :library_listview
15
16
 
16
17
  def initialize(library_listview, parent)
@@ -50,7 +51,7 @@ module Alexandria
50
51
 
51
52
  if (match = contains_illegal_character(new_text))
52
53
  if match.instance_of? MatchData
53
- chars = match[1].gsub(/&/, "&amp;")
54
+ chars = match[1].gsub("&", "&amp;")
54
55
  ErrorDialog.new(@main_app, _("Invalid library name '%s'") % new_text,
55
56
  _("The name provided contains the " \
56
57
  "disallowed character <b>%s</b>") % chars).display
@@ -128,71 +129,71 @@ module Alexandria
128
129
 
129
130
  @library_listview
130
131
  .signal_connect("drag-motion") do |_widget, drag_context, x, y, time, _data|
131
- log.debug { "drag-motion" }
132
-
133
- path, column, =
134
- @library_listview.get_path_at_pos(x, y)
135
-
136
- if path
137
- # Refuse drags from/to smart libraries.
138
- if @parent.selected_library.is_a?(SmartLibrary)
139
- path = nil
140
- else
141
- iter = @library_listview.model.get_iter(path)
142
- if iter[3] # separator?
132
+ log.debug { "drag-motion" }
133
+
134
+ path, column, =
135
+ @library_listview.get_path_at_pos(x, y)
136
+
137
+ if path
138
+ # Refuse drags from/to smart libraries.
139
+ if @parent.selected_library.is_a?(SmartLibrary)
143
140
  path = nil
144
141
  else
145
- library = @libraries.all_libraries.find do |lib|
146
- lib.name == iter[1]
142
+ iter = @library_listview.model.get_iter(path)
143
+ if iter[3] # separator?
144
+ path = nil
145
+ else
146
+ library = @libraries.all_libraries.find do |lib|
147
+ lib.name == iter[1]
148
+ end
149
+ path = nil if library.is_a?(SmartLibrary)
147
150
  end
148
- path = nil if library.is_a?(SmartLibrary)
149
151
  end
150
152
  end
151
- end
152
153
 
153
- @library_listview.set_drag_dest_row(path, :into_or_after)
154
+ @library_listview.set_drag_dest_row(path, :into_or_after)
154
155
 
155
- Gdk.drag_status(drag_context,
156
- path ? drag_context.suggested_action : 0,
157
- time)
156
+ Gdk.drag_status(drag_context,
157
+ path ? drag_context.suggested_action : 0,
158
+ time)
158
159
  end
159
160
 
160
161
  @library_listview
161
162
  .signal_connect("drag-drop") do |widget, drag_context, _x, _y, time, _data|
162
- log.debug { "drag-drop" }
163
+ log.debug { "drag-drop" }
163
164
 
164
- widget.drag_get_data(drag_context,
165
- drag_context.targets.first,
166
- time)
167
- true
165
+ widget.drag_get_data(drag_context,
166
+ drag_context.targets.first,
167
+ time)
168
+ true
168
169
  end
169
170
 
170
171
  @library_listview
171
172
  .signal_connect("drag-data-received") do |_, drag_context, x, y, data, _, _|
172
- log.debug { "drag-data-received" }
173
-
174
- success = false
175
- # FIXME: Ruby-GNOME2 should make comparison work without needing to
176
- # call #name.
177
- if data.data_type.name == Gdk::Selection::TYPE_STRING.name
178
- success, path =
179
- @library_listview.get_dest_row_at_pos(x, y)
180
-
181
- if success
182
- iter = @library_listview.model.get_iter(path)
183
- library = @libraries.all_libraries.find do |lib|
184
- lib.name == iter[1]
173
+ log.debug { "drag-data-received" }
174
+
175
+ success = false
176
+ # FIXME: Ruby-GNOME2 should make comparison work without needing to
177
+ # call #name.
178
+ if data.data_type.name == Gdk::Selection::TYPE_STRING.name
179
+ success, path =
180
+ @library_listview.get_dest_row_at_pos(x, y)
181
+
182
+ if success
183
+ iter = @library_listview.model.get_iter(path)
184
+ library = @libraries.all_libraries.find do |lib|
185
+ lib.name == iter[1]
186
+ end
187
+ @parent.move_selected_books_to_library(library)
188
+ success = true
185
189
  end
186
- @parent.move_selected_books_to_library(library)
187
- success = true
188
190
  end
189
- end
190
- begin
191
- drag_context.finish(success: success, delete: false)
192
- rescue StandardError => ex
193
- log.error { "drag_context.finish failed: #{ex}" }
194
- raise
195
- end
191
+ begin
192
+ drag_context.finish(success: success, delete: false)
193
+ rescue StandardError => ex
194
+ log.error { "drag_context.finish failed: #{ex}" }
195
+ raise
196
+ end
196
197
  end
197
198
  end
198
199
  end
@@ -11,6 +11,7 @@ module Alexandria
11
11
  class SkipEntryDialog < AlertDialog
12
12
  include GetText
13
13
  include Logging
14
+
14
15
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
15
16
 
16
17
  def initialize(parent, message)
@@ -8,6 +8,7 @@ module Alexandria
8
8
  module UI
9
9
  class SmartLibraryPropertiesDialog < SmartLibraryPropertiesDialogBase
10
10
  include GetText
11
+
11
12
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
12
13
 
13
14
  def initialize(parent, smart_library)
@@ -13,6 +13,7 @@ module Alexandria
13
13
  include Logging
14
14
  include CalendarPopup
15
15
  include GetText
16
+
16
17
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
17
18
 
18
19
  attr_reader :predicate_operator_rule, :dialog
@@ -77,7 +78,7 @@ module Alexandria
77
78
  new_rule.value = nil
78
79
  end
79
80
 
80
- protected
81
+ private
81
82
 
82
83
  attr_reader :smart_library_rules
83
84
 
@@ -28,7 +28,10 @@ module Alexandria
28
28
  module UI
29
29
  ## Uses Ruby/GStreamer to play Ogg/Vorbis sound effects
30
30
  class SoundEffectsPlayer
31
+ include Logging
32
+
31
33
  def initialize
34
+ log.info { "Setting up SoundEffectsPlayer" }
32
35
  @sounds_dir = Alexandria::Config::SOUNDS_DIR
33
36
  @ogg_vorbis_pipeline = Gst::Pipeline.new
34
37
  set_up_pipeline