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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +5 -1
- data/.github/workflows/ruby.yml +36 -22
- data/.rubocop.yml +12 -3
- data/.rubocop_todo.yml +35 -47
- data/.simplecov +2 -2
- data/CHANGELOG.md +71 -24
- data/Gemfile +0 -6
- data/Rakefile +5 -5
- data/alexandria-book-collection-manager.gemspec +24 -21
- data/bin/rake +28 -0
- data/bin/rspec +28 -0
- data/doc/dependency_decisions.yml +32 -26
- data/{bin → exe}/alexandria +1 -3
- data/lib/alexandria/about.rb +1 -0
- data/lib/alexandria/book_providers/bl_provider.rb +4 -6
- data/lib/alexandria/book_providers/{douban.rb → douban_provider.rb} +1 -1
- data/lib/alexandria/book_providers/loc_provider.rb +2 -6
- data/lib/alexandria/book_providers/sbn_provider.rb +2 -12
- data/lib/alexandria/book_providers/thalia_provider.rb +5 -6
- data/lib/alexandria/book_providers/{web.rb → website_based_provider.rb} +20 -1
- data/lib/alexandria/book_providers/{worldcat.rb → world_cat_provider.rb} +3 -4
- data/lib/alexandria/book_providers/z3950_provider.rb +25 -27
- data/lib/alexandria/book_providers.rb +14 -10
- data/lib/alexandria/config.rb +2 -2
- data/lib/alexandria/console.rb +12 -10
- data/lib/alexandria/export_format.rb +3 -2
- data/lib/alexandria/export_library.rb +35 -40
- data/lib/alexandria/import_library.rb +3 -4
- data/lib/alexandria/import_library_csv.rb +2 -2
- data/lib/alexandria/library_collection.rb +1 -1
- data/lib/alexandria/library_store.rb +20 -15
- data/lib/alexandria/logging.rb +22 -21
- data/lib/alexandria/models/book.rb +1 -2
- data/lib/alexandria/models/library.rb +7 -8
- data/lib/alexandria/preferences.rb +7 -19
- data/lib/alexandria/{book_providers/pseudomarc.rb → pseudo_marc_parser.rb} +2 -2
- data/lib/alexandria/scanners/cue_cat.rb +5 -9
- data/lib/alexandria/scanners/{keyboard.rb → keyboard_wedge.rb} +3 -3
- data/lib/alexandria/scanners.rb +2 -2
- data/lib/alexandria/smart_library.rb +9 -5
- data/lib/alexandria/ui/acquire_dialog.rb +42 -45
- data/lib/alexandria/ui/alert_dialog.rb +3 -3
- data/lib/alexandria/ui/barcode_animation.rb +3 -3
- data/lib/alexandria/ui/book_properties_dialog.rb +9 -9
- data/lib/alexandria/ui/book_properties_dialog_base.rb +13 -14
- data/lib/alexandria/ui/builder_base.rb +1 -1
- data/lib/alexandria/ui/callbacks.rb +8 -7
- data/lib/alexandria/ui/confirm_erase_dialog.rb +1 -0
- data/lib/alexandria/ui/conflict_while_copying_dialog.rb +1 -0
- data/lib/alexandria/ui/export_dialog.rb +1 -0
- data/lib/alexandria/ui/{iconview.rb → icon_view_manager.rb} +1 -0
- data/lib/alexandria/ui/icons.rb +2 -2
- data/lib/alexandria/ui/iconview_tooltips.rb +1 -1
- data/lib/alexandria/ui/init.rb +10 -4
- data/lib/alexandria/ui/keep_bad_isbn_dialog.rb +1 -0
- data/lib/alexandria/ui/libraries_combo.rb +1 -0
- data/lib/alexandria/ui/listview.rb +2 -0
- data/lib/alexandria/ui/main_app.rb +3 -1
- data/lib/alexandria/ui/multi_drag_treeview.rb +0 -2
- data/lib/alexandria/ui/new_book_dialog.rb +15 -20
- data/lib/alexandria/ui/new_book_dialog_manual.rb +7 -7
- data/lib/alexandria/ui/new_provider_dialog.rb +1 -0
- data/lib/alexandria/ui/new_smart_library_dialog.rb +2 -1
- data/lib/alexandria/ui/preferences_dialog.rb +4 -4
- data/lib/alexandria/ui/provider_preferences_dialog.rb +1 -0
- data/lib/alexandria/ui/really_delete_dialog.rb +1 -0
- data/lib/alexandria/ui/sidepane_manager.rb +49 -48
- data/lib/alexandria/ui/skip_entry_dialog.rb +1 -0
- data/lib/alexandria/ui/smart_library_properties_dialog.rb +1 -0
- data/lib/alexandria/ui/smart_library_properties_dialog_base.rb +2 -1
- data/lib/alexandria/ui/{sound.rb → sound_effects_player.rb} +3 -0
- data/lib/alexandria/ui/ui_manager.rb +194 -143
- data/lib/alexandria/ui.rb +1 -0
- data/lib/alexandria/version.rb +1 -1
- data/lib/alexandria/web_themes.rb +1 -1
- data/lib/alexandria.rb +6 -5
- data/po/Makefile +1 -1
- data/po/it.po +64 -82
- data/spec/alexandria/book_providers/bl_provider_spec.rb +11 -2
- data/spec/alexandria/book_providers/douban_provider_spec.rb +17 -0
- data/spec/alexandria/book_providers/loc_provider_spec.rb +10 -2
- data/spec/alexandria/book_providers/sbn_provider_spec.rb +10 -2
- data/spec/alexandria/book_providers/thalia_provider_spec.rb +9 -1
- data/spec/alexandria/book_providers/world_cat_provider_spec.rb +30 -10
- data/spec/alexandria/book_providers/z3950_provider_spec.rb +22 -0
- data/spec/alexandria/book_spec.rb +5 -3
- data/spec/alexandria/console_spec.rb +1 -1
- data/spec/alexandria/export_library_spec.rb +65 -19
- data/spec/alexandria/library_collection_spec.rb +24 -0
- data/spec/alexandria/library_spec.rb +68 -53
- data/spec/alexandria/library_store_spec.rb +33 -1
- data/spec/alexandria/preferences_spec.rb +7 -7
- data/spec/alexandria/pseudo_marc_parser_spec.rb +71 -0
- data/spec/alexandria/scanners/cue_cat_spec.rb +11 -4
- data/spec/alexandria/scanners/keyboard_wedge_spec.rb +47 -0
- data/spec/alexandria/smart_library_spec.rb +7 -5
- data/spec/alexandria/ui/about_dialog_spec.rb +2 -2
- data/spec/alexandria/ui/acquire_dialog_spec.rb +8 -3
- data/spec/alexandria/ui/alert_dialog_spec.rb +6 -4
- data/spec/alexandria/ui/bad_isbns_dialog_spec.rb +2 -2
- data/spec/alexandria/ui/book_properties_dialog_spec.rb +5 -5
- data/spec/alexandria/ui/confirm_erase_dialog_spec.rb +19 -3
- data/spec/alexandria/ui/conflict_while_copying_dialog_spec.rb +2 -2
- data/spec/alexandria/ui/error_dialog_spec.rb +14 -3
- data/spec/alexandria/ui/export_dialog_spec.rb +6 -6
- data/spec/alexandria/ui/{iconview_spec.rb → icon_view_manager_spec.rb} +2 -2
- data/spec/alexandria/ui/import_dialog_spec.rb +3 -3
- data/spec/alexandria/ui/keep_bad_isbn_dialog_spec.rb +2 -2
- data/spec/alexandria/ui/main_app_spec.rb +0 -2
- data/spec/alexandria/ui/new_book_dialog_manual_spec.rb +5 -5
- data/spec/alexandria/ui/new_book_dialog_spec.rb +7 -4
- data/spec/alexandria/ui/new_provider_dialog_spec.rb +3 -3
- data/spec/alexandria/ui/new_smart_library_dialog_spec.rb +9 -7
- data/spec/alexandria/ui/preferences_dialog_spec.rb +2 -2
- data/spec/alexandria/ui/provider_preferences_dialog_spec.rb +22 -7
- data/spec/alexandria/ui/really_delete_dialog_spec.rb +2 -2
- data/spec/alexandria/ui/sidepane_manager_spec.rb +2 -2
- data/spec/alexandria/ui/skip_entry_dialog_spec.rb +19 -3
- data/spec/alexandria/ui/smart_library_properties_dialog_spec.rb +2 -2
- data/spec/alexandria/ui/ui_manager_spec.rb +7 -5
- data/spec/end_to_end/basic_run_spec.rb +2 -1
- data/spec/spec_helper.rb +26 -33
- data/tasks/setup.rb +1 -1
- data/util/rake/fileinstall.rb +12 -13
- data/util/rake/gettextgenerate.rb +1 -1
- data/util/rake/omfgenerate.rb +1 -1
- metadata +97 -64
- /data/spec/alexandria/ui/{sound_spec.rb → sound_effects_player_spec.rb} +0 -0
|
@@ -1,80 +1,86 @@
|
|
|
1
1
|
---
|
|
2
2
|
- - :permit
|
|
3
3
|
- LGPL-3+
|
|
4
|
-
- :who:
|
|
5
|
-
:why:
|
|
4
|
+
- :who:
|
|
5
|
+
:why:
|
|
6
6
|
:versions: []
|
|
7
7
|
:when: 2017-07-23 05:51:53.629753437 Z
|
|
8
8
|
- - :permit
|
|
9
9
|
- LGPL-2.1+
|
|
10
|
-
- :who:
|
|
11
|
-
:why:
|
|
10
|
+
- :who:
|
|
11
|
+
:why:
|
|
12
12
|
:versions: []
|
|
13
13
|
:when: 2017-07-23 05:52:02.088395832 Z
|
|
14
14
|
- - :permit
|
|
15
15
|
- MIT
|
|
16
|
-
- :who:
|
|
17
|
-
:why:
|
|
16
|
+
- :who:
|
|
17
|
+
:why:
|
|
18
18
|
:versions: []
|
|
19
19
|
:when: 2017-07-23 05:52:06.806192042 Z
|
|
20
20
|
- - :permit
|
|
21
21
|
- LGPLv2+
|
|
22
|
-
- :who:
|
|
23
|
-
:why:
|
|
22
|
+
- :who:
|
|
23
|
+
:why:
|
|
24
24
|
:versions: []
|
|
25
25
|
:when: 2017-07-23 05:52:24.618189811 Z
|
|
26
26
|
- - :permit
|
|
27
27
|
- ruby
|
|
28
|
-
- :who:
|
|
29
|
-
:why:
|
|
28
|
+
- :who:
|
|
29
|
+
:why:
|
|
30
30
|
:versions: []
|
|
31
31
|
:when: 2017-07-23 05:52:36.986497403 Z
|
|
32
32
|
- - :approve
|
|
33
33
|
- alexandria-book-collection-manager
|
|
34
|
-
- :who:
|
|
35
|
-
:why:
|
|
34
|
+
- :who:
|
|
35
|
+
:why:
|
|
36
36
|
:versions: []
|
|
37
37
|
:when: 2017-07-23 05:53:02.657760962 Z
|
|
38
38
|
- - :approve
|
|
39
39
|
- unf
|
|
40
|
-
- :who:
|
|
41
|
-
:why:
|
|
40
|
+
- :who:
|
|
41
|
+
:why:
|
|
42
42
|
:versions: []
|
|
43
43
|
:when: 2017-07-23 05:54:45.171526986 Z
|
|
44
44
|
- - :approve
|
|
45
45
|
- gettext
|
|
46
|
-
- :who:
|
|
47
|
-
:why:
|
|
46
|
+
- :who:
|
|
47
|
+
:why:
|
|
48
48
|
:versions: []
|
|
49
49
|
:when: 2017-07-23 05:54:51.349832715 Z
|
|
50
50
|
- - :approve
|
|
51
51
|
- cairo
|
|
52
|
-
- :who:
|
|
53
|
-
:why:
|
|
52
|
+
- :who:
|
|
53
|
+
:why:
|
|
54
54
|
:versions: []
|
|
55
55
|
:when: 2017-07-23 05:54:54.822319735 Z
|
|
56
56
|
- - :license
|
|
57
57
|
- zoom
|
|
58
58
|
- LGPL-2.1
|
|
59
|
-
- :who:
|
|
60
|
-
:why:
|
|
59
|
+
- :who:
|
|
60
|
+
:why:
|
|
61
61
|
:versions: []
|
|
62
62
|
:when: 2020-07-30 06:44:22.960902375 Z
|
|
63
63
|
- - :permit
|
|
64
64
|
- Simplified BSD
|
|
65
|
-
- :who:
|
|
66
|
-
:why:
|
|
65
|
+
- :who:
|
|
66
|
+
:why:
|
|
67
67
|
:versions: []
|
|
68
68
|
:when: 2020-07-30 06:45:58.599399721 Z
|
|
69
69
|
- - :permit
|
|
70
70
|
- Apache 2.0
|
|
71
|
-
- :who:
|
|
72
|
-
:why:
|
|
71
|
+
- :who:
|
|
72
|
+
:why:
|
|
73
73
|
:versions: []
|
|
74
74
|
:when: 2020-07-30 06:46:08.280121582 Z
|
|
75
75
|
- - :permit
|
|
76
76
|
- LGPL-2.1
|
|
77
|
-
- :who:
|
|
78
|
-
:why:
|
|
77
|
+
- :who:
|
|
78
|
+
:why:
|
|
79
79
|
:versions: []
|
|
80
80
|
:when: 2020-07-30 06:46:32.729325577 Z
|
|
81
|
+
- - :permit
|
|
82
|
+
- LGPL-2.1-or-later
|
|
83
|
+
- :who:
|
|
84
|
+
:why:
|
|
85
|
+
:versions: []
|
|
86
|
+
:when: 2025-04-19 19:30:36.770204331 Z
|
data/{bin → exe}/alexandria
RENAMED
|
@@ -8,16 +8,14 @@
|
|
|
8
8
|
require "gettext"
|
|
9
9
|
require "alexandria"
|
|
10
10
|
require "optparse"
|
|
11
|
-
require "ostruct"
|
|
12
11
|
|
|
13
12
|
store = Alexandria::LibraryStore.new(Alexandria::Library::DEFAULT_DIR)
|
|
14
13
|
Alexandria::LibraryCollection.instance.library_store = store
|
|
15
14
|
|
|
16
|
-
# options = OpenStruct.new
|
|
17
15
|
OptionParser.new do |opts|
|
|
18
16
|
opts.banner = "Usage: alexandria [options]"
|
|
19
17
|
opts.on("-l", "--list", "List libraries in numbered format") do
|
|
20
|
-
puts Alexandria.list_books_on_console
|
|
18
|
+
puts Alexandria::Console.list_books_on_console
|
|
21
19
|
exit
|
|
22
20
|
end
|
|
23
21
|
opts.on("-d", "--debug", "Run in debug mode") do
|
data/lib/alexandria/about.rb
CHANGED
|
@@ -23,6 +23,7 @@ module Alexandria
|
|
|
23
23
|
TITLE = "Alexandria"
|
|
24
24
|
TEXTDOMAIN = "alexandria"
|
|
25
25
|
extend GetText
|
|
26
|
+
|
|
26
27
|
bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
|
27
28
|
DESCRIPTION = _("A program to help you manage your book collection.")
|
|
28
29
|
COPYRIGHT = "Copyright (C) 2004-2006 Laurent Sansonetti\n" \
|
|
@@ -22,6 +22,7 @@ module Alexandria
|
|
|
22
22
|
unabstract
|
|
23
23
|
|
|
24
24
|
include GetText
|
|
25
|
+
|
|
25
26
|
GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
|
26
27
|
|
|
27
28
|
def initialize
|
|
@@ -34,10 +35,7 @@ module Alexandria
|
|
|
34
35
|
prefs.read
|
|
35
36
|
end
|
|
36
37
|
|
|
37
|
-
def url(
|
|
38
|
-
"http://copac.ac.uk/openurl?isbn=" + Library.canonicalise_isbn(book.isbn)
|
|
39
|
-
rescue StandardError => ex
|
|
40
|
-
log.warn { "Cannot create url for book #{book}; #{ex.message}" }
|
|
38
|
+
def url(_book)
|
|
41
39
|
nil
|
|
42
40
|
end
|
|
43
41
|
|
|
@@ -76,8 +74,8 @@ module Alexandria
|
|
|
76
74
|
end
|
|
77
75
|
|
|
78
76
|
if title # and !authors.empty?
|
|
79
|
-
book = Book.new(title, authors, isbn,
|
|
80
|
-
|
|
77
|
+
book = Book.new(title, authors, isbn, publisher || nil,
|
|
78
|
+
publish_year || nil, edition || nil)
|
|
81
79
|
results << [book]
|
|
82
80
|
end
|
|
83
81
|
end
|
|
@@ -13,6 +13,7 @@ module Alexandria
|
|
|
13
13
|
unabstract
|
|
14
14
|
|
|
15
15
|
include GetText
|
|
16
|
+
|
|
16
17
|
GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
|
17
18
|
|
|
18
19
|
def initialize
|
|
@@ -25,12 +26,7 @@ module Alexandria
|
|
|
25
26
|
prefs.read
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
def url(
|
|
29
|
-
isbn = Library.canonicalise_isbn(book.isbn)
|
|
30
|
-
"http://catalog.loc.gov/cgi-bin/Pwebrecon.cgi?" \
|
|
31
|
-
"DB=local&CNT=25+records+per+page&CMD=isbn+#{isbn}"
|
|
32
|
-
rescue StandardError => ex
|
|
33
|
-
log.warn { "Cannot create url for book #{book}; #{ex.message}" }
|
|
29
|
+
def url(_book)
|
|
34
30
|
nil
|
|
35
31
|
end
|
|
36
32
|
end
|
|
@@ -14,6 +14,7 @@ module Alexandria
|
|
|
14
14
|
unabstract
|
|
15
15
|
|
|
16
16
|
include GetText
|
|
17
|
+
|
|
17
18
|
GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
|
18
19
|
|
|
19
20
|
def initialize
|
|
@@ -27,18 +28,7 @@ module Alexandria
|
|
|
27
28
|
prefs.read
|
|
28
29
|
end
|
|
29
30
|
|
|
30
|
-
def url(
|
|
31
|
-
"http://sbnonline.sbn.it/cgi-bin/zgw/BRIEF.pl?displayquery=" \
|
|
32
|
-
"%253CB%253E%253Cfont%2520color%253D%2523000064%253E" \
|
|
33
|
-
"Codice%2520ISBN%253C%2FB%253E%253C%2Ffont%253E%2520" \
|
|
34
|
-
"contiene%2520%2522%2520%253CFONT%2520COLOR%253Dred%253E" +
|
|
35
|
-
canonicalise_isbn_with_dashes(book.isbn) +
|
|
36
|
-
"%253C%2FFONT%253E%2522&session=&zurl=opac" \
|
|
37
|
-
"&zquery=%281%3D7+4%3D2+2%3D3+5%3D100+6%3D1+3%3D3+%22" +
|
|
38
|
-
canonicalise_isbn_with_dashes(book.isbn) +
|
|
39
|
-
"%22%29&language=it&maxentries=10&target=0&position=1"
|
|
40
|
-
rescue StandardError => ex
|
|
41
|
-
log.warn { "Cannot create url for book #{book}; #{ex.message}" }
|
|
31
|
+
def url(_book)
|
|
42
32
|
nil
|
|
43
33
|
end
|
|
44
34
|
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
# for Alexandria. (21 Dec 2009)
|
|
12
12
|
|
|
13
13
|
require "net/http"
|
|
14
|
-
require "cgi"
|
|
15
|
-
require "alexandria/book_providers/
|
|
14
|
+
require "cgi/escape"
|
|
15
|
+
require "alexandria/book_providers/website_based_provider"
|
|
16
16
|
|
|
17
17
|
module Alexandria
|
|
18
18
|
class BookProviders
|
|
@@ -20,7 +20,7 @@ module Alexandria
|
|
|
20
20
|
include Logging
|
|
21
21
|
|
|
22
22
|
SITE = "https://www.thalia.de"
|
|
23
|
-
BASE_SEARCH_URL = "#{SITE}/shop/bde_bu_hg_startseite/suche/?%s=%s" # type,term
|
|
23
|
+
BASE_SEARCH_URL = "#{SITE}/shop/bde_bu_hg_startseite/suche/?%s=%s".freeze # type,term
|
|
24
24
|
|
|
25
25
|
def initialize
|
|
26
26
|
super("Thalia", "Thalia (Germany)")
|
|
@@ -116,10 +116,9 @@ module Alexandria
|
|
|
116
116
|
title = div["data-titel"]
|
|
117
117
|
|
|
118
118
|
if (author_p = doc % "p.aim-author")
|
|
119
|
-
authors = []
|
|
120
119
|
author_links = author_p / :a
|
|
121
|
-
author_links.
|
|
122
|
-
|
|
120
|
+
authors = author_links.map do |a|
|
|
121
|
+
a.inner_text.strip
|
|
123
122
|
end
|
|
124
123
|
end
|
|
125
124
|
|
|
@@ -4,6 +4,25 @@
|
|
|
4
4
|
#
|
|
5
5
|
# See the file README.md for authorship and licensing information.
|
|
6
6
|
|
|
7
|
+
# By default, Nokogiri will configure libxml2 to use Ruby's memory
|
|
8
|
+
# management functions. This leads to the following sequence of events:
|
|
9
|
+
#
|
|
10
|
+
# - GC starts
|
|
11
|
+
# - Ruby/GNOME traverses the known GObject objects
|
|
12
|
+
# - Ruby/GNOME fetches properties for all objects
|
|
13
|
+
# - One of the properties (I do not know which one) gets initialized to its default value
|
|
14
|
+
# - As part of this process some SVG is parsed
|
|
15
|
+
# - Do do this, some memory needs to be allocated
|
|
16
|
+
# - Ruby does not want memory to be allocated during GC
|
|
17
|
+
# - The process crashes
|
|
18
|
+
#
|
|
19
|
+
# To avoid this, before loading nokogiri, set an environment variable that
|
|
20
|
+
# tells Nokogiri to leave libxml2's memory management alone.
|
|
21
|
+
#
|
|
22
|
+
# See https://github.com/sparklemotion/nokogiri/blob/main/adr/2023-04-libxml-memory-management.md
|
|
23
|
+
#
|
|
24
|
+
ENV["NOKOGIRI_LIBXML_MEMORY_MANAGEMENT"] = "default"
|
|
25
|
+
|
|
7
26
|
require "nokogiri"
|
|
8
27
|
require "htmlentities"
|
|
9
28
|
|
|
@@ -11,7 +30,7 @@ module Alexandria
|
|
|
11
30
|
class BookProviders
|
|
12
31
|
class WebsiteBasedProvider < GenericProvider
|
|
13
32
|
def initialize(name, fullname = nil)
|
|
14
|
-
super
|
|
33
|
+
super
|
|
15
34
|
@htmlentities = HTMLEntities.new
|
|
16
35
|
end
|
|
17
36
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
# This file is part of Alexandria.
|
|
4
4
|
#
|
|
5
5
|
# See the file README.md for authorship and licensing information.
|
|
6
|
-
# frozen_string_literal: true
|
|
7
6
|
|
|
8
7
|
# http://en.wikipedia.org/wiki/WorldCat
|
|
9
8
|
# See http://www.oclc.org/worldcat/policies/terms/
|
|
@@ -15,9 +14,9 @@
|
|
|
15
14
|
# Updated from Palatina, to reflect changes in the worldcat website.
|
|
16
15
|
# (1 Sep 2009)
|
|
17
16
|
|
|
18
|
-
require "cgi"
|
|
17
|
+
require "cgi/escape"
|
|
19
18
|
require "alexandria/net"
|
|
20
|
-
require "alexandria/book_providers/
|
|
19
|
+
require "alexandria/book_providers/website_based_provider"
|
|
21
20
|
|
|
22
21
|
module Alexandria
|
|
23
22
|
class BookProviders
|
|
@@ -25,7 +24,7 @@ module Alexandria
|
|
|
25
24
|
include Logging
|
|
26
25
|
|
|
27
26
|
SITE = "https://www.worldcat.org"
|
|
28
|
-
BASE_SEARCH_URL = "#{SITE}/search?q=%s%s&qt=advanced" # type, term
|
|
27
|
+
BASE_SEARCH_URL = "#{SITE}/search?q=%s%s&qt=advanced".freeze # type, term
|
|
29
28
|
|
|
30
29
|
def initialize
|
|
31
30
|
super("WorldCat", "WorldCat")
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# See the file README.md for authorship and licensing information.
|
|
6
6
|
|
|
7
7
|
require "zoom"
|
|
8
|
-
require "alexandria/
|
|
8
|
+
require "alexandria/pseudo_marc_parser"
|
|
9
9
|
require "marc"
|
|
10
10
|
|
|
11
11
|
module Alexandria
|
|
@@ -13,6 +13,7 @@ module Alexandria
|
|
|
13
13
|
class Z3950Provider < AbstractProvider
|
|
14
14
|
include Logging
|
|
15
15
|
include GetText
|
|
16
|
+
|
|
16
17
|
GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
|
17
18
|
|
|
18
19
|
def initialize(name = "Z3950", fullname = "Z39.50")
|
|
@@ -80,19 +81,7 @@ module Alexandria
|
|
|
80
81
|
end
|
|
81
82
|
|
|
82
83
|
def marc_to_book(marc_txt, isbn)
|
|
83
|
-
|
|
84
|
-
marc = MARC::Record.new_from_marc(marc_txt, forgiving: true)
|
|
85
|
-
rescue StandardError => ex
|
|
86
|
-
log.error { ex.message }
|
|
87
|
-
log.error { ex.backtrace.join("> \n") }
|
|
88
|
-
begin
|
|
89
|
-
marc = MARC::Record.new(marc_txt)
|
|
90
|
-
rescue StandardError => ex
|
|
91
|
-
log.error { ex.message }
|
|
92
|
-
log.error { ex.backtrace.join("> \n") }
|
|
93
|
-
raise ex
|
|
94
|
-
end
|
|
95
|
-
end
|
|
84
|
+
marc = MARC::Record.new_from_marc(marc_txt, forgiving: true)
|
|
96
85
|
|
|
97
86
|
log.debug do
|
|
98
87
|
msg = "Parsing MARC"
|
|
@@ -112,9 +101,9 @@ module Alexandria
|
|
|
112
101
|
|
|
113
102
|
Book.new(marc.title, marc.authors,
|
|
114
103
|
isbn,
|
|
115
|
-
|
|
104
|
+
marc.publisher || "",
|
|
116
105
|
marc.respond_to?(:publish_year) ? marc.publish_year.to_i : nil,
|
|
117
|
-
|
|
106
|
+
marc.edition || "")
|
|
118
107
|
end
|
|
119
108
|
|
|
120
109
|
def books_from_marc(resultset, isbn)
|
|
@@ -151,19 +140,11 @@ module Alexandria
|
|
|
151
140
|
end
|
|
152
141
|
|
|
153
142
|
def search_records(criterion, type, conn_count)
|
|
154
|
-
|
|
155
|
-
unless prefs["username"].empty? || prefs["password"].empty?
|
|
156
|
-
options["user"] = prefs["username"]
|
|
157
|
-
options["password"] = prefs["password"]
|
|
158
|
-
end
|
|
159
|
-
hostname = prefs["hostname"]
|
|
160
|
-
port = prefs["port"].to_i
|
|
161
|
-
log.debug { "hostname #{hostname} port #{port} options #{options}" }
|
|
162
|
-
conn = ZOOM::Connection.new(options).connect(hostname, port)
|
|
143
|
+
conn = connect_to_server
|
|
163
144
|
conn.database_name = prefs["database"]
|
|
164
|
-
|
|
165
145
|
conn.preferred_record_syntax = prefs["record_syntax"]
|
|
166
146
|
conn.element_set_name = "F"
|
|
147
|
+
|
|
167
148
|
conn.count = conn_count
|
|
168
149
|
attr = case type
|
|
169
150
|
when SEARCH_BY_ISBN then [7]
|
|
@@ -183,7 +164,7 @@ module Alexandria
|
|
|
183
164
|
end
|
|
184
165
|
conn.search(pqf)
|
|
185
166
|
rescue StandardError => ex
|
|
186
|
-
if
|
|
167
|
+
if ex.message.include?("1005") &&
|
|
187
168
|
prefs.variable_named("piggyback") && prefs["piggyback"]
|
|
188
169
|
log.error { "Z39.50 search failed:: #{ex.message}" }
|
|
189
170
|
log.info { "Turning off piggybacking for this provider" }
|
|
@@ -194,6 +175,23 @@ module Alexandria
|
|
|
194
175
|
raise ex
|
|
195
176
|
end
|
|
196
177
|
end
|
|
178
|
+
|
|
179
|
+
def connect_to_server
|
|
180
|
+
options = {}
|
|
181
|
+
unless prefs["username"].empty? || prefs["password"].empty?
|
|
182
|
+
options["user"] = prefs["username"]
|
|
183
|
+
options["password"] = prefs["password"]
|
|
184
|
+
end
|
|
185
|
+
hostname = prefs["hostname"]
|
|
186
|
+
port = prefs["port"].to_i
|
|
187
|
+
log.debug { "hostname #{hostname} port #{port} options #{options}" }
|
|
188
|
+
|
|
189
|
+
ZOOM::Connection.new(options).connect(hostname, port)
|
|
190
|
+
rescue RuntimeError => ex
|
|
191
|
+
raise ConnectionError if ex.message.include?("10007")
|
|
192
|
+
|
|
193
|
+
raise ex
|
|
194
|
+
end
|
|
197
195
|
end
|
|
198
196
|
end
|
|
199
197
|
end
|
|
@@ -29,6 +29,7 @@ module Alexandria
|
|
|
29
29
|
include Singleton
|
|
30
30
|
include Observable
|
|
31
31
|
include GetText
|
|
32
|
+
|
|
32
33
|
GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
|
33
34
|
|
|
34
35
|
SEARCH_BY_ISBN, SEARCH_BY_TITLE, SEARCH_BY_AUTHORS,
|
|
@@ -36,6 +37,8 @@ module Alexandria
|
|
|
36
37
|
|
|
37
38
|
class SearchError < StandardError; end
|
|
38
39
|
|
|
40
|
+
class ConnectionError < SearchError; end
|
|
41
|
+
|
|
39
42
|
class NoResultsError < SearchError; end
|
|
40
43
|
|
|
41
44
|
class TooManyResultsError < SearchError; end
|
|
@@ -138,7 +141,6 @@ module Alexandria
|
|
|
138
141
|
|
|
139
142
|
def initialize(provider, name, description, default_value,
|
|
140
143
|
possible_values = nil, mandatory = true)
|
|
141
|
-
|
|
142
144
|
@provider = provider
|
|
143
145
|
@name = name
|
|
144
146
|
@description = description
|
|
@@ -166,17 +168,17 @@ module Alexandria
|
|
|
166
168
|
end
|
|
167
169
|
end
|
|
168
170
|
|
|
169
|
-
def add(*
|
|
170
|
-
self << Variable.new(@provider, *
|
|
171
|
+
def add(*)
|
|
172
|
+
self << Variable.new(@provider, *)
|
|
171
173
|
end
|
|
172
174
|
|
|
173
175
|
def [](obj)
|
|
174
176
|
case obj
|
|
175
177
|
when String
|
|
176
178
|
var = variable_named(obj)
|
|
177
|
-
var
|
|
179
|
+
var&.value
|
|
178
180
|
when Integer
|
|
179
|
-
super
|
|
181
|
+
super
|
|
180
182
|
end
|
|
181
183
|
end
|
|
182
184
|
|
|
@@ -195,12 +197,13 @@ module Alexandria
|
|
|
195
197
|
|
|
196
198
|
class AbstractProvider
|
|
197
199
|
include GetText
|
|
200
|
+
|
|
198
201
|
attr_reader :prefs
|
|
199
202
|
attr_accessor :name, :fullname
|
|
200
203
|
|
|
201
204
|
def initialize(name, fullname = nil)
|
|
202
205
|
@name = name
|
|
203
|
-
@fullname =
|
|
206
|
+
@fullname = fullname || name
|
|
204
207
|
@prefs = Preferences.new(self)
|
|
205
208
|
@prefs.add("enabled", _("Enabled"), true, [true, false])
|
|
206
209
|
end
|
|
@@ -277,6 +280,7 @@ module Alexandria
|
|
|
277
280
|
# FIXME: Clean up this complex abstract/concrete class system
|
|
278
281
|
def self.unabstract
|
|
279
282
|
include Singleton
|
|
283
|
+
|
|
280
284
|
undef_method :reinitialize
|
|
281
285
|
undef_method :name=
|
|
282
286
|
undef_method :fullname=
|
|
@@ -288,11 +292,11 @@ module Alexandria
|
|
|
288
292
|
unabstract
|
|
289
293
|
end
|
|
290
294
|
|
|
291
|
-
require "alexandria/book_providers/
|
|
295
|
+
require "alexandria/book_providers/douban_provider"
|
|
292
296
|
|
|
293
297
|
# Website based providers
|
|
294
298
|
require "alexandria/book_providers/thalia_provider"
|
|
295
|
-
require "alexandria/book_providers/
|
|
299
|
+
require "alexandria/book_providers/world_cat_provider"
|
|
296
300
|
|
|
297
301
|
# Z39.50 based providers
|
|
298
302
|
require "alexandria/book_providers/loc_provider"
|
|
@@ -351,7 +355,7 @@ module Alexandria
|
|
|
351
355
|
end
|
|
352
356
|
clear
|
|
353
357
|
rejig_providers_priority
|
|
354
|
-
priority =
|
|
358
|
+
priority = @prefs.providers_priority || []
|
|
355
359
|
priority.map!(&:strip)
|
|
356
360
|
rest = providers.keys - priority
|
|
357
361
|
priority.each { |pname| self << providers[pname] }
|
|
@@ -370,7 +374,7 @@ module Alexandria
|
|
|
370
374
|
private
|
|
371
375
|
|
|
372
376
|
def rejig_providers_priority
|
|
373
|
-
priority =
|
|
377
|
+
priority = @prefs.providers_priority || []
|
|
374
378
|
return if priority.empty?
|
|
375
379
|
|
|
376
380
|
changed = false
|
data/lib/alexandria/config.rb
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module Alexandria
|
|
4
4
|
module Config
|
|
5
5
|
SHARE_DIR = File.expand_path("../../share", File.dirname(__FILE__))
|
|
6
|
-
SOUNDS_DIR = "#{SHARE_DIR}/sounds/alexandria"
|
|
7
|
-
DATA_DIR = "#{SHARE_DIR}/alexandria"
|
|
6
|
+
SOUNDS_DIR = "#{SHARE_DIR}/sounds/alexandria".freeze
|
|
7
|
+
DATA_DIR = "#{SHARE_DIR}/alexandria".freeze
|
|
8
8
|
MAIN_DATA_DIR = DATA_DIR
|
|
9
9
|
end
|
|
10
10
|
end
|
data/lib/alexandria/console.rb
CHANGED
|
@@ -5,16 +5,18 @@
|
|
|
5
5
|
# See the file README.md for authorship and licensing information.
|
|
6
6
|
|
|
7
7
|
module Alexandria
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
module Console
|
|
9
|
+
def self.list_books_on_console
|
|
10
|
+
collection = Alexandria::LibraryCollection.instance
|
|
11
|
+
collection.reload
|
|
12
|
+
libraries = collection.all_regular_libraries
|
|
13
|
+
output_string = ""
|
|
14
|
+
@books = libraries.flatten
|
|
15
|
+
@books.each do |book|
|
|
16
|
+
book_authors = book.authors.join(" & ")
|
|
17
|
+
output_string += [book.title, book_authors].join(", ") + "\n"
|
|
18
|
+
end
|
|
19
|
+
output_string
|
|
17
20
|
end
|
|
18
|
-
output_string
|
|
19
21
|
end
|
|
20
22
|
end
|
|
@@ -11,6 +11,7 @@ module Alexandria
|
|
|
11
11
|
include GetText
|
|
12
12
|
include Logging
|
|
13
13
|
extend GetText
|
|
14
|
+
|
|
14
15
|
bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
|
15
16
|
|
|
16
17
|
def self.all
|
|
@@ -25,10 +26,10 @@ module Alexandria
|
|
|
25
26
|
]
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
def invoke(library, sort_order, filename, *
|
|
29
|
+
def invoke(library, sort_order, filename, *)
|
|
29
30
|
sorted = ExportLibrary.new(library, sort_order)
|
|
30
31
|
log.debug { "Exporting library sorted by #{sort_order}" }
|
|
31
|
-
sorted.send(@message, filename, *
|
|
32
|
+
sorted.send(@message, filename, *)
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
def needs_preview?
|