alexandria-book-collection-manager 0.6.9.pre1 → 0.6.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -4
- data/.rubocop_todo.yml +21 -79
- data/CHANGELOG.md +9 -1
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/alexandria-book-collection-manager.gemspec +26 -4
- data/bin/alexandria +1 -1
- data/doc/AUTHORS +2 -1
- data/lib/alexandria.rb +1 -1
- data/lib/alexandria/about.rb +6 -6
- data/lib/alexandria/book_providers.rb +1 -1
- data/lib/alexandria/book_providers/adlibris.rb +4 -4
- data/lib/alexandria/book_providers/barnes_and_noble.rb +9 -5
- data/lib/alexandria/book_providers/bol_it.rb +0 -2
- data/lib/alexandria/book_providers/ibs_it.rb +0 -2
- data/lib/alexandria/book_providers/mcu.rb +3 -5
- data/lib/alexandria/book_providers/proxis.rb +1 -5
- data/lib/alexandria/book_providers/renaud.rb +0 -2
- data/lib/alexandria/book_providers/thalia.rb +10 -8
- data/lib/alexandria/book_providers/webster_it.rb +0 -2
- data/lib/alexandria/book_providers/worldcat.rb +8 -4
- data/lib/alexandria/book_providers/z3950.rb +2 -8
- data/lib/alexandria/execution_queue.rb +1 -3
- data/lib/alexandria/export_library.rb +2 -7
- data/lib/alexandria/import_library.rb +1 -6
- data/lib/alexandria/logging.rb +1 -1
- data/lib/alexandria/models/book.rb +2 -2
- data/lib/alexandria/models/library.rb +5 -7
- data/lib/alexandria/preferences.rb +1 -1
- data/lib/alexandria/scanners.rb +4 -3
- data/lib/alexandria/scanners/cuecat.rb +1 -1
- data/lib/alexandria/smart_library.rb +4 -3
- data/lib/alexandria/ui/callbacks.rb +2 -2
- data/lib/alexandria/ui/completion_models.rb +22 -19
- data/lib/alexandria/ui/dialogs/acquire_dialog.rb +2 -4
- data/lib/alexandria/ui/dialogs/barcode_animation.rb +1 -1
- data/lib/alexandria/ui/dialogs/book_properties_dialog.rb +1 -3
- data/lib/alexandria/ui/dialogs/book_properties_dialog_base.rb +0 -4
- data/lib/alexandria/ui/dialogs/export_dialog.rb +1 -3
- data/lib/alexandria/ui/dialogs/import_dialog.rb +4 -4
- data/lib/alexandria/ui/dialogs/new_book_dialog.rb +8 -11
- data/lib/alexandria/ui/dialogs/new_book_dialog_manual.rb +4 -5
- data/lib/alexandria/ui/dialogs/new_smart_library_dialog.rb +15 -9
- data/lib/alexandria/ui/dialogs/preferences_dialog.rb +20 -23
- data/lib/alexandria/ui/dialogs/smart_library_properties_dialog_base.rb +10 -14
- data/lib/alexandria/ui/dndable.rb +0 -1
- data/lib/alexandria/ui/gtk_thread_help.rb +2 -1
- data/lib/alexandria/ui/icons.rb +3 -3
- data/lib/alexandria/ui/iconview_tooltips.rb +9 -5
- data/lib/alexandria/ui/init.rb +6 -6
- data/lib/alexandria/ui/listview.rb +4 -4
- data/lib/alexandria/ui/main_app.rb +1 -1
- data/lib/alexandria/ui/multi_drag_treeview.rb +3 -5
- data/lib/alexandria/ui/sidepane.rb +26 -10
- data/lib/alexandria/ui/ui_manager.rb +5 -9
- data/lib/alexandria/undo_manager.rb +0 -2
- data/lib/alexandria/version.rb +3 -3
- data/lib/alexandria/web_themes.rb +1 -3
- data/{test/providers_test.rb → spec/alexandria/book_providers_spec.rb} +17 -15
- data/{test/book_test.rb → spec/alexandria/book_spec.rb} +4 -4
- data/spec/alexandria/library_spec.rb +189 -141
- data/spec/alexandria/scanners/cuecat_spec.rb +0 -2
- data/spec/alexandria/ui/main_app_spec.rb +13 -8
- data/spec/alexandria/ui/sidepane_spec.rb +1 -1
- data/spec/alexandria/ui/ui_utilities_spec.rb +1 -1
- data/{test → spec}/data/isbns.txt +0 -0
- data/tasks/spec.rake +2 -0
- data/util/rake/fileinstall.rb +1 -1
- metadata +32 -16
- data/tasks/test.rake +0 -38
- data/test/application_test.rb +0 -39
- data/test/isbn_test.rb +0 -68
- data/test/test_helper.rb +0 -42
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (C) 2007 Joseph Method
|
2
|
-
#
|
2
|
+
# Copyright (C) 2011, 2015 Matijs van Zuijlen
|
3
3
|
#
|
4
4
|
# Alexandria is free software; you can redistribute it and/or
|
5
5
|
# modify it under the terms of the GNU General Public License as
|
@@ -16,7 +16,7 @@
|
|
16
16
|
# write to the Free Software Foundation, Inc., 51 Franklin Street,
|
17
17
|
# Fifth Floor, Boston, MA 02110-1301 USA.
|
18
18
|
|
19
|
-
require
|
19
|
+
require 'spec_helper'
|
20
20
|
|
21
21
|
describe Alexandria::Book do
|
22
22
|
it 'should be a thing' do
|
@@ -26,9 +26,9 @@ describe Alexandria::Book do
|
|
26
26
|
it 'should establish equality only with books with the same identity' do
|
27
27
|
book = an_artist_of_the_floating_world
|
28
28
|
same_book = an_artist_of_the_floating_world
|
29
|
-
same_book.
|
29
|
+
expect(same_book).to eq book
|
30
30
|
different_book = an_artist_of_the_floating_world
|
31
31
|
different_book.isbn = '9780571147999'
|
32
|
-
different_book.
|
32
|
+
expect(different_book).not_to eq book
|
33
33
|
end
|
34
34
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#-- -*- ruby -*-
|
2
|
+
# Copyright (C) 2004-2006 Dafydd Harries
|
2
3
|
# Copyright (C) 2007 Cathal Mc Ginley
|
3
|
-
# Copyright (C) 2014 Matijs van Zuijlen
|
4
|
+
# Copyright (C) 2011, 2014, 2015 Matijs van Zuijlen
|
4
5
|
#
|
5
6
|
# Alexandria is free software; you can redistribute it and/or
|
6
7
|
# modify it under the terms of the GNU General Public License as
|
@@ -16,190 +17,237 @@
|
|
16
17
|
# License along with Alexandria; see the file COPYING. If not,
|
17
18
|
# write to the Free Software Foundation, Inc., 51 Franklin Street,
|
18
19
|
# Fifth Floor, Boston, MA 02110-1301 USA.
|
19
|
-
|
20
|
+
|
21
|
+
require 'spec_helper'
|
20
22
|
|
21
23
|
describe Alexandria::Library do
|
24
|
+
describe '::EXT' do
|
25
|
+
it 'has symbolic references to file extensions' do
|
26
|
+
extensions = Alexandria::Library::EXT
|
27
|
+
expect(extensions[:book]).not_to be_nil
|
28
|
+
expect(extensions[:cover]).not_to be_nil
|
29
|
+
end
|
30
|
+
end
|
22
31
|
|
23
|
-
|
24
|
-
|
32
|
+
describe '#valid_isbn?' do
|
33
|
+
it 'returns a true value for valid isbns' do
|
34
|
+
for x in ['014143984X', '0-345-43192-8']
|
35
|
+
expect(Alexandria::Library.valid_isbn?(x)).to be_truthy
|
36
|
+
end
|
37
|
+
end
|
25
38
|
end
|
26
39
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
40
|
+
describe '#valid_ean?' do
|
41
|
+
it 'returns a true value for valid EANs' do
|
42
|
+
expect(Alexandria::Library.valid_ean?('9780345431929')).to be_truthy
|
43
|
+
|
44
|
+
# Regression test: this EAN has a checksum of 10, which should be
|
45
|
+
# treated like a checksum of 0.
|
46
|
+
expect(Alexandria::Library.valid_ean?('9784047041790')).to be_truthy
|
47
|
+
end
|
31
48
|
end
|
32
49
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
50
|
+
describe '#canonicalise_isbn' do
|
51
|
+
it 'returns the correct value for several examples' do
|
52
|
+
expect(Alexandria::Library.canonicalise_isbn('014143984X')).to eq '014143984X'
|
53
|
+
expect(Alexandria::Library.canonicalise_isbn('0-345-43192-8')).to eq '0345431928'
|
54
|
+
expect(Alexandria::Library.canonicalise_isbn('3522105907')).to eq '3522105907'
|
55
|
+
# EAN number
|
56
|
+
expect(Alexandria::Library.canonicalise_isbn('9780345431929')).to eq '0345431928'
|
57
|
+
end
|
39
58
|
end
|
40
59
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
my_library << first_copy
|
46
|
-
my_library.delete(first_copy)
|
60
|
+
context 'with an empty library' do
|
61
|
+
before(:each) do
|
62
|
+
FileUtils.mkdir(TESTDIR) unless File.exist? TESTDIR
|
63
|
+
end
|
47
64
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
65
|
+
it 'disallows multiple deletion of the same copy of a book' do
|
66
|
+
my_library = Alexandria::Library.loadall[0]
|
67
|
+
first_copy = an_artist_of_the_floating_world
|
68
|
+
my_library << first_copy
|
69
|
+
my_library.delete(first_copy)
|
70
|
+
expect { my_library.delete(first_copy) }.to raise_error
|
71
|
+
end
|
52
72
|
|
53
|
-
|
73
|
+
it 'allows multiple copies of a book to be added and deleted in turn' do
|
74
|
+
my_library = Alexandria::Library.loadall[0]
|
75
|
+
first_copy = an_artist_of_the_floating_world
|
76
|
+
# puts "first_copy #{first_copy.object_id}"
|
77
|
+
my_library << first_copy
|
78
|
+
my_library.delete(first_copy)
|
54
79
|
|
55
|
-
|
56
|
-
|
57
|
-
|
80
|
+
second_copy = an_artist_of_the_floating_world
|
81
|
+
my_library << second_copy
|
82
|
+
third_copy = an_artist_of_the_floating_world
|
83
|
+
my_library << third_copy
|
58
84
|
|
59
|
-
|
60
|
-
# my_library.size.should == 1 # not yet an established feature...
|
61
|
-
end
|
85
|
+
# puts "AAA my_library.size #{my_library.size}"
|
62
86
|
|
63
|
-
|
64
|
-
|
65
|
-
|
87
|
+
# puts "second_copy #{second_copy.object_id}"
|
88
|
+
# lambda { my_library.delete(second_copy) }.should raise_error
|
89
|
+
expect { my_library.delete(second_copy) }.not_to raise_error
|
66
90
|
|
67
|
-
|
68
|
-
|
69
|
-
|
91
|
+
# puts "BBB my_library.size #{my_library.size}"
|
92
|
+
# my_library.size.should == 1 # not yet an established feature...
|
93
|
+
end
|
70
94
|
|
71
|
-
|
72
|
-
|
73
|
-
|
95
|
+
after(:each) do
|
96
|
+
FileUtils.rm_rf(TESTDIR)
|
97
|
+
end
|
74
98
|
end
|
75
99
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
# Guide to LaTeX
|
88
|
-
latex_book = my_library.select { |b| b.title.include? 'Latex' }[0]
|
89
|
-
expect(latex_book.isbn).to eq('9780201398250')
|
90
|
-
expect(latex_book.publisher).to eq('Addison Wesley') # note, no Ruby-Amazon cruft
|
91
|
-
end
|
100
|
+
describe '.import_as_isbn_list' do
|
101
|
+
before :all do
|
102
|
+
require 'alexandria/import_library'
|
103
|
+
end
|
104
|
+
|
105
|
+
def __test_fake_import_isbns
|
106
|
+
libraries = Alexandria::Libraries.instance
|
107
|
+
library = Alexandria::Library.new('Test Library')
|
108
|
+
libraries.add_library(library)
|
109
|
+
[library, libraries]
|
110
|
+
end
|
92
111
|
|
93
|
-
|
94
|
-
|
112
|
+
it "doesn't work quite yet" do
|
113
|
+
skip
|
114
|
+
# Doesn't work quite yet.
|
115
|
+
on_iterate_cb = proc { }
|
116
|
+
on_error_cb = proc { }
|
117
|
+
library, libraries = __test_fake_import_isbns
|
118
|
+
test_file = "data/isbns.txt"
|
119
|
+
library.import_as_isbn_list("Test Library", test_file, on_iterate_cb, on_error_cb)
|
120
|
+
end
|
95
121
|
end
|
96
122
|
|
97
|
-
|
123
|
+
context 'imported from 0.6.1 data files' do
|
124
|
+
before(:each) do
|
125
|
+
lib_version = File.join(LIBDIR, '0.6.1')
|
126
|
+
FileUtils.cp_r(lib_version, TESTDIR)
|
127
|
+
end
|
98
128
|
|
99
|
-
|
129
|
+
it 'imports cleanly from version 0.6.1 data format' do
|
130
|
+
libs = Alexandria::Library.loadall
|
131
|
+
expect(libs.size).to eq(1)
|
132
|
+
my_library = libs[0]
|
133
|
+
expect(my_library.size).to eq(3)
|
134
|
+
# Malory
|
135
|
+
malory_book = my_library.select { |b| b.isbn == '9780192812179' }[0]
|
136
|
+
expect(malory_book.publisher).to eq('Oxford University Press')
|
137
|
+
expect(malory_book.authors.include?('Vinaver')).to be_truthy
|
138
|
+
expect(malory_book.version).to eq(Alexandria::DATA_VERSION)
|
139
|
+
|
140
|
+
# Guide to LaTeX
|
141
|
+
latex_book = my_library.select { |b| b.title.include? 'Latex' }[0]
|
142
|
+
expect(latex_book.isbn).to eq('9780201398250')
|
143
|
+
expect(latex_book.publisher).to eq('Addison Wesley') # note, no Ruby-Amazon cruft
|
144
|
+
end
|
100
145
|
|
101
|
-
|
102
|
-
|
103
|
-
|
146
|
+
after(:each) do
|
147
|
+
FileUtils.rm_rf(TESTDIR)
|
148
|
+
end
|
104
149
|
end
|
105
150
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
151
|
+
context 'imported from 0.6.1 with books without an ISBN' do
|
152
|
+
before(:each) do
|
153
|
+
lib_version = File.join(LIBDIR, '0.6.1-noisbn')
|
154
|
+
FileUtils.cp_r(lib_version, TESTDIR)
|
155
|
+
end
|
111
156
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
157
|
+
it 'allows books to have no ISBN' do
|
158
|
+
libs = Alexandria::Library.loadall
|
159
|
+
expect(libs.size).to eq(1)
|
160
|
+
my_library = libs[0]
|
161
|
+
expect(my_library.size).to eq(2)
|
117
162
|
|
118
|
-
|
119
|
-
|
120
|
-
|
163
|
+
# Guide to LaTeX
|
164
|
+
latex_book = my_library.select { |b| b.title.include? 'Latex' }[0]
|
165
|
+
expect(latex_book.isbn).to eq('9780201398250')
|
166
|
+
expect(latex_book.publisher).to eq('Addison Wesley') # note, no Ruby-Amazon cruft
|
167
|
+
expect(latex_book.version).to eq(Alexandria::DATA_VERSION)
|
121
168
|
|
122
|
-
|
169
|
+
# Lex and Yacc
|
170
|
+
lex_and_yacc_book = my_library.select { |b| b.title.include? 'Lex' }[0]
|
171
|
+
expect(lex_and_yacc_book.publisher).to eq("O'Reilley")
|
123
172
|
|
124
|
-
|
125
|
-
my_library.save(book, true)
|
126
|
-
end
|
173
|
+
# puts "ident -> " + lex_and_yacc_book.ident
|
127
174
|
|
128
|
-
|
129
|
-
|
175
|
+
my_library.each do |book|
|
176
|
+
my_library.save(book, true)
|
177
|
+
end
|
130
178
|
|
131
|
-
|
179
|
+
libraries_reloaded = Alexandria::Library.loadall
|
180
|
+
my_library_reloaded = libraries_reloaded[0]
|
132
181
|
|
133
|
-
|
134
|
-
expect(latex_book).not_to be_nil
|
135
|
-
expect(latex_book.publisher).to eq('Addison Wesley')
|
136
|
-
# puts latex_book.title
|
182
|
+
expect(my_library_reloaded.size).to eq(2)
|
137
183
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
184
|
+
latex_book = my_library_reloaded.select { |b| b.title.include? 'Latex' }[0]
|
185
|
+
expect(latex_book).not_to be_nil
|
186
|
+
expect(latex_book.publisher).to eq('Addison Wesley')
|
187
|
+
# puts latex_book.title
|
142
188
|
|
143
|
-
|
189
|
+
lex_and_yacc_book = my_library_reloaded.select { |b| b.title.include? 'Lex' }[0]
|
190
|
+
expect(lex_and_yacc_book).not_to be_nil
|
191
|
+
expect(lex_and_yacc_book.publisher).to eq("O'Reilley")
|
192
|
+
# puts lex_and_yacc_book.title
|
193
|
+
end
|
144
194
|
|
145
|
-
|
146
|
-
|
195
|
+
after(:each) do
|
196
|
+
FileUtils.rm_rf(TESTDIR)
|
197
|
+
end
|
147
198
|
end
|
148
199
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
require 'tmpdir'
|
155
|
-
require 'csv'
|
156
|
-
end
|
200
|
+
context 'when exporting' do
|
201
|
+
before(:all) do
|
202
|
+
require 'tmpdir'
|
203
|
+
require 'csv'
|
204
|
+
end
|
157
205
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
206
|
+
before(:each) do
|
207
|
+
lib_version = File.join(LIBDIR, '0.6.2')
|
208
|
+
FileUtils.cp_r(lib_version, TESTDIR)
|
209
|
+
@format = Alexandria::ExportFormat.new('CSV list', 'csv', :export_as_csv_list)
|
210
|
+
@outfile = File.join(Dir.tmpdir, 'my_library-0.6.2.csv')
|
211
|
+
@my_library = Alexandria::Library.loadall[0]
|
212
|
+
end
|
165
213
|
|
166
|
-
|
167
|
-
|
168
|
-
|
214
|
+
def load_rows_from_csv
|
215
|
+
CSV.read(@outfile, col_sep: ';')
|
216
|
+
end
|
169
217
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
218
|
+
it 'can sort by title' do
|
219
|
+
sort_by_title = Alexandria::LibrarySortOrder.new(:title)
|
220
|
+
@format.invoke(@my_library, sort_by_title, @outfile)
|
221
|
+
expect(File.exist?(@outfile)).to be_truthy
|
222
|
+
rows = load_rows_from_csv
|
223
|
+
rows.shift
|
224
|
+
expect(rows.size).to eq(@my_library.size)
|
225
|
+
TITLE = 0
|
226
|
+
comparisons = rows.size - 1
|
227
|
+
comparisons.times do |index|
|
228
|
+
expect(rows[index][TITLE]).to be <= rows[index + 1][TITLE]
|
229
|
+
end
|
181
230
|
end
|
182
|
-
end
|
183
231
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
232
|
+
it 'can sort in descending order' do
|
233
|
+
sort_by_date_desc = Alexandria::LibrarySortOrder.new(:publishing_year, false)
|
234
|
+
@format.invoke(@my_library, sort_by_date_desc, @outfile)
|
235
|
+
expect(File.exist?(@outfile)).to be_truthy
|
236
|
+
rows = load_rows_from_csv
|
237
|
+
rows.shift
|
238
|
+
expect(rows.size).to eq(@my_library.size)
|
239
|
+
DATE = 5
|
240
|
+
comparisons = rows.size - 1
|
241
|
+
comparisons.times do |index|
|
242
|
+
expect(rows[index][DATE]).to be >= rows[index + 1][DATE]
|
243
|
+
end
|
195
244
|
end
|
196
|
-
end
|
197
245
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
246
|
+
after(:each) do
|
247
|
+
FileUtils.rm_rf(TESTDIR)
|
248
|
+
if File.exist? @outfile
|
249
|
+
File.unlink @outfile
|
250
|
+
end
|
202
251
|
end
|
203
252
|
end
|
204
|
-
|
205
253
|
end
|
@@ -22,7 +22,6 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../../lib'))
|
|
22
22
|
require 'alexandria/scanners/cuecat'
|
23
23
|
|
24
24
|
describe Alexandria::Scanners::CueCat do
|
25
|
-
|
26
25
|
before :all do
|
27
26
|
@cuecat = Alexandria::Scanners::CueCat.new
|
28
27
|
@partials = ['.',
|
@@ -64,5 +63,4 @@ describe Alexandria::Scanners::CueCat do
|
|
64
63
|
it 'should decode UPC barcodes' do
|
65
64
|
skip 'Test scan UPC'
|
66
65
|
end
|
67
|
-
|
68
66
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# Copyright (C) 2007 Joseph Method
|
2
|
-
# Copyright (C)
|
2
|
+
# Copyright (C) 2007 Cathal Mc Ginley
|
3
|
+
# Copyright (C) 2011, 2014, 2015 Matijs van Zuijlen
|
3
4
|
#
|
4
5
|
# Alexandria is free software; you can redistribute it and/or
|
5
6
|
# modify it under the terms of the GNU General Public License as
|
@@ -33,16 +34,20 @@ describe Gtk::IconView do
|
|
33
34
|
end
|
34
35
|
|
35
36
|
describe Alexandria::UI::MainApp do
|
36
|
-
before do
|
37
|
-
allow(Alexandria::UI::UIManager).to receive(:new).
|
38
|
-
and_return(double(Alexandria::UI::UIManager,
|
39
|
-
actiongroup: double(Object), appbar: nil,
|
40
|
-
prefs: nil))
|
41
|
-
end
|
42
37
|
it 'should be a singleton' do
|
43
38
|
expect do
|
44
39
|
Alexandria::UI::MainApp.new
|
45
40
|
end.to raise_error
|
46
|
-
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'runs' do
|
44
|
+
@main_app = Alexandria::UI::MainApp.instance
|
45
|
+
|
46
|
+
Gtk.timeout_add(100) do
|
47
|
+
@main_app.main_app.destroy
|
48
|
+
Gtk.main_quit
|
49
|
+
end
|
50
|
+
|
51
|
+
Gtk.main
|
47
52
|
end
|
48
53
|
end
|