alexandria-book-collection-manager 0.7.7 → 0.7.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88a834cc5346bc0704749533797d91e6ff2a04c372e066fe9f91ca239baa63f1
4
- data.tar.gz: 4a68efa9e12431f6ea356325b4bcee4a702a7f1f49710860a399657866c158e6
3
+ metadata.gz: 86ff53adf7e1792c32534b149370ab80a99a24c8a363273a1ca3d3f83e2c73c0
4
+ data.tar.gz: 6a38d050f6cf13a9d86e0c387cdbe472442a02c33f74563f4902f4338deac228
5
5
  SHA512:
6
- metadata.gz: 213ed219cd387370ff664b32b108aff3e6655e07579962f436f013616e02e423ef17afb6ed6bc6f036d2c5de863a9b51f8c5d5de5e8f33b9a51a0dff6522da61
7
- data.tar.gz: c6440f573914defb43a7a9f451a4cf5e9091275039137c4dabd02d2290c72e87a17d35f62db08f7669d1a66f51ea53e5ef1b1e170cdd3beea237df1d3a1f5dd4
6
+ metadata.gz: fbd36ea7f9caaabff7979e3ab57471e27a6a1a5daa33ce140d4a8df590b07d91f4302267db64c601281f3513401e5726a1874dba622a4d9e72a361c7898c1284
7
+ data.tar.gz: 87c17e9d9bc4c4bd057a1013068d034a48ca38e3fcd5784a743a1c1d971671165df4347bcb2aa710dd4a636ecc3d1bfdbee1f0bfe7a4eb7fccd7d4fb8acddd77
@@ -21,7 +21,7 @@ Metrics/BlockNesting:
21
21
 
22
22
  # Configuration parameters: CountComments, CountAsOne.
23
23
  Metrics/ClassLength:
24
- Max: 990
24
+ Max: 997
25
25
 
26
26
  # Configuration parameters: IgnoredMethods.
27
27
  Metrics/CyclomaticComplexity:
@@ -125,7 +125,6 @@ Style/OptionalBooleanParameter:
125
125
  - 'lib/alexandria/book_providers.rb'
126
126
  - 'lib/alexandria/book_providers/barnes_and_noble.rb'
127
127
  - 'lib/alexandria/book_providers/siciliano.rb'
128
- - 'lib/alexandria/book_providers/thalia.rb'
129
128
  - 'lib/alexandria/book_providers/worldcat.rb'
130
129
  - 'lib/alexandria/console.rb'
131
130
  - 'lib/alexandria/execution_queue.rb'
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.8 / 2020-11-29
4
+
5
+ * Fix ThaliaProvider
6
+ * Avoid warnings for calendar popup
7
+ * Make Rename menu item work
8
+ * Fix crash when changing covers
9
+ * Make alerts show alert details if available
10
+
3
11
  ## 0.7.7 / 2020-11-15
4
12
 
5
13
  * Update Polish translation ([#88] by [Piotr Drąg][piotrdrag])
@@ -54,13 +54,13 @@ Gem::Specification.new do |s|
54
54
  s.add_runtime_dependency("psych", ["~> 3.2.0"])
55
55
  s.add_runtime_dependency("zoom", ["~> 0.5.0"])
56
56
 
57
- s.add_development_dependency("gnome_app_driver", ["~> 0.2.1"])
57
+ s.add_development_dependency("gnome_app_driver", "~> 0.3.0")
58
58
  s.add_development_dependency("minitest", ["~> 5.0"])
59
59
  s.add_development_dependency("rake", ["~> 13.0"])
60
60
  s.add_development_dependency("rspec", ["~> 3.0"])
61
61
  s.add_development_dependency("rubocop", "~> 0.93.1")
62
62
  s.add_development_dependency("rubocop-i18n", ["~> 2.0.2"])
63
- s.add_development_dependency("rubocop-performance", ["~> 1.8.0"])
63
+ s.add_development_dependency("rubocop-performance", "~> 1.9.0")
64
64
  s.add_development_dependency("rubocop-rspec", "~> 1.44.1")
65
65
  s.add_development_dependency("webmock", "~> 3.9")
66
66
 
@@ -299,7 +299,7 @@ module Alexandria
299
299
  require "alexandria/book_providers/barnes_and_noble"
300
300
  require "alexandria/book_providers/proxis"
301
301
  require "alexandria/book_providers/siciliano"
302
- require "alexandria/book_providers/thalia"
302
+ require "alexandria/book_providers/thalia_provider"
303
303
  require "alexandria/book_providers/worldcat"
304
304
 
305
305
  # Z39.50 based providers
@@ -1,27 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright (C) 2009 Cathal Mc Ginley
4
- # Copyright (C) 2014 Matijs van Zuijlen
3
+ # This file is part of Alexandria.
5
4
  #
6
- # Alexandria is free software; you can redistribute it and/or
7
- # modify it under the terms of the GNU General Public License as
8
- # published by the Free Software Foundation; either version 2 of the
9
- # License, or (at your option) any later version.
10
- #
11
- # Alexandria is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- # General Public License for more details.
15
- #
16
- # You should have received a copy of the GNU General Public
17
- # License along with Alexandria; see the file COPYING. If not,
18
- # write to the Free Software Foundation, Inc., 51 Franklin Street,
19
- # Fifth Floor, Boston, MA 02110-1301 USA.
5
+ # See the file README.md for authorship and licensing information.
20
6
 
21
7
  # http://de.wikipedia.org/wiki/Thalia_%28Buchhandel%29
22
8
  # Thalia.de bought the Austrian book trade chain Amadeus
23
9
 
24
- # New Tlalia provider, taken from Palatina MetaDataSource and modified
10
+ # New Thalia provider, taken from Palatina MetaDataSource and modified
25
11
  # for Alexandria. (21 Dec 2009)
26
12
 
27
13
  require "net/http"
@@ -33,7 +19,7 @@ module Alexandria
33
19
  class ThaliaProvider < WebsiteBasedProvider
34
20
  include Logging
35
21
 
36
- SITE = "http://www.thalia.de"
22
+ SITE = "https://www.thalia.de"
37
23
  BASE_SEARCH_URL = "#{SITE}/shop/bde_bu_hg_startseite/suche/?%s=%s" # type,term
38
24
 
39
25
  def initialize
@@ -80,40 +66,36 @@ module Alexandria
80
66
  def parse_search_result_data(html)
81
67
  doc = html_to_doc(html)
82
68
  book_search_results = []
83
- results_divs = doc / "div.articlePresentationSearchCH"
84
- results_divs.each do |div|
69
+
70
+ results_items = doc / "ul.weitere-formate li.format"
71
+
72
+ results_items.each do |item|
85
73
  result = {}
86
- title_link = div % "div.articleText/h2/a"
87
- result[:title] = title_link.inner_html
88
- result[:lookup_url] = title_link["href"]
74
+ item_link = item % "a"
75
+ result[:lookup_url] = "#{SITE}#{item_link['href']}"
89
76
  book_search_results << result
90
77
  end
91
78
  book_search_results
92
79
  end
93
80
 
94
81
  def data_from_label(node, label_text)
95
- label_node = node % "strong[text()*='#{label_text}']"
96
- if (item_node = label_node.parent)
97
- data = ""
98
- item_node.children.each do |n|
99
- data += n.to_html if n.text?
100
- end
101
- data.strip
102
- else
103
- ""
104
- end
82
+ label_node = node % "th[text()*='#{label_text}']"
83
+ return "" unless label_node
84
+
85
+ item_node = label_node.parent % "td"
86
+ item_node.inner_text.strip
105
87
  end
106
88
 
107
89
  def get_book_from_search_result(result)
108
90
  log.debug { "Fetching book from #{result[:lookup_url]}" }
109
91
  html_data = transport.get_response(URI.parse(result[:lookup_url]))
110
- parse_result_data(html_data.body, "noisbn", true)
92
+ parse_result_data(html_data.body, "noisbn", recursing: true)
111
93
  end
112
94
 
113
- def parse_result_data(html, isbn, recursing = false)
95
+ def parse_result_data(html, isbn, recursing: false)
114
96
  doc = html_to_doc(html)
115
97
 
116
- results_divs = doc / "div.articlePresentationSearchCH"
98
+ results_divs = doc / "ul.weitere-formate"
117
99
  unless results_divs.empty?
118
100
  if recursing
119
101
  # already recursing, avoid doing so endlessly second time
@@ -122,66 +104,48 @@ module Alexandria
122
104
  return
123
105
  end
124
106
 
125
- # ISBN-lookup results in multiple results (trying to be
126
- # useful, such as for new editions e.g. 9780974514055
127
- # "Programming Ruby" )
107
+ # ISBN-lookup results in multiple results
128
108
  results = parse_search_result_data(html)
129
- isbn10 = Library.canonicalise_isbn(isbn)
130
- # e.g. .../dave_thomas/ISBN0-9745140-5-5/ID6017044.html
131
109
  chosen = results.first # fallback!
132
- results.each do |rslt|
133
- if rslt[:lookup_url] =~ %r{/ISBN(\d+[\d-]*)/} &&
134
- (Regexp.last_match[1].delete("-") == isbn10)
135
- chosen = rslt
136
- break
137
- end
138
- end
139
110
  html_data = transport.get_response(URI.parse(chosen[:lookup_url]))
140
- return parse_result_data(html_data.body, isbn, true)
111
+ return parse_result_data(html_data.body, isbn, recursing: true)
141
112
  end
142
113
 
143
114
  begin
144
- if (div = doc % "div#contentFull")
145
- title_img = ((div % :h2) / :img).first
146
- title = title_img["alt"]
147
-
148
- # note, the following img also has alt="von Author, Author..."
115
+ if (div = doc % "section#sbe-product-details")
116
+ title = div["data-titel"]
149
117
 
150
- if (author_h = doc % 'h3[text()*="Mehr von"]') # "More from..." links
118
+ if (author_p = doc % "p.aim-author")
151
119
  authors = []
152
- author_links = author_h.parent / :a
120
+ author_links = author_p / :a
153
121
  author_links.each do |a|
154
- if a["href"].include? "BUCH/sa"
155
- # 'sa' means search author, there may also be 'ssw' (search keyword) links
156
- authors << a.inner_text[0..-2].strip
157
- # NOTE stripping the little >> character here...
158
- end
122
+ authors << a.inner_text.strip
159
123
  end
160
124
  end
161
125
 
162
- item_details = doc % "ul.itemDataList"
126
+ item_details = doc % "section.artikeldetails"
163
127
  isbns = []
164
128
  isbns << data_from_label(item_details, "EAN")
165
129
  isbns << data_from_label(item_details, "ISBN")
130
+ isbns.reject!(&:empty?)
166
131
 
167
132
  year = nil
168
- date = data_from_label(item_details, "Erschienen:")
133
+ date = data_from_label(item_details, "Erscheinungsdatum")
169
134
  year = Regexp.last_match[1].to_i if date =~ /(\d{4})/
170
135
 
171
- binding = data_from_label(item_details, "Einband")
136
+ book_binding = data_from_label(item_details, "Einband")
172
137
 
173
- publisher = data_from_label(item_details, "Erschienen bei:")
138
+ publisher = data_from_label(item_details, "Verlag")
174
139
 
175
140
  book = Book.new(title, authors, isbns.first,
176
- publisher, year, binding)
141
+ publisher, year, book_binding)
177
142
 
178
143
  image_url = nil
179
- if (image_link = doc % "a[@id=itemPicStart]")
180
- image_url = image_link["href"]
144
+ if (image = doc % "section.imagesPreview img")
145
+ image_url = image["src"]
181
146
  end
182
147
 
183
148
  [book, image_url]
184
-
185
149
  end
186
150
  rescue StandardError => ex
187
151
  trace = ex.backtrace.join("\n> ")
@@ -31,7 +31,7 @@ module Alexandria
31
31
  return super(severity, message, progname, &block) if source.nil?
32
32
 
33
33
  category = self.class.category(source)
34
- return super(severity, progname, category) unless block_given?
34
+ return super(severity, progname, category) unless block
35
35
 
36
36
  category = "#{category} #{progname}" if progname
37
37
  super(severity, message, category, &block)
@@ -4,6 +4,8 @@
4
4
  #
5
5
  # See the file README.md for authorship and licensing information.
6
6
 
7
+ require "cgi"
8
+
7
9
  module Alexandria
8
10
  module UI
9
11
  class AlertDialog
@@ -26,7 +28,7 @@ module Alexandria
26
28
  vbox = Gtk::Box.new(:vertical, 6)
27
29
  vbox.homogeneous = false
28
30
  vbox.pack_start make_label("<b><big>#{title}</big></b>")
29
- vbox.pack_start make_label(message.strip) unless message
31
+ vbox.pack_start make_label CGI.escapeHTML(message.strip) if message
30
32
  hbox.pack_start(vbox)
31
33
 
32
34
  @dialog.child.pack_start(hbox)
@@ -9,7 +9,6 @@ require "alexandria/ui/error_dialog"
9
9
  module Alexandria
10
10
  module UI
11
11
  class BookPropertiesDialog < BookPropertiesDialogBase
12
- include Logging
13
12
  include GetText
14
13
  extend GetText
15
14
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
@@ -12,6 +12,7 @@ module Alexandria
12
12
  module UI
13
13
  class BookPropertiesDialogBase < BuilderBase
14
14
  include CalendarPopup
15
+ include Logging
15
16
  include GetText
16
17
  extend GetText
17
18
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
@@ -156,14 +157,12 @@ module Alexandria
156
157
 
157
158
  @@latest_filechooser_directory = ENV["HOME"]
158
159
  def on_change_cover
159
- backend = `uname`.chomp == "FreeBSD" ? "neant" : "gnome-vfs"
160
- dialog = Gtk::FileChooserDialog.new(_("Select a cover image"),
161
- @book_properties_dialog,
162
- Gtk::FileChooser::ACTION_OPEN,
163
- backend,
164
- [_("No Cover"), Gtk::ResponseType::REJECT],
165
- [Gtk::Stock::CANCEL, Gtk::ResponseType::CANCEL],
166
- [Gtk::Stock::OPEN, Gtk::ResponseType::ACCEPT])
160
+ dialog = Gtk::FileChooserDialog.new(title: _("Select a cover image"),
161
+ parent: @book_properties_dialog,
162
+ action: :open,
163
+ buttons: [[_("No Cover"), :reject],
164
+ [Gtk::Stock::CANCEL, :cancel],
165
+ [Gtk::Stock::OPEN, :accept]])
167
166
  dialog.current_folder = @@latest_filechooser_directory
168
167
  response = dialog.run
169
168
  case response
@@ -201,9 +201,9 @@ module Alexandria
201
201
 
202
202
  def on_rename(*)
203
203
  iter = @library_listview.selection.selected
204
- @library_listview.set_cursor(iter.path,
205
- @library_listview.get_column(0),
206
- true)
204
+ column = @library_listview.get_column(0)
205
+ cell = column.cells.last
206
+ @library_listview.set_cursor_on_cell(iter.path, column, cell, true)
207
207
  end
208
208
 
209
209
  def on_delete(*)
@@ -24,28 +24,29 @@ class Gtk::ActionGroup
24
24
  end
25
25
  end
26
26
 
27
- class Gtk::IconView
28
- def freeze
29
- @old_model = model
30
- self.model = nil
27
+ module Alexandria::UI::FreezeThaw
28
+ def frozen?
29
+ @old_model && !model
31
30
  end
32
31
 
33
- def unfreeze
34
- self.model = @old_model
35
- end
36
- end
37
-
38
- class Gtk::TreeView
39
32
  def freeze
33
+ return if frozen?
34
+
40
35
  @old_model = model
41
36
  self.model = nil
42
37
  end
43
38
 
44
39
  def unfreeze
40
+ return unless frozen?
41
+
45
42
  self.model = @old_model
43
+ @old_model = nil
46
44
  end
47
45
  end
48
46
 
47
+ Gtk::IconView.include Alexandria::UI::FreezeThaw
48
+ Gtk::TreeView.include Alexandria::UI::FreezeThaw
49
+
49
50
  class Alexandria::Library
50
51
  def action_name
51
52
  "MoveIn" + name.gsub(/\s/, "")
@@ -108,7 +108,9 @@ module Alexandria
108
108
  cell.editable = iter[2]
109
109
  # log.debug { "exit sidepane: editable #{cell}, #{iter}" }
110
110
  end
111
- renderer.signal_connect("edited", &method(:on_edited_library))
111
+ renderer.signal_connect("edited") do |cell, path_string, new_text|
112
+ on_edited_library(cell, path_string, new_text)
113
+ end
112
114
  @library_listview.append_column(column)
113
115
 
114
116
  @library_listview.set_row_separator_func do |model, iter|
@@ -123,7 +123,9 @@ module Alexandria
123
123
 
124
124
  def setup_toolbar_filter_entry
125
125
  @filter_entry = Gtk::Entry.new
126
- @filter_entry.signal_connect("changed", &method(:on_toolbar_filter_entry_changed))
126
+ @filter_entry.signal_connect("changed") do |entry|
127
+ on_toolbar_filter_entry_changed(entry)
128
+ end
127
129
  @toolitem = Gtk::ToolItem.new
128
130
  @toolitem.expand = true
129
131
  @toolitem.border_width = 5
@@ -149,7 +151,7 @@ module Alexandria
149
151
  cb.append_text(item)
150
152
  end
151
153
  cb.active = 0
152
- cb.signal_connect("changed", &method(:on_criterion_combobox_changed))
154
+ cb.signal_connect("changed") { |combo| on_criterion_combobox_changed(combo) }
153
155
 
154
156
  # Put the combo box in a event box because it is not currently
155
157
  # possible assign a tooltip to a combo box.
@@ -167,8 +169,9 @@ module Alexandria
167
169
  @toolbar_view_as.append_text(_("View as Icons"))
168
170
  @toolbar_view_as.append_text(_("View as List"))
169
171
  @toolbar_view_as.active = 0
170
- @toolbar_view_as_signal_hid = \
171
- @toolbar_view_as.signal_connect("changed", &method(:on_toolbar_view_as_changed))
172
+ @toolbar_view_as_signal_hid = @toolbar_view_as.signal_connect("changed") do |combo|
173
+ on_toolbar_view_as_changed(combo)
174
+ end
172
175
 
173
176
  # Put the combo box in a event box because it is not currently
174
177
  # possible assign a tooltip to a combo box.
@@ -226,8 +229,12 @@ module Alexandria
226
229
 
227
230
  def setup_window_events
228
231
  log.debug { "setup_window_events" }
229
- @main_app.signal_connect("window-state-event", &method(:on_window_state_event))
230
- @main_app.signal_connect("destroy", &method(:on_window_destroy))
232
+ @main_app.signal_connect("window-state-event") do |window, event|
233
+ on_window_state_event(window, event)
234
+ end
235
+ @main_app.signal_connect("destroy") do |window|
236
+ on_window_destroy(window)
237
+ end
231
238
  end
232
239
 
233
240
  def setup_active_model
@@ -343,7 +350,7 @@ module Alexandria
343
350
  sensitize_library selected_library if library_already_selected
344
351
 
345
352
  GLib::Idle.add do
346
- menu.popup(nil, nil, event.button, event.time)
353
+ menu.popup_at_pointer(event)
347
354
  false
348
355
  end
349
356
 
@@ -391,7 +398,7 @@ module Alexandria
391
398
  end
392
399
 
393
400
  menu = selected_books.empty? ? @nobook_popup : @book_popup
394
- menu.popup(nil, nil, event.button, event.time)
401
+ menu.popup_at_pointer(event)
395
402
  end
396
403
 
397
404
  def get_library_selection_text(library)
@@ -5,7 +5,7 @@
5
5
  # See the file README.md for authorship and licensing information.
6
6
 
7
7
  module Alexandria
8
- VERSION = "0.7.7"
8
+ VERSION = "0.7.8"
9
9
  DATA_VERSION = "0.6.3"
10
- DISPLAY_VERSION = "0.7.7"
10
+ DISPLAY_VERSION = VERSION
11
11
  end
@@ -0,0 +1,119 @@
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
+ require "spec_helper"
8
+
9
+ RSpec.describe Alexandria::BookProviders::ThaliaProvider do
10
+ let(:normal_people_main) do
11
+ +<<~HTML
12
+ <!DOCTYPE html>
13
+ <html lang="de" data-environment="prod">
14
+ <head>
15
+ <title>Artikel von 0571334652 ansehen | Thalia</title>
16
+ </head>
17
+ <body data-mandant="2" data-version="20201112100740_528b0df" data-environment="prod">
18
+ <main class="suche-grid--main nur-suchergebnis">
19
+ <section class="suchergebnis">
20
+ <ul class="suchergebnis-liste no-bullets">
21
+ <li class="suchergebnis" data-seite="1"
22
+ data-ean="9780571334650"
23
+ data-id="134292338"
24
+ data-preis="9.49"
25
+ data-preis-reduziert="false"
26
+ data-alterpreis="">
27
+ <a href="/shop/home/artikeldetails/ID134292338.html" class="layered-link">Normal People von Sally Rooney</a>
28
+
29
+ <ul class="weitere-formate no-bullets" impression="product-variant">
30
+ <li class="format aktiv">
31
+ <a href="/shop/home/artikeldetails/ID134292338.html">Buch (Taschenbuch)</a>
32
+ </li>
33
+ <li class="format">
34
+ <a href="/shop/home/artikeldetails/ID95227195.html">Weitere: Buch (Taschenbuch)</a>
35
+ </li>
36
+ </ul>
37
+ </li>
38
+ </ul>
39
+ </section>
40
+ </main>
41
+ </body>
42
+ </html>
43
+ HTML
44
+ end
45
+ let(:normal_people_details) do
46
+ +<<~HTML
47
+ <!DOCTYPE html>
48
+ <html class="no-js" id="ID-2" lang="de">
49
+ <head>
50
+ <title>Normal People von Sally Rooney - Taschenbuch - 978-0-571-33465-0 | Thalia</title>
51
+ </head>
52
+ <body>
53
+ <section class="artikel-medien imagesPreview">
54
+ <img src="https://assets.thalia.media/img/artikel/ae9934c90f2c7d595146807ea6253c99532043ec-00-00.jpeg" class='largeImg'>
55
+ </section>
56
+
57
+ <section class="artikel-infos" id="sbe-product-details"
58
+ data-shopid="2"
59
+ data-id="A1051452169"
60
+ data-id-alt="134292338"
61
+ data-titel="Normal People"
62
+ data-verfuegbarkeit="Sofort lieferbar"
63
+ data-preis-netto="9.02"
64
+ data-preis-brutto="9.49"
65
+ data-ean="9780571334650"
66
+ data-reduziert="false"
67
+ data-waehrung="EUR"
68
+ data-preis-liste="9.49"
69
+ data-hersteller="Faber &amp; Faber"
70
+ data-form="Taschenbuch"
71
+ data-verkaufsrang="5"
72
+ data-anzahlbewertungen="19"
73
+ data-durchschnittsbewertung="4.5"
74
+ data-preisbindung="false"
75
+ data-mandant="2"
76
+ data-environment="prod"
77
+ component="artikeldetails-produktdetails">
78
+
79
+ <h1 class="ncTitle">
80
+ Normal People
81
+ </h1>
82
+
83
+ <p class="aim-author">
84
+ <a href="https://www.thalia.de/shop/home/mehr-von-suche/ANY/sp/suche.html?mehrVon=Sally%20Rooney" interaction="autor-klick">Sally Rooney</a>
85
+ </p>
86
+ </section>
87
+
88
+ <section class="artikeldetails">
89
+ <table>
90
+ <tr> <th> Einband </th> <td> Taschenbuch </td> </tr>
91
+ <tr> <th> Erscheinungsdatum </th> <td> 02.05.2019 </td> </tr>
92
+ <tr> <th> ISBN </th> <td> 978-0-571-33465-0 </td> </tr>
93
+ </table>
94
+ <table>
95
+ <tr>
96
+ <th> Verlag </th>
97
+ <td>
98
+ <a href="https://www.thalia.de/shop/home/mehr-von-suche/ANY/sv/suche.html?mehrVon=Faber%20%26%20Faber" interaction="auswahl">
99
+ Faber &amp; Faber
100
+ </a>
101
+ </td>
102
+ </tr>
103
+ </table>
104
+ </section>
105
+ </body>
106
+ </html>
107
+ HTML
108
+ end
109
+
110
+ it "works when searching by ISBN" do
111
+ stub_request(:get,
112
+ "https://www.thalia.de/shop/bde_bu_hg_startseite/suche/?sq=0571334652")
113
+ .to_return(status: 200, body: normal_people_main, headers: {})
114
+ stub_request(:get, "https://www.thalia.de/shop/home/artikeldetails/ID134292338.html")
115
+ .to_return(status: 200, body: normal_people_details, headers: {})
116
+
117
+ assert_correct_search_result(described_class, "9780571334650")
118
+ end
119
+ end
@@ -76,23 +76,6 @@ describe Alexandria::BookProviders do
76
76
  end
77
77
  end
78
78
 
79
- describe Alexandria::BookProviders::ThaliaProvider do
80
- before do
81
- skip "Needs fixing"
82
- end
83
-
84
- it "works" do
85
- # german book
86
- assert_correct_search_result(described_class, "9783896673305")
87
- # international book
88
- assert_correct_search_result(described_class, "9780440241904")
89
- # movie dvd
90
- assert_correct_search_result(described_class, "4010232037824")
91
- # music cd
92
- assert_correct_search_result(described_class, "0094638203520")
93
- end
94
- end
95
-
96
79
  describe Alexandria::BookProviders::AdLibrisProvider do
97
80
  it "works" do
98
81
  skip "Needs fixing: site has changed"
@@ -7,11 +7,53 @@
7
7
  require_relative "../../spec_helper"
8
8
 
9
9
  describe Alexandria::UI::BookPropertiesDialog do
10
+ let(:parent) { Gtk::Window.new :toplevel }
11
+ let(:library) do
12
+ store = Alexandria::LibraryCollection.instance.library_store
13
+ store.load_library("Bar Library")
14
+ end
15
+ let(:book) do
16
+ Alexandria::Book.new("Foo Book", ["Jane Doe"], "98765432", "Bar Publisher",
17
+ 1972, "edition")
18
+ end
19
+
20
+ before do
21
+ library << book
22
+ end
23
+
10
24
  it "works" do
11
- parent = Gtk::Window.new :toplevel
12
- library = instance_double(Alexandria::Library, name: "Bar Library", cover: "")
13
- book = Alexandria::Book.new("Foo Book", ["Jane Doe"], "98765432", "Bar Publisher",
14
- 1972, "edition")
15
25
  described_class.new parent, library, book
16
26
  end
27
+
28
+ describe "#on_change_cover" do
29
+ let(:dialog) { described_class.new parent, library, book }
30
+ let(:filechooser) { instance_double(Gtk::FileChooserDialog).as_null_object }
31
+
32
+ before do
33
+ allow(Gtk::FileChooserDialog).to receive(:new).and_return(filechooser)
34
+ allow(filechooser).to receive(:filename)
35
+ .and_return File.join(__dir__, "../../fixtures/cover.jpg")
36
+ end
37
+
38
+ it "works when response is accept" do
39
+ allow(filechooser)
40
+ .to receive(:run).and_return(Gtk::ResponseType::ACCEPT)
41
+
42
+ dialog.on_change_cover
43
+ end
44
+
45
+ it "works when response is reject" do
46
+ allow(filechooser)
47
+ .to receive(:run).and_return(Gtk::ResponseType::REJECT)
48
+
49
+ dialog.on_change_cover
50
+ end
51
+
52
+ it "works when response is cancel" do
53
+ allow(filechooser)
54
+ .to receive(:run).and_return(Gtk::ResponseType::CANCEL)
55
+
56
+ dialog.on_change_cover
57
+ end
58
+ end
17
59
  end
@@ -7,9 +7,45 @@
7
7
  require_relative "../../spec_helper"
8
8
 
9
9
  describe Alexandria::UI::NewBookDialogManual do
10
+ let(:parent) { Gtk::Window.new :toplevel }
11
+ let(:library) do
12
+ store = Alexandria::LibraryCollection.instance.library_store
13
+ store.load_library("Bar Library")
14
+ end
15
+
10
16
  it "works" do
11
- parent = Gtk::Window.new :toplevel
12
- library = instance_double(Alexandria::Library)
13
17
  described_class.new parent, library
14
18
  end
19
+
20
+ describe "#on_change_cover" do
21
+ let(:dialog) { described_class.new parent, library }
22
+ let(:filechooser) { instance_double(Gtk::FileChooserDialog).as_null_object }
23
+
24
+ before do
25
+ allow(Gtk::FileChooserDialog).to receive(:new).and_return(filechooser)
26
+ allow(filechooser).to receive(:filename)
27
+ .and_return File.join(__dir__, "../../fixtures/cover.jpg")
28
+ end
29
+
30
+ it "works when response is accept" do
31
+ allow(filechooser)
32
+ .to receive(:run).and_return(Gtk::ResponseType::ACCEPT)
33
+
34
+ dialog.on_change_cover
35
+ end
36
+
37
+ it "works when response is reject" do
38
+ allow(filechooser)
39
+ .to receive(:run).and_return(Gtk::ResponseType::REJECT)
40
+
41
+ dialog.on_change_cover
42
+ end
43
+
44
+ it "works when response is cancel" do
45
+ allow(filechooser)
46
+ .to receive(:run).and_return(Gtk::ResponseType::CANCEL)
47
+
48
+ dialog.on_change_cover
49
+ end
50
+ end
15
51
  end
@@ -39,6 +39,7 @@ describe Alexandria::UI::UIManager do
39
39
  # FIXME: This is needed because right now UIManager#refresh_books doesn't
40
40
  # work without Gtk loop.
41
41
  regular_library.each { |book| ui.append_book book }
42
+ # This makes the iconview model re-appear
42
43
  ui.iconview.unfreeze
43
44
  expect(ui.model.iter_n_children).to eq regular_library.count
44
45
 
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alexandria-book-collection-manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 0.7.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander McCormmach
@@ -25,10 +25,10 @@ authors:
25
25
  - Takayuki Kusano
26
26
  - Timothy Malone
27
27
  - Zachary P. Landau
28
- autorequire:
28
+ autorequire:
29
29
  bindir: bin
30
30
  cert_chain: []
31
- date: 2020-11-15 00:00:00.000000000 Z
31
+ date: 2020-11-29 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: gettext
@@ -162,14 +162,14 @@ dependencies:
162
162
  requirements:
163
163
  - - "~>"
164
164
  - !ruby/object:Gem::Version
165
- version: 0.2.1
165
+ version: 0.3.0
166
166
  type: :development
167
167
  prerelease: false
168
168
  version_requirements: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
- version: 0.2.1
172
+ version: 0.3.0
173
173
  - !ruby/object:Gem::Dependency
174
174
  name: minitest
175
175
  requirement: !ruby/object:Gem::Requirement
@@ -246,14 +246,14 @@ dependencies:
246
246
  requirements:
247
247
  - - "~>"
248
248
  - !ruby/object:Gem::Version
249
- version: 1.8.0
249
+ version: 1.9.0
250
250
  type: :development
251
251
  prerelease: false
252
252
  version_requirements: !ruby/object:Gem::Requirement
253
253
  requirements:
254
254
  - - "~>"
255
255
  - !ruby/object:Gem::Version
256
- version: 1.8.0
256
+ version: 1.9.0
257
257
  - !ruby/object:Gem::Dependency
258
258
  name: rubocop-rspec
259
259
  requirement: !ruby/object:Gem::Requirement
@@ -282,7 +282,7 @@ dependencies:
282
282
  - - "~>"
283
283
  - !ruby/object:Gem::Version
284
284
  version: '3.9'
285
- description:
285
+ description:
286
286
  email:
287
287
  - matijs@matijs.net
288
288
  executables:
@@ -331,7 +331,7 @@ files:
331
331
  - lib/alexandria/book_providers/proxis.rb
332
332
  - lib/alexandria/book_providers/pseudomarc.rb
333
333
  - lib/alexandria/book_providers/siciliano.rb
334
- - lib/alexandria/book_providers/thalia.rb
334
+ - lib/alexandria/book_providers/thalia_provider.rb
335
335
  - lib/alexandria/book_providers/web.rb
336
336
  - lib/alexandria/book_providers/worldcat.rb
337
337
  - lib/alexandria/book_providers/z3950.rb
@@ -555,6 +555,7 @@ files:
555
555
  - share/sounds/alexandria/good_scan.wav
556
556
  - share/sounds/alexandria/scanning.ogg
557
557
  - share/sounds/alexandria/scanning.wav
558
+ - spec/alexandria/book_providers/thalia_provider_spec.rb
558
559
  - spec/alexandria/book_providers/world_cat_provider_spec.rb
559
560
  - spec/alexandria/book_providers_spec.rb
560
561
  - spec/alexandria/book_spec.rb
@@ -609,6 +610,7 @@ files:
609
610
  - spec/data/libraries/0.6.2/My Library/9780755322800.cover
610
611
  - spec/data/libraries/0.6.2/My Library/9780755322800.yaml
611
612
  - spec/end_to_end/basic_run_spec.rb
613
+ - spec/fixtures/cover.jpg
612
614
  - spec/spec_helper.rb
613
615
  - tasks/setup.rb
614
616
  - tasks/spec.rake
@@ -619,7 +621,7 @@ homepage: http://www.github.com/mvz/alexandria-book-collection-manager
619
621
  licenses:
620
622
  - GPL-2
621
623
  metadata: {}
622
- post_install_message:
624
+ post_install_message:
623
625
  rdoc_options:
624
626
  - "--main"
625
627
  - README.md
@@ -636,8 +638,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
636
638
  - !ruby/object:Gem::Version
637
639
  version: '0'
638
640
  requirements: []
639
- rubygems_version: 3.1.2
640
- signing_key:
641
+ rubygems_version: 3.1.4
642
+ signing_key:
641
643
  specification_version: 4
642
644
  summary: GNOME application for managing collections of books
643
645
  test_files: []